/** * 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; }
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(); }
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; }
/** * 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; }