- Added new section in AGENTS.md detailing learned workspace facts for better understanding of settlement processes. - Updated AgentNodeDestroyController to remove unnecessary checks for admin users. - Enhanced AgentSettlement controllers to assert permissions for finance adjustments and bill operations. - Improved query scopes in AgentSettlement services to ensure proper data access based on admin roles. - Refactored methods in SettlementPartyEnrichment for better bill row enrichment and data handling. - Introduced new methods in AdminAgentSettlementScope for managing agent node visibility and finance adjustments.
70 lines
2.0 KiB
PHP
70 lines
2.0 KiB
PHP
<?php
|
||
|
||
namespace App\Support;
|
||
|
||
use Carbon\Carbon;
|
||
use Illuminate\Validation\ValidationException;
|
||
|
||
/** 账期起止边界:开账时规范化写入,关账/聚合/流水筛选共用同一对 UTC 时刻。 */
|
||
final class AgentSettlementPeriodWindow
|
||
{
|
||
/**
|
||
* @return array{0: Carbon, 1: Carbon}
|
||
*/
|
||
public static function bounds(string $periodStart, string $periodEnd): array
|
||
{
|
||
return [
|
||
Carbon::parse($periodStart)->utc(),
|
||
Carbon::parse($periodEnd)->utc(),
|
||
];
|
||
}
|
||
|
||
/**
|
||
* @return array{0: string, 1: string}
|
||
*/
|
||
public static function boundStrings(string $periodStart, string $periodEnd): array
|
||
{
|
||
[$start, $end] = self::bounds($periodStart, $periodEnd);
|
||
|
||
return [$start->toDateTimeString(), $end->toDateTimeString()];
|
||
}
|
||
|
||
/**
|
||
* 开账 API:支持 `Y-m-d` 或带时刻字符串;前者按 UTC 自然日扩界,后者按 UTC 解释。
|
||
*
|
||
* @return array{0: string, 1: string}
|
||
*/
|
||
public static function normalizeInputBounds(string $periodStart, string $periodEnd): array
|
||
{
|
||
$startRaw = trim($periodStart);
|
||
$endRaw = trim($periodEnd);
|
||
|
||
if ($startRaw === '' || $endRaw === '') {
|
||
throw ValidationException::withMessages([
|
||
'period_start' => ['required'],
|
||
]);
|
||
}
|
||
|
||
$startAt = self::isDateOnly($startRaw)
|
||
? Carbon::parse($startRaw.' 00:00:00', 'UTC')
|
||
: Carbon::parse($startRaw)->utc();
|
||
|
||
$endAt = self::isDateOnly($endRaw)
|
||
? Carbon::parse($endRaw.' 23:59:59', 'UTC')
|
||
: Carbon::parse($endRaw)->utc();
|
||
|
||
if ($endAt->lessThan($startAt)) {
|
||
throw ValidationException::withMessages([
|
||
'period_end' => ['after:period_start'],
|
||
]);
|
||
}
|
||
|
||
return [$startAt->toDateTimeString(), $endAt->toDateTimeString()];
|
||
}
|
||
|
||
private static function isDateOnly(string $value): bool
|
||
{
|
||
return (bool) preg_match('/^\d{4}-\d{2}-\d{2}$/', $value);
|
||
}
|
||
}
|