cqp пре 8 часа
родитељ
комит
293c2f6310
3 измењених фајлова са 275 додато и 12 уклоњено
  1. 2 1
      app/Console/Commands/U8Settle.php
  2. 20 6
      app/Jobs/ProcessWMSDataJob.php
  3. 253 5
      app/Service/U8ThirdPartyService.php

+ 2 - 1
app/Console/Commands/U8Settle.php

@@ -94,7 +94,7 @@ class U8Settle extends Command
                 'detail' => 'PU_ArrivalVouchs',
                 'main_key' => 'ID',
                 'key' => 'ID',
-                'whereRaw' => "(dDate >= '{$pu}')",
+                'whereRaw' => "(dDate >= '{$pu}' and cBusType = '普通采购')",
                 'main_field' => ['ID as id','cCode as no','dDate as order_date', 'cMakeTime as crt_time', 'cModifyTime as upd_time', 'iBillType as type', 'cverifier as reviewer'],
                 'son_field' => [
                     'detail.ID as id',
@@ -104,6 +104,7 @@ class U8Settle extends Command
                     'detail.iQuantity as planQty',
                     'detail.cDefine23',
                     'detail.cBatch',
+                    'detail.bGsp', //是否检验
                 ],
                 'limit' => 30,
             ],

+ 20 - 6
app/Jobs/ProcessWMSDataJob.php

@@ -98,7 +98,14 @@ class ProcessWMSDataJob implements ShouldQueue
         if($record->type_2 == 1 && $record->type == SyncTempRecord::type_one) $path = '/erp/outbound';
         $apiUrl = config('wms.api_url') . $path;
 
+        $bool = true;
         if (isset($u8Data['details']) && is_array($u8Data['details'])) {
+            if($record->type == SyncTempRecord::type_one){
+                // 采购到货|退货单
+                $warehouse_code = array_unique(array_column($u8Data['details'],'warehouseCode'));
+                $warehouse_code_array = ['01', '02', '05', '06' , '24', '25', '50', '51', '52', '53'];
+                if(empty(array_intersect($warehouse_code, $warehouse_code_array))) $bool = false;
+            }
             if($path == '/erp/inbound'){ //入
                 foreach ($u8Data['details'] as $item) {
                     $productDate = "";
@@ -107,6 +114,9 @@ class ProcessWMSDataJob implements ShouldQueue
                     if(! empty($item['iMassDate'])) $validTime = $item['iMassDate'];
                     $lot = "";
                     if(! empty($item['cBatch'])) $lot = $item['cBatch'];
+                    $inspectionStatus = 0;
+                    //采购到货单 bGsp为是否质检(1-质检;0-不质检) 不质检直接合格
+                    if($record->type == SyncTempRecord::type_one && isset($item['bGsp']) && ! $item['bGsp']) $inspectionStatus = 1;
                     $jsonBody['details'][] = [
                         'lineNum'       => $item['lineNum'] ?? 0,
                         'materialCode'  => $item['materialCode'] ?? '',
@@ -115,6 +125,7 @@ class ProcessWMSDataJob implements ShouldQueue
                         'productDate'       => $productDate,
                         'validTime'       => $validTime,
                         'lot'       => $lot,
+                        'inspectionStatus' => $inspectionStatus,
                         'lottar1'       => $item['cDefine23'] ?? "",
                         'lottar2'       => "",
                         'lottar3'       => '',
@@ -146,15 +157,18 @@ class ProcessWMSDataJob implements ShouldQueue
             }
         }
 
-        // 5. 调用 post_helper
-        list($status, $result) = $this->post_helper($apiUrl, $jsonBody, ['Content-Type: application/json']);
+        if($bool){
+            //请求音飞
+            list($status, $result) = $this->post_helper($apiUrl, $jsonBody, ['Content-Type: application/json']);
 
-        if (!$status) {
-            // 接口返回失败或网络失败
-            $record->update(['status' => SyncTempRecord::status_two, 'error_msg' => "音飞API返回:" . $result]);
-            return [false, $result];
+            if (!$status) {
+                // 接口返回失败或网络失败
+                $record->update(['status' => SyncTempRecord::status_two, 'error_msg' => "音飞API返回:" . $result]);
+                return [false, $result];
+            }
         }
 
+
         // 6. 接口返回成功 (200) 的后续操作
         DB::transaction(function () use ($record, $u8Data) {
             // 更新本地流水状态为成功

+ 253 - 5
app/Service/U8ThirdPartyService.php

@@ -104,7 +104,7 @@ class U8ThirdPartyService extends Service
     /**
      * 采购到货单拆行/更新处理
      */
-    public function purchaseIn($data)
+    public function purchaseIn1($data)
     {
         if (empty($data['orderId'])) return [false, '采购到货单ID不能为空'];
         if (empty($data['orderNo'])) return [false, '采购到货单单号不能为空'];
@@ -119,10 +119,6 @@ class U8ThirdPartyService extends Service
         $templateRow = reset($result);
         $mainId = $templateRow['ID'];
 
-        // 2. 存货管控校验(批次/保质期)
-//        list($status, $msg) = $service->checkInventoryControl(array_column($data['detail'], 'materialCode'));
-//        if (!$status) return [false, $msg];
-
         $insertData = [];
         $rowNo = 1;
 
@@ -229,6 +225,258 @@ class U8ThirdPartyService extends Service
         return [true, ''];
     }
 
+    public function purchaseIn($data)
+    {
+        if (empty($data['orderId'])) return [false, '采购到货单ID不能为空'];
+        if (empty($data['orderNo'])) return [false, '采购到货单单号不能为空'];
+        if (empty($data['detail'])) return [false, '表体信息detail不能为空'];
+
+        // 1. 获取到货单明细
+        $service = new U8ThirtyPartyDatabaseServerService();
+        list($status, $result) = $service->getCGDHDetails($data['orderId']);
+        if (! $status) return [false, $result];
+
+        // ==================== 核心修改:前置全单 bGsp 类型强一致性校验 ====================
+        $hasInspect = false;   // 是否存在需要检验的行 (bGsp = 1)
+        $hasNoInspect = false; // 是否存在不需要检验的行 (bGsp = 0)
+
+        foreach ($result as $item) {
+            if (isset($item['bGsp']) && (int)$item['bGsp'] === 1) {
+                $hasInspect = true;
+            } else {
+                $hasNoInspect = true;
+            }
+        }
+
+        // 只要同时存在【检验】和【免检】,直接在这里拦截,后面任何多余的计算和数据库操作都不执行
+        if ($hasInspect && $hasNoInspect) {
+            return [false, '该采购到货单中同时存在【检验】与【免检】的存货,无法混合处理,请拆单或修正单据中存货属性。'];
+        }
+
+        // 如果明细为空,直接返回
+        if (!$hasInspect && !$hasNoInspect) {
+            return [false, '未找到有效的明细数据进行处理'];
+        }
+        // ==========================================================================
+
+        // 取出第一行作为模板,保留 ID, cCode 等主表关联信息
+        $templateRow = reset($result);
+        $mainId = $templateRow['ID'];
+
+        $insertData = [];
+        $rowNo = 1;
+
+        foreach ($data['detail'] as $value) {
+            if (!isset($result[$value['materialCode']])) continue;
+
+            $map = $result[$value['materialCode']]; // 获取原始行信息
+
+            // 计算单价
+            $oldQty = (float)($map['iQuantity'] ?? 0);
+            if ($oldQty <= 0) continue;
+            $unitPrice = (float)$map['iOriSum'] / $oldQty;
+            $unitMoney = (float)$map['iOriMoney'] / $oldQty;
+            $unitLocalSum = (float)$map['iSum'] / $oldQty;
+            $unitLocalMoney = (float)$map['iMoney'] / $oldQty;
+
+            $newQty = (float)$value['iQuantity'];
+
+            // 组织新行数据
+            $newRow = $map;
+
+            // 清理旧行主键和业务累积状态
+            unset($newRow['Autoid']);
+            $newRow['fInspectQuantity'] = 0;
+            $newRow['fValidQuantity']   = 0;
+            $newRow['iQuantity']        = $newQty;
+            $newRow['ivouchrowno']      = $rowNo++;
+
+            // 填充计算后的金额和批次日期
+            $newRow['iOriMoney']    = round($unitMoney * $newQty, 2);
+            $newRow['iOriSum']      = round($unitPrice * $newQty, 2);
+            $newRow['iOriTaxPrice'] = round(($unitPrice - $unitMoney) * $newQty, 2);
+            $newRow['iMoney']       = round($unitLocalMoney * $newQty, 2);
+            $newRow['iSum']         = round($unitLocalSum * $newQty, 2);
+            $newRow['iTaxPrice']    = round(($unitLocalSum - $unitLocalMoney) * $newQty, 2);
+
+            $newRow['cBatch'] = !empty($value['lot']) ? $value['lot'] : null;
+            $newRow['dPDate'] = !empty($value['productDate']) ? $this->formatAndValidateDate($value['productDate']) : null;
+            $newRow['dVDate'] = !empty($value['failureDate']) ? $this->formatAndValidateDate($value['failureDate']) : null;
+            $newRow['cFree1'] = !empty($value['param_one']) ? $value['param_one'] : null;
+            $newRow['cFree2'] = !empty($value['param_two']) ? $value['param_two'] : null;
+
+            $insertData[] = $newRow;
+        }
+
+        // 3. 执行数据库操作:先删后插
+        list($status, $msg) = $service->rebuildDhDetails($mainId, $insertData);
+        if (!$status) return [false, $msg];
+
+        // 查询采购到货单(获取最新插入并带有最新 Autoid 的明细数据)
+        list($status, $order) = $service->getCgOrder($data['orderId']);
+        if(! $status) return [false, $order];
+
+        // ==================== 整单分流处理 ====================
+        $host = $data['u8_data']['host'];
+        $token = $data['u8_data']['token'];
+        $header = ["Authorization: {$token}", 'Content-Type:application/json'];
+
+        if ($hasInspect) {
+            // -------------- 全单走:来料报检单 --------------
+            $inspectBody = [];
+            foreach ($order['details'] as $item) {
+                $qty = (float)($item['iQuantity'] ?? 0);
+                if ($qty <= 0) continue;
+
+                $inspectBody[] = [
+                    "SOURCEAUTOID" => $item['Autoid'],
+                    "ITESTSTYLE"   => 0,
+                    "CINVCODE"     => $item['cInvCode'],
+                    "FCHANGRATE"   => (float)($item['iInvExchRate'] ?? 0),
+                    "FQUANTITY"    => $qty,
+                    "CBATCH"       => $item['cBatch'],
+                    'DPRODATE'     => $item['dPDate'],
+                    'DVDATE'       => $item['dVDate'],
+                    'cFree1'       => $item['cFree1'],
+                    'cFree2'       => $item['cFree2'],
+                ];
+            }
+
+            $inspectData = [
+                [
+                    "Inum" => "ArrInspect",
+                    "Data" => [
+                        "iHead" => [
+                            "CSOURCEID" => $order['ID'],
+                            "CDEPCODE"  => $order['cDepCode'],
+                            "DDATE"     => date("Y-m-d"),
+                            "CCHECKTYPECODE" => 'ARR',
+                        ],
+                        "iBody" => $inspectBody
+                    ]
+                ]
+            ];
+
+            $url = $host . "/api/QmArr/ArrInspectAdd";
+            list($status, $result) = $this->post_helper1($url, json_encode($inspectData), $header, 30);
+            if(! $status) return [false, '报检单接口请求失败: ' . json_encode($result)];
+            if(! isset($result['code']) || $result['code'] != 0) {
+                return [false, '报检单生成失败: ' . ($result['msg'] ?? '未知错误')];
+            }
+
+            return [true, '报检单生成成功'];
+
+        } else {
+            // -------------- 全单走:采购入库单 --------------
+            $purchaseInBody = [];
+            $rn = 1;
+            $warehouse_code = "";
+            foreach ($order['details'] as $item) {
+                $qty = (float)($item['iQuantity'] ?? 0);
+                if ($qty <= 0) continue;
+                if(empty($warehouse_code)) $warehouse_code = $item['cWhCode'];
+
+//                $purchaseInBody[] = [
+//                    "iRowNo"       => $rn++,
+//                    "cInvCode"     => $item['cInvCode'],
+//                    "cPosition"    => "",
+//                    "cBatch"       => $item['cBatch'],
+//                    "iinvexchrate" => (float)($item['iInvExchRate'] ?? 0),
+//                    "iQuantity"    => $qty,
+//                    "iSum"         => (float)($item['iSum'] ?? 0),
+//                    "iNum"         => 0,
+//                    "iNQuantity"   => $qty,
+//                    "iNNum"        => 0,
+//                    "chVencode"    => $order['cVenCode'],
+//                    "iPOsID"       => $item['iPOsID'],
+//                    "iArrsId"      => $item['Autoid']
+//                ];
+
+                // --- 核心金额计算逻辑 ---
+                $taxRate = (float)($item['iTaxRate'] ?? 13.0); // 税率
+                $taxUnitPrice = (float)($item['iOriTaxCost'] ?? 0); // 原币含税单价
+
+                // 1. 价税合计 (iSum)
+                $iSum = round($qty * $taxUnitPrice, 2);
+                // 2. 原币无税金额 (imoney) = 价税合计 / (1 + 税率/100)
+                $iMoney = round($iSum / (1 + ($taxRate / 100)), 2);
+                // 3. 税额 (itax)
+                $iTax = round($iSum - $iMoney, 2);
+                // 4. 原币无税单价 (iunitprice)
+                $iUnitPrice = round($taxUnitPrice / (1 + ($taxRate / 100)), 6);
+                $purchaseInBody[] = [
+                    "iRowNo"       => $rn++,
+                    "cInvCode"     => $item['cInvCode'],
+                    "cPosition"    => "",
+                    "cBatch"       => $item['cBatch'],
+                    "iinvexchrate" => (float)($item['iInvExchRate'] ?? 0),
+                    "iQuantity"    => $qty,
+                    "iSum"         => (float)($item['iSum'] ?? 0),
+                    "iNum"         => 0,
+                    "iNQuantity"   => $qty,
+                    "iNNum"        => 0,
+                    "chVencode"    => $order['cVenCode'],
+                    "iPOsID"       => $item['iPOsID'],
+                    "iArrsId"      => $item['Autoid'],
+
+                    // --- 新增价格字段 ---
+                    "iOriTaxCost"   => (float)$taxUnitPrice, // 原币含税单价
+                    "iOriCost"      => (float)$iUnitPrice,    // 原币无税单价
+                    "iOriMoney"     => (float)$iMoney,       // 原币无税金额
+                    "iOriTaxPrice"  => (float)$iTax,         // 原币税额
+                    "iOriSum"       => (float)$iSum,         // 原币价税合计
+                    "iTaxRate"      => (float)$taxRate,      // 税率
+                    // 本币字段 (inat...) 建议也加上,防止 U8 换算误差
+                    "fNatMoney"     => (float)$iMoney,       // 本币无税金额
+                    "fNatTax"       => (float)$iTax,         // 本币税额
+                    "fNatSum"       => (float)$iSum,         // 本币价税合计
+                    "dMadeDate"     => $item['DPRODATE'] ?? null,
+                    "dVDate"        => $item['DVDATE'] ?? null,
+                    'cFree1' => $item['CFREE1'] ?? null,
+                    'cFree2' => $item['CFREE2'] ?? null,
+                ];
+            }
+
+            $purchaseInData = [
+                [
+                    "Inum" => "PurchaseIn",
+                    "Data" => [
+                        "iHead" => [
+                            "IsVerify"      => true,
+                            "bCalPrice"     => true,          // 开启自动计算
+                            "PriceCalKey"   => "iOriTaxCost", // 以含税单价为准
+//                            "IsVerify"    => true,
+//                            "bCalPrice"   => false,
+//                            "PriceCalKey" => "iSum",
+                            "cWhCode"     => $warehouse_code,
+                            "cRdCode"     => "0101",
+                            "cDepCode"    => $order['cDepCode'],
+                            "cVenCode"    => $order['cVenCode'],
+                            "cARVCode"    => $order['cCode'],
+                            "cSource"     => "采购到货单",
+                            "cBusType"    => "普通采购",
+                            "cMemo"       => "接口生成",
+                            "cexch_name"  => "人民币",
+                            "iExchRate"   => $order['iExchRate'],
+                            "iTaxRate"    => $order['iTaxRate'],
+                            "dDate"       => date("Y-m-d")
+                        ],
+                        "iBody" => $purchaseInBody
+                    ]
+                ]
+            ];
+
+            $url = $host . "/api/PurchaseIn/Add";
+            list($status, $result) = $this->post_helper1($url, json_encode($purchaseInData), $header, 30);
+            if(! $status) return [false, '采购入库单接口请求失败: ' . json_encode($result)];
+            if(! isset($result['code']) || $result['code'] != 0) {
+                return [false, '采购入库单生成失败: ' . ($result['msg'] ?? '未知错误')];
+            }
+
+            return [true, '采购入库单生成成功'];
+        }
+    }
+
     public function materialOut($data)
     {
         if (empty($data['orderId'])) return [false, '领料申请单ID不能为空'];