shipment_id !== (int) $shipment->id) { $updates['shipment_id'] = $shipment->id; } if (! $clearance->transaction_id && $shipment->transaction_id) { $updates['transaction_id'] = $shipment->transaction_id; } if (! $clearance->contact_id && $shipment->contact_id) { $updates['contact_id'] = $shipment->contact_id; } if ($updates) { $clearance->update($updates); } } public function linkByTransaction(CustomsClearance $clearance): CustomsClearance { $settings = $this->tmsUtil->getTmsSettings($clearance->business_id); if (empty($settings['auto_link_customs_shipment'])) { return $clearance; } if ($clearance->shipment_id) { return $clearance; } if ($clearance->transaction_id) { $shipment = Shipment::where('business_id', $clearance->business_id) ->where('transaction_id', $clearance->transaction_id) ->first(); if ($shipment) { $this->linkMutually($clearance, $shipment); $this->syncShipmentFromCustoms($clearance->fresh()); return $clearance->fresh(); } } if ($clearance->clearance_type === 'import' && ! empty($settings['auto_create_shipment_on_customs_import'])) { $shipment = $this->createImportShipmentForCustoms($clearance); if ($shipment) { $this->linkMutually($clearance->fresh(), $shipment); $this->syncShipmentFromCustoms($clearance->fresh()); } } return $clearance->fresh(); } public function linkByTransactionForShipment(Shipment $shipment): Shipment { $settings = $this->tmsUtil->getTmsSettings($shipment->business_id); if (empty($settings['auto_link_customs_shipment']) || ! $shipment->transaction_id) { return $shipment; } $clearance = CustomsClearance::where('business_id', $shipment->business_id) ->where('transaction_id', $shipment->transaction_id) ->first(); if ($clearance) { $this->linkMutually($clearance, $shipment); $this->syncShipmentFromCustoms($clearance->fresh()); } return $shipment->fresh(['customsClearance']); } public function syncShipmentFromCustoms(CustomsClearance $clearance): void { $settings = $this->tmsUtil->getTmsSettings($clearance->business_id); if (empty($settings['sync_customs_shipment_status']) || ! $clearance->shipment_id) { return; } $shipment = Shipment::find($clearance->shipment_id); if (! $shipment) { return; } $newStatus = $this->tmsUtil->mapCustomsStatusToShipment($clearance->status, $shipment->status); if (! $newStatus || $shipment->status === $newStatus) { return; } $this->shipmentService()->updateStatus( $shipment, $newStatus, __('tms::lang.synced_from_customs', ['ref' => $clearance->ref_no]), null, skipCustomsCheck: true ); } public function createImportShipmentForCustoms(CustomsClearance $clearance): ?Shipment { if ($clearance->clearance_type !== 'import') { return null; } $business_id = (int) $clearance->business_id; $transaction = $clearance->transaction_id ? Transaction::find($clearance->transaction_id) : null; if ($transaction) { $existing = Shipment::where('business_id', $business_id) ->where('transaction_id', $transaction->id) ->first(); if ($existing) { return $existing; } } $shipment = Shipment::create([ 'business_id' => $business_id, 'ref_no' => $this->tmsUtil->generateRefNo($business_id), 'shipment_type' => 'import', 'transaction_id' => $clearance->transaction_id, 'contact_id' => $clearance->contact_id ?? $transaction?->contact_id, 'origin_location_id' => $transaction?->location_id, 'destination_address' => $transaction?->shipping_address, 'status' => 'at_customs', 'scheduled_at' => $transaction?->delivery_date ?? now(), 'freight_cost' => $transaction?->shipping_charges ?? 0, 'cargo_description' => $transaction?->shipping_details, 'created_by' => auth()->id(), ]); $this->shipmentService()->logStatus( $shipment, 'at_customs', __('tms::lang.shipment_created_from_customs', ['ref' => $clearance->ref_no]) ); return $shipment; } protected function shipmentService(): TmsShipmentService { return app(TmsShipmentService::class); } public function customsBlocksTransit(Shipment $shipment): bool { $settings = $this->tmsUtil->getTmsSettings($shipment->business_id); if (empty($settings['require_customs_cleared_before_transit'])) { return false; } $clearance = $shipment->customsClearance ?? CustomsClearance::where('shipment_id', $shipment->id)->first(); if (! $clearance) { return false; } return ! in_array($clearance->status, ['cleared', 'released'], true); } public function transitBlockMessage(Shipment $shipment): string { $clearance = $shipment->customsClearance ?? CustomsClearance::where('shipment_id', $shipment->id)->first(); $ref = $clearance?->ref_no ?? ''; return __('tms::lang.customs_blocks_transit', ['ref' => $ref]); } }