/**
  * 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');
     }
 }
Example #2
0
 /**
  * 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);
 }
Example #4
0
 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;
 }
Example #5
0
 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;
 }
Example #6
0
 /**
  * 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');
     }
 }