130 lines
4.2 KiB
PHP
130 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace Modules\EcommerceFinance\Services;
|
|
|
|
class ShengsuanOrderProfitRowMapper
|
|
{
|
|
public const TABLE = 'ops_shengsuan_order_profit_rows';
|
|
|
|
private const FEE_FIELDS = [
|
|
'包材费(自动匹配)' => 'matched_package_fee',
|
|
'快递费(自动匹配)' => 'matched_freight_fee',
|
|
'账单费用(自动匹配)' => 'matched_bill_fee',
|
|
'分类单成本生成费用' => 'generated_classification_fee',
|
|
'商品成本生成费用' => 'generated_product_fee',
|
|
'人工维护' => 'manual_fee',
|
|
'订单费用' => 'order_fee',
|
|
'其中:推广费' => 'promotion_fee',
|
|
];
|
|
|
|
private const ROW_FIELDS = [
|
|
'店铺名称' => 'shop_name',
|
|
'线上单号' => 'online_order_no',
|
|
'内部单号' => 'internal_order_no',
|
|
'发货时间' => 'ship_time',
|
|
'商品成本' => 'product_cost',
|
|
];
|
|
|
|
public function table(): string
|
|
{
|
|
return self::TABLE;
|
|
}
|
|
|
|
/**
|
|
* @param array<string,mixed> $decoded
|
|
* @return list<array<string,mixed>>
|
|
*/
|
|
public function rows(array $decoded): array
|
|
{
|
|
$data = $decoded['data'] ?? $decoded;
|
|
if (! is_array($data)) {
|
|
return [];
|
|
}
|
|
|
|
$heads = is_array($data['fldHeads'] ?? null) ? $data['fldHeads'] : [];
|
|
$dataList = is_array($data['dataList'] ?? null) ? $data['dataList'] : [];
|
|
|
|
$fields = [];
|
|
foreach (self::ROW_FIELDS + self::FEE_FIELDS as $title => $field) {
|
|
$fields[$field] = $this->fieldForTitle($heads, $title);
|
|
}
|
|
|
|
$rows = [];
|
|
$now = now();
|
|
foreach ($dataList as $record) {
|
|
if (! is_array($record)) {
|
|
continue;
|
|
}
|
|
|
|
$shopName = trim((string) $this->value($record, $fields['shop_name'] ?? null));
|
|
$onlineOrder = trim((string) $this->value($record, $fields['online_order_no'] ?? null));
|
|
$internalOrder = trim((string) $this->value($record, $fields['internal_order_no'] ?? null));
|
|
$orderNo = $onlineOrder !== '' ? $onlineOrder : $internalOrder;
|
|
if ($shopName === '' || $orderNo === '') {
|
|
continue;
|
|
}
|
|
|
|
$row = [
|
|
'shop_name' => $shopName,
|
|
'online_order_no' => $onlineOrder !== '' ? $onlineOrder : null,
|
|
'internal_order_no' => $internalOrder !== '' ? $internalOrder : null,
|
|
'order_key' => $shopName . '|' . $orderNo,
|
|
'ship_time' => $this->dateTime($this->value($record, $fields['ship_time'] ?? null)),
|
|
'product_cost' => $this->decimal($this->value($record, $fields['product_cost'] ?? null)),
|
|
'source_payload' => json_encode($record, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
|
|
'synced_at' => $now,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
];
|
|
foreach (self::FEE_FIELDS as $title => $column) {
|
|
$row[$column] = $this->decimal($this->value($record, $fields[$column] ?? null));
|
|
}
|
|
|
|
$rows[] = $row;
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
|
|
/**
|
|
* @param list<array<string,mixed>> $heads
|
|
*/
|
|
private function fieldForTitle(array $heads, string $title): ?string
|
|
{
|
|
foreach ($heads as $head) {
|
|
if (trim((string) ($head['title'] ?? '')) === $title) {
|
|
$field = trim((string) ($head['fld'] ?? ''));
|
|
|
|
return $field === '' ? null : $field;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/** @param array<string,mixed> $record */
|
|
private function value(array $record, ?string $field): mixed
|
|
{
|
|
return $field === null ? null : ($record[$field] ?? null);
|
|
}
|
|
|
|
private function decimal(mixed $value): ?float
|
|
{
|
|
if ($value === null || $value === '') {
|
|
return null;
|
|
}
|
|
|
|
return is_numeric($value) ? round((float) $value, 2) : null;
|
|
}
|
|
|
|
private function dateTime(mixed $value): ?string
|
|
{
|
|
if ($value === null || trim((string) $value) === '') {
|
|
return null;
|
|
}
|
|
$timestamp = strtotime((string) $value);
|
|
|
|
return $timestamp === false ? null : date('Y-m-d H:i:s', $timestamp);
|
|
}
|
|
}
|