332 lines
13 KiB
PHP
332 lines
13 KiB
PHP
<?php
|
|
/**
|
|
* Module Partial Shipment - Main file
|
|
*
|
|
* @author My Addons <contact@myaddons.io>
|
|
* @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;
|
|
}
|
|
}
|