Correctly use qantity for invoice items prices

This commit is contained in:
samapraku committed 2020-08-18 20:26:26 +02:00
1 parent b94d9741fa
commit ce3e02eca5
7 files changed
+77 -37

No files matched your search

+1 -1
View File
@@ -124,6 +124,6 @@ class Payment_Invoice_Item
public function getTotalWithTax()
{
return $this->getTotal() + $this->getQuantity() * $this->getTax();
return $this->getTotal() + $this->getTax();
}
}
+14 -4
View File
@@ -323,8 +323,8 @@ class Service implements InjectionAwareInterface
$items_discount = 0;
foreach ($products as $product) {
$p = $this->cartProductToApiArray($product);
$total += $p['total'];
$items_discount += $p['discount_price'];
$total += $p['total'] + $p['setup_price'];
$items_discount += $p['discount'];
$items[] = $p;
}
@@ -546,7 +546,7 @@ class Service implements InjectionAwareInterface
$invoice_items[] = array(
'title' => $order->title,
'price' => $order->price * $order->quantity,
'price' => $order->price,
'quantity' => $order->quantity,
'unit' => $order->unit,
'period' => $order->period,
@@ -563,6 +563,7 @@ class Service implements InjectionAwareInterface
'quantity' => 1,
'unit' => 'discount',
'rel_id' => $order->id,
'taxed' => $taxed,
);
}
@@ -731,6 +732,14 @@ class Service implements InjectionAwareInterface
list ($discount_price, $discount_setup) = $this->getProductDiscount($model, $setup);
$discount_total = $discount_price + $discount_setup;
$subtotal = ($price * $qty);
if(abs($discount_total) > ($subtotal + $setup) ) {
$discount_total = $subtotal;
$discount_price = $subtotal;
}
$data = array_merge($config, array(
'id' => $model->id,
'product_id' => $product->id,
@@ -741,9 +750,10 @@ class Service implements InjectionAwareInterface
'unit' => $repo->getUnit($product),
'price' => $price,
'setup_price' => $setup,
'discount' => $discount_total,
'discount_price'=> $discount_price,
'discount_setup'=> $discount_setup,
'total' => ($price * $qty) ,
'total' => $subtotal,
));
return $data;
}
+4 -21
View File
@@ -146,16 +146,8 @@ class Service implements InjectionAwareInterface
foreach($items as $item) {
$order_id = ($item->type == \Model_InvoiceItem::TYPE_ORDER) ? $item->rel_id : null;
/* Item quantity shouldn't be used to determine total price at this point.
* The total price must be determined when invoice is being generated else recurring discounts will be
* applied by a factor of the quantity instead of being applied once as demonstrated below.
* If the order has a recurring discount, the price that is fetched already has the discount applied. Example:
* Case 1 - correct: $item->price = ($order->price * $order->quantity) - $order->discount
* Case 2 - incorrect: $item->price = ($order->price - $order->discount) * $order->quantity
* However, case 1 cannot be calculated at this point because invoice_item doesn't store discount so the calculation must
* be done before calling toApiArray.
*/
$total += $item->price;
$line_total = $item->price * $item->quantity;
$total += $line_total;
$line_tax = $invoiceItemService->getTax($item) * $item->quantity;
$tax_total += $line_tax;
$line = array(
@@ -168,7 +160,7 @@ class Service implements InjectionAwareInterface
'tax' => $line_tax,
'taxed' => $item->taxed,
'charged' => $item->charged,
'total' => $item->price, //total appears to be redundant.
'total' => $line_total,
'order_id' => $order_id,
'type' => $item->type,
'rel_id' => $item->rel_id,
@@ -945,16 +937,7 @@ class Service implements InjectionAwareInterface
$this->setInvoiceDefaults($proforma);
$price = $order->price * $order->quantity;
// apply discount for new invoice if promo code is recurrent
if($order->promo_recurring) {
$price = $price - $order->discount;
if($price < 0) {
$price = 0;
}
$order->promo_used +=1;
$this->di['db']->store($order);
}
$price = $order->price;
$invoiceItemService = $this->di['mod_service']('Invoice', "InvoiceItem");
$invoiceItemService->generateFromOrder($proforma, $order, \Model_InvoiceItem::TASK_RENEW, $price);
@@ -312,6 +312,49 @@ class ServiceInvoiceItem implements InjectionAwareInterface
$this->di['db']->store($pi);
$corderService->setUnpaidInvoice($order, $proforma);
// apply discount for new invoice if promo code is recurrent
if($order->promo_recurring) {
$order_total = $order->price * $order->quantity;
$promo_discount = $order->discount;
if($promo_discount > $order_total) {
$promo_discount = $order_total;
}
$discount_title = $this->_getTitleForPromoDiscount($order->promo_id, $order->currency);
$pd = [
'title' => $discount_title,
'price' => $promo_discount * -1,
'quantity' => 1,
'unit' => 'discount',
'rel_id' => $order->id,
'taxed' => $taxed,
];
$this->addNew($proforma, $pd);
$order->promo_used +=1;
$this->di['db']->store($order);
}
}
private function _getTitleForPromoDiscount($promo_id, $currency)
{
$promo = $this->di['db']->findOne('Promo', 'id = ?', [$promo_id]);
$api_guest = $this->di['api_guest'];
switch ($promo->type) {
case \Model_Promo::ABSOLUTE:
$currencyAmount = $api_guest->currency_format(['code' => $currency, 'price' => $promo->value]);
return __('Promotional Code: :code - :value Discount', [':code' => $promo->code, ':value' => $currencyAmount]);
case \Model_Promo::PERCENTAGE:
return __('Promotional Code: :code - :value%', [':code' => $promo->code, ':value' => $promo->value]);
default:
break;
}
}
/**
+8 -2
View File
@@ -962,6 +962,7 @@ class Service implements InjectionAwareInterface
}
$discount = 0;
$quantity = 1;
switch ($promo->type) {
case \Model_Promo::ABSOLUTE:
@@ -969,7 +970,12 @@ class Service implements InjectionAwareInterface
break;
case \Model_Promo::PERCENTAGE:
$discount += round(($price * $promo->value / 100), 2);
if(isset($config['quantity']) && is_numeric($config['quantity'])){
$quantity = $config['quantity'];
}
$discount += round(($price * $quantity * $promo->value / 100), 2);
break;
default:
@@ -1063,4 +1069,4 @@ class Service implements InjectionAwareInterface
);
}
}
}
+1 -1
View File
@@ -548,6 +548,7 @@ class Service implements \Box\InjectionAwareInterface
$data['replies'] = $this->messageGetRepliesCount($model);
$data['first'] = $this->messageToApiArray($firstSupportTicketMessage);
$data['helpdesk'] = $this->helpdeskToApiArray($supportHelpdesk);
$data['client'] = $this->getClientApiArrayForTicket($model);
if ($deep) {
$messages = $this->messageGetTicketMessages($model);
@@ -559,7 +560,6 @@ class Service implements \Box\InjectionAwareInterface
if ($identity instanceof \Model_Admin) {
$data['rel'] = $this->_getRelDetails($model);
$data['priority'] = $model->priority;
$data['client'] = $this->getClientApiArrayForTicket($model);
$supportTicketNotes = $this->di['db']->find('SupportTicketNote', 'support_ticket_id = :support_ticket_id', array(':support_ticket_id' => $model->id));
foreach ($supportTicketNotes as $note) {
@@ -42,10 +42,10 @@
<td>{{ item.period | period_title }}</td>
<td class="currency">
{% if item.discount_price %}
<del>{{ (item.price*item.quantity) | money_convert }}</del>
{{ (item.price*item.quantity - item.discount_price*item.quantity) | money_convert }}
<del>{{ (item.total) | money_convert }}</del>
{{ (item.total - item.discount_price) | money_convert }}
{% else %}
{{ item.price | money_convert }}
{{ (item.total) | money_convert }}
{% endif %}
</td>
</tr>
@@ -96,11 +96,9 @@
<div class="currency">{{ tax_amount | money_convert }}</div>
{% endif %}
<p>{% trans 'Total:' %}</p>
<div class="currency">{% if cart.items[1].quantity > 1 and cart.items[1].discount_price%}
{{ (cart.total - (cart.items[1].price*(cart.items[1].quantity-1))) | money_convert }}
{%else%}
{{(cart.total + tax_amount) | money_convert }}
{%endif%}</div>
<div class="currency">
{{(cart.total + tax_amount) | money_convert }}
</div>
<form method="post" action="{{ 'api/client/cart/checkout'|link }}" class="api-form" data-api-jsonp="onAfterCartCheckout">
{% set enough_in_balance = client.client_balance_get_total >= cart.total %}
{% if cart.total and not enough_in_balance %}