Fix: Incorrect tax calculation after room reallocation
This commit is contained in:
@@ -2598,8 +2598,53 @@ class OrderCore extends ObjectModel
|
||||
Product::PRICE_ADDITION_TYPE_WITH_ROOM
|
||||
)
|
||||
) {
|
||||
$additionalTaxAmounts = $tax_calculator->getTaxesAmount($autoAddedPriceExcl);
|
||||
$totalTaxBase += $autoAddedPriceExcl;
|
||||
$autoAddedServiceData = $objServiceProductOrderDetail->getRoomTypeServiceProducts(
|
||||
$order_detail['id_order'],
|
||||
0, 0,
|
||||
$order_detail['product_id'],
|
||||
0, 0, 0,
|
||||
false, false, true,
|
||||
Product::PRICE_ADDITION_TYPE_WITH_ROOM
|
||||
);
|
||||
|
||||
// We are getting auto added service for specific room.There will be only on htl_booking_detail but can have multiple auto added service with room.
|
||||
// Note: All the auto added service with room have same id_tax_rule group
|
||||
$autoAddedServiceData = array_shift($autoAddedServiceData);
|
||||
$autoAddedServices = $autoAddedServiceData['additional_services'];
|
||||
|
||||
// Calculate total quantity of auto-added services
|
||||
$totalAutoAddedQty = array_reduce($autoAddedServices, function ($quantity, $service) {
|
||||
$qty = isset($service['quantity']) ? $service['quantity'] : 0;
|
||||
return $quantity + $qty;
|
||||
}, 0);
|
||||
|
||||
$firstAutoAddedService = array_shift($autoAddedServices);
|
||||
$id_tax_rule_group = $firstAutoAddedService['id_tax_rules_group'];
|
||||
|
||||
// If tax group is different from order detail, add tax info separately
|
||||
if ($order_detail['id_tax_rules_group'] != $id_tax_rule_group) {
|
||||
$objAddress = new Address((int)$this->id_address_tax);
|
||||
$autoAddedServiceTaxManager = TaxManagerFactory::getManager($objAddress, (int)$id_tax_rule_group);
|
||||
$autoAddedServiceTaxCalculator = $autoAddedServiceTaxManager->getTaxCalculator();
|
||||
// Calculate tax for the total price
|
||||
$additionalTaxAmounts = $autoAddedServiceTaxCalculator->getTaxesAmount($autoAddedPriceExcl);
|
||||
foreach ($additionalTaxAmounts as $taxId => $amount) {
|
||||
$objTax = new Tax((int)$taxId);
|
||||
$groupedTaxDetails[$taxId] = array(
|
||||
'id_order_detail' => $firstAutoAddedService['id_order_detail'],
|
||||
'id_tax' => $taxId,
|
||||
'tax_rate' => $objTax->rate,
|
||||
'unit_tax_base' => $autoAddedPriceExcl / $totalAutoAddedQty,
|
||||
'total_tax_base' => $autoAddedPriceExcl,
|
||||
'unit_amount' => $amount,
|
||||
'total_amount' => Tools::processPriceRounding($amount, $totalAutoAddedQty),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Calculate tax for the total price
|
||||
$additionalTaxAmounts = $tax_calculator->getTaxesAmount($autoAddedPriceExcl);
|
||||
$totalTaxBase += $autoAddedPriceExcl;
|
||||
}
|
||||
}
|
||||
|
||||
$taxBaseShare = $totalTaxBase;
|
||||
|
||||
@@ -650,7 +650,7 @@ class OrderInvoiceCore extends ObjectModel
|
||||
'total_price_tax_excl' => 0,
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
'rate' => $key,
|
||||
'rate' => sprintf('%.3f', $row['tax_rate']),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -231,10 +231,11 @@ class HTMLTemplateOrderSlipCore extends HTMLTemplateInvoice
|
||||
{
|
||||
$breakdowns = array(
|
||||
'room_tax' => $this->getRoomTypeTaxesBreakdown(),
|
||||
'service_products_tax' => $this->getServiceProductsTaxesBreakdown($this->order),
|
||||
'shipping_tax' => $this->getShippingTaxesBreakdown(),
|
||||
'ecotax_tax' => $this->order_slip->getEcoTaxTaxesBreakdown(),
|
||||
);
|
||||
|
||||
|
||||
foreach ($breakdowns as $type => $bd) {
|
||||
if (empty($bd)) {
|
||||
unset($breakdowns[$type]);
|
||||
@@ -339,6 +340,68 @@ class HTMLTemplateOrderSlipCore extends HTMLTemplateInvoice
|
||||
return $breakdown;
|
||||
}
|
||||
|
||||
public function getServiceProductsTaxesBreakdown()
|
||||
{
|
||||
$sum_composite_taxes = !$this->useOneAfterAnotherTaxComputationMethod();
|
||||
|
||||
// $breakdown will be an array with tax rates as keys and at least the columns:
|
||||
// - 'total_price_tax_excl'
|
||||
// - 'total_amount'
|
||||
$breakdown = array();
|
||||
$order_detail = array_filter($this->order->products, function($v) {
|
||||
return (!$v['is_booking_product'] && (
|
||||
$v['selling_preference_type'] == Product::SELLING_PREFERENCE_STANDALONE
|
||||
|| $v['selling_preference_type'] == Product::SELLING_PREFERENCE_HOTEL_STANDALONE
|
||||
));
|
||||
});
|
||||
|
||||
$details = $this->order->getProductTaxesDetails($order_detail, false);
|
||||
|
||||
if ($sum_composite_taxes) {
|
||||
$grouped_details = array();
|
||||
foreach ($details as $row) {
|
||||
if (!isset($grouped_details[$row['id_order_detail']])) {
|
||||
$grouped_details[$row['id_order_detail']] = array(
|
||||
'tax_rate' => 0,
|
||||
'total_tax_base' => $row['total_tax_base'],
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
);
|
||||
}
|
||||
|
||||
$grouped_details[$row['id_order_detail']]['tax_rate'] += $row['tax_rate'];
|
||||
$grouped_details[$row['id_order_detail']]['total_amount'] += $row['total_amount'];
|
||||
}
|
||||
$details = $grouped_details;
|
||||
}
|
||||
foreach ($details as $row) {
|
||||
if (!$sum_composite_taxes) {
|
||||
$key = $row['id_tax'];
|
||||
} else {
|
||||
$key = sprintf('%.3f', $row['tax_rate']);
|
||||
}
|
||||
if (!isset($breakdown[$key])) {
|
||||
$breakdown[$key] = array(
|
||||
'total_price_tax_excl' => 0,
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
'rate' => sprintf('%.3f', $row['tax_rate']),
|
||||
);
|
||||
}
|
||||
|
||||
$breakdown[$key]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$key]['total_amount'] += $row['total_amount'];
|
||||
}
|
||||
|
||||
foreach ($breakdown as $key => $data) {
|
||||
$breakdown[$key]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $this->order->round_mode);
|
||||
$breakdown[$key]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $this->order->round_mode);
|
||||
}
|
||||
|
||||
ksort($breakdown);
|
||||
return $breakdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Shipping tax breakdown elements
|
||||
*
|
||||
|
||||
@@ -140,11 +140,14 @@ class TaxCalculatorCore
|
||||
$taxes_amounts = array();
|
||||
|
||||
foreach ($this->taxes as $tax) {
|
||||
if (!isset($taxes_amounts[$tax->id])) {
|
||||
$taxes_amounts[$tax->id] = 0;
|
||||
}
|
||||
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD) {
|
||||
$taxes_amounts[$tax->id] = $price_te * (abs($tax->rate) / 100);
|
||||
$taxes_amounts[$tax->id] += $price_te * (abs($tax->rate) / 100);
|
||||
$price_te = $price_te + $taxes_amounts[$tax->id];
|
||||
} else {
|
||||
$taxes_amounts[$tax->id] = ($price_te * (abs($tax->rate) / 100));
|
||||
$taxes_amounts[$tax->id] += ($price_te * (abs($tax->rate) / 100));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,8 @@ class RoomTypeServiceProductPrice extends ObjectModel
|
||||
{
|
||||
$cache_key = 'RoomTypeServiceProductPrice::getProductRoomTypePriceAndTax'.$idProduct.'_'.$idElement.'_'.$elementType;
|
||||
if (!Cache::isStored($cache_key)) {
|
||||
$objServiceProductCartDetail = new ServiceProductCartDetail();
|
||||
$objServiceProduct = new Product((int)$idProduct);
|
||||
if ($result = Db::getInstance()->getRow('
|
||||
SELECT spp.`price`, spp.`id_tax_rules_group`, p.`auto_add_to_cart`, p.`price_addition_type`
|
||||
FROM `'._DB_PREFIX_.'product` p
|
||||
@@ -88,6 +90,15 @@ class RoomTypeServiceProductPrice extends ObjectModel
|
||||
$result['id_tax_rules_group'] = Product::getIdTaxRulesGroupByIdProduct((int)$idElement);
|
||||
}
|
||||
}
|
||||
} elseif ($objServiceProduct->auto_add_to_cart
|
||||
&& $elementType == RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE
|
||||
&& $objServiceProduct->price_addition_type == Product::PRICE_ADDITION_TYPE_WITH_ROOM
|
||||
&& $objServiceProductCartDetail->alreadyExists(Context::getContext()->cart->id, $idProduct)
|
||||
) {
|
||||
$result = array();
|
||||
$result['auto_add_to_cart'] = 1;
|
||||
$result['price_addition_type'] = Product::PRICE_ADDITION_TYPE_WITH_ROOM;
|
||||
$result['id_tax_rules_group'] = Product::getIdTaxRulesGroupByIdProduct((int)$idElement);
|
||||
}
|
||||
|
||||
Cache::store($cache_key, $result);
|
||||
|
||||
@@ -304,6 +304,8 @@ class ServiceProductOrderDetail extends ObjectModel
|
||||
'name' => $product['name'],
|
||||
'quantity' => $product['quantity'],
|
||||
'allow_multiple_quantity' => $product['product_allow_multiple_quantity'],
|
||||
'tax_computation_method' => $product['tax_computation_method'],
|
||||
'id_tax_rules_group' => $product['id_tax_rules_group'],
|
||||
'price_calculation_method' => $product['product_price_calculation_method'],
|
||||
'product_tax' => $product_tax,
|
||||
'product_tax_label' => $product_tax_label,
|
||||
|
||||
Reference in New Issue
Block a user