/** * Checks the stock level for all items in an order **only** if the order's * type is set as an applicable order type. * * If the quantity of a particular unit in the order is greater than the * amount in the defined stock location, the extra items are removed so the * quantity matches the stock level and a flash message is added to the * session. * * @param OrderEvent $event The event object */ public function checkStock(OrderEvent $event) { $order = $event->getOrder(); if (!in_array($order->type, $this->_orderTypes)) { return false; } $addFlash = false; $unitLoader = $this->get('product.unit.loader')->includeInvisible(true)->includeOutOfStock(true); foreach ($order->items->getRows() as $row) { $unit = $unitLoader->getByID($row->first()->unitID); $stock = $unit->getStockForLocation($row->first()->stockLocation); if ($row->getQuantity() > $stock) { $amountToRemove = $row->getQuantity() - $stock; $addFlash = true; foreach ($row as $item) { if ($amountToRemove < 1) { break; } $order->items->remove($item); $amountToRemove--; } } } if ($addFlash) { $this->get('http.session')->getFlashBag()->add('warning', 'Some of the items in your basket are no longer available and have been removed.'); } }
/** * Decrement the additional discount statistics if the order was discounted. * * @param Event\Event $event */ public function recordDiscountRevenueDeleted(OrderEvent $event) { $order = $event->getOrder(); if ($order->totalDiscount > 0) { $this->get('statistics')->get('discounted.sales.gross')->counter->decrement($order->totalGross); $this->get('statistics')->get('discount.gross')->counter->decrement($order->totalDiscount); } }
/** * @param Order\Event\Event $event */ public function sendOrderConfirmationMail(Order\Event\Event $event) { $order = $event->getOrder(); $merchant = $this->get('cfg')->merchant; if ($order->type == 'web') { $payments = $this->get('order.payment.loader')->getByOrder($order); $factory = $this->get('mail.factory.order.confirmation')->set('order', $order)->set('payments', $payments); $this->get('mail.dispatcher')->send($factory->getMessage()); } }
/** * Resets the item's discount and sets the amount to 0 if the discount * is a percentage one. * * @param Event $event The event object */ public function resetDiscountAmounts(Event\Event $event) { foreach ($event->getOrder()->items as $item) { $item->discount = 0; } foreach ($event->getOrder()->discounts as $discount) { if ($discount->percentage) { $discount->amount = 0; } } }
public function updateDiscountEmail(Event\Event $event) { $order = $event->getOrder(); foreach ($order->discounts as $orderDiscount) { if ($orderDiscount->code) { $discount = $this->get('discount.loader')->getByCode($orderDiscount->code); if (in_array($order->userEmail, $discount->emails)) { $this->get('discount.edit')->markEmailAsUsed($discount, $order->userEmail); } } } }
/** * Loop through bundles assigned to order and check that they are still valid. Add discount entities to the order * if the bundles are valid and the discount has not already been added to the order, and remove them if they * are invalid and have been set against the order. * * This method uses the metadata key for the bundle (i.e. 'bundle_[number]') as the ID for the discount entity. * The ID is not saved to the database so this only exists on the basket. This makes it easier to keep track of * which bundle is which. * * @param OrderEvent $event * * @return bool | string */ public function validateBundle(OrderEvent $event) { $bundleIDs = $this->_getBundleIDs($event->getOrder()); if (count($bundleIDs) <= 0) { return false; } $bundles = $this->get('discount.bundle_loader')->getByID($bundleIDs); $validator = $this->get('discount.bundle_validator'); foreach ($bundleIDs as $metadataKey => $bundleID) { if (array_key_exists($metadataKey, $this->_bundleLog)) { // If the metadata key exists in the bundle log, the only reason this method is being called against is // because it has just been added to the order, so we don't need to revalidate the bundle. Instead, we // remove it from the bundle log and break out of the loop. unset($this->_bundleLog[$metadataKey]); break; } $bundle = $bundles[$bundleID]; $bundleExists = $this->get('basket.order')->discounts->exists($metadataKey); if ($bundleExists) { $this->get('basket.order')->discounts->remove($this->get('basket.order')->discounts->get($metadataKey)); } // Validator will throw an exception if the bundle is not valid for the order. Remove the discount if it // has already been set and show a flash message. try { $validator->validate($bundle, $event->getOrder()); $discount = $this->get('discount.bundle.order_discount_factory')->createOrderDiscount($event->getOrder(), $bundle); // Temporarily set ID to keep track of bundles that have had their discounts applied $discount->id = $metadataKey; // Add the bundle ID to the log to prevent an infinite loop $this->_bundleLog[$metadataKey] = $metadataKey; $this->get('basket')->addEntity('discounts', $discount); } catch (Exception\BundleValidationException $e) { if ($bundleExists) { $this->get('http.session')->getFlashBag()->add('warning', $e->getMessage()); } return false; } } return true; }
/** * Listen to when an order has been completed and check to see whether the user that made the order has been * referred. If they have and the reward creation has triggered, it will then validate the order fulfills * any rules set by the constraints. * * If the referral is valid and fulfills the specifications of the reward configuration, a discount code will be * generated and an event will be fired. If for some reason a discount code not be generated, the referrer * will be informed that they are eligible for a discount but its generation was not successful, and that they * should get in touch with the vendor. The referral will be marked with an error status. * * @param OrderEvent $event */ public function giveReward(OrderEvent $event) { $order = $event->getOrder(); $referrals = $this->get('refer.referral.loader')->getByEmail($order->user->email, Statuses::PENDING); if (empty($referrals)) { return; } foreach ($referrals as $referral) { if ($referral->hasTriggered(OrderEvents::CREATE_COMPLETE)) { foreach ($referral->getRewardConfig()->getConstraints() as $constraint) { // Don't bother checking minimum order if currency does not match if ($constraint instanceof MinimumOrder && $order->currencyID !== $constraint->getCurrency()) { continue; } if (false === $constraint->isValid($referral, $event)) { return; } } try { $discount = $this->get('refer.discount.discount_builder')->build($referral); $discount = $this->get('discount.create')->create($discount); if ($discount->id) { // Save again because the emails don't save on create. $discount = $this->get('discount.edit')->save($discount); $event = new DiscountCreateEvent(); $event->setReferral($referral); $event->setDiscount($discount); $this->get('event.dispatcher')->dispatch(DiscountRewardEvents::DISCOUNT_CREATE, $event); } else { throw new DiscountBuildException('Could not save new discount to database'); } } catch (DiscountBuildException $e) { $this->get('refer.discount.failure_mailer')->report($referral, $e); $referral->setStatus(Statuses::ERROR); $this->get('refer.referral.edit')->save($referral); } } } }
/** * @param Order\Order $order * @param Order\CancellationRefund $refund */ public function __construct(Order\Order $order, Order\CancellationRefund $refund) { parent::__construct($order); $this->_refund = $refund; }
/** * Alter analytics view in checkout if possible * * @param OrderEvent $event */ public function switchAnalyticsCheckoutView(OrderEvent $event) { $provider = $this->get('analytics.provider'); if (!$provider instanceof AnalyticsEditableProviderInterface) { return; } $viewRef = 'Message:Mothership:Ecommerce::analytics:' . $provider->getName(); try { $this->get('templating.view_name_parser')->parse($viewRef); } catch (NotAcceptableHttpException $e) { return; } $parentView = $provider->getViewReference(); $params = array_merge($provider->getViewParams(), ['order' => $event->getOrder(), 'parentView' => $parentView]); $provider->setViewReference($viewRef); $provider->setViewParams($params); }
/** * Decrement the products.sales stat for each product ordered. * * @param Event\Event $event */ public function recordProductsSalesDeleted(Event\Event $event) { $dataset = $this->get('statistics')->get('products.sales'); foreach ($event->getOrder()->getItemRows() as $unitID => $items) { $dataset->counter->decrement($unitID, count($items)); } }
/** * Set status of voucher items to received if e-vouchers are enabled * * @param Order\Event\Event $event */ public function setVoucherItemStatus(Order\Event\Event $event) { if ($this->_eVouchersDisabled()) { return; } $vouchers = $this->_getVoucherItems($event->getOrder()->items); if (!empty($vouchers)) { $this->get('order.item.edit')->updateStatus($vouchers, Order\Statuses::RECEIVED); } if (count($vouchers) === count($event->getOrder()->items)) { $this->get('order.edit')->updateStatus($event->getOrder(), Order\Statuses::RECEIVED); } }
public function calculateAllItemsTax(Event\Event $event) { foreach ($event->getOrder()->items as $item) { $this->_calculateTaxForItem($item); } }
/** * Record the time it took since the order was created to complete * fulfillment. * * @param Event\Event $event */ public function recordFulfillmentTime(Event\Event $event) { $order = $event->getOrder(); $fulfillmentTime = time() - $order->authorship->createdAt()->getTimestamp(); $this->get('statistics')->get('fulfillment.time')->counter->set($order->id, $fulfillmentTime); }
/** * Set the totals on the order as the last event before the order is created. * * @param Event $event The event object */ public function setTotals(Event\Event $event) { $order = $event->getOrder(); $order->updateTotals(); }
/** * Constructor. * * @param Order $order * @param Dispatch $dispatch */ public function __construct(Dispatch $dispatch, Order $order = null) { $order = $order ?: $dispatch->order; parent::__construct($order); $this->setDispatch($dispatch); }
/** * If no status has been set on the order yet, set it to the default status * (awaiting dispatch). * * @param Event $event The event object */ public function setDefaultStatus(Event\Event $event) { if (!$event->getOrder()->status) { $event->getOrder()->status = $this->get('order.statuses')->get(Statuses::AWAITING_DISPATCH); } }