/** * Update the status of the returned item if there is one to whatever the * status was before it was returned. * * Currently this just chooses the status before the current one, but it * could be more robust. * * @todo Look into making this more robust, by knowing how many steps to * take back in the status history to get to just before the return * started. * * @param OrderTransaction\Event\TransactionalEvent $event */ public function revertReturnedItemStatus(OrderTransaction\Event\TransactionalEvent $event) { $transaction = $event->getTransaction(); // Skip if the transaction is not a return transaction if (Types::ORDER_RETURN !== $transaction->type) { return false; } $itemEdit = $this->get('order.item.edit'); $itemEdit->setTransaction($event->getDbTransaction()); foreach ($transaction->records->getByType(OrderReturn::RECORD_TYPE) as $return) { // Skip if the return was not for an order (i.e. it was a standalone return) if (!$return->item->order) { return false; } $item = $return->item->orderItem; $history = $this->get('order.item.status.loader')->getHistory($item); // Skip if there was not more than 2 statuses on the item if (count($history) < 2) { continue; } // Get the status before the current one $previousStatus = array_shift($history); $previousStatus = array_shift($history); $itemEdit->updateStatus($item, $previousStatus->code); } }
/** * Creates the transaction. * If a DB\Transaction has been explicitly set, adds the Transaction to the * DB\Transaction. Otherwise commits $_query. * * @param Transaction $transaction transaction to be created * * @return Transaction if transaction wasn't overridden * re-loaded $transaction, otherwise just * $transaction */ public function create(Transaction $transaction) { // Set create authorship data if not already set if (!$transaction->authorship->createdAt()) { $transaction->authorship->create(new DateTimeImmutable(), $this->_currentUser->id); } $event = new Event\TransactionalEvent($transaction); $event->setDbTransaction($this->_query); $transaction = $this->_eventDispatcher->dispatch(Events::CREATE_START, $event)->getTransaction(); $this->_validate($transaction); $this->_query->run(' INSERT INTO transaction SET created_at = :createdAt?d, created_by = :createdBy?in, type = :type?s ', array('createdAt' => $transaction->authorship->createdAt(), 'createdBy' => $transaction->authorship->createdBy(), 'type' => $transaction->type)); $sqlVariable = 'TRANSACTION_ID_' . uniqid(); $this->_query->setIDVariable($sqlVariable); $transaction->id = '@' . $sqlVariable; $this->_createRecords($transaction); $this->_createAttributes($transaction); $loader = $this->_loader; $this->_query->attachEvent(Events::CREATE_COMPLETE, function ($dbTrans) use($loader, $sqlVariable) { return new Event\Event($loader->getByID($dbTrans->getIDVariable($sqlVariable))); }); if (!$this->_transOverridden) { $this->_query->commit(); } return $transaction; }
/** * Voids the given transaction. * * @param Transaction $transaction Transaction to be voided * * @return Transaction The voided transaction * * @throws \InvalidArgumentException If transaction is already voided */ public function void(Transaction $transaction) { if ($transaction->isVoided()) { throw new \InvalidArgumentException('Transaction has already been voided.'); } $transaction->voidedAt = new DateTimeImmutable(); $transaction->voidedBy = $this->_user->id; $result = $this->_query->run(' UPDATE transaction SET voided_at = :at?d, voided_by = :by?in WHERE transaction_id = :id?i ', ['at' => $transaction->voidedAt, 'by' => $transaction->voidedBy, 'id' => $transaction->id]); $event = new Event\TransactionalEvent($transaction); $event->setDbTransaction($this->_query); $transaction = $this->_eventDispatcher->dispatch(Events::VOID, $event)->getTransaction(); if (!$this->_transOverridden) { $this->_query->commit(); } return $transaction; }
/** * Create a stock movement to put all items in a transaction that is being * voided back into stock in the stock location they were purchased from. * * @param Transaction\Event\TransactionalEvent $event */ public function returnItemsToStock(Transaction\Event\TransactionalEvent $event) { $transaction = $event->getTransaction(); $stockManager = $this->get('stock.manager'); $stockManager->setTransaction($event->getDbTransaction()); $stockManager->createWithRawNote(true); $stockManager->setReason($this->get('stock.movement.reasons')->get('void_transaction')); $event->getDbTransaction()->add("\n\t\t\tSET @STOCK_NOTE = CONCAT('Void transaction #', ?i)\n\t\t", $transaction->id); $stockManager->setNote('@STOCK_NOTE'); $stockManager->setAutomated(true); foreach ($transaction->records->getByType(Item\Item::RECORD_TYPE) as $item) { $stockManager->increment($item->getUnit(), $item->stockLocation); } }