Files
api/services/nginx/app/tests/Unit/Selfserve/SelfserveLaneInvoiceModeBillingTest.php
T

187 lines
6.6 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 ?int $attachedBillingCustomerNumber = null;
public ?int $attachedDraftCustomerNumber = null;
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;
public ?int $lastOrderCustomerNumber = null;
public ?int $lastAttachmentBillingCustomerNumber = null;
public ?int $lastAttachmentDraftCustomerNumber = null;
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;
private ?int $draftCustomerNumber = null;
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 setDraftCustomerNumberForTest(?int $customer_number): void
{
$this->draftCustomerNumber = $customer_number;
}
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++;
$billing_customer_number = $this->getCustomerNumber();
$draft_customer_number = $this->draftCustomerNumber;
$order = new SelfserveLaneInvoiceModeOrderStub();
$order->id = 424242;
$this->lastOrderCustomerNumber = $billing_customer_number;
$this->last_invoice_order_id = (int)$order->id;
$this->attachSelfServeMetadataToOrder($order, $billing_customer_number, $draft_customer_number);
return $order;
}
protected function attachSelfServeMetadataToOrder(
orders_o $order,
int $billing_customer_number,
?int $draft_customer_number,
?\modules\selfserve\classes\selfserve_lane_command_arguments $arguments = null
): void {
$order->attachedBillingCustomerNumber = $billing_customer_number;
$order->attachedDraftCustomerNumber = $draft_customer_number;
$this->lastAttachmentBillingCustomerNumber = $billing_customer_number;
$this->lastAttachmentDraftCustomerNumber = $draft_customer_number;
}
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();
});
it('creates self-serve invoice orders for the actual lane customer when a draft customer is configured', function (): void {
$harness = new SelfserveLaneInvoiceModeBillingHarness();
$harness->setLaneModeForTest(selfserve_lane_mode::MANUAL);
$harness->setElapsedWashTimeSecondsForTest(59);
$harness->setDraftCustomerNumberForTest(9999);
$result = $harness->invoice();
expect($result)->toBeTrue();
expect($harness->createdOrderContexts)->toBe(1);
expect($harness->lastOrderCustomerNumber)->toBe(1234);
expect($harness->lastAttachmentBillingCustomerNumber)->toBe(1234);
expect($harness->lastAttachmentDraftCustomerNumber)->toBe(9999);
});
it('keeps the real billing customer as the authoritative order customer in the invoice context', function (): void {
$source = file_get_contents(app_path('modules/selfserve/traits/selfserve_lane_invoice_t.php'));
expect($source)->not->toContain('$order_customer_number = $draft_customer_number ?? $billing_customer_number');
expect($source)->toContain('(new orders_o())->add(
$billing_customer_number,');
expect($source)->toContain('$this->attachSelfServeMetadataToOrder($order, $billing_customer_number, $draft_customer_number, $arguments);');
});