diff --git a/src/bb-library/Payment/Invoice/Item.php b/src/bb-library/Payment/Invoice/Item.php index fdcb902dc..ec32b13b1 100644 --- a/src/bb-library/Payment/Invoice/Item.php +++ b/src/bb-library/Payment/Invoice/Item.php @@ -124,6 +124,6 @@ class Payment_Invoice_Item public function getTotalWithTax() { - return $this->getTotal() + $this->getQuantity() * $this->getTax(); + return $this->getTotal() + $this->getTax(); } } \ No newline at end of file diff --git a/src/bb-modules/Cart/Service.php b/src/bb-modules/Cart/Service.php index 257cc426c..c3b1cb610 100644 --- a/src/bb-modules/Cart/Service.php +++ b/src/bb-modules/Cart/Service.php @@ -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; } diff --git a/src/bb-modules/Invoice/Service.php b/src/bb-modules/Invoice/Service.php index fc0e536bb..9ab36022b 100644 --- a/src/bb-modules/Invoice/Service.php +++ b/src/bb-modules/Invoice/Service.php @@ -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); diff --git a/src/bb-modules/Invoice/ServiceInvoiceItem.php b/src/bb-modules/Invoice/ServiceInvoiceItem.php index 291e6c791..525b52bdb 100644 --- a/src/bb-modules/Invoice/ServiceInvoiceItem.php +++ b/src/bb-modules/Invoice/ServiceInvoiceItem.php @@ -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; + } } /** diff --git a/src/bb-modules/Product/Service.php b/src/bb-modules/Product/Service.php index 63a2f7d00..39c9b08bd 100644 --- a/src/bb-modules/Product/Service.php +++ b/src/bb-modules/Product/Service.php @@ -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 ); } -} +} \ No newline at end of file diff --git a/src/bb-modules/Support/Service.php b/src/bb-modules/Support/Service.php index c2cebeafb..b2337ddcf 100644 --- a/src/bb-modules/Support/Service.php +++ b/src/bb-modules/Support/Service.php @@ -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) { diff --git a/src/bb-themes/boxbilling/html/mod_cart_index.phtml b/src/bb-themes/boxbilling/html/mod_cart_index.phtml index 12fde4e70..01e8c434d 100644 --- a/src/bb-themes/boxbilling/html/mod_cart_index.phtml +++ b/src/bb-themes/boxbilling/html/mod_cart_index.phtml @@ -42,10 +42,10 @@
{% trans 'Total:' %}
-