Browse Source

成品入仓同步

unknown 4 days ago
parent
commit
526bcfbb57

+ 69 - 23
application/api/controller/FinishedProductWarehousing.php

@@ -570,6 +570,13 @@ public function getList()
             $sjChanged = trim((string)$req['jjcp_sj']) !== trim((string)$old['jjcp_sj']);
             $sjChanged = trim((string)$req['jjcp_sj']) !== trim((string)$old['jjcp_sj']);
         }
         }
 
 
+        $sysIdChanged = false;
+        if ($sysId !== null && $sysId !== '') {
+            $oldSys = trim((string)($old['Sys_id'] ?? ''));
+            $sysIdChanged = trim((string)$sysId) !== $oldSys;
+        }
+        $needsMiddleSync = $hasQty || $hasSmb || $hasSj || $sysIdChanged;
+
         // 改为末板时,校验同工单同印件是否已有其他末板记录
         // 改为末板时,校验同工单同印件是否已有其他末板记录
         if ($smbChanged && $this->isEndBoard($newSmb)) {
         if ($smbChanged && $this->isEndBoard($newSmb)) {
             $existingEndBoard = $this->findExistingEndBoard($old['jjcp_gdbh'], $old['jjcp_yjno']);
             $existingEndBoard = $this->findExistingEndBoard($old['jjcp_gdbh'], $old['jjcp_yjno']);
@@ -608,22 +615,11 @@ public function getList()
             }
             }
         }
         }
 
 
-        // 2. 同步中间表(与超节损独立;失败/未同步均写入日志)
-        // - 数量变更:插入差值为新同步数据(增加为正、减少为负)
-        // - 仅修改 smb / 时间:正常同步完整数量
-        // - 数量与其他同时改:只同步差值
-        if ($qtyChanged || $smbChanged || $sjChanged) {
-            $recordForSync = array_merge($old, $data);
-            $iQtyOverride = $qtyChanged ? ($newQty - $oldQty) : null;
-            $syncMsg = $this->syncFinishStockOrLogSkip(
-                $recordForSync,
-                $uniqId,
-                '修改',
-                $iQtyOverride,
-                $sysId
-            );
-            if ($syncMsg !== null) {
-                $warnings[] = $syncMsg;
+        // 2. 同步中间表:先「新增」负数量冲销原数据,再「新增」写入修改后数据(不用「修改」类型)
+        if ($needsMiddleSync) {
+            $syncMsgs = $this->syncFinishStockAfterEditOrLogSkip($old, $uniqId, $sysId);
+            if (!empty($syncMsgs)) {
+                $warnings = array_merge($warnings, $syncMsgs);
             }
             }
         }
         }
 
 
@@ -1207,14 +1203,16 @@ public function getList()
             }
             }
         }
         }
         krsort($data1);
         krsort($data1);
+
         //成品入仓中jjcp_smb不为空的工单
         //成品入仓中jjcp_smb不为空的工单
 
 
         $rows2 = db('成品入仓')
         $rows2 = db('成品入仓')
             ->where('jjcp_sj','>=',$date)
             ->where('jjcp_sj','>=',$date)
+            // ->where('jjcp_smb','<>','末 板')
             ->group('jjcp_gdbh, jjcp_cpdh')
             ->group('jjcp_gdbh, jjcp_cpdh')
             ->column("CONCAT( jjcp_gdbh, '-',  jjcp_yjno) AS gdyj, max(jjcp_smb) as jjcp_smb,
             ->column("CONCAT( jjcp_gdbh, '-',  jjcp_yjno) AS gdyj, max(jjcp_smb) as jjcp_smb,
             sum(jjcp_sl) as jjcp_sls, left(max(jjcp_sj),10) as jjcp_sj,UniqId");
             sum(jjcp_sl) as jjcp_sls, left(max(jjcp_sj),10) as jjcp_sj,UniqId");
-            
+
         $data = [];
         $data = [];
         foreach($data1 as $key=>$value){
         foreach($data1 as $key=>$value){
 
 
@@ -1565,9 +1563,9 @@ public function getList()
         if ($gdbh === '' || !isset($gdbh[0]) || $gdbh[0] !== 'Y') {
         if ($gdbh === '' || !isset($gdbh[0]) || $gdbh[0] !== 'Y') {
             return ['ok' => false, 'reason' => '不满足同步条件:工单编号不以Y开头或为空[' . $gdbh . ']'];
             return ['ok' => false, 'reason' => '不满足同步条件:工单编号不以Y开头或为空[' . $gdbh . ']'];
         }
         }
-        if ((int)substr($gdbh, 1) < 2608001) {
-            return ['ok' => false, 'reason' => '不满足同步条件:工单编号小于Y2608001[' . $gdbh . ']'];
-        }
+        // if ((int)substr($gdbh, 1) < 2608001) {
+        //     return ['ok' => false, 'reason' => '不满足同步条件:工单编号小于Y2608001[' . $gdbh . ']'];
+        // }
 
 
         try {
         try {
             $orderDate = db('工单_基本资料')->where('Gd_gdbh', $gdbh)->value('接单日期');
             $orderDate = db('工单_基本资料')->where('Gd_gdbh', $gdbh)->value('接单日期');
@@ -1577,9 +1575,9 @@ public function getList()
         if (empty($orderDate)) {
         if (empty($orderDate)) {
             return ['ok' => false, 'reason' => '不满足同步条件:工单_基本资料无接单日期[' . $gdbh . ']'];
             return ['ok' => false, 'reason' => '不满足同步条件:工单_基本资料无接单日期[' . $gdbh . ']'];
         }
         }
-        if (strtotime(trim((string)$orderDate)) < strtotime('2026-08-01')) {
-            return ['ok' => false, 'reason' => '不满足同步条件:接单日期[' . trim((string)$orderDate) . ']早于2026-08-01'];
-        }
+        // if (strtotime(trim((string)$orderDate)) < strtotime('2026-08-01')) {
+        //     return ['ok' => false, 'reason' => '不满足同步条件:接单日期[' . trim((string)$orderDate) . ']早于2026-08-01'];
+        // }
 
 
         try {
         try {
             // db3:正式中间库,仅查询 U8_06工单资料是否存在该工单
             // db3:正式中间库,仅查询 U8_06工单资料是否存在该工单
@@ -1624,6 +1622,54 @@ public function getList()
         }
         }
     }
     }
 
 
+    /**
+     * 修改后同步中间表:① 新增 + 原数量负数(修改前快照) ② 新增 + 修改后正数量
+     * @param array $old 修改前成品入仓记录
+     * @param int $uniqId
+     * @param string|null $sysId
+     * @return array 失败提示列表,空表示无告警
+     */
+    protected function syncFinishStockAfterEditOrLogSkip(array $old, $uniqId, $sysId = null)
+    {
+        $warnings = [];
+        $gdbh = $old['jjcp_gdbh'] ?? '';
+        $gate = $this->explainFinishStockSyncGate($gdbh);
+        $synchronization = new \app\api\controller\Synchronization();
+        $operator = ($sysId !== null && trim((string)$sysId) !== '') ? $sysId : ($old['Sys_id'] ?? '');
+
+        if (!$gate['ok']) {
+            $synchronization->logFinishStockSync($old, $uniqId, '新增', '未同步', $gate['reason']);
+            return $warnings;
+        }
+
+        $oldQty = (float)$old['jjcp_sl'];
+        if (abs($oldQty) < 0.00001) {
+            $synchronization->logFinishStockSync($old, $uniqId, '新增', '未同步', '原数量为0,跳过冲销同步');
+            return $warnings;
+        }
+
+        try {
+            $synchronization->syncFinishStockMiddle(
+                $uniqId,
+                '新增',
+                -1 * $oldQty,
+                $operator,
+                $old
+            );
+        } catch (\Exception $e) {
+            $warnings[] = '修改冲销同步失败:' . $e->getMessage();
+            return $warnings;
+        }
+
+        try {
+            $synchronization->syncFinishStockMiddle($uniqId, '新增', null, $operator);
+        } catch (\Exception $e) {
+            $warnings[] = '修改重传同步失败:' . $e->getMessage();
+        }
+
+        return $warnings;
+    }
+
     /**
     /**
      * 末版入仓后进入超节损
      * 末版入仓后进入超节损
      * @param string $gdbh
      * @param string $gdbh

+ 41 - 5
application/api/controller/Synchronization.php

@@ -2100,10 +2100,11 @@ class Synchronization extends Api
      * @param string $insertType 插入类型:新增/修改/删除
      * @param string $insertType 插入类型:新增/修改/删除
      * @param float|int|null $iQtyOverride 数量覆盖(修改数量时传差值:增加为正、减少为负;null 则用记录原数量)
      * @param float|int|null $iQtyOverride 数量覆盖(修改数量时传差值:增加为正、减少为负;null 则用记录原数量)
      * @param string|null $usernameOverride 操作人覆盖(删除/修改时前端传入的 sys_id)
      * @param string|null $usernameOverride 操作人覆盖(删除/修改时前端传入的 sys_id)
+     * @param array|null $recordOverride 覆盖成品入仓字段(修改冲销时用修改前快照)
      * @return bool
      * @return bool
      * @throws \Exception 同步失败时抛出,便于调用方提示
      * @throws \Exception 同步失败时抛出,便于调用方提示
      */
      */
-    public function syncFinishStockMiddle($uniqId, $insertType = '新增', $iQtyOverride = null, $usernameOverride = null)
+    public function syncFinishStockMiddle($uniqId, $insertType = '新增', $iQtyOverride = null, $usernameOverride = null, $recordOverride = null)
     {
     {
         $syncTime = date('Y-m-d H:i:s');
         $syncTime = date('Y-m-d H:i:s');
         $record = [
         $record = [
@@ -2125,6 +2126,9 @@ class Synchronization extends Api
                 throw new \Exception('同步失败:未找到成品入仓记录 UniqId=' . $uniqId);
                 throw new \Exception('同步失败:未找到成品入仓记录 UniqId=' . $uniqId);
             }
             }
             $record = $found;
             $record = $found;
+            if ($recordOverride !== null && is_array($recordOverride)) {
+                $record = array_merge($record, $recordOverride);
+            }
 
 
             if ($usernameOverride !== null && trim((string)$usernameOverride) !== '') {
             if ($usernameOverride !== null && trim((string)$usernameOverride) !== '') {
                 $record['Sys_id'] = $usernameOverride;
                 $record['Sys_id'] = $usernameOverride;
@@ -2139,13 +2143,12 @@ class Synchronization extends Api
             $isEndBoard = ($smb !== '' && mb_substr($smb, 0, 1, 'UTF-8') === '末') ? '末板' : '';
             $isEndBoard = ($smb !== '' && mb_substr($smb, 0, 1, 'UTF-8') === '末') ? '末板' : '';
             $iQty = $iQtyOverride !== null ? $iQtyOverride : $record['jjcp_sl'];
             $iQty = $iQtyOverride !== null ? $iQtyOverride : $record['jjcp_sl'];
 
 
-            $maxId = (int)$targetDb->name($targetTable)->max('id');
-            $id = $maxId + 1;
+            $id = $this->getFinishStockMiddleNextId($targetDb, $targetTable);
 
 
             $data = [
             $data = [
                 'id'          => $id,
                 'id'          => $id,
                 'MESCode'     => '000000',
                 'MESCode'     => '000000',
-                'dDate'       => $record['jjcp_sj'],
+                'dDate'       => date('Y-m-d 00:00:00', strtotime((string)$record['jjcp_sj'])),
                 'cWhCode'     => $record['仓库编号'],
                 'cWhCode'     => $record['仓库编号'],
                 'cMoCode'     => $record['jjcp_gdbh'],
                 'cMoCode'     => $record['jjcp_gdbh'],
                 'cMemo'       => $record['jjcp_desc'],
                 'cMemo'       => $record['jjcp_desc'],
@@ -2163,7 +2166,7 @@ class Synchronization extends Api
                 '印件名称'    => $record['jjcp_cpmc'],
                 '印件名称'    => $record['jjcp_cpmc'],
                 '成品编码'    => $record['成品编码'],
                 '成品编码'    => $record['成品编码'],
                 '成品名称'    => $record['成品名称'],
                 '成品名称'    => $record['成品名称'],
-                'UniqId'      => $record['UniqId'],
+//                'UniqId'      => $record['UniqId'],
             ];
             ];
 
 
             $this->insertFinishStockMiddle($targetDb, $targetTable, $data);
             $this->insertFinishStockMiddle($targetDb, $targetTable, $data);
@@ -2263,6 +2266,39 @@ class Synchronization extends Api
         }
         }
     }
     }
 
 
+    /**
+     * 中间表下一主键 id(按数值取 MAX,避免字符型 id 出现 9>10 导致卡在 10)
+     * @param \think\db\Connection $targetDb
+     * @param string $table
+     * @return int
+     */
+    protected function getFinishStockMiddleNextId($targetDb, $table)
+    {
+        $dbType = strtolower((string)$targetDb->getConfig('type'));
+        $isSqlsrv = (strpos($dbType, 'sqlsrv') !== false || strpos($dbType, 'sqlserver') !== false);
+
+        if ($isSqlsrv) {
+            $quotedTable = '[' . str_replace(']', ']]', $table) . ']';
+            $sql = "SELECT MAX(CAST([id] AS BIGINT)) AS max_id FROM {$quotedTable}";
+        } else {
+            $quotedTable = '`' . str_replace('`', '``', $table) . '`';
+            $sql = "SELECT MAX(CAST(`id` AS UNSIGNED)) AS max_id FROM {$quotedTable}";
+        }
+
+        $rows = $targetDb->query($sql);
+        $maxId = 0;
+        if (!empty($rows)) {
+            $row = $rows[0];
+            if (isset($row['max_id'])) {
+                $maxId = (int)$row['max_id'];
+            } else {
+                $maxId = (int)reset($row);
+            }
+        }
+
+        return $maxId + 1;
+    }
+
     /**
     /**
      * 中间表插入(兼容 MySQL / SQL Server 中文字段,使用位置绑定)
      * 中间表插入(兼容 MySQL / SQL Server 中文字段,使用位置绑定)
      * @param \think\db\Connection $targetDb
      * @param \think\db\Connection $targetDb