回筐逻辑修改
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\BillModel;
|
||||
use App\Models\ContainerReturnModel;
|
||||
use App\Models\CustomerLevelModel;
|
||||
use App\Models\ProductModel;
|
||||
use App\Models\ProductPriceModel;
|
||||
use App\Models\PurchaseOrderModel;
|
||||
use App\Models\StoreModel;
|
||||
use App\Models\StoreOrderModel;
|
||||
use App\Models\UserModel;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\SystemTool\Services\SysSiteConfigService;
|
||||
|
||||
/**
|
||||
* 压回筐记录:周转筐/托盘跟账单走(生成账单时写入完整快照,只读);
|
||||
* 数量正数=压筐(附加金额),负数=回筐(抵扣金额),数量为 0 不写记录;
|
||||
* 门店表不再记录待回数量
|
||||
*/
|
||||
class ContainerReturnTest extends ProcurementTestCase
|
||||
{
|
||||
/** 注入站点配置:筐单价 5.00、托盘单价 20.00 */
|
||||
private function seedContainerConfig(): void
|
||||
{
|
||||
DB::table('sys_site_config_group')->insert([
|
||||
'id' => 100,
|
||||
'title' => '业务配置',
|
||||
'key' => 'services',
|
||||
'remark' => '',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
DB::table('sys_site_config_items')->insert([
|
||||
[
|
||||
'group_id' => 100, 'key' => 'box_amount', 'title' => '周转筐金额', 'describe' => '',
|
||||
'values' => '5.00', 'type' => 'InputNumber', 'options' => null, 'props' => null, 'sort' => 0,
|
||||
'created_at' => now(), 'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'group_id' => 100, 'key' => 'tray_amount', 'title' => '周转托盘金额', 'describe' => '',
|
||||
'values' => '20.00', 'type' => 'InputNumber', 'options' => null, 'props' => null, 'sort' => 1,
|
||||
'created_at' => now(), 'updated_at' => now(),
|
||||
],
|
||||
]);
|
||||
SysSiteConfigService::refreshSiteConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* 完整业务链造账单(商品 5.00 × 4 = 20.00,配送费 0),按指定筐/托盘数量生成
|
||||
*
|
||||
* @return array{0: StoreModel, 1: BillModel}
|
||||
*/
|
||||
private function makeBillWithContainers(int $boxNum, int $trayNum): array
|
||||
{
|
||||
$level = CustomerLevelModel::factory()->create();
|
||||
$store = StoreModel::factory()->create(['level_id' => $level->id]);
|
||||
$product = ProductModel::factory()->create(['status' => ProductModel::STATUS_ON]);
|
||||
ProductPriceModel::factory()->create([
|
||||
'product_id' => $product->id,
|
||||
'level_id' => $level->id,
|
||||
'price' => '5.00',
|
||||
]);
|
||||
$user = UserModel::factory()->forStore($store->id)->create();
|
||||
|
||||
$this->actingAsMiniUser($user);
|
||||
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 4]]])
|
||||
->assertJsonPath('success', true);
|
||||
$order = StoreOrderModel::where('store_id', $store->id)->first();
|
||||
|
||||
$this->actingAsSysUser();
|
||||
$this->putJson("/order/store/{$order->id}/status", ['status' => StoreOrderModel::STATUS_SUMMARIZED])
|
||||
->assertJsonPath('success', true);
|
||||
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
|
||||
->assertJsonPath('success', true);
|
||||
$purchase = PurchaseOrderModel::first();
|
||||
$this->putJson("/purchase/order/{$purchase->id}/finish")->assertJsonPath('success', true);
|
||||
$this->postJson("/purchase/order/{$purchase->id}/bill", [
|
||||
'stores' => [[
|
||||
'store_id' => $store->id,
|
||||
'delivery_fee' => 0,
|
||||
'box_num' => $boxNum,
|
||||
'tray_num' => $trayNum,
|
||||
]],
|
||||
])->assertJsonPath('success', true);
|
||||
|
||||
return [$store, BillModel::where('store_id', $store->id)->first()];
|
||||
}
|
||||
|
||||
/** 压筐(正数):附加金额增加账单总额,写入完整快照记录 */
|
||||
public function test_press_containers_adds_amount_and_writes_record(): void
|
||||
{
|
||||
$this->seedContainerConfig();
|
||||
[$store, $bill] = $this->makeBillWithContainers(3, 2);
|
||||
|
||||
// 附加 = 3×5 + 2×20 = 55;总额 = 20 + 55 = 75
|
||||
$this->assertSame('55.00', (string) $bill->added_amount);
|
||||
$this->assertSame('75.00', (string) $bill->total_amount);
|
||||
|
||||
$record = ContainerReturnModel::where('bill_id', $bill->id)->first();
|
||||
$this->assertNotNull($record);
|
||||
$this->assertSame($store->id, $record->store_id);
|
||||
$this->assertSame(3, $record->box_num);
|
||||
$this->assertSame(2, $record->tray_num);
|
||||
$this->assertSame('5.00', (string) $record->box_price, '筐单价快照');
|
||||
$this->assertSame('20.00', (string) $record->tray_price, '托盘单价快照');
|
||||
$this->assertSame('55.00', (string) $record->amount);
|
||||
}
|
||||
|
||||
/** 回筐(负数):抵扣账单金额,记录为负 */
|
||||
public function test_return_containers_deducts_amount(): void
|
||||
{
|
||||
$this->seedContainerConfig();
|
||||
[, $bill] = $this->makeBillWithContainers(-2, 0);
|
||||
|
||||
// 附加 = -2×5 + 0 = -10;总额 = 20 - 10 = 10
|
||||
$this->assertSame('-10.00', (string) $bill->added_amount);
|
||||
$this->assertSame('10.00', (string) $bill->total_amount);
|
||||
|
||||
$record = ContainerReturnModel::where('bill_id', $bill->id)->first();
|
||||
$this->assertNotNull($record);
|
||||
$this->assertSame(-2, $record->box_num);
|
||||
$this->assertSame(0, $record->tray_num);
|
||||
$this->assertSame('-10.00', (string) $record->amount);
|
||||
}
|
||||
|
||||
/** 混合:筐回(负)+ 托盘压(正),金额按代数和计 */
|
||||
public function test_mixed_sign_containers(): void
|
||||
{
|
||||
$this->seedContainerConfig();
|
||||
[, $bill] = $this->makeBillWithContainers(-3, 1);
|
||||
|
||||
// 附加 = -3×5 + 1×20 = 5;总额 = 20 + 5 = 25
|
||||
$this->assertSame('5.00', (string) $bill->added_amount);
|
||||
$this->assertSame('25.00', (string) $bill->total_amount);
|
||||
|
||||
$record = ContainerReturnModel::where('bill_id', $bill->id)->first();
|
||||
$this->assertNotNull($record);
|
||||
$this->assertSame(-3, $record->box_num);
|
||||
$this->assertSame(1, $record->tray_num);
|
||||
$this->assertSame('5.00', (string) $record->amount);
|
||||
}
|
||||
|
||||
/** 数量为 0:不写压回筐记录 */
|
||||
public function test_zero_containers_writes_no_record(): void
|
||||
{
|
||||
$this->seedContainerConfig();
|
||||
[, $bill] = $this->makeBillWithContainers(0, 0);
|
||||
|
||||
$this->assertSame('20.00', (string) $bill->total_amount);
|
||||
$this->assertSame(0, ContainerReturnModel::where('bill_id', $bill->id)->count());
|
||||
}
|
||||
|
||||
/** 筐/托盘数量非整数 → 拒绝 */
|
||||
public function test_non_integer_containers_rejected(): void
|
||||
{
|
||||
$level = CustomerLevelModel::factory()->create();
|
||||
$store = StoreModel::factory()->create(['level_id' => $level->id]);
|
||||
$this->actingAsSysUser();
|
||||
$purchase = PurchaseOrderModel::factory()->create(['status' => PurchaseOrderModel::STATUS_COMPLETED]);
|
||||
|
||||
$this->postJson("/purchase/order/{$purchase->id}/bill", [
|
||||
'stores' => [[
|
||||
'store_id' => $store->id,
|
||||
'delivery_fee' => 0,
|
||||
'box_num' => 1.5,
|
||||
'tray_num' => 0,
|
||||
]],
|
||||
])->assertJsonPath('success', false);
|
||||
}
|
||||
|
||||
/** 压回筐记录只读:手动登记/删除端点已下线 */
|
||||
public function test_manual_create_and_delete_routes_removed(): void
|
||||
{
|
||||
$this->actingAsSysUser();
|
||||
|
||||
$this->postJson('/recon/container-return', [
|
||||
'store_id' => 1,
|
||||
'box_num' => 1,
|
||||
'tray_num' => 0,
|
||||
])->assertJsonPath('success', false);
|
||||
$this->deleteJson('/recon/container-return/1')->assertJsonPath('success', false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user