Exemple #1
0
 function calculate($order)
 {
     //============ format data ============//
     $result = array();
     App::import('Lib', 'Shop.ShopConfig');
     $default = array('country' => ShopConfig::load('defaultCountry'), 'region' => ShopConfig::load('defaultRegion'));
     $extract_data = array('country' => array('country', 'ShopOrder.billing_country', 'ShopOrder.shipping_country'), 'region' => array('region', 'ShopOrder.billing_region', 'ShopOrder.shipping_region'), 'shipping_type' => array('shipping_type', 'ShopOrder.shipping_type'));
     if (isset($order['order'])) {
         $order['ShopOrder'] = $order['order'];
     }
     App::import('Lib', 'Shop.SetMulti');
     $data = SetMulti::extractHierarchicMulti($extract_data, $order, array('extractNull' => false));
     $data = array_merge($default, $data);
     //debug($data);
     if (isset($order['ShopOrdersItem'])) {
         $rawItems = $order['ShopOrdersItem'];
     } else {
         if ($order['items']) {
             $rawItems = $order['items'];
         }
     }
     if (empty($rawItems)) {
         return false;
     }
     foreach ($rawItems as $orderItem) {
         $orderItems[] = $this->extractOrderItemData($orderItem, $order);
     }
     $order['ShopOrdersItem'] =& $orderItems;
     $supplements = ShopConfig::getSupplementOpts();
     //debug($supplements);
     $order['Supplements'] =& $supplements;
     //============ calcul subItems ============//
     $orderItems = $this->calculSubItem($orderItems, $order);
     //debug($orderItems);
     //============ calcul promos ============//
     $this->calculPromo($order);
     //debug($orderItems);
     //============ total_items ============//
     $result['total_items'] = 0;
     $result['nb_total'] = 0;
     $excludeFromResult = array('ShopPromotion', 'ShopSubproduct', 'ShopOrdersSubitem');
     if (!empty($orderItems)) {
         foreach ($orderItems as &$orderItem) {
             $result['nb_total'] += $orderItem['nb'];
             $orderItem['total'] = round($orderItem['item_price'], 2) * $orderItem['nb'];
             $result['total_items'] += $orderItem['total'];
             $result['OrderItem'][] = array_diff_key($orderItem, array_flip($excludeFromResult));
         }
     }
     //============ sub_total ============//
     $result['sub_total'] = 0;
     $result['sub_total'] = $result['total_items'];
     //============ Supplements (Shipping, Packing, etc) ============//
     $result['total_supplements'] = 0;
     $exportedSupplements = ShopConfig::getExportedSupplements();
     $defaultType = ShopConfig::getDefaultSupplementName();
     $supplementsData = array();
     if (!empty($data['supplement_choices'])) {
         $supplementsData = (array) $data['supplement_choices'];
     }
     foreach ($exportedSupplements as $name) {
         if (!empty($data[$name . '_type'])) {
             $supplementsData[$name] = $data[$name . '_type'];
         }
     }
     foreach ($supplements as $sName => $supplement) {
         $supplement_choice = array('type' => $defaultType);
         if (!empty($supplementsData[$sName])) {
             if (!is_array($supplementsData[$sName])) {
                 $supplementsData[$sName] = array('type' => $supplementsData[$sName]);
             }
             if (empty($supplementsData[$sName]['type'])) {
                 $supplementsData[$sName]['type'] = $defaultType;
             }
             if (isset($supplements[$sName][$supplementsData[$sName]['type']])) {
                 $supplement_choice = $supplementsData[$sName];
             }
         }
         $supplementItem = $supplement[$supplement_choice['type']];
         if (!empty($supplementItem['applicable'])) {
             if (!is_array($supplementItem['applicable']) || isset($supplementItem['applicable']['component'])) {
                 $supplementItem['applicable'] = array($supplementItem['applicable']);
             }
             foreach ($supplementItem['applicable'] as $funct => $fopt) {
                 //debug($supplementItem);
                 if (is_string($fopt)) {
                     $funct = $fopt;
                     $fopt = array();
                 }
                 $res = null;
                 if (method_exists($this->SupplementMethod, $funct)) {
                     $res = $this->SupplementMethod->{$funct}($fopt, $supplementItem, $order, $supplement_choice, $result);
                 } elseif (!empty($fopt['component'])) {
                     $fopt['params'][] = $supplementItem;
                     $fopt['params'][] = $order;
                     $fopt['params'][] = $supplement_choice;
                     $fopt['params'][] = $result;
                     $res = $this->callExternalfunction($fopt);
                 }
                 if ($res === false) {
                     break 2;
                 }
             }
         }
         $supplementItem['total'] = $supplementItem['price'];
         if (!empty($supplementItem['calcul'])) {
             if (!is_array($supplementItem['calcul']) || isset($supplementItem['calcul']['component'])) {
                 $supplementItem['calcul'] = array($supplementItem['calcul']);
             }
             foreach ($supplementItem['calcul'] as $funct => $fopt) {
                 if (is_string($fopt)) {
                     $funct = $fopt;
                     $fopt = array();
                 }
                 $res = null;
                 if (method_exists($this->SupplementMethod, $funct)) {
                     $res = $this->SupplementMethod->{$funct}($fopt, $supplementItem, $order, $supplement_choice, $result);
                 } elseif (!empty($fopt['component'])) {
                     $fopt['params'][] = $supplementItem;
                     $fopt['params'][] = $order;
                     $fopt['params'][] = $supplement_choice;
                     $fopt['params'][] = $result;
                     $res = $this->callExternalfunction($fopt);
                 }
                 if (!is_null($res)) {
                     if (!is_array($res)) {
                         $res = array('total' => $res);
                     }
                     if (!array_key_exists('total', $res) || $res['total'] === true) {
                         $res['total'] = $supplementItem['total'];
                     } elseif ($res['total'] === false) {
                         $res['total'] = 0;
                     }
                     $supplementItem = array_merge($supplementItem, $res);
                 }
             }
         }
         unset($supplementItem['calculFunction']);
         unset($supplementItem['calcul']);
         $result['supplements'][$sName] = $supplementItem;
         $result['total_supplements'] += $supplementItem['total'];
     }
     //debug($exportedSupplements);
     //debug($result['supplements']);
     foreach ($exportedSupplements as $name) {
         if (isset($result['supplements'][$name]['total'])) {
             $result['total_' . $name] = $result['supplements'][$name]['total'];
         }
     }
     //============ calcul taxes ============//
     $result['total_taxes'] = 0;
     $this->ShopTax = ClassRegistry::init('Shop.ShopTax');
     $rawTaxes = $this->ShopTax->find('all', array('conditions' => array('active' => 1, 'country' => $data['country'], 'OR' => array('region' => $data['region'], 'region IS NULL')), 'order' => array('region' => 'ASC', 'code' => 'ASC')));
     if (!empty($rawTaxes)) {
         /*$general_taxes = array();
         		foreach($taxes as $taxe){
         			$general_taxes[$taxe['ShopTax']['code']] = $taxe['ShopTax'];
         		}
         		
         		$tmpTotal = $result['sub_total'];
         		foreach($general_taxes as $taxe){
         			if($taxe['apply']){
         				if($taxe['apply_prev']){
         					$amount = $tmpTotal * $taxe['rate'];
         				}else{
         					$amount = $result['sub_total'] * $taxe['rate'];
         				}
         				$result['taxes'][$taxe['code']] = $amount;
         				$tmpTotal += $amount;
         				$result['total_taxes'] += $amount;
         			}
         		}*/
         $taxes = array();
         foreach ($rawTaxes as $taxe) {
             $taxes[$taxe['ShopTax']['code']] = $taxe['ShopTax'];
         }
         //debug($taxes);
         $tcheckableItems = $orderItems;
         if (!empty($result['supplements'])) {
             $tcheckableItems = array_merge($orderItems, array_values($result['supplements']));
         }
         foreach ($tcheckableItems as $item) {
             $item['tmpTotal'] = $item['total'];
             if (isset($item['item_tax_applied'])) {
                 $item['tax_applied'] = $item['item_tax_applied'];
             }
             if (!empty($item['tax_applied'])) {
                 foreach ($taxes as $taxe) {
                     //$taxe = $taxe['ShopTax'];
                     $apply = $taxe['apply'];
                     if ($item['tax_applied'] === false) {
                         $apply = false;
                     } elseif (is_array($item['tax_applied'])) {
                         $apply = in_array($taxe['code'], $item['tax_applied']);
                     }
                     if ($apply) {
                         if ($taxe['apply_prev']) {
                             $apply_to = $item['tmpTotal'];
                         } else {
                             $apply_to = $item['total'];
                         }
                         if (!isset($result['taxes'][$taxe['code']]) || !isset($result['taxe_subs'][$taxe['code']])) {
                             $result['taxe_subs'][$taxe['code']] = 0;
                             $result['taxes'][$taxe['code']] = 0;
                         }
                         $result['taxe_subs'][$taxe['code']] += $apply_to;
                         $amount = $apply_to * $taxe['rate'];
                         $result['taxes'][$taxe['code']] += $amount;
                         $item['tmpTotal'] += $amount;
                         $result['total_taxes'] += $amount;
                     }
                 }
             }
         }
     }
     //============ total ============//
     $result['total'] = 0;
     $result['total'] += $result['sub_total'];
     $result['total'] += $result['total_supplements'];
     $result['total'] += $result['total_taxes'];
     $result['total'] = round($result['total'], 2);
     //debug($result);
     return $result;
 }