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); $this->temporary_net_amount = 125.5; $this->customer_id->set(1234567); $this->cashier_id->set(42); $this->department_id->set(12); $this->created_at->set('2026-04-09 12:34:56'); $this->reference->set('Ref'); } protected function resolveDepartmentIncludedInInvoicing(): bool { return $this->departmentIncluded; } public function isPendingHandheld(): bool { return false; } } } it('lets the order-level override include an otherwise excluded order', function (): void { $order = new OrdersIncludeInInvoiceOverrideOrderDouble(); $order->departmentIncluded = false; $order->include_in_invoice->set(true); expect($order->getIncludeInInvoiceOverride())->toBeTrue(); expect($order->isIncludedInInvoicing())->toBeTrue(); }); it('lets the order-level override exclude an otherwise included order', function (): void { $order = new OrdersIncludeInInvoiceOverrideOrderDouble(); $order->departmentIncluded = true; $order->include_in_invoice->set(false); expect($order->getIncludeInInvoiceOverride())->toBeFalse(); expect($order->isIncludedInInvoicing())->toBeFalse(); }); it('falls back to the department invoicing rule when the override is null', function (): void { $order = new OrdersIncludeInInvoiceOverrideOrderDouble(); $order->departmentIncluded = false; $order->include_in_invoice->set(null); expect($order->getIncludeInInvoiceOverride())->toBeNull(); expect($order->isIncludedInInvoicing())->toBeFalse(); }); it('serializes both raw and effective include_in_invoice values', function (): void { $order = new OrdersIncludeInInvoiceOverrideOrderDouble(); $order->departmentIncluded = true; $order->include_in_invoice->set(null); expect($order->asArray(true, false))->toMatchArray([ 'include_in_invoice' => null, 'include_in_invoice_effective' => true, 'safety_seal' => null, 'created_at' => '2026-04-09 12:34:56', 'total_net_amount' => 125.5, ]); });