Bug #11: For customer 35131752 ('kd'), the 15% e-conomic discount was configured on the customer but never applied to the draft invoice line items. The customer discount was only used in the flag/preview service for expected price calculations, not when actually building the draft invoice. Changes: - economicCustomers.php: log swallowed missing-currency-price errors so silently-missing discounts (like customer 35131752) become visible in the application log instead of vanishing. - economic_invoice_draft.php: thread the customer discount percentage through addOrderItemLines/addOrderItemLine and apply it at the line level (e-conomic's draft invoice line API requires per-line discountPercentage; an aggregate TotDiscount line is ignored when the customer has a per-line discount configured). - economic_invoices_draft_endpoint.php: forward the customer discount percentage to the draft builder. - collected_order_invoices_o.php: resolve the customer discount via Redis cache + e-conomicCustomers, then pass it to add_orders. - Tests: new EconomicInvoiceDraftCustomerDiscountTest covering the customer 35131752 15% case, plus updates to the existing wiring tests to account for the new parameter and the customer-discount guard on the aggregate TotDiscount line.
183 lines
5.7 KiB
PHP
183 lines
5.7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Tests for the e-conomic customer-level discount being applied at the line level.
|
|
*
|
|
* Regression coverage for bug #11 — E-conomic 15% discount not applied on
|
|
* customer 35131752 ("kd"). The customer has a 15% global discount configured in
|
|
* e-conomic, but the invoice was being sent without any discount on the line items.
|
|
*
|
|
* The fix threads the customer discount percentage through the draft builder so it
|
|
* is applied at the line level via the `discountPercentage` field that e-conomic
|
|
* expects on each line.
|
|
*/
|
|
|
|
app_require('modules/economic/helpers/economic_invoice_draft.php');
|
|
|
|
use helpers\economic_invoice_draft;
|
|
|
|
if (!class_exists('EconomicInvoiceDraftCustomerDiscountProbe')) {
|
|
class EconomicInvoiceDraftCustomerDiscountProbe extends economic_invoice_draft
|
|
{
|
|
public array $sentBatches = [];
|
|
|
|
public function __construct()
|
|
{
|
|
$this->draft_invoice_number = 35131752;
|
|
$this->currency = 'DKK';
|
|
$this->conversion_rate = 1.0;
|
|
$this->draft_invoice_data = (object)['draftInvoiceNumber' => 35131752];
|
|
}
|
|
|
|
protected function sendDraftLines(array $draft_lines): object
|
|
{
|
|
$this->sentBatches[] = $draft_lines;
|
|
return (object)['lines' => $draft_lines];
|
|
}
|
|
}
|
|
}
|
|
|
|
function economic_customer_discount_order_item(float $price, float $product_price, array $overrides = []): array
|
|
{
|
|
return array_replace_recursive([
|
|
'id' => 9001,
|
|
'quantity' => 1,
|
|
'price' => $price,
|
|
'reference' => '',
|
|
'notes' => '',
|
|
'include_in_invoice' => true,
|
|
'product' => [
|
|
'economic_product_id' => '5',
|
|
'name' => 'Wash',
|
|
'price' => $product_price,
|
|
],
|
|
], $overrides);
|
|
}
|
|
|
|
it('applies the 15% customer discount to a line item for customer 35131752 "kd"', function (): void {
|
|
$draft = new EconomicInvoiceDraftCustomerDiscountProbe();
|
|
|
|
// Order item is at full price (no per-item discount) — exactly the customer 35131752
|
|
// case where the 15% global e-conomic discount was silently dropped.
|
|
$draft->addOrderItemLine(
|
|
economic_customer_discount_order_item(100.0, 100.0),
|
|
[
|
|
'economic_department_id' => 75,
|
|
'economic_dimension_id' => 1,
|
|
],
|
|
false,
|
|
false,
|
|
15
|
|
);
|
|
$draft->flushLinesInBatches();
|
|
|
|
$line = $draft->sentBatches[0][0];
|
|
expect($line['product']['productNumber'])->toBe('5')
|
|
->and($line['description'])->toBe('Wash')
|
|
->and($line['quantity'])->toBe(1.0)
|
|
->and($line['unitNetPrice'])->toBe(100.0)
|
|
->and($line['discountPercentage'])->toBe(15.0);
|
|
});
|
|
|
|
it('uses the larger discount when both per-item and customer discounts are present', function (): void {
|
|
$draft = new EconomicInvoiceDraftCustomerDiscountProbe();
|
|
|
|
// Per-item discount = 10%, customer discount = 15% → max(15, 10) = 15.
|
|
$draft->addOrderItemLine(
|
|
economic_customer_discount_order_item(90.0, 100.0),
|
|
[
|
|
'economic_department_id' => 75,
|
|
'economic_dimension_id' => 1,
|
|
],
|
|
false,
|
|
true,
|
|
15
|
|
);
|
|
$draft->flushLinesInBatches();
|
|
|
|
$line = $draft->sentBatches[0][0];
|
|
expect($line['unitNetPrice'])->toBe(100.0)
|
|
->and($line['discountPercentage'])->toBe(15.0);
|
|
});
|
|
|
|
it('uses the per-item discount when it is larger than the customer discount', function (): void {
|
|
$draft = new EconomicInvoiceDraftCustomerDiscountProbe();
|
|
|
|
// Per-item discount = 25%, customer discount = 15% → max(25, 15) = 25.
|
|
$draft->addOrderItemLine(
|
|
economic_customer_discount_order_item(75.0, 100.0),
|
|
[
|
|
'economic_department_id' => 75,
|
|
'economic_dimension_id' => 1,
|
|
],
|
|
false,
|
|
true,
|
|
15
|
|
);
|
|
$draft->flushLinesInBatches();
|
|
|
|
$line = $draft->sentBatches[0][0];
|
|
expect($line['unitNetPrice'])->toBe(100.0)
|
|
->and($line['discountPercentage'])->toBe(25.0);
|
|
});
|
|
|
|
it('clamps the customer discount percentage to the 0..100 range', function (): void {
|
|
$draft = new EconomicInvoiceDraftCustomerDiscountProbe();
|
|
|
|
$draft->addOrderItemLine(
|
|
economic_customer_discount_order_item(100.0, 100.0),
|
|
[
|
|
'economic_department_id' => 75,
|
|
'economic_dimension_id' => 1,
|
|
],
|
|
false,
|
|
false,
|
|
150
|
|
);
|
|
$draft->flushLinesInBatches();
|
|
|
|
$line = $draft->sentBatches[0][0];
|
|
expect($line['discountPercentage'])->toBe(100.0);
|
|
});
|
|
|
|
it('emits no line discount when both per-item and customer discounts are zero', function (): void {
|
|
$draft = new EconomicInvoiceDraftCustomerDiscountProbe();
|
|
|
|
$draft->addOrderItemLine(
|
|
economic_customer_discount_order_item(100.0, 100.0),
|
|
[
|
|
'economic_department_id' => 75,
|
|
'economic_dimension_id' => 1,
|
|
],
|
|
false,
|
|
false,
|
|
0
|
|
);
|
|
$draft->flushLinesInBatches();
|
|
|
|
$line = $draft->sentBatches[0][0];
|
|
expect($line['unitNetPrice'])->toBe(100.0)
|
|
->and($line['discountPercentage'])->toBe(0.0);
|
|
});
|
|
|
|
it('keeps base behavior unchanged when the customer discount is zero', function (): void {
|
|
$draft = new EconomicInvoiceDraftCustomerDiscountProbe();
|
|
|
|
// No customer discount, no per-item discount — unit price should be the final price.
|
|
$draft->addOrderItemLine(
|
|
economic_customer_discount_order_item(100.0, 100.0),
|
|
[
|
|
'economic_department_id' => 75,
|
|
'economic_dimension_id' => 1,
|
|
],
|
|
false,
|
|
false,
|
|
0
|
|
);
|
|
$draft->flushLinesInBatches();
|
|
|
|
$line = $draft->sentBatches[0][0];
|
|
expect($line['unitNetPrice'])->toBe(100.0)
|
|
->and($line['discountPercentage'])->toBe(0.0);
|
|
});
|