移除对账

This commit is contained in:
liu
2026-08-14 15:54:53 +08:00
parent 629d28a369
commit f0927e57e9
20 changed files with 1 additions and 2363 deletions
+1 -3
View File
@@ -24,8 +24,6 @@ class BillNumberService
private const NUMBER_SOURCES = [
'PO' => ['purchase_order', 'purchase_no'],
'SO' => ['store_order', 'order_no'],
'RC' => ['reconciliation', 'recon_no'],
'JS' => ['settlement', 'settlement_no'],
'ZD' => ['bill', 'bill_no'],
'ZF' => ['payment', 'payment_no'],
];
@@ -33,7 +31,7 @@ class BillNumberService
/**
* 生成业务单号
*
* @param string $prefix 业务前缀:PO 采购单 / SO 订货单 / RC 对账 / JS 结算 / ZD 账单 / ZF 支付
* @param string $prefix 业务前缀:PO 采购单 / SO 订货单 / ZD 账单 / ZF 支付
* @return string 如 PO202607230001
*/
public function make(string $prefix): string
-124
View File
@@ -1,124 +0,0 @@
<?php
namespace App\Services;
use App\Exceptions\RepositoryException;
use App\Models\ProductCategoryModel;
use App\Models\ProductModel;
use App\Models\ReconciliationItemModel;
use App\Models\ReconciliationModel;
use App\Models\StoreOrderItemModel;
use App\Models\StoreOrderModel;
use Illuminate\Support\Facades\DB;
/**
* 对账明细构建(D1 品类 / D2 供应商筛选)
*
* 流程(事务内,可重复 build:先清后建):
* 1. 按周期 + 品类(含子孙分类)+ 供应商拉取「已完成」门店订单的订货明细
* 2. 每条订货明细 → 一条对账明细:
* publish_amount = 订货金额(order_item.amount = 每包等级价×数量)
* actual_amount = 采购成本(数量 × 每包成本价;单价/包规不参与金额计算)
* diff = publish actual,冗余 product_name / store_id
* 3. 汇总写回头的 publish/actual/diff_amountstatus → 对账中
*/
class ReconciliationBuildService
{
/**
* @return int 生成的对账明细数
*/
public function build(ReconciliationModel $recon): int
{
return DB::transaction(function () use ($recon) {
// 1. 按周期 + 品类 + 供应商拉取已完成订单的订货明细
$itemQuery = StoreOrderItemModel::query()
->join('store_order', 'store_order.id', '=', 'store_order_item.order_id')
->where('store_order.status', StoreOrderModel::STATUS_COMPLETED)
->whereNull('store_order.deleted_at')
->whereDate('store_order.order_date', '>=', $recon->period_start)
->whereDate('store_order.order_date', '<=', $recon->period_end)
->select('store_order_item.*');
if ((int) $recon->supplier_id > 0) {
$itemQuery->where('store_order_item.supplier_id', $recon->supplier_id);
}
if ((int) $recon->category_id > 0) {
$itemQuery->whereIn(
'store_order_item.category_id',
$this->descendantCategoryIds((int) $recon->category_id)
);
}
$orderItems = $itemQuery->get()->makeVisible('cost_price');
if ($orderItems->isEmpty()) {
throw new RepositoryException('周期内无符合筛选条件的已完成订单数据,无法生成对账明细');
}
// 2. 先清后建(幂等)
ReconciliationItemModel::where('recon_id', $recon->id)->delete();
$publishTotal = '0';
$actualTotal = '0';
$rows = [];
$sort = 1;
$now = now();
foreach ($orderItems as $orderItem) {
$publish = (string) $orderItem->amount;
$actual = bcmul((string) $orderItem->quantity, (string) ($orderItem->cost_price ?? '0'), 2);
$publishTotal = bcadd($publishTotal, $publish, 2);
$actualTotal = bcadd($actualTotal, $actual, 2);
$rows[] = [
'recon_id' => $recon->id,
'store_id' => $orderItem->store_id,
'order_item_id' => $orderItem->id,
'product_id' => $orderItem->product_id,
'product_name' => $orderItem->product_name,
'quantity' => $orderItem->quantity,
'weight' => $orderItem->weight,
'publish_amount' => $publish,
'actual_amount' => $actual,
'diff_amount' => bcsub($publish, $actual, 2),
'is_reconciled' => ReconciliationItemModel::NOT_RECONCILED,
'store_remark' => '',
'sort' => $sort++,
'created_at' => $now,
'updated_at' => $now,
];
}
ReconciliationItemModel::insert($rows);
// 3. 汇总写回头 + 状态流转
$recon->publish_amount = $publishTotal;
$recon->actual_amount = $actualTotal;
$recon->diff_amount = bcsub($publishTotal, $actualTotal, 2);
$recon->status = ReconciliationModel::STATUS_WORKING;
$recon->save();
return count($rows);
});
}
/**
* 分类自身 + 全部子孙分类ID(多级分类下按顶级分类筛选)
*
* @return array<int, int>
*/
private function descendantCategoryIds(int $categoryId): array
{
$parentMap = ProductCategoryModel::pluck('parent_id', 'id');
$ids = [$categoryId];
$queue = [$categoryId];
while ($queue !== []) {
$current = array_shift($queue);
foreach ($parentMap as $id => $parentId) {
if ((int) $parentId === $current && ! in_array((int) $id, $ids, true)) {
$ids[] = (int) $id;
$queue[] = (int) $id;
}
}
}
return $ids;
}
}