'boolean', 'is_manual_update' => 'boolean', 'is_delay_deliver' => 'boolean', ]; protected $dates = [ 'sent_at', 'received_at', 'weighed_at', ]; static public $enums = [ 'status' => [ '' => 0, '生成订单' => 1, '已复核' => 2, '已称重' => 3, '已揽件' => 4, '在途' => 5, '派送中' => 6, '已签收' => 7, '其他' => 8, '返回中' => 9, ], 'exception_status' => [ '' => 0, '单号异常' => 1, '无法获取路由' => 2, '延迟发货' => 3, '疑似库内丢件' => 4, '在途异常' => 5, '揽件异常' => 6, '派送异常' => 7, ], ]; function __construct(array $attributes = []) { foreach (self::$enums as &$enum) { $enum = $enum + array_flip($enum); } parent::__construct($attributes); } public function getStatusAttribute($value) { if (!$value || !isset(self::$enums['status'][$value])) return ''; return self::$enums['status'][$value]; } public function setStatusAttribute($value) { if (!$value) return 0; if (!(self::$enums['status'][$value] ?? false)) return 0; $this->attributes['status'] = self::$enums['status'][$value]; } public static function switchStatus($value): int { if (!(self::$enums['status'][$value] ?? false)) return 0; return self::$enums['status'][$value]; } public function getExceptionStatusAttribute($value) { if (!$value || !isset(self::$enums['exception_status'][$value])) return ''; return self::$enums['exception_status'][$value]; } public function setExceptionStatusAttribute($value) { if (!$value) return 0; if (!(self::$enums['exception_status'][$value] ?? false)) return 0; $this->attributes['exception_status'] = self::$enums['exception_status'][$value]; } public static function switchExceptionStatus($value): int { if (!(self::$enums['exception_status'][$value] ?? false)) return 0; return self::$enums['exception_status'][$value]; } public function order() { return $this->belongsTo('App\Order', 'order_id', 'id'); } public function commodities(): HasMany { return $this->hasMany('App\OrderPackageCommodities', 'order_package_id', 'id'); } public function paperBox(): HasOne { return $this->hasOne('App\PaperBox', 'id', 'paper_box_id'); } public function workOrder(): HasOne { return $this->hasOne(WorkOrder::class, 'order_id', 'order_id'); } public function measuringMachine(): HasOne { return $this->hasOne('App\MeasuringMachine', 'id', 'measuring_machine_id'); } public function WMSReflectPackage(): HasOne { return $this->hasOne('App\WMSReflectPackage', 'SOReference5', 'logistic_number'); } static protected $oracleOrderHeaderFields = [ 'doc_order_header.userdefine1', 'doc_order_header.soreference5', 'doc_order_header.waveno', 'doc_order_header.orderno', 'doc_order_header.customerid', 'doc_order_header.consigneename', 'doc_order_header.carrierid', 'doc_order_header.c_tel1', 'doc_order_header.c_tel2', 'doc_wave_header.descr', ]; protected $tempFields = [ 'temOracleInfo', 'temOwner', 'temLogistic', ]; public function setLengthAttribute($value) { if (empty((int)($value))) return; $this->attributes['length'] = $value; } public function setWidthAttribute($value) { if (empty((int)($value))) return; $this->attributes['width'] = $value; } public function setHeightAttribute($value) { if (empty((int)($value))) return; $this->attributes['height'] = $value; } public function setBulkAttribute($value) { if (empty((int)($value))) return; $this->attributes['bulk'] = $value; } public function delete() { $this->commodities()->delete(); return parent::delete(); } public function deleteSafe() { return parent::delete(); } public function isActivityBatch() { return ($this['batch_rule'] && strstr($this['batch_rule'], '组合') && $this['batch_number']); } public function fetchAllFromOracle() { if (empty($this->oracleInfo)) return null; $this['batch_rule'] = $this->oracleInfo['descr']; $this['batch_number'] = $this->oracleInfo['waveno'] ?? null; } static public function createPackagesFromBatchCode($batchCode, $weight) { $queryBuilder = OracleDOCOrderHeader::query()->select(self::$oracleOrderHeaderFields); $queryBuilder->where('doc_order_header.waveno', $batchCode); $queryBuilder->leftJoin('act_allocation_details', 'act_allocation_details.orderno', 'doc_order_header.orderno'); $queryBuilder->leftJoin('doc_wave_header', 'doc_wave_header.waveno', 'doc_order_header.waveno'); $resultOracleObjs = $queryBuilder->get(); $resultOracleObjs_grouped = $resultOracleObjs->groupBy('soreference5'); $packages = []; $now = Carbon::now(); foreach ($resultOracleObjs_grouped as $resultOracleObj_grouped) { $resultOracleObj = $resultOracleObj_grouped[0]; /** @var OrderService $orderService */ $orderService = app('OrderService'); $order = $orderService->logisticNumberFirstOrCreateOrder($resultOracleObj['soreference5']); if (!$order) { app('LogService')->log(__METHOD__, "此包裹在WMS未找到order", json_encode($resultOracleObj), Auth::user()['id']); continue; } array_push($packages, [ 'batch_number' => $batchCode ?? '', 'order_id' => $order->id, 'logistic_number' => $resultOracleObj['soreference5'] ?? '', 'weight' => $weight, 'weighed_at' => $now, 'uploaded_to_wms' => "是", "created_at" => $now, ]); } $packagesLogisticNumbers = array_map(function ($orderPackage) { return $orderPackage['logistic_number']; }, $packages); $existingOrderPackages = OrderPackage::whereIn('logistic_number', $packagesLogisticNumbers)->get(); $existingLogisticNumbers = $existingOrderPackages->map(function ($orderPackage) { return $orderPackage['logistic_number']; })->toArray(); OrderPackage::whereIn('logistic_number', $existingLogisticNumbers)->update([ 'batch_number' => $batchCode ?? '', 'weight' => $weight, 'weighed_at' => $now, 'uploaded_to_wms' => "是",]); $newPackages = $packages; if ($existingOrderPackages->isNotEmpty()) $newPackages = array_filter($packages, function ($package) use ($existingLogisticNumbers) { return array_search($package['logistic_number'], $existingLogisticNumbers) === false; }); DB::transaction(function () use ($newPackages) { OrderPackage::query()->insert($newPackages); }); } public function unifyThisMeasureUnderSameBatch() { $this->fetchPaperBox(); $params = []; !empty($this['weight']) ? $params['weight'] = $this['weight'] : null; !empty($this['length']) ? $params['length'] = $this['length'] : null; !empty($this['width']) ? $params['width'] = $this['width'] : null; !empty($this['height']) ? $params['height'] = $this['height'] : null; !empty($this['bulk']) ? $params['bulk'] = $this['bulk'] : null; !empty($this['measuring_machine_id']) ? $params['measuring_machine_id'] = $this['measuring_machine_id'] : null; !empty($this['weighed_at']) ? $params['weighed_at'] = $this['weighed_at'] : null; !empty($this['paper_box_id']) ? $params['paper_box_id'] = $this['paper_box_id'] : null; if (empty($params) || empty($this['batch_number'])) return; OrderPackage::query()->where(['batch_number' => $this['batch_number']])->update($params); } public function fetchLogisticFromOracle() { if (empty($this->oracleInfo)) return null; if (Arr::exists($this->tempFields, 'temLogistic')) return $this->tempFields['temLogistic']; Controller::logs(__METHOD__, __FUNCTION__, "tempPackage:{$this->oracleInfo['carrierid']}||SOR:{$this->oracleInfo['SOReference5']}||sor:{$this->oracleInfo['soreference5']}||orderno:{$this['orderno']}", null); if (!$this->oracleInfo['carrierid']) return null; $logistic = Logistic::query()->where('code', $this->oracleInfo['carrierid'])->first(); if (!$logistic) { $logistic = Logistic::query()->create(['code' => $this->oracleInfo['carrierid'], 'name' => $this->oracleInfo['carrierid']]); Controller::logs(__METHOD__, __FUNCTION__, "富勒下发找不到快递公司,添加{$this->oracleInfo['carrierid']}", null); } Controller::logs(__METHOD__, __FUNCTION__, "tempPackage2:{$logistic->id}", null); if (!$logistic) return null; $this->tempFields['temLogistic'] = $logistic; $this['logistic_id'] = $logistic['id']; return $logistic; } public function fetchOwnerFromOracle() { if (empty($this->oracleInfo)) return null; if (Arr::exists($this->tempFields, 'temOwner')) return $this->tempFields['temOwner']; $owner = Owner::query()->where('code', $this->oracleInfo['customerid'])->first(); if (!$owner) { $owner = Owner::query()->create(['code' => $this->oracleInfo['customerid'], 'name' => $this->oracleInfo['customerid']]); Controller::logs(__METHOD__, __FUNCTION__, "富勒下发找不到货主,添加{$this->oracleInfo['customerid']}", null); } if (!$owner) return null; $this->tempFields['temOwner'] = $owner; $this['owner_id'] = $owner['id']; return $owner; } //寻找相近纸箱ID public function fetchPaperBox($max = null, $centre = null, $min = null, $owner_id = null) { if ($this['paper_box_id']) return $this['paper_box_id']; $sumDiffer = 0; $maxDiffer = 0; $paperBox_id = null; if (!$max) $max = $this['length']; if (!$centre) $centre = $this['width']; if (!$min) $min = $this['height']; if (!$owner_id) $owner_id = $this['order'] ? $this['order']['owner_id'] : null; if (!$owner_id) { $owner = $this->fetchOwnerFromOracle(); $owner_id = $owner['id']; if (!$owner_id) return null; } $boxes = Owner::select('id')->with('paperBoxes')->find($owner_id); $targetPaperBox = null; foreach ($boxes->paperBoxes as $i => $paperBox) { if ($paperBox->length == $max && $paperBox->width == $centre && $paperBox->height == $min) { $targetPaperBox = $paperBox; break; } $lengthDiffer = abs($paperBox->length - $max); $widthDiffer = abs($paperBox->width - $centre); $heightDiffer = abs($paperBox->height - $min); $thisMaxDiffer = ($lengthDiffer >= ($widthDiffer >= $heightDiffer ? $widthDiffer : $heightDiffer) ? $lengthDiffer : ($widthDiffer >= $heightDiffer ? $widthDiffer : $heightDiffer)); if ($i == 0) { $maxDiffer = $thisMaxDiffer; $sumDiffer = $lengthDiffer + $widthDiffer + $heightDiffer; $targetPaperBox = $paperBox; } if ($thisMaxDiffer == $maxDiffer) { if ($sumDiffer > ($lengthDiffer + $widthDiffer + $heightDiffer)) { $sumDiffer = $lengthDiffer + $widthDiffer + $heightDiffer; $targetPaperBox = $paperBox; } } if ($thisMaxDiffer < $maxDiffer) { $sumDiffer = $lengthDiffer + $widthDiffer + $heightDiffer; $maxDiffer = $thisMaxDiffer; $targetPaperBox = $paperBox; } } if ($targetPaperBox) $this['paper_box_id'] = $targetPaperBox['id']; return $targetPaperBox['id']; } public function getOracleInfoAttribute() { if (isset($this->tempFields['temOracleInfo'])) return $this->tempFields['temOracleInfo']; if (empty($this['logistic_number']) && empty($this['order_code'])) return ''; if ($this['order_code']) { $resultOracleObjs = OracleDOCOrderHeader::query()->select(self::$oracleOrderHeaderFields)->where('orderno', $this['order_code']); $resultOracleObjs->leftJoin('doc_wave_header', 'doc_wave_header.waveno', 'doc_order_header.waveno'); } else { $resultOracleObjs = OracleActAllocationDetails::query()->select(self::$oracleOrderHeaderFields); $resultOracleObjs->where('picktotraceid', $this['logistic_number']); $resultOracleObjs->leftJoin('DOC_Order_Header', 'act_allocation_details.orderno', 'doc_order_header.orderno'); $resultOracleObjs->leftJoin('doc_wave_header', 'doc_wave_header.waveno', 'doc_order_header.waveno'); } $this->tempFields['temOracleInfo'] = $resultOracleObjs->first(); if (empty($this->tempFields['temOracleInfo'])) { $resultOracleObjs = OracleDOCOrderHeader::query()->select(self::$oracleOrderHeaderFields)->where('soreference5', $this['logistic_number']); $resultOracleObjs->leftJoin('doc_wave_header', 'doc_wave_header.waveno', 'doc_order_header.waveno'); } $this->tempFields['temOracleInfo'] = $resultOracleObjs->first(); return $this->tempFields['temOracleInfo']; } public function getLogisticNumberAttribute($val) { if (strpos($val, 'null') !== false) return ''; return $val; } public function scopeFilter($query, $filters) { return $filters->apply($query); } public function owner(): BelongsTo { return $this->belongsTo(Owner::class); } public function orderPackageRemarks(): HasMany { return $this->hasMany(OrderPackageRemark::class); } public function rejectedBill(): BelongsTo { return $this->belongsTo(RejectedBill::class, 'logistic_number', 'logistic_number_return'); } public function orderPackageExpressRoute(): BelongsTo { return $this->belongsTo(OrderPackageExpressRoute::class, 'order_package_express_route_id', 'id'); } }