mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-09-12 21:37:23 -04:00
- Require reports_sales grant on postUnsuspend; return 403 on denial - Reject unsuspend of non-SUSPENDED sales; skip silently on invalid state - Move clear_all() after validation so an invalid sale_id no longer wipes the active in-progress cart - Null-guard get_sale_status() on missing row instead of fatal property access; widen return type to ?int - Fix getSaleType null-coalescing — CI4 session default only fires when key is unset, not when value is null - Rename get_sale_type → getSaleType, sale_id → saleId (PSR-12 camelCase) - Extract SaleFixtureTrait with createSale()/createSuspendedSale(); add regression coverage for auth denial, status gating, and cart preservation
66 lines
1.9 KiB
PHP
66 lines
1.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Support;
|
|
|
|
use App\Models\Sale;
|
|
use Config\Database;
|
|
|
|
trait SaleFixtureTrait
|
|
{
|
|
/**
|
|
* Inserts a minimal completed sale row directly, bypassing Sale::save_value()
|
|
* (which requires a full cart/inventory/tax pipeline unrelated to authorization
|
|
* checks). Sale::get_info() inner-joins sales_items, so a matching item/
|
|
* sales_items row is required for the sale to be found.
|
|
*/
|
|
protected function createSale(int $employeeId): int
|
|
{
|
|
$unique = uniqid();
|
|
$db = Database::connect();
|
|
|
|
$db->table('items')->insert([
|
|
'name' => "Test Item $unique",
|
|
'category' => 'Test',
|
|
'description' => 'Test item',
|
|
'cost_price' => 1,
|
|
'unit_price' => 1,
|
|
'item_number' => "TEST-$unique",
|
|
]);
|
|
$itemId = (int) $db->insertID();
|
|
|
|
$db->table('sales')->insert([
|
|
'sale_time' => date('Y-m-d H:i:s'),
|
|
'customer_id' => null,
|
|
'employee_id' => $employeeId,
|
|
'comment' => 'test sale',
|
|
'invoice_number' => null,
|
|
]);
|
|
$saleId = (int) $db->insertID();
|
|
|
|
$db->table('sales_items')->insert([
|
|
'sale_id' => $saleId,
|
|
'item_id' => $itemId,
|
|
'line' => 1,
|
|
'quantity_purchased' => 1,
|
|
'item_cost_price' => 1,
|
|
'item_unit_price' => 1,
|
|
'item_location' => 1,
|
|
]);
|
|
|
|
return $saleId;
|
|
}
|
|
|
|
/**
|
|
* Same as createSale(), but flips the sale to SUSPENDED afterward so
|
|
* postUnsuspend's status check can be exercised.
|
|
*/
|
|
protected function createSuspendedSale(int $employeeId): int
|
|
{
|
|
$saleId = $this->createSale($employeeId);
|
|
|
|
model(Sale::class)->update_sale_status($saleId, SUSPENDED);
|
|
|
|
return $saleId;
|
|
}
|
|
}
|