m0_70156489 hai 1 semana
pai
achega
366da09f38

+ 111 - 24
application/admin/controller/Procuremen.php

@@ -1866,6 +1866,70 @@ class Procuremen extends Backend
         return implode("\n", $lines);
     }
 
+    /**
+     * 从订单 bundle 取报价截止时间(多工序取首个有效 sys_rq)
+     */
+    protected function resolveBundleSysRq(array $bundle): string
+    {
+        foreach ($bundle['pos'] ?? [] as $po) {
+            if (!is_array($po)) {
+                continue;
+            }
+            $sr = trim((string)($po['sys_rq'] ?? ''));
+            if ($sr !== '' && !preg_match('/^0000-00-00/i', $sr)) {
+                return $sr;
+            }
+        }
+
+        return '';
+    }
+
+    /**
+     * 报价截止时间是否已到(未设置截止时间则视为可查看报价)
+     */
+    protected function isProcuremenQuoteDeadlineReached($sysRq): bool
+    {
+        $raw = trim((string)$sysRq);
+        if ($raw === '' || preg_match('/^0000-00-00/i', $raw)) {
+            return true;
+        }
+        $ts = strtotime(str_replace('T', ' ', $raw));
+        if ($ts === false || $ts <= 0) {
+            return true;
+        }
+
+        return time() >= $ts;
+    }
+
+    /**
+     * 截止时间前:隐藏单价/交期真实值,统一展示文案
+     *
+     * @param array<string, mixed> $line
+     */
+    protected function maskSupplierQuoteLineBeforeDeadline(array &$line): void
+    {
+        $text = '未到截止时间';
+        $line['amount_filled'] = false;
+        $line['delivery_filled'] = false;
+        $line['unit_price_text'] = $text;
+        $line['amount_show'] = '';
+        if (array_key_exists('amount_text', $line)) {
+            $line['amount_text'] = $text;
+        }
+        $line['delivery_show'] = $text;
+        if (array_key_exists('delivery_text', $line)) {
+            $line['delivery_text'] = $text;
+        }
+        $line['delivery_ymd'] = '';
+        $line['subtotal_text'] = '';
+        $line['subtotal_num'] = null;
+        $line['is_quoted'] = false;
+        if (array_key_exists('quote_label', $line)) {
+            $line['quote_label'] = $text;
+        }
+        $line['quote_before_deadline'] = true;
+    }
+
     /**
      * 审核弹窗:按供应商汇总报价明细
      *
@@ -1887,6 +1951,7 @@ class Procuremen extends Backend
         if ($sids === []) {
             return [];
         }
+        $deadlineReached = $this->isProcuremenQuoteDeadlineReached($this->resolveBundleSysRq($bundle));
         $gymcMap = [];
         $qtyBySid = [];
         foreach ($bundle['merge_rows'] ?? [] as $mr) {
@@ -1978,7 +2043,7 @@ class Procuremen extends Backend
             $unitPriceText = $amountFilled
                 ? ($amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : $am)
                 : '未填写';
-            $byCompany[$cn]['lines'][] = [
+            $lineRow = [
                 'cgymc'           => $gymc,
                 'amount'          => $am,
                 'amount_show'     => $amountFilled ? ($amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : $am) : '',
@@ -1994,26 +2059,32 @@ class Procuremen extends Backend
                 'is_quoted'       => $amountFilled,
                 'quote_label'     => $amountFilled ? '已报价' : '未报价',
             ];
+            if (!$deadlineReached) {
+                $this->maskSupplierQuoteLineBeforeDeadline($lineRow);
+            }
+            $byCompany[$cn]['lines'][] = $lineRow;
         }
         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;
+            if ($deadlineReached) {
+                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]['has_quote'] = $deadlineReached && $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]['total_text'] = ($deadlineReached && $groupHasTotal) ? $this->formatProcuremenMoneyDisplay($groupTotal) : '';
             $byCompany[$cn]['display_rowspan'] = $total + ($total > 0 ? 1 : 0);
         }
 
@@ -2043,6 +2114,7 @@ class Procuremen extends Backend
         if ($sids === []) {
             return [];
         }
+        $deadlineReached = $this->isProcuremenQuoteDeadlineReached($this->resolveBundleSysRq($bundle));
         $gymcMap = [];
         $qtyBySid = [];
         $orderedSids = [];
@@ -2142,7 +2214,7 @@ class Procuremen extends Backend
             $unitPriceText = $amountFilled
                 ? ($amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : $am)
                 : '未填写';
-            $byCompany[$cn]['pick_lines'][$sid] = [
+            $pickLine = [
                 'cgymc'           => $gymc,
                 'amount_text'     => $amountFilled ? ($amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : $am) : '未填写',
                 'delivery_text'   => $deliveryFilled ? $deliveryShow : '未填写',
@@ -2153,6 +2225,10 @@ class Procuremen extends Backend
                 'subtotal_num'    => $subtotal,
                 'is_quoted'       => $amountFilled,
             ];
+            if (!$deadlineReached) {
+                $this->maskSupplierQuoteLineBeforeDeadline($pickLine);
+            }
+            $byCompany[$cn]['pick_lines'][$sid] = $pickLine;
             $byCompany[$cn]['detail_picks'][$sid] = [
                 'scydgy_id'         => $sid,
                 'detail_id'         => $detailId,
@@ -2183,17 +2259,19 @@ class Procuremen extends Backend
             }
             $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;
+            if ($deadlineReached) {
+                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['total_text'] = ($deadlineReached && $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 : []);
@@ -4549,6 +4627,7 @@ class Procuremen extends Backend
     protected function buildProcuremenDetailsQuoteView(array $mergeRows, array $details, array $main): array
     {
         $processRows = $this->buildAuditProcessDisplayRows($mergeRows);
+        $deadlineReached = $this->isProcuremenQuoteDeadlineReached($main['sys_rq'] ?? '');
         $qtyBySid = [];
         $gymcBySid = [];
         $orderedSids = [];
@@ -4598,7 +4677,8 @@ class Procuremen extends Backend
                 &$groupHas,
                 &$groupVoid,
                 $qtyBySid,
-                $gymcBySid
+                $gymcBySid,
+                $deadlineReached
             ) {
                 $isVoid = $this->isPurchaseOrderDetailVoid($d);
                 if (!$isVoid) {
@@ -4609,13 +4689,9 @@ class Procuremen extends Backend
                 $sub = null;
                 if (!$isVoid && $amountNum !== null) {
                     $sub = $this->calcProcuremenDetailSubtotal($d['amount'] ?? null, $qtyStr);
-                    if ($sub !== null) {
-                        $groupTotal += $sub;
-                        $groupHas = true;
-                    }
                 }
                 $ct = $this->resolveDetailSupplierOperTime($d);
-                $lines[] = [
+                $line = [
                     'cgymc'           => $gymcBySid[$sid] ?? trim((string)($d['CGYMC'] ?? '')),
                     'unit_price_text' => $amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : trim((string)($d['amount'] ?? '')),
                     'subtotal_text'   => $sub !== null ? $this->formatProcuremenMoneyDisplay($sub) : '',
@@ -4625,6 +4701,13 @@ class Procuremen extends Backend
                     'is_void'         => $isVoid,
                     'oper_time_text'  => $ct,
                 ];
+                if (!$deadlineReached && !$isVoid) {
+                    $this->maskSupplierQuoteLineBeforeDeadline($line);
+                } elseif ($sub !== null) {
+                    $groupTotal += $sub;
+                    $groupHas = true;
+                }
+                $lines[] = $line;
             };
             foreach ($orderedSids as $sid) {
                 if (!isset($bySid[$sid])) {
@@ -4662,7 +4745,7 @@ class Procuremen extends Backend
                 'lines'          => $lines,
                 'line_count'     => $lineCount,
                 'display_rowspan'=> $lineCount + ($lineCount > 0 ? 1 : 0),
-                'total_text'     => $groupHas ? $this->formatProcuremenMoneyDisplay($groupTotal) : '',
+                'total_text'     => ($deadlineReached && $groupHas) ? $this->formatProcuremenMoneyDisplay($groupTotal) : '',
                 'has_total'      => $lineCount > 0,
             ];
         }
@@ -6091,6 +6174,7 @@ class Procuremen extends Backend
         $this->view->assign('quoteGroupsJson', json_encode($quoteGroups, JSON_UNESCAPED_UNICODE));
         $this->view->assign('pickedCompanyName', $pickedName);
         $this->view->assign('sysRq', $this->formatProcuremenSysRqForInput($po['sys_rq'] ?? null));
+        $this->view->assign('quoteDeadlineReached', $this->isProcuremenQuoteDeadlineReached($this->resolveBundleSysRq($bundle)) ? 1 : 0);
 
         return $this->view->fetch('procuremen/audit_issue');
     }
@@ -6137,6 +6221,9 @@ class Procuremen extends Backend
         }
 
         $sysRqDb = $this->parseProcuremenSysRqInput(trim((string)$this->request->post('sys_rq', '')), true);
+        if (!$this->isProcuremenQuoteDeadlineReached($sysRqDb)) {
+            $this->error('报价截止时间未到,暂不能确认供应商');
+        }
 
         $ccydhLog = trim((string)($bundle['ccydh'] ?? ''));
         $procCnt = count($mergeRows);

+ 9 - 3
application/admin/view/procuremen/audit_issue.html

@@ -202,6 +202,12 @@
             </div>
         </div>
     </form>
+    {if condition="$quoteDeadlineReached neq 1"}
+    <p class="audit-notify-tip" style="margin-top:-2px;">
+        <i class="fa fa-clock-o"></i>
+        报价截止时间未到,单价与交货日期暂不展示,到期后可查看各供应商报价。
+    </p>
+    {/if}
     <p class="audit-notify-tip">
         <i class="fa fa-exclamation-triangle"></i>
         <strong>重要提示:</strong>请查看各供应商报价,<strong>选定唯一一家</strong>后点击「确认供应商」进入采购终审(本步<strong>任何发送短信通知</strong>)。
@@ -240,9 +246,9 @@
                 <td{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{$co.phone|default=''|htmlentities}</td>
                 {/if}
                 <td>{$ln.cgymc|default=''|htmlentities}</td>
-                <td class="text-center{if condition="$ln.amount_filled neq 1"} audit-quote-empty{/if}">{$ln.unit_price_text|default='未填写'|htmlentities}</td>
-                <td class="text-center{if condition="$ln.delivery_filled neq 1"} audit-quote-empty{/if}">{$ln.delivery_show|default='未填写'|htmlentities}</td>
-                <td class="text-center">{$ln.subtotal_text|default=''|htmlentities}</td>
+                <td class="text-center{if condition="$ln.quote_before_deadline eq 1 || $ln.amount_filled neq 1"} audit-quote-empty{/if}">{$ln.unit_price_text|default='未填写'|htmlentities}</td>
+                <td class="text-center{if condition="$ln.quote_before_deadline eq 1 || $ln.delivery_filled neq 1"} audit-quote-empty{/if}">{$ln.delivery_show|default='未填写'|htmlentities}</td>
+                <td class="text-center{if condition="$ln.quote_before_deadline eq 1"} audit-quote-empty{/if}">{$ln.subtotal_text|default=''|htmlentities}</td>
                 {if $lk == 1}
                 <td class="text-center audit-op-cell"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">
                     {if $auth->check('procuremen/auditresendemail')}

+ 2 - 2
application/admin/view/procuremen/outward_detail.html

@@ -215,8 +215,8 @@
                 <td{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{$co.phone|default=''|htmlentities}</td>
                 {/if}
                 <td>{$ql.cgymc|default=''|htmlentities}</td>
-                <td class="text-center{if condition="$ql.amount_filled neq 1"} outward-quote-empty{/if}">{$ql.unit_price_text|default='未填写'|htmlentities}</td>
-                <td class="text-center{if condition="$ql.delivery_filled neq 1"} outward-quote-empty{/if}">{$ql.delivery_text|default='未填写'|htmlentities}</td>
+                <td class="text-center{if condition="$ql.quote_before_deadline eq 1 || $ql.amount_filled neq 1"} outward-quote-empty{/if}">{$ql.unit_price_text|default='未填写'|htmlentities}</td>
+                <td class="text-center{if condition="$ql.quote_before_deadline eq 1 || $ql.delivery_filled neq 1"} outward-quote-empty{/if}">{$ql.delivery_text|default='未填写'|htmlentities}</td>
                 <td class="text-center">{$ql.subtotal_text|default=''|htmlentities}</td>
             </tr>
             {/volist}