public function returnCreated(Event $event) { $return = $event->getReturn(); $transaction = new Transaction(); $transaction->type = Types::ORDER_RETURN; $transaction->records->add($return); foreach ($return->payments as $payment) { if ($return->item->order) { $payment = new OrderPayment($payment); $payment->order = $return->item->order; } $transaction->records->add($payment); } foreach ($return->refunds as $refund) { if ($return->item->order) { $refund = new OrderRefund($refund); $refund->order = $return->item->order; } $transaction->records->add($refund); } // Add the exchange item, if there is one if ($exchangeItem = $return->item->exchangeItem) { $transaction->records->add($exchangeItem); // Add the exchange item's order, if it's standalone if (!$return->item->order) { $transaction->records->add($exchangeItem->order); } } $this->get('order.transaction.create')->setDbTransaction($event->getTransaction())->create($transaction); }
public function saveDocument(Event $event) { $return = $event->getReturn(); $statusCode = $return->item->status->code; if ($statusCode === Statuses::AWAITING_RETURN) { $document = $this->get('file.return_slip')->save($return); $this->get('db.query')->run("\n\t\t\t\tUPDATE\n\t\t\t\t\t`return`\n\t\t\t\tSET\n\t\t\t\t\tdocument_id = :documentID?i\n\t\t\t\tWHERE\n\t\t\t\t\treturn_id = :returnID?i\n\t\t\t\t", ['documentID' => $document->id, 'returnID' => $return->id]); } }
/** * Save a return entity into the database. * * @todo Update to handle multiple return items. * @todo Break this up into either events or smaller classes handling * each separate responsibility. * * @param Entity\OrderReturn $return * @return Entity\OrderReturn */ public function create(Entity\OrderReturn $return) { $isStandalone = !($return->item->order and $return->item->order->id); $this->_validate($return); $this->_orderCreate->setTransaction($this->_trans); $this->_noteCreate->setTransaction($this->_trans); $this->_paymentCreate->setTransaction($this->_trans); $this->_refundCreate->setTransaction($this->_trans); $this->_stockManager->setTransaction($this->_trans); $this->_orderItemEdit->setTransaction($this->_trans); $this->_orderRefundCreate->setTransaction($this->_trans); $this->_orderPaymentCreate->setTransaction($this->_trans); $this->_stockManager->setAutomated(true); $this->_stockManager->createWithRawNote(true); // Get the return item status $statusCode = $return->item->status ? $return->item->status->code : Statuses::AWAITING_RETURN; // Set create authorship data if not already set if (!$return->authorship->createdAt()) { $return->authorship->create(new DateTimeImmutable(), $this->_currentUser->id); } // Create the return $this->_trans->run("\n\t\t\tINSERT INTO\n\t\t\t\t`return`\n\t\t\tSET\n\t\t\t\tcreated_at = :createdAt?i,\n\t\t\t\tcreated_by = :createdBy?i,\n\t\t\t\tcompleted_at = :completedAt?i,\n\t\t\t\tcompleted_by = :completedBy?i,\n\t\t\t\ttype = :type?s,\n\t\t\t\tcurrency_id = :currencyID?s\n\t\t", ['createdAt' => $return->authorship->createdAt(), 'createdBy' => $return->authorship->createdBy(), 'completedAt' => $statusCode == Statuses::RETURN_COMPLETED ? $return->authorship->createdAt() : null, 'completedBy' => $statusCode == Statuses::RETURN_COMPLETED ? $return->authorship->createdBy() : null, 'type' => $return->type, 'currencyID' => $return->currencyID]); $this->_trans->setIDVariable(self::MYSQL_ID_VAR); $return->id = '@' . self::MYSQL_ID_VAR; // Get the order for the return for quick reference $order = $return->item->order; // If this is a standalone exchange, create an order for entities to be // attached to and representing the original sale. if ($isStandalone && $return->item->exchangeItem) { $order = clone $this->_newOrder; } if ($order && !$order->currencyID) { $order->currencyID = $return->currencyID; } if ($order && !$order->type) { $order->type = 'standalone-return'; } // Create the related note if there is one if ($order && $return->item->note) { $return->item->note->order = $order; $order->notes->append($return->item->note); if (!$isStandalone) { $this->_noteCreate->create($return->item->note); } } // Create the related payments if there are any if ($return->payments) { foreach ($return->payments as $payment) { // Set the currency id to match the return if null if (!$payment->currencyID) { $payment->currencyID = $return->currencyID; } $this->_trans->run("\n\t\t\t\t\tINSERT INTO\n\t\t\t\t\t\t`return_payment`\n\t\t\t\t\tSET\n\t\t\t\t\t\treturn_id = :returnID?i,\n\t\t\t\t\t\tpayment_id = :paymentID?i\n\t\t\t\t", ['returnID' => $return->id, 'paymentID' => $payment->id]); $this->_paymentCreate->create($payment); if ($order) { $orderPayment = new OrderPayment($payment); $orderPayment->order = $order; $order->payments->append($orderPayment); if (!$isStandalone) { $this->_orderPaymentCreate->create($orderPayment); } } } } // Create the related refunds if there are any if ($return->refunds) { foreach ($return->refunds as $refund) { // Set the currency id to match the return if null if (!$refund->currencyID) { $refund->currencyID = $return->currencyID; } $this->_refundCreate->create($refund); $this->_trans->run("\n\t\t\t\t\tINSERT INTO\n\t\t\t\t\t\t`return_refund`\n\t\t\t\t\tSET\n\t\t\t\t\t\treturn_id = :returnID?i,\n\t\t\t\t\t\trefund_id = :refundID?i\n\t\t\t\t", ['returnID' => $return->id, 'refundID' => $refund->id]); if ($order) { $orderRefund = new OrderRefund($refund); $orderRefund->order = $order; $order->refunds->append($orderRefund); if (!$isStandalone) { $this->_orderRefundCreate->create($orderRefund); } } } } // Create the related exchange item, set the status and move it's stock if ($return->item->exchangeItem) { if (!$return->item->exchangeItem->status) { $return->item->exchangeItem->status = clone $this->_orderItemStatusCollection->get(OrderItemStatuses::HOLD); } if (!$return->item->exchangeItem->stockLocation) { $return->item->exchangeItem->stockLocation = $this->_stockLocations->getRoleLocation(StockLocations::SELL_ROLE); } $return->item->exchangeItem->order = $order; $order->items->append($return->item->exchangeItem); if (!$isStandalone) { $return->item->exchangeItem = $this->_orderItemCreate->create($return->item->exchangeItem); } } // If there is a related order item update its status if ($return->item->orderItem) { $this->_orderItemEdit->updateStatus($return->item->orderItem, $statusCode); } // If this is a standalone return, create the new order if ($isStandalone && $order) { $this->_orderCreate->create($order); } // Get the values for the return item $returnItemValues = array_merge((array) $return->item, ['returnID' => $return->id, 'orderID' => !$isStandalone && $order ? $order->id : null, 'orderItemID' => $return->item->orderItem ? $return->item->orderItem->id : null, 'exchangeItemID' => $return->item->exchangeItem ? $return->item->exchangeItem->id : null, 'noteID' => $return->item->note ? $return->item->note->id : null, 'createdAt' => $return->authorship->createdAt(), 'createdBy' => $return->authorship->createdBy(), 'completedAt' => $statusCode == Statuses::RETURN_COMPLETED ? $return->authorship->createdAt() : null, 'completedBy' => $statusCode == Statuses::RETURN_COMPLETED ? $return->authorship->createdBy() : null, 'statusCode' => $statusCode, 'reason' => $return->item->reason->code, 'returnedStockLocation' => $return->item->returnedStockLocation ? $return->item->returnedStockLocation->name : null, 'returnedStock' => $return->item->returnedStock]); // Create the return item $itemResult = $this->_trans->run("\n\t\t\tINSERT INTO\n\t\t\t\t`return_item`\n\t\t\tSET\n\t\t\t\treturn_id = :returnID?i,\n\t\t\t\torder_id = :orderID?in,\n\t\t\t\titem_id = :orderItemID?in,\n\t\t\t\texchange_item_id = :exchangeItemID?in,\n\t\t\t\tnote_id = :noteID?in,\n\t\t\t\tcreated_at = :createdAt?i,\n\t\t\t\tcreated_by = :createdBy?i,\n\t\t\t\tcompleted_at = :completedAt?in,\n\t\t\t\tcompleted_by = :completedBy?in,\n\t\t\t\tstatus_code = :statusCode?i,\n\t\t\t\treason = :reason?s,\n\t\t\t\taccepted = :accepted?bn,\n\t\t\t\tbalance = :balance?fn,\n\t\t\t\tcalculated_balance = :calculatedBalance?fn,\n\t\t\t\tremaining_balance = :remainingBalance?fn,\n\t\t\t\treturned_value = :returnedValue?f,\n\t\t\t\treturned_stock_location = :returnedStockLocation?s,\n\t\t\t\treturned_stock = :returnedStock?b,\n\t\t\t\tlist_price = :listPrice?f,\n\t\t\t\tactual_price = :actualPrice?f,\n\t\t\t\tnet = :net?f,\n\t\t\t\tdiscount = :discount?f,\n\t\t\t\ttax = :tax?f,\n\t\t\t\tgross = :gross?f,\n\t\t\t\trrp = :rrp?f,\n\t\t\t\ttax_rate = :taxRate?f,\n\t\t\t\tproduct_tax_rate = :productTaxRate?f,\n\t\t\t\ttax_strategy = :taxStrategy?s,\n\t\t\t\tproduct_id = :productID?i,\n\t\t\t\tproduct_name = :productName?s,\n\t\t\t\tunit_id = :unitID?i,\n\t\t\t\tunit_revision = :unitRevision?s,\n\t\t\t\tsku = :sku?s,\n\t\t\t\tbarcode = :barcode?s,\n\t\t\t\toptions = :options?s,\n\t\t\t\tbrand = :brand?s,\n\t\t\t\tweight_grams = :weight?i\n\t\t", $returnItemValues); // Insert item tax rates $tokens = []; $inserts = []; $this->_trans->setIDVariable(self::MYSQL_ITEM_ID_VAR); $idToken = '@' . self::MYSQL_ITEM_ID_VAR; foreach ($return->item->taxes as $type => $rate) { $tokens[] = '(?i, ?s, ?f, ?f)'; $inserts[] = $idToken; $inserts[] = $type; $inserts[] = $rate; $inserts[] = $return->item->net * $rate / 100; } if ($inserts) { $this->_trans->run("INSERT INTO \n\t\t\t\t\t`return_item_tax` (`return_item_id`, `tax_type`, `tax_rate`, `tax_amount`) \n\t\t\t\tVALUES " . implode(',', $tokens) . ";", $inserts); } // set stock manager's properties, because we can't change them anymore // once an adjustment was added... if (true === $return->item->accepted) { if ($return->item->order) { $this->_trans->run("SET @STOCK_NOTE = CONCAT('Order #', CONCAT(:orderID?i, CONCAT(', Return #', :returnID?i)));", ['orderID' => $return->item->order->id, 'returnID' => $return->id]); } else { $this->_trans->run("SET @STOCK_NOTE = CONCAT('Standalone Return #', ?i);", $return->id); } $this->_stockManager->setReason($this->_stockMovementReasons->get(ReturnStockMovementReasons::RETURNED)); } if (!$isStandalone && $return->item->exchangeItem) { $this->_trans->run("SET @STOCK_NOTE = CONCAT('Order #', CONCAT(:orderID?i, CONCAT(', Return #', CONCAT(:returnID?i, ', Exchange Item requested'))));", ['orderID' => $return->item->order->id, 'returnID' => $return->id]); $this->_stockManager->setReason($this->_stockMovementReasons->get(ReturnStockMovementReasons::EXCHANGE_ITEM)); } $this->_stockManager->setNote('@STOCK_NOTE'); // if the return is already accepted, immediatly move returned item back // to stock if (true === $return->item->accepted) { $this->_stockManager->increment($return->item->unit, $return->item->returnedStockLocation); } // Adjust the stock if this is an exchange and the newly created order // doesn't take care of this if (!$isStandalone && $return->item->exchangeItem) { $unit = $return->item->exchangeItem->getUnit(); // Decrement from sell stock $this->_stockManager->decrement($unit, $return->item->exchangeItem->stockLocation); if (null === $return->item->accepted) { // Increment in hold stock $this->_stockManager->increment($unit, $this->_stockLocations->getRoleLocation(StockLocations::HOLD_ROLE)); } } // Fire the created event $event = new Event($return); $event->setTransaction($this->_trans); $return = $this->_eventDispatcher->dispatch(Events::CREATE_END, $event)->getReturn(); // Commit all the changes if (!$this->_transOverridden) { $this->_trans->commit(); $return->id = $this->_trans->getIDVariable(self::MYSQL_ID_VAR); $this->_eventDispatcher->dispatch(Events::CREATE_COMPLETE, $event); } return $return; }