Compare commits
2 Commits
main
...
deploy/lim
| Author | SHA1 | Date | |
|---|---|---|---|
| f8abc8d2ea | |||
| a88c6e8826 |
@ -343,9 +343,6 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$plantingRows = 0;
|
||||
$remarkMap = app(AccountLedgerRemarkMap::class);
|
||||
$tabPlatform = $remarkMap->defaultPlatform($platform);
|
||||
$ledgerMap = $remarkMap->map();
|
||||
$incomeOverlapRows = 0;
|
||||
$incomeOverlapTotal = 0.0;
|
||||
/** @var array<string,int> $promoRowsByKey 门店+订单 维度的优惠/冲减账单行数(用于统计未挂单行数) */
|
||||
$promoRowsByKey = [];
|
||||
// 本月账单里真正命中「优惠收入 / 冲减收入 / 退款」的行数(重建后自检用:
|
||||
@ -354,9 +351,8 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
foreach ($bills as $bill) {
|
||||
$storeName = (string) ($bill->store_name ?? '');
|
||||
$billItem = (string) ($bill->bill_item ?? '');
|
||||
// 收入金额沿用「总账备注映射」白名单口径,保证既有数字不变;
|
||||
// 优惠 / 冲减两列按新口径(科目映射表的财务备注优先)取数。
|
||||
$legacyRemark = $ledgerMap[$remarkMap->platform($storeName, $tabPlatform) ?? ''][$billItem] ?? null;
|
||||
// 收入 / 优惠 / 冲减 / 退款统一按科目映射表的当前财务备注判桶;
|
||||
// 只有当前科目映射表没有规则时,remark() 才回落到旧总账备注表。
|
||||
$remark = $remarkMap->remark(
|
||||
$storeName,
|
||||
$tabPlatform,
|
||||
@ -367,15 +363,10 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$isPromoRemark = in_array($remark, self::DISCOUNT_REMARKS, true)
|
||||
|| in_array($remark, self::OFFSET_REMARKS, true);
|
||||
$isRefundRemark = in_array($remark, self::REFUND_REMARKS, true);
|
||||
$isIncomeRemark = in_array($legacyRemark, self::LEDGER_REMARKS, true);
|
||||
$isIncomeRemark = in_array($remark, self::LEDGER_REMARKS, true);
|
||||
if ($isPromoRemark || $isRefundRemark) {
|
||||
$moneyRemarkRows++;
|
||||
}
|
||||
if ($isIncomeRemark && ($isPromoRemark || $isRefundRemark)) {
|
||||
// 已经在收入金额里的行:不重复计入优惠/冲减列,单独提示金额。
|
||||
$incomeOverlapRows++;
|
||||
$incomeOverlapTotal += (float) $bill->{$amountColumn};
|
||||
}
|
||||
$bucket = match (true) {
|
||||
$isIncomeRemark => 'income',
|
||||
$isRefundRemark => 'refund',
|
||||
@ -467,7 +458,6 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$bills,
|
||||
$groups,
|
||||
$remarkMap,
|
||||
$ledgerMap,
|
||||
$tabPlatform,
|
||||
$orderColumn,
|
||||
$timeColumn,
|
||||
@ -496,14 +486,6 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
number_format($unattachedRows) . ' 行',
|
||||
number_format(($discountTotal + $offsetTotal) - ($attachedDiscount + $attachedOffset), 2),
|
||||
));
|
||||
if ($incomeOverlapRows > 0) {
|
||||
$this->line(sprintf(
|
||||
' 提示:%d 笔(%s 元)按旧口径已计入收入金额,未重复计入优惠/冲减列。',
|
||||
$incomeOverlapRows,
|
||||
number_format($incomeOverlapTotal, 2),
|
||||
));
|
||||
}
|
||||
|
||||
if ((bool) $this->option('amounts-only')) {
|
||||
return $this->backfillPromoAmounts($month, $source, $groups, $promoOnlyGroups, $reportMonth);
|
||||
}
|
||||
@ -1109,14 +1091,12 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
*
|
||||
* @param iterable<int,mixed> $bills
|
||||
* @param array<string,array<string,mixed>> $groups 已有收款行(已按 payment_count 过滤)
|
||||
* @param array<string,string> $ledgerMap
|
||||
* @return array<string,array<string,mixed>>
|
||||
*/
|
||||
private function promoOnlyGroups(
|
||||
iterable $bills,
|
||||
array $groups,
|
||||
AccountLedgerRemarkMap $remarkMap,
|
||||
array $ledgerMap,
|
||||
?string $tabPlatform,
|
||||
string $orderColumn,
|
||||
string $timeColumn,
|
||||
@ -1142,12 +1122,6 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
continue;
|
||||
}
|
||||
|
||||
// 已经算进「收入金额」白名单的行不重复补。
|
||||
$legacy = $ledgerMap[$remarkMap->platform($storeName, $tabPlatform) ?? ''][$billItem] ?? null;
|
||||
if (in_array($legacy, self::LEDGER_REMARKS, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rawNo = trim((string) ($bill->{$orderColumn} ?? ''));
|
||||
$core = self::cleanOrderNo($rawNo);
|
||||
$realStore = $realStoreColumn !== '' ? (string) ($bill->{$realStoreColumn} ?? '') : '';
|
||||
|
||||
@ -16,7 +16,7 @@ use Modules\EcommerceFinance\Repositories\ShippingOrderRepository;
|
||||
* 2. 用线上订单号去匹配发货数据(jst_oms_shipping)中 M-1、M 两个月发货的交易单号,匹配到的保留;
|
||||
* 3. 匹配到的单里,任务备注或卖家备注写了“拍A发B”或“拍A发A”的不扣款,单独列出发给运营;
|
||||
* 4. 实际只发了「信誉订单虚拟条码」「透明挂钩」这类商品的不扣款;
|
||||
* 5. 其余匹配到的作为扣款项,扣款金额 = Σ 发货商品成本价 × 数量 × 1.2(成本价+成本价×20%),
|
||||
* 5. 其余匹配到的作为扣款项,扣款金额 = Σ 发货商品成本价 × 数量 + 该订单在发货数据中的运费(2026-10-19 更正),
|
||||
* 成本价按发货条形码(=商品编码)取普通商品资料。未匹配到发货的不计入种菜损耗。
|
||||
*/
|
||||
class PlantingLossCalculator
|
||||
@ -34,9 +34,6 @@ class PlantingLossCalculator
|
||||
/** 发货商品名称或条码含这些字样的不计扣款。 */
|
||||
public const FREE_GOODS_KEYWORDS = ['信誉订单虚拟条码', '虚拟条码', '透明挂钩'];
|
||||
|
||||
/** 扣款 = 成本价 × (1 + 20%)。 */
|
||||
public const MARKUP_PERCENT = 20;
|
||||
|
||||
public const SKU_DATASET = 'operations_replica.rpt.jst_sku';
|
||||
|
||||
private const CHUNK = 1000;
|
||||
@ -104,10 +101,10 @@ class PlantingLossCalculator
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 成本价(元,字符串)× 数量 × 1.2 → 分。 */
|
||||
/** 成本价(元,字符串)× 数量 → 分。 */
|
||||
public static function deductionCents(string $costPrice, int $qty): int
|
||||
{
|
||||
return (int) round((float) $costPrice * 100 * $qty * (100 + self::MARKUP_PERCENT) / 100);
|
||||
return (int) round((float) $costPrice * 100 * $qty);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,23 +165,37 @@ class PlantingLossCalculator
|
||||
}
|
||||
$lineCents = self::deductionCents($cost, $line['qty']);
|
||||
$cents += $lineCents;
|
||||
$deductLines[] = sprintf('%s × %d × %s × 1.2 = %s', $line['barcode'], $line['qty'], $cost, number_format($lineCents / 100, 2, '.', ''));
|
||||
$deductLines[] = sprintf('%s × %d × %s = %s', $line['barcode'], $line['qty'], $cost, number_format($lineCents / 100, 2, '.', ''));
|
||||
}
|
||||
$freight = $shipment['freight'] ?? null;
|
||||
if ($deductLines !== []) {
|
||||
if ($freight === null) {
|
||||
$deductLines[] = '运费缺失';
|
||||
} else {
|
||||
$cents += (int) round((float) $freight * 100);
|
||||
$deductLines[] = '运费 ' . $freight;
|
||||
}
|
||||
}
|
||||
$missing = array_values(array_unique($missingCost));
|
||||
$missingText = implode(';', array_filter([
|
||||
$missing === [] ? '' : '成本价缺失:' . implode('、', $missing),
|
||||
$deductLines !== [] && $freight === null ? '运费缺失' : '',
|
||||
]));
|
||||
|
||||
$keyword = $shipment === null ? null : self::exemptionKeyword((string) $row['task_remark'], (string) $row['seller_remark']);
|
||||
[$result, $basis] = match (true) {
|
||||
$shipment === null => [self::RESULT_UNMATCHED, self::shippingLabel($month) . ' 发货数据中无此交易单号'],
|
||||
$keyword !== null => [self::RESULT_EXEMPT, '备注含“' . $keyword . '”'],
|
||||
$deductLines === [] => [self::RESULT_FREE_GOODS, '只发了虚拟条码/透明挂钩'],
|
||||
$missingCost !== [] => [self::RESULT_DEDUCT, '成本价缺失:' . implode('、', array_unique($missingCost)) . ',扣款金额未含该商品'],
|
||||
default => [self::RESULT_DEDUCT, '已匹配发货,按成本价×1.2扣款'],
|
||||
$missingText !== '' => [self::RESULT_DEDUCT, $missingText . ',扣款金额未含缺失部分'],
|
||||
default => [self::RESULT_DEDUCT, '已匹配发货,按成本价×数量+运费扣款'],
|
||||
};
|
||||
|
||||
$row['loss_result'] = $result;
|
||||
$row['loss_basis'] = $basis;
|
||||
$row['deduction_amount'] = $result === self::RESULT_DEDUCT ? number_format($cents / 100, 2, '.', '') : null;
|
||||
$row['deduction_detail'] = $result === self::RESULT_DEDUCT ? implode("\n", $deductLines) : '';
|
||||
$row['cost_missing'] = $result === self::RESULT_DEDUCT && $missingCost !== [];
|
||||
$row['cost_missing'] = $result === self::RESULT_DEDUCT && $missingText !== '';
|
||||
$row['shipped_at'] = $shipment['shipped_at'] ?? '';
|
||||
$row['express_no'] = $shipment['express_no'] ?? '';
|
||||
$row['warehouse_name'] = $shipment['warehouse_name'] ?? '';
|
||||
|
||||
@ -6,7 +6,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Modules\EcommerceFinance\Repositories\PlantingReimbursementRepository as Repository;
|
||||
use Modules\EcommerceFinance\Services\PlantingLossCalculator as Calculator;
|
||||
|
||||
/** 种菜数据汇总 → 种菜损耗:种菜报销明细匹配近两个月发货数据,拍A发B/拍A发A、只发虚拟条码/透明挂钩的不扣款,其余按成本价×1.2 扣款。 */
|
||||
/** 种菜数据汇总 → 种菜损耗:种菜报销明细匹配近两个月发货数据,拍A发B/拍A发A、只发虚拟条码/透明挂钩的不扣款,其余按成本价×数量+运费扣款。 */
|
||||
class PlantingLossPageData
|
||||
{
|
||||
use PlantingPageFilters;
|
||||
@ -25,7 +25,7 @@ class PlantingLossPageData
|
||||
];
|
||||
|
||||
public const COLUMNS = [
|
||||
'loss_result' => '损耗判定', 'deduction_amount' => '扣款金额', 'loss_basis' => '判定说明', 'deduction_detail' => '扣款计算(条码×数量×成本价×1.2)',
|
||||
'loss_result' => '损耗判定', 'deduction_amount' => '扣款金额', 'loss_basis' => '判定说明', 'deduction_detail' => '扣款计算(条码×数量×成本价+运费)',
|
||||
'completed_at' => '报销完成时间', 'work_order_no' => '工单编号', 'platform' => '平台', 'shop_name' => '店铺名称',
|
||||
'online_order_no' => '线上订单号', 'task_remark' => '任务备注', 'seller_remark' => '卖家备注',
|
||||
'actual_paid_amount' => '实付金额', 'task_payment' => '任务付款金额', 'reimbursement_amount' => '最终报销金额',
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
@endphp
|
||||
<div class="pw-page" data-preference-key="planting-loss:{{ company_id() }}:{{ optional(user())->id }}">
|
||||
<div class="pw-heading">
|
||||
<p>{{ $plantingFilters['month'] }} 月种菜报销明细(完成时间 {{ substr($plantingWindow['from'], 0, 10) }} 至 {{ \Illuminate\Support\Carbon::parse($plantingWindow['to'])->subDay()->format('Y-m-d') }})的线上订单号,匹配 {{ $shippingLabel }} 发货数据(发货时间 {{ substr($plantingShippingWindow['from'], 0, 10) }} 至 {{ \Illuminate\Support\Carbon::parse($plantingShippingWindow['to'])->subDay()->format('Y-m-d') }})中的交易单号。匹配到的单中,任务备注或卖家备注写了“拍A发B / 拍A发A”的、以及只发了信誉订单虚拟条码/透明挂钩的不扣款,其余按发货商品成本价×1.2 扣款。</p>
|
||||
<p>{{ $plantingFilters['month'] }} 月种菜报销明细(完成时间 {{ substr($plantingWindow['from'], 0, 10) }} 至 {{ \Illuminate\Support\Carbon::parse($plantingWindow['to'])->subDay()->format('Y-m-d') }})的线上订单号,匹配 {{ $shippingLabel }} 发货数据(发货时间 {{ substr($plantingShippingWindow['from'], 0, 10) }} 至 {{ \Illuminate\Support\Carbon::parse($plantingShippingWindow['to'])->subDay()->format('Y-m-d') }})中的交易单号。匹配到的单中,任务备注或卖家备注写了“拍A发B / 拍A发A”的、以及只发了信誉订单虚拟条码/透明挂钩的不扣款,其余按发货商品成本价×数量+该单运费扣款。</p>
|
||||
<div class="pw-tags">
|
||||
<span class="pw-tag {{ $plantingSync['code'] === 'ready' ? '' : 'warn' }}">{{ $syncLabels[$plantingSync['code']] ?? $plantingSync['code'] }}@if($plantingSync['last_succeeded_at']) · {{ \Illuminate\Support\Str::of($plantingSync['last_succeeded_at'])->substr(0, 16) }}@endif</span>
|
||||
<span class="pw-tag {{ ($plantingShippingSync['code'] ?? '') === 'succeeded' ? '' : 'warn' }}">{{ $shippingLabels[$plantingShippingSync['code'] ?? 'unavailable'] ?? $plantingShippingSync['code'] }}@if($plantingShippingSync['last_succeeded_at'] ?? null) · {{ \Illuminate\Support\Str::of($plantingShippingSync['last_succeeded_at'])->substr(0, 16) }}@endif</span>
|
||||
@ -37,12 +37,12 @@
|
||||
@php $deduct = $plantingSummary[Calculator::RESULT_DEDUCT]; $exempt = $plantingSummary[Calculator::RESULT_EXEMPT]; $free = $plantingSummary[Calculator::RESULT_FREE_GOODS]; $unmatched = $plantingSummary[Calculator::RESULT_UNMATCHED]; @endphp
|
||||
<div class="pw-metrics">
|
||||
<div><span>当月种菜报销</span><strong>{{ number_format($plantingSummary['total']) }}</strong><small>匹配到发货 {{ number_format($deduct['count'] + $exempt['count'] + $free['count']) }} 单</small></div>
|
||||
<a href="{{ $resultUrl(Calculator::RESULT_DEDUCT) }}" class="is-key {{ $plantingFilters['result'] === Calculator::RESULT_DEDUCT ? 'is-active' : '' }}"><span>扣款金额(元)</span><strong>{{ $money($deduct['deduction_amount']) }}</strong><small>扣款 {{ number_format($deduct['count']) }} 单@if($deduct['cost_missing'] > 0) · <b class="pw-warn-text">{{ number_format($deduct['cost_missing']) }} 单成本价缺失</b>@endif</small></a>
|
||||
<a href="{{ $resultUrl(Calculator::RESULT_DEDUCT) }}" class="is-key {{ $plantingFilters['result'] === Calculator::RESULT_DEDUCT ? 'is-active' : '' }}"><span>扣款金额(元)</span><strong>{{ $money($deduct['deduction_amount']) }}</strong><small>扣款 {{ number_format($deduct['count']) }} 单@if($deduct['cost_missing'] > 0) · <b class="pw-warn-text">{{ number_format($deduct['cost_missing']) }} 单成本价/运费缺失</b>@endif</small></a>
|
||||
<a href="{{ $resultUrl(Calculator::RESULT_EXEMPT) }}" class="{{ $plantingFilters['result'] === Calculator::RESULT_EXEMPT ? 'is-active' : '' }}"><span>不扣款(拍A发B/拍A发A)</span><strong>{{ number_format($exempt['count']) }}</strong><small>需发运营 · 最终报销 {{ $money($exempt['reimbursement_amount']) }}</small></a>
|
||||
<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”(不区分全半角、大小写和空格)的不做扣款,单独列出发给运营。④ 实际只发了“信誉订单虚拟条码”“透明挂钩”这类商品的不扣款;同一单里这类商品也不计入扣款。⑤ 其余匹配到的为扣款项:扣款金额 = Σ 发货条形码(商品编码)在「普通商品资料」中的成本价 × 发货数量 × 1.2(成本价 + 成本价×20%);普通商品资料里没有成本价(空或 0)的商品标为“成本价缺失”,不计入扣款金额,需补齐成本价后自动重算。未匹配到发货的单不计入种菜损耗,仅供核对。</p></details>
|
||||
<details class="pw-rules"><summary>计算口径</summary><p>① 取该月种菜报销明细:工单类型“种菜报销”、状态“已完成”,完成时间 M 月 2 日 00:00 至次月 1 日 23:59:59(与「种菜报销」页同一口径)。② 用线上订单号(交易单号)精确匹配「快递应付 → 发货数据」中发货时间在上月 1 日至本月末的交易单号,匹配到的保留,同一单多个包裹/商品合并为一行。③ 匹配到的单中,任务备注或卖家备注写了“拍A发B”或“拍A发A”(不区分全半角、大小写和空格)的不做扣款,单独列出发给运营。④ 实际只发了“信誉订单虚拟条码”“透明挂钩”这类商品的不扣款;同一单里这类商品也不计入扣款。⑤ 其余匹配到的为扣款项:扣款金额 = Σ 发货条形码(商品编码)在「普通商品资料」中的成本价 × 发货数量 + 该订单在「发货数据」中的运费合计;普通商品资料里没有成本价(空或 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="种菜损耗明细">
|
||||
|
||||
@ -23,6 +23,7 @@ class PlantingWorkOrderPagesTest extends FeatureTestCase
|
||||
'task_empty_package_fee' => '0.00', 'reimbursement_amount' => '39.79', 'payee_name' => '黄文梳',
|
||||
'loss_result' => Calculator::RESULT_DEDUCT, 'loss_basis' => '已匹配发货,备注无拍A发B/拍A发A',
|
||||
'shipped_amount' => '40.60', 'shipped_freight' => '3.20', 'express_no' => 'YT001',
|
||||
'deduction_amount' => '207.40', 'deduction_detail' => "DNZ-01 × 2 × 100.5 = 201.00\n运费 6.40", 'cost_missing' => false,
|
||||
], $patch);
|
||||
}
|
||||
|
||||
@ -78,7 +79,9 @@ class PlantingWorkOrderPagesTest extends FeatureTestCase
|
||||
->assertSee('GD565967381')
|
||||
->assertDontSee('GD-EXEMPT')
|
||||
->assertDontSee('GD-NONE')
|
||||
->assertSee('2026-08-01');
|
||||
->assertSee('2026-08-01')
|
||||
->assertSee('207.40')
|
||||
->assertSee('DNZ-01 × 2 × 100.5 = 201.00');
|
||||
|
||||
$this->loginAs()->get($this->url('planting-loss', ['month' => '2026-09', 'result' => Calculator::RESULT_EXEMPT]))
|
||||
->assertOk()->assertSee('GD-EXEMPT')->assertDontSee('GD565967381');
|
||||
|
||||
@ -148,8 +148,8 @@ class PlantingLossCalculatorTest extends TestCase
|
||||
$this->assertTrue(Calculator::isFreeGoods('XN001', '信誉订单虚拟条码'));
|
||||
$this->assertTrue(Calculator::isFreeGoods('GG003-SZ', '透明挂钩3个'));
|
||||
$this->assertFalse(Calculator::isFreeGoods('DNZ-01', '儿童学习椅'));
|
||||
$this->assertSame(12060, Calculator::deductionCents('100.5', 1));
|
||||
$this->assertSame(24120, Calculator::deductionCents('100.5', 2));
|
||||
$this->assertSame(10050, Calculator::deductionCents('100.5', 1));
|
||||
$this->assertSame(20100, Calculator::deductionCents('100.5', 2));
|
||||
}
|
||||
|
||||
public function test_loss_rows_match_shipments_and_split_exempt_from_deduct(): void
|
||||
@ -187,9 +187,9 @@ class PlantingLossCalculatorTest extends TestCase
|
||||
$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 × 1.2 = 241.20,挂钩不计。
|
||||
$this->assertSame('241.20', $rows['GD-DEDUCT']['deduction_amount']);
|
||||
$this->assertSame('DNZ-01 × 2 × 100.5 × 1.2 = 241.20', $rows['GD-DEDUCT']['deduction_detail']);
|
||||
// 取最新一条普通商品成本价 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']);
|
||||
|
||||
$this->assertSame(Calculator::RESULT_FREE_GOODS, $rows['GD-VIRTUAL']['loss_result']);
|
||||
@ -197,7 +197,7 @@ class PlantingLossCalculatorTest extends TestCase
|
||||
|
||||
// 成本价为 0、或只有组合装资料的条码视为成本价缺失。
|
||||
$this->assertSame(Calculator::RESULT_DEDUCT, $rows['GD-NOCOST']['loss_result']);
|
||||
$this->assertSame('0.00', $rows['GD-NOCOST']['deduction_amount']);
|
||||
$this->assertSame('6.40', $rows['GD-NOCOST']['deduction_amount']);
|
||||
$this->assertTrue($rows['GD-NOCOST']['cost_missing']);
|
||||
$this->assertStringContainsString('ZERO、DNZ-02', $rows['GD-NOCOST']['loss_basis']);
|
||||
$this->assertNull($rows['GD-EXEMPT']['deduction_amount']);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user