cart = $cart; } /** * Get cart. * * @return Cart */ public function getCart() { return $this->cart; } /** * Check if cart is in database. * * @return bool */ public function isCartInDb() { if (!isset($this->cart->id)) { return false; } return (bool) $this->cart->id; } /** * Check if order match module. * * @param string $moduleName * * @return bool */ public function isModuleOfOrderMatched($moduleName) { $order = $this->getFirstOrder(); if ($order) { return $order['module'] === $moduleName; } return false; } /** * Check if order has already been placed * * @return bool result */ public function orderExists() { $sql = 'SELECT count(*) FROM `' . _DB_PREFIX_ . 'orders` WHERE `id_cart` = ' . (int) $this->cart->id; $result = (bool) Db::getInstance()->getValue($sql); return $result; } /** * Get the first order bind to the selected cart. * * @return Order|null Order details */ public function getFirstOrderObject() { $this->getFirstOrder(); return new Order($this->getFirstOrderId()); } /** * Get the first order bind to the selected cart. * * @return array|null Order details */ private function getFirstOrder() { if (!$this->firstOrder) { $sql = 'SELECT * FROM `' . _DB_PREFIX_ . 'orders` WHERE `id_cart` = ' . (int) $this->cart->id . Shop::addSqlRestriction() . ' ORDER BY `id_order` ASC'; $data = Db::getInstance()->getRow($sql); if (!$data) { $this->firstOrder = null; } else { $this->firstOrder = $data; } } return $this->firstOrder; } /** * Get order id. * * @return int|null */ public function getFirstOrderId() { $order = $this->getFirstOrder(); if ($order && $order['id_order']) { return (int) $order['id_order']; } return null; } /** * The reference is the same for all orders from the single cart. * * @return string|null */ public function getOrderReference() { $order = $this->getFirstOrder(); if ($order && $order['reference']) { return $order['reference']; } return null; } /** * Get all orders for the single cart. * * Returns null if there are no orders. * * @return PrestaShopCollection|null */ public function getAllOrders() { $orders = new PrestaShopCollection('Order'); $orders->where('id_cart', '=', $this->cart->id); if (count($orders)) { return $orders; } return null; } /** * Get payments. * * @return PrestaShopCollection|null */ public function getPayments() { /* Any order from the same cart is fine. */ $orderId = $this->getFirstOrderId(); if ($orderId) { $order = new Order($orderId); $payments = $order->getOrderPaymentCollection(); } else { $payments = null; } return $payments; } /** * Return currency for the cart. * * @return CurrencyCore */ public function getCurrency() { if (!$this->currency) { $this->currency = new Currency($this->cart->id_currency); } return $this->currency; } /** * Get extracharge from database. * * @return Przelewy24Extracharge|null */ public function getExtrachargeFromDatabase() { if ($this->orderExists()) { /* For now bind it to the first order in group. */ return Przelewy24Extracharge::prepareByOrderId($this->getFirstOrderId()); } return null; } /** * Get p24 rounded amount. * * @param float $amount * * @return int */ public function formatAmount($amount) { $currency = $this->getCurrency(); if ('0' === (string) $currency->decimals && Configuration::hasKey('PS_PRICE_ROUND_MODE')) { switch (Configuration::get('PS_PRICE_ROUND_MODE')) { case 0: $amount = ceil($amount); break; case 1: $amount = floor($amount); break; case 2: $amount = round($amount); break; } } return (int) round($amount * 100); } /** * Get extra charge amount. * * @return float */ public function computeExtrachargeAmount() { $currency = $this->getCurrency(); $currencySuffix = ('PLN' === $currency->iso_code) ? '' : '_' . $currency->iso_code; $amount = $this->cart->getOrderTotal(true, Cart::BOTH); $extrachargeStatic = Przelewy24ServicePaymentOptions::getExtrachargeStatic($amount, $currencySuffix); return $extrachargeStatic; } /** * Add extra charge. * * @return bool */ public function addExtracharge() { if ($this->getExtrachargeFromDatabase()) { return false; } /* This is amount for all orders from the cart. */ $extrachargeAmount = $this->computeExtrachargeAmount(); if ($extrachargeAmount) { $orderId = $this->getFirstOrderId(); $order = new Order($orderId); $order->total_paid += ($extrachargeAmount / 100); $order->total_paid_tax_incl += ($extrachargeAmount / 100); $order->total_paid_tax_excl += ($extrachargeAmount / 100); try { $order->update(); $extracharge = new Extracharge(); $extracharge->id_order = (int) $order->id; $extracharge->extracharge_amount = ($extrachargeAmount / 100); $extracharge->add(); return true; } catch (Exception $e) { Przelewy24Logger::addLog(__CLASS__ . ' ' . __METHOD__ . ' ' . $e->getMessage(), 1); } } return false; } /** * Return total paid with extracharge. * * @return float */ public function getTotalAmountWithExtraCharge() { if ($this->orderExists()) { /* Extracharge should be included. */ $orders = $this->getAllOrders(); $totalPaid = 0.0; foreach ($orders as $order) { $totalPaid = round($totalPaid + $order->total_paid, 2); } } else { $extrachargeAmount = $this->computeExtrachargeAmount(); $cartTotal = $this->cart->getOrderTotal(true, Cart::BOTH); $totalPaid = round($extrachargeAmount + $cartTotal, 2); } return $totalPaid; } /** * Get total without extra charge * * @return false|float */ public function getTotalAmountWithoutExtraCharge() { if ($this->orderExists()) { $totalPaid = $this->getTotalAmountWithExtraCharge(); $extraCharge = $this->getExtrachargeFromDatabase(); if ($extraCharge) { $extraAmount = $extraCharge->extra_charge_amount / 100; $amountWithout = round($totalPaid - $extraAmount, 2); } else { $amountWithout = $totalPaid; } /* Extracharge should be included. */ $orders = $this->getAllOrders(); $totalPaid = 0.0; foreach ($orders as $order) { $totalPaid = round($totalPaid + $order->total_paid, 2); } } else { $amountWithout = $this->cart->getOrderTotal(true, Cart::BOTH); } return $amountWithout; } /** * Return shipping costs. * * @return float */ public function getShippingCosts() { if ($this->orderExists()) { $orders = $this->getAllOrders(); $shippingCosts = 0.0; foreach ($orders as $order) { $shippingCosts = round($shippingCosts + $order->total_shipping_tax_incl, 2); } } else { $shippingCostsRaw = $this->cart->getPackageShippingCost((int) $this->cart->id_carrier); $shippingCosts = round($shippingCostsRaw, 2); } return $shippingCosts; } /** * Get sum of discounts. * * @return float */ public function getDiscounts() { if ($this->orderExists()) { $orders = $this->getAllOrders(); $totalDiscounts = 0.0; foreach ($orders as $order) { $totalDiscounts = round($totalDiscounts + $order->total_discounts_tax_incl, 2); } } else { $totalDiscountsRaw = $this->cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS); $totalDiscounts = round($totalDiscountsRaw, 2); } return $totalDiscounts; } /** * Get products. * * @return array */ public function getProducts() { if ($this->orderExists()) { $orders = $this->getAllOrders(); $products = []; foreach ($orders as $order) { $products += $order->getProducts(); } } else { $products = $this->cart->getProducts(); } return $products; } /** * Try to get extracharge amount for order in question. * * Return 0 if order is from different cart. * * @param $reference * * @return float */ public function getExtrachargeForOrderReference($reference) { /* Accept first or only */ $rex = '/^([^\\#]+)(\\#1)?$/'; if (preg_match($rex, $reference, $m)) { $order = $this->getFirstOrder(); if ($order['reference'] === $m[1]) { $extraCharge = $this->getExtrachargeFromDatabase(); return $extraCharge->extracharge_amount; } } return 0.0; } /** * Fix extracharge in temporal order representations. * * In few steps there are temporal order objects without extracharge. * This method fix them. * * @param Order $tmpOrder */ public function fixExtrachargeInTmpOrder(Order $tmpOrder) { $orderId = (int) $tmpOrder->id; if (!$orderId) { throw new LogicException('Cannot fix orders without id.'); } $order = new Order($orderId); $tmpOrder->total_paid = $order->total_paid; $tmpOrder->total_paid_tax_incl = $order->total_paid_tax_incl; $tmpOrder->total_paid_tax_excl = $order->total_paid_tax_excl; } /** * @param Przelewy24ServicePaymentOptions $paymentOptions */ public function setPaymentOptons(Przelewy24ServicePaymentOptions $paymentOptions) { $this->paymentOptions = $paymentOptions; } /** * @return Przelewy24ServicePaymentOptions|null */ public function getPaymentOptons() { return $this->paymentOptions; } /** * Check if there's more than one order. * * @return bool */ public function isMultiOrder() { $orders = $this->getAllOrders(); if (null === $orders) { return false; } return $orders->count() > 1; } /** * Update statuses on every order that belongs to this particular cart. * Returns first order for compatibility * * @param int $status * * @return Order */ public function setStateOnOrderCollection($status) { $firstOrder = null; /** @var Order $orderPaid */ foreach ($this->getAllOrders() as $orderPaid) { $orderPaid->setCurrentState($status); if ($orderPaid->id === $this->getFirstOrderId()) { $firstOrder = $orderPaid; } } return $firstOrder; } /** * Rough but working solution to check if cart has extracharge. */ public function hasExtracharge() { $extraCharges = []; foreach ($this->getAllOrders() as $order) { $extraCharge = Przelewy24Extracharge::prepareByOrderId($order->id); $extraCharges[] = !empty($extraCharge->extra_charge_amount) ? $extraCharge->extra_charge_amount : 0; } return array_sum($extraCharges) > 0; } }