Files
api/services/nginx/app/tests/Unit/Selfserve/SelfserveLaneInvoiceModeBillingTest.php
T
Jeppe B 20eb92891a Avoid empty self-serve invoice orders
Only create the invoice order context when elapsed minute billing has a positive quantity. This preserves automatic-mode included-minute reduction without leaving an empty order id on the lane.

Tests:
- bash scripts/php-ci-test.sh unit
2026-05-28 17:21:36 +02:00

135 lines
4.0 KiB
PHP

<?php
app_require('modules/selfserve/traits/selfserve_lane_invoice_t.php');
app_require('modules/selfserve/helpers/selfserve_lane_mode.php');
app_require('modules/selfserve/helpers/selfserve_lane_status.php');
app_require('objects/orders_o.php');
use modules\selfserve\helpers\selfserve_lane_mode;
use modules\selfserve\helpers\selfserve_lane_status;
use modules\selfserve\traits\selfserve_lane_invoice_t;
use objects\orders_o;
class SelfserveLaneInvoiceModeOrderStub extends orders_o
{
public function __construct() {}
}
class SelfserveLaneInvoiceModeBillingHarness
{
use selfserve_lane_invoice_t;
public int $id = 101;
public ?int $lastAddedOrderId = null;
public ?int $lastAddedProductId = null;
public ?int $lastAddedQuantity = null;
public int $createdOrderContexts = 0;
private selfserve_lane_status $laneStatus = selfserve_lane_status::OCCUPIED;
private selfserve_lane_mode $laneMode = selfserve_lane_mode::MANUAL;
private int $customerNumber = 1234;
private string $licensePlate = 'AB12345';
private int $elapsedWashTimeSeconds = 0;
private int $minuteBillingProductId = 999;
private int $includedMinutes = 0;
public function setLaneModeForTest(selfserve_lane_mode $mode): void
{
$this->laneMode = $mode;
}
public function setElapsedWashTimeSecondsForTest(int $seconds): void
{
$this->elapsedWashTimeSeconds = $seconds;
}
public function setIncludedMinutesForTest(int $minutes): void
{
$this->includedMinutes = $minutes;
}
public function getLaneStatus(): selfserve_lane_status
{
return $this->laneStatus;
}
public function getLaneMode(): selfserve_lane_mode
{
return $this->laneMode;
}
public function getCustomerNumber(): int
{
return $this->customerNumber;
}
public function getLicensePlate(): string
{
return $this->licensePlate;
}
public function getMinuteBillingProductId(): ?int
{
return $this->minuteBillingProductId;
}
public function getElapsedWashTime(): ?int
{
return $this->elapsedWashTimeSeconds;
}
public function getMachineWashMinutesIncluded(): int
{
return $this->includedMinutes;
}
protected function createInvoiceOrderContext(): orders_o
{
$this->createdOrderContexts++;
$order = new SelfserveLaneInvoiceModeOrderStub();
$order->id = 424242;
$this->last_invoice_order_id = (int)$order->id;
return $order;
}
protected function addMinuteBillingLine(int $order_id, int $product_id, int $quantity): void
{
$this->lastAddedOrderId = $order_id;
$this->lastAddedProductId = $product_id;
$this->lastAddedQuantity = $quantity;
}
}
it('bills manual self-serve stop using full elapsed minutes without included-minute reduction', function (): void {
$harness = new SelfserveLaneInvoiceModeBillingHarness();
$harness->setLaneModeForTest(selfserve_lane_mode::MANUAL);
$harness->setElapsedWashTimeSecondsForTest(59);
$harness->setIncludedMinutesForTest(5);
$result = $harness->invoice();
expect($result)->toBeTrue();
expect($harness->lastAddedOrderId)->toBe(424242);
expect($harness->lastAddedProductId)->toBe(999);
expect($harness->lastAddedQuantity)->toBe(1);
expect($harness->createdOrderContexts)->toBe(1);
expect($harness->getLastInvoiceOrderId())->toBe(424242);
});
it('keeps included-minute reduction for automatic mode', function (): void {
$harness = new SelfserveLaneInvoiceModeBillingHarness();
$harness->setLaneModeForTest(selfserve_lane_mode::AUTOMATIC);
$harness->setElapsedWashTimeSecondsForTest(59);
$harness->setIncludedMinutesForTest(5);
$result = $harness->invoice();
expect($result)->toBeTrue();
expect($harness->lastAddedOrderId)->toBeNull();
expect($harness->lastAddedProductId)->toBeNull();
expect($harness->lastAddedQuantity)->toBeNull();
expect($harness->createdOrderContexts)->toBe(0);
expect($harness->getLastInvoiceOrderId())->toBeNull();
});