- Introduced `safety_seal` column in the `orders` table. - Updated order creation and completion logic to handle safety seal values. - Enhanced order and booking classes to manage safety seal attachment and retrieval. - Added tests to validate safety seal functionality in order processing.
144 lines
5.7 KiB
PHP
144 lines
5.7 KiB
PHP
<?php
|
|
|
|
app_require('classes/object_property.php');
|
|
app_require('objects/order_bookings_o.php');
|
|
app_require('objects/orders_o.php');
|
|
|
|
use classes\object_property;
|
|
use objects\order_bookings_o;
|
|
use objects\orders_o;
|
|
|
|
if (!class_exists('OrdersAutoWashCertificateLinkedBookingDouble')) {
|
|
class OrdersAutoWashCertificateLinkedBookingDouble extends order_bookings_o
|
|
{
|
|
public int $send_count = 0;
|
|
|
|
public function sendWashCertificateToCustomer(): void
|
|
{
|
|
$this->send_count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!class_exists('OrdersAutoWashCertificateCompletionDouble')) {
|
|
class OrdersAutoWashCertificateCompletionDouble extends orders_o
|
|
{
|
|
public bool $containsWashCertificate = false;
|
|
public bool $washCertificateAttached = false;
|
|
/** @var array<int, array{seal_number:?string,operator:?string,date:mixed}> */
|
|
public array $generatedCertificates = [];
|
|
public ?order_bookings_o $linkedBooking = null;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->id = -1;
|
|
$this->customer_id = new object_property('orders', -1, 'customer_id', 'int', true);
|
|
$this->cashier_id = new object_property('orders', -1, 'cashier_id', 'int', true);
|
|
$this->reference = new object_property('orders', -1, 'reference', 'string', false);
|
|
$this->notes = new object_property('orders', -1, 'notes', 'string', false);
|
|
$this->department_id = new object_property('orders', -1, 'department_id', 'int', true);
|
|
$this->reg_1 = new object_property('orders', -1, 'reg_1', 'string', false);
|
|
$this->reg_2 = new object_property('orders', -1, 'reg_2', 'string', false);
|
|
$this->reg_3 = new object_property('orders', -1, 'reg_3', 'string', false);
|
|
$this->created_at = new object_property('orders', -1, 'created_at', 'timestamp', false);
|
|
$this->include_in_invoice = new object_property('orders', -1, 'include_in_invoice', 'bool', false);
|
|
$this->completed_at = new object_property('orders', -1, 'completed_at', 'timestamp', false);
|
|
$this->deleted_at = new object_property('orders', -1, 'deleted_at', 'timestamp', false);
|
|
$this->invoice_collection_id = new object_property('orders', -1, 'invoice_collection_id', 'int', false);
|
|
$this->booking_id = new object_property('orders', -1, 'booking_id', 'int', false);
|
|
$this->wash_id = new object_property('orders', -1, 'wash_id', 'string', false);
|
|
$this->lane = new object_property('orders', -1, 'lane', 'string', false);
|
|
$this->po = new object_property('orders', -1, 'po', 'string', false);
|
|
$this->safety_seal = new object_property('orders', -1, 'safety_seal', 'string', false);
|
|
$this->using_hand_held = new object_property('orders', -1, 'using_hand_held', 'bool', false);
|
|
}
|
|
|
|
public function objectChanged(): void
|
|
{
|
|
}
|
|
|
|
protected function resolveDepartmentIncludedInInvoicing(): bool
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public function isPendingHandheld(): bool
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public function containsWashCertificateItem(): bool
|
|
{
|
|
return $this->containsWashCertificate;
|
|
}
|
|
|
|
public function hasWashCertificateAttached(): bool
|
|
{
|
|
return $this->washCertificateAttached;
|
|
}
|
|
|
|
public function generateWashCertificate(string|null $safety_seal = null, string|null $operator = null, $date = null): void
|
|
{
|
|
if ($this->washCertificateAttached) {
|
|
return;
|
|
}
|
|
|
|
$this->generatedCertificates[] = [
|
|
'seal_number' => self::normalizeSafetySealValue($safety_seal),
|
|
'operator' => $operator,
|
|
'date' => $date,
|
|
];
|
|
$this->washCertificateAttached = true;
|
|
}
|
|
|
|
public function getOrderBooking(): order_bookings_o|null
|
|
{
|
|
return $this->linkedBooking;
|
|
}
|
|
}
|
|
}
|
|
|
|
it('auto-attaches a wash certificate on order completion when a wash certificate item is present', function (): void {
|
|
$booking = new OrdersAutoWashCertificateLinkedBookingDouble();
|
|
$order = new OrdersAutoWashCertificateCompletionDouble();
|
|
$order->containsWashCertificate = true;
|
|
$order->booking_id->set(123);
|
|
$order->linkedBooking = $booking;
|
|
$order->safety_seal->set('SEAL-41');
|
|
|
|
$order->markAsCompleted('Operator One');
|
|
|
|
expect($order->completed_at->value())->not->toBeNull();
|
|
expect($order->generatedCertificates)->toHaveCount(1);
|
|
expect($order->generatedCertificates[0])->toMatchArray([
|
|
'seal_number' => 'SEAL-41',
|
|
'operator' => 'Operator One',
|
|
]);
|
|
expect($booking->send_count)->toBe(1);
|
|
});
|
|
|
|
it('keeps order completion idempotent when a wash certificate is already attached', function (): void {
|
|
$booking = new OrdersAutoWashCertificateLinkedBookingDouble();
|
|
$order = new OrdersAutoWashCertificateCompletionDouble();
|
|
$order->containsWashCertificate = true;
|
|
$order->washCertificateAttached = true;
|
|
$order->booking_id->set(456);
|
|
$order->linkedBooking = $booking;
|
|
|
|
$order->markAsCompleted('Operator Two');
|
|
|
|
expect($order->generatedCertificates)->toBe([]);
|
|
expect($booking->send_count)->toBe(0);
|
|
});
|
|
|
|
it('allows blank safety seal values when auto-attaching a wash certificate on completion', function (): void {
|
|
$order = new OrdersAutoWashCertificateCompletionDouble();
|
|
$order->containsWashCertificate = true;
|
|
$order->safety_seal->set(null);
|
|
|
|
$order->markAsCompleted('Operator Three');
|
|
|
|
expect($order->generatedCertificates)->toHaveCount(1);
|
|
expect($order->generatedCertificates[0]['seal_number'])->toBeNull();
|
|
});
|