|
|
@@ -1407,6 +1407,105 @@ class Index extends Frontend
|
|
|
return ($sr !== '' && !preg_match('/^0000-00-00/i', $sr)) ? $sr : '';
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 从主表/明细解析订单号
|
|
|
+ *
|
|
|
+ * @param array<string, mixed>|null $po
|
|
|
+ * @param array<string, mixed>|null $row
|
|
|
+ */
|
|
|
+ protected function mprocResolveCcydhFromPoOrRow(?array $po, ?array $row = null): string
|
|
|
+ {
|
|
|
+ foreach ([$po, $row] as $src) {
|
|
|
+ if (!is_array($src)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $c = trim((string)($src['CCYDH'] ?? $src['ccydh'] ?? ''));
|
|
|
+ if ($c !== '') {
|
|
|
+ return $c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量:已开标验证的订单号集合(本请求内可复用)
|
|
|
+ *
|
|
|
+ * @var array<string, bool>|null
|
|
|
+ */
|
|
|
+ protected $mprocBidOpenVerifiedSet = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param array<int, string> $ccydhs
|
|
|
+ * @return array<string, bool>
|
|
|
+ */
|
|
|
+ protected function mprocLoadBidOpenVerifiedCcydhSet(array $ccydhs): array
|
|
|
+ {
|
|
|
+ $set = [];
|
|
|
+ $list = [];
|
|
|
+ foreach ($ccydhs as $c) {
|
|
|
+ $c = trim((string)$c);
|
|
|
+ if ($c !== '') {
|
|
|
+ $list[$c] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($list === []) {
|
|
|
+ return $set;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ $rows = Db::table('purchase_order_bid_open')
|
|
|
+ ->where('ccydh', 'in', array_keys($list))
|
|
|
+ ->field('ccydh')
|
|
|
+ ->select();
|
|
|
+ if (!is_array($rows)) {
|
|
|
+ return $set;
|
|
|
+ }
|
|
|
+ foreach ($rows as $row) {
|
|
|
+ if (!is_array($row)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $c = trim((string)($row['ccydh'] ?? ''));
|
|
|
+ if ($c !== '') {
|
|
|
+ $set[$c] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ return $set;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 该订单是否已完成开标双重验证(有 purchase_order_bid_open 记录)
|
|
|
+ */
|
|
|
+ protected function mprocIsBidOpenVerified(string $ccydh): bool
|
|
|
+ {
|
|
|
+ $ccydh = trim($ccydh);
|
|
|
+ if ($ccydh === '') {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (is_array($this->mprocBidOpenVerifiedSet)) {
|
|
|
+ return isset($this->mprocBidOpenVerifiedSet[$ccydh]);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ $row = Db::table('purchase_order_bid_open')->where('ccydh', $ccydh)->find();
|
|
|
+
|
|
|
+ return is_array($row);
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param array<string, mixed>|null $po
|
|
|
+ * @param array<string, mixed>|null $row
|
|
|
+ */
|
|
|
+ protected function mprocIsBidOpenVerifiedForPoOrRow(?array $po, ?array $row = null): bool
|
|
|
+ {
|
|
|
+ return $this->mprocIsBidOpenVerified($this->mprocResolveCcydhFromPoOrRow($po, $row));
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 手机端:仅当主表设置了 sys_rq 且已到期时视为截止(无截止时间仍可填报)
|
|
|
* 保存时务必再调一次,防止页面长时间打开、截止后仍提交
|
|
|
@@ -1454,6 +1553,40 @@ class Index extends Frontend
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 保存前:截止时间 + 已开标均不可再改
|
|
|
+ *
|
|
|
+ * @param array<string, mixed>|null $po
|
|
|
+ * @param array<string, mixed>|null $row
|
|
|
+ */
|
|
|
+ protected function mprocAssertQuoteStillEditable(?array $po, string $label = '', ?array $row = null): void
|
|
|
+ {
|
|
|
+ $this->mprocAssertQuoteNotDeadlineReached($po, $label);
|
|
|
+ $freshPo = is_array($po) ? $po : null;
|
|
|
+ if (is_array($po)) {
|
|
|
+ $sid = (int)($po['scydgy_id'] ?? $po['SCYDGY_ID'] ?? 0);
|
|
|
+ if ($this->mprocIsValidScydgyRowId($sid)) {
|
|
|
+ try {
|
|
|
+ $got = Db::table('purchase_order')->where('scydgy_id', $sid)->find();
|
|
|
+ if (is_array($got)) {
|
|
|
+ $freshPo = $got;
|
|
|
+ }
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 保存场景不走列表缓存,直接查库
|
|
|
+ $prev = $this->mprocBidOpenVerifiedSet;
|
|
|
+ $this->mprocBidOpenVerifiedSet = null;
|
|
|
+ $opened = $this->mprocIsBidOpenVerifiedForPoOrRow($freshPo, $row);
|
|
|
+ $this->mprocBidOpenVerifiedSet = $prev;
|
|
|
+ if ($opened) {
|
|
|
+ throw new \InvalidArgumentException(
|
|
|
+ ($label !== '' ? $label : '') . '已开标验证,不可再提交'
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 主单已完结后:中标 / 未中标
|
|
|
*
|
|
|
@@ -1554,13 +1687,20 @@ class Index extends Frontend
|
|
|
$g['lines'] = $lines;
|
|
|
$g['line_count'] = count($lines);
|
|
|
$canEdit = false;
|
|
|
+ $bidOpen = false;
|
|
|
foreach ($lines as $ln) {
|
|
|
- if (is_array($ln) && (int)($ln['mproc_can_edit'] ?? 0) === 1) {
|
|
|
+ if (!is_array($ln)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if ((int)($ln['mproc_can_edit'] ?? 0) === 1) {
|
|
|
$canEdit = true;
|
|
|
- break;
|
|
|
+ }
|
|
|
+ if ((int)($ln['mproc_bid_open_verified'] ?? 0) === 1) {
|
|
|
+ $bidOpen = true;
|
|
|
}
|
|
|
}
|
|
|
$g['can_edit'] = $canEdit ? 1 : 0;
|
|
|
+ $g['mproc_bid_open_verified'] = $bidOpen ? 1 : 0;
|
|
|
$remark = '';
|
|
|
$doneLabel = '';
|
|
|
$pickResult = '';
|
|
|
@@ -1664,6 +1804,27 @@ class Index extends Frontend
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ $ccydhForBid = [];
|
|
|
+ foreach ($poBySid as $pr) {
|
|
|
+ if (!is_array($pr)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $c = trim((string)($pr['CCYDH'] ?? $pr['ccydh'] ?? ''));
|
|
|
+ if ($c !== '') {
|
|
|
+ $ccydhForBid[$c] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ foreach ($rows as $r0) {
|
|
|
+ if (!is_array($r0)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $c = trim((string)($r0['CCYDH'] ?? $r0['ccydh'] ?? ''));
|
|
|
+ if ($c !== '') {
|
|
|
+ $ccydhForBid[$c] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $this->mprocBidOpenVerifiedSet = $this->mprocLoadBidOpenVerifiedCcydhSet(array_keys($ccydhForBid));
|
|
|
+
|
|
|
foreach ($rows as &$row) {
|
|
|
if (!is_array($row)) {
|
|
|
continue;
|
|
|
@@ -1704,6 +1865,7 @@ class Index extends Frontend
|
|
|
$row['status_name'] = trim((string)$row['status_name']);
|
|
|
}
|
|
|
$row['mproc_can_edit'] = $this->mprocCanEditRow($user, $row, $poRow) ? 1 : 0;
|
|
|
+ $row['mproc_bid_open_verified'] = $this->mprocIsBidOpenVerifiedForPoOrRow($poRow, $row) ? 1 : 0;
|
|
|
|
|
|
$am = $row['amount'] ?? null;
|
|
|
if ($am === null || $am === '' || (is_string($am) && trim($am) === '')) {
|
|
|
@@ -1933,6 +2095,7 @@ class Index extends Frontend
|
|
|
$row['mproc_done_label'] = '';
|
|
|
}
|
|
|
$row['mproc_can_edit'] = $this->mprocCanEditRow($user, $row, $poRow) ? 1 : 0;
|
|
|
+ $row['mproc_bid_open_verified'] = $this->mprocIsBidOpenVerifiedForPoOrRow(is_array($poRow) ? $poRow : null, $row) ? 1 : 0;
|
|
|
$am = $row['amount'] ?? null;
|
|
|
$row['amount_display'] = ($am === null || $am === '' || (is_string($am) && trim($am) === '')) ? '' : (is_scalar($am) ? (string)$am : '');
|
|
|
$dv = isset($row['delivery']) ? trim((string)$row['delivery']) : '';
|
|
|
@@ -2527,6 +2690,9 @@ class Index extends Frontend
|
|
|
if ($this->mprocIsQuoteDeadlineReachedForPo($po)) {
|
|
|
return false;
|
|
|
}
|
|
|
+ if ($this->mprocIsBidOpenVerifiedForPoOrRow($po, $row)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
$uCo = trim((string)($user['company_name'] ?? ''));
|
|
|
if ($uCo === '') {
|
|
|
$uPhone = trim((string)($user['phone'] ?? ''));
|
|
|
@@ -2717,12 +2883,15 @@ class Index extends Frontend
|
|
|
if (in_array($effectiveSn, ['已完成', '未通过', '已废弃'], true)) {
|
|
|
throw new \InvalidArgumentException($label . '已结束,不能再修改');
|
|
|
}
|
|
|
- $this->mprocAssertQuoteNotDeadlineReached(is_array($po) ? $po : null, $label);
|
|
|
+ $this->mprocAssertQuoteStillEditable(is_array($po) ? $po : null, $label, $row);
|
|
|
if (!$this->mprocCanEditRow($user, array_merge($row, ['status_name' => $effectiveSn]), is_array($po) ? $po : null)) {
|
|
|
if (!empty($user['is_admin'])) {
|
|
|
throw new \InvalidArgumentException('当前账号仅可查看,不能修改单价与交货日期');
|
|
|
}
|
|
|
- // 截止后 canEdit=false,统一给明确文案
|
|
|
+ // 截止后 / 已开标 canEdit=false,统一给明确文案
|
|
|
+ if ($this->mprocIsBidOpenVerifiedForPoOrRow(is_array($po) ? $po : null, $row)) {
|
|
|
+ throw new \InvalidArgumentException($label . '已开标验证,不可再提交');
|
|
|
+ }
|
|
|
if ($this->mprocIsQuoteDeadlineReachedForPo(is_array($po) ? $po : null)) {
|
|
|
throw new \InvalidArgumentException($label . '已超过招标截止时间,不可再提交');
|
|
|
}
|
|
|
@@ -2917,11 +3086,14 @@ class Index extends Frontend
|
|
|
if (in_array($effectiveSn, ['已完成', '未通过', '已废弃'], true)) {
|
|
|
throw new \InvalidArgumentException('订单已结束,不能再修改备注');
|
|
|
}
|
|
|
- $this->mprocAssertQuoteNotDeadlineReached(is_array($po) ? $po : null);
|
|
|
+ $this->mprocAssertQuoteStillEditable(is_array($po) ? $po : null, '', $row);
|
|
|
if (!$this->mprocCanEditRow($user, array_merge($row, ['status_name' => $effectiveSn]), is_array($po) ? $po : null)) {
|
|
|
if (!empty($user['is_admin'])) {
|
|
|
throw new \InvalidArgumentException('当前账号仅可查看,不能修改备注');
|
|
|
}
|
|
|
+ if ($this->mprocIsBidOpenVerifiedForPoOrRow(is_array($po) ? $po : null, $row)) {
|
|
|
+ throw new \InvalidArgumentException('已开标验证,不可再提交');
|
|
|
+ }
|
|
|
if ($this->mprocIsQuoteDeadlineReachedForPo(is_array($po) ? $po : null)) {
|
|
|
throw new \InvalidArgumentException('已超过招标截止时间,不可再提交');
|
|
|
}
|