/** * Order process controller */ public function autoStep() { if ($this->step >= 2 && (!$this->context->cart->id_address_delivery || !$this->context->cart->id_address_invoice)) { Tools::redirect('index.php?controller=order&step=1'); } if ($this->step > 2 && !$this->context->cart->isVirtualCart()) { $redirect = false; if (count($this->context->cart->getDeliveryOptionList()) == 0) { $redirect = true; } if (!$this->context->cart->isMultiAddressDelivery()) { foreach ($this->context->cart->getProducts() as $product) { if (!in_array($this->context->cart->id_carrier, Carrier::getAvailableCarrierList(new Product($product['id_product']), null, $this->context->cart->id_address_delivery))) { $redirect = true; break; } } } if ($redirect) { Tools::redirect('index.php?controller=order&step=2'); } } $delivery = new Address((int) $this->context->cart->id_address_delivery); $invoice = new Address((int) $this->context->cart->id_address_invoice); if ($delivery->deleted || $invoice->deleted) { if ($delivery->deleted) { unset($this->context->cart->id_address_delivery); } if ($invoice->deleted) { unset($this->context->cart->id_address_invoice); } Tools::redirect('index.php?controller=order&step=1'); } }
/** * Get all the ids of the delivery addresses without carriers * * @param bool $return_collection Return a collection * * @return array Array of address id or of address object */ public function getDeliveryAddressesWithoutCarriers($return_collection = false) { $addresses_without_carriers = array(); foreach ($this->getProducts() as $product) { if (!in_array($product['id_address_delivery'], $addresses_without_carriers) && !count(Carrier::getAvailableCarrierList(new Product($product['id_product']), null, $product['id_address_delivery']))) { $addresses_without_carriers[] = $product['id_address_delivery']; } } if (!$return_collection) { return $addresses_without_carriers; } else { $addresses_instance_without_carriers = array(); foreach ($addresses_without_carriers as $id_address) { $addresses_instance_without_carriers[] = new Address($id_address); } return $addresses_instance_without_carriers; } }
protected function processChangeProductAddressDelivery() { if (!Configuration::get('PS_ALLOW_MULTISHIPPING')) { return; } $old_id_address_delivery = (int) Tools::getValue('old_id_address_delivery'); $new_id_address_delivery = (int) Tools::getValue('new_id_address_delivery'); if (!count(Carrier::getAvailableCarrierList(new Product($this->id_product), null, $new_id_address_delivery))) { $this->ajaxDie(Tools::jsonEncode(array('hasErrors' => true, 'error' => Tools::displayError('It is not possible to deliver this product to the selected address.', false)))); } $this->context->cart->setProductAddressDelivery($this->id_product, $this->id_product_attribute, $old_id_address_delivery, $new_id_address_delivery); }
public function getPackageList($flush = false) { static $cache = array(); if (isset($cache[(int) $this->id . '_' . (int) $this->id_address_delivery]) && $cache[(int) $this->id . '_' . (int) $this->id_address_delivery] !== false && !$flush) { return $cache[(int) $this->id . '_' . (int) $this->id_address_delivery]; } $product_list = $this->getProducts(); // Step 1 : Get product informations (warehouse_list and carrier_list), count warehouse // Determine the best warehouse to determine the packages // For that we count the number of time we can use a warehouse for a specific delivery address $warehouse_count_by_address = array(); $warehouse_carrier_list = array(); $stock_management_active = Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'); foreach ($product_list as &$product) { if ((int) $product['id_address_delivery'] == 0) { $product['id_address_delivery'] = (int) $this->id_address_delivery; } if (!isset($warehouse_count_by_address[$product['id_address_delivery']])) { $warehouse_count_by_address[$product['id_address_delivery']] = array(); } $product['warehouse_list'] = array(); if ($stock_management_active && ((int) $product['advanced_stock_management'] == 1 || Pack::usesAdvancedStockManagement((int) $product['id_product']))) { $warehouse_list = Warehouse::getProductWarehouseList($product['id_product'], $product['id_product_attribute'], $this->id_shop); if (count($warehouse_list) == 0) { $warehouse_list = Warehouse::getProductWarehouseList($product['id_product'], $product['id_product_attribute']); } // Does the product is in stock ? // If yes, get only warehouse where the product is in stock $warehouse_in_stock = array(); $manager = StockManagerFactory::getManager(); foreach ($warehouse_list as $key => $warehouse) { $product_real_quantities = $manager->getProductRealQuantities($product['id_product'], $product['id_product_attribute'], array($warehouse['id_warehouse']), true); if ($product_real_quantities > 0 || Pack::isPack((int) $product['id_product'])) { $warehouse_in_stock[] = $warehouse; } } if (!empty($warehouse_in_stock)) { $warehouse_list = $warehouse_in_stock; $product['in_stock'] = true; } else { $product['in_stock'] = false; } } else { //simulate default warehouse $warehouse_list = array(0); $product['in_stock'] = StockAvailable::getQuantityAvailableByProduct($product['id_product'], $product['id_product_attribute']) > 0; } foreach ($warehouse_list as $warehouse) { if (!isset($warehouse_carrier_list[$warehouse['id_warehouse']])) { $warehouse_object = new Warehouse($warehouse['id_warehouse']); $warehouse_carrier_list[$warehouse['id_warehouse']] = $warehouse_object->getCarriers(); } $product['warehouse_list'][] = $warehouse['id_warehouse']; if (!isset($warehouse_count_by_address[$product['id_address_delivery']][$warehouse['id_warehouse']])) { $warehouse_count_by_address[$product['id_address_delivery']][$warehouse['id_warehouse']] = 0; } $warehouse_count_by_address[$product['id_address_delivery']][$warehouse['id_warehouse']]++; } } unset($product); arsort($warehouse_count_by_address); // Step 2 : Group product by warehouse $grouped_by_warehouse = array(); foreach ($product_list as &$product) { if (!isset($grouped_by_warehouse[$product['id_address_delivery']])) { $grouped_by_warehouse[$product['id_address_delivery']] = array('in_stock' => array(), 'out_of_stock' => array()); } $product['carrier_list'] = array(); $id_warehouse = 0; foreach ($warehouse_count_by_address[$product['id_address_delivery']] as $id_war => $val) { if (in_array((int) $id_war, $product['warehouse_list'])) { $product['carrier_list'] = array_merge($product['carrier_list'], Carrier::getAvailableCarrierList(new Product($product['id_product']), $id_war, $product['id_address_delivery'], null, $this)); if (!$id_warehouse) { $id_warehouse = (int) $id_war; } } } if (!isset($grouped_by_warehouse[$product['id_address_delivery']]['in_stock'][$id_warehouse])) { $grouped_by_warehouse[$product['id_address_delivery']]['in_stock'][$id_warehouse] = array(); $grouped_by_warehouse[$product['id_address_delivery']]['out_of_stock'][$id_warehouse] = array(); } if (!$this->allow_seperated_package) { $key = 'in_stock'; } else { $key = $product['in_stock'] ? 'in_stock' : 'out_of_stock'; } if (empty($product['carrier_list'])) { $product['carrier_list'] = array(0); } $grouped_by_warehouse[$product['id_address_delivery']][$key][$id_warehouse][] = $product; } unset($product); // Step 3 : grouped product from grouped_by_warehouse by available carriers $grouped_by_carriers = array(); foreach ($grouped_by_warehouse as $id_address_delivery => $products_in_stock_list) { if (!isset($grouped_by_carriers[$id_address_delivery])) { $grouped_by_carriers[$id_address_delivery] = array('in_stock' => array(), 'out_of_stock' => array()); } foreach ($products_in_stock_list as $key => $warehouse_list) { if (!isset($grouped_by_carriers[$id_address_delivery][$key])) { $grouped_by_carriers[$id_address_delivery][$key] = array(); } foreach ($warehouse_list as $id_warehouse => $product_list) { if (!isset($grouped_by_carriers[$id_address_delivery][$key][$id_warehouse])) { $grouped_by_carriers[$id_address_delivery][$key][$id_warehouse] = array(); } foreach ($product_list as $product) { $package_carriers_key = implode(',', $product['carrier_list']); if (!isset($grouped_by_carriers[$id_address_delivery][$key][$id_warehouse][$package_carriers_key])) { $grouped_by_carriers[$id_address_delivery][$key][$id_warehouse][$package_carriers_key] = array('product_list' => array(), 'carrier_list' => $product['carrier_list'], 'warehouse_list' => $product['warehouse_list']); } $grouped_by_carriers[$id_address_delivery][$key][$id_warehouse][$package_carriers_key]['product_list'][] = $product; } } } } $package_list = array(); // Step 4 : merge product from grouped_by_carriers into $package to minimize the number of package foreach ($grouped_by_carriers as $id_address_delivery => $products_in_stock_list) { if (!isset($package_list[$id_address_delivery])) { $package_list[$id_address_delivery] = array('in_stock' => array(), 'out_of_stock' => array()); } foreach ($products_in_stock_list as $key => $warehouse_list) { if (!isset($package_list[$id_address_delivery][$key])) { $package_list[$id_address_delivery][$key] = array(); } // Count occurance of each carriers to minimize the number of packages $carrier_count = array(); foreach ($warehouse_list as $id_warehouse => $products_grouped_by_carriers) { foreach ($products_grouped_by_carriers as $data) { foreach ($data['carrier_list'] as $id_carrier) { if (!isset($carrier_count[$id_carrier])) { $carrier_count[$id_carrier] = 0; } $carrier_count[$id_carrier]++; } } } arsort($carrier_count); foreach ($warehouse_list as $id_warehouse => $products_grouped_by_carriers) { if (!isset($package_list[$id_address_delivery][$key][$id_warehouse])) { $package_list[$id_address_delivery][$key][$id_warehouse] = array(); } foreach ($products_grouped_by_carriers as $data) { foreach ($carrier_count as $id_carrier => $rate) { if (in_array($id_carrier, $data['carrier_list'])) { if (!isset($package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier])) { $package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier] = array('carrier_list' => $data['carrier_list'], 'warehouse_list' => $data['warehouse_list'], 'product_list' => array()); } $package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier]['carrier_list'] = array_intersect($package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier]['carrier_list'], $data['carrier_list']); $package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier]['product_list'] = array_merge($package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier]['product_list'], $data['product_list']); break; } } } } } } // Step 5 : Reduce depth of $package_list $final_package_list = array(); foreach ($package_list as $id_address_delivery => $products_in_stock_list) { if (!isset($final_package_list[$id_address_delivery])) { $final_package_list[$id_address_delivery] = array(); } foreach ($products_in_stock_list as $key => $warehouse_list) { foreach ($warehouse_list as $id_warehouse => $products_grouped_by_carriers) { foreach ($products_grouped_by_carriers as $data) { $final_package_list[$id_address_delivery][] = array('product_list' => $data['product_list'], 'carrier_list' => $data['carrier_list'], 'warehouse_list' => $data['warehouse_list'], 'id_warehouse' => $id_warehouse); } } } } //принудительно все на 1 склад чтоб не создавалось 2 заказа if (count($final_package_list[$this->id_address_delivery]) > 1) { foreach ($final_package_list[$this->id_address_delivery] as $k => &$part) { if ($k == 0) { continue; } foreach ($final_package_list[$this->id_address_delivery][$k]['product_list'] as $product_list_item) { $final_package_list[$this->id_address_delivery][0]['product_list'][] = $product_list_item; } unset($final_package_list[$this->id_address_delivery][$k]); } } $cache[(int) $this->id] = $final_package_list; return $final_package_list; }
public function getPackageList($flush = false) { static $cache = array(); if (isset($cache[(int) $this->cart_id . '_' . (int) $this->address_delivery_id]) && $cache[(int) $this->cart_id . '_' . (int) $this->address_delivery_id] !== false && !$flush) { return $cache[(int) $this->cart_id . '_' . (int) $this->address_delivery_id]; } $product_list = $this->getProducts(); // Step 1 : Get product informations (warehouse_list and carrier_list), count warehouse // Determine the best warehouse to determine the packages // For that we count the number of time we can use a warehouse for a specific delivery address $warehouse_count_by_address = array(); $warehouse_carrier_list = array(); $stock_management_active = JeproshopSettingModelSetting::getValue('advanced_stock_management'); foreach ($product_list as &$product) { if ((int) $product->address_delivery_id == 0) { $product->address_delivery_id = (int) $this->address_delivery_id; } if (!isset($warehouse_count_by_address[$product->address_delivery_id])) { $warehouse_count_by_address[$product->address_delivery_id] = array(); } $product->warehouse_list = array(); if ($stock_management_active && ((int) $product['advanced_stock_management'] == 1 || Pack::usesAdvancedStockManagement((int) $product->product_id))) { $warehouse_list = Warehouse::getProductWarehouseList($product->product_id, $product->roduct_attribute_id, $this->shop_id); if (count($warehouse_list) == 0) { $warehouse_list = Warehouse::getProductWarehouseList($product->product_id, $product->roduct_attribute_id); } // Does the product is in stock ? // If yes, get only warehouse where the product is in stock $warehouse_in_stock = array(); $manager = StockManagerFactory::getManager(); foreach ($warehouse_list as $key => $warehouse) { $product_real_quantities = $manager->getProductRealQuantities($product->product_id, $product->product_attribute_id, array($warehouse->warehouse_id), true); if ($product_real_quantities > 0 || Pack::isPack((int) $product->product_id)) { $warehouse_in_stock[] = $warehouse; } } if (!empty($warehouse_in_stock)) { $warehouse_list = $warehouse_in_stock; $product->in_stock = true; } else { $product->in_stock = false; } } else { //simulate default warehouse $warehouse_list = array(0); $product->in_stock = StockAvailable::getQuantityAvailableByProduct($product->product_id, $product->product_attribute_id) > 0; } foreach ($warehouse_list as $warehouse) { if (!isset($warehouse_carrier_list[$warehouse->warehouse_id])) { $warehouse_object = new JeproshopWarehouseModelWarehouse($warehouse->warehouse_id); $warehouse_carrier_list[$warehouse->warehouse_id] = $warehouse_object->getCarriers(); } $product->warehouse_list[] = $warehouse->warehouse_id; if (!isset($warehouse_count_by_address[$product->address_delivery_id][$warehouse->warehouse_id])) { $warehouse_count_by_address[$product->address_delivery_id][$warehouse->warehouse_id] = 0; } $warehouse_count_by_address[$product->address_delivery_id][$warehouse->warehouse_id]++; } } unset($product); arsort($warehouse_count_by_address); // Step 2 : Group product by warehouse $grouped_by_warehouse = array(); foreach ($product_list as &$product) { if (!isset($grouped_by_warehouse[$product->address_delivery_id])) { $grouped_by_warehouse[$product->address_delivery_id] = array('in_stock' => array(), 'out_of_stock' => array()); } $product->carrier_list = array(); $warehouse_id = 0; foreach ($warehouse_count_by_address[$product->address_delivery_id] as $war_id => $val) { if (in_array((int) $war_id, $product->warehouse_list)) { $product->carrier_list = array_merge($product->carrier_list, Carrier::getAvailableCarrierList(new Product($product->product_id), $war_id, $product->address_delivery_id, null, $this)); if (!$warehouse_id) { $warehouse_id = (int) $war_id; } } } if (!isset($grouped_by_warehouse[$product->address_delivery_id]['in_stock'][$warehouse_id])) { $grouped_by_warehouse[$product->address_delivery_id]['in_stock'][$warehouse_id] = array(); $grouped_by_warehouse[$product->address_delivery_id]['out_of_stock'][$warehouse_id] = array(); } if (!$this->allow_separated_package) { $key = 'in_stock'; } else { $key = $product->in_stock ? 'in_stock' : 'out_of_stock'; } if (empty($product->carrier_list)) { $product->carrier_list = array(0); } $grouped_by_warehouse[$product->address_delivery_id][$key][$warehouse_id][] = $product; } unset($product); // Step 3 : grouped product from grouped_by_warehouse by available carriers $grouped_by_carriers = array(); foreach ($grouped_by_warehouse as $address_delivery_id => $products_in_stock_list) { if (!isset($grouped_by_carriers[$address_delivery_id])) { $grouped_by_carriers[$address_delivery_id] = array('in_stock' => array(), 'out_of_stock' => array()); } foreach ($products_in_stock_list as $key => $warehouse_list) { if (!isset($grouped_by_carriers[$address_delivery_id][$key])) { $grouped_by_carriers[$address_delivery_id][$key] = array(); } foreach ($warehouse_list as $warehouse_id => $product_list) { if (!isset($grouped_by_carriers[$address_delivery_id][$key][$warehouse_id])) { $grouped_by_carriers[$address_delivery_id][$key][$warehouse_id] = array(); } foreach ($product_list as $product) { $package_carriers_key = implode(',', $product->carrier_list); if (!isset($grouped_by_carriers[$address_delivery_id][$key][$warehouse_id][$package_carriers_key])) { $grouped_by_carriers[$address_delivery_id][$key][$warehouse_id][$package_carriers_key] = array('product_list' => array(), 'carrier_list' => $product->carrier_list, 'warehouse_list' => $product->warehouse_list); } $grouped_by_carriers[$address_delivery_id][$key][$warehouse_id][$package_carriers_key]['product_list'][] = $product; } } } } $package_list = array(); // Step 4 : merge product from grouped_by_carriers into $package to minimize the number of package foreach ($grouped_by_carriers as $address_delivery_id => $products_in_stock_list) { if (!isset($package_list[$address_delivery_id])) { $package_list[$address_delivery_id] = array('in_stock' => array(), 'out_of_stock' => array()); } foreach ($products_in_stock_list as $key => $warehouse_list) { if (!isset($package_list[$address_delivery_id][$key])) { $package_list[$address_delivery_id][$key] = array(); } // Count occurrence of each carriers to minimize the number of packages $carrier_count = array(); foreach ($warehouse_list as $warehouse_id => $products_grouped_by_carriers) { foreach ($products_grouped_by_carriers as $data) { foreach ($data['carrier_list'] as $carrier_id) { if (!isset($carrier_count[$carrier_id])) { $carrier_count[$carrier_id] = 0; } $carrier_count[$carrier_id]++; } } } arsort($carrier_count); foreach ($warehouse_list as $warehouse_id => $products_grouped_by_carriers) { if (!isset($package_list[$address_delivery_id][$key][$warehouse_id])) { $package_list[$address_delivery_id][$key][$warehouse_id] = array(); } foreach ($products_grouped_by_carriers as $data) { foreach ($carrier_count as $carrier_id => $rate) { if (in_array($carrier_id, $data['carrier_list'])) { if (!isset($package_list[$address_delivery_id][$key][$warehouse_id][$carrier_id])) { $package_list[$address_delivery_id][$key][$warehouse_id][$carrier_id] = array('carrier_list' => $data['carrier_list'], 'warehouse_list' => $data['warehouse_list'], 'product_list' => array()); } $package_list[$address_delivery_id][$key][$warehouse_id][$carrier_id]['carrier_list'] = array_intersect($package_list[$address_delivery_id][$key][$warehouse_id][$carrier_id]['carrier_list'], $data['carrier_list']); $package_list[$address_delivery_id][$key][$warehouse_id][$carrier_id]['product_list'] = array_merge($package_list[$address_delivery_id][$key][$warehouse_id][$carrier_id]['product_list'], $data['product_list']); break; } } } } } } // Step 5 : Reduce depth of $package_list $final_package_list = array(); foreach ($package_list as $address_delivery_id => $products_in_stock_list) { if (!isset($final_package_list[$address_delivery_id])) { $final_package_list[$address_delivery_id] = array(); } foreach ($products_in_stock_list as $key => $warehouse_list) { foreach ($warehouse_list as $warehouse_id => $products_grouped_by_carriers) { foreach ($products_grouped_by_carriers as $data) { $final_package_list[$address_delivery_id][] = array('product_list' => $data['product_list'], 'carrier_list' => $data['carrier_list'], 'warehouse_list' => $data['warehouse_list'], 'warehouse_id' => $warehouse_id); } } } } $cache[(int) $this->cart_id] = $final_package_list; return $final_package_list; }
/** * Order process controller */ public function autoStep() { $app = JFactory::getApplication(); if (($this->current_step == 'address' || $this->current_step == 'delivery' || $this->current_step == 'payment') && (!$this->context->cart->address_delivery_id || !$this->context->cart->address_invoice_id)) { $app->redirect('index.php?option=com_jeproshop&view=order&step=summary'); } if (($this->current_step == 'delivery' || $this->current_step == 'payment') && !$this->context->cart->isVirtualCart()) { $redirect = false; if (count($this->context->cart->getDeliveryOptionList()) == 0) { $redirect = true; } if (!$this->context->cart->isMultiAddressDelivery()) { foreach ($this->context->cart->getProducts() as $product) { if (!in_array($this->context->cart->carrier_id, Carrier::getAvailableCarrierList(new Product($product['id_product']), null, $this->context->cart->id_address_delivery))) { $redirect = true; break; } } } if ($redirect) { Tools::redirect('index.php?option=com_jeproshop&view=order&step=address'); } } $delivery = new JeproshopAddressModelAddress((int) $this->context->cart->address_delivery_id); $invoice = new JeproshopAddressModelAddress((int) $this->context->cart->address_invoice_id); if ($delivery->deleted || $invoice->deleted) { if ($delivery->deleted) { unset($this->context->cart->address_delivery_id); } if ($invoice->deleted) { unset($this->context->cart->address_invoice_id); } $app->redirect('index.php?option=com_jeproshop&view=order&step=summary'); } }