コード例 #1
0
 /**
  * Updates or deletes dispatches when items of an order are cancelled.
  * Removes all cancelled items and updates the dispatch.
  * If all items have been cancelled, the dispatch is deleted.
  * 
  * @param  Event\TransactionalEvent $event Event
  */
 public function updateDispatches(Event\TransactionalEvent $event)
 {
     $order = $event->getOrder();
     $trans = $event->getTransaction();
     $dispatchEdit = $this->get('order.dispatch.edit');
     $dispatchDeleter = $this->get('order.dispatch.delete');
     $dispatchEdit->setTransaction($trans);
     $dispatchDeleter->setTransaction($trans);
     foreach ($order->dispatches as $dispatch) {
         if ($dispatch->authorship->isDeleted()) {
             continue;
         }
         $updateNecessary = false;
         foreach ($dispatch->items as $item) {
             if (Statuses::CANCELLED === $item->status->code) {
                 $dispatch->items->remove($item);
                 $updateNecessary = true;
             }
         }
         if ($updateNecessary) {
             $dispatchEdit->update($dispatch);
             if (0 === $dispatch->items->count()) {
                 $dispatchDeleter->delete($dispatch);
             }
         }
     }
 }
コード例 #2
0
 /**
  * Update the items' statuses to match their parent order's status, where
  * the order status is 'cancelled'.
  *
  * @param  EventTransactionalEvent $event
  */
 public function updateStatus(Event\TransactionalEvent $event)
 {
     $order = $event->getOrder();
     if (Statuses::CANCELLED === $order->status->code) {
         $this->_itemEdit->setTransaction($event->getTransaction());
         $this->_itemEdit->updateStatus($order->items->all(), Statuses::CANCELLED);
     }
 }
 public function adjustStock(Event\TransactionalEvent $event)
 {
     $order = $event->getOrder();
     $trans = $event->getTransaction();
     $stockManager = $this->get('stock.manager');
     $stockManager->setTransaction($trans);
     $stockManager->createWithRawNote(true);
     $stockManager->setReason($this->get('stock.movement.reasons')->get('new_order'));
     $trans->add("SET @STOCK_NOTE = CONCAT('Order #', ?i);", $order->id);
     $stockManager->setNote('@STOCK_NOTE');
     $stockManager->setAutomated(true);
     foreach ($order->getItems() as $item) {
         $stockManager->decrement($item->getUnit(), $item->stockLocation);
     }
 }
コード例 #4
0
 /**
  * Dispatch the event to set the order's overall status. This is fired when
  * an item status changes.
  *
  * If the event results in a status code that is different to the order's
  * existing status code, it is updated.
  *
  * @param  Event\TransactionalEvent $event The event object
  */
 public function dispatchSetOrderStatusEvent(Event\TransactionalEvent $event)
 {
     $statusEvent = $event->getDispatcher()->dispatch(OrderEvents::SET_STATUS, new Event\SetOrderStatusEvent($event->getOrder()));
     $orderStatus = $statusEvent->getStatus();
     $order = $statusEvent->getOrder();
     // Skip if no status was set
     if (is_null($orderStatus)) {
         return;
     }
     // Skip if the status hasn't changed
     if ($orderStatus === $order->status->code) {
         return;
     }
     $edit = $this->get('order.edit');
     $edit->setTransaction($event->getTransaction());
     $edit->updateStatus($order, $orderStatus);
 }
コード例 #5
0
 /**
  * Creates a transaction with records for the order, all items and payments
  *
  * @param  Event\Event $event event carrying information about order
  */
 public function createOrderTransaction(Event\TransactionalEvent $event)
 {
     $order = $event->getOrder();
     if ($order->status->code >= Statuses::AWAITING_DISPATCH || $order->status->code === Statuses::PAYMENT_PENDING) {
         $transaction = new Transaction();
         $transaction->records->add($order);
         foreach ($order->items as $item) {
             $transaction->records->add($item);
         }
         foreach ($order->payments as $payment) {
             $transaction->records->add($payment);
         }
         // $transaction->type =
         // 	($order->status->code === Statuses::PAYMENT_PENDING ? Types::CONTRACT_INITIATION : Types::ORDER);
         $transaction->type = Types::ORDER;
         $this->get('order.transaction.create')->setDbTransaction($event->getTransaction())->create($transaction);
     }
 }
コード例 #6
0
    /**
     * Delete an order by marking it as deleted in the database.
     *
     * @param  Order     $order The order to be deleted
     *
     * @return Order     The order that was deleted, with the "delete" authorship data set
     */
    public function delete(Order $order)
    {
        $order->authorship->delete(new DateTimeImmutable(), $this->_currentUser->id);
        $event = new Event\TransactionalEvent($order);
        $event->setTransaction($this->_trans);
        $order = $this->_eventDispatcher->dispatch(Events::DELETE_START, $event)->getOrder();
        $this->_trans->run('
			UPDATE
				order_summary
			SET
				deleted_at = :at?d,
				deleted_by = :by?in
			WHERE
				order_id = :id?i
		', array('at' => $order->authorship->deletedAt(), 'by' => $order->authorship->deletedBy(), 'id' => $order->id));
        $event = new Event\TransactionalEvent($order);
        $event->setTransaction($this->_trans);
        $order = $this->_eventDispatcher->dispatch(Events::DELETE_END, $event)->getOrder();
        return $order;
    }
コード例 #7
0
    public function updateStatus(Order $order, $statusCode)
    {
        if (!$this->_statuses->exists($statusCode)) {
            throw new \InvalidArgumentException(sprintf('Order status `%s` does not exist', $statusCode));
        }
        $status = $this->_statuses->get($statusCode);
        // Skip if the item is already at this status
        if ($status->code === $order->status->code) {
            return false;
        }
        $order->authorship->update(new DateTimeImmutable(), $this->_currentUser->id);
        $this->_query->run('
			UPDATE
				order_summary
			SET
				status_code = :status?i,
				updated_at  = :updatedAt?i,
				updated_by  = :updatedBy?in
			WHERE
				order_id = :id?i
		', array('id' => $order->id, 'status' => $status->code, 'updatedAt' => $order->authorship->updatedAt(), 'updatedBy' => $order->authorship->updatedBy()));
        if ($status->code === Statuses::CANCELLED) {
            $this->_query->run('UPDATE
					`order_shipping`
				SET
					`status_code` = :status?i
				WHERE
					`order_id` = :id?i', ['id' => $order->id, 'status' => $status->code]);
        }
        $order->status = clone $status;
        $event = new Event\TransactionalEvent($order);
        $event->setTransaction($this->_query);
        $order = $this->_eventDispatcher->dispatch(Events::STATUS_CHANGE, $event)->getOrder();
        if (!$this->_transOverridden) {
            $this->_query->commit();
        }
        return $this->_eventDispatcher->dispatch(Events::EDIT, new Event\Event($order))->getOrder();
    }
コード例 #8
0
 /**
  * Constructor.
  *
  * @param Order           $order
  * @param EntityInterface $entity
  */
 public function __construct(Order $order, EntityInterface $entity)
 {
     parent::__construct($order);
     $this->setEntity($entity);
 }
コード例 #9
0
    public function create(Order $order)
    {
        $event = new Event\TransactionalEvent($order);
        $event->setTransaction($this->_trans);
        $order = $this->_eventDispatcher->dispatch(Events::CREATE_START, $event)->getOrder();
        $validation = $this->_eventDispatcher->dispatch(Events::CREATE_VALIDATE, new Event\ValidateEvent($order));
        if ($validation->hasErrors()) {
            throw new \InvalidArgumentException(sprintf('Cannot create order: %s', implode(', ', $validation->getErrors())));
        }
        if (!$order->authorship->createdAt()) {
            $order->authorship->create(new DateTimeImmutable(), $this->_currentUser->id);
        }
        $this->_trans->add('
			INSERT INTO
				order_summary
			SET
				created_at       = :createdAt?d,
				created_by       = :createdBy?in,
				status_code      = :status?i,
				user_id          = :userID?in,
				user_email		 = :userEmail?sn,
				type             = :type?sn,
				locale           = :locale?s,
				taxable          = :taxable?b,
				currency_id      = :currencyID?s,
				conversion_rate  = :conversionRate?f,
				product_net      = :productNet?f,
				product_discount = :productDiscount?f,
				product_tax      = :productTax?f,
				product_gross    = :productGross?f,
				total_net        = :totalNet?f,
				total_discount   = :totalDiscount?f,
				total_tax        = :totalTax?f,
				total_gross      = :totalGross?f
		', array('createdAt' => $order->authorship->createdAt(), 'createdBy' => $order->authorship->createdBy(), 'userID' => $order->user ? $order->user->id : null, 'userEmail' => $order->user ? $order->user->email : null, 'status' => $order->status->code, 'type' => $order->type, 'locale' => $order->locale, 'taxable' => $order->taxable, 'currencyID' => $order->currencyID, 'conversionRate' => $order->conversionRate, 'productNet' => $order->productNet, 'productDiscount' => $order->productDiscount, 'productTax' => $order->productTax, 'productGross' => $order->productGross, 'totalNet' => $order->totalNet, 'totalDiscount' => $order->totalDiscount, 'totalTax' => $order->totalTax, 'totalGross' => $order->totalGross));
        $this->_trans->setIDVariable('ORDER_ID');
        $order->id = '@ORDER_ID';
        $this->_trans->add('
			INSERT INTO
				order_shipping
			SET
				order_id     = :orderID?i,
				list_price   = :listPrice?f,
				net          = :net?f,
				discount     = :discount?f,
				tax          = :tax?f,
				tax_rate     = :taxRate?f,
				gross        = :gross?f,
				name         = :name?sn,
				display_name = :display_name?sn
		', array('orderID' => $order->id, 'listPrice' => $order->shippingListPrice, 'net' => $order->shippingNet, 'discount' => $order->shippingDiscount, 'tax' => $order->shippingTax, 'taxRate' => $order->shippingTaxRate, 'gross' => $order->shippingGross, 'name' => $order->shippingName, 'display_name' => $order->shippingDisplayName));
        // Insert metadata
        foreach ($order->metadata as $key => $value) {
            $this->_trans->add('
				INSERT INTO
					order_metadata
				SET
					`order_id` = :orderID?i,
					`key`      = :key?s,
					`value`    = :value?sn
			', array('orderID' => $order->id, 'key' => $key, 'value' => $value));
        }
        foreach ($order->getEntities() as $name => $collection) {
            if (count($collection) > 0 && !array_key_exists($name, $this->_entityCreators)) {
                throw new \LogicException(sprintf('Creator for `%s` order entity not set on order creator', $name));
            }
            foreach ($collection as $entity) {
                $entity->order = $order;
                // Create the entities with the same authorship data as the order
                if (isset($entity->authorship) && $entity->authorship instanceof Authorship && !$entity->authorship->createdAt()) {
                    $entity->authorship->create($order->authorship->createdAt(), $order->authorship->createdBy());
                }
                $this->_entityCreators[$name]->create($entity);
            }
        }
        // Insert item tax rates
        $tokens = [];
        $inserts = [];
        foreach ($order->getShippingTaxes() as $type => $rate) {
            $tokens[] = '(?i, ?s, ?f, ?f)';
            $inserts[] = $order->id;
            $inserts[] = $type;
            $inserts[] = $rate;
            $inserts[] = $order->shippingNet * $rate / 100;
        }
        if ($inserts) {
            $this->_trans->add("INSERT INTO\n\t\t\t\t\t`order_shipping_tax` (`order_id`, `tax_type`, `tax_rate`, `tax_amount`)\n\t\t\t\tVALUES " . implode(',', $tokens), $inserts);
        }
        // Fire the "create end" event before committing the transaction
        $event = new Event\TransactionalEvent($order);
        $event->setTransaction($this->_trans);
        $this->_eventDispatcher->dispatch(Events::CREATE_END, $event);
        $order = $event->getOrder();
        // add CREATE_COMPLETE event to when transaction is committed
        $loader = $this->_loader;
        $this->_trans->attachEvent(Events::CREATE_COMPLETE, function ($trans) use($loader) {
            return new Event\Event($loader->getByID($trans->getIDVariable('ORDER_ID')));
        });
        // @todo ideally we want to listen to CREATE_COMPLETE
        // check if $event->getOrder()->id == $sqlVariableThing
        // then set that as the return value
        if (!$this->_transOverridden) {
            $this->_trans->commit();
            $order = $this->_loader->getByID($this->_trans->getIDVariable('ORDER_ID'));
        }
        return $order;
    }
コード例 #10
0
    /**
     * Update the status of an item or items.
     *
     * @param  Item|Collection|array $items Item, array of items or collection
     *                                      of items
     * @param  int              $statusCode Status code to set
     *
     * @return Edit                         Returns $this for chainability
     *
     * @throws \InvalidArgumentException If the item status supplied is not
     *                                   set on the status collection
     * @throws \InvalidArgumentException If no valid Item instances are passed
     * @throws \InvalidArgumentException If a non-falsey value that is not an
     *                                   instance of Item is passed as an item
     */
    public function updateStatus($items, $statusCode)
    {
        if (!$this->_statuses->exists($statusCode)) {
            throw new \InvalidArgumentException(sprintf('Order item status `%s` does not exist', $statusCode));
        }
        $status = $this->_statuses->get($statusCode);
        if (!is_array($items) && !$items instanceof Collection) {
            $items = array($items);
        }
        // Filter out any falsey values
        $items = $items instanceof Collection ? $items->all() : $items;
        $items = array_filter($items);
        $orders = [];
        // Throw exception if we don't have any items
        if (empty($items)) {
            throw new \InvalidArgumentException('No items passed to `updateStatus()`');
        }
        foreach ($items as $key => $item) {
            if (!$item instanceof Item) {
                $type = gettype($item);
                if ($type == 'object') {
                    $type = get_class($item);
                }
                throw new \InvalidArgumentException(sprintf('Unexpected value: expected order item instance - "' . $type . '"'));
            }
            // Skip if the item is already at this status
            if ($status->code === $item->status->code) {
                continue;
            }
            // Get instance of item status (so we have authorship info)
            $status = new Status\Status($status->code, $status->name);
            $status->authorship->create(new DateTimeImmutable(), $this->_currentUser->id);
            $this->_query->add('
				INSERT INTO
					order_item_status
				SET
					order_id    = :orderID?i,
					item_id     = :itemID?i,
					status_code = :status?i,
					created_at  = :createdAt?i,
					created_by  = :createdBy?in
			', array('orderID' => $item->order->id, 'itemID' => $item->id, 'status' => $status->code, 'createdAt' => $status->authorship->createdAt(), 'createdBy' => $status->authorship->createdBy()));
            $item->status = $status;
            // Collect the order if it hasn't been collected yet
            if (!array_key_exists($item->order->id, $orders)) {
                $orders[$item->order->id] = $item->order;
            }
        }
        // Dispatch an event for each individual order
        foreach ($orders as $order) {
            $event = new Event\TransactionalEvent($order);
            $event->setTransaction($this->_query);
            $this->_eventDispatcher->dispatch(OrderEvents::ITEM_STATUS_CHANGE, $event);
        }
        if (!$this->_transOverridden) {
            $this->_query->commit();
        }
        return $this;
    }