|
|
@@ -1736,6 +1736,7 @@ class Procuremen extends Backend
|
|
|
return [];
|
|
|
}
|
|
|
$gymcMap = [];
|
|
|
+ $qtyBySid = [];
|
|
|
foreach ($bundle['merge_rows'] ?? [] as $mr) {
|
|
|
if (!is_array($mr)) {
|
|
|
continue;
|
|
|
@@ -1743,6 +1744,11 @@ class Procuremen extends Backend
|
|
|
$gid = $this->extractScydgyRowId($mr);
|
|
|
if ($this->isValidScydgyRowId($gid)) {
|
|
|
$gymcMap[$gid] = trim((string)($mr['CGYMC'] ?? ''));
|
|
|
+ $qty = trim((string)($mr['This_quantity'] ?? ''));
|
|
|
+ if ($qty === '') {
|
|
|
+ $qty = trim((string)($mr['NGZL'] ?? ''));
|
|
|
+ }
|
|
|
+ $qtyBySid[$gid] = $qty;
|
|
|
}
|
|
|
}
|
|
|
foreach ($bundle['pos'] ?? [] as $po) {
|
|
|
@@ -1811,15 +1817,27 @@ class Procuremen extends Backend
|
|
|
$deliveryShow = $deliveryRaw;
|
|
|
}
|
|
|
$amountFilled = ($am !== '' && $am !== '0' && $am !== '0.00');
|
|
|
- $deliveryFilled = ($deliveryShow !== '');
|
|
|
+ $deliveryFilled = ($deliveryShow !== '' && !preg_match('/^0000-00-00/i', $deliveryShow));
|
|
|
+ $amountNum = $this->parseProcuremenMoneyNumber($d['amount'] ?? null);
|
|
|
+ $subtotal = null;
|
|
|
+ if ($amountNum !== null) {
|
|
|
+ $subtotal = $this->calcProcuremenDetailSubtotal($d['amount'] ?? null, $qtyBySid[$sid] ?? '');
|
|
|
+ }
|
|
|
+ $unitPriceText = $amountFilled
|
|
|
+ ? ($amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : $am)
|
|
|
+ : '未填写';
|
|
|
$byCompany[$cn]['lines'][] = [
|
|
|
'cgymc' => $gymc,
|
|
|
'amount' => $am,
|
|
|
- 'amount_show' => $amountFilled ? $am : '',
|
|
|
+ 'amount_show' => $amountFilled ? ($amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : $am) : '',
|
|
|
'amount_filled' => $amountFilled,
|
|
|
+ 'unit_price_text' => $unitPriceText,
|
|
|
'delivery' => $deliveryRaw,
|
|
|
- 'delivery_show' => $deliveryFilled ? $deliveryShow : '',
|
|
|
+ 'delivery_show' => $deliveryFilled ? $deliveryShow : '未填写',
|
|
|
'delivery_filled' => $deliveryFilled,
|
|
|
+ 'delivery_ymd' => $deliveryFilled ? $deliveryShow : '',
|
|
|
+ 'subtotal_text' => $subtotal !== null ? $this->formatProcuremenMoneyDisplay($subtotal) : '',
|
|
|
+ 'subtotal_num' => $subtotal,
|
|
|
'status_name' => trim((string)($d['status_name'] ?? '')),
|
|
|
'is_quoted' => $amountFilled,
|
|
|
'quote_label' => $amountFilled ? '已报价' : '未报价',
|
|
|
@@ -1828,13 +1846,23 @@ class Procuremen extends Backend
|
|
|
foreach ($byCompany as $cn => $g) {
|
|
|
$total = count($g['lines']);
|
|
|
$quoted = 0;
|
|
|
+ $groupTotal = 0.0;
|
|
|
+ $groupHasTotal = false;
|
|
|
foreach ($g['lines'] as $ln) {
|
|
|
$am = trim((string)($ln['amount'] ?? ''));
|
|
|
if ($am !== '' && $am !== '0' && $am !== '0.00') {
|
|
|
$quoted++;
|
|
|
}
|
|
|
+ if (isset($ln['subtotal_num']) && $ln['subtotal_num'] !== null) {
|
|
|
+ $groupTotal += (float)$ln['subtotal_num'];
|
|
|
+ $groupHasTotal = true;
|
|
|
+ }
|
|
|
}
|
|
|
$byCompany[$cn]['has_quote'] = $total > 0 && $quoted === $total;
|
|
|
+ $byCompany[$cn]['line_count'] = $total;
|
|
|
+ $byCompany[$cn]['has_total'] = $total > 0;
|
|
|
+ $byCompany[$cn]['total_text'] = $groupHasTotal ? $this->formatProcuremenMoneyDisplay($groupTotal) : '';
|
|
|
+ $byCompany[$cn]['display_rowspan'] = $total + ($total > 0 ? 1 : 0);
|
|
|
}
|
|
|
|
|
|
return array_values($byCompany);
|
|
|
@@ -1901,6 +1929,8 @@ class Procuremen extends Backend
|
|
|
return [];
|
|
|
}
|
|
|
$gymcMap = [];
|
|
|
+ $qtyBySid = [];
|
|
|
+ $orderedSids = [];
|
|
|
foreach ($bundle['merge_rows'] ?? [] as $mr) {
|
|
|
if (!is_array($mr)) {
|
|
|
continue;
|
|
|
@@ -1908,6 +1938,12 @@ class Procuremen extends Backend
|
|
|
$gid = $this->extractScydgyRowId($mr);
|
|
|
if ($this->isValidScydgyRowId($gid)) {
|
|
|
$gymcMap[$gid] = trim((string)($mr['CGYMC'] ?? ''));
|
|
|
+ $orderedSids[] = $gid;
|
|
|
+ $qty = trim((string)($mr['This_quantity'] ?? ''));
|
|
|
+ if ($qty === '') {
|
|
|
+ $qty = trim((string)($mr['NGZL'] ?? ''));
|
|
|
+ }
|
|
|
+ $qtyBySid[$gid] = $qty;
|
|
|
}
|
|
|
}
|
|
|
foreach ($bundle['pos'] ?? [] as $po) {
|
|
|
@@ -1982,11 +2018,25 @@ class Procuremen extends Backend
|
|
|
if ($deliveryShow === '' && $deliveryRaw !== '') {
|
|
|
$deliveryShow = $deliveryRaw;
|
|
|
}
|
|
|
+ $deliveryFilled = ($deliveryShow !== '' && !preg_match('/^0000-00-00/i', $deliveryShow));
|
|
|
+ $amountNum = $this->parseProcuremenMoneyNumber($d['amount'] ?? null);
|
|
|
+ $subtotal = null;
|
|
|
+ if ($amountNum !== null) {
|
|
|
+ $subtotal = $this->calcProcuremenDetailSubtotal($d['amount'] ?? null, $qtyBySid[$sid] ?? '');
|
|
|
+ }
|
|
|
+ $unitPriceText = $amountFilled
|
|
|
+ ? ($amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : $am)
|
|
|
+ : '未填写';
|
|
|
$byCompany[$cn]['pick_lines'][$sid] = [
|
|
|
- 'cgymc' => $gymc,
|
|
|
- 'amount_text' => $amountFilled ? $am : '未填写',
|
|
|
- 'delivery_text' => $deliveryShow !== '' ? $deliveryShow : '未填写',
|
|
|
- 'is_quoted' => $amountFilled,
|
|
|
+ 'cgymc' => $gymc,
|
|
|
+ 'amount_text' => $amountFilled ? ($amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : $am) : '未填写',
|
|
|
+ 'delivery_text' => $deliveryFilled ? $deliveryShow : '未填写',
|
|
|
+ 'amount_filled' => $amountFilled,
|
|
|
+ 'delivery_filled' => $deliveryFilled,
|
|
|
+ 'unit_price_text' => $unitPriceText,
|
|
|
+ 'subtotal_text' => $subtotal !== null ? $this->formatProcuremenMoneyDisplay($subtotal) : '',
|
|
|
+ 'subtotal_num' => $subtotal,
|
|
|
+ 'is_quoted' => $amountFilled,
|
|
|
];
|
|
|
$byCompany[$cn]['detail_picks'][$sid] = [
|
|
|
'scydgy_id' => $sid,
|
|
|
@@ -1997,11 +2047,39 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
$out = [];
|
|
|
foreach ($byCompany as $g) {
|
|
|
- $pickLines = $g['pick_lines'] ?? [];
|
|
|
- if (!is_array($pickLines) || $pickLines === []) {
|
|
|
+ $pickLinesMap = $g['pick_lines'] ?? [];
|
|
|
+ if (!is_array($pickLinesMap) || $pickLinesMap === []) {
|
|
|
continue;
|
|
|
}
|
|
|
- $g['pick_lines'] = array_values($pickLines);
|
|
|
+ $pickLines = [];
|
|
|
+ $usedLineSids = [];
|
|
|
+ foreach ($orderedSids as $sid) {
|
|
|
+ if (!isset($pickLinesMap[$sid])) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $pickLines[] = $pickLinesMap[$sid];
|
|
|
+ $usedLineSids[$sid] = true;
|
|
|
+ }
|
|
|
+ foreach ($pickLinesMap as $sid => $ln) {
|
|
|
+ if (isset($usedLineSids[$sid])) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $pickLines[] = $ln;
|
|
|
+ }
|
|
|
+ $groupTotal = 0.0;
|
|
|
+ $groupHasTotal = false;
|
|
|
+ foreach ($pickLines as $ln) {
|
|
|
+ if (isset($ln['subtotal_num']) && $ln['subtotal_num'] !== null) {
|
|
|
+ $groupTotal += (float)$ln['subtotal_num'];
|
|
|
+ $groupHasTotal = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $lineCount = count($pickLines);
|
|
|
+ $g['pick_lines'] = $pickLines;
|
|
|
+ $g['line_count'] = $lineCount;
|
|
|
+ $g['has_total'] = $lineCount > 0;
|
|
|
+ $g['total_text'] = $groupHasTotal ? $this->formatProcuremenMoneyDisplay($groupTotal) : '';
|
|
|
+ $g['display_rowspan'] = $lineCount + ($lineCount > 0 ? 1 : 0);
|
|
|
$detailPicks = $g['detail_picks'] ?? [];
|
|
|
$g['detail_picks'] = array_values(is_array($detailPicks) ? $detailPicks : []);
|
|
|
$g['detail_picks_json'] = json_encode($g['detail_picks'], JSON_UNESCAPED_UNICODE);
|
|
|
@@ -3277,6 +3355,39 @@ class Procuremen extends Backend
|
|
|
return '';
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 操作记录时间(取指定 action 最近一条)
|
|
|
+ *
|
|
|
+ * @param string|array<int, string> $actions
|
|
|
+ */
|
|
|
+ protected function resolveProcuremenOperLogTime(int $scydgyId, $actions): string
|
|
|
+ {
|
|
|
+ if (!$this->isValidScydgyRowId($scydgyId)) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ $acts = is_array($actions) ? $actions : [$actions];
|
|
|
+ $acts = array_values(array_filter(array_map('strval', $acts)));
|
|
|
+ if ($acts === []) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ $log = Db::table('purchase_order_oper_log')
|
|
|
+ ->where('scydgy_id', $scydgyId)
|
|
|
+ ->where('action', 'in', $acts)
|
|
|
+ ->order('id', 'desc')
|
|
|
+ ->find();
|
|
|
+ if (is_array($log)) {
|
|
|
+ $ct = (int)($log['createtime'] ?? 0);
|
|
|
+ if ($ct > 946684800) {
|
|
|
+ return date('Y-m-d H:i:s', $ct);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ }
|
|
|
+
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 详情弹层:进度步骤 + 订单摘要 + 下发明细(已下发 / 已完结均可用)
|
|
|
*
|
|
|
@@ -3320,29 +3431,9 @@ class Procuremen extends Backend
|
|
|
$issued = $this->isProcuremenOrderIssued($main, $issueCnt);
|
|
|
$issueTime = $issued ? $this->resolveProcuremenIssueTime($main, $details) : '';
|
|
|
|
|
|
- $auditNotifyTime = '';
|
|
|
- if ($wflowStatus >= 2 || ($wflowStatus === 0 && $issueCnt > 0)) {
|
|
|
- $scydgyId = (int)($main['scydgy_id'] ?? 0);
|
|
|
- if ($this->isValidScydgyRowId($scydgyId)) {
|
|
|
- try {
|
|
|
- $auditLog = Db::table('purchase_order_oper_log')
|
|
|
- ->where('scydgy_id', $scydgyId)
|
|
|
- ->where('action', 'audit_confirm')
|
|
|
- ->order('id', 'desc')
|
|
|
- ->find();
|
|
|
- if (is_array($auditLog)) {
|
|
|
- $ct = (int)($auditLog['createtime'] ?? 0);
|
|
|
- if ($ct > 946684800) {
|
|
|
- $auditNotifyTime = date('Y-m-d H:i:s', $ct);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (\Throwable $e) {
|
|
|
- }
|
|
|
- }
|
|
|
- if ($auditNotifyTime === '' && $issueTime !== '') {
|
|
|
- $auditNotifyTime = $issueTime;
|
|
|
- }
|
|
|
- }
|
|
|
+ $scydgyId = (int)($main['scydgy_id'] ?? 0);
|
|
|
+ $auditSelectTime = $this->resolveProcuremenOperLogTime($scydgyId, ['audit_select', 'audit_confirm']);
|
|
|
+ $confirmApproveTime = $this->resolveProcuremenOperLogTime($scydgyId, ['purchase_confirm']);
|
|
|
|
|
|
$supplierTime = '';
|
|
|
if ($acceptCnt > 0) {
|
|
|
@@ -3358,7 +3449,6 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
|
|
|
$directComplete = ($mainStatus === 1 && !$issued);
|
|
|
- $scydgyId = (int)($main['scydgy_id'] ?? 0);
|
|
|
|
|
|
$doneTime = '';
|
|
|
if ($mainStatus === 1) {
|
|
|
@@ -3395,16 +3485,17 @@ class Procuremen extends Backend
|
|
|
} else {
|
|
|
$step1Done = $issued;
|
|
|
$step2Done = $issued;
|
|
|
- // wflow=1:初选已下发、待审批确认通知;wflow>=2 或旧数据(有明细且 wf=0)视为已通知
|
|
|
- $step3Done = $wflowStatus >= 2 || ($wflowStatus === 0 && $issueCnt > 0);
|
|
|
- $step4Done = $acceptCnt > 0;
|
|
|
- $step5Done = false;
|
|
|
- foreach ($details as $dr) {
|
|
|
- if (is_array($dr) && (int)($dr['status'] ?? 0) === 1) {
|
|
|
- $step5Done = true;
|
|
|
- break;
|
|
|
+ $step3Done = $acceptCnt > 0;
|
|
|
+ $step4Done = $wflowStatus >= 2;
|
|
|
+ if (!$step4Done) {
|
|
|
+ foreach ($details as $dr) {
|
|
|
+ if (is_array($dr) && (int)($dr['status'] ?? 0) === 1) {
|
|
|
+ $step4Done = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ $step5Done = $confirmApproveTime !== '' || $mainStatus === 1;
|
|
|
$step6Done = $mainStatus === 1;
|
|
|
|
|
|
// 已走下发流程并完结:中间环节按业务视为已全部完成(不显示灰色「未到达」)
|
|
|
@@ -3424,17 +3515,21 @@ class Procuremen extends Backend
|
|
|
$pickedTime = $fillT;
|
|
|
}
|
|
|
}
|
|
|
- if ($auditNotifyTime === '') {
|
|
|
+ if ($auditSelectTime === '') {
|
|
|
+ $fillT = $doneTime !== '' ? $doneTime : $poTime;
|
|
|
+ if ($fillT !== '') {
|
|
|
+ $auditSelectTime = $fillT;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($confirmApproveTime === '') {
|
|
|
$fillT = $doneTime !== '' ? $doneTime : $poTime;
|
|
|
if ($fillT !== '') {
|
|
|
- $auditNotifyTime = $fillT;
|
|
|
+ $confirmApproveTime = $fillT;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- $auditPendingSubtitle = '待确认通知';
|
|
|
-
|
|
|
$steps = [
|
|
|
[
|
|
|
'title' => '未发',
|
|
|
@@ -3443,27 +3538,29 @@ class Procuremen extends Backend
|
|
|
'done' => $step1Done,
|
|
|
],
|
|
|
[
|
|
|
- 'title' => '初选下发',
|
|
|
+ 'title' => '下发',
|
|
|
'subtitle' => '',
|
|
|
'time' => $step2Done ? ($issueTime !== '' ? $issueTime : $poTime) : '',
|
|
|
'done' => $step2Done,
|
|
|
],
|
|
|
[
|
|
|
- 'title' => '待审批',
|
|
|
- 'subtitle' => $step3Done ? '' : $auditPendingSubtitle,
|
|
|
- 'time' => $step3Done ? $auditNotifyTime : '',
|
|
|
+ 'title' => '供应商接单',
|
|
|
+ 'subtitle' => '下发 ' . $issueCnt . ' / 接单 ' . $acceptCnt,
|
|
|
+ 'time' => $step3Done ? $supplierTime : '',
|
|
|
'done' => $step3Done,
|
|
|
],
|
|
|
[
|
|
|
- 'title' => '供应商接单',
|
|
|
- 'subtitle' => '下发 ' . $issueCnt . ' / 接单 ' . $acceptCnt,
|
|
|
- 'time' => $step4Done ? $supplierTime : '',
|
|
|
+ 'title' => '待确认',
|
|
|
+ 'subtitle' => $step4Done
|
|
|
+ ? ($pickedName !== '' ? ('选定:' . $pickedName) : '')
|
|
|
+ : ($issued ? '待选供应商' : ''),
|
|
|
+ 'time' => $step4Done ? ($auditSelectTime !== '' ? $auditSelectTime : $pickedTime) : '',
|
|
|
'done' => $step4Done,
|
|
|
],
|
|
|
[
|
|
|
- 'title' => '采购确认',
|
|
|
- 'subtitle' => $pickedName !== '' ? ('选中供应商:' . $pickedName) : '',
|
|
|
- 'time' => $step5Done ? ($pickedTime !== '' ? $pickedTime : '') : '',
|
|
|
+ 'title' => '待审批',
|
|
|
+ 'subtitle' => ($pickedName !== '' && $step4Done) ? ('供应商:' . $pickedName) : '',
|
|
|
+ 'time' => $step5Done ? ($confirmApproveTime !== '' ? $confirmApproveTime : $doneTime) : '',
|
|
|
'done' => $step5Done,
|
|
|
],
|
|
|
[
|
|
|
@@ -4395,14 +4492,31 @@ class Procuremen extends Backend
|
|
|
}
|
|
|
$appendLine((int)$sid, $d);
|
|
|
}
|
|
|
+ $firstDetail = null;
|
|
|
+ foreach ($bySid as $d) {
|
|
|
+ if (is_array($d)) {
|
|
|
+ $firstDetail = $d;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $ph = is_array($firstDetail) ? trim((string)($firstDetail['phone'] ?? '')) : '';
|
|
|
+ $username = is_array($firstDetail) ? trim((string)($firstDetail['username'] ?? '')) : '';
|
|
|
+ if ($username === '' && $ph !== '') {
|
|
|
+ $username = $this->resolveCustomerContactName($ph, $cn);
|
|
|
+ }
|
|
|
+ $lineCount = count($lines);
|
|
|
$supplierGroups[] = [
|
|
|
- 'company_name' => $cn,
|
|
|
- 'is_selected' => ($selectedCompany !== '' && $cn === $selectedCompany),
|
|
|
- 'is_void' => $groupVoid,
|
|
|
- 'lines' => $lines,
|
|
|
- 'line_count' => count($lines),
|
|
|
- 'total_text' => $groupHas ? $this->formatProcuremenMoneyDisplay($groupTotal) : '',
|
|
|
- 'has_total' => count($lines) > 0,
|
|
|
+ 'company_name' => $cn,
|
|
|
+ 'username' => $username,
|
|
|
+ 'email' => is_array($firstDetail) ? trim((string)($firstDetail['email'] ?? '')) : '',
|
|
|
+ 'phone' => $ph,
|
|
|
+ 'is_selected' => ($selectedCompany !== '' && $cn === $selectedCompany),
|
|
|
+ 'is_void' => $groupVoid,
|
|
|
+ 'lines' => $lines,
|
|
|
+ 'line_count' => $lineCount,
|
|
|
+ 'display_rowspan'=> $lineCount + ($lineCount > 0 ? 1 : 0),
|
|
|
+ 'total_text' => $groupHas ? $this->formatProcuremenMoneyDisplay($groupTotal) : '',
|
|
|
+ 'has_total' => $lineCount > 0,
|
|
|
];
|
|
|
}
|
|
|
usort($supplierGroups, function ($a, $b) {
|