批量对账
This commit is contained in:
@@ -4,6 +4,7 @@ namespace Tests\Feature;
|
||||
|
||||
use App\Models\CustomerLevelModel;
|
||||
use App\Models\ProductModel;
|
||||
use App\Models\PurchaseItemCheckModel;
|
||||
use App\Models\PurchaseOrderModel;
|
||||
use App\Models\StoreModel;
|
||||
use App\Models\StoreOrderItemModel;
|
||||
@@ -607,4 +608,137 @@ class PurchaseEditTest extends ProcurementTestCase
|
||||
$this->assertSame(2, $item->fresh()->quantity, '被拒绝后明细不变');
|
||||
$this->assertSame('10.00', (string) $item->fresh()->cost_price);
|
||||
}
|
||||
|
||||
/** 单品「已对账」标记:切换入库持久化,详情接口回显,再次切换取消 */
|
||||
public function test_item_check_toggle_persists_and_echoes_in_detail(): void
|
||||
{
|
||||
[$purchase, $product] = $this->buildPurchase();
|
||||
$this->actingAsSysUser();
|
||||
|
||||
// 初始无标记
|
||||
$this->getJson("/purchase/order/{$purchase->id}")
|
||||
->assertJsonPath('success', true)
|
||||
->assertJsonPath('data.checked_product_ids', []);
|
||||
|
||||
// 标记 → 入库
|
||||
$this->putJson("/purchase/order/{$purchase->id}/check/{$product->id}")
|
||||
->assertJsonPath('success', true)
|
||||
->assertJsonPath('data.checked', true);
|
||||
$this->assertDatabaseHas('purchase_item_check', [
|
||||
'purchase_id' => $purchase->id,
|
||||
'product_id' => $product->id,
|
||||
]);
|
||||
|
||||
// 详情回显
|
||||
$this->getJson("/purchase/order/{$purchase->id}")
|
||||
->assertJsonPath('data.checked_product_ids.0', $product->id);
|
||||
|
||||
// 再次切换 → 取消标记,记录删除
|
||||
$this->putJson("/purchase/order/{$purchase->id}/check/{$product->id}")
|
||||
->assertJsonPath('success', true)
|
||||
->assertJsonPath('data.checked', false);
|
||||
$this->assertDatabaseMissing('purchase_item_check', [
|
||||
'purchase_id' => $purchase->id,
|
||||
'product_id' => $product->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** 对账标记与采购单状态无关:已完成采购单仍可切换标记 */
|
||||
public function test_item_check_allowed_when_purchase_completed(): void
|
||||
{
|
||||
[$purchase, $product] = $this->buildPurchase();
|
||||
$purchase->update(['status' => PurchaseOrderModel::STATUS_COMPLETED]);
|
||||
$this->actingAsSysUser();
|
||||
|
||||
$this->putJson("/purchase/order/{$purchase->id}/check/{$product->id}")
|
||||
->assertJsonPath('success', true)
|
||||
->assertJsonPath('data.checked', true);
|
||||
}
|
||||
|
||||
/** 对账标记校验:采购单不存在 / 采购单内无此商品均报错,不入库 */
|
||||
public function test_item_check_toggle_validates_purchase_and_product(): void
|
||||
{
|
||||
[$purchase] = $this->buildPurchase();
|
||||
$this->actingAsSysUser();
|
||||
|
||||
$this->putJson('/purchase/order/99999/check/1')
|
||||
->assertJsonPath('success', false)
|
||||
->assertJsonPath('msg', '采购单不存在');
|
||||
$this->putJson("/purchase/order/{$purchase->id}/check/99999")
|
||||
->assertJsonPath('success', false)
|
||||
->assertJsonPath('msg', '该采购单下无此商品的订货明细');
|
||||
|
||||
$this->assertSame(0, PurchaseItemCheckModel::count());
|
||||
}
|
||||
|
||||
/** 批量标记(全选):一次标记多个商品,重复标记幂等,批量取消仅清指定商品 */
|
||||
public function test_item_check_batch_marks_and_clears(): void
|
||||
{
|
||||
[$purchase, $product, $stores] = $this->buildPurchase();
|
||||
$this->actingAsSysUser();
|
||||
|
||||
// 采购单内再加一个商品(通过新增单品端点挂靠门店订单)
|
||||
$product2 = ProductModel::factory()->create([
|
||||
'status' => ProductModel::STATUS_ON,
|
||||
'cost_price' => 5,
|
||||
'spec' => '1斤',
|
||||
'unit' => '斤',
|
||||
]);
|
||||
$this->postJson("/purchase/order/{$purchase->id}/store/{$stores[0]->id}/item", [
|
||||
'product_id' => $product2->id,
|
||||
'quantity' => 1,
|
||||
])->assertJsonPath('success', true);
|
||||
|
||||
// 批量标记两个商品
|
||||
$this->putJson("/purchase/order/{$purchase->id}/check", [
|
||||
'product_ids' => [$product->id, $product2->id],
|
||||
'checked' => true,
|
||||
])->assertJsonPath('success', true)
|
||||
->assertJsonPath('data.count', 2);
|
||||
$this->assertSame(2, PurchaseItemCheckModel::where('purchase_id', $purchase->id)->count());
|
||||
|
||||
// 重复批量标记幂等(不产生重复行)
|
||||
$this->putJson("/purchase/order/{$purchase->id}/check", [
|
||||
'product_ids' => [$product->id, $product2->id],
|
||||
'checked' => true,
|
||||
])->assertJsonPath('success', true);
|
||||
$this->assertSame(2, PurchaseItemCheckModel::where('purchase_id', $purchase->id)->count());
|
||||
|
||||
// 详情回显两个标记
|
||||
$ids = $this->getJson("/purchase/order/{$purchase->id}")->json('data.checked_product_ids');
|
||||
$this->assertEqualsCanonicalizing([$product->id, $product2->id], $ids);
|
||||
|
||||
// 批量取消其中一个
|
||||
$this->putJson("/purchase/order/{$purchase->id}/check", [
|
||||
'product_ids' => [$product->id],
|
||||
'checked' => false,
|
||||
])->assertJsonPath('success', true);
|
||||
$this->assertDatabaseMissing('purchase_item_check', [
|
||||
'purchase_id' => $purchase->id,
|
||||
'product_id' => $product->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('purchase_item_check', [
|
||||
'purchase_id' => $purchase->id,
|
||||
'product_id' => $product2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** 批量标记校验:空列表/采购单不存在报错;无效商品静默忽略 */
|
||||
public function test_item_check_batch_validates_and_ignores_unknown_products(): void
|
||||
{
|
||||
[$purchase] = $this->buildPurchase();
|
||||
$this->actingAsSysUser();
|
||||
|
||||
$this->putJson("/purchase/order/{$purchase->id}/check", ['product_ids' => [], 'checked' => true])
|
||||
->assertJsonPath('success', false);
|
||||
$this->putJson('/purchase/order/99999/check', ['product_ids' => [1], 'checked' => true])
|
||||
->assertJsonPath('success', false)
|
||||
->assertJsonPath('msg', '采购单不存在');
|
||||
|
||||
// 采购单内无此商品 → 静默忽略不入库
|
||||
$this->putJson("/purchase/order/{$purchase->id}/check", ['product_ids' => [99999], 'checked' => true])
|
||||
->assertJsonPath('success', true)
|
||||
->assertJsonPath('data.count', 0);
|
||||
$this->assertSame(0, PurchaseItemCheckModel::count());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user