ultimatepos/Modules/Tms/Services/TmsCustomsShipmentSyncService.php

198 lines
6.2 KiB
PHP

<?php
namespace Modules\Tms\Services;
use App\Transaction;
use Modules\Tms\Models\CustomsClearance;
use Modules\Tms\Models\Shipment;
use Modules\Tms\Utils\TmsUtil;
class TmsCustomsShipmentSyncService
{
public function __construct(
protected TmsUtil $tmsUtil
) {}
public function linkMutually(CustomsClearance $clearance, Shipment $shipment): void
{
$updates = [];
if ((int) $clearance->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]);
}
}