ProcuremenStatus.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <?php
  2. namespace app\common\library;
  3. /**
  4. * 协助采购状态文案(purchase_order / purchase_order_detail)
  5. *
  6. * purchase_order.status(主单是否完结):
  7. * 进行中 — 协助流程未完结(已下发、待确认、待审批等)
  8. * 已完结 — 采购确认通过,或协助初选直接点「完结」
  9. *
  10. * purchase_order.wflow_status(主单流程阶段,与 status 分工不同):
  11. * 待下发 — 尚未协助下发,或退回初选后
  12. * 待确认 — 已通知供应商报价,待采购选定供应商(原 1)
  13. * 已驳回 — 采购终审驳回,退回确认供应商(可再次选定,业务上等同待确认)
  14. * 待审批 — 已选定供应商,待采购终审(原 2)
  15. * 已审核 — 采购终审通过,流程结束(原 3)
  16. *
  17. * purchase_order_detail.status(下发明细采购选定):
  18. * 未选中 — 默认 / 未中标
  19. * 已选中 — 采购确认选中的供应商明细(原 1)
  20. * 已废弃 — 退回初选归档,不参与当前流程(原 2)
  21. *
  22. * purchase_order_detail.status_name(供应商填单 / 手机端 Tab,保持原中文):
  23. * 未提交 / 已提交 / 已完成 / 未通过 / 已废弃
  24. */
  25. class ProcuremenStatus
  26. {
  27. public const PO_IN_PROGRESS = '进行中';
  28. public const PO_COMPLETED = '已完结';
  29. public const WFLOW_PENDING_ISSUE = '待下发';
  30. public const WFLOW_PENDING_CONFIRM = '待确认';
  31. public const WFLOW_REJECTED = '已驳回';
  32. public const WFLOW_PENDING_APPROVAL = '待审批';
  33. public const WFLOW_APPROVED = '已审核';
  34. public const POD_UNPICKED = '未选中';
  35. public const POD_PICKED = '已选中';
  36. public const POD_VOID = '已废弃';
  37. public static function normalizePoStatus($value): string
  38. {
  39. $s = trim((string)$value);
  40. if ($s === '' || $s === '0' || strcasecmp($s, self::PO_IN_PROGRESS) === 0) {
  41. return self::PO_IN_PROGRESS;
  42. }
  43. if ($s === '1' || strcasecmp($s, self::PO_COMPLETED) === 0) {
  44. return self::PO_COMPLETED;
  45. }
  46. return $s;
  47. }
  48. public static function isPoCompleted($value): bool
  49. {
  50. return self::normalizePoStatus($value) === self::PO_COMPLETED;
  51. }
  52. public static function isPoInProgress($value): bool
  53. {
  54. return self::normalizePoStatus($value) === self::PO_IN_PROGRESS;
  55. }
  56. public static function normalizeWflowStatus($value): string
  57. {
  58. $s = trim((string)$value);
  59. if ($s === '' || $s === '0' || strcasecmp($s, self::WFLOW_PENDING_ISSUE) === 0) {
  60. return self::WFLOW_PENDING_ISSUE;
  61. }
  62. if ($s === '1' || strcasecmp($s, self::WFLOW_PENDING_CONFIRM) === 0) {
  63. return self::WFLOW_PENDING_CONFIRM;
  64. }
  65. if ($s === '4' || strcasecmp($s, self::WFLOW_REJECTED) === 0) {
  66. return self::WFLOW_REJECTED;
  67. }
  68. if ($s === '2' || strcasecmp($s, self::WFLOW_PENDING_APPROVAL) === 0 || $s === '待审核') {
  69. return self::WFLOW_PENDING_APPROVAL;
  70. }
  71. if ($s === '3' || strcasecmp($s, self::WFLOW_APPROVED) === 0) {
  72. return self::WFLOW_APPROVED;
  73. }
  74. return $s;
  75. }
  76. public static function isWflowPendingIssue($value): bool
  77. {
  78. return self::normalizeWflowStatus($value) === self::WFLOW_PENDING_ISSUE;
  79. }
  80. public static function isWflowRejected($value): bool
  81. {
  82. return self::normalizeWflowStatus($value) === self::WFLOW_REJECTED;
  83. }
  84. /**
  85. * 待采购选定供应商:待确认 + 已驳回(驳回后可再次选定)
  86. */
  87. public static function isWflowPendingConfirm($value): bool
  88. {
  89. $w = self::normalizeWflowStatus($value);
  90. return $w === self::WFLOW_PENDING_CONFIRM || $w === self::WFLOW_REJECTED;
  91. }
  92. public static function isWflowPendingApproval($value): bool
  93. {
  94. return self::normalizeWflowStatus($value) === self::WFLOW_PENDING_APPROVAL;
  95. }
  96. public static function isWflowApproved($value): bool
  97. {
  98. return self::normalizeWflowStatus($value) === self::WFLOW_APPROVED;
  99. }
  100. public static function wflowAtLeastConfirm($value): bool
  101. {
  102. $w = self::normalizeWflowStatus($value);
  103. return $w === self::WFLOW_PENDING_CONFIRM
  104. || $w === self::WFLOW_REJECTED
  105. || $w === self::WFLOW_PENDING_APPROVAL;
  106. }
  107. public static function normalizePodPickStatus($value): string
  108. {
  109. $s = trim((string)$value);
  110. if ($s === '' || $s === '0' || strcasecmp($s, self::POD_UNPICKED) === 0) {
  111. return self::POD_UNPICKED;
  112. }
  113. if ($s === '1' || strcasecmp($s, self::POD_PICKED) === 0) {
  114. return self::POD_PICKED;
  115. }
  116. if ($s === '2' || strcasecmp($s, self::POD_VOID) === 0 || strcasecmp($s, '已废弃') === 0) {
  117. return self::POD_VOID;
  118. }
  119. return $s;
  120. }
  121. public static function isPodPicked($value): bool
  122. {
  123. return self::normalizePodPickStatus($value) === self::POD_PICKED;
  124. }
  125. public static function isPodVoid($value): bool
  126. {
  127. return self::normalizePodPickStatus($value) === self::POD_VOID;
  128. }
  129. /** @return string[] */
  130. public static function wflowPendingConfirmValues(): array
  131. {
  132. // 已驳回可再次选定供应商,与待确认同属确认页工作队列
  133. return [self::WFLOW_PENDING_CONFIRM, self::WFLOW_REJECTED, '1', '4'];
  134. }
  135. /** @return string[] */
  136. public static function wflowPendingApprovalValues(): array
  137. {
  138. return [self::WFLOW_PENDING_APPROVAL, '2'];
  139. }
  140. /** @return string[] */
  141. public static function wflowApprovedValues(): array
  142. {
  143. return [self::WFLOW_APPROVED, '3'];
  144. }
  145. /**
  146. * 确认页 / 审批页共用列表:待确认 + 已驳回 + 待审批 + 已审核
  147. *
  148. * @return string[]
  149. */
  150. public static function wflowConfirmAndAuditListValues(): array
  151. {
  152. return array_values(array_unique(array_merge(
  153. self::wflowPendingConfirmValues(),
  154. self::wflowPendingApprovalValues(),
  155. self::wflowApprovedValues()
  156. )));
  157. }
  158. /**
  159. * 列表「订单状态」展示:待确认 / 已驳回 / 待审核 / 已审核
  160. */
  161. public static function orderStatusLabelForList($value): string
  162. {
  163. $w = self::normalizeWflowStatus($value);
  164. if ($w === self::WFLOW_REJECTED || $w === '已驳回') {
  165. return '已驳回';
  166. }
  167. if ($w === self::WFLOW_PENDING_CONFIRM || $w === '待确认') {
  168. return '待确认';
  169. }
  170. if ($w === self::WFLOW_PENDING_APPROVAL || $w === '待审核') {
  171. return '待审核';
  172. }
  173. if ($w === self::WFLOW_APPROVED || $w === '已审核') {
  174. return '已审核';
  175. }
  176. return $w !== '' ? $w : '';
  177. }
  178. /**
  179. * 确认/审批列表按订单状态排序权重(越小越靠前)
  180. * - audit(采购供应商确认):已驳回 → 待确认 → 待审核 → 已审核
  181. * - confirm(采购确认/审批):待审核 → 已驳回 → 待确认 → 已审核
  182. */
  183. public static function orderStatusSortWeight(string $stage, $value): int
  184. {
  185. $label = self::orderStatusLabelForList($value);
  186. if ($stage === 'audit') {
  187. $map = ['已驳回' => 0, '待确认' => 1, '待审核' => 2, '已审核' => 3];
  188. } else {
  189. // confirm(审批页)等
  190. $map = ['待审核' => 0, '已驳回' => 1, '待确认' => 2, '已审核' => 3];
  191. }
  192. return $map[$label] ?? 99;
  193. }
  194. /** @return string[] */
  195. public static function wflowPendingIssueValues(): array
  196. {
  197. return [self::WFLOW_PENDING_ISSUE, '0', ''];
  198. }
  199. /** @return string[] */
  200. public static function podPickedValues(): array
  201. {
  202. return [self::POD_PICKED, '1'];
  203. }
  204. /** @return string[] */
  205. public static function podUnpickedValues(): array
  206. {
  207. return [self::POD_UNPICKED, '0', ''];
  208. }
  209. /** @return string[] */
  210. public static function poCompletedValues(): array
  211. {
  212. return [self::PO_COMPLETED, '1'];
  213. }
  214. /** @return string[] */
  215. public static function poInProgressValues(): array
  216. {
  217. return [self::PO_IN_PROGRESS, '0'];
  218. }
  219. public static function sqlPoCompleted(string $column = 'status'): string
  220. {
  221. $c = self::quoteSqlIdent($column);
  222. return "TRIM(CAST({$c} AS CHAR)) IN ('" . self::PO_COMPLETED . "','1')";
  223. }
  224. public static function sqlPoInProgress(string $column = 'status'): string
  225. {
  226. $c = self::quoteSqlIdent($column);
  227. return "TRIM(CAST({$c} AS CHAR)) IN ('" . self::PO_IN_PROGRESS . "','0')";
  228. }
  229. public static function sqlPodNotVoid(string $column = 'status'): string
  230. {
  231. $c = self::quoteSqlIdent($column);
  232. $void = str_replace("'", "''", self::POD_VOID);
  233. return "({$c} IS NULL OR TRIM(CAST({$c} AS CHAR)) NOT IN ('{$void}','2'))";
  234. }
  235. protected static function quoteSqlIdent(string $column): string
  236. {
  237. if (strpos($column, '.') !== false) {
  238. $parts = explode('.', $column, 2);
  239. return '`' . str_replace('`', '', $parts[0]) . '`.`' . str_replace('`', '', $parts[1]) . '`';
  240. }
  241. return '`' . str_replace('`', '', $column) . '`';
  242. }
  243. }