Skip to content

Commit

Permalink
Merge pull request #717 from amansinghbais/#704
Browse files Browse the repository at this point in the history
Improved: support for adding tracking details while packing (#704)
  • Loading branch information
ravilodhi authored Sep 2, 2024
2 parents 2200c32 + dbc8cd7 commit 9fbd03f
Show file tree
Hide file tree
Showing 6 changed files with 346 additions and 4 deletions.
283 changes: 283 additions & 0 deletions src/components/GenerateTrackingCodeModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
<template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button @click="closeModal">
<ion-icon slot="icon-only" :icon="closeOutline" />
</ion-button>
</ion-buttons>
<ion-title>{{ translate("Pack order") }}</ion-title>
</ion-toolbar>
</ion-header>

<ion-content>
<ion-list>
<ion-item lines="none">
<ion-label>{{ translate(isTrackingRequired ? "Tracking details are required in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually." : "Tracking details are missing in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually.") }}</ion-label>
</ion-item>

<ion-item>
<ion-select :disabled="!order.missingLabelImage" :label="translate('Carrier')" v-model="carrierPartyId" interface="popover" @ionChange="updateCarrier(carrierPartyId)">
<ion-select-option v-for="carrier in facilityCarriers" :key="carrier.partyId" :value="carrier.partyId">{{ translate(carrier.groupName) }}</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-select :disabled="!order.missingLabelImage" :label="translate('Method')" v-model="shipmentMethodTypeId" interface="popover">
<ion-select-option v-for="method in carrierMethods" :key="method.productStoreShipMethId" :value="method.shipmentMethodTypeId">{{ translate(method.description) }}</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-input :label="translate('Tracking code')" :placeholder="translate('enter code')" v-model="trackingCode" />
</ion-item>
<ion-item>
<ion-label>{{ translate("Tracking URL:", { trackingUrl: generateTrackingUrl() }) }}</ion-label>
<ion-button slot="end" fill="clear" size="default" :disabled="!trackingCode.trim() || !getCarrierTrackingUrl()" @click="redirectToTrackingUrl()">
{{ translate("Test") }}
<ion-icon :icon="openOutline" slot="end" />
</ion-button>
</ion-item>
</ion-list>
</ion-content>

<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button :disabled="isTrackingRequired ? !shipmentMethodTypeId: ''" @click="confirmSave()">
<ion-icon :icon="isForceScanEnabled ? barcodeOutline : saveOutline" />
</ion-fab-button>
</ion-fab>
</template>

<script lang="ts">
import {
IonButton,
IonButtons,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonInput,
IonItem,
IonLabel,
IonList,
IonSelect,
IonSelectOption,
IonTitle,
IonToolbar,
modalController,
} from "@ionic/vue";
import { defineComponent } from "vue";
import { barcodeOutline, closeOutline, copyOutline, openOutline, saveOutline } from "ionicons/icons";
import { translate } from "@hotwax/dxp-components";
import { mapGetters, useStore } from "vuex";
import { OrderService } from '@/services/OrderService';
import logger from "@/logger";
import { showToast } from "@/utils";
import { hasError } from "@/adapter";
export default defineComponent({
name: "GenerateTrackingCodeModal",
components: {
IonButton,
IonButtons,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonInput,
IonItem,
IonLabel,
IonList,
IonSelect,
IonSelectOption,
IonTitle,
IonToolbar,
},
computed: {
...mapGetters({
facilityCarriers: 'carrier/getFacilityCarriers',
isForceScanEnabled: 'util/isForceScanEnabled',
productStoreShipmentMethods: 'carrier/getProductStoreShipmentMethods',
productStoreShipmentMethCount: 'util/getProductStoreShipmentMethCount',
})
},
data() {
return {
isTrackingRequired: false,
carrierMethods:[] as any,
carrierPartyId: "",
shipmentMethodTypeId: "",
trackingCode: "",
isGeneratingShippingLabel: false
}
},
props: ["order", "updateCarrierShipmentDetails"],
async mounted() {
this.isTrackingRequired = this.isTrackingRequiredForAnyShipmentPackage()
if(this.facilityCarriers) {
const shipmentPackage = this.order.shipmentPackages?.[0];
this.carrierPartyId = shipmentPackage?.carrierPartyId ? shipmentPackage?.carrierPartyId : this.facilityCarriers[0].partyId;
this.carrierMethods = await this.getProductStoreShipmentMethods(this.carrierPartyId);
this.shipmentMethodTypeId = shipmentPackage?.shipmentMethodTypeId;
}
},
methods: {
closeModal(payload = {}) {
modalController.dismiss({ dismissed: true, ...payload });
},
isTrackingRequiredForAnyShipmentPackage() {
return this.order.shipmentPackages?.some((shipmentPackage: any) => shipmentPackage.isTrackingRequired === 'Y')
},
async getProductStoreShipmentMethods(carrierPartyId: string) {
return this.productStoreShipmentMethods?.filter((method: any) => method.partyId === carrierPartyId) || [];
},
async updateCarrier(carrierPartyId: string) {
this.carrierMethods = await this.getProductStoreShipmentMethods(carrierPartyId);
this.shipmentMethodTypeId = this.carrierMethods?.[0]?.shipmentMethodTypeId;
},
async confirmSave() {
let order = this.order
let isRegenerated = false as any;
// if the request to print shipping label is not yet completed, then clicking multiple times on the button
// should not do anything
if(this.isGeneratingShippingLabel) {
return;
}
this.isGeneratingShippingLabel = true;
const isUpdated = await this.updateCarrierAndShippingMethod(this.carrierPartyId, this.shipmentMethodTypeId)
if(!isUpdated) {
showToast(translate("Failed to update shipment method detail."));
return;
}
if(this.trackingCode.trim()) {
isRegenerated = await this.addTrackingCode(order);
} else if(this.shipmentMethodTypeId) {
isRegenerated = await this.regenerateShippingLabel(order)
}
//fetching updated shipment packages
await this.store.dispatch('order/updateShipmentPackageDetail', order)
if(isRegenerated || !this.isTrackingRequired) {
this.closeModal({ moveToNext: true });
}
this.isGeneratingShippingLabel = false;
},
async addTrackingCode(order: any) {
try {
for (const shipmentPackage of order.shipmentPackages) {
await OrderService.addTrackingCode({
"shipmentId": shipmentPackage.shipmentId,
"shipmentRouteSegmentId": shipmentPackage.shipmentRouteSegmentId,
"shipmentPackageSeqId": shipmentPackage.shipmentPackageSeqId,
"trackingCode": this.trackingCode.trim()
});
}
} catch (error: any) {
logger.error('Failed to add tracking code', error);
showToast(translate("Failed to add tracking code."));
return false;
}
return true;
},
async regenerateShippingLabel(order: any) {
// If there are no product store shipment method configured, then not generating the label and displaying an error toast
if(this.productStoreShipmentMethCount <= 0) {
showToast(translate("Unable to generate shipping label due to missing product store shipping method configuration"))
return false;
}
// Getting all the shipmentIds from shipmentPackages for which label is missing
const shipmentIds = order.shipmentPackages
?.filter((shipmentPackage: any) => !shipmentPackage.trackingCode)
.map((shipmentPackage: any) => shipmentPackage.shipmentId);
if(!shipmentIds?.length) {
showToast(translate("Failed to generate shipping label"))
return false;
}
try {
const resp = await OrderService.retryShippingLabel(shipmentIds)
if(hasError(resp)) {
throw resp.data;
}
} catch(error: any) {
logger.error(error);
showToast(translate("Failed to generate shipping label"))
return false;
}
return true;
},
getCarrierTrackingUrl() {
return this.facilityCarriers.find((carrier: any) => carrier.partyId === this.carrierPartyId)?.trackingUrl
},
generateTrackingUrl() {
if(this.getCarrierTrackingUrl()) {
return this.getCarrierTrackingUrl()?.replace("${trackingNumber}", this.trackingCode)
}
return translate("A tracking URL not configured for", { carrierName: this.getCarrierName() })
},
getCarrierName() {
return this.facilityCarriers.find((carrier: any) => carrier.partyId === this.carrierPartyId)?.groupName
},
async updateCarrierAndShippingMethod(carrierPartyId: string, shipmentMethodTypeId: string) {
let resp;
try{
const carrierShipmentMethods = await this.getProductStoreShipmentMethods(carrierPartyId);
shipmentMethodTypeId = shipmentMethodTypeId ? shipmentMethodTypeId : carrierShipmentMethods?.[0]?.shipmentMethodTypeId;
const params = {
orderId: this.order.orderId,
shipGroupSeqId: this.order.shipGroupSeqId,
shipmentMethodTypeId : shipmentMethodTypeId ? shipmentMethodTypeId : "",
carrierPartyId
}
resp = await OrderService.updateOrderItemShipGroup(params)
if(!hasError(resp)) {
for (const shipmentPackage of this.order.shipmentPackages) {
resp = await OrderService.updateShipmentRouteSegment({
"shipmentId": shipmentPackage.shipmentId,
"shipmentRouteSegmentId": shipmentPackage.shipmentRouteSegmentId,
"carrierPartyId": carrierPartyId,
"shipmentMethodTypeId" : shipmentMethodTypeId ? shipmentMethodTypeId : "",
}) as any;
if(hasError(resp)) {
throw resp.data;
}
}
} else {
throw resp.data;
}
} catch(error: any) {
logger.error("Failed to update carrier and method", error);
return false;
}
this.updateCarrierShipmentDetails && this.updateCarrierShipmentDetails(carrierPartyId, shipmentMethodTypeId);
return true;
},
redirectToTrackingUrl() {
window.open(this.getCarrierTrackingUrl().replace("${trackingNumber}", this.trackingCode), "_blank");
}
},
setup() {
const store = useStore();
return {
barcodeOutline,
closeOutline,
copyOutline,
openOutline,
saveOutline,
store,
translate
};
},
});
</script>
7 changes: 7 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"Are you sure you want to reject in progress order(s)?": "Are you sure you want to reject { ordersCount } in progress order(s)?",
"Are you sure you want to update box selection?": "Are you sure you want to update box selection?",
"Assign Pickers": "Assign Pickers",
"A tracking URL not configured for": "A tracking URL not configured for {carrierName}",
"Auto reject related items": "Auto reject related items",
"Back to Launchpad": "Back to Launchpad",
"Billing Address 1": "Billing Address 1",
Expand Down Expand Up @@ -142,6 +143,7 @@
"Edit Pickers": "Edit Pickers",
"Edit sequence": "Edit sequence",
"Email": "Email",
"enter code": "enter code",
"Enter key": "Enter key",
"Enter mapping name": "Enter mapping name",
"Enter tracking details for shipping labels generated outside of the fulfillment app. This tracking code will be shared with customers when you complete the fulfillment of the order.": "Enter tracking details for shipping labels generated outside of the fulfillment app. This tracking code will be shared with customers when you complete the fulfillment of the order.",
Expand Down Expand Up @@ -170,6 +172,7 @@
"Facilities": "Facilities",
"Failed to activate gift card.": "Failed to activate gift card.",
"Failed to add box": "Failed to add box",
"Failed to add tracking code.": "Failed to add tracking code.",
"Failed to create picklist for orders": "Failed to create picklist for orders",
"Failed to create rejection reason.": "Failed to create rejection reason.",
"Failed to delete CSV mapping.": "Failed to delete CSV mapping.",
Expand Down Expand Up @@ -537,6 +540,7 @@
"Store pickup": "Store pickup",
"Store Pickup": "Store Pickup",
"STAY": "STAY",
"Test": "Test",
"Test tracking url": "Test tracking url",
"The import orders has been uploaded successfully": "The import orders has been uploaded successfully",
"The picked quantity cannot exceed the ordered quantity.": "The picked quantity cannot exceed the ordered quantity.",
Expand All @@ -558,7 +562,10 @@
"Tracking code added successfully.": "Tracking code added successfully.",
"Tracking Code": "Tracking Code",
"Tracking code settings updated successfully.": "Tracking code settings updated successfully.",
"Tracking details are missing in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually.": "Tracking details are missing in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually.",
"Tracking details are required in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually.": "Tracking details are required in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually.",
"Tracking ID": "Tracking ID",
"Tracking URL:": "Tracking URL: {trackingUrl}",
"Tracking url is not configured for following carrier.": "Tracking url is not configured for following carrier.",
"Transfer Orders": "Transfer Orders",
"Transfer Order Details": "Transfer Order Details",
Expand Down
7 changes: 7 additions & 0 deletions src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"Are you sure you want to reject in progress order(s)?": "¿Estás seguro/a de que quieres rechazar { ordersCount } pedido(s) en curso?",
"Are you sure you want to update box selection?": "¿Está seguro de que desea actualizar la selección del cuadro?",
"Assign Pickers": "Asignar Recolectores",
"A tracking URL not configured for": "A tracking URL not configured for {carrierName}",
"Auto reject related items": "Auto reject related items",
"Back to Launchpad": "Volver a Launchpad",
"Billing Address 1": "Dirección de Facturación 1",
Expand Down Expand Up @@ -140,6 +141,7 @@
"Edit Pickers": "Editar recolectores",
"Edit sequence": "Edit sequence",
"Email": "Correo Electrónico",
"enter code": "enter code",
"Enter key": "Ingresar clave",
"Enter mapping name": "Insertar nombre de mapeo",
"Enter tracking details for shipping labels generated outside of the fulfillment app. This tracking code will be shared with customers when you complete the fulfillment of the order.": "Enter tracking details for shipping labels generated outside of the fulfillment app. This tracking code will be shared with customers when you complete the fulfillment of the order.",
Expand Down Expand Up @@ -168,6 +170,7 @@
"Facilities": "Facilities",
"Failed to activate gift card.": "Failed to activate gift card.",
"Failed to add box": "Error al agregar la caja",
"Failed to add tracking code.": "Failed to add tracking code.",
"Failed to create picklist for orders": "Error al crear la lista de selección para los pedidos",
"Failed to create rejection reason.": "Failed to create rejection reason.",
"Failed to delete CSV mapping.": "Intento fallido de envio de mapeo de CSV",
Expand Down Expand Up @@ -534,6 +537,7 @@
"Store": "Tienda",
"Store pickup": "Recoger en tienda",
"Store Pickup": "Recoger en tienda",
"Test": "Test",
"Test tracking url": "Test tracking url",
"The import orders has been uploaded successfully": "Los pedidos de importación se han cargado exitosamente",
"The picked quantity cannot exceed the ordered quantity.": "La cantidad seleccionada no puede exceder la cantidad pedida.",
Expand All @@ -555,7 +559,10 @@
"Tracking code added successfully.": "Tracking code added successfully.",
"Tracking Code": "Código de Seguimiento",
"Tracking code settings updated successfully.": "Tracking code settings updated successfully.",
"Tracking details are missing in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually.": "Tracking details are missing in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually.",
"Tracking details are required in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually.": "Tracking details are required in order to pack this shipment. Try generating a label from the selected carrier or enter a tracking code manually.",
"Tracking ID": "ID de Seguimiento",
"Tracking URL:": "Tracking URL: {trackingUrl}",
"Tracking url is not configured for following carrier.": "Tracking url is not configured for following carrier.",
"Transfer Orders": "Transferir Ordenes",
"Transfer Order Details": "Transferir los Detalles del Pedido",
Expand Down
Loading

0 comments on commit 9fbd03f

Please sign in to comment.