Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented product identifier using dxp-components. #181

Closed
wants to merge 8 commits into from
506 changes: 295 additions & 211 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@capacitor/ios": "^2.5.0",
"@hotwax/app-version-info": "^1.0.0",
"@hotwax/apps-theme": "^1.2.3",
"@hotwax/dxp-components": "^1.3.4",
"@hotwax/oms-api": "^1.6.0",
"@ionic/core": "6.7.5",
"@ionic/vue": "6.7.5",
Expand Down
32 changes: 30 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
IonSplitPane
} from "@ionic/vue";
import Menu from '@/components/Menu.vue';
import { defineComponent } from "vue";
import { defineComponent, provide, ref } from "vue";
import { useI18n } from 'vue-i18n'
import TaskQueue from './task-queue';
import OfflineHelper from "./offline-helper"
Expand All @@ -24,6 +24,7 @@ import { mapGetters, useStore } from 'vuex';
import { Settings } from 'luxon'
import { initialise, resetConfig } from '@/adapter'
import { useRouter } from 'vue-router';
import { useProductIdentificationStore } from "@hotwax/dxp-components";

export default defineComponent({
name: "App",
Expand All @@ -43,7 +44,8 @@ export default defineComponent({
...mapGetters({
userProfile: 'user/getUserProfile',
userToken: 'user/getUserToken',
instanceUrl: 'user/getInstanceUrl'
instanceUrl: 'user/getInstanceUrl',
currentEComStore: 'user/getCurrentEComStore'
})
},
methods: {
Expand Down Expand Up @@ -99,6 +101,12 @@ export default defineComponent({
if (this.userProfile && this.userProfile.userTimeZone) {
Settings.defaultZone = this.userProfile.userTimeZone;
}

// Get product identification from api using dxp-component and set the state if eComStore is defined
if (this.currentEComStore.productStoreId) {
await useProductIdentificationStore().getIdentificationPref(this.currentEComStore.productStoreId)
.catch((error) => console.error(error));
}
},
unmounted() {
emitter.off('presentLoader', this.presentLoader);
Expand All @@ -111,6 +119,26 @@ export default defineComponent({
OfflineHelper.register();
const { t, locale } = useI18n();
const router = useRouter();

/* Start Product Identifier */

const productIdentificationStore = useProductIdentificationStore();

// Reactive state for productIdentificationPref
let productIdentificationPref = ref(
productIdentificationStore.$state.productIdentificationPref
);

// Providing productIdentificationPref to child components
provide('productIdentificationPref', productIdentificationPref);

// Subscribing to productIdentificationStore state change and changing value productIdentificationPref
productIdentificationStore.$subscribe((mutation: any, state) => {
productIdentificationPref.value = state.productIdentificationPref;
});

/* End Product Identifier */

return {
router,
TaskQueue,
Expand Down
10 changes: 8 additions & 2 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"Added to at": "Added to {categoryName} at {addedDateTime}",
"Active jobs": "Active jobs",
"Active purchase order": "Active purchase order",
"Added to pre-order category on, against PO but not listed on all stores" : "Added to pre-order category on {fromDate}, against PO #{POID} but not listed on all stores",
"Added to pre-order category on, against PO but not listed on all stores": "Added to pre-order category on {fromDate}, against PO #{POID} but not listed on all stores",
"Adding to in": "Adding to {categoryName} in {addingTime}",
"All": "All",
"App": "App",
Expand All @@ -30,6 +30,7 @@
"Category and brokering jobs": "Category and brokering jobs",
"Change": "Change",
"Change time zone": "Change time zone",
"Choosing a product identifier allows you to view products with your preferred identifiers.": "Choosing a product identifier allows you to view products with your preferred identifiers.",
"Click the backdrop to dismiss.": "Click the backdrop to dismiss.",
"Color": "Color",
"Colors": "Colors",
Expand Down Expand Up @@ -139,10 +140,13 @@
"preorders will be automatically brokered and assigned for fulfillment.": "{count} preorders will be automatically brokered and assigned for fulfillment.",
"preorder items will be released to the warehouse you have selected.": "{count} preorder items will be released to the warehouse you have selected.",
"preorders will be cancelled. This action cannot be undone.": "{count} preorders will be cancelled. This action cannot be undone.",
"primary identifier": "primary identifier",
"Primary Product Identifier": "Primary Product Identifier",
"Products": "Products",
"Product details": "Product details",
"Product cannot be pre-sold because it does not have active purchase orders": "Product cannot be pre-sold because it does not have active purchase orders",
"Product has been accepting from against PO #": "Product has been accepting {category}s from {fromDate} against PO #${POID}",
"Product Identifier": "Product Identifier",
"Product is eligible for but not added to the category": "Product is eligible for {category}s but not added to the {category} category",
"Product is currently in stock and cannot accept": "Product is currently in stock and cannot accept {category}s",
"Product has no active purchase order to be eligible for accepting": "Product has no active purchase order to be eligible for accepting {category}s",
Expand Down Expand Up @@ -170,6 +174,8 @@
"Search products": "Search products",
"Search time zones": "Search time zones",
"Search warehouses": "Search warehouses",
"secondary identifier": "secondary identifier",
"Secondary Product Identifier": "Secondary Product Identifier",
"select": "select",
"Select date": "Select date",
"Select item": "Select item",
Expand Down Expand Up @@ -226,4 +232,4 @@
"With Hold Pre-order Queue Physical Inventory disabled, the excess inventory is now available for sale online after deducting the queues": "With Hold Pre-order Queue Physical Inventory disabled, the excess inventory is now available for sale online after deducting the queues",
"Would you like to update your time zone to . Your profile is currently set to . This setting can always be changed from the settings menu.": "Would you like to update your time zone to {localTimeZone}. Your profile is currently set to {profileTimeZone}. This setting can always be changed from the settings menu.",
"Yes": "Yes"
}
}
27 changes: 17 additions & 10 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,26 @@ import '@ionic/vue/css/display.css';

/* Theme variables */
import './theme/variables.css';
import { dxpComponents } from '@hotwax/dxp-components';
import { setProductIdentificationPref, getProductIdentificationPref } from '@hotwax/oms-api';

const app = createApp(App)
.use(IonicVue, {
mode: 'md'
})
.use(router)
.use(i18n)
.use(store);

.use(store)
.use(dxpComponents, {
defaultImgUrl: require("@/assets/images/defaultImage.png"),
setProductIdentificationPref,
getProductIdentificationPref
});

// Filters are removed in Vue 3 and global filter introduced https://v3.vuejs.org/guide/migration/filters.html#global-filters
app.config.globalProperties.$filters = {
formatDate(value: any, inFormat?: string, outFormat = 'MM-dd-yyyy') {
if(inFormat){
if (inFormat) {
return DateTime.fromFormat(value, inFormat).toFormat(outFormat);
}
return DateTime.fromISO(value).toFormat(outFormat);
Expand All @@ -53,7 +60,7 @@ app.config.globalProperties.$filters = {
return DateTime.fromISO(value, { zone: 'utc' }).setZone(userProfile.userTimeZone).toFormat(outFormat ? outFormat : 'MM-dd-yyyy')
},
getOrderIdentificationId(identifications: any, id: string) {
let externalId = ''
let externalId = ''
if (identifications) {
const externalIdentification = identifications.find((identification: any) => identification.startsWith(id))
const externalIdentificationSplit = externalIdentification ? externalIdentification.split('/') : [];
Expand All @@ -62,7 +69,7 @@ app.config.globalProperties.$filters = {
return externalId;
},
getFeature(featureHierarchy: any, featureKey: string) {
let featureValue = ''
let featureValue = ''
if (featureHierarchy) {
const feature = featureHierarchy.find((featureItem: any) => featureItem.startsWith(featureKey))
const featureSplit = feature ? feature.split('/') : [];
Expand All @@ -76,7 +83,7 @@ app.config.globalProperties.$filters = {
const featureSplit = feature.split('/');
if (featureSplit[1] && featureSplit[2]) {
filteredFeatures[featureSplit[1]] ? filteredFeatures[featureSplit[1]].push(featureSplit[2]) : filteredFeatures[featureSplit[1]] = [featureSplit[2]]
}
}
return filteredFeatures;
}, {});
const sortedFeatures = {} as any;
Expand Down Expand Up @@ -109,12 +116,12 @@ app.config.globalProperties.$filters = {
return featureKey === '1/SIZE/' ? sortSizes(featuresList) : featuresList;
},
getCustomerLoyalty(orderNotes: any, cusotmerLoyaltyOptions: any) {
let customerLoyalty = '' as any
let customerLoyalty = '' as any
if (orderNotes && cusotmerLoyaltyOptions) {
for (const customerLoyaltyOption of Object.entries(cusotmerLoyaltyOptions)) {
if (orderNotes.includes(customerLoyaltyOption[0])) {
customerLoyalty = customerLoyaltyOption[1];
}
if (orderNotes.includes(customerLoyaltyOption[0])) {
customerLoyalty = customerLoyaltyOption[1];
}
}
}
return customerLoyalty;
Expand Down
13 changes: 13 additions & 0 deletions src/store/modules/user/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { hasError, showToast } from '@/utils'
import { translate } from '@/i18n'
import { Settings } from 'luxon'
import { updateInstanceUrl, updateToken, resetConfig } from '@/adapter'
import { useProductIdentificationStore } from '@hotwax/dxp-components'

const actions: ActionTree<UserState, RootState> = {

Expand Down Expand Up @@ -127,6 +128,12 @@ const actions: ActionTree<UserState, RootState> = {
}
commit(types.USER_CURRENT_ECOM_STORE_UPDATED, userPrefStore);
commit(types.USER_INFO_UPDATED, userProfile);

// Get product identification from api using dxp-component and set the state if eComStore is defined
if(userPrefStore.productStoreId){
await useProductIdentificationStore().getIdentificationPref(userPrefStore.productStoreId)
.catch((error) => console.error(error));
}
}
},

Expand Down Expand Up @@ -156,6 +163,12 @@ const actions: ActionTree<UserState, RootState> = {
'userPrefTypeId': 'SELECTED_BRAND',
'userPrefValue': payload.eComStore.productStoreId
});

// Get product identification from api using dxp-component and set the state if eComStore is defined
if(payload.eComStore.productStoreId){
await useProductIdentificationStore().getIdentificationPref(payload.eComStore.productStoreId)
.catch((error) => console.error(error));
}
},

/**
Expand Down
43 changes: 32 additions & 11 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@ import { DateTime } from "luxon";

// TODO Remove it when HC APIs are fully REST compliant
const hasError = (response: any) => {
return typeof response.data != "object" || !!response.data._ERROR_MESSAGE_ || !!response.data._ERROR_MESSAGE_LIST_ || !!response.data.error;
return typeof response.data != "object" || !!response.data._ERROR_MESSAGE_ || !!response.data._ERROR_MESSAGE_LIST_ || !!response.data.error;
}

const showToast = async (message: string) => {
const toast = await toastController
.create({
message,
duration: 3000,
position: 'bottom',
})
return toast.present();
const toast = await toastController
.create({
message,
duration: 3000,
position: 'bottom',
})
return toast.present();
}
const handleDateTimeInput = (dateTimeValue: any) => {
// TODO Handle it in a better way
// Remove timezone and then convert to timestamp
// Current date time picker picks browser timezone and there is no supprt to change it
const dateTime = DateTime.fromISO(dateTimeValue, { setZone: true}).toFormat("yyyy-MM-dd'T'HH:mm:ss")
const dateTime = DateTime.fromISO(dateTimeValue, { setZone: true }).toFormat("yyyy-MM-dd'T'HH:mm:ss")
return DateTime.fromISO(dateTime).toMillis()
}

const getFeature = (featureHierarchy: any, featureKey: string) => {
let featureValue = ''
let featureValue = ''
if (featureHierarchy) {
const feature = featureHierarchy.find((featureItem: any) => featureItem.startsWith(featureKey))
const featureSplit = feature ? feature.split('/') : [];
Expand All @@ -34,4 +34,25 @@ const getFeature = (featureHierarchy: any, featureKey: string) => {
return featureValue;
}

export { handleDateTimeInput, showToast, hasError, getFeature }
const getProductIdentificationValue = (productIdentifier: string, product: any) => {

// handled this case as on page load initially the data is not available, so not to execute furthur code
// untill product are not available
if (!Object.keys(product).length) {
return;
}

let value = product[productIdentifier]

// considered that the goodIdentification will always have values in the format "productIdentifier/value" and there will be no entry like "productIdentifier/"
const identification = product['goodIdentifications'].find((identification: string) => identification.startsWith(productIdentifier + "/"))

if (identification) {
const goodIdentification = identification.split('/')
value = goodIdentification[1]
}

return value;
}

export { handleDateTimeInput, showToast, hasError, getFeature, getProductIdentificationValue }
16 changes: 11 additions & 5 deletions src/views/catalog-product-details.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

<div class="product-info" v-if="Object.keys(currentVariant).length">
<div class="ion-padding">
<h4>{{ currentVariant.parentProductName }}</h4>
<p>{{ currentVariant.sku }}</p>
<h4>{{ getProductIdentificationValue(productIdentificationPref.primaryId, currentVariant) }}</h4>
<p>{{ getProductIdentificationValue(productIdentificationPref.secondaryId, currentVariant) }}</p>
</div>

<div class="product-features">
Expand Down Expand Up @@ -404,7 +404,7 @@ import {
IonRow,
popoverController,
} from "@ionic/vue";
import { defineComponent } from "vue";
import { defineComponent, inject } from "vue";
import {
alertCircleOutline,
checkmarkCircleOutline,
Expand All @@ -414,7 +414,7 @@ import {
import { useStore } from "@/store";
import Image from '@/components/Image.vue';
import { mapGetters } from "vuex";
import { showToast, getFeature, hasError } from "@/utils";
import { showToast, getFeature, hasError, getProductIdentificationValue } from "@/utils";
import { translate } from "@/i18n";
import { sortSizes } from '@/apparel-sorter';
import { DateTime } from "luxon";
Expand Down Expand Up @@ -1072,13 +1072,19 @@ export default defineComponent({
setup() {
const store = useStore();
const router = useRouter();

// Injecting identifier preference from app.view
const productIdentificationPref: any = inject("productIdentificationPref");

return {
alertCircleOutline,
checkmarkCircleOutline,
chevronForwardOutline,
router,
shirtOutline,
store
store,
productIdentificationPref,
getProductIdentificationValue
};
},
});
Expand Down
13 changes: 9 additions & 4 deletions src/views/catalog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
<Image :src="product.mainImageUrl" />
</ion-thumbnail>
<ion-label class="ion-text-wrap">
<h5>{{ product.parentProductName }}</h5>
<p>{{ product.sku }}</p>
<h5>{{ getProductIdentificationValue(productIdentificationPref.primaryId, product) }}</h5>
<p>{{ getProductIdentificationValue(productIdentificationPref.secondaryId, product) }}</p>
</ion-label>
</ion-item>

Expand Down Expand Up @@ -106,14 +106,14 @@ import {
IonTitle,
IonToolbar,
} from '@ionic/vue';
import { defineComponent } from 'vue';
import { defineComponent, inject } from 'vue';
import { useRouter } from "vue-router";
import { useStore } from "@/store";
import Image from '@/components/Image.vue';
import { mapGetters } from 'vuex';
import { DateTime } from 'luxon';
import { JobService } from '@/services/JobService';
import { hasError } from '@/utils';
import { hasError, getProductIdentificationValue } from '@/utils';

export default defineComponent({
name: 'Catalog',
Expand Down Expand Up @@ -270,9 +270,14 @@ export default defineComponent({
const router = useRouter();
const store = useStore();

// Injecting identifier preference from app.view
const productIdentificationPref: any = inject("productIdentificationPref");

return {
router,
store,
productIdentificationPref,
getProductIdentificationValue
};
},
});
Expand Down
Loading
Loading