|
|
@@ -48,7 +48,7 @@ class Procuremen extends Backend
|
|
|
protected $pickHiddenScydgySetCache = null;
|
|
|
|
|
|
/** 邮件发送日志表结构已就绪缓存键 */
|
|
|
- protected const EMAIL_SEND_LOG_SCHEMA_CACHE_KEY = 'purchase_email_send_log_schema_v1';
|
|
|
+ protected const EMAIL_SEND_LOG_SCHEMA_CACHE_KEY = 'purchase_email_send_log_schema_v2';
|
|
|
|
|
|
/**
|
|
|
* 采购子接口均走菜单规则鉴权;下列方法在方法内用 hasProcuremenPerm 做别名校验。
|
|
|
@@ -94,6 +94,7 @@ class Procuremen extends Backend
|
|
|
'1' => ProcuremenStatus::WFLOW_PENDING_CONFIRM,
|
|
|
'2' => ProcuremenStatus::WFLOW_PENDING_APPROVAL,
|
|
|
'3' => ProcuremenStatus::WFLOW_APPROVED,
|
|
|
+ '4' => ProcuremenStatus::WFLOW_REJECTED,
|
|
|
];
|
|
|
try {
|
|
|
foreach ($map as $num => $text) {
|
|
|
@@ -1352,8 +1353,9 @@ class Procuremen extends Backend
|
|
|
protected function loadPurchaseOrderRowsForListStage(string $stage, string $ym = '', bool $applyMonthRange = false): array
|
|
|
{
|
|
|
$this->ensurePurchaseOrderCzlyqColumn();
|
|
|
+ $this->ensurePurchaseOrderManualPickColumns();
|
|
|
$fields = 'id,scydgy_id,CCYDH,CYJMC,CCLBMMC,CDXMC,CGYBH,CGYMC,CDW,NGZL,CDF,cGzzxMc,MBZ,cywyxm,czlyq,'
|
|
|
- . 'This_quantity,ceilingPrice,pick_time,createtime,dputrecord,dStamp,wflow_status,status,pick_company_name,order_batch_no';
|
|
|
+ . 'This_quantity,ceilingPrice,pick_time,createtime,dputrecord,dStamp,wflow_status,status,pick_company_name,manual_pick,order_batch_no';
|
|
|
try {
|
|
|
$this->ensurePurchaseOrderOrderBatchNoColumn();
|
|
|
$query = Db::table('purchase_order')->field($fields);
|
|
|
@@ -1815,9 +1817,58 @@ class Procuremen extends Backend
|
|
|
$sortField = 'ID';
|
|
|
}
|
|
|
}
|
|
|
+ // 列表「下发时间」列字段为 issue_time,与 pick_time 同义
|
|
|
+ if ($sortField === 'issue_time') {
|
|
|
+ $sortField = 'pick_time';
|
|
|
+ }
|
|
|
$ord = strtoupper((string)$order) === 'ASC' ? 1 : -1;
|
|
|
$nFiltered = count($filtered);
|
|
|
- if ($nFiltered > 1) {
|
|
|
+ if (in_array($wffTab, ['audit', 'confirm'], true) && $nFiltered > 1) {
|
|
|
+ // 确认/审批:状态分组优先;同状态内固定按下发时间倒序(最新在上,不跟前端 ASC/DESC 翻转)
|
|
|
+ // 先补齐下发时间,避免 pick_time 空时回退到提交日导致顺序错乱
|
|
|
+ $this->hydrateProcuremenListIssueSortTimes($filtered);
|
|
|
+ usort($filtered, function ($a, $b) use ($wffTab) {
|
|
|
+ if (!is_array($a)) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ if (!is_array($b)) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ $statusKeyA = $a['order_status_text'] ?? $a['wflow_status'] ?? '';
|
|
|
+ if (trim((string)$statusKeyA) === '') {
|
|
|
+ $statusKeyA = $a['wflow_status'] ?? '';
|
|
|
+ }
|
|
|
+ $statusKeyB = $b['order_status_text'] ?? $b['wflow_status'] ?? '';
|
|
|
+ if (trim((string)$statusKeyB) === '') {
|
|
|
+ $statusKeyB = $b['wflow_status'] ?? '';
|
|
|
+ }
|
|
|
+ $wa = ProcuremenStatus::orderStatusSortWeight($wffTab, $statusKeyA);
|
|
|
+ $wb = ProcuremenStatus::orderStatusSortWeight($wffTab, $statusKeyB);
|
|
|
+ if ($wa !== $wb) {
|
|
|
+ return $wa <=> $wb;
|
|
|
+ }
|
|
|
+ $ta = trim((string)($a['_issue_sort_time'] ?? ''));
|
|
|
+ if ($ta === '') {
|
|
|
+ $ta = $this->procuremenRowListSortTime($a, 'pick_time');
|
|
|
+ }
|
|
|
+ $tb = trim((string)($b['_issue_sort_time'] ?? ''));
|
|
|
+ if ($tb === '') {
|
|
|
+ $tb = $this->procuremenRowListSortTime($b, 'pick_time');
|
|
|
+ }
|
|
|
+ if ($ta !== $tb) {
|
|
|
+ if ($ta === '') {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ if ($tb === '') {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ // 倒序:新的在前
|
|
|
+ return strcmp($tb, $ta);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ((int)($b['ID'] ?? 0) <=> (int)($a['ID'] ?? 0));
|
|
|
+ });
|
|
|
+ } elseif ($nFiltered > 1) {
|
|
|
if (in_array($sortField, ['pick_time', 'dputrecord', 'dStamp', 'createtime'], true)) {
|
|
|
usort($filtered, function ($a, $b) use ($sortField, $ord) {
|
|
|
$ta = $this->procuremenRowListSortTime($a, $sortField);
|
|
|
@@ -1871,22 +1922,6 @@ class Procuremen extends Backend
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
- // 确认/审批:订单状态优先(同状态内保留上面时间等排序)
|
|
|
- if (in_array($wffTab, ['audit', 'confirm'], true) && count($filtered) > 1) {
|
|
|
- $statusWeights = [];
|
|
|
- foreach ($filtered as $i => $row) {
|
|
|
- if (!is_array($row)) {
|
|
|
- $statusWeights[$i] = 99;
|
|
|
- continue;
|
|
|
- }
|
|
|
- $statusKey = $row['order_status_text'] ?? $row['wflow_status'] ?? '';
|
|
|
- if (trim((string)$statusKey) === '') {
|
|
|
- $statusKey = $row['wflow_status'] ?? '';
|
|
|
- }
|
|
|
- $statusWeights[$i] = ProcuremenStatus::orderStatusSortWeight($wffTab, $statusKey);
|
|
|
- }
|
|
|
- array_multisort($statusWeights, SORT_ASC, SORT_NUMERIC, $filtered);
|
|
|
- }
|
|
|
|
|
|
$offset = max(0, (int)$offset);
|
|
|
$limit = max(1, (int)$limit);
|
|
|
@@ -2373,6 +2408,111 @@ class Procuremen extends Backend
|
|
|
return $pool;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 确认/审批列表排序:补齐下发时间(pick_time + 下发操作日志)
|
|
|
+ *
|
|
|
+ * @param array<int, array<string, mixed>> $rows
|
|
|
+ */
|
|
|
+ protected function hydrateProcuremenListIssueSortTimes(array &$rows): void
|
|
|
+ {
|
|
|
+ if ($rows === []) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $sidList = [];
|
|
|
+ foreach ($rows as $rw) {
|
|
|
+ if (!is_array($rw)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!empty($rw['_order_merge_rows']) && is_array($rw['_order_merge_rows'])) {
|
|
|
+ foreach ($rw['_order_merge_rows'] as $mr) {
|
|
|
+ if (!is_array($mr)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $mid = (int)($mr['ID'] ?? 0);
|
|
|
+ if ($this->isValidScydgyRowId($mid)) {
|
|
|
+ $sidList[$mid] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $id = (int)($rw['ID'] ?? 0);
|
|
|
+ if ($this->isValidScydgyRowId($id)) {
|
|
|
+ $sidList[$id] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $issueBySid = [];
|
|
|
+ $sids = array_keys($sidList);
|
|
|
+ if ($sids !== []) {
|
|
|
+ $issueActs = ProcuremenOperLog::expandActionQueryValues('issue_submit');
|
|
|
+ if ($issueActs !== []) {
|
|
|
+ try {
|
|
|
+ $logs = Db::table('purchase_order_oper_log')
|
|
|
+ ->where(ProcuremenOperLog::COL_SCYDGY_ID, 'in', $sids)
|
|
|
+ ->where(ProcuremenOperLog::COL_ACTION, 'in', $issueActs)
|
|
|
+ ->field(ProcuremenOperLog::COL_SCYDGY_ID . ',' . ProcuremenOperLog::COL_TIME)
|
|
|
+ ->order('id', 'asc')
|
|
|
+ ->select();
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ $logs = [];
|
|
|
+ }
|
|
|
+ if (is_array($logs)) {
|
|
|
+ foreach ($logs as $lg) {
|
|
|
+ if (!is_array($lg)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $lg = ProcuremenOperLog::normalizeRow($lg);
|
|
|
+ $sid = (int)($lg[ProcuremenOperLog::COL_SCYDGY_ID] ?? 0);
|
|
|
+ if ($sid === 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $tm = $this->formatProcuremenDetailTime($lg[ProcuremenOperLog::COL_TIME] ?? null);
|
|
|
+ if ($tm === '') {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!isset($issueBySid[$sid]) || strcmp($tm, $issueBySid[$sid]) > 0) {
|
|
|
+ $issueBySid[$sid] = $tm;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ foreach ($rows as &$rw) {
|
|
|
+ if (!is_array($rw)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $mergeSids = [];
|
|
|
+ if (!empty($rw['_order_merge_rows']) && is_array($rw['_order_merge_rows'])) {
|
|
|
+ foreach ($rw['_order_merge_rows'] as $mr) {
|
|
|
+ if (!is_array($mr)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $mid = (int)($mr['ID'] ?? 0);
|
|
|
+ if ($this->isValidScydgyRowId($mid)) {
|
|
|
+ $mergeSids[] = $mid;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $rid = (int)($rw['ID'] ?? 0);
|
|
|
+ if ($this->isValidScydgyRowId($rid) && !in_array($rid, $mergeSids, true)) {
|
|
|
+ $mergeSids[] = $rid;
|
|
|
+ }
|
|
|
+ $best = $this->procuremenRowListSortTime($rw, 'pick_time');
|
|
|
+ foreach ($mergeSids as $sid) {
|
|
|
+ if (isset($issueBySid[$sid]) && ($best === '' || strcmp($issueBySid[$sid], $best) > 0)) {
|
|
|
+ $best = $issueBySid[$sid];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $rw['_issue_sort_time'] = $best;
|
|
|
+ if ($best !== '') {
|
|
|
+ $pickOut = trim((string)($rw['pick_time'] ?? ''));
|
|
|
+ if ($pickOut === '' || stripos($pickOut, '0000-00-00') === 0) {
|
|
|
+ $rw['pick_time'] = $best;
|
|
|
+ }
|
|
|
+ $rw['issue_time'] = $best;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ unset($rw);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 列表排序用时间:下发时间 pick_time 优先,其次 createtime / dputrecord / dStamp
|
|
|
*/
|
|
|
@@ -3441,25 +3581,42 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if ($batchNo !== '') {
|
|
|
- // 有正式批次号:开标只看本批;指定只看本行/同批合并行,不按订单号全局查
|
|
|
- $verified = isset($bidOpenBatchSet[$batchNo]);
|
|
|
- } else {
|
|
|
- // 旧数据无批次号:兼容按订单号开标/指定
|
|
|
- $verified = false;
|
|
|
- $ccydhTokens = $this->expandProcuremenCcydhTokens($rw['CCYDH'] ?? '');
|
|
|
- if (!empty($rw['_order_merge_rows']) && is_array($rw['_order_merge_rows'])) {
|
|
|
- foreach ($rw['_order_merge_rows'] as $mr) {
|
|
|
- if (!is_array($mr)) {
|
|
|
+ // 收集本行/合并行订单号,供开标记录与自选集合兜底(自选=免开标,等同已开标可继续确认)
|
|
|
+ $ccydhTokens = $this->expandProcuremenCcydhTokens($rw['CCYDH'] ?? '');
|
|
|
+ if (!empty($rw['_order_merge_rows']) && is_array($rw['_order_merge_rows'])) {
|
|
|
+ foreach ($rw['_order_merge_rows'] as $mr) {
|
|
|
+ if (!is_array($mr)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if ($batchNo !== '') {
|
|
|
+ $mrBatch = $this->resolveProcuremenOrderBatchNo($mr);
|
|
|
+ if ($mrBatch !== '' && $mrBatch !== $batchNo) {
|
|
|
continue;
|
|
|
}
|
|
|
- foreach ($this->expandProcuremenCcydhTokens($mr['CCYDH'] ?? '') as $one) {
|
|
|
- if (!in_array($one, $ccydhTokens, true)) {
|
|
|
- $ccydhTokens[] = $one;
|
|
|
- }
|
|
|
+ }
|
|
|
+ foreach ($this->expandProcuremenCcydhTokens($mr['CCYDH'] ?? '') as $one) {
|
|
|
+ if (!in_array($one, $ccydhTokens, true)) {
|
|
|
+ $ccydhTokens[] = $one;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($batchNo !== '') {
|
|
|
+ // 有正式批次号:开标只看本批
|
|
|
+ $verified = isset($bidOpenBatchSet[$batchNo]);
|
|
|
+ // 自选兜底:本行字段漏带时,仍可用有效主单上的自选标记(旧批已软删,不会串读)
|
|
|
+ if (!$manual) {
|
|
|
+ foreach ($ccydhTokens as $c) {
|
|
|
+ if (isset($manualPickSet[$c])) {
|
|
|
+ $manual = true;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ } else {
|
|
|
+ // 旧数据无批次号:兼容按订单号开标/指定
|
|
|
+ $verified = false;
|
|
|
foreach ($ccydhTokens as $c) {
|
|
|
if (isset($bidOpenSet[$c])) {
|
|
|
$verified = true;
|
|
|
@@ -3541,7 +3698,7 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 按订单状态筛选(待确认 / 待审核 / 已审核)
|
|
|
+ * 按订单状态筛选(待确认 / 已驳回 / 待审核 / 已审核)
|
|
|
*
|
|
|
* @param array<int, array<string, mixed>> $pool
|
|
|
* @return array<int, array<string, mixed>>
|
|
|
@@ -3549,7 +3706,7 @@ class Procuremen extends Backend
|
|
|
protected function filterProcuremenPoolByOrderStatus(array $pool, string $status): array
|
|
|
{
|
|
|
$status = trim($status);
|
|
|
- if ($status === '' || !in_array($status, ['待确认', '待审核', '已审核'], true)) {
|
|
|
+ if ($status === '' || !in_array($status, ['待确认', '已驳回', '待审核', '已审核'], true)) {
|
|
|
return $pool;
|
|
|
}
|
|
|
$out = [];
|
|
|
@@ -4816,6 +4973,8 @@ class Procuremen extends Backend
|
|
|
$r['pick_company_name'] = $pickNm;
|
|
|
$r['picked_supplier_name'] = $pickNm;
|
|
|
}
|
|
|
+ // 列表开标状态依赖此字段:有批次号时只认本行/合并行,必须从库带出
|
|
|
+ $r['manual_pick'] = ((int)($dbRow['manual_pick'] ?? 0) === 1) ? 1 : 0;
|
|
|
$r['wflow_status'] = trim((string)($dbRow['wflow_status'] ?? ''));
|
|
|
$r['order_status_text'] = ProcuremenStatus::orderStatusLabelForList($r['wflow_status']);
|
|
|
if (array_key_exists('status', $dbRow)) {
|
|
|
@@ -6019,6 +6178,9 @@ class Procuremen extends Backend
|
|
|
if (isset($pos[0]) && is_array($pos[0])) {
|
|
|
$poIdLog = (int)($pos[0]['id'] ?? 0);
|
|
|
}
|
|
|
+ $mergeRowsLog = is_array($bundle['merge_rows'] ?? null) ? $bundle['merge_rows'] : [];
|
|
|
+ $emailLogCcydh = $this->collectCcydhListForEmailLog($mergeRowsLog, $pos);
|
|
|
+ $emailLogBatchNo = $this->resolveBundleOrderBatchNo($bundle);
|
|
|
$sendSmsSafe = function ($phone, $content) {
|
|
|
$phone = trim((string)$phone);
|
|
|
if ($phone === '') {
|
|
|
@@ -6030,7 +6192,7 @@ class Procuremen extends Backend
|
|
|
Log::write('采购确认短信失败 phone=' . $phone . ' ' . $e->getMessage(), 'error');
|
|
|
}
|
|
|
};
|
|
|
- $sendConfirmEmailSafe = function (array $dr, string $emailScene) use ($confirmNotifyVars, $poIdLog) {
|
|
|
+ $sendConfirmEmailSafe = function (array $dr, string $emailScene) use ($confirmNotifyVars, $poIdLog, $emailLogCcydh, $emailLogBatchNo) {
|
|
|
$cname = trim((string)($dr['company_name'] ?? ''));
|
|
|
$ph = trim((string)($dr['phone'] ?? ''));
|
|
|
$toEmail = trim((string)($dr['email'] ?? ''));
|
|
|
@@ -6063,16 +6225,18 @@ class Procuremen extends Backend
|
|
|
$mailSubject = $this->resolveProcuremenEmailSubject($emailScene);
|
|
|
$mailConfig = $this->loadMailerConfig();
|
|
|
$this->issueSendSupplierEmail([
|
|
|
- 'company_name' => $cname,
|
|
|
- 'email' => $toEmail,
|
|
|
- 'mail_plain' => $mailPlain,
|
|
|
- 'mail_body' => $mailBody,
|
|
|
- 'notify_vars' => $vars,
|
|
|
- 'sms_content' => '',
|
|
|
- 'detail_links' => $platformUrl !== '' ? [['url' => $platformUrl, 'cgymc' => '']] : [],
|
|
|
- 'email_log_scene' => (strpos((string)$emailScene, 'confirm_ok') !== false) ? 'confirm_ok' : 'confirm_fail',
|
|
|
- 'email_log_scydgy_id' => (int)($dr['scydgy_id'] ?? 0),
|
|
|
+ 'company_name' => $cname,
|
|
|
+ 'email' => $toEmail,
|
|
|
+ 'mail_plain' => $mailPlain,
|
|
|
+ 'mail_body' => $mailBody,
|
|
|
+ 'notify_vars' => $vars,
|
|
|
+ 'sms_content' => '',
|
|
|
+ 'detail_links' => $platformUrl !== '' ? [['url' => $platformUrl, 'cgymc' => '']] : [],
|
|
|
+ 'email_log_scene' => (strpos((string)$emailScene, 'confirm_ok') !== false) ? 'confirm_ok' : 'confirm_fail',
|
|
|
+ 'email_log_scydgy_id' => (int)($dr['scydgy_id'] ?? 0),
|
|
|
'email_log_purchase_order_id' => $poIdLog,
|
|
|
+ 'email_log_ccydh' => $emailLogCcydh !== '' ? $emailLogCcydh : trim((string)($vars['ccydh'] ?? '')),
|
|
|
+ 'email_log_order_batch_no' => $emailLogBatchNo,
|
|
|
], $mailConfig, $mailSubject);
|
|
|
} catch (\Throwable $e) {
|
|
|
Log::write('采购确认邮件失败 company=' . $cname . ' email=' . $toEmail . ' ' . $e->getMessage(), 'error');
|
|
|
@@ -7050,6 +7214,7 @@ class Procuremen extends Backend
|
|
|
try {
|
|
|
$poBn = Db::table('purchase_order')
|
|
|
->where('scydgy_id', 'in', array_keys($detailSidList))
|
|
|
+ ->whereRaw("TRIM(IFNULL(`order_batch_no`,'')) <> ''")
|
|
|
->order('id', 'desc')
|
|
|
->find();
|
|
|
if (is_array($poBn)) {
|
|
|
@@ -7752,16 +7917,20 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
// 已选供应商:取合并行中首个非空 pick_company_name
|
|
|
$pickedName = '';
|
|
|
+ $manualPick = ((int)($head['manual_pick'] ?? 0) === 1) ? 1 : 0;
|
|
|
foreach ($rows as $r) {
|
|
|
if (!is_array($r)) {
|
|
|
continue;
|
|
|
}
|
|
|
+ if ((int)($r['manual_pick'] ?? 0) === 1) {
|
|
|
+ $manualPick = 1;
|
|
|
+ }
|
|
|
$pn = trim((string)($r['pick_company_name'] ?? $r['picked_supplier_name'] ?? ''));
|
|
|
- if ($pn !== '') {
|
|
|
+ if ($pn !== '' && $pickedName === '') {
|
|
|
$pickedName = $pn;
|
|
|
- break;
|
|
|
}
|
|
|
}
|
|
|
+ $merged['manual_pick'] = $manualPick;
|
|
|
if ($pickedName !== '') {
|
|
|
$merged['pick_company_name'] = $pickedName;
|
|
|
$merged['picked_supplier_name'] = $pickedName;
|
|
|
@@ -9151,7 +9320,9 @@ class Procuremen extends Backend
|
|
|
{
|
|
|
$map = $this->buildBundleOrderDeliveryDeadlineMap($bundle);
|
|
|
if ($map !== []) {
|
|
|
- return (string)reset($map);
|
|
|
+ $firstDeadline = reset($map);
|
|
|
+
|
|
|
+ return (string)$firstDeadline;
|
|
|
}
|
|
|
|
|
|
return '';
|
|
|
@@ -9638,6 +9809,9 @@ class Procuremen extends Backend
|
|
|
$poIdLog = (int)($pos[0]['id'] ?? 0);
|
|
|
}
|
|
|
$notifyBundle['email_log_purchase_order_id'] = $poIdLog;
|
|
|
+ // 日志单独记订单号/批次号:多订单下发时模版变量 ccydh 会刻意留空,不能沿用到日志
|
|
|
+ $notifyBundle['email_log_ccydh'] = $this->collectCcydhListForEmailLog($mergeRows, $pos);
|
|
|
+ $notifyBundle['email_log_order_batch_no'] = $this->resolveBundleOrderBatchNo($bundle);
|
|
|
|
|
|
if ($sendEmail) {
|
|
|
$mailTplRow = $this->loadNotifyTemplateRow($emailTplScene);
|
|
|
@@ -9771,7 +9945,7 @@ class Procuremen extends Backend
|
|
|
Log::write('procuremen auditResend partial fail: ' . implode(';', $notifyErrors), 'error');
|
|
|
$ok = max(0, count($targets) - count($notifyErrors));
|
|
|
$this->success(
|
|
|
- '已向 ' . $ok . ' 家发送成功;个别未送达请核对手机号/邮箱后重试',
|
|
|
+ '已向 ' . $ok . ' 家发送成功;',
|
|
|
'',
|
|
|
[
|
|
|
'notify_failed' => 1,
|
|
|
@@ -9917,39 +10091,38 @@ class Procuremen extends Backend
|
|
|
$fromEmail = trim((string)($mailConfig['addr'] ?? ''));
|
|
|
$sendOk = true;
|
|
|
$failReason = '';
|
|
|
+ $logCcydh = trim((string)($bundle['email_log_ccydh'] ?? ''));
|
|
|
+ if ($logCcydh === '') {
|
|
|
+ $logCcydh = trim((string)(($bundle['notify_vars']['ccydh'] ?? '') ?: ($bundle['ccydh'] ?? '')));
|
|
|
+ }
|
|
|
+ $logBatchNo = trim((string)($bundle['email_log_order_batch_no'] ?? ($bundle['order_batch_no'] ?? '')));
|
|
|
+ $logCommon = [
|
|
|
+ 'from_email' => $fromEmail,
|
|
|
+ 'to_email' => $toEmail,
|
|
|
+ 'send_time' => date('Y-m-d H:i:s'),
|
|
|
+ 'scene' => (string)($bundle['email_log_scene'] ?? '初选下发'),
|
|
|
+ 'order_batch_no' => $logBatchNo,
|
|
|
+ 'ccydh' => $logCcydh,
|
|
|
+ 'company_name' => $companyName,
|
|
|
+ 'mail_subject' => $mailSubject,
|
|
|
+ 'scydgy_id' => (int)($bundle['email_log_scydgy_id'] ?? 0),
|
|
|
+ 'purchase_order_id' => (int)($bundle['email_log_purchase_order_id'] ?? 0),
|
|
|
+ ];
|
|
|
try {
|
|
|
$mail->send();
|
|
|
} catch (\Throwable $e) {
|
|
|
$sendOk = false;
|
|
|
$failReason = $e->getMessage();
|
|
|
- $this->persistEmailSendLog([
|
|
|
- 'from_email' => $fromEmail,
|
|
|
- 'to_email' => $toEmail,
|
|
|
- 'send_time' => date('Y-m-d H:i:s'),
|
|
|
- 'scene' => (string)($bundle['email_log_scene'] ?? '初选下发'),
|
|
|
- 'ccydh' => trim((string)(($bundle['notify_vars']['ccydh'] ?? '') ?: ($bundle['ccydh'] ?? ''))),
|
|
|
- 'company_name' => $companyName,
|
|
|
- 'mail_subject' => $mailSubject,
|
|
|
- 'status' => 0,
|
|
|
- 'fail_reason' => $failReason,
|
|
|
- 'scydgy_id' => (int)($bundle['email_log_scydgy_id'] ?? 0),
|
|
|
- 'purchase_order_id' => (int)($bundle['email_log_purchase_order_id'] ?? 0),
|
|
|
- ]);
|
|
|
+ $this->persistEmailSendLog(array_merge($logCommon, [
|
|
|
+ 'status' => 0,
|
|
|
+ 'fail_reason' => $failReason,
|
|
|
+ ]));
|
|
|
throw $e;
|
|
|
}
|
|
|
- $this->persistEmailSendLog([
|
|
|
- 'from_email' => $fromEmail,
|
|
|
- 'to_email' => $toEmail,
|
|
|
- 'send_time' => date('Y-m-d H:i:s'),
|
|
|
- 'scene' => (string)($bundle['email_log_scene'] ?? '初选下发'),
|
|
|
- 'ccydh' => trim((string)(($bundle['notify_vars']['ccydh'] ?? '') ?: ($bundle['ccydh'] ?? ''))),
|
|
|
- 'company_name' => $companyName,
|
|
|
- 'mail_subject' => $mailSubject,
|
|
|
- 'status' => 1,
|
|
|
- 'fail_reason' => '',
|
|
|
- 'scydgy_id' => (int)($bundle['email_log_scydgy_id'] ?? 0),
|
|
|
- 'purchase_order_id' => (int)($bundle['email_log_purchase_order_id'] ?? 0),
|
|
|
- ]);
|
|
|
+ $this->persistEmailSendLog(array_merge($logCommon, [
|
|
|
+ 'status' => 1,
|
|
|
+ 'fail_reason' => '',
|
|
|
+ ]));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -10086,6 +10259,45 @@ class Procuremen extends Backend
|
|
|
];
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 邮件发送日志用的订单号列表(多单逗号分隔;与模版变量是否留空无关)
|
|
|
+ *
|
|
|
+ * @param array<int, array<string, mixed>> $mergeRows
|
|
|
+ * @param array<int, array<string, mixed>> $pos
|
|
|
+ */
|
|
|
+ protected function collectCcydhListForEmailLog(array $mergeRows, array $pos = []): string
|
|
|
+ {
|
|
|
+ $set = [];
|
|
|
+ foreach ($mergeRows as $r) {
|
|
|
+ if (!is_array($r)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ foreach (['CCYDH', 'ccydh'] as $k) {
|
|
|
+ $dh = trim((string)($r[$k] ?? ''));
|
|
|
+ if ($dh !== '') {
|
|
|
+ $set[$dh] = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($set === []) {
|
|
|
+ foreach ($pos as $po) {
|
|
|
+ if (!is_array($po)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ foreach (['CCYDH', 'ccydh'] as $k) {
|
|
|
+ $dh = trim((string)($po[$k] ?? ''));
|
|
|
+ if ($dh !== '') {
|
|
|
+ $set[$dh] = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return implode(',', array_keys($set));
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 调试:app_debug 或 notify_dry_run 时把短信/邮件内容写入 runtime/log
|
|
|
*
|
|
|
@@ -10102,7 +10314,7 @@ class Procuremen extends Backend
|
|
|
protected function ensurePurchaseEmailSendLogTableOnce(): void
|
|
|
{
|
|
|
try {
|
|
|
- Db::query('SELECT 1 FROM `purchase_email_send_log` LIMIT 1');
|
|
|
+ Db::query('SELECT `id`,`order_batch_no`,`ccydh` FROM `purchase_email_send_log` LIMIT 1');
|
|
|
Cache::set(self::EMAIL_SEND_LOG_SCHEMA_CACHE_KEY, 1);
|
|
|
return;
|
|
|
} catch (\Throwable $e) {
|
|
|
@@ -10123,6 +10335,34 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ try {
|
|
|
+ $cols = Db::query("SHOW COLUMNS FROM `purchase_email_send_log` LIKE 'order_batch_no'");
|
|
|
+ if (!is_array($cols) || $cols === []) {
|
|
|
+ Db::execute(
|
|
|
+ "ALTER TABLE `purchase_email_send_log` ADD COLUMN `order_batch_no` varchar(32) NOT NULL DEFAULT '' COMMENT '下发批次号' AFTER `scene`"
|
|
|
+ );
|
|
|
+ }
|
|
|
+ } catch (\Throwable $ignore) {
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ $cols = Db::query("SHOW COLUMNS FROM `purchase_email_send_log` LIKE 'ccydh'");
|
|
|
+ if (is_array($cols) && $cols !== []) {
|
|
|
+ $type = strtolower((string)($cols[0]['Type'] ?? $cols[0]['type'] ?? ''));
|
|
|
+ if (preg_match('/varchar\((\d+)\)/', $type, $m) && (int)$m[1] < 500) {
|
|
|
+ Db::execute(
|
|
|
+ "ALTER TABLE `purchase_email_send_log` MODIFY COLUMN `ccydh` varchar(500) NOT NULL DEFAULT '' COMMENT '订单号(多单逗号分隔)'"
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (\Throwable $ignore) {
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ $idx = Db::query("SHOW INDEX FROM `purchase_email_send_log` WHERE Key_name = 'idx_order_batch_no'");
|
|
|
+ if (!is_array($idx) || $idx === []) {
|
|
|
+ Db::execute('ALTER TABLE `purchase_email_send_log` ADD INDEX `idx_order_batch_no` (`order_batch_no`)');
|
|
|
+ }
|
|
|
+ } catch (\Throwable $ignore) {
|
|
|
+ }
|
|
|
Cache::set(self::EMAIL_SEND_LOG_SCHEMA_CACHE_KEY, 1);
|
|
|
}
|
|
|
|
|
|
@@ -10150,7 +10390,8 @@ class Procuremen extends Backend
|
|
|
'to_email' => $cut($row['to_email'] ?? '', 128),
|
|
|
'send_time' => $row['send_time'] ?? date('Y-m-d H:i:s'),
|
|
|
'scene' => $cut($this->normalizeEmailLogSceneForStore((string)($row['scene'] ?? '')), 64),
|
|
|
- 'ccydh' => $cut($row['ccydh'] ?? '', 64),
|
|
|
+ 'order_batch_no' => $cut($row['order_batch_no'] ?? '', 32),
|
|
|
+ 'ccydh' => $cut($row['ccydh'] ?? '', 500),
|
|
|
'company_name' => $cut($row['company_name'] ?? '', 128),
|
|
|
'mail_subject' => $cut($row['mail_subject'] ?? '', 255),
|
|
|
'status' => !empty($row['status']) ? 1 : 0,
|
|
|
@@ -10164,6 +10405,17 @@ class Procuremen extends Backend
|
|
|
try {
|
|
|
Db::table('purchase_email_send_log')->insert($data);
|
|
|
} catch (\Throwable $e) {
|
|
|
+ // 兼容尚未自动补列的旧库:去掉批次号再试一次
|
|
|
+ if (stripos($e->getMessage(), 'order_batch_no') !== false) {
|
|
|
+ try {
|
|
|
+ unset($data['order_batch_no']);
|
|
|
+ Db::table('purchase_email_send_log')->insert($data);
|
|
|
+ return;
|
|
|
+ } catch (\Throwable $e2) {
|
|
|
+ Log::write('persistEmailSendLog: ' . $e2->getMessage(), 'error');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
Log::write('persistEmailSendLog: ' . $e->getMessage(), 'error');
|
|
|
}
|
|
|
}
|
|
|
@@ -10195,7 +10447,7 @@ class Procuremen extends Backend
|
|
|
public function emailLog()
|
|
|
{
|
|
|
$this->relationSearch = false;
|
|
|
- $this->searchFields = 'from_email,to_email,ccydh,company_name,admin_name,mail_subject';
|
|
|
+ $this->searchFields = 'from_email,to_email,ccydh,order_batch_no,company_name,admin_name,mail_subject';
|
|
|
$this->request->filter(['strip_tags', 'trim']);
|
|
|
$bakModel = $this->model;
|
|
|
$this->model = new \app\admin\model\Purchaseemailsendlog;
|
|
|
@@ -10212,6 +10464,7 @@ class Procuremen extends Backend
|
|
|
->paginate($limit);
|
|
|
|
|
|
$rows = [];
|
|
|
+ $needEnrichPoIds = [];
|
|
|
foreach ($list->items() as $item) {
|
|
|
$row = is_array($item) ? $item : $item->toArray();
|
|
|
$scene = trim((string)($row['scene'] ?? ''));
|
|
|
@@ -10219,8 +10472,35 @@ class Procuremen extends Backend
|
|
|
$row['status_text'] = !empty($row['status']) ? '成功' : '失败';
|
|
|
$row['to_email_masked'] = mask_email((string)($row['to_email'] ?? ''));
|
|
|
$row['from_email_masked'] = mask_email((string)($row['from_email'] ?? ''));
|
|
|
+ $row['order_batch_no'] = trim((string)($row['order_batch_no'] ?? ''));
|
|
|
+ $row['ccydh'] = trim((string)($row['ccydh'] ?? ''));
|
|
|
+ $poId = (int)($row['purchase_order_id'] ?? 0);
|
|
|
+ if ($poId > 0 && ($row['ccydh'] === '' || $row['order_batch_no'] === '')) {
|
|
|
+ $needEnrichPoIds[$poId] = true;
|
|
|
+ }
|
|
|
$rows[] = $row;
|
|
|
}
|
|
|
+ if ($needEnrichPoIds !== []) {
|
|
|
+ $poMap = $this->loadEmailLogEnrichPoMap(array_keys($needEnrichPoIds));
|
|
|
+ foreach ($rows as &$row) {
|
|
|
+ $poId = (int)($row['purchase_order_id'] ?? 0);
|
|
|
+ if ($poId <= 0 || !isset($poMap[$poId])) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $info = $poMap[$poId];
|
|
|
+ if ($row['order_batch_no'] === '' && $info['order_batch_no'] !== '') {
|
|
|
+ $row['order_batch_no'] = $info['order_batch_no'];
|
|
|
+ }
|
|
|
+ if ($row['ccydh'] === '') {
|
|
|
+ if ($info['order_batch_no'] !== '' && isset($info['batch_ccydhs']) && $info['batch_ccydhs'] !== '') {
|
|
|
+ $row['ccydh'] = $info['batch_ccydhs'];
|
|
|
+ } elseif ($info['ccydh'] !== '') {
|
|
|
+ $row['ccydh'] = $info['ccydh'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ unset($row);
|
|
|
+ }
|
|
|
|
|
|
$this->model = $bakModel;
|
|
|
|
|
|
@@ -10232,6 +10512,80 @@ class Procuremen extends Backend
|
|
|
return $this->view->fetch('procuremen/emaillog');
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 历史邮件日志缺订单号/批次号时,按 purchase_order_id 回填展示
|
|
|
+ *
|
|
|
+ * @param array<int, int> $poIds
|
|
|
+ * @return array<int, array{ccydh:string,order_batch_no:string,batch_ccydhs:string}>
|
|
|
+ */
|
|
|
+ protected function loadEmailLogEnrichPoMap(array $poIds): array
|
|
|
+ {
|
|
|
+ $out = [];
|
|
|
+ $poIds = array_values(array_unique(array_filter(array_map('intval', $poIds))));
|
|
|
+ if ($poIds === []) {
|
|
|
+ return $out;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ $pos = Db::table('purchase_order')->where('id', 'in', $poIds)->field('id,CCYDH,order_batch_no')->select();
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ try {
|
|
|
+ $pos = Db::table('purchase_order')->where('id', 'in', $poIds)->field('id,CCYDH')->select();
|
|
|
+ } catch (\Throwable $e2) {
|
|
|
+ return $out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $batchSet = [];
|
|
|
+ foreach ($pos as $po) {
|
|
|
+ if (!is_array($po)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $id = (int)($po['id'] ?? 0);
|
|
|
+ if ($id <= 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $bn = $this->resolveProcuremenOrderBatchNo($po);
|
|
|
+ $out[$id] = [
|
|
|
+ 'ccydh' => trim((string)($po['CCYDH'] ?? '')),
|
|
|
+ 'order_batch_no' => $bn,
|
|
|
+ 'batch_ccydhs' => '',
|
|
|
+ ];
|
|
|
+ if ($bn !== '') {
|
|
|
+ $batchSet[$bn] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($batchSet === []) {
|
|
|
+ return $out;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ $batchRows = Db::table('purchase_order')
|
|
|
+ ->where('order_batch_no', 'in', array_keys($batchSet))
|
|
|
+ ->field('CCYDH,order_batch_no')
|
|
|
+ ->select();
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ return $out;
|
|
|
+ }
|
|
|
+ $byBatch = [];
|
|
|
+ foreach ($batchRows as $br) {
|
|
|
+ if (!is_array($br)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $bn = trim((string)($br['order_batch_no'] ?? ''));
|
|
|
+ $dh = trim((string)($br['CCYDH'] ?? ''));
|
|
|
+ if ($bn === '' || $dh === '') {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $byBatch[$bn][$dh] = true;
|
|
|
+ }
|
|
|
+ foreach ($out as $id => $info) {
|
|
|
+ $bn = $info['order_batch_no'];
|
|
|
+ if ($bn !== '' && isset($byBatch[$bn])) {
|
|
|
+ $out[$id]['batch_ccydhs'] = implode(',', array_keys($byBatch[$bn]));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $out;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 协助下发弹窗(选多家供应商并通知)
|
|
|
*/
|
|
|
@@ -11527,6 +11881,8 @@ class Procuremen extends Backend
|
|
|
'email_log_scene' => 'rfq_salesman',
|
|
|
'email_log_scydgy_id' => $sid,
|
|
|
'email_log_purchase_order_id' => (int)($po['id'] ?? 0),
|
|
|
+ 'email_log_ccydh' => $ccydh,
|
|
|
+ 'email_log_order_batch_no' => $this->resolveProcuremenOrderBatchNo(is_array($po) ? $po : []),
|
|
|
'notify_vars' => $notifyVars,
|
|
|
];
|
|
|
$this->issueSendSupplierEmail($bundle, $mailConfig, $mailSubject);
|
|
|
@@ -11991,6 +12347,8 @@ class Procuremen extends Backend
|
|
|
'email_log_scene' => 'delivery_notify',
|
|
|
'email_log_scydgy_id' => $firstSid,
|
|
|
'email_log_purchase_order_id' => $firstPoId,
|
|
|
+ 'email_log_ccydh' => $ccydh,
|
|
|
+ 'email_log_order_batch_no' => $this->resolveProcuremenOrderBatchNo(is_array($po) ? $po : []),
|
|
|
'notify_vars' => $notifyVars,
|
|
|
], $mailConfig, $mailSubject);
|
|
|
$okNames[] = $toName . '(' . $toEmail . ')';
|
|
|
@@ -13233,7 +13591,7 @@ class Procuremen extends Backend
|
|
|
'notify_failed' => 0,
|
|
|
];
|
|
|
$successMsg = '下发成功' . $skipHint . ',已向 ' . $okCount
|
|
|
- . ' 家供应商发起通知。若个别未收到短信或邮件,请到「协助审批下发」使用重发功能补发。';
|
|
|
+ . ' 家供应商发起通知。';
|
|
|
|
|
|
if ($this->isProcuremenNotifyDryRun()) {
|
|
|
$this->notifyDryRunPreview = [];
|
|
|
@@ -13356,13 +13714,45 @@ class Procuremen extends Backend
|
|
|
$bidOpenVerified = $this->isProcuremenBidOpenVerifiedForBundle($bundle) ? 1 : 0;
|
|
|
$manualPickInfo = $this->resolveProcuremenManualPickInfo($bundle);
|
|
|
$manualPicked = $this->isProcuremenManualPickedForBundle($bundle) ? 1 : 0;
|
|
|
- $quoteVisible = ($bidOpenVerified || $manualPicked) ? 1 : 0;
|
|
|
+ $isRejected = 0;
|
|
|
+ foreach ($pos as $poRow) {
|
|
|
+ if (!is_array($poRow)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (ProcuremenStatus::isWflowRejected($poRow['wflow_status'] ?? '')) {
|
|
|
+ $isRejected = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $quoteVisible = ($bidOpenVerified || $manualPicked || $isRejected) ? 1 : 0;
|
|
|
if ($manualPicked && $pickedName === '' && $manualPickInfo['company'] !== '') {
|
|
|
$pickedName = $manualPickInfo['company'];
|
|
|
- $this->view->assign('pickedCompanyName', $pickedName);
|
|
|
}
|
|
|
+ // 驳回后:仅一家供应商时自动选定,便于直接确认;多家则留空供用户选择
|
|
|
+ $quoteGroupCount = 0;
|
|
|
+ $onlyQuoteCompany = '';
|
|
|
+ foreach ($quoteGroups as $g) {
|
|
|
+ if (!is_array($g)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $nm = trim((string)($g['name'] ?? ''));
|
|
|
+ if ($nm === '') {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $quoteGroupCount++;
|
|
|
+ if ($onlyQuoteCompany === '') {
|
|
|
+ $onlyQuoteCompany = $nm;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($isRejected) {
|
|
|
+ // 驳回需重新选定:清空锁定用的已选名;仅一家时再自动勾选
|
|
|
+ $pickedName = ($quoteGroupCount === 1) ? $onlyQuoteCompany : '';
|
|
|
+ }
|
|
|
+ $this->view->assign('pickedCompanyName', $pickedName);
|
|
|
$this->view->assign('bidOpenVerified', $bidOpenVerified);
|
|
|
$this->view->assign('manualPicked', $manualPicked);
|
|
|
+ $this->view->assign('isRejected', $isRejected);
|
|
|
+ $this->view->assign('quoteGroupCount', $quoteGroupCount);
|
|
|
$this->view->assign('manualPickReason', $manualPickInfo['reason']);
|
|
|
$this->view->assign('quoteVisible', $quoteVisible);
|
|
|
$orderScoreRule = ProcuremenSupplierScore::resolveRuleForCcydh((string)($bundle['ccydh'] ?? ''));
|
|
|
@@ -13613,7 +14003,7 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
|
|
|
$this->respondSuccessThenContinue(
|
|
|
- '已补加 ' . count($toAdd) . ' 家供应商并发起通知。若个别未收到,请使用「重发短信 / 重发邮件」补发。',
|
|
|
+ '已补加 ' . count($toAdd) . ' 家供应商并发起通知。',
|
|
|
['append_ok' => 1, 'notify_pending' => 1, 'notify_failed' => 0]
|
|
|
);
|
|
|
|
|
|
@@ -14110,7 +14500,8 @@ class Procuremen extends Backend
|
|
|
// 同订单其它旧批次(有明确批次号、未完结)软删除,避免列表/弹窗仍读到旧批「已开标/已指定」
|
|
|
$keepBatch = '';
|
|
|
if ($batchSet !== []) {
|
|
|
- $keepBatch = (string)reset(array_keys($batchSet));
|
|
|
+ $batchKeys = array_keys($batchSet);
|
|
|
+ $keepBatch = (string)reset($batchKeys);
|
|
|
}
|
|
|
$this->softDeleteOtherBatchPurchaseOrders(array_keys($ccydhSet), array_keys($sids), $keepBatch);
|
|
|
$this->voidPurchaseOrderDetailsForScydgyIds(array_keys($sids));
|
|
|
@@ -14352,7 +14743,7 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
|
|
|
$this->pickHiddenScydgySetCache = null;
|
|
|
- $this->success('已驳回并退回「协助审批下发」');
|
|
|
+ $this->success('已驳回并退回「确认供应商」');
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -14370,7 +14761,7 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
|
|
|
Db::table('purchase_order')->where('scydgy_id', $sid)->update([
|
|
|
- 'wflow_status' => ProcuremenStatus::WFLOW_PENDING_CONFIRM,
|
|
|
+ 'wflow_status' => ProcuremenStatus::WFLOW_REJECTED,
|
|
|
'status' => ProcuremenStatus::PO_IN_PROGRESS,
|
|
|
'pick_company_name' => '',
|
|
|
]);
|