Compare commits
1 Commits
main
...
fix/limeng
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b089cd6bf |
@ -37,8 +37,9 @@ class PlantingLossCalculator
|
||||
/**
|
||||
* 信誉订单虚拟条码(种菜单自身的虚拟商品)。发货数据里同一交易单号下若出现它,说明这单本身是按虚拟条码走的,
|
||||
* 同单号下的其它商品是合并发货的别的订单,整单不扣款(2026-10-19 财务确认:信誉订单虚拟条码不扣款)。
|
||||
* 透明挂钩同理:同单号下出现透明挂钩即整单不扣款(2026-10-20 财务确认)。
|
||||
*/
|
||||
public const VIRTUAL_ORDER_KEYWORDS = ['信誉订单虚拟条码', '虚拟条码'];
|
||||
public const VIRTUAL_ORDER_KEYWORDS = ['信誉订单虚拟条码', '虚拟条码', '透明挂钩'];
|
||||
|
||||
public const VIRTUAL_ORDER_BARCODES = ['X00006', 'X00002'];
|
||||
|
||||
@ -214,7 +215,7 @@ class PlantingLossCalculator
|
||||
[$result, $basis] = match (true) {
|
||||
$shipment === null => [self::RESULT_UNMATCHED, self::shippingLabel($month) . ' 发货数据中无此交易单号'],
|
||||
$keyword !== null => [self::RESULT_EXEMPT, '备注含“' . $keyword . '”'],
|
||||
$virtualOrder => [self::RESULT_FREE_GOODS, '发货含信誉订单虚拟条码(同单号其它商品为合并发货的别的订单)'],
|
||||
$virtualOrder => [self::RESULT_FREE_GOODS, '发货含信誉订单虚拟条码/透明挂钩,整单不扣款'],
|
||||
$deductLines === [] => [self::RESULT_FREE_GOODS, '只发了虚拟条码/透明挂钩/无实物商品'],
|
||||
$missingText !== '' => [self::RESULT_DEDUCT, $missingText . ',扣款金额未含缺失部分'],
|
||||
default => [self::RESULT_DEDUCT, '已匹配发货,按成本价×数量+运费扣款'],
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
<a href="{{ $resultUrl(Calculator::RESULT_FREE_GOODS) }}" class="{{ $plantingFilters['result'] === Calculator::RESULT_FREE_GOODS ? 'is-active' : '' }}"><span>不扣款(虚拟条码/透明挂钩)</span><strong>{{ number_format($free['count']) }}</strong><small>最终报销 {{ $money($free['reimbursement_amount']) }}</small></a>
|
||||
<a href="{{ $resultUrl(Calculator::RESULT_UNMATCHED) }}" class="{{ $plantingFilters['result'] === Calculator::RESULT_UNMATCHED ? 'is-active' : '' }}"><span>未匹配发货(不计入)</span><strong>{{ number_format($unmatched['count']) }}</strong><small>最终报销 {{ $money($unmatched['reimbursement_amount']) }}</small></a>
|
||||
</div>
|
||||
<details class="pw-rules"><summary>计算口径</summary><p>① 取该月种菜报销明细:工单类型“种菜报销”、状态“已完成”,完成时间 M 月 2 日 00:00 至次月 1 日 23:59:59(与「种菜报销」页同一口径)。② 用线上订单号(交易单号)精确匹配「快递应付 → 发货数据」中发货时间在上月 1 日至本月末的交易单号,匹配到的保留,同一单多个包裹/商品合并为一行。③ 匹配到的单中,任务备注或卖家备注写了“拍A发B”或“拍A发A”(不区分全半角、大小写和空格)的不做扣款,单独列出发给运营。④ 发货数据里该交易单号下出现“信誉订单虚拟条码”(X00006/X00002)的整单不扣款——同单号下的其它商品是合并发货的别的订单;只发了“透明挂钩”“无实物”这类商品的也不扣款,同一单里这类商品不计入扣款。⑤ 其余匹配到的为扣款项:扣款金额 = Σ 发货条形码(商品编码)在「普通商品资料」中的成本价 × 发货数量 + 该订单在「发货数据」中的运费合计;普通商品资料里没有成本价(空或 0)的商品、发货数据里运费为空的订单分别标为“成本价缺失”“运费缺失”,缺失部分不计入扣款金额,补齐后自动重算。未匹配到发货的单不计入种菜损耗,仅供核对。</p></details>
|
||||
<details class="pw-rules"><summary>计算口径</summary><p>① 取该月种菜报销明细:工单类型“种菜报销”、状态“已完成”,完成时间 M 月 2 日 00:00 至次月 1 日 23:59:59(与「种菜报销」页同一口径)。② 用线上订单号(交易单号)精确匹配「快递应付 → 发货数据」中发货时间在上月 1 日至本月末的交易单号,匹配到的保留,同一单多个包裹/商品合并为一行。③ 匹配到的单中,任务备注或卖家备注写了“拍A发B”或“拍A发A”(不区分全半角、大小写和空格)的不做扣款,单独列出发给运营。④ 发货数据里该交易单号下出现“信誉订单虚拟条码”(X00006/X00002)或“透明挂钩”的整单不扣款(同单号下的其它商品视为合并发货的别的订单);只发了“无实物”商品的也不扣款。⑤ 其余匹配到的为扣款项:扣款金额 = Σ 发货条形码(商品编码)在「普通商品资料」中的成本价 × 发货数量 + 该订单在「发货数据」中的运费合计;普通商品资料里没有成本价(空或 0)的商品、发货数据里运费为空的订单分别标为“成本价缺失”“运费缺失”,缺失部分不计入扣款金额,补齐后自动重算。未匹配到发货的单不计入种菜损耗,仅供核对。</p></details>
|
||||
@if(($plantingShippingSync['code'] ?? '') !== 'succeeded' && ! $plantingError)<div class="pw-warn">发货数据当前状态为“{{ $shippingLabels[$plantingShippingSync['code'] ?? 'unavailable'] ?? $plantingShippingSync['code'] }}”{{ ($plantingShippingSync['warning'] ?? '') !== '' ? ':' . $plantingShippingSync['warning'] : '' }},匹配结果可能不完整。</div>@endif
|
||||
@if($plantingError)<div class="pw-error" role="alert">{{ $plantingError }}</div>@endif
|
||||
<section class="pw-panel" aria-label="种菜损耗明细">
|
||||
|
||||
@ -150,7 +150,7 @@ class PlantingLossCalculatorTest extends TestCase
|
||||
$this->assertFalse(Calculator::isFreeGoods('DNZ-01', '儿童学习椅'));
|
||||
$this->assertTrue(Calculator::isFreeGoods('tcxj', '书柜 晒图有奖励(无实物)'));
|
||||
$this->assertTrue(Calculator::isVirtualOrderItem('X00006', ''));
|
||||
$this->assertFalse(Calculator::isVirtualOrderItem('GG003-SZ', '透明挂钩3个'));
|
||||
$this->assertTrue(Calculator::isVirtualOrderItem('GG003-SZ', '透明挂钩3个'));
|
||||
$this->assertSame(10050, Calculator::deductionCents('100.5', 1));
|
||||
$this->assertSame(20100, Calculator::deductionCents('100.5', 2));
|
||||
}
|
||||
@ -171,10 +171,11 @@ class PlantingLossCalculatorTest extends TestCase
|
||||
$this->workOrder(10, 'GD-VIRTUAL', '5555', '2026-09-20 10:00:00');
|
||||
$this->workOrder(11, 'GD-NOCOST', '6666', '2026-09-21 10:00:00');
|
||||
$this->workOrder(12, 'GD-MERGED', '7777', '2026-09-22 10:00:00');
|
||||
$this->workOrder(13, 'GD-HOOK', '8888', '2026-09-23 10:00:00');
|
||||
|
||||
// 一单两个包裹:学习椅 ×2 + 透明挂钩(挂钩不扣)。
|
||||
// 一单两个包裹:学习椅 ×2 + 无实物商品(不计货值)。
|
||||
$this->ship('3316392626048007769', '2026-08-28 10:00:00', 'YT001', 40.6, 'DNZ-01', '儿童学习椅', 2);
|
||||
$this->ship('3316392626048007769', '2026-08-28 10:00:00', 'YT002', 10, 'GG003-SZ', '透明挂钩3个');
|
||||
$this->ship('3316392626048007769', '2026-08-28 10:00:00', 'YT002', 10, 'XS-01', '晒图有奖励(无实物)');
|
||||
$this->ship('3604408018648198', '2026-09-30 23:59:59');
|
||||
$this->ship('260901-000000000000001', '2026-09-01 08:00:00');
|
||||
$this->ship('9999', '2026-07-31 23:59:59'); // 早于上月 1 日
|
||||
@ -185,16 +186,19 @@ class PlantingLossCalculatorTest extends TestCase
|
||||
// 合并发货:同一交易单号下有信誉订单虚拟条码 + 别的订单的实物,整单不扣。
|
||||
$this->ship('7777', '2026-09-11 08:00:00', 'YT777', 0, 'X00006', '信誉订单虚拟条码');
|
||||
$this->ship('7777', '2026-09-11 08:00:00', 'YT777', 0, 'DNZ-01', '儿童学习椅');
|
||||
// 实物 + 透明挂钩:整单不扣。
|
||||
$this->ship('8888', '2026-09-12 08:00:00', 'YT888', 0, 'DNZ-01', '儿童学习椅');
|
||||
$this->ship('8888', '2026-09-12 08:00:00', 'YT888', 0, 'GG003-SZ', '透明挂钩3个');
|
||||
$this->ship('6666', '2026-09-10 08:00:00', 'YT666', 0, 'DNZ-02', '组合商品');
|
||||
|
||||
$rows = collect($this->app->make(Calculator::class)->rows('2026-09'))->keyBy('work_order_no');
|
||||
|
||||
$this->assertSame(['GD-DEDUCT', 'GD-EXEMPT', 'GD-MERGED', 'GD-NOCOST', 'GD-SELLER', 'GD-UNMATCHED', 'GD-VIRTUAL'], $rows->keys()->sort()->values()->all());
|
||||
$this->assertSame(['GD-DEDUCT', 'GD-EXEMPT', 'GD-HOOK', 'GD-MERGED', 'GD-NOCOST', 'GD-SELLER', 'GD-UNMATCHED', 'GD-VIRTUAL'], $rows->keys()->sort()->values()->all());
|
||||
$this->assertSame(Calculator::RESULT_DEDUCT, $rows['GD-DEDUCT']['loss_result']);
|
||||
$this->assertSame("YT001\nYT002", $rows['GD-DEDUCT']['express_no']);
|
||||
$this->assertSame('50.60', $rows['GD-DEDUCT']['shipped_amount']);
|
||||
$this->assertSame('3', $rows['GD-DEDUCT']['shipped_qty']);
|
||||
// 取最新一条普通商品成本价 100.5:100.5 × 2 = 201.00,挂钩不计货值;加该单运费 3.20 × 2 个包裹 = 6.40。
|
||||
// 取最新一条普通商品成本价 100.5:100.5 × 2 = 201.00,无实物不计货值;加该单运费 3.20 × 2 个包裹 = 6.40。
|
||||
$this->assertSame('207.40', $rows['GD-DEDUCT']['deduction_amount']);
|
||||
$this->assertSame("DNZ-01 × 2 × 100.5 = 201.00\n运费 6.40", $rows['GD-DEDUCT']['deduction_detail']);
|
||||
$this->assertFalse($rows['GD-DEDUCT']['cost_missing']);
|
||||
@ -204,6 +208,8 @@ class PlantingLossCalculatorTest extends TestCase
|
||||
$this->assertSame(Calculator::RESULT_FREE_GOODS, $rows['GD-MERGED']['loss_result']);
|
||||
$this->assertNull($rows['GD-MERGED']['deduction_amount']);
|
||||
$this->assertStringContainsString('信誉订单虚拟条码', $rows['GD-MERGED']['loss_basis']);
|
||||
$this->assertSame(Calculator::RESULT_FREE_GOODS, $rows['GD-HOOK']['loss_result']);
|
||||
$this->assertNull($rows['GD-HOOK']['deduction_amount']);
|
||||
|
||||
// 成本价为 0、或只有组合装资料的条码视为成本价缺失。
|
||||
$this->assertSame(Calculator::RESULT_DEDUCT, $rows['GD-NOCOST']['loss_result']);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user