* @copyright 2017 My Addons * @license myaddons.io * @version 1.0.0 * @since File available since Release 1.0 */ class PartialShipment extends ObjectModel { /** * @var int id partial shipment */ public $id_partial_shipment; /** * @var int order id */ public $id_order; /** * @var string tracking number */ public $tracking_number; /** * @var string Date */ public $date_add; /** * @see ObjectModel::$definition */ public static $definition = array( 'table' => 'bt_partial_shipment', 'primary' => 'id_partial_shipment', 'fields' => array( 'id_order' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true), 'tracking_number' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => false), 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'required' => true), ), ); public static function getPartialShipmentByOrderId($id_order) { if ($id_order) { $shipments = Db::getInstance()->ExecuteS(' SELECT `id_partial_shipment` FROM `'._DB_PREFIX_.'bt_partial_shipment` WHERE `id_order` ='.(int)$id_order); return ($shipments ? $shipments : false); } return false; } public function getPartialShipmentDetail() { return Db::getInstance()->ExecuteS(' SELECT `id_order_detail`, `quantity` FROM `'._DB_PREFIX_.'bt_partial_shipment_detail` WHERE `id_partial_shipment` ='.(int)$this->id); } public function cloneOrderObject() { $order = new Order((int) $this->id_order); if (Validate::isLoadedObject($order)) { $newOrder = clone $order; //We reset total orders //We recalculate total in btpartialshipment.php $newOrder->id = ''; $newOrder->total_products = 0; $newOrder->total_products_wt = 0; $newOrder->total_discounts = 0; $newOrder->total_discounts_tax_incl = 0; $newOrder->total_discounts_tax_excl = 0; $newOrder->total_paid = 0; $newOrder->total_paid_tax_incl = 0; $newOrder->total_paid_tax_excl = 0; $newOrder->total_paid_real = 0; $newOrder->delivery_number = ''; $newOrder->shipping_number = ''; $newOrder->total_shipping_tax_incl = 0; $newOrder->total_shipping_tax_excl = 0; $newOrder->total_shipping = 0; $newOrder->save(); $id_order_carrier = $this->getIdOrderCarrier(); if ($id_order_carrier) { $orderCarrier = new OrderCarrier((int) $id_order_carrier); if (Validate::isLoadedObject($orderCarrier)) { $newOrderCarrier = clone $orderCarrier; $newOrderCarrier->id = ''; $newOrderCarrier->id_order = (int) $newOrder->id; $newOrderCarrier->id_order_invoice = 0; $newOrderCarrier->shipping_cost_tax_excl = 0; $newOrderCarrier->shipping_cost_tax_incl = 0; $newOrderCarrier->tracking_number = ''; $newOrderCarrier->save(); } } if (Validate::isLoadedObject($newOrder)) { return $newOrder; } } } public function getIdOrderCarrier() { return (int)Db::getInstance()->getValue(' SELECT `id_order_carrier` FROM `'._DB_PREFIX_.'order_carrier` WHERE `id_order` = '.(int) $this->id_order); } public function modifyOrderDetail($newOrder, $orderDetail, $quantityShipped, $generateInvoice = false) { //We update parent order $order = new Order((int) $this->id_order); if (Validate::isLoadedObject($order) && Validate::isLoadedObject($orderDetail)) { if ($this->_deleteAddProduct($newOrder, $orderDetail, $quantityShipped, $generateInvoice)) { return true; } } return false; } protected function _deleteAddProduct($newOrder, $orderDetail, $quantity, $generateInvoice = false) { $order = new Order((int) $this->id_order); $cart = new Cart((int) $order->id_cart); if (Validate::isLoadedObject($order) && Validate::isLoadedObject($orderDetail) && Validate::isLoadedObject($newOrder) && Validate::isLoadedObject($cart)) { //We calculate remaining quantity $quantity = ($orderDetail->product_quantity - $orderDetail->product_quantity_refunded) - $quantity; $product_price_tax_excl = $orderDetail->unit_price_tax_excl * $quantity; $product_price_tax_incl = $orderDetail->unit_price_tax_incl * $quantity; if ($orderDetail->product_weight) { $productWeight = round($orderDetail->product_weight / $quantity, 6); } else { $productWeight = 0; } /* Update order */ $order->total_products -= $product_price_tax_excl; $order->total_products_wt -= $product_price_tax_incl; $order->total_paid -= $product_price_tax_incl; $order->total_paid_tax_incl -= $product_price_tax_incl; $order->total_paid_tax_excl -= $product_price_tax_excl; if ($order->total_paid_real > 0) { $order->total_paid_real -= $product_price_tax_incl; } $fields = array( 'total_shipping', 'total_shipping_tax_excl', 'total_shipping_tax_incl', 'total_products', 'total_products_wt', 'total_paid', 'total_paid_tax_incl', 'total_paid_tax_excl', 'total_paid_real', 'total_discounts', 'total_discounts_tax_incl', 'total_discounts_tax_excl' ); /* Prevent from floating precision issues */ foreach ($fields as $field) { if ($order->{$field} < 0) { $order->{$field} = 0; } } /* Prevent from floating precision issues */ foreach ($fields as $field) { if (version_compare(_PS_VERSION_, '1.6', '<')) { $order->{$field} = number_format($order->{$field}, 2, '.', ''); } else { $order->{$field} = number_format($order->{$field}, _PS_PRICE_COMPUTE_PRECISION_, '.', ''); } } //For new Order $newOrder->total_products += $product_price_tax_excl; $newOrder->total_products_wt += $product_price_tax_incl; $newOrder->total_paid += $product_price_tax_incl; $newOrder->total_paid_tax_incl += $product_price_tax_incl; $newOrder->total_paid_tax_excl += $product_price_tax_excl; if ($order->total_paid_real > 0) { $newOrder->total_paid_real += $product_price_tax_incl; } /* Prevent from floating precision issues */ foreach ($fields as $field) { if ($newOrder->{$field} < 0) { $newOrder->{$field} = 0; } } /* Prevent from floating precision issues */ foreach ($fields as $field) { if (version_compare(_PS_VERSION_, '1.6', '<')) { $newOrder->{$field} = number_format($newOrder->{$field}, 2, '.', ''); } else { $newOrder->{$field} = number_format($newOrder->{$field}, _PS_PRICE_COMPUTE_PRECISION_, '.', ''); } } //We select Parent Order Invoice $orderInvoice = $this->_getInvoiceByNumber((int) $newOrder->invoice_number); // If you don't generate new Invoice we must create the same invoice to parent order with the same number if (!$generateInvoice) { if (Validate::isLoadedObject($orderInvoice)) { //We verify if new order has already invoice if (!$newOrder->hasInvoice()) { $newOrderInvoice = clone $orderInvoice; if (Validate::isLoadedObject($newOrderInvoice)) { $newOrderInvoice->id = ''; $newOrderInvoice->id_order = $newOrder->id; $newOrderInvoice->total_paid_tax_incl = 0; $newOrderInvoice->total_paid_tax_excl = 0; $newOrderInvoice->number = $newOrder->invoice_number; $newOrderInvoice->delivery_number = ''; $newOrderInvoice->save(); } } else { //We get invoice generate $id_order_invoice = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' SELECT `id_order_invoice` FROM `'._DB_PREFIX_.'order_invoice` WHERE id_order = '.(int)$newOrder->id); $newOrderInvoice = new OrderInvoice((int) $id_order_invoice); } } } else { $orderInvoice = $this->_getInvoiceByNumber((int) $order->invoice_number); if (Validate::isLoadedObject($orderInvoice)) { //We retrieve order_payment $orderPayment = OrderPayment::getByInvoiceId((int) $orderInvoice->id); if (Validate::isLoadedObject($orderPayment)) { $orderPayment->amount -= round($newOrder->total_paid, 2); $orderPayment->save(); } } } //We add order detail in new order $newOrderDetail = clone $orderDetail; $newOrderDetail->id = ''; $newOrderDetail->id_order = (int) $newOrder->id; $newOrderDetail->id_order_invoice = ((isset($newOrderInvoice) && $newOrderInvoice->id) ? $newOrderInvoice->id : ''); $newOrderDetail->product_quantity = (int) $quantity; $newOrderDetail->total_price_tax_incl = $product_price_tax_incl; $newOrderDetail->total_price_tax_excl = $product_price_tax_excl; $newOrderDetail->total_shipping_price_tax_incl = 0; $newOrderDetail->total_shipping_price_tax_excl = 0; $newOrderDetail->product_weight = $productWeight * $newOrderDetail->product_quantity; if ($newOrderDetail->save() && $newOrder->save()) { $newOrderDetail->updateTaxAmount($newOrder); } /* Update order detail */ $orderDetail->product_quantity -= (int)$quantity; if ($orderDetail->product_quantity == 0) { if (!$orderDetail->delete()) { return false; } if (count($order->getProductsDetail()) == 0) { $history = new OrderHistory(); $history->id_order = (int)$order->id; $history->changeIdOrderState(Configuration::get('PS_OS_CANCELED'), $order); if (!$history->addWithemail()) { return false; } } } else { $orderDetail->total_price_tax_incl -= $product_price_tax_incl; $orderDetail->total_price_tax_excl -= $product_price_tax_excl; } $orderDetail->save() && $order->save(); if ($generateInvoice) { $orderDetail->updateTaxAmount($order); } return true; } } protected function _getInvoiceByNumber($id_invoice) { if (is_numeric($id_invoice)) { $id_invoice = (int) $id_invoice; } elseif (is_string($id_invoice)) { $matches = array(); if (preg_match('/^(?:'.Configuration::get('PS_INVOICE_PREFIX', Context::getContext()->language->id).')\s*([0-9]+)$/i', $id_invoice, $matches)) { $id_invoice = $matches[1]; } } if (!$id_invoice) { return false; } $sql = 'SELECT `id_order_invoice` FROM `'._DB_PREFIX_.'order_invoice` WHERE number = '.(int) $id_invoice.' ORDER BY `id_order` ASC'; $id_order_invoice = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); return $id_order_invoice ? new OrderInvoice($id_order_invoice) : false; } }