112 lines
4.0 KiB
PHP
112 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace Modules\EcommerceFinance\Repositories;
|
|
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
|
|
|
|
/**
|
|
* Supplier product pricing and repricing records from JianSun.
|
|
*/
|
|
class ProductPriceRepository
|
|
{
|
|
private const SOURCE = 'jiansun';
|
|
private const TABLE = '[dbo].[pm_priceAdjustment_log]';
|
|
|
|
private const PRICE_TYPES = [
|
|
'pricing' => '0',
|
|
'repricing' => '1',
|
|
];
|
|
|
|
private const COST_REDUCTION = [
|
|
'yes' => '1',
|
|
'no' => '0',
|
|
];
|
|
|
|
private readonly UpstreamReadOnlyQuery $query;
|
|
|
|
public function __construct(UpstreamReadOnlyQueryFactory $queries)
|
|
{
|
|
$this->query = $queries->forSource(self::SOURCE);
|
|
}
|
|
|
|
/** @return array{rows:array<int,array<string,mixed>>} */
|
|
public function paginate(array $filters, int $page, int $limit): array
|
|
{
|
|
$page = max($page, 1);
|
|
$limit = min(max($limit, 1), 100);
|
|
$where = [];
|
|
$bindings = [];
|
|
|
|
if (($filters['barcode'] ?? '') !== '') {
|
|
$where[] = "[skucode] LIKE ? ESCAPE '\\'";
|
|
$bindings[] = $this->contains((string) $filters['barcode']);
|
|
}
|
|
|
|
$priceType = self::PRICE_TYPES[(string) ($filters['price_type'] ?? '')] ?? null;
|
|
|
|
if ($priceType !== null) {
|
|
$where[] = '[priceType] = ?';
|
|
$bindings[] = $priceType;
|
|
}
|
|
|
|
$costReduction = self::COST_REDUCTION[(string) ($filters['cost_reduction'] ?? '')] ?? null;
|
|
|
|
if ($costReduction !== null) {
|
|
$where[] = '[isCostReduction] = ?';
|
|
$bindings[] = $costReduction;
|
|
}
|
|
|
|
if (($filters['effective_from'] ?? '') !== '') {
|
|
$where[] = '[effectStartTime] >= CAST(? AS date)';
|
|
$bindings[] = (string) $filters['effective_from'];
|
|
}
|
|
|
|
if (($filters['effective_to'] ?? '') !== '') {
|
|
$where[] = '[effectStartTime] < DATEADD(day, 1, CAST(? AS date))';
|
|
$bindings[] = (string) $filters['effective_to'];
|
|
}
|
|
|
|
$whereSql = $where === [] ? '' : ' WHERE ' . implode(' AND ', $where);
|
|
$offset = ($page - 1) * $limit;
|
|
$fetch = $limit + 1;
|
|
$sql = 'SELECT '
|
|
. '[skucode] AS barcode, '
|
|
. "CASE [priceType] WHEN '0' THEN N'定价' WHEN '1' THEN N'变价' ELSE NULLIF([priceType], '') END AS price_type, "
|
|
. "CASE [priceChangeType] WHEN '0' THEN N'普通变价' WHEN '1' THEN N'清货变价' "
|
|
. "WHEN '2' THEN N'阶段变价' WHEN '4' THEN N'打折入库' ELSE NULLIF([priceChangeType], '') END AS change_type, "
|
|
. "CASE [isCostReduction] WHEN '1' THEN N'是' WHEN '0' THEN N'否' ELSE NULL END AS cost_reduction, "
|
|
. '[originalPrice] AS price_before, '
|
|
. '[afterPrice] AS price_after, '
|
|
. '[diffPrice] AS price_diff, '
|
|
. '[applyUser] AS applicant, '
|
|
. '[remark] AS remark, '
|
|
. 'CONVERT(varchar(19), [effectStartTime], 120) AS effective_start, '
|
|
. 'CONVERT(varchar(19), [effectEndTime], 120) AS effective_end, '
|
|
. 'CONVERT(varchar(19), COALESCE([updateTime], [createTime]), 120) AS completed_at '
|
|
. 'FROM ' . self::TABLE
|
|
. $whereSql
|
|
. ' ORDER BY COALESCE([updateTime], [createTime]) DESC, [Id] DESC, [skucode] ASC'
|
|
. " OFFSET {$offset} ROWS FETCH NEXT {$fetch} ROWS ONLY";
|
|
|
|
return ['rows' => array_map([$this, 'normalize'], $this->query->select($sql, $bindings))];
|
|
}
|
|
|
|
private function contains(string $value): string
|
|
{
|
|
return '%' . str_replace(['\\', '%', '_'], ['\\\\', '\\%', '\\_'], trim($value)) . '%';
|
|
}
|
|
|
|
/** @param array<string,mixed> $row */
|
|
private function normalize(array $row): array
|
|
{
|
|
foreach (['price_before', 'price_after', 'price_diff'] as $field) {
|
|
$row[$field] = $row[$field] === null || $row[$field] === ''
|
|
? null
|
|
: (float) $row[$field];
|
|
}
|
|
|
|
return $row;
|
|
}
|
|
}
|