ReplenishmentPolicy.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. <?php
  2. declare(strict_types=1);
  3. namespace plugin\saiadmin\app\service\alerts;
  4. /** One persisted platform policy snapshot per query service. */
  5. final class ReplenishmentPolicy
  6. {
  7. private readonly array $settings;
  8. public function __construct() { $this->settings=(new AlertSettings())->current(); }
  9. public function settings(): array { return $this->settings; }
  10. public function daysExpression(): string
  11. {
  12. return '(CASE WHEN e.employee_count > 0 THEN a.full_qty * '.(int)$this->settings['days_per_barrel'].'.0 / NULLIF(e.employee_count,0) ELSE NULL END)';
  13. }
  14. public function alertExpression(): string
  15. {
  16. return '(a.full_qty < '.(int)$this->settings['alert_qty'].')';
  17. }
  18. public function urgentExpression(): string
  19. {
  20. return '(a.full_qty <= '.(int)$this->settings['urgent_qty'].')';
  21. }
  22. public function evaluate(array $row): array
  23. {
  24. $full = (int)$row['full_qty'];
  25. $people = (int)($row['employee_count'] ?? 0);
  26. $daily = $people > 0 ? (float)$row['liters'] * $people / $this->settings['days_per_barrel'] : null;
  27. $days = $people > 0 ? $full * $this->settings['days_per_barrel'] / $people : null;
  28. $alert = $full < $this->settings['alert_qty'];
  29. return ['available_entitlement' => (int)$row['entitlement'] - (int)$row['frozen'],
  30. 'employee_count' => $people > 0 ? $people : null,
  31. 'estimated_daily_liters' => $daily === null ? null : round($daily, 2),
  32. 'estimated_daily_barrels' => $people > 0 ? round($people / $this->settings['days_per_barrel'], 2) : null,
  33. 'days_left' => $days === null ? null : round($days, 1), 'raw_days_left' => $days,
  34. 'is_alert' => $alert, 'severity' => !$alert ? 'healthy' : ($full <= $this->settings['urgent_qty'] ? 'urgent' : 'normal'),
  35. 'reasons' => [($alert ? '现场满桶少于' : '现场满桶不少于').$this->settings['alert_qty'].'桶']];
  36. }
  37. }