protected function addProductsToOrder($products, $parentId = 0) { if (!is_array($products)) { throw new BadRequestHttpException(); } $order = $this->loadOrder(true); $result = ['errors' => [], 'itemModalPreview' => '']; foreach ($products as $product) { if (!isset($product['id']) || is_null($productModel = Product::findById($product['id']))) { $result['errors'][] = Yii::t('app', 'Product not found.'); continue; } /** @var Product $productModel */ $quantity = isset($product['quantity']) && (double) $product['quantity'] > 0 ? (double) $product['quantity'] : 1; $quantity = $productModel->measure->ceilQuantity($quantity); if ($this->module->allowToAddSameProduct || is_null($orderItem = OrderItem::findOne(['order_id' => $order->id, 'product_id' => $productModel->id, 'parent_id' => 0]))) { $orderItem = new OrderItem(); $orderItem->attributes = ['parent_id' => $parentId, 'order_id' => $order->id, 'product_id' => $productModel->id, 'quantity' => $quantity, 'price_per_pcs' => PriceHelper::getProductPrice($productModel, $order, 1, SpecialPriceList::TYPE_CORE)]; } else { /** @var OrderItem $orderItem */ $orderItem->quantity += $quantity; } if (!$orderItem->save()) { $result['errors'][] = Yii::t('app', 'Cannot save order item.'); } else { // refresh order Order::clearStaticOrder(); $order = $this->loadOrder(false); } if (isset($product['children'])) { $result = ArrayHelper::merge($result, $this->addProductsToOrder($product['children'], $orderItem->id)); } if ($parentId === 0) { $result['itemModalPreview'] .= $this->renderPartial('item-modal-preview', ['order' => $order, 'orderItem' => $orderItem, 'product' => $product]); } } if ($parentId === 0) { $order->calculate(true); } $mainCurrency = Currency::getMainCurrency(); return ArrayHelper::merge($result, ['itemsCount' => $order->items_count, 'success' => true, 'totalPrice' => $mainCurrency->format($order->total_price)]); }
public function actionAddProduct($orderId, $productId, $parentId = 0) { $order = $this->findModel($orderId); /** @var OrderItem $orderItem */ $orderItem = OrderItem::findOne(['product_id' => $productId, 'order_id' => $orderId]); /** @var Product $product */ $product = Product::findById($productId); if (is_null($orderItem)) { $orderItem = new OrderItem(); $orderItem->attributes = ['parent_id' => $parentId, 'order_id' => $order->id, 'product_id' => $product->id, 'quantity' => $product->measure->nominal, 'price_per_pcs' => PriceHelper::getProductPrice($product, $order, 1, SpecialPriceList::TYPE_CORE)]; } else { $orderItem->quantity++; } $orderItem->save(); $order->calculate(true); return $this->redirect(['view', 'id' => $orderId]); }
/** * Calculate order total price and items count with all additional markups. * @param bool $callSave Call save method after calculating. * @param bool $deleteNotActiveProducts Delete Order Item if product is not active or is not exist. * @return bool */ public function calculate($callSave = false, $deleteNotActiveProducts = true) { $itemsCount = 0; foreach ($this->items as $item) { if (null === OrderItem::findOne(['id' => $item->id])) { $item->delete(); continue; } if ($deleteNotActiveProducts && (null === $item->product || $item->product->active == 0)) { $item->delete(); continue; } if (Yii::$app->getModule('shop')->countChildrenProducts == 1) { $itemsCount += Yii::$app->getModule('shop')->countUniqueProductsOnly == 1 ? 1 : $item->quantity; } else { if ($item->parent_id == 0) { $itemsCount += Yii::$app->getModule('shop')->countUniqueProductsOnly == 1 ? 1 : $item->quantity; } } } $event = new OrderCalculateEvent(); $event->order = $this; $event->price = PriceHelper::getOrderPrice($this, SpecialPriceList::TYPE_CORE); EventTriggeringHelper::triggerSpecialEvent($event); $this->items_count = $itemsCount; $this->total_price = PriceHelper::getOrderPrice($this); $event->state = OrderCalculateEvent::AFTER_CALCULATE; EventTriggeringHelper::triggerSpecialEvent($event); TagDependency::invalidate(Yii::$app->cache, ['Session:' . Yii::$app->session->id]); return $callSave ? $this->save(true, ['items_count', 'total_price', 'total_price_with_shipping']) : true; }
/** * @param Order $order * @param array $products * @param $result * @param int $parentId * @return mixed * @throws BadRequestHttpException * @throws NotFoundHttpException */ protected function addProductsToOrder(Order $order, $products = [], $result, $parentId = 0) { $parentId = intval($parentId); if ($parentId !== 0) { // if parent id is set - order item should exist in this order! $parentOrderItem = OrderItem::findOne(['order_id' => $order->id, 'id' => $parentId]); if ($parentOrderItem === null) { throw new BadRequestHttpException(); } } foreach ($products as $product) { $productModel = $addonModel = null; if (!isset($product['id'])) { if (isset($product['addon_id'])) { $addonModel = Addon::findById($product['addon_id']); } } else { $productModel = Product::findById($product['id']); } if ($addonModel === null && $productModel === null) { $result['errors'][] = Yii::t('app', 'Product not found.'); continue; } /** @var Product $productModel */ $quantity = isset($product['quantity']) && (double) $product['quantity'] > 0 ? (double) $product['quantity'] : 1; $condition = ['order_id' => $order->id, 'parent_id' => 0]; if ($productModel !== null) { $condition['product_id'] = $productModel->id; $thisItemModel = $productModel; $quantity = $productModel->measure->ceilQuantity($quantity); } else { $condition['addon_id'] = $addonModel->id; $thisItemModel = $addonModel; if (!$addonModel->can_change_quantity) { $quantity = 1; } } $orderItem = OrderItem::findOne($condition); if ($this->module->allowToAddSameProduct || null === $orderItem) { $orderItem = new OrderItem(); $orderItem->attributes = ['parent_id' => $parentId, 'order_id' => $order->id, 'quantity' => $quantity, 'price_per_pcs' => PriceHelper::getProductPrice($thisItemModel, $order, 1, SpecialPriceList::TYPE_CORE)]; if (empty($product['customName']) === false) { $orderItem->custom_name = $product['customName']; } if ($productModel !== null) { $orderItem->product_id = $thisItemModel->id; } else { $orderItem->addon_id = $thisItemModel->id; } } else { /** @var OrderItem $orderItem */ if ($addonModel !== null && !$addonModel->can_change_quantity) { // quantity can not be changed $quantity = 0; } if (null !== $orderItem) { $orderItem->quantity += $quantity; } } if (false === $orderItem->save()) { $result['errors'][] = Yii::t('app', 'Cannot save order item.'); } else { // refresh order Order::clearStaticOrder(); $order = $this->loadOrder(false); } if (null !== $productModel) { $result['products'][] = ['model' => $productModel, 'quantity' => $quantity, 'orderItem' => $orderItem]; } if (isset($product['children']) && is_array($product['children'])) { $result = $this->addProductsToOrder($order, $product['children'], $result, $orderItem->id); } } return $result; }