/** * Returns the tax calculator associated to this order detail. * @since 1.5.0.1 * @return TaxCalculator */ public function getTaxCalculator() { return OrderDetail::getTaxCalculatorStatic($this->id); }
/** * Marked as deprecated but should not throw any "deprecated" message * This function is used in order to keep front office backward compatibility 14 -> 1.5 * (Order History) * * @deprecated */ public function setProductPrices(&$row) { $tax_calculator = OrderDetail::getTaxCalculatorStatic((int) $row['id_order_detail']); $row['tax_calculator'] = $tax_calculator; $row['tax_rate'] = $tax_calculator->getTotalRate(); $row['product_price'] = Tools::ps_round($row['unit_price_tax_excl'], 2); $row['product_price_wt'] = Tools::ps_round($row['unit_price_tax_incl'], 2); $group_reduction = 1; if ($row['group_reduction'] > 0) { $group_reduction = 1 - $row['group_reduction'] / 100; } $row['product_price_wt_but_ecotax'] = $row['product_price_wt'] - $row['ecotax']; $row['total_wt'] = $row['total_price_tax_incl']; $row['total_price'] = $row['total_price_tax_excl']; }
public function getProductTaxesBreakdown() { $tmp_tax_infos = array(); foreach ($this->order_slip->getOrdersSlipDetail((int) $this->order_slip->id) as $order_slip_details) { $tax_calculator = OrderDetail::getTaxCalculatorStatic((int) $order_slip_details['id_order_detail']); $tax_amount = $tax_calculator->getTaxesAmount($order_slip_details['amount_tax_excl']); if ($this->order->useOneAfterAnotherTaxComputationMethod()) { foreach ($tax_amount as $tax_id => $amount) { $tax = new Tax((int) $tax_id); if (!isset($total_tax_amount[$tax->rate])) { $tmp_tax_infos[$tax->rate]['name'] = $tax->name; $tmp_tax_infos[$tax->rate]['total_price_tax_excl'] = $order_slip_details['amount_tax_excl']; $tmp_tax_infos[$tax->rate]['total_amount'] = $amount; } else { $tmp_tax_infos[$tax->rate]['total_price_tax_excl'] += $order_slip_details['amount_tax_excl']; $tmp_tax_infos[$tax->rate]['total_amount'] += $amount; } } } else { $infos = array('total_price_tax_excl' => 0, 'total_amount' => 0); $tax_rate = 0; foreach ($tax_amount as $tax_id => $amount) { $tax = new Tax((int) $tax_id); $tax_rate += $tax->rate; $infos['total_price_tax_excl'] += $order_slip_details['amount_tax_excl']; $infos['total_amount'] += $amount; } $tmp_tax_infos[(string) number_format($tax_rate, 3)] = $infos; } } return $tmp_tax_infos; }
public function getProductTaxesBreakdown() { $tmp_tax_infos = array(); $infos = array('total_price_tax_excl' => 0, 'total_amount' => 0); foreach ($this->order_slip->getOrdersSlipDetail((int) $this->order_slip->id) as $order_slip_details) { $tax_calculator = OrderDetail::getTaxCalculatorStatic((int) $order_slip_details['id_order_detail']); $tax_amount = $tax_calculator->getTaxesAmount($order_slip_details['amount_tax_excl']); if ($this->order->useOneAfterAnotherTaxComputationMethod()) { foreach ($tax_amount as $tax_id => $amount) { $tax = new Tax((int) $tax_id); if (!isset($total_tax_amount[$tax->rate])) { $tmp_tax_infos[$tax->rate]['name'] = $tax->name; $tmp_tax_infos[$tax->rate]['total_price_tax_excl'] = $order_slip_details['amount_tax_excl']; $tmp_tax_infos[$tax->rate]['total_amount'] = $amount; } else { $tmp_tax_infos[$tax->rate]['total_price_tax_excl'] += $order_slip_details['amount_tax_excl']; $tmp_tax_infos[$tax->rate]['total_amount'] += $amount; } } } else { $tax_rate = 0; foreach ($tax_amount as $tax_id => $amount) { $tax = new Tax((int) $tax_id); $tax_rate = $tax->rate; $infos['total_price_tax_excl'] += (double) Tools::ps_round($order_slip_details['amount_tax_excl'], 2); $infos['total_amount'] += (double) Tools::ps_round($amount, 2); } $tmp_tax_infos[(string) number_format($tax_rate, 3)] = $infos; } } // Delete ecotax from the total $ecotax = $this->order_slip->getEcoTaxTaxesBreakdown(); if ($this->order_slip->order_slip_type == 1) { foreach ($tmp_tax_infos as $rate => &$row) { $row['total_price_tax_excl'] -= Db::getInstance()->getValue('SELECT `value_tax_excl` FROM ' . _DB_PREFIX_ . 'order_cart_rule WHERE id_order = ' . $this->order_slip->id_order); $row['total_amount'] -= Db::getInstance()->getValue('SELECT `value` FROM ' . _DB_PREFIX_ . 'order_cart_rule WHERE id_order = ' . $this->order_slip->id_order) - $row['total_price_tax_excl']; } } if ($ecotax) { foreach ($tmp_tax_infos as $rate => &$row) { if (!isset($ecotax[$rate])) { continue; } $row['total_price_tax_excl'] -= $ecotax[$rate]['ecotax_tax_excl']; $row['total_amount'] -= $ecotax[$rate]['ecotax_tax_incl'] - $ecotax[$rate]['ecotax_tax_excl']; } } return $tmp_tax_infos; }
/** * By default this function was made for invoice, to compute tax amounts and balance delta (because of computation made on round values). * If you provide $limitToOrderDetails, only these item will be taken into account. This option is usefull for order slip for example, * where only sublist of the order is refunded. * * @param $limitToOrderDetails Optional array of OrderDetails to take into account. False by default to take all OrderDetails from the current Order. * @return array A list of tax rows applied to the given OrderDetails (or all OrderDetails linked to the current Order). */ public function getProductTaxesDetails($limitToOrderDetails = false) { $round_type = $this->round_type; if ($round_type == 0) { // if this is 0, it means the field did not exist // at the time the order was made. // Set it to old type, which was closest to line. $round_type = Order::ROUND_LINE; } // compute products discount $order_discount_tax_excl = $this->total_discounts_tax_excl; $free_shipping_tax = 0; $product_specific_discounts = array(); $expected_total_base = $this->total_products - $this->total_discounts_tax_excl; foreach ($this->getCartRules() as $order_cart_rule) { if ($order_cart_rule['free_shipping'] && $free_shipping_tax === 0) { $free_shipping_tax = $this->total_shipping_tax_incl - $this->total_shipping_tax_excl; $order_discount_tax_excl -= $this->total_shipping_tax_excl; $expected_total_base += $this->total_shipping_tax_excl; } $cart_rule = new CartRule($order_cart_rule['id_cart_rule']); if ($cart_rule->reduction_product > 0) { if (empty($product_specific_discounts[$cart_rule->reduction_product])) { $product_specific_discounts[$cart_rule->reduction_product] = 0; } $product_specific_discounts[$cart_rule->reduction_product] += $order_cart_rule['value_tax_excl']; $order_discount_tax_excl -= $order_cart_rule['value_tax_excl']; } } $products_tax = $this->total_products_wt - $this->total_products; $discounts_tax = $this->total_discounts_tax_incl - $this->total_discounts_tax_excl; // We add $free_shipping_tax because when there is free shipping, the tax that would // be paid if there wasn't is included in $discounts_tax. $expected_total_tax = $products_tax - $discounts_tax + $free_shipping_tax; $actual_total_tax = 0; $actual_total_base = 0; $order_detail_tax_rows = array(); $breakdown = array(); // Get order_details $order_details = $limitToOrderDetails ? $limitToOrderDetails : $this->getOrderDetailList(); $order_ecotax_tax = 0; $tax_rates = array(); foreach ($order_details as $order_detail) { $id_order_detail = $order_detail['id_order_detail']; $tax_calculator = OrderDetail::getTaxCalculatorStatic($id_order_detail); // TODO: probably need to make an ecotax tax breakdown here instead, // but it seems unlikely there will be different tax rates applied to the // ecotax in the same order in the real world $unit_ecotax_tax = $order_detail['ecotax'] * $order_detail['ecotax_tax_rate'] / 100.0; $order_ecotax_tax += $order_detail['product_quantity'] * $unit_ecotax_tax; $discount_ratio = 0; if ($this->total_products > 0) { $discount_ratio = ($order_detail['unit_price_tax_excl'] + $order_detail['ecotax']) / $this->total_products; } // share of global discount $discounted_price_tax_excl = $order_detail['unit_price_tax_excl'] - $discount_ratio * $order_discount_tax_excl; // specific discount if (!empty($product_specific_discounts[$order_detail['product_id']])) { $discounted_price_tax_excl -= $product_specific_discounts[$order_detail['product_id']]; } $quantity = $order_detail['product_quantity']; foreach ($tax_calculator->taxes as $tax) { $tax_rates[$tax->id] = $tax->rate; } foreach ($tax_calculator->getTaxesAmount($discounted_price_tax_excl) as $id_tax => $unit_amount) { $total_tax_base = 0; switch ($round_type) { case Order::ROUND_ITEM: $total_tax_base = $quantity * Tools::ps_round($discounted_price_tax_excl, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode); $total_amount = $quantity * Tools::ps_round($unit_amount, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode); break; case Order::ROUND_LINE: $total_tax_base = Tools::ps_round($quantity * $discounted_price_tax_excl, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode); $total_amount = Tools::ps_round($quantity * $unit_amount, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode); break; case Order::ROUND_TOTAL: $total_tax_base = $quantity * $discounted_price_tax_excl; $total_amount = $quantity * $unit_amount; break; } if (!isset($breakdown[$id_tax])) { $breakdown[$id_tax] = array('tax_base' => 0, 'tax_amount' => 0); } $breakdown[$id_tax]['tax_base'] += $total_tax_base; $breakdown[$id_tax]['tax_amount'] += $total_amount; $order_detail_tax_rows[] = array('id_order_detail' => $id_order_detail, 'id_tax' => $id_tax, 'tax_rate' => $tax_rates[$id_tax], 'unit_tax_base' => $discounted_price_tax_excl, 'total_tax_base' => $total_tax_base, 'unit_amount' => $unit_amount, 'total_amount' => $total_amount); } } if (!empty($order_detail_tax_rows)) { foreach ($breakdown as $data) { $actual_total_tax += Tools::ps_round($data['tax_amount'], _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode); $actual_total_base += Tools::ps_round($data['tax_base'], _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode); } $order_ecotax_tax = Tools::ps_round($order_ecotax_tax, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode); $tax_rounding_error = $expected_total_tax - $actual_total_tax - $order_ecotax_tax; if ($tax_rounding_error !== 0) { Tools::spreadAmount($tax_rounding_error, _PS_PRICE_COMPUTE_PRECISION_, $order_detail_tax_rows, 'total_amount'); } $base_rounding_error = $expected_total_base - $actual_total_base; if ($base_rounding_error !== 0) { Tools::spreadAmount($base_rounding_error, _PS_PRICE_COMPUTE_PRECISION_, $order_detail_tax_rows, 'total_tax_base'); } } return $order_detail_tax_rows; }