Objetivo
Objetivo
Objetivo:
Agregar el nombre de la cuenta del seller a los nombres de origenes al crear objetos en move y
mandarlo como destino
Detalle:
● Al crear un shipment o workflow en move, para la dirección de origen debe anteponerse
el nombre de la cuenta, ej. "Hoga - Deposito principal" en vez de "Deposito principal".
● Tener en cuenta lo siguiente:
○ Trimear espacios y signos de puntuación o no alfanuméricos
○ No repetir el nombre de la cuenta en el origen.
■ Ej. Cuenta = "Hoga" y Origen = "Hoga" -> enviar "Hoga"
■ Ej. Cuenta = "Beiró Hogar" y Origen = "Depósito Beiró Hogar" -> enviar
"Beiró Hogar - Depósito"
○ Si el nombre de la cuenta es mas largo que 15 caracteres, recortarlo.
■ Ej. Cuenta = "Visuar, Vstore, Samsung, Smartlife, Mercadolibre" y Origen
"VISUAR (Parque Industrial Cañuelas)" -> enviar "Visuar Vstore -
VISUAR Parque Industrial Cañuelas"
app/Services/Api/ZippinMove.php
<?php
/*
* Copyright (c) 2023-2024. Zippin Logistics International, Inc. and its
subsidiaries.
* Proprietary and confidential. No reproduction or derivative work is
allowed from this code.
*/
namespace Kraken\Services\Api;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use Kraken\Events\Shipment\MoveWorkflowUpdatedEvent;
use Kraken\Models\RecollectionBag;
use Kraken\Models\Shipment;
use Kraken\Models\Shipment\MoveWorkflow;
use Kraken\Services\Api\ZippinMove\WorkflowBuilder;
use Kraken\Services\Carriers\SelfServiceCarrier;
use Kraken\Services\Helpers;
use Kraken\Support\ActionResult;
class ZippinMove
{
protected string $org;
if (! isset($move_settings['credentials']['carrier']) || !
isset($move_settings['credentials']['token'])) {
return false;
} else {
}
public function createShipment(Shipment $shipment, $withInitialWorkflow
= true)
{
$body = [
'shipper_id' => $this->shipper_id,
'external_reference' => $shipment->remito,
'declared_value' => $shipment->carrier_declared_value,
'origin' => [
'name' => $shipment->origin->name,
'street' => $shipment->origin->street,
'street_number' => $shipment->origin->street_number,
'floor' => null,
'apartment' => null,
'reference' => $shipment->origin->street_extras,
'city' => $shipment->origin->city->name,
'state' => $shipment->origin->state->name,
'country' => $shipment->origin->country->iso_code,
'zipcode' => $shipment->origin->zipcode,
'phone' => str_pad($shipment->origin->phone, 10, '1',
STR_PAD_LEFT),
'email' => $shipment->origin->email,
'geo_latitude' => $shipment->origin->location_latitude,
'geo_longitude' => $shipment->origin->location_longitude,
],
'requires_pickup' => false,
'destination' => [
'name' => $shipment->destination->name,
'street' => $shipment->destination->street,
'street_number' => $shipment->destination->street_number,
'floor' => null,
'apartment' => null,
'reference' => $shipment->destination->street_extras,
'city' => $shipment->destination->city->name,
'state' => $shipment->destination->state->name,
'country' => $shipment->destination->country->iso_code,
'zipcode' => $shipment->destination->zipcode,
'phone' => $shipment->destination->phone,
'email' => $shipment->destination->email,
'geo_latitude' => $shipment->destination-
>location_latitude,
'geo_longitude' => $shipment->destination-
>location_longitude,
],
'packages' => [],
];
if (! $withInitialWorkflow) {
$body['initial_workflow'] = false;
}
if (empty($body['origin']['email'])) {
$body['origin']['email'] = $shipment->account->operations_email
?? $shipment->account->communication_email;
}
if (empty($body['origin']['phone'])) {
$body['origin']['phone'] = $shipment->account->operations_phone
?? $shipment->account->company_phone;
}
if (empty($body['destination']['street_number'])) {
$body['destination']['street_number'] = 'S/N';
}
$i = 1;
foreach ($shipment->packages as $package) {
if ($shipment->carrier->code == SelfServiceCarrier::CODE) {
$label_code = $package->id;
} else {
$label_code = $shipment->remito.'-'.str_pad($i, 4, '0',
STR_PAD_LEFT);
}
$body['packages'][] = [
'external_reference' => $shipment->external_id.'-'.$i,
'label_code' => (string) $label_code,
'classification' => 'default',
'grams' => $package->weight,
'length' => $package->length,
'width' => $package->width,
'height' => $package->height,
];
$i++;
}
$url = 'https://'.$this->org.'.zippinmove.com/api/v1/shipments';
$response = Http::withToken($this->token)->asJson()->post($url,
$body);
if ($response->json('success')) {
return ActionResult::success('Shipment created', ['response' =>
$response->json()]);
}
$response = Http::withToken($this->token)->asJson()->post($url,
null);
if ($response->json('success')) {
return ActionResult::success('Shipment canceled', ['response'
=> $response->json()]);
}
$url = 'https://'.$this->org.'.zippinmove.com/api/v1/workflows';
$response = Http::withToken($this->token)->asJson()->post($url,
$body);
if ($response->json('success')) {
Shipment\MoveWorkflow::create([
'shipment_id' => $shipment->id,
'workflow_id' => $response->json('workflow.id'),
'workflow_type' => $workflow_code,
'workflow_status' => $response-
>json('workflow.current_status', 'new'),
'move_workflows_metadata' => empty($metadata) ? null :
$metadata,
]);
if ($response->json('id')) {
return $response->json();
}
if ($response->successful()) {
$shipment_workflow->workflow_status = $response-
>json('data.workflow.current_status');
$shipment_workflow->update();
return ActionResult::success('Workflow canceled', ['response'
=> $response->json()]);
}
if ($response->json('tracking')) {
return $response->json('tracking');
}
return false;
}
if ($response->json('attachments')) {
return $response->json('attachments');
}
return false;
}
if ($response->json('content')) {
return $response->json();
}
return false;
}
return false;
return false;
if ($withAttachments) {
$query['include_attachments'] = 1;
}
if ($withHistory) {
$query['include_history'] = 1;
}
return false;
if (! isset($move_settings['credentials']['carrier']) || !
isset($move_settings['credentials']['token'])) {
$log->error('Credenciales de ZippinMove incompletas', ['bag_id'
=> $closedBag->id, 'move_settings' => $move_settings, 'crossdock_carrier'
=> $closedBag->crossdock?->carrier?->id]);
} else {
if ($check_existing_workflow) {
// Check if shipment has another workflow
if (Shipment\MoveWorkflow::where('shipment_id',
$shipment->id)->where(
'workflow_type', ZippinMove\
WorkflowBuilder::BLUEPRINT_SELLER_TO_CROSSDOCK
)->where('move_workflows_metadata->bag_id', $closedBag-
>id)->count()) {
$log->warning('Shipment ya tiene workflow seller-
to-xd en ZippinMove', ['bag_id' => $closedBag->id, 'shipment_id' =>
$shipment->id]);
$shipment_workflows['skipped'][] = $shipment->id;
continue;
}
}
$metadata = [
'bag_id' => $closedBag->id,
];
try {
$creation = $move->createWorkflow(ZippinMove\
WorkflowBuilder::BLUEPRINT_SELLER_TO_CROSSDOCK, $shipment, $metadata);
if ($creation->wasSuccessful()) {
$log->info('Workflow creado en ZippinMove',
['bag_id' => $closedBag->id, 'shipment_id' => $shipment->id, 'workflow_id'
=> $creation->getRelated('response')['workflow']['id']]);
$shipment_workflows['created'][$shipment->id] =
$creation->getRelated('response')['workflow']['id'];
} else {
$log->error('Error al crear workflow en ZippinMove:
'.$creation->getReason(), ['bag_id' => $closedBag->id, 'shipment_id' =>
$shipment->id, 'related' => $creation->getRelated()]);
$shipment_workflows['failed'][$shipment->id] =
$creation->getReason();
}
} catch (\Exception $e) {
$log->error('Error al crear workflow en ZippinMove: '.
$e->getMessage(), ['bag_id' => $closedBag->id, 'shipment_id' => $shipment-
>id, 'related' => $e]);
$shipment_workflows['failed'][$shipment->id] = $e-
>getMessage();
}
}
if (! count($shipment_workflows['created'])) {
return ActionResult::failure('No se crearon workflows');
} else {
return ActionResult::success('Workflows creados',
['shipment_workflows' => $shipment_workflows]);
}
}
}
if (! isset($move_settings['credentials']['carrier']) || !
isset($move_settings['credentials']['token'])) {
$log->error('Credenciales de ZippinMove incompletas', ['bag_id'
=> $closedBag->id, 'move_settings' => $move_settings, 'crossdock_carrier'
=> $closedBag->crossdock?->carrier?->id]);
} else {
if ($cancelResult->wasSuccessful()) {
$log->info('Workflow cancelado en ZippinMove',
['workflow_id' => $shipment_workflow->workflow_id, 'id' =>
$shipment_workflow->id]);
$shipment_workflows['cancel']
[$shipment_workflow->id] = $shipment_workflow->id;
} else {
$log->error('Error al cancelar workflow en
ZippinMove: '.$cancelResult->getReason(), ['workflow_id' =>
$shipment_workflow->workflow_id, 'id' => $shipment_workflow->id]);
}
} catch (\Exception $e) {
$log->error('Error al cancelar workflow en
ZippinMove: '.$e->getMessage(), ['workflow_id' => $shipment_workflow-
>workflow_id, 'id' => $shipment_workflow->id]);
}
}
}
if (! count($shipment_workflows['cancel'])) {
$log->info('No se cancelaron workflows');
} else {
$log->info('Workflows cancelados', ['shipment_workflows' =>
$shipment_workflows['cancel']]);
}
}
}
if (! isset($move_settings['credentials']['carrier']) || !
isset($move_settings['credentials']['token'])) {
$log->error('Credenciales de ZippinMove incompletas', ['bag_id'
=> $bag->id, 'move_settings' => $move_settings, 'crossdock_carrier' =>
$bag->crossdock?->carrier?->id]);
} else {
$updated_workflows = [];
if (! $shipment_workflows->count()) {
$log->warning('Shipment no tiene workflows seller-to-xd
o point-to-xd en ZippinMove', ['bag_id' => $bag->id, 'shipment_id' =>
$shipment->id]);
continue;
}
$body = [
'settings' => [
[
'step_name' => 'pickup',
'should_complete_after' => $shipment-
>recollectionBag->must_picked_at->midDay()-
>setTimezone(config('app.display_timezone'))->startOfDay()->utc()-
>format('Y-m-d H:i:s'),
'should_complete_before' => $shipment-
>recollectionBag->must_picked_at->midDay()-
>setTimezone(config('app.display_timezone'))->endOfDay()->utc()-
>format('Y-m-d H:i:s'),
],
[
'step_name' => 'deliver_to_crossdock',
'should_complete_after' => $shipment-
>recollectionBag->must_picked_at->midDay()-
>setTimezone(config('app.display_timezone'))->startOfDay()->utc()-
>format('Y-m-d H:i:s'),
'should_complete_before' => $shipment-
>recollectionBag->must_picked_at->midDay()-
>setTimezone(config('app.display_timezone'))->endOfDay()->utc()-
>format('Y-m-d H:i:s'),
],
]
];
if ($updateResult->wasSuccessful()) {
$log->info('Workflow actualizado en
ZippinMove', ['workflow_id' => $shipment_workflow->workflow_id, 'id' =>
$shipment_workflow->id]);
$updated_workflows[$shipment_workflow->id] =
$shipment_workflow->id;
} else {
$log->error('Error al actualizar workflow en
ZippinMove: '.$updateResult->getReason(), ['workflow_id' =>
$shipment_workflow->workflow_id, 'id' => $shipment_workflow->id]);
}
} catch (\Exception $e) {
$log->error('Error al actualizar workflow en
ZippinMove: '.$e->getMessage(), ['workflow_id' => $shipment_workflow-
>workflow_id, 'id' => $shipment_workflow->id]);
}
}
}
if (! count($updated_workflows)) {
$log->info('No se actualizaron workflows');
} else {
$log->info('Workflows actualizados', ['shipment_workflows'
=> $updated_workflows]);
}
}
}
}
app/Models/Shipment.php
public function origin()
{
return $this->hasOne(Address::class, 'id', 'origin_id');
}
app/Models/Address.php
public function address_book()
{
return $this->hasOne(AddressBook::class, 'id', 'address_book_id');
}
Comentarios:
cuando una adres tiene una relacion con adresbook
si el origin o destination tiene un adresbook asociado le concatena el nombre a delante
15:25
aacount_id del origen con el account_id del envio coincide