function zen_add_tax($price, $tax) { global $currencies; if (DISPLAY_PRICE_WITH_TAX == 'true' && $tax > 0) { return zen_round($price, $currencies->currencies[DEFAULT_CURRENCY]['decimal_places']) + zen_calculate_tax($price, $tax); } else { return zen_round($price, $currencies->currencies[DEFAULT_CURRENCY]['decimal_places']); } }
function calculate_deductions($order_total) { global $db, $order; $od_amount = array(); if ($order_total == 0) { return $od_amount; } $orderTotal = $this->get_order_total(); $orderTotalTax = $orderTotal['tax']; $taxGroups = $orderTotal['taxGroups']; $group_query = $db->Execute("select customers_group_pricing from " . TABLE_CUSTOMERS . " where customers_id = '" . (int) $_SESSION['customer_id'] . "'"); if ($group_query->fields['customers_group_pricing'] != '0') { $group_discount = $db->Execute("select group_name, group_percentage from " . TABLE_GROUP_PRICING . "\n where group_id = '" . (int) $group_query->fields['customers_group_pricing'] . "'"); $gift_vouchers = $_SESSION['cart']->gv_only(); $discount = ($orderTotal['total'] - $gift_vouchers) * $group_discount->fields['group_percentage'] / 100; // echo "discout = $discount<br>"; $od_amount['total'] = round($discount, 2); $ratio = $od_amount['total'] / $order_total; /** * when calculating the ratio add some insignificant values to stop divide by zero errors */ switch ($this->calculate_tax) { case 'None': if ($this->include_tax) { reset($order->info['tax_groups']); foreach ($order->info['tax_groups'] as $key => $value) { $od_amount['tax_groups'][$key] = $order->info['tax_groups'][$key] * $ratio; } } break; case 'Standard': if ($od_amount['total'] >= $order_total) { $ratio = 1; } $adjustedTax = $orderTotalTax * $ratio; if ($order->info['tax'] == 0) { return $od_amount; } $ratioTax = $orderTotalTax != 0 ? $adjustedTax / $orderTotalTax : 0; reset($order->info['tax_groups']); $tax_deduct = 0; foreach ($taxGroups as $key => $value) { $od_amount['tax_groups'][$key] = $value * $ratioTax; $tax_deduct += $od_amount['tax_groups'][$key]; } $od_amount['tax'] = $tax_deduct; break; case 'Credit Note': $tax_rate = zen_get_tax_rate($this->tax_class); $od_amount['tax'] = zen_calculate_tax($od_amount['total'], $tax_rate); $tax_description = zen_get_tax_description($this->tax_class); $od_amount['tax_groups'][$tax_description] = $od_amount['tax']; break; } } return $od_amount; }
function process() { global $order, $currencies, $cod_cost, $cod_country, $shipping; if ($this->enabled == true) { //Will become true, if cod can be processed. $cod_country = false; //check if payment method is cod. If yes, check if cod is possible. if ($_SESSION['payment'] == 'cod') { //process installed shipping modules if (substr_count($_SESSION['shipping']['id'], 'flat') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_FLAT); } if (substr_count($_SESSION['shipping']['id'], 'free') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_FREE); } if (substr_count($_SESSION['shipping']['id'], 'freeshipper') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_FREESHIPPER); } if (substr_count($_SESSION['shipping']['id'], 'freeoptions') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_FREEOPTIONS); } if (substr_count($_SESSION['shipping']['id'], 'item') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_ITEM); } if (substr_count($_SESSION['shipping']['id'], 'perweightunit') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_PERWEIGHTUNIT); } if (substr_count($_SESSION['shipping']['id'], 'table') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_TABLE); } if (substr_count($_SESSION['shipping']['id'], 'ups') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_UPS); } if (substr_count($_SESSION['shipping']['id'], 'usps') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_USPS); } if (substr_count($_SESSION['shipping']['id'], 'fedex') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_FEDEX); } if (substr_count($_SESSION['shipping']['id'], 'zones') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_ZONES); } if (substr_count($_SESSION['shipping']['id'], 'ap') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_AP); } if (substr_count($_SESSION['shipping']['id'], 'dp') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_DP); } //satt inn av Pompel if (substr_count($_SESSION['shipping']['id'], 'servicepakke') != 0) { $cod_zones = preg_split("/[:,]/", MODULE_ORDER_TOTAL_COD_FEE_SERVICEPAKKE); } for ($i = 0; $i < count($cod_zones); $i++) { if ($cod_zones[$i] == $order->delivery['country']['iso_code_2']) { $cod_cost = $cod_zones[$i + 1]; $cod_country = true; //print('match' . $i . ': ' . $cod_cost); break; } elseif ($cod_zones[$i] == '00') { $cod_cost = $cod_zones[$i + 1]; $cod_country = true; //print('match' . $i . ': ' . $cod_cost); break; } else { //print('no match'); } $i++; } } else { //COD selected, but no shipping module which offers COD } if ($cod_country) { $cod_tax_address = zen_get_tax_locations(); $tax = zen_get_tax_rate(MODULE_ORDER_TOTAL_COD_TAX_CLASS, $cod_tax_address['country_id'], $cod_tax_address['zone_id']); $order->info['total'] += $cod_cost; if ($tax > 0) { $tax_description = zen_get_tax_description(MODULE_ORDER_TOTAL_COD_TAX_CLASS, $cod_tax_address['country_id'], $cod_tax_address['zone_id']); $order->info['tax'] += zen_calculate_tax($cod_cost, $tax); $order->info['tax_groups'][$tax_description] += zen_calculate_tax($cod_cost, $tax); $order->info['total'] += zen_calculate_tax($cod_cost, $tax); if (DISPLAY_PRICE_WITH_TAX == 'true') { $cod_cost += zen_calculate_tax($cod_cost, $tax); } } $this->output[] = array('title' => $this->title . ':', 'text' => $currencies->format($cod_cost, true, $order->info['currency'], $order->info['currency_value']), 'value' => $cod_cost); } else { //Following code should be improved if we can't get the shipping modules disabled, who don't allow COD // as well as countries who do not have cod // $this->output[] = array('title' => $this->title . ':', // 'text' => 'No COD for this module.', // 'value' => ''); } } }
function zen_add_tax($price, $tax) { global $currencies; if (DISPLAY_PRICE_WITH_TAX == 'true' && $tax > 0) { return $price + zen_calculate_tax($price, $tax); } else { return $price; } }
function process() { global $order, $currencies; if (MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING == 'true') { switch (MODULE_ORDER_TOTAL_SHIPPING_DESTINATION) { case 'national': if ($order->delivery['country_id'] == STORE_COUNTRY) { $pass = true; } break; case 'international': if ($order->delivery['country_id'] != STORE_COUNTRY) { $pass = true; } break; case 'both': $pass = true; break; default: $pass = false; break; } if ($pass == true && $order->info['total'] - $order->info['shipping_cost'] >= MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_OVER) { $order->info['shipping_method'] = $this->title; $order->info['total'] -= $order->info['shipping_cost']; $order->info['shipping_cost'] = 0; } } $module = substr($_SESSION['shipping']['id'], 0, strpos($_SESSION['shipping']['id'], '_')); if (zen_not_null($order->info['shipping_method'])) { if ($GLOBALS[$module]->tax_class > 0) { if (!defined($GLOBALS[$module]->tax_basis)) { $shipping_tax_basis = STORE_SHIPPING_TAX_BASIS; } else { $shipping_tax_basis = $GLOBALS[$module]->tax_basis; } if ($shipping_tax_basis == 'Billing') { $shipping_tax = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); $shipping_tax_description = zen_get_tax_description($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); } elseif ($shipping_tax_basis == 'Shipping') { $shipping_tax = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); $shipping_tax_description = zen_get_tax_description($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); } else { if (STORE_ZONE == $order->billing['zone_id']) { $shipping_tax = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); $shipping_tax_description = zen_get_tax_description($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); } elseif (STORE_ZONE == $order->delivery['zone_id']) { $shipping_tax = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); $shipping_tax_description = zen_get_tax_description($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); } else { $shipping_tax = 0; } } $order->info['tax'] += zen_calculate_tax($order->info['shipping_cost'], $shipping_tax); $order->info['tax_groups']["{$shipping_tax_description}"] += zen_calculate_tax($order->info['shipping_cost'], $shipping_tax); $order->info['total'] += zen_calculate_tax($order->info['shipping_cost'], $shipping_tax); if (DISPLAY_PRICE_WITH_TAX == 'true') { $order->info['shipping_cost'] += zen_calculate_tax($order->info['shipping_cost'], $shipping_tax); } } if ($_SESSION['shipping'] == 'free_free') { $order->info['shipping_method'] = FREE_SHIPPING_TITLE; } $this->output[] = array('title' => $order->info['shipping_method'] . ':', 'text' => $currencies->format($order->info['shipping_cost'], true, $order->info['currency'], $order->info['currency_value']), 'value' => $order->info['shipping_cost']); } }
function get_product_price($product_id) { global $db, $order; $products_id = zen_get_prid($product_id); // products price $qty = $_SESSION['cart']->contents[$product_id]['qty']; $product = $db->Execute("select products_id, products_price, products_tax_class_id, products_weight\n from " . TABLE_PRODUCTS . " where products_id='" . $products_id . "'"); if ($product->RecordCount() > 0) { $prid = $product->fields['products_id']; $products_tax = zen_get_tax_rate($product->fields['products_tax_class_id']); $products_price = $product->fields['products_price']; $specials = $db->Execute("select specials_new_products_price\n from " . TABLE_SPECIALS . " where products_id = '" . $prid . "' and status = '1'"); if ($specials->RecordCount() > 0) { $products_price = $specials->fields['specials_new_products_price']; } if ($this->include_tax == 'true') { $total_price += ($products_price + zen_calculate_tax($products_price, $products_tax)) * $qty; } else { $total_price += $products_price * $qty; } // attributes price if (isset($_SESSION['cart']->contents[$product_id]['attributes'])) { reset($_SESSION['cart']->contents[$product_id]['attributes']); while (list($option, $value) = each($_SESSION['cart']->contents[$product_id]['attributes'])) { $attribute_price = $db->Execute("select options_values_price, price_prefix\n from " . TABLE_PRODUCTS_ATTRIBUTES . "\n where products_id = '" . $prid . "'\n and options_id = '" . $option . "'\n and options_values_id = '" . $value . "'"); if ($attribute_price->fields['price_prefix'] == '-') { if ($this->include_tax == 'true') { $total_price -= $qty * ($attribute_price->fields['options_values_price'] + zen_calculate_tax($attribute_price->fields['options_values_price'], $products_tax)); } else { $total_price -= $qty * $attribute_price->fields['options_values_price']; } } else { if ($this->include_tax == 'true') { $total_price += $qty * ($attribute_price->fields['options_values_price'] + zen_calculate_tax($attribute_price->fields['options_values_price'], $products_tax)); } else { $total_price += $qty * $attribute_price->fields['options_values_price']; } } } } } return $total_price; }
/** * Prepare subtotal and line-item detail content to send to PayPal */ function getLineItemDetails() { global $order, $currencies, $order_totals, $order_total_modules; $optionsST = array(); $optionsLI = array(); $onetimeSum = 0; $onetimeTax = 0; $creditsApplied = 0; $creditsTax_applied = 0; $sumOfLineItems = 0; $sumOfLineTax = 0; // prepare subtotals for ($i = 0, $n = sizeof($order_totals); $i < $n; $i++) { if ($order_totals[$i]['code'] == 'ot_subtotal') { $optionsST['ITEMAMT'] = round($order_totals[$i]['value'], 2); } if ($order_totals[$i]['code'] == 'ot_tax') { $optionsST['TAXAMT'] = round($order_totals[$i]['value'], 2); } if ($order_totals[$i]['code'] == 'ot_shipping') { $optionsST['SHIPPINGAMT'] = round($order_totals[$i]['value'], 2); } if ($order_totals[$i]['code'] == 'ot_total') { $optionsST['AMT'] = round($order_totals[$i]['value'], 2); } $optionsST['HANDLINGAMT'] = 0; global ${$order_totals[$i]['code']}; if (isset(${$order_totals[$i]['code']}->credit_class) && ${$order_totals[$i]['code']}->credit_class == true) { $creditsApplied += round($order_totals[$i]['value'], 2); } // treat all other OT's as if they're related to handling fees if (!in_array($order_totals[$i]['code'], array('ot_total', 'ot_subtotal', 'ot_tax', 'ot_shipping')) && !(isset(${$order_totals[$i]['code']}->credit_class) && ${$order_totals[$i]['code']}->credit_class == true)) { $optionsST['HANDLINGAMT'] += $order_totals[$i]['value']; } } // Move shipping tax amount from Tax subtotal into Shipping subtotal for submission to PayPal $module = substr($_SESSION['shipping']['id'], 0, strpos($_SESSION['shipping']['id'], '_')); if (zen_not_null($order->info['shipping_method'])) { if ($GLOBALS[$module]->tax_class > 0) { $shipping_tax_basis = !isset($GLOBALS[$module]->tax_basis) ? STORE_SHIPPING_TAX_BASIS : $GLOBALS[$module]->tax_basis; $shippingOnBilling = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); $shippingOnDelivery = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); if ($shipping_tax_basis == 'Billing') { $shipping_tax = $shippingOnBilling; } elseif ($shipping_tax_basis == 'Shipping') { $shipping_tax = $shippingOnDelivery; } else { if (STORE_ZONE == $order->billing['zone_id']) { $shipping_tax = $shippingOnBilling; } elseif (STORE_ZONE == $order->delivery['zone_id']) { $shipping_tax = $shippingOnDelivery; } else { $shipping_tax = 0; } } $taxAdjustmentForShipping = zen_calculate_tax($order->info['shipping_cost'], $shipping_tax); $optionsST['SHIPPINGAMT'] += $taxAdjustmentForShipping; $optionsST['TAXAMT'] -= $taxAdjustmentForShipping; } } // loop thru all products to display quantity and price. Appends *** if out-of-stock. for ($i = 0, $n = sizeof($order->products), $k = 0; $i < $n; $i++, $k++) { $optionsLI["L_NUMBER{$k}"] = $order->products[$i]['model']; $optionsLI["L_QTY{$k}"] = (int) $order->products[$i]['qty']; $optionsLI["L_NAME{$k}"] = $order->products[$i]['name']; $optionsLI["L_NAME{$k}"] .= zen_get_products_stock($order->products[$i]['id']) - $order->products[$i]['qty'] < 0 ? STOCK_MARK_PRODUCT_OUT_OF_STOCK : ''; // if there are attributes, loop thru them and add to description if (isset($order->products[$i]['attributes']) && sizeof($order->products[$i]['attributes']) > 0) { for ($j = 0, $n2 = sizeof($order->products[$i]['attributes']); $j < $n2; $j++) { $optionsLI["L_NAME{$k}"] .= "\n " . $order->products[$i]['attributes'][$j]['option'] . ': ' . $order->products[$i]['attributes'][$j]['value']; } // end loop } // endif attribute-info $optionsLI["L_AMT{$k}"] = $order->products[$i]['final_price']; $optionsLI["L_TAXAMT{$k}"] = zen_calculate_tax($order->products[$i]['final_price'], $order->products[$i]['tax']); // track one-time charges if ($order->products[$i]['onetime_charges'] != 0) { $onetimeSum += $order->products[$i]['onetime_charges']; $onetimeTax += zen_calculate_tax($order->products[$i]['onetime_charges'], $order->products[$i]['tax']); } // Replace & and = with * if found. $optionsLI["L_NAME{$k}"] = str_replace(array('&', '='), '*', $optionsLI["L_NAME{$k}"]); $optionsLI["L_NAME{$k}"] = zen_clean_html($optionsLI["L_NAME{$k}"], 'strong'); // reformat properly $optionsLI["L_NUMBER{$k}"] = substr($optionsLI["L_NUMBER{$k}"], 0, 127); $optionsLI["L_NAME{$k}"] = substr($optionsLI["L_NAME{$k}"], 0, 127); $optionsLI["L_AMT{$k}"] = $optionsLI["L_AMT{$k}"]; $optionsLI["L_TAXAMT{$k}"] = round($optionsLI["L_TAXAMT{$k}"], 2); } // end for loopthru all products if ($onetimeSum > 0) { $i++; $k++; $optionsLI["L_NUMBER{$k}"] = $k; $optionsLI["L_NAME{$k}"] = 'One-Time Charges'; $optionsLI["L_AMT{$k}"] = $onetimeSum; $optionsLI["L_TAXAMT{$k}"] = $onetimeTax; $optionsLI["L_QTY{$k}"] = 1; } // handle discounts such as gift certificates and coupons if ($creditsApplied > 0) { $optionsST['HANDLINGAMT'] -= $creditsApplied; } // add all one-time charges $optionsST['ITEMAMT'] += $onetimeSum; //ensure things are not negative $optionsST['HANDLINGAMT'] = abs(strval($optionsST['HANDLINGAMT'])); // ensure all numbers are non-negative if (is_array($optionsST)) { foreach ($optionsST as $key => $value) { $optionsST[$key] = abs(strval($value)); } } if (is_array($optionsLI)) { foreach ($optionsLI as $key => $value) { if (strstr($key, 'AMT')) { $optionsLI[$key] = abs(strval($value)); } } } // subtotals have to add up to AMT // Thus, if there is a discrepancy, make adjustment to HANDLINGAMT: $st = $optionsST['ITEMAMT'] + $optionsST['TAXAMT'] + $optionsST['SHIPPINGAMT'] + $optionsST['HANDLINGAMT']; if ($st != $optionsST['AMT']) { $optionsST['HANDLINGAMT'] += strval($optionsST['AMT'] - $st); } /* //PayPal API spec contradicts itself ... and apparently neither of these "requirements" are enforced. //Thus skipping this section for now: // according to API specs, these cannot be set if they contain zero values, so unset if they are zero: if ($optionsST['TAXAMT'] == 0) unset($optionsST['TAXAMT']); if ($optionsST['SHIPPINGAMT'] == 0) unset($optionsST['SHIPPINGAMT']); if ($optionsST['HANDLINGAMT'] == 0) unset($optionsST['HANDLINGAMT']); // set missing subtotals if they are zero values, since all must be submitted if (!isset($optionsST['TAXAMT'])) $optionsST['TAXAMT'] = 0; if (!isset($optionsST['SHIPPINGAMT'])) $optionsST['SHIPPINGAMT'] = 0; if (!isset($optionsST['HANDLINGAMT'])) $optionsST['HANDLINGAMT'] = 0; */ // Since the PayPal spec cannot handle mathematically mismatched values caused by one-time charges, // must drop line-item details if any one-time charges apply to this order: // if there are any discounts in this order, do NOT supply line-item details if ($onetimeSum > 0) { $optionsLI = array(); } // Do sanity check -- if any of the line-item subtotal math doesn't add up properly, skip line-item details, // so that the order can go through even though PayPal isn't being flexible to handle Zen Cart's diversity for ($j = 0; $j < $k; $j++) { $itemAMT = $optionsLI["L_AMT{$j}"]; $itemTAX = $optionsLI["L_TAXAMT{$j}"]; $itemQTY = $optionsLI["L_QTY{$j}"]; $sumOfLineItems += $itemQTY * $itemAMT; $sumOfLineTax += round($itemQTY * $itemTAX, 2); } if ((double) $optionsST['ITEMAMT'] != (double) strval($sumOfLineItems)) { $optionsLI = array(); $this->zcLog('getLineItemDetails 1', 'Order Subtotal does not match sum of line-item prices. Line-item-details skipped.' . "\n" . (double) $optionsST['ITEMAMT'] . ' ' . (double) $sumOfLineItems); //die('ITEMAMT != $sumOfLineItems ' . $optionsST['ITEMAMT'] . ' ' . $sumOfLineItems); } if ((double) $optionsST['TAXAMT'] != (double) strval($sumOfLineTax)) { $optionsLI = array(); $this->zcLog('getLineItemDetails 2', 'Tax Subtotal does not match sum of taxes for line-items. Line-item-details skipped.' . "\n" . $optionsST['TAXAMT'] . ' ' . $sumOfLineTax); //die('TAXAMT != $sumofLineTax ' . $optionsST['TAXAMT'] . ' ' . $sumOfLineTax); } $this->zcLog('getLineItemDetails 3', 'LineItemDetails: ' . "\n" . ($creditsApplied ? 'Credits apply to this order, so all line-item details are NOT being submitted. Thus, the following data is REDUNDANT' . "\n" : '') . 'Details:' . print_r(array_merge($optionsST, $optionsLI), true) . "\n\n" . 'DEFAULT_CURRENCY = ' . DEFAULT_CURRENCY . "\nSESSION['currency'] = " . $_SESSION['currency'] . "\n" . "order->info['currency'] = " . $order->info['currency'] . "\n\$currencies->currencies[\$_SESSION['currency']]['value'] = " . $currencies->currencies[$_SESSION['currency']]['value'] . "\n" . print_r($currencies, true)); // if not default currency, do not send subtotals or line-item details if (DEFAULT_CURRENCY != $order->info['currency']) { $this->zcLog('getLineItemDetails 4', 'Not using default currency. Thus, no line-item details can be submitted.'); return array(); } if ($currencies->currencies[$_SESSION['currency']]['value'] != 1) { $this->zcLog('getLineItemDetails 5', 'currency val not equal to 1.0000 - cannot proceed without coping with currency conversions. Aborting line-item details.'); return array(); } // if there are any discounts in this order, do not supply subtotals or line-item details if (strval($creditsApplied) > 0) { return array(); } //$this->zcLog('getLineItemDetails 6', 'no credits - okay'); // if subtotals are not adding up correctly, then skip sending any line-item or subtotal details to PayPal $st = round(strval($optionsST['ITEMAMT'] + $optionsST['TAXAMT'] + $optionsST['SHIPPINGAMT'] + $optionsST['HANDLINGAMT']), 2); $stDiff = strval($optionsST['AMT'] - $st); $stDiffRounded = strval(abs($st) - abs(round($optionsST['AMT'], 2))); // tidy up all values so that they comply with proper format (number_format(xxxx,2) for PayPal US use ) if (!defined('PAYPALWPP_SKIP_LINE_ITEM_DETAIL_FORMATTING') || PAYPALWPP_SKIP_LINE_ITEM_DETAIL_FORMATTING != 'true') { if (is_array($optionsST)) { foreach ($optionsST as $key => $value) { $optionsST[$key] = number_format(abs($value), 2); } } if (is_array($optionsLI)) { foreach ($optionsLI as $key => $value) { if (strstr($key, 'AMT')) { $optionsLI[$key] = number_format(abs($value), 2); } } } } $this->zcLog('getLineItemDetails 7', 'checking subtotals... ' . "\nitemamt: " . $optionsST['ITEMAMT'] . "\ntaxamt: " . $optionsST['TAXAMT'] . "\nshippingamt: " . $optionsST['SHIPPINGAMT'] . "\nhandlingamt: " . $optionsST['HANDLINGAMT'] . "\n-------------------\nsubtotal: " . number_format($st, 2) . "\nAMT: " . $optionsST['AMT'] . "\n-------------------\ndifference: " . $stDiff . ' (abs+rounded: ' . $stDiffRounded . ')'); if ($stDiffRounded != 0) { return array(); } //die('bad subtotals'); //return array(); $this->zcLog('getLineItemDetails 8', 'subtotals balance - okay'); if (abs($optionsST['HANDLINGAMT']) == 0) { unset($optionsST['HANDLINGAMT']); } // Send Subtotal and LineItem results back to be submitted to PayPal return array_merge($optionsST, $optionsLI); }
function ot_shipping() { global $order, $currencies; $this->code = 'ot_shipping'; $this->title = MODULE_ORDER_TOTAL_SHIPPING_TITLE; $this->description = MODULE_ORDER_TOTAL_SHIPPING_DESCRIPTION; $this->sort_order = MODULE_ORDER_TOTAL_SHIPPING_SORT_ORDER; unset($_SESSION['shipping_tax_description']); $this->output = array(); if (MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING == 'true') { switch (MODULE_ORDER_TOTAL_SHIPPING_DESTINATION) { case 'national': if ($order->delivery['country_id'] == STORE_COUNTRY) { $pass = true; } break; case 'international': if ($order->delivery['country_id'] != STORE_COUNTRY) { $pass = true; } break; case 'both': $pass = true; break; default: $pass = false; break; } if ($pass == true && $order->info['total'] - $order->info['shipping_cost'] >= MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_OVER) { $order->info['shipping_method'] = $this->title; $order->info['total'] -= $order->info['shipping_cost']; $order->info['shipping_cost'] = 0; } } $module = isset($_SESSION['shipping']) && isset($_SESSION['shipping']['id']) ? substr($_SESSION['shipping']['id'], 0, strpos($_SESSION['shipping']['id'], '_')) : ''; if (is_object($order) && zen_not_null($order->info['shipping_method'])) { if ($GLOBALS[$module]->tax_class > 0) { if (!isset($GLOBALS[$module]->tax_basis)) { $shipping_tax_basis = STORE_SHIPPING_TAX_BASIS; } else { $shipping_tax_basis = $GLOBALS[$module]->tax_basis; } if ($shipping_tax_basis == 'Billing') { $shipping_tax = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); $shipping_tax_description = zen_get_tax_description($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); } elseif ($shipping_tax_basis == 'Shipping') { $shipping_tax = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); $shipping_tax_description = zen_get_tax_description($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); } else { if (STORE_ZONE == $order->billing['zone_id']) { $shipping_tax = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); $shipping_tax_description = zen_get_tax_description($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); } elseif (STORE_ZONE == $order->delivery['zone_id']) { $shipping_tax = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); $shipping_tax_description = zen_get_tax_description($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); } else { $shipping_tax = 0; } } $shipping_tax_amount = zen_calculate_tax($order->info['shipping_cost'], $shipping_tax); $order->info['shipping_tax'] += $shipping_tax_amount; $order->info['tax'] += $shipping_tax_amount; $order->info['tax_groups']["{$shipping_tax_description}"] += zen_calculate_tax($order->info['shipping_cost'], $shipping_tax); $order->info['total'] += zen_calculate_tax($order->info['shipping_cost'], $shipping_tax); $_SESSION['shipping_tax_description'] = $shipping_tax_description; $_SESSION['shipping_tax_amount'] = $shipping_tax_amount; if (DISPLAY_PRICE_WITH_TAX == 'true') { $order->info['shipping_cost'] += zen_calculate_tax($order->info['shipping_cost'], $shipping_tax); } } if ($_SESSION['shipping']['id'] == 'free_free') { $order->info['shipping_method'] = FREE_SHIPPING_TITLE; $order->info['shipping_cost'] = 0; } } }
/** * Enter description here... * * @return unknown */ function get_order_total() { global $order; $order_total_tax = $order->info['tax']; $order_total = $order->info['total']; // echo "order total = $order_total<br>"; // echo "order total shipping = {$order->info['shipping_cost']}<br>"; // echo "order total tax = {$order->info['tax']}<br>"; if ($this->include_shipping != 'true') { $order_total -= $order->info['shipping_cost']; } if ($this->include_shipping != 'true') { $order_total_tax -= $order->info['shipping_tax']; } if ($this->include_tax != 'true') { $order_total -= $order->info['tax']; } // if ($this->include_tax != "true" && $this->include_shipping != 'true') $order_total -= $order->info['shipping_tax']; // echo "order total = $order_total<br>"; $orderTotalFull = $order_total; $products = $_SESSION['cart']->get_products(); for ($i = 0; $i < sizeof($products); $i++) { if (!is_product_valid($products[$i]['id'], $_SESSION['cc_id'])) { $order_total -= $products[$i]['final_price'] * $products[$i]['quantity']; if ($this->include_tax == 'true') { $products_tax = zen_get_tax_rate($products[$i]['tax_class_id']); $order_total -= zen_calculate_tax($products[$i]['final_price'], $products_tax) * $products[$i]['quantity']; } $order_total_tax -= zen_calculate_tax($products[$i]['final_price'], zen_get_tax_rate($products[$i]['tax_class_id'])) * $products[$i]['quantity']; } } $orderTotalInclusive = $order_total + $order_total_tax; if (DISPLAY_PRICE_WITH_TAX == 'true') { $order_total += $order_total_tax; } $order_total = array('totalFull' => $orderTotalFull, 'total' => $order_total, 'tax' => $order_total_tax, 'totalInclusive' => $orderTotalInclusive); return $order_total; }
function create_add_products($zf_insert_id, $zf_mode = false) { global $db, $currencies, $order_total_modules, $order_totals, $zco_notifier; // initialized for the email confirmation $this->products_ordered = ''; $this->products_ordered_html = ''; $this->subtotal = 0; $this->total_tax = 0; // lowstock email report $this->email_low_stock = ''; for ($i = 0, $n = sizeof($this->products); $i < $n; $i++) { $custom_insertable_text = ''; // Stock Update - Joao Correia if (STOCK_LIMITED == 'true') { if (DOWNLOAD_ENABLED == 'true') { $stock_query_raw = "select p.products_quantity, pad.products_attributes_filename, p.product_is_always_free_shipping\n\n from " . TABLE_PRODUCTS . " p\n\n left join " . TABLE_PRODUCTS_ATTRIBUTES . " pa\n\n on p.products_id=pa.products_id\n\n left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad\n\n on pa.products_attributes_id=pad.products_attributes_id\n\n WHERE p.products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"; // Will work with only one option for downloadable products // otherwise, we have to build the query dynamically with a loop $products_attributes = $this->products[$i]['attributes']; if (is_array($products_attributes)) { $stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'"; } $stock_values = $db->Execute($stock_query_raw); } else { $stock_values = $db->Execute("select * from " . TABLE_PRODUCTS . " where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); } $zco_notifier->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_BEGIN'); if ($stock_values->RecordCount() > 0) { // do not decrement quantities if products_attributes_filename exists if (DOWNLOAD_ENABLED != 'true' || $stock_values->fields['product_is_always_free_shipping'] == 2 || !$stock_values->fields['products_attributes_filename']) { $stock_left = $stock_values->fields['products_quantity'] - $this->products[$i]['qty']; $this->products[$i]['stock_reduce'] = $this->products[$i]['qty']; } else { $stock_left = $stock_values->fields['products_quantity']; } // $this->products[$i]['stock_value'] = $stock_values->fields['products_quantity']; $db->Execute("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); if (defined('TABLE_PRODUCTS_WITH_ATTRIBUTES_STOCK')) { // kuroi: Begin Stock by Attributes additions // added to update quantities of products with attributes $attribute_search = array(); $attribute_stock_left = STOCK_REORDER_LEVEL + 1; // kuroi: prevent false low stock triggers if (isset($this->products[$i]['attributes']) and sizeof($this->products[$i]['attributes']) > 0) { foreach ($this->products[$i]['attributes'] as $attributes) { $attribute_search[] = $attributes['value_id']; } if (sizeof($attribute_search) > 1) { $attribute_search = 'where options_values_id in ("' . implode('","', $attribute_search) . '")'; } else { $attribute_search = 'where options_values_id="' . $attribute_search[0] . '"'; } $query = 'select products_attributes_id from ' . TABLE_PRODUCTS_ATTRIBUTES . ' ' . $attribute_search . ' and products_id="' . zen_get_prid($this->products[$i]['id']) . '" order by products_attributes_id'; $attributes = $db->Execute($query); $stock_attributes_search = array(); while (!$attributes->EOF) { $stock_attributes_search[] = $attributes->fields['products_attributes_id']; $attributes->MoveNext(); } if (sizeof($stock_attributes_search) > 1) { $stock_attributes_search = implode(',', $stock_attributes_search); } else { foreach ($stock_attributes_search as $attribute_search) { $stock_attributes_search1 = $attribute_search; } $stock_attributes_search = $stock_attributes_search1; } $get_quantity_query = 'select quantity from ' . TABLE_PRODUCTS_WITH_ATTRIBUTES_STOCK . ' where products_id="' . zen_get_prid($this->products[$i]['id']) . '" and stock_attributes="' . $stock_attributes_search . '"'; $attribute_stock_available = $db->Execute($get_quantity_query); $attribute_stock_left = $attribute_stock_available->fields['quantity'] - $this->products[$i]['qty']; $attribute_update_query = 'update ' . TABLE_PRODUCTS_WITH_ATTRIBUTES_STOCK . ' set quantity=' . $attribute_stock_left . ' where products_id="' . zen_get_prid($this->products[$i]['id']) . '" and stock_attributes="' . $stock_attributes_search . '"'; $db->Execute($attribute_update_query); } // kuroi: End Stock by Attribute additions } if ($stock_left <= 0) { // only set status to off when not displaying sold out if (SHOW_PRODUCTS_SOLD_OUT == '0') { $db->Execute("update " . TABLE_PRODUCTS . " set products_status = 0 where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); } } // for low stock email if ($stock_left <= STOCK_REORDER_LEVEL) { // WebMakers.com Added: add to low stock email $this->email_low_stock .= 'ID# ' . zen_get_prid($this->products[$i]['id']) . ', ' . $this->products[$i]['model'] . ', ' . $this->products[$i]['name'] . ', ' . 'Stock: ' . $stock_left . "\n\n"; // kuroi: trigger and details for attribute low stock email } elseif ($attribute_stock_left <= STOCK_REORDER_LEVEL) { $this->email_low_stock .= 'ID# ' . zen_get_prid($this->products[$i]['id']) . ', ' . $this->products[$i]['model'] . ', ' . $this->products[$i]['name'] . ', '; foreach ($this->products[$i]['attributes'] as $attributes) { $this->email_low_stock .= $attributes['option'] . ': ' . $attributes['value'] . ', '; } $this->email_low_stock .= 'Stock: ' . $attribute_stock_left . "\n\n"; } } } // Update products_ordered (for bestsellers list) // $db->Execute("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%d', $order->products[$i]['qty']) . " where products_id = '" . zen_get_prid($order->products[$i]['id']) . "'"); $db->Execute("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%f', $this->products[$i]['qty']) . " where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); $zco_notifier->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_END'); $products_name = $this->products[$i]['name']; if (strlen($products_name) > 64) { $products_name = substr($products_name, 0, 64); } $sql_data_array = array('orders_id' => $zf_insert_id, 'products_id' => zen_get_prid($this->products[$i]['id']), 'products_model' => $this->products[$i]['model'], 'products_name' => $products_name, 'products_price' => $this->products[$i]['price'], 'final_price' => $this->products[$i]['final_price'], 'onetime_charges' => $this->products[$i]['onetime_charges'], 'products_tax' => $this->products[$i]['tax'], 'products_quantity' => $this->products[$i]['qty'], 'products_priced_by_attribute' => $this->products[$i]['products_priced_by_attribute'], 'product_is_free' => $this->products[$i]['product_is_free'], 'products_discount_type' => $this->products[$i]['products_discount_type'], 'products_discount_type_from' => $this->products[$i]['products_discount_type_from'], 'products_prid' => $this->products[$i]['id']); zen_db_perform(TABLE_ORDERS_PRODUCTS, $sql_data_array); $order_products_id = $db->Insert_ID(); $zco_notifier->notify('NOTIFY_ORDER_DURING_CREATE_ADDED_PRODUCT_LINE_ITEM', array_merge(array('orders_products_id' => $order_products_id), $sql_data_array)); if (FEC_GIFT_WRAPPING_SWITCH == 'true') { // Gift wrap $wrap_count = 0; $wrapsettings = $_SESSION['wrapsettings']; $prid = $this->products[$i]['id']; for ($q = 1; $q <= $this->products[$i]['qty']; $q++) { if (!isset($wrapsettings[$prid][$q]) || $wrapsettings[$prid][$q] == 0) { continue; } $sql_data_array = array('orders_id' => $zf_insert_id, 'orders_products_id' => $order_products_id, 'wrap' => $wrapsettings[$prid][$q]); zen_db_perform(TABLE_ORDERS_GIFTWRAP, $sql_data_array); $wrap_count++; } // End gift wrap } $zco_notifier->notify('NOTIFY_ORDER_PROCESSING_CREDIT_ACCOUNT_UPDATE_BEGIN'); $order_total_modules->update_credit_account($i); //ICW ADDED FOR CREDIT CLASS SYSTEM $zco_notifier->notify('NOTIFY_ORDER_PROCESSING_ATTRIBUTES_BEGIN'); //------ bof: insert customer-chosen options to order-------- $attributes_exist = '0'; $this->products_ordered_attributes = ''; if (isset($this->products[$i]['attributes'])) { $attributes_exist = '1'; for ($j = 0, $n2 = sizeof($this->products[$i]['attributes']); $j < $n2; $j++) { if (DOWNLOAD_ENABLED == 'true') { $attributes_query = "select popt.products_options_name, poval.products_options_values_name,\n\n pa.options_values_price, pa.price_prefix,\n\n pa.product_attribute_is_free, pa.products_attributes_weight, pa.products_attributes_weight_prefix,\n\n pa.attributes_discounted, pa.attributes_price_base_included, pa.attributes_price_onetime,\n\n pa.attributes_price_factor, pa.attributes_price_factor_offset,\n\n pa.attributes_price_factor_onetime, pa.attributes_price_factor_onetime_offset,\n\n pa.attributes_qty_prices, pa.attributes_qty_prices_onetime,\n\n pa.attributes_price_words, pa.attributes_price_words_free,\n\n pa.attributes_price_letters, pa.attributes_price_letters_free,\n\n pad.products_attributes_maxdays, pad.products_attributes_maxcount, pad.products_attributes_filename,\n\n pa.product_attribute_is_free, pa.attributes_discounted\n\n from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa\n\n left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad\n\n on pa.products_attributes_id=pad.products_attributes_id\n\n where pa.products_id = '" . zen_db_input($this->products[$i]['id']) . "'\n\n and pa.options_id = '" . $this->products[$i]['attributes'][$j]['option_id'] . "'\n\n and pa.options_id = popt.products_options_id\n\n and pa.options_values_id = '" . $this->products[$i]['attributes'][$j]['value_id'] . "'\n\n and pa.options_values_id = poval.products_options_values_id\n\n and popt.language_id = '" . $_SESSION['languages_id'] . "'\n\n and poval.language_id = '" . $_SESSION['languages_id'] . "'"; $attributes_values = $db->Execute($attributes_query); } else { $attributes_values = $db->Execute("select popt.products_options_name, poval.products_options_values_name,\n\n pa.options_values_price, pa.price_prefix,\n\n pa.product_attribute_is_free, pa.products_attributes_weight, pa.products_attributes_weight_prefix,\n\n pa.attributes_discounted, pa.attributes_price_base_included, pa.attributes_price_onetime,\n\n pa.attributes_price_factor, pa.attributes_price_factor_offset,\n\n pa.attributes_price_factor_onetime, pa.attributes_price_factor_onetime_offset,\n\n pa.attributes_qty_prices, pa.attributes_qty_prices_onetime,\n\n pa.attributes_price_words, pa.attributes_price_words_free,\n\n pa.attributes_price_letters, pa.attributes_price_letters_free\n\n from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa\n\n where pa.products_id = '" . $this->products[$i]['id'] . "' and pa.options_id = '" . (int) $this->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . (int) $this->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $_SESSION['languages_id'] . "' and poval.language_id = '" . $_SESSION['languages_id'] . "'"); } //clr 030714 update insert query. changing to use values form $order->products for products_options_values. $sql_data_array = array('orders_id' => $zf_insert_id, 'orders_products_id' => $order_products_id, 'products_options' => $attributes_values->fields['products_options_name'], 'products_options_values' => $this->products[$i]['attributes'][$j]['value'], 'options_values_price' => $attributes_values->fields['options_values_price'], 'price_prefix' => $attributes_values->fields['price_prefix'], 'product_attribute_is_free' => $attributes_values->fields['product_attribute_is_free'], 'products_attributes_weight' => $attributes_values->fields['products_attributes_weight'], 'products_attributes_weight_prefix' => $attributes_values->fields['products_attributes_weight_prefix'], 'attributes_discounted' => $attributes_values->fields['attributes_discounted'], 'attributes_price_base_included' => $attributes_values->fields['attributes_price_base_included'], 'attributes_price_onetime' => $attributes_values->fields['attributes_price_onetime'], 'attributes_price_factor' => $attributes_values->fields['attributes_price_factor'], 'attributes_price_factor_offset' => $attributes_values->fields['attributes_price_factor_offset'], 'attributes_price_factor_onetime' => $attributes_values->fields['attributes_price_factor_onetime'], 'attributes_price_factor_onetime_offset' => $attributes_values->fields['attributes_price_factor_onetime_offset'], 'attributes_qty_prices' => $attributes_values->fields['attributes_qty_prices'], 'attributes_qty_prices_onetime' => $attributes_values->fields['attributes_qty_prices_onetime'], 'attributes_price_words' => $attributes_values->fields['attributes_price_words'], 'attributes_price_words_free' => $attributes_values->fields['attributes_price_words_free'], 'attributes_price_letters' => $attributes_values->fields['attributes_price_letters'], 'attributes_price_letters_free' => $attributes_values->fields['attributes_price_letters_free'], 'products_options_id' => (int) $this->products[$i]['attributes'][$j]['option_id'], 'products_options_values_id' => (int) $this->products[$i]['attributes'][$j]['value_id'], 'products_prid' => $this->products[$i]['id']); zen_db_perform(TABLE_ORDERS_PRODUCTS_ATTRIBUTES, $sql_data_array); $zco_notifier->notify('NOTIFY_ORDER_DURING_CREATE_ADDED_ATTRIBUTE_LINE_ITEM', $sql_data_array); if (DOWNLOAD_ENABLED == 'true' && isset($attributes_values->fields['products_attributes_filename']) && zen_not_null($attributes_values->fields['products_attributes_filename'])) { $sql_data_array = array('orders_id' => $zf_insert_id, 'orders_products_id' => $order_products_id, 'orders_products_filename' => $attributes_values->fields['products_attributes_filename'], 'download_maxdays' => $attributes_values->fields['products_attributes_maxdays'], 'download_count' => $attributes_values->fields['products_attributes_maxcount'], 'products_prid' => $this->products[$i]['id']); zen_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array); $zco_notifier->notify('NOTIFY_ORDER_DURING_CREATE_ADDED_ATTRIBUTE_DOWNLOAD_LINE_ITEM', $sql_data_array); } //clr 030714 changing to use values from $orders->products and adding call to zen_decode_specialchars() // $this->products_ordered_attributes .= "\n\t" . $attributes_values->fields['products_options_name'] . ' ' . $attributes_values->fields['products_options_values_name']; $this->products_ordered_attributes .= "\n\t" . $attributes_values->fields['products_options_name'] . ' ' . zen_decode_specialchars($this->products[$i]['attributes'][$j]['value']); } } //------eof: insert customer-chosen options ---- $zco_notifier->notify('NOTIFY_ORDER_DURING_CREATE_ADD_PRODUCTS', $custom_insertable_text); /* START: ADD MY CUSTOM DETAILS * 1. calculate/prepare custom information to be added to this product entry in order-confirmation. * 2. Add that data to the $this->products_ordered_attributes variable, using this sort of format: * $this->products_ordered_attributes .= {INSERT CUSTOM INFORMATION HERE}; */ $this->products_ordered_attributes .= ''; // $custom_insertable_text; /* END: ADD MY CUSTOM DETAILS */ // update totals counters $this->total_weight += $this->products[$i]['qty'] * $this->products[$i]['weight']; $this->total_tax += zen_calculate_tax($total_products_price, $products_tax) * $this->products[$i]['qty']; $this->total_cost += $total_products_price; $zco_notifier->notify('NOTIFY_ORDER_PROCESSING_ONE_TIME_CHARGES_BEGIN'); // build output for email notification $this->products_ordered .= $this->products[$i]['qty'] . ' x ' . $this->products[$i]['name'] . ($this->products[$i]['model'] != '' ? ' (' . $this->products[$i]['model'] . ') ' : '') . ' = ' . $currencies->display_price($this->products[$i]['final_price'], $this->products[$i]['tax'], $this->products[$i]['qty']) . ($this->products[$i]['onetime_charges'] != 0 ? "\n" . TEXT_ONETIME_CHARGES_EMAIL . $currencies->display_price($this->products[$i]['onetime_charges'], $this->products[$i]['tax'], 1) : '') . $this->products_ordered_attributes . "\n"; $this->products_ordered_html .= '<tr>' . "\n" . '<td class="product-details" align="right" valign="top" width="30">' . $this->products[$i]['qty'] . ' x</td>' . "\n" . '<td class="product-details" valign="top">' . nl2br($this->products[$i]['name']) . ($this->products[$i]['model'] != '' ? ' (' . nl2br($this->products[$i]['model']) . ') ' : '') . "\n" . '<nobr><small><em> ' . nl2br($this->products_ordered_attributes) . '</em></small></nobr></td>' . "\n" . '<td class="product-details-num" valign="top" align="right">' . $currencies->display_price($this->products[$i]['final_price'], $this->products[$i]['tax'], $this->products[$i]['qty']) . ($this->products[$i]['onetime_charges'] != 0 ? '</td></tr>' . "\n" . '<tr><td class="product-details">' . nl2br(TEXT_ONETIME_CHARGES_EMAIL) . '</td>' . "\n" . '<td>' . $currencies->display_price($this->products[$i]['onetime_charges'], $this->products[$i]['tax'], 1) : '') . '</td></tr>' . "\n"; } $order_total_modules->apply_credit(); //ICW ADDED FOR CREDIT CLASS SYSTEM $zco_notifier->notify('NOTIFY_ORDER_AFTER_ORDER_CREATE_ADD_PRODUCTS'); }
function create_add_products($zf_insert_id, $zf_mode = false) { global $db, $currencies, $order_total_modules, $order_totals; // initialized for the email confirmation $this->products_ordered = ''; $this->products_ordered_html = ''; $this->subtotal = 0; $this->total_tax = 0; // lowstock email report $this->email_low_stock = ''; for ($i = 0, $n = sizeof($this->products); $i < $n; $i++) { // Stock Update - Joao Correia if (STOCK_LIMITED == 'true') { if (DOWNLOAD_ENABLED == 'true') { $stock_query_raw = "SELECT products_quantity, pad.products_attributes_filename\r\n FROM " . TABLE_PRODUCTS . " p\r\n LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES . " pa\r\n ON p.products_id=pa.products_id\r\n LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad\r\n ON pa.products_attributes_id=pad.products_attributes_id\r\n WHERE p.products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"; // Will work with only one option for downloadable products // otherwise, we have to build the query dynamically with a loop $products_attributes = $this->products[$i]['attributes']; if (is_array($products_attributes)) { $stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'"; } $stock_values = $db->Execute($stock_query_raw); } else { $stock_values = $db->Execute("select products_quantity from " . TABLE_PRODUCTS . " where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); } if ($stock_values->RecordCount() > 0) { // do not decrement quantities if products_attributes_filename exists if (DOWNLOAD_ENABLED != 'true' || !$stock_values->fields['products_attributes_filename']) { $stock_left = $stock_values->fields['products_quantity'] - $this->products[$i]['qty']; $this->products[$i]['stock_reduce'] = $this->products[$i]['qty']; } else { $stock_left = $stock_values->fields['products_quantity']; } // $this->products[$i]['stock_value'] = $stock_values->fields['products_quantity']; $db->Execute("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); // if ( ($stock_left < 1) && (STOCK_ALLOW_CHECKOUT == 'false') ) { if ($stock_left < 1) { // only set status to off when not displaying sold out if (SHOW_PRODUCTS_SOLD_OUT == '0') { $db->Execute("update " . TABLE_PRODUCTS . " set products_status = '0' where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); } } // for low stock email if ($stock_left <= STOCK_REORDER_LEVEL) { // WebMakers.com Added: add to low stock email $this->email_low_stock .= 'ID# ' . zen_get_prid($this->products[$i]['id']) . "\t\t" . $this->products[$i]['model'] . "\t\t" . $this->products[$i]['name'] . "\t\t" . ' Qty Left: ' . $stock_left . "\n"; } } } // Update products_ordered (for bestsellers list) // $db->Execute("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%d', $order->products[$i]['qty']) . " where products_id = '" . zen_get_prid($order->products[$i]['id']) . "'"); $db->Execute("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%f', $this->products[$i]['qty']) . " where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); $sql_data_array = array('orders_id' => $zf_insert_id, 'products_id' => zen_get_prid($this->products[$i]['id']), 'products_model' => $this->products[$i]['model'], 'products_name' => $this->products[$i]['name'], 'products_price' => $this->products[$i]['price'], 'final_price' => $this->products[$i]['final_price'], 'onetime_charges' => $this->products[$i]['onetime_charges'], 'products_tax' => $this->products[$i]['tax'], 'products_quantity' => $this->products[$i]['qty'], 'products_priced_by_attribute' => $this->products[$i]['products_priced_by_attribute'], 'product_is_free' => $this->products[$i]['product_is_free'], 'products_discount_type' => $this->products[$i]['products_discount_type'], 'products_discount_type_from' => $this->products[$i]['products_discount_type_from'], 'products_prid' => $this->products[$i]['id']); zen_db_perform(TABLE_ORDERS_PRODUCTS, $sql_data_array); $order_products_id = $db->Insert_ID(); $order_total_modules->update_credit_account($i); //ICW ADDED FOR CREDIT CLASS SYSTEM //------insert customer choosen option to order-------- $attributes_exist = '0'; $this->products_ordered_attributes = ''; if (isset($this->products[$i]['attributes'])) { $attributes_exist = '1'; for ($j = 0, $n2 = sizeof($this->products[$i]['attributes']); $j < $n2; $j++) { if (DOWNLOAD_ENABLED == 'true') { $attributes_query = "select popt.products_options_name, poval.products_options_values_name,\r\n pa.options_values_price, pa.price_prefix,\r\n pa.product_attribute_is_free, pa.products_attributes_weight, pa.products_attributes_weight_prefix,\r\n pa.attributes_discounted, pa.attributes_price_base_included, pa.attributes_price_onetime,\r\n pa.attributes_price_factor, pa.attributes_price_factor_offset,\r\n pa.attributes_price_factor_onetime, pa.attributes_price_factor_onetime_offset,\r\n pa.attributes_qty_prices, pa.attributes_qty_prices_onetime,\r\n pa.attributes_price_words, pa.attributes_price_words_free,\r\n pa.attributes_price_letters, pa.attributes_price_letters_free,\r\n pad.products_attributes_maxdays, pad.products_attributes_maxcount, pad.products_attributes_filename,\r\n pa.product_attribute_is_free, pa.attributes_discounted\r\n from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa\r\n left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad\r\n on pa.products_attributes_id=pad.products_attributes_id\r\n where pa.products_id = '" . zen_db_input($this->products[$i]['id']) . "'\r\n and pa.options_id = '" . $this->products[$i]['attributes'][$j]['option_id'] . "'\r\n and pa.options_id = popt.products_options_id\r\n and pa.options_values_id = '" . $this->products[$i]['attributes'][$j]['value_id'] . "'\r\n and pa.options_values_id = poval.products_options_values_id\r\n and popt.language_id = '" . $_SESSION['languages_id'] . "'\r\n and poval.language_id = '" . $_SESSION['languages_id'] . "'"; $attributes_values = $db->Execute($attributes_query); } else { $attributes_values = $db->Execute("select popt.products_options_name, poval.products_options_values_name,\r\n pa.options_values_price, pa.price_prefix,\r\n pa.product_attribute_is_free, pa.products_attributes_weight, pa.products_attributes_weight_prefix,\r\n pa.attributes_discounted, pa.attributes_price_base_included, pa.attributes_price_onetime,\r\n pa.attributes_price_factor, pa.attributes_price_factor_offset,\r\n pa.attributes_price_factor_onetime, pa.attributes_price_factor_onetime_offset,\r\n pa.attributes_qty_prices, pa.attributes_qty_prices_onetime,\r\n pa.attributes_price_words, pa.attributes_price_words_free,\r\n pa.attributes_price_letters, pa.attributes_price_letters_free\r\n from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa\r\n where pa.products_id = '" . $this->products[$i]['id'] . "' and pa.options_id = '" . $this->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . $this->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $_SESSION['languages_id'] . "' and poval.language_id = '" . $_SESSION['languages_id'] . "'"); } //clr 030714 update insert query. changing to use values form $order->products for products_options_values. $sql_data_array = array('orders_id' => $zf_insert_id, 'orders_products_id' => $order_products_id, 'products_options' => $attributes_values->fields['products_options_name'], 'products_options_values' => $this->products[$i]['attributes'][$j]['value'], 'options_values_price' => $attributes_values->fields['options_values_price'], 'price_prefix' => $attributes_values->fields['price_prefix'], 'product_attribute_is_free' => $attributes_values->fields['product_attribute_is_free'], 'products_attributes_weight' => $attributes_values->fields['products_attributes_weight'], 'products_attributes_weight_prefix' => $attributes_values->fields['products_attributes_weight_prefix'], 'attributes_discounted' => $attributes_values->fields['attributes_discounted'], 'attributes_price_base_included' => $attributes_values->fields['attributes_price_base_included'], 'attributes_price_onetime' => $attributes_values->fields['attributes_price_onetime'], 'attributes_price_factor' => $attributes_values->fields['attributes_price_factor'], 'attributes_price_factor_offset' => $attributes_values->fields['attributes_price_factor_offset'], 'attributes_price_factor_onetime' => $attributes_values->fields['attributes_price_factor_onetime'], 'attributes_price_factor_onetime_offset' => $attributes_values->fields['attributes_price_factor_onetime_offset'], 'attributes_qty_prices' => $attributes_values->fields['attributes_qty_prices'], 'attributes_qty_prices_onetime' => $attributes_values->fields['attributes_qty_prices_onetime'], 'attributes_price_words' => $attributes_values->fields['attributes_price_words'], 'attributes_price_words_free' => $attributes_values->fields['attributes_price_words_free'], 'attributes_price_letters' => $attributes_values->fields['attributes_price_letters'], 'attributes_price_letters_free' => $attributes_values->fields['attributes_price_letters_free'], 'products_options_id' => $this->products[$i]['attributes'][$j]['option_id'], 'products_options_values_id' => $this->products[$i]['attributes'][$j]['value_id'], 'products_prid' => $this->products[$i]['id']); zen_db_perform(TABLE_ORDERS_PRODUCTS_ATTRIBUTES, $sql_data_array); if (DOWNLOAD_ENABLED == 'true' && isset($attributes_values->fields['products_attributes_filename']) && zen_not_null($attributes_values->fields['products_attributes_filename'])) { $sql_data_array = array('orders_id' => $zf_insert_id, 'orders_products_id' => $order_products_id, 'orders_products_filename' => $attributes_values->fields['products_attributes_filename'], 'download_maxdays' => $attributes_values->fields['products_attributes_maxdays'], 'download_count' => $attributes_values->fields['products_attributes_maxcount'], 'products_prid' => $this->products[$i]['id']); zen_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array); } //clr 030714 changing to use values from $orders->products and adding call to zen_decode_specialchars() // $this->products_ordered_attributes .= "\n\t" . $attributes_values->fields['products_options_name'] . ' ' . $attributes_values->fields['products_options_values_name']; $this->products_ordered_attributes .= "\n\t" . $attributes_values->fields['products_options_name'] . ' ' . zen_decode_specialchars($this->products[$i]['attributes'][$j]['value']); } } //------insert customer choosen option eof ---- $this->total_weight += $this->products[$i]['qty'] * $this->products[$i]['weight']; $this->total_tax += zen_calculate_tax($total_products_price, $products_tax) * $this->products[$i]['qty']; $this->total_cost += $total_products_price; // include onetime charges $this->products_ordered .= $this->products[$i]['qty'] . ' x ' . $this->products[$i]['name'] . ($this->products[$i]['model'] != '' ? ' (' . $this->products[$i]['model'] . ') ' : '') . ' = ' . $currencies->display_price($this->products[$i]['final_price'], $this->products[$i]['tax'], $this->products[$i]['qty']) . ($this->products[$i]['onetime_charges'] != 0 ? "\n" . TEXT_ONETIME_CHARGES_EMAIL . $currencies->display_price($this->products[$i]['onetime_charges'], $this->products[$i]['tax'], 1) : '') . $this->products_ordered_attributes . "\n"; $this->products_ordered_html .= '<tr>' . '<td class="product-details" align="right" valign="top" width="30">' . $this->products[$i]['qty'] . ' x</td>' . '<td class="product-details" valign="top">' . $this->products[$i]['name'] . ($this->products[$i]['model'] != '' ? ' (' . $this->products[$i]['model'] . ') ' : '') . '<nobr><small><em> ' . $this->products_ordered_attributes . '</em></small></nobr></td>' . '<td class="product-details-num" valign="top" align="right">' . $currencies->display_price($this->products[$i]['final_price'], $this->products[$i]['tax'], $this->products[$i]['qty']) . ($this->products[$i]['onetime_charges'] != 0 ? '</td></tr><tr><td class="product-details">' . TEXT_ONETIME_CHARGES_EMAIL . '</td>' . '<td>' . $currencies->display_price($this->products[$i]['onetime_charges'], $this->products[$i]['tax'], 1) : '') . '</td></tr>'; } $order_total_modules->apply_credit(); //ICW ADDED FOR CREDIT CLASS SYSTEM }
function build_li_totals($oID) { global $db; $id = $this->timeframe_id; // if we have to filter on manufacturer, the SQL is totally different if ($this->manufacturer) { $products_sql = "select op.* from " . TABLE_ORDERS_PRODUCTS . " op, " . TABLE_PRODUCTS . " p\n where p.products_id = op.products_id\n and p.manufacturers_id = " . $this->manufacturer . "\n and op.orders_id = '" . $oID . "'" . $this->product_filter; } else { $products_sql = "select op.* from " . TABLE_ORDERS_PRODUCTS . " op\n where op.orders_id = '" . $oID . "'" . $this->product_filter; } $products = $db->Execute($products_sql); // these "order_" variables are local to the build_li_totals() function. They // are used to determine order total, timeframe grand total, and order count $order_goods = 0; $order_tax = 0; $order_shipping = 0; $order_discount = 0; $order_gc_sold = 0; $order_gc_used = 0; while (!$products->EOF) { // assign key values to shorter variables for clarity $pID = $products->fields['products_id']; $final_price = $products->fields['final_price']; $quantity = $products->fields['products_quantity']; $tax = $products->fields['products_tax']; $onetime_charges = $products->fields['onetime_charges']; $model = zen_db_output($products->fields['products_model']); // do the math // gift certificates aren't products, so we must separate those out if (substr($model, 0, 4) == 'GIFT') { $order_gc_sold += $final_price * $quantity; $this->timeframe[$id]['total']['gc_sold'] += $final_price * $quantity; $this->build_li_orders($oID, 'gc_sold', $final_price * $quantity); $this->timeframe[$id]['total']['gc_sold_qty'] += $quantity; $this->build_li_orders($oID, 'gc_sold_qty', $quantity); $order_goods += $onetime_charges; $this->timeframe[$id]['total']['goods'] += $onetime_charges; $this->build_li_orders($oID, 'goods', $onetime_charges); } else { $order_goods += $final_price * $quantity + $onetime_charges; $this->timeframe[$id]['total']['goods'] += $final_price * $quantity + $onetime_charges; $this->build_li_orders($oID, 'goods', $final_price * $quantity + $onetime_charges); $this->timeframe[$id]['total']['num_products'] += $quantity; $this->build_li_orders($oID, 'num_products', $quantity); } // future code - currently being pulled from orders_total table for better accuracy // calculate tax values //$this->timeframe[$id]['total']['tax'] += zen_calculate_tax($onetime_charges, $tax); //$this->timeframe[$id]['total']['tax'] += zen_calculate_tax(($final_price * $quantity), $tax); // check to see if product is unique in this timeframe // add to 'diff_products' array if so $diff_prod_total = $this->unique_count($pID, $this->timeframe[$id]['total']['diff_products']); if ($diff_prod_total) { $this->timeframe[$id]['total']['diff_products'][] = $pID; } $diff_prod_order = $this->unique_count($pID, $this->timeframe[$id]['orders'][$oID]['diff_products']); if ($diff_prod_order) { $this->timeframe[$id]['orders'][$oID]['diff_products'][] = $pID; } // build product line items (if requested) if ($this->detail_level == 'product' || $this->detail_level == 'matrix') { // build array of product info so the function already has what it needs, avoiding another query $product_tax = zen_calculate_tax($onetime_charges, $tax) + zen_calculate_tax($final_price * $quantity, $tax); $this_product = array('id' => $pID, 'name' => $products->fields['products_name'], 'model' => $model, 'base_price' => $products->fields['products_price'], 'quantity' => $quantity, 'tax' => $product_tax, 'onetime_charges' => $onetime_charges, 'total' => $final_price * $quantity + $onetime_charges); $this->build_li_products($this_product); } $products->MoveNext(); } // pull shipping, discounts, tax, and gift certificates used from orders_total table $totals = $db->Execute("select * from " . TABLE_ORDERS_TOTAL . " where orders_id = '" . $oID . "'"); while (!$totals->EOF) { $class = $totals->fields['class']; $value = $totals->fields['value']; if ($class != "ot_total" && $class != "ot_subtotal") { if ($class == "ot_gv") { $order_gc_used += $value; $this->timeframe[$id]['total']['gc_used'] += $value; $this->build_li_orders($oID, 'gc_used', $value); $this->timeframe[$id]['total']['gc_used_qty']++; $this->build_li_orders($oID, 'gc_used_qty', 1); } elseif ($class == "ot_coupon" || $class == "ot_group_pricing") { $order_discount += $value; $this->timeframe[$id]['total']['discount'] += $value; $this->build_li_orders($oID, 'discount', $value); $this->timeframe[$id]['total']['discount_qty']++; $this->build_li_orders($oID, 'discount_qty', 1); } elseif ($class == "ot_tax") { $order_tax += $value; $this->timeframe[$id]['total']['tax'] += $value; $this->build_li_orders($oID, 'tax', $value); } elseif ($class == "ot_shipping") { $order_shipping += $value; $this->timeframe[$id]['total']['shipping'] += $value; $this->build_li_orders($oID, 'shipping', $value); } elseif ($value < 0) { $order_discount += abs($value); $this->timeframe[$id]['total']['discount'] += abs($value); $this->build_li_orders($oID, 'discount', abs($value)); $this->timeframe[$id]['total']['discount_qty']++; $this->build_li_orders($oID, 'discount_qty', 1); } } $totals->MoveNext(); } // we want to count an order if it has a value in any category $order_values = $order_goods + $order_tax + $order_shipping + $order_gc_sold + $order_discount + $order_gc_used; if ($order_values != 0) { $this->timeframe[$id]['total']['num_orders']++; $this->build_li_orders($oID, 'has_no_value', false); // add up stored values for order grand total // (goods + tax + shipping + gc_sold) - (discount + gc_used) $order_total = $order_goods + $order_tax + $order_shipping + $order_gc_sold - ($order_discount + $order_gc_used); if ($this->detail_level == 'order' || $this->detail_level == 'matrix') { $this->build_li_orders($oID, 'grand', $order_total); } return $order_total; } else { $this->build_li_orders($oID, 'has_no_value', true); return 0; } }
function zen_add_tax_invoice($price, $tax) { global $currencies; return zen_round($price, $currencies->currencies[DEFAULT_CURRENCY]['decimal_places']) + zen_calculate_tax($price, $tax); }
/** * Enter description here... * * @return unknown */ function get_order_total() { global $order; $order_total_tax = $order->info['tax']; $order_total = $order->info['total']; if ($this->include_shipping != 'true') { $order_total -= $order->info['shipping_cost']; } if ($this->include_tax != 'true') { $order_total -= $order->info['tax']; } $orderTotalFull = $order_total; $products = $_SESSION['cart']->get_products(); for ($i = 0; $i < sizeof($products); $i++) { if (!is_product_valid($products[$i]['id'], $_SESSION['cc_id'])) { $order_total -= $products[$i]['final_price'] * $products[$i]['quantity']; if ($this->include_tax == 'true') { $products_tax = zen_get_tax_rate($products[$i]['tax_class_id']); $order_total -= zen_calculate_tax($products[$i]['final_price'], $products_tax) * $products[$i]['quantity']; } $order_total_tax -= zen_calculate_tax($products[$i]['final_price'], zen_get_tax_rate($products[$i]['tax_class_id'])) * $products[$i]['quantity']; } } $order_total = array('totalFull' => $orderTotalFull, 'total' => $order_total, 'tax' => $order_total_tax); return $order_total; }
function process() { global $order, $currencies; if (MODULE_ORDER_TOTAL_LOWORDERFEE_LOW_ORDER_FEE == 'true') { switch (MODULE_ORDER_TOTAL_LOWORDERFEE_DESTINATION) { case 'national': if ($order->delivery['country_id'] == STORE_COUNTRY) { $pass = true; } break; case 'international': if ($order->delivery['country_id'] != STORE_COUNTRY) { $pass = true; } break; case 'both': $pass = true; break; default: $pass = false; break; } // if ( ($pass == true) && ( ($order->info['total'] - $order->info['shipping_cost']) < MODULE_ORDER_TOTAL_LOWORDERFEE_ORDER_UNDER) ) { if ($pass == true && $order->info['subtotal'] < MODULE_ORDER_TOTAL_LOWORDERFEE_ORDER_UNDER) { $charge_it = 'true'; $cart_content_type = $_SESSION['cart']->get_content_type(); $gv_content_only = $_SESSION['cart']->gv_only(); if ($cart_content_type == 'physical' or $cart_content_type == 'mixed') { $charge_it = 'true'; } else { // check to see if everything is virtual, if so - skip the low order fee. if ($cart_content_type == 'virtual' and MODULE_ORDER_TOTAL_LOWORDERFEE_VIRTUAL == 'true') { $charge_it = 'false'; if ($gv_content_only > 0 and MODULE_ORDER_TOTAL_LOWORDERFEE_GV == 'false') { $charge_it = 'true'; } } if ($gv_content_only > 0 and MODULE_ORDER_TOTAL_LOWORDERFEE_GV == 'true') { // check to see if everything is gift voucher, if so - skip the low order fee. $charge_it = 'false'; if ($cart_content_type == 'virtual' and MODULE_ORDER_TOTAL_LOWORDERFEE_VIRTUAL == 'false') { $charge_it = 'true'; } } } if ($charge_it == 'true') { $tax_address = zen_get_tax_locations(); $tax = zen_get_tax_rate(MODULE_ORDER_TOTAL_LOWORDERFEE_TAX_CLASS, $tax_address['country_id'], $tax_address['zone_id']); $tax_description = zen_get_tax_description(MODULE_ORDER_TOTAL_LOWORDERFEE_TAX_CLASS, $tax_address['country_id'], $tax_address['zone_id']); // calculate from flat fee or percentage if (substr(MODULE_ORDER_TOTAL_LOWORDERFEE_FEE, -1) == '%') { $low_order_fee = $order->info['subtotal'] * (MODULE_ORDER_TOTAL_LOWORDERFEE_FEE / 100); } else { $low_order_fee = MODULE_ORDER_TOTAL_LOWORDERFEE_FEE; } $order->info['tax'] += zen_calculate_tax($low_order_fee, $tax); $order->info['tax_groups']["{$tax_description}"] += zen_calculate_tax($low_order_fee, $tax); $order->info['total'] += $low_order_fee + zen_calculate_tax($low_order_fee, $tax); if (DISPLAY_PRICE_WITH_TAX == 'true') { $low_order_fee += zen_calculate_tax($low_order_fee, $tax); } $this->output[] = array('title' => $this->title . ':', 'text' => $currencies->format($low_order_fee, true, $order->info['currency'], $order->info['currency_value']), 'value' => $low_order_fee); } } } }
function calculate_deductions($order_total) { global $db, $order, $messageStack; $od_amount = array(); $deduction = $this->calculate_credit($this->get_order_total()); $od_amount['total'] = $deduction; switch ($this->calculate_tax) { case 'None': $remainder = $order->info['total'] - $od_amount['total']; $tax_deduct = $order->info['tax'] - $remainder; // division by 0 if ($order->info['tax'] <= 0) { $ratio_tax = 0; } else { $ratio_tax = $tax_deduct / $order->info['tax']; } $tax_deduct = 0; /* if ($this->include_tax) { reset($order->info['tax_groups']); foreach ($order->info['tax_groups'] as $key=>$value) { $od_amount['tax_groups'][$key] = $order->info['tax_groups'][$key] * $ratio_tax; $tax_deduct += $od_amount['tax_groups'][$key]; } } */ $od_amount['tax'] = $tax_deduct; break; case 'Standard': if ($od_amount['total'] >= $order_total) { $ratio = 1; } else { $ratio = $od_amount['total'] / ($order_total - $order->info['tax']); } reset($order->info['tax_groups']); $tax_deduct = 0; foreach ($order->info['tax_groups'] as $key => $value) { $od_amount['tax_groups'][$key] = $order->info['tax_groups'][$key] * $ratio; $tax_deduct += $od_amount['tax_groups'][$key]; } $od_amount['tax'] = $tax_deduct; break; case 'Credit Note': $od_amount['total'] = $deduction; $tax_rate = zen_get_tax_rate($this->tax_class); $od_amount['tax'] = zen_calculate_tax($deduction, $tax_rate); $tax_description = zen_get_tax_description($this->tax_class); $od_amount['tax_groups'][$tax_description] = $od_amount['tax']; break; default: } return $od_amount; }
function get_order_total($couponCode) { global $order; $orderTaxGroups = $order->info['tax_groups']; $orderTotalTax = $order->info['tax']; $orderTotal = $order->info['total']; // left for total order amount vs qualified order amount just switch the commented lines $orderTotalFull = $orderTotal; $products = $_SESSION['cart']->get_products(); for ($i = 0; $i < sizeof($products); $i++) { if (!is_product_valid($products[$i]['id'], $couponCode)) { $products_tax = zen_get_tax_rate($products[$i]['tax_class_id']); $productsTaxAmount = zen_calculate_tax($products[$i]['final_price'], $products_tax) * $products[$i]['quantity']; $orderTotal -= $products[$i]['final_price'] * $products[$i]['quantity']; if ($this->include_tax == 'true') { $orderTotal -= $productsTaxAmount; } if (DISPLAY_PRICE_WITH_TAX == 'true') { $orderTotal -= $productsTaxAmount; } $orderTaxGroups[zen_get_tax_description($products[$i]['tax_class_id'])] -= $productsTaxAmount; $orderTotalTax -= zen_calculate_tax($products[$i]['final_price'], zen_get_tax_rate($products[$i]['tax_class_id'])) * $products[$i]['quantity']; } } if ($this->include_shipping != 'true') { $orderTotal -= $order->info['shipping_cost']; if (isset($_SESSION['shipping_tax_description']) && $_SESSION['shipping_tax_description'] != '') { $orderTaxGroups[$_SESSION['shipping_tax_description']] -= $order->info['shipping_tax']; $orderTotalTax -= $order->info['shipping_tax']; } } if (DISPLAY_PRICE_WITH_TAX != 'true') { $orderTotal -= $order->info['tax']; } // left for total order amount vs qualified order amount - $orderTotalFull return array('totalFull' => $orderTotalFull, 'orderTotal' => $orderTotal, 'orderTaxGroups' => $orderTaxGroups, 'orderTax' => $orderTotalTax, 'shipping' => $order->info['shipping_cost'], 'shippingTax' => $order->info['shipping_tax']); }
/** * Prepare subtotal and line-item detail content to send to PayPal */ function getLineItemDetails($restrictedCurrency) { global $order, $currencies, $order_totals, $order_total_modules; // if not default currency, do not send subtotals or line-item details if (DEFAULT_CURRENCY != $order->info['currency'] || $restrictedCurrency != DEFAULT_CURRENCY) { $this->zcLog('getLineItemDetails 1', 'Not using default currency. Thus, no line-item details can be submitted.'); return array(); } if ($currencies->currencies[$_SESSION['currency']]['value'] != 1 || $currencies->currencies[$order->info['currency']]['value'] != 1) { $this->zcLog('getLineItemDetails 2', 'currency val not equal to 1.0000 - cannot proceed without coping with currency conversions. Aborting line-item details.'); return array(); } $optionsST = array(); $optionsLI = array(); $optionsNB = array(); $numberOfLineItemsProcessed = 0; $creditsApplied = 0; $surcharges = 0; $sumOfLineItems = 0; $sumOfLineTax = 0; $optionsST['AMT'] = 0; $optionsST['ITEMAMT'] = 0; $optionsST['TAXAMT'] = 0; $optionsST['SHIPPINGAMT'] = 0; $optionsST['SHIPDISCAMT'] = 0; $optionsST['HANDLINGAMT'] = 0; $optionsST['INSURANCEAMT'] = 0; $flagSubtotalsUnknownYet = true; $subTotalLI = 0; $subTotalTax = 0; $subTotalShipping = 0; $subtotalPRE = array('no data'); $discountProblemsFlag = FALSE; $flag_treat_as_partial = FALSE; if (sizeof($order_totals)) { // prepare subtotals for ($i = 0, $n = sizeof($order_totals); $i < $n; $i++) { if ($order_totals[$i]['code'] == '') { continue; } if (in_array($order_totals[$i]['code'], array('ot_total', 'ot_subtotal', 'ot_tax', 'ot_shipping')) || strstr($order_totals[$i]['code'], 'insurance')) { if ($order_totals[$i]['code'] == 'ot_shipping') { $optionsST['SHIPPINGAMT'] = round($order_totals[$i]['value'], 2); } if ($order_totals[$i]['code'] == 'ot_total') { $optionsST['AMT'] = round($order_totals[$i]['value'], 2); } if ($order_totals[$i]['code'] == 'ot_tax') { $optionsST['TAXAMT'] = round($order_totals[$i]['value'], 2); } if ($order_totals[$i]['code'] == 'ot_subtotal') { $optionsST['ITEMAMT'] = round($order_totals[$i]['value'], 2); } if (strstr($order_totals[$i]['code'], 'insurance')) { $optionsST['INSURANCEAMT'] += round($order_totals[$i]['value'], 2); } //$optionsST['SHIPDISCAMT'] = ''; // Not applicable } else { // handle other order totals: global ${$order_totals[$i]['code']}; if (substr($order_totals[$i]['text'], 0, 1) == '-' || isset(${$order_totals[$i]['code']}->credit_class) && ${$order_totals[$i]['code']}->credit_class == true) { // handle credits $creditsApplied += round($order_totals[$i]['value'], 2); } else { // treat all other OT's as if they're related to handling fees or other extra charges to be added/included $surcharges += $order_totals[$i]['value']; } } } if ($creditsApplied > 0) { $optionsST['ITEMAMT'] -= $creditsApplied; } if ($surcharges > 0) { $optionsST['ITEMAMT'] += $surcharges; } // Handle tax-included scenario if (DISPLAY_PRICE_WITH_TAX == 'true') { $optionsST['TAXAMT'] = 0; } $subtotalPRE = $optionsST; // Move shipping tax amount from Tax subtotal into Shipping subtotal for submission to PayPal, since PayPal applies tax to each line-item individually $module = substr($_SESSION['shipping']['id'], 0, strpos($_SESSION['shipping']['id'], '_')); if (zen_not_null($order->info['shipping_method']) && DISPLAY_PRICE_WITH_TAX != 'true') { if ($GLOBALS[$module]->tax_class > 0) { $shipping_tax_basis = !isset($GLOBALS[$module]->tax_basis) ? STORE_SHIPPING_TAX_BASIS : $GLOBALS[$module]->tax_basis; $shippingOnBilling = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->billing['country']['id'], $order->billing['zone_id']); $shippingOnDelivery = zen_get_tax_rate($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); if ($shipping_tax_basis == 'Billing') { $shipping_tax = $shippingOnBilling; } elseif ($shipping_tax_basis == 'Shipping') { $shipping_tax = $shippingOnDelivery; } else { if (STORE_ZONE == $order->billing['zone_id']) { $shipping_tax = $shippingOnBilling; } elseif (STORE_ZONE == $order->delivery['zone_id']) { $shipping_tax = $shippingOnDelivery; } else { $shipping_tax = 0; } } $taxAdjustmentForShipping = zen_round(zen_calculate_tax($order->info['shipping_cost'], $shipping_tax), $currencies->currencies[$_SESSION['currency']]['decimal_places']); $optionsST['SHIPPINGAMT'] += $taxAdjustmentForShipping; $optionsST['TAXAMT'] -= $taxAdjustmentForShipping; } } $flagSubtotalsUnknownYet = $optionsST['SHIPPINGAMT'] + $optionsST['SHIPDISCAMT'] + $optionsST['AMT'] + $optionsST['TAXAMT'] + $optionsST['ITEMAMT'] + $optionsST['INSURANCEAMT'] == 0; } else { // if we get here, we don't have any order-total information yet because the customer has clicked Express before starting normal checkout flow // thus, we must make a note to manually calculate subtotals, rather than relying on the more robust order-total infrastructure $flagSubtotalsUnknownYet = TRUE; } // loop thru all products to prepare details of quantity and price. for ($i = 0, $n = sizeof($order->products), $k = 0; $i < $n; $i++, $k++) { // PayPal won't accept zero-value line-items, so skip this entry if price is zero if ($order->products[$i]['final_price'] == 0) { continue; } $optionsLI["L_NUMBER{$k}"] = $order->products[$i]['model']; $optionsLI["L_NAME{$k}"] = $order->products[$i]['name']; // Append *** if out-of-stock. $optionsLI["L_NAME{$k}"] .= zen_get_products_stock($order->products[$i]['id']) - $order->products[$i]['qty'] < 0 ? STOCK_MARK_PRODUCT_OUT_OF_STOCK : ''; // if there are attributes, loop thru them and add to description if (isset($order->products[$i]['attributes']) && sizeof($order->products[$i]['attributes']) > 0) { $optionsLI["L_DESC{$k}"] = ''; for ($j = 0, $n2 = sizeof($order->products[$i]['attributes']); $j < $n2; $j++) { $optionsLI["L_DESC{$k}"] .= "\n " . $order->products[$i]['attributes'][$j]['option'] . ': ' . $order->products[$i]['attributes'][$j]['value']; } // end loop } // endif attribute-info // check for rounding problems with taxes $m1 = zen_round($order->products[$i]['qty'] * $order->products[$i]['final_price'], $currencies->currencies[$_SESSION['currency']]['decimal_places']); $m2 = $order->products[$i]['qty'] * zen_round($order->products[$i]['final_price'], $currencies->currencies[$_SESSION['currency']]['decimal_places']); $n1 = $order->products[$i]['qty'] * zen_calculate_tax($order->products[$i]['final_price'], $order->products[$i]['tax']); $n2 = zen_calculate_tax($order->products[$i]['qty'] * $order->products[$i]['final_price'], $order->products[$i]['tax']); if ($m1 != $m2 || zen_round($n1, $currencies->currencies[$_SESSION['currency']]['decimal_places']) != zen_round($n2, $currencies->currencies[$_SESSION['currency']]['decimal_places'])) { $flag_treat_as_partial = true; } // PayPal can't handle partial-quantity values, so fudge it here if ($flag_treat_as_partial || $order->products[$i]['qty'] != (int) $order->products[$i]['qty']) { $optionsLI["L_NAME{$k}"] = '(' . $order->products[$i]['qty'] . ' x ) ' . $optionsLI["L_NAME{$k}"]; $optionsLI["L_AMT{$k}"] = zen_round($order->products[$i]['qty'] * $order->products[$i]['final_price'], $currencies->currencies[$_SESSION['currency']]['decimal_places']); $optionsLI["L_TAXAMT{$k}"] = zen_calculate_tax(zen_round($order->products[$i]['qty'] * $order->products[$i]['final_price'], $currencies->currencies[$_SESSION['currency']]['decimal_places']), $order->products[$i]['tax']); $optionsLI["L_QTY{$k}"] = 1; } else { $optionsLI["L_AMT{$k}"] = $order->products[$i]['final_price']; $optionsLI["L_QTY{$k}"] = $order->products[$i]['qty']; $optionsLI["L_TAXAMT{$k}"] = zen_calculate_tax(1 * $order->products[$i]['final_price'], $order->products[$i]['tax']); } // For tax-included pricing, combine tax with price instead of treating separately: if (DISPLAY_PRICE_WITH_TAX == 'true') { $optionsLI["L_AMT{$k}"] += $optionsLI["L_TAXAMT{$k}"]; $optionsLI["L_TAXAMT{$k}"] = 0; } $subTotalLI += $optionsLI["L_QTY{$k}"] * $optionsLI["L_AMT{$k}"]; $subTotalTax += $optionsLI["L_QTY{$k}"] * $optionsLI["L_TAXAMT{$k}"]; // add line-item for one-time charges on this product if ($order->products[$i]['onetime_charges'] != 0) { $k++; $optionsLI["L_NAME{$k}"] = MODULES_PAYMENT_PAYPALWPP_LINEITEM_TEXT_ONETIME_CHARGES_PREFIX . substr(htmlentities($order->products[$i]['name'], ENT_QUOTES, 'UTF-8'), 0, 120); $optionsLI["L_AMT{$k}"] = $order->products[$i]['onetime_charges']; $optionsLI["L_QTY{$k}"] = 1; $optionsLI["L_TAXAMT{$k}"] = zen_calculate_tax($order->products[$i]['onetime_charges'], $order->products[$i]['tax']); $subTotalLI += $order->products[$i]['onetime_charges']; $subTotalTax += $optionsLI["L_TAXAMT{$k}"]; } $numberOfLineItemsProcessed = $k; } // end for loopthru all products // add line items for any surcharges added by order-total modules if ($surcharges > 0) { $numberOfLineItemsProcessed++; $k = $numberOfLineItemsProcessed; $optionsLI["L_NAME{$k}"] = MODULES_PAYMENT_PAYPALWPP_LINEITEM_TEXT_SURCHARGES_SHORT; $optionsLI["L_DESC{$k}"] = MODULES_PAYMENT_PAYPALWPP_LINEITEM_TEXT_SURCHARGES_LONG; $optionsLI["L_AMT{$k}"] = $surcharges; $optionsLI["L_QTY{$k}"] = 1; $subTotalLI += $surcharges; } // add line items for discounts such as gift certificates and coupons if ($creditsApplied > 0) { $numberOfLineItemsProcessed++; $k = $numberOfLineItemsProcessed; $optionsLI["L_NAME{$k}"] = MODULES_PAYMENT_PAYPALWPP_LINEITEM_TEXT_DISCOUNTS_SHORT; $optionsLI["L_DESC{$k}"] = MODULES_PAYMENT_PAYPALWPP_LINEITEM_TEXT_DISCOUNTS_LONG; $optionsLI["L_AMT{$k}"] = -1 * $creditsApplied; $optionsLI["L_QTY{$k}"] = 1; $subTotalLI -= $creditsApplied; } // Reformat properly for ($k = 0, $n = $numberOfLineItemsProcessed + 1; $k < $n; $k++) { // Replace & and = and % with * if found. $optionsLI["L_NAME{$k}"] = str_replace(array('&', '=', '%'), '*', $optionsLI["L_NAME{$k}"]); if (isset($optionsLI["L_DESC{$k}"])) { $optionsLI["L_DESC{$k}"] = str_replace(array('&', '=', '%'), '*', $optionsLI["L_DESC{$k}"]); } if (isset($optionsLI["L_NUMBER{$k}"])) { $optionsLI["L_NUMBER{$k}"] = str_replace(array('&', '=', '%'), '*', $optionsLI["L_NUMBER{$k}"]); } // Remove HTML markup if found $optionsLI["L_NAME{$k}"] = zen_clean_html($optionsLI["L_NAME{$k}"], 'strong'); if (isset($optionsLI["L_DESC{$k}"])) { $optionsLI["L_DESC{$k}"] = zen_clean_html($optionsLI["L_DESC{$k}"], 'strong'); } // reformat properly according to API specs $optionsLI["L_NAME{$k}"] = substr($optionsLI["L_NAME{$k}"], 0, 127); if (isset($optionsLI["L_NUMBER{$k}"])) { $optionsLI["L_NUMBER{$k}"] = substr($optionsLI["L_NUMBER{$k}"], 0, 127); } if (isset($optionsLI["L_DESC{$k}"]) && $optionsLI["L_DESC{$k}"] == '') { unset($optionsLI["L_DESC{$k}"]); } if (isset($optionsLI["L_DESC{$k}"])) { $optionsLI["L_DESC{$k}"] = substr($optionsLI["L_DESC{$k}"], 0, 127); } if (isset($optionsLI["L_TAXAMT{$k}"]) && ($optionsLI["L_TAXAMT{$k}"] != '' || $optionsLI["L_TAXAMT{$k}"] > 0)) { $optionsLI["L_TAXAMT{$k}"] = round($optionsLI["L_TAXAMT{$k}"], 2); } } /** * PayPal says their math works like this: * a) ITEMAMT = L_AMTn * L_QTYn * b) TAXAMT = L_QTYn * L_TAXAMTn * c) AMT = ITEMAMT + SHIPPINGAMT + HANDLINGAMT + TAXAMT */ // Sanity Check of line-item subtotals for ($j = 0; $j < $k; $j++) { $itemAMT = $optionsLI["L_AMT{$j}"]; $itemQTY = $optionsLI["L_QTY{$j}"]; $itemTAX = isset($optionsLI["L_TAXAMT{$j}"]) ? $optionsLI["L_TAXAMT{$j}"] : 0; $sumOfLineItems += $itemQTY * $itemAMT; $sumOfLineTax += $itemQTY * $itemTAX; } $sumOfLineItems = round($sumOfLineItems, 2); $sumOfLineTax = round($sumOfLineTax, 2); if ($sumOfLineItems == 0) { $sumOfLineTax = 0; $optionsLI = array(); $discountProblemsFlag = TRUE; if ($optionsST['SHIPPINGAMT'] == $optionsST['AMT']) { $optionsST['SHIPPINGAMT'] = 0; } } // Sanity check -- if tax-included pricing is causing problems, remove the numbers and put them in a comment instead: $stDiffTaxOnly = strval($sumOfLineItems - $sumOfLineTax - round($optionsST['AMT'], 2)) + 0; if (DISPLAY_PRICE_WITH_TAX == 'true' && $stDiffTaxOnly == 0) { $optionsNB['DESC'] = 'Tax included in prices: ' . $sumOfLineTax . ' (' . $optionsST['TAXAMT'] . ') '; $optionsST['TAXAMT'] = 0; for ($k = 0, $n = $numberOfLineItemsProcessed + 1; $k < $n; $k++) { if (isset($optionsLI["L_TAXAMT{$k}"])) { unset($optionsLI["L_TAXAMT{$k}"]); } } } // Do sanity check -- if any of the line-item subtotal math doesn't add up properly, skip line-item details, // so that the order can go through even though PayPal isn't being flexible to handle Zen Cart's diversity if (strval($subTotalTax) - strval($sumOfLineTax) > 0.02) { $this->zcLog('getLineItemDetails 3', 'Tax Subtotal does not match sum of taxes for line-items. Tax details are being removed from line-item submission data.' . "\n" . $sumOfLineTax . ' ' . $subTotalTax . print_r(array_merge($optionsST, $optionsLI), true)); for ($k = 0, $n = $numberOfLineItemsProcessed + 1; $k < $n; $k++) { if (isset($optionsLI["L_TAXAMT{$k}"])) { unset($optionsLI["L_TAXAMT{$k}"]); } } $subTotalTax = 0; $sumOfLineTax = 0; } // If coupons exist and there's a calculation problem, then it's likely that taxes are incorrect, so reset L_TAXAMTn values if ($creditsApplied > 0 && strval($optionsST['TAXAMT']) != strval($sumOfLineTax)) { $pre = $optionsLI; for ($k = 0, $n = $numberOfLineItemsProcessed + 1; $k < $n; $k++) { if (isset($optionsLI["L_TAXAMT{$k}"])) { unset($optionsLI["L_TAXAMT{$k}"]); } } $this->zcLog('getLineItemDetails 4', 'Coupons/Discounts have affected tax calculations, so tax details are being removed from line-item submission data.' . "\n" . $sumOfLineTax . ' ' . $optionsST['TAXAMT'] . "\n" . print_r(array_merge($optionsST, $pre, $optionsNB), true) . "\nAFTER:" . print_r(array_merge($optionsST, $optionsLI, $optionsNB), TRUE)); $subTotalTax = 0; $sumOfLineTax = 0; } if (TRUE) { // disable line-item tax details, leaving only TAXAMT subtotal as tax indicator for ($k = 0, $n = $numberOfLineItemsProcessed + 1; $k < $n; $k++) { if (isset($optionsLI["L_TAXAMT{$k}"])) { unset($optionsLI["L_TAXAMT{$k}"]); } } } // check subtotals if (strval($optionsST['ITEMAMT']) > 0 && strval($subTotalLI) > 0 && strval($subTotalLI) != strval($optionsST['ITEMAMT']) || strval($subTotalLI) - strval($sumOfLineItems) != 0) { $this->zcLog('getLineItemDetails 5', 'Line-item subtotals do not add up properly. Line-item-details skipped.' . "\n" . (double) $sumOfLineItems . ' ' . (double) $subTotalTax . print_r(array_merge($optionsST, $optionsLI), true)); $optionsLI = array(); } // check whether discounts are causing a problem if (strval($optionsST['ITEMAMT']) < 0) { $pre = array_merge($optionsST, $optionsLI); $optionsLI = array(); $optionsST['ITEMAMT'] = $optionsST['AMT']; if ($optionsST['AMT'] < $optionsST['TAXAMT']) { $optionsST['TAXAMT'] = 0; } if ($optionsST['AMT'] < $optionsST['SHIPPINGAMT']) { $optionsST['SHIPPINGAMT'] = 0; } $discountProblemsFlag = TRUE; $this->zcLog('getLineItemDetails 6', 'Discounts have caused the subtotal to calculate incorrectly. Line-item-details cannot be submitted.' . "\nBefore:" . print_r($pre, TRUE) . "\nAfter:" . print_r(array_merge($optionsST, $optionsLI), true)); } // if AMT or ITEMAMT values are 0 (ie: certain OT modules disabled) or we've started express checkout without going through normal checkout flow, we have to get subtotals manually if ((!isset($optionsST['AMT']) || $optionsST['AMT'] == 0 || $flagSubtotalsUnknownYet == TRUE || $optionsST['ITEMAMT'] == 0) && $discountProblemsFlag != TRUE) { $optionsST['ITEMAMT'] = $sumOfLineItems; $optionsST['TAXAMT'] = $sumOfLineTax; if ($subTotalShipping > 0) { $optionsST['SHIPPINGAMT'] = $subTotalShipping; } $optionsST['AMT'] = $sumOfLineItems + $optionsST['TAXAMT'] + $optionsST['SHIPPINGAMT']; } $this->zcLog('getLineItemDetails 7 - subtotal comparisons', 'BEFORE line-item calcs: ' . print_r($subtotalPRE, true) . ($flagSubtotalsUnknownYet == TRUE ? 'Subtotals Unknown Yet' : '') . ' - AFTER doing line-item calcs: ' . print_r(array_merge($optionsST, $optionsLI, $optionsNB), true)); // if subtotals are not adding up correctly, then skip sending any line-item or subtotal details to PayPal $stAll = round(strval($optionsST['ITEMAMT'] + $optionsST['TAXAMT'] + $optionsST['SHIPPINGAMT'] + $optionsST['SHIPDISCAMT'] + $optionsST['HANDLINGAMT'] + $optionsST['INSURANCEAMT']), 2); $stDiff = strval($optionsST['AMT'] - $stAll); $stDiffRounded = strval($stAll - round($optionsST['AMT'], 2)) + 0; // unset any subtotal values that are zero if (isset($optionsST['ITEMAMT']) && $optionsST['ITEMAMT'] == 0) { unset($optionsST['ITEMAMT']); } if (isset($optionsST['TAXAMT']) && $optionsST['TAXAMT'] == 0) { unset($optionsST['TAXAMT']); } if (isset($optionsST['SHIPPINGAMT']) && $optionsST['SHIPPINGAMT'] == 0) { unset($optionsST['SHIPPINGAMT']); } if (isset($optionsST['SHIPDISCAMT']) && $optionsST['SHIPDISCAMT'] == 0) { unset($optionsST['SHIPDISCAMT']); } if (isset($optionsST['HANDLINGAMT']) && $optionsST['HANDLINGAMT'] == 0) { unset($optionsST['HANDLINGAMT']); } if (isset($optionsST['INSURANCEAMT']) && $optionsST['INSURANCEAMT'] == 0) { unset($optionsST['INSURANCEAMT']); } // tidy up all values so that they comply with proper format (number_format(xxxx,2) for PayPal US use ) if (!defined('PAYPALWPP_SKIP_LINE_ITEM_DETAIL_FORMATTING') || PAYPALWPP_SKIP_LINE_ITEM_DETAIL_FORMATTING != 'true' || in_array($order->info['currency'], array('JPY', 'NOK'))) { if (is_array($optionsST)) { foreach ($optionsST as $key => $value) { $optionsST[$key] = number_format($value, $order->info['currency'] == 'JPY' ? 0 : 2); } } if (is_array($optionsLI)) { foreach ($optionsLI as $key => $value) { if (substr($key, 0, 8) == 'L_TAXAMT' && ($optionsLI[$key] == '' || $optionsLI[$key] == 0)) { unset($optionsLI[$key]); } else { if (strstr($key, 'AMT')) { $optionsLI[$key] = number_format($value, $order->info['currency'] == 'JPY' ? 0 : 2); } } } } } $this->zcLog('getLineItemDetails 8', 'checking subtotals... ' . "\n" . print_r(array_merge(array('calculated total' => number_format($stAll, $order->info['currency'] == 'JPY' ? 0 : 2)), $optionsST), true) . "\n-------------------\ndifference: " . ($stDiff + 0) . ' (abs+rounded: ' . ($stDiffRounded + 0) . ')'); if ($stDiffRounded != 0) { $this->zcLog('getLineItemDetails 9', 'Subtotals Bad. Skipping line-item/subtotal details'); return array(); } $this->zcLog('getLineItemDetails 10', 'subtotals balance - okay'); // Send Subtotal and LineItem results back to be submitted to PayPal return array_merge($optionsST, $optionsLI, $optionsNB); }
function process() { global $order, $currencies, $cod_cost; if (MODULE_ORDER_TOTAL_MONEY_COD_STATUS == 'true') { $tax = zen_get_tax_rate(MODULE_ORDER_TOTAL_MONEY_COD_TAX_CLASS); if ($_SESSION['payment'] == 'cod' && $_GET['main_page'] == 'checkout_confirmation') { // #8883 リクエストを改ざんして代金引替を指定した場合をエラーにする。 // 代金引換を指定後、確認画面で離脱した場合は、代金引換がセッションに積まれたままになるので // checkout_payment 画面でもこのチェックが実行される。 // 従って画面をチェックする。 if ($order->info['subtotal'] + $order->info['shipping_cost'] >= MODULE_ORDER_TOTAL_MONEY_COD_FEE_LIMIT) { // コンテンツが出力されているのでリダイレクトできない。 die('Bad request.'); } } $cod_fee_target_money = $order->info['subtotal']; /* // ot_subpoint 側の実装がよく分かってないので未対応とする // #8883 ポイントによる支払いは手数料計算対象金額に含めない。 if ( isset($GLOBALS['otsubpoint']) ) { $save_value = $GLOBALS['ot_subpoint']->pre_process_if_not_last_call(); $GLOBALS['ot_subpoint']->process(); $cod_fee_target_money = $cod_fee_target_money - $GLOBALS['ot_subpoint']->deduction; $GLOBALS['ot_subpoint']->post_process_if_not_last_call($save_value); } */ // #8883 配送料は手数料計算対象金額に含める。 $cod_fee_target_money = $cod_fee_target_money + $order->info['shipping_cost']; $cod_cost = ""; if ($_SESSION['payment'] == 'cod' && $cod_fee_target_money < MODULE_ORDER_TOTAL_MONEY_COD_FEE_LIMIT) { $tmp_cod_fee_list = split("[:,]", MODULE_ORDER_TOTAL_MONEY_COD_FEE_LIST); $list = array(); $i = 0; foreach ($tmp_cod_fee_list as $value) { if ($i % 2 == 0) { $list[] = array("limit" => $value, "fee" => $tmp_cod_fee_list[$i + 1]); } $i++; } //手数料計算 foreach ($list as $k => $v) { if ($v['limit'] >= $cod_fee_target_money) { if ($k == 0) { $cod_cost = $v['fee']; break; } } if (isset($list[$k + 1]) && $list[$k + 1]['limit'] >= $cod_fee_target_money) { $cod_cost = $list[$k + 1]['fee']; break; } } if ($cod_cost == "") { $cod_cost = 0; } $order->info['tax'] += zen_calculate_tax($cod_cost, $tax); $order->info['tax_groups']["{$tax}"] += zen_calculate_tax($cod_cost, $tax); $order->info['total'] += $cod_cost + zen_calculate_tax($cod_cost, $tax); $this->output[] = array('title' => TEXT_INFO_ORDER_TOTAL_MONEY_COD_TITLE . ':', 'text' => $currencies->format(zen_add_tax($cod_cost, $tax), true, $order->info['currency'], $order->info['currency_value']), 'value' => zen_add_tax($cod_cost, $tax)); } } }
function create_add_products($zf_insert_id, $zf_mode = false) { global $db, $currencies, $order_total_modules, $order_totals; // initialized for the email confirmation $this->products_ordered = ''; $this->products_ordered_html = ''; $this->subtotal = 0; $this->total_tax = 0; // lowstock email report $this->email_low_stock = ''; for ($i = 0, $n = sizeof($this->products); $i < $n; $i++) { $custom_insertable_text = ''; $this->doStockDecrement = STOCK_LIMITED == 'true'; $this->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_INIT', array('i' => $i), $this->products[$i], $i); // Stock Update - Joao Correia if ($this->doStockDecrement) { if (DOWNLOAD_ENABLED == 'true') { $stock_query_raw = "select p.products_quantity, pad.products_attributes_filename, p.product_is_always_free_shipping\n from " . TABLE_PRODUCTS . " p\n left join " . TABLE_PRODUCTS_ATTRIBUTES . " pa\n on p.products_id=pa.products_id\n left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad\n on pa.products_attributes_id=pad.products_attributes_id\n WHERE p.products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"; // Will work with only one option for downloadable products // otherwise, we have to build the query dynamically with a loop $products_attributes = $this->products[$i]['attributes']; if (is_array($products_attributes)) { $stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'"; } $stock_values = $db->Execute($stock_query_raw, false, false, 0, true); } else { $stock_values = $db->Execute("select * from " . TABLE_PRODUCTS . " where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'", false, false, 0, true); } $this->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_BEGIN', $i, $stock_values); if ($stock_values->RecordCount() > 0) { // do not decrement quantities if products_attributes_filename exists if (DOWNLOAD_ENABLED != 'true' || $stock_values->fields['product_is_always_free_shipping'] == 2 || !$stock_values->fields['products_attributes_filename']) { $stock_left = $stock_values->fields['products_quantity'] - $this->products[$i]['qty']; $this->products[$i]['stock_reduce'] = $this->products[$i]['qty']; } else { $stock_left = $stock_values->fields['products_quantity']; } // $this->products[$i]['stock_value'] = $stock_values->fields['products_quantity']; $db->Execute("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); // if ( ($stock_left < 1) && (STOCK_ALLOW_CHECKOUT == 'false') ) { if ($stock_left <= 0) { // only set status to off when not displaying sold out if (SHOW_PRODUCTS_SOLD_OUT == '0') { $db->Execute("update " . TABLE_PRODUCTS . " set products_status = 0 where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); } } // for low stock email if ($stock_left <= STOCK_REORDER_LEVEL) { // WebMakers.com Added: add to low stock email $this->email_low_stock .= 'ID# ' . zen_get_prid($this->products[$i]['id']) . "\t\t" . $this->products[$i]['model'] . "\t\t" . $this->products[$i]['name'] . "\t\t" . ' Qty Left: ' . $stock_left . "\n"; } } } // Update products_ordered (for bestsellers list) $this->bestSellersUpdate = TRUE; $this->notify('NOTIFY_ORDER_PROCESSING_BESTSELLERS_UPDATE', array(), $this->products[$i], $i); if ($this->bestSellersUpdate) { $db->Execute("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%f', $this->products[$i]['qty']) . " where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'"); } $this->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_END', $i); $sql_data_array = array('orders_id' => $zf_insert_id, 'products_id' => zen_get_prid($this->products[$i]['id']), 'products_model' => $this->products[$i]['model'], 'products_name' => $this->products[$i]['name'], 'products_price' => $this->products[$i]['price'], 'final_price' => $this->products[$i]['final_price'], 'onetime_charges' => $this->products[$i]['onetime_charges'], 'products_tax' => $this->products[$i]['tax'], 'products_quantity' => $this->products[$i]['qty'], 'products_priced_by_attribute' => $this->products[$i]['products_priced_by_attribute'], 'product_is_free' => $this->products[$i]['product_is_free'], 'products_discount_type' => $this->products[$i]['products_discount_type'], 'products_discount_type_from' => $this->products[$i]['products_discount_type_from'], 'products_prid' => $this->products[$i]['id']); zen_db_perform(TABLE_ORDERS_PRODUCTS, $sql_data_array); $order_products_id = $db->Insert_ID(); $this->notify('NOTIFY_ORDER_DURING_CREATE_ADDED_PRODUCT_LINE_ITEM', array_merge(array('orders_products_id' => $order_products_id, 'i' => $i), $sql_data_array), $order_products_id); $this->notify('NOTIFY_ORDER_PROCESSING_CREDIT_ACCOUNT_UPDATE_BEGIN'); $order_total_modules->update_credit_account($i); //ICW ADDED FOR CREDIT CLASS SYSTEM $this->notify('NOTIFY_ORDER_PROCESSING_ATTRIBUTES_BEGIN'); //------ bof: insert customer-chosen options to order-------- $attributes_exist = '0'; $this->products_ordered_attributes = ''; if (isset($this->products[$i]['attributes'])) { $attributes_exist = '1'; for ($j = 0, $n2 = sizeof($this->products[$i]['attributes']); $j < $n2; $j++) { if (DOWNLOAD_ENABLED == 'true') { $attributes_query = "select popt.products_options_name, poval.products_options_values_name,\n pa.options_values_price, pa.price_prefix,\n pa.product_attribute_is_free, pa.products_attributes_weight, pa.products_attributes_weight_prefix,\n pa.attributes_discounted, pa.attributes_price_base_included, pa.attributes_price_onetime,\n pa.attributes_price_factor, pa.attributes_price_factor_offset,\n pa.attributes_price_factor_onetime, pa.attributes_price_factor_onetime_offset,\n pa.attributes_qty_prices, pa.attributes_qty_prices_onetime,\n pa.attributes_price_words, pa.attributes_price_words_free,\n pa.attributes_price_letters, pa.attributes_price_letters_free,\n pad.products_attributes_maxdays, pad.products_attributes_maxcount, pad.products_attributes_filename\n from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa\n left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad\n on pa.products_attributes_id=pad.products_attributes_id\n where pa.products_id = '" . zen_db_input($this->products[$i]['id']) . "'\n and pa.options_id = '" . $this->products[$i]['attributes'][$j]['option_id'] . "'\n and pa.options_id = popt.products_options_id\n and pa.options_values_id = '" . $this->products[$i]['attributes'][$j]['value_id'] . "'\n and pa.options_values_id = poval.products_options_values_id\n and popt.language_id = '" . $_SESSION['languages_id'] . "'\n and poval.language_id = '" . $_SESSION['languages_id'] . "'"; $attributes_values = $db->Execute($attributes_query); } else { $attributes_values = $db->Execute("select popt.products_options_name, poval.products_options_values_name,\n pa.options_values_price, pa.price_prefix,\n pa.product_attribute_is_free, pa.products_attributes_weight, pa.products_attributes_weight_prefix,\n pa.attributes_discounted, pa.attributes_price_base_included, pa.attributes_price_onetime,\n pa.attributes_price_factor, pa.attributes_price_factor_offset,\n pa.attributes_price_factor_onetime, pa.attributes_price_factor_onetime_offset,\n pa.attributes_qty_prices, pa.attributes_qty_prices_onetime,\n pa.attributes_price_words, pa.attributes_price_words_free,\n pa.attributes_price_letters, pa.attributes_price_letters_free\n from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa\n where pa.products_id = '" . $this->products[$i]['id'] . "' and pa.options_id = '" . (int) $this->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . (int) $this->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $_SESSION['languages_id'] . "' and poval.language_id = '" . $_SESSION['languages_id'] . "'"); } //clr 030714 update insert query. changing to use values form $order->products for products_options_values. $sql_data_array = array('orders_id' => $zf_insert_id, 'orders_products_id' => $order_products_id, 'products_options' => $attributes_values->fields['products_options_name'], 'products_options_values' => $this->products[$i]['attributes'][$j]['value'], 'options_values_price' => $attributes_values->fields['options_values_price'], 'price_prefix' => $attributes_values->fields['price_prefix'], 'product_attribute_is_free' => $attributes_values->fields['product_attribute_is_free'], 'products_attributes_weight' => $attributes_values->fields['products_attributes_weight'], 'products_attributes_weight_prefix' => $attributes_values->fields['products_attributes_weight_prefix'], 'attributes_discounted' => $attributes_values->fields['attributes_discounted'], 'attributes_price_base_included' => $attributes_values->fields['attributes_price_base_included'], 'attributes_price_onetime' => $attributes_values->fields['attributes_price_onetime'], 'attributes_price_factor' => $attributes_values->fields['attributes_price_factor'], 'attributes_price_factor_offset' => $attributes_values->fields['attributes_price_factor_offset'], 'attributes_price_factor_onetime' => $attributes_values->fields['attributes_price_factor_onetime'], 'attributes_price_factor_onetime_offset' => $attributes_values->fields['attributes_price_factor_onetime_offset'], 'attributes_qty_prices' => $attributes_values->fields['attributes_qty_prices'], 'attributes_qty_prices_onetime' => $attributes_values->fields['attributes_qty_prices_onetime'], 'attributes_price_words' => $attributes_values->fields['attributes_price_words'], 'attributes_price_words_free' => $attributes_values->fields['attributes_price_words_free'], 'attributes_price_letters' => $attributes_values->fields['attributes_price_letters'], 'attributes_price_letters_free' => $attributes_values->fields['attributes_price_letters_free'], 'products_options_id' => (int) $this->products[$i]['attributes'][$j]['option_id'], 'products_options_values_id' => (int) $this->products[$i]['attributes'][$j]['value_id'], 'products_prid' => $this->products[$i]['id']); zen_db_perform(TABLE_ORDERS_PRODUCTS_ATTRIBUTES, $sql_data_array); $opa_insert_id = $db->insert_ID(); $this->notify('NOTIFY_ORDER_DURING_CREATE_ADDED_ATTRIBUTE_LINE_ITEM', array_merge(array('orders_products_attributes_id' => $opa_insert_id), $sql_data_array), $opa_insert_id); if (DOWNLOAD_ENABLED == 'true' && isset($attributes_values->fields['products_attributes_filename']) && zen_not_null($attributes_values->fields['products_attributes_filename'])) { $sql_data_array = array('orders_id' => $zf_insert_id, 'orders_products_id' => $order_products_id, 'orders_products_filename' => $attributes_values->fields['products_attributes_filename'], 'download_maxdays' => $attributes_values->fields['products_attributes_maxdays'], 'download_count' => $attributes_values->fields['products_attributes_maxcount'], 'products_prid' => $this->products[$i]['id']); zen_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array); $opd_insert_id = $db->insert_ID(); $this->notify('NOTIFY_ORDER_DURING_CREATE_ADDED_ATTRIBUTE_DOWNLOAD_LINE_ITEM', $sql_data_array, $opd_insert_id); } $this->products_ordered_attributes .= "\n\t" . $attributes_values->fields['products_options_name'] . ' ' . zen_decode_specialchars($this->products[$i]['attributes'][$j]['value']); } } //------eof: insert customer-chosen options ---- $this->notify('NOTIFY_ORDER_PROCESSING_ATTRIBUTES_EXIST', $attributes_exist); $this->notify('NOTIFY_ORDER_DURING_CREATE_ADD_PRODUCTS', $i, $custom_insertable_text); /* START: ADD MY CUSTOM DETAILS * 1. calculate/prepare custom information to be added to this product entry in order-confirmation, perhaps as a function call to custom code to build a serial number etc: * Possible parameters to pass to custom functions at this point: * Product ID ordered (for this line item): $this->products[$i]['id'] * Quantity ordered (of this line-item): $this->products[$i]['qty'] * Order number: $zf_insert_id * Attribute Option Name ID: (int)$this->products[$i]['attributes'][$j]['option_id'] * Attribute Option Value ID: (int)$this->products[$i]['attributes'][$j]['value_id'] * Attribute Filename: $attributes_values->fields['products_attributes_filename'] * * 2. Add that data to the $this->products_ordered_attributes variable, using this sort of format: * $this->products_ordered_attributes .= {INSERT CUSTOM INFORMATION HERE}; */ $this->products_ordered_attributes .= $custom_insertable_text; /* END: ADD MY CUSTOM DETAILS */ // update totals counters $this->total_weight += $this->products[$i]['qty'] * $this->products[$i]['weight']; $this->total_tax += zen_calculate_tax($this->products[$i]['final_price'] * $this->products[$i]['qty'], $this->products[$i]['tax']); $this->total_cost += $this->products[$i]['final_price'] + $this->products[$i]['onetime_charges']; $this->notify('NOTIFY_ORDER_PROCESSING_ONE_TIME_CHARGES_BEGIN', $i); // build output for email notification $this->products_ordered .= $this->products[$i]['qty'] . ' x ' . $this->products[$i]['name'] . ($this->products[$i]['model'] != '' ? ' (' . $this->products[$i]['model'] . ') ' : '') . ' = ' . $currencies->display_price($this->products[$i]['final_price'], $this->products[$i]['tax'], $this->products[$i]['qty']) . ($this->products[$i]['onetime_charges'] != 0 ? "\n" . TEXT_ONETIME_CHARGES_EMAIL . $currencies->display_price($this->products[$i]['onetime_charges'], $this->products[$i]['tax'], 1) : '') . $this->products_ordered_attributes . "\n"; $this->products_ordered_html .= '<tr>' . "\n" . '<td class="product-details" align="right" valign="top" width="30">' . $this->products[$i]['qty'] . ' x</td>' . "\n" . '<td class="product-details" valign="top">' . nl2br($this->products[$i]['name']) . ($this->products[$i]['model'] != '' ? ' (' . nl2br($this->products[$i]['model']) . ') ' : '') . "\n" . '<nobr>' . '<small><em> ' . nl2br($this->products_ordered_attributes) . '</em></small>' . '</nobr>' . '</td>' . "\n" . '<td class="product-details-num" valign="top" align="right">' . $currencies->display_price($this->products[$i]['final_price'], $this->products[$i]['tax'], $this->products[$i]['qty']) . ($this->products[$i]['onetime_charges'] != 0 ? '</td></tr>' . "\n" . '<tr><td class="product-details">' . nl2br(TEXT_ONETIME_CHARGES_EMAIL) . '</td>' . "\n" . '<td>' . $currencies->display_price($this->products[$i]['onetime_charges'], $this->products[$i]['tax'], 1) : '') . '</td></tr>' . "\n"; } $order_total_modules->apply_credit(); //ICW ADDED FOR CREDIT CLASS SYSTEM $this->notify('NOTIFY_ORDER_AFTER_ORDER_CREATE_ADD_PRODUCTS'); }
function eo_get_product_taxes($product, $shown_price = -1, $add = true) { global $db, $currencies, $order; if (DISPLAY_PRICE_WITH_TAX == 'true') { $shown_price = (zen_round($product['final_price'], $currencies->get_decimal_places($_SESSION['currency'])) + zen_calculate_tax($product['final_price'], $product['tax'])) * $product['qty']; $shown_price += zen_round($product['onetime_charges'], $currencies->get_decimal_places($_SESSION['currency'])) + zen_calculate_tax($product['onetime_charges'], $product['tax']); } else { $shown_price = $product['final_price'] * $product['qty']; $shown_price += $product['onetime_charges']; } // Not standard Zen Cart - but clears up some math issues later $shown_price = zen_round($shown_price, $currencies->get_decimal_places($_SESSION['currency'])); if (array_key_exists('tax_description', $product)) { $products_tax_description = $product['tax_description']; } else { $query = $db->Execute('SELECT `products_tax_class_id` ' . 'FROM `' . TABLE_PRODUCTS . '` WHERE `products_id`=\'' . (int) $product['id'] . '\' '); if (!$query->EOF) { $products_tax_description = zen_get_tax_description($query->fields['products_tax_class_id']); } else { if (array_key_exists('tax', $product)) { $products_tax_description = TEXT_UNKNOWN_TAX_RATE . ' (' . zen_display_tax_value($product['tax']) . '%)'; } } } $totalTaxAdd = 0; if (zen_not_null($products_tax_description)) { $taxAdd = 0; // Done this way to ensure we calculate if (DISPLAY_PRICE_WITH_TAX == 'true') { $taxAdd = $shown_price - $shown_price / ($product['tax'] < 10 ? "1.0" . str_replace('.', '', $product['tax']) : "1." . str_replace('.', '', $product['tax'])); } else { $taxAdd = zen_calculate_tax($shown_price, $product['tax']); } if (isset($order->info['tax_groups'][$products_tax_description])) { if ($add) { $order->info['tax_groups'][$products_tax_description] += $taxAdd; } else { $order->info['tax_groups'][$products_tax_description] -= $taxAdd; } } else { if ($add) { $order->info['tax_groups'][$products_tax_description] = $taxAdd; } } $totalTaxAdd += $taxAdd; unset($taxAdd); } return $totalTaxAdd; }