Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/hotwax/bopis into bopis/#358
Browse files Browse the repository at this point in the history
  • Loading branch information
amansinghbais committed Jun 13, 2024
2 parents a9d5da5 + c2e17f2 commit d44c387
Show file tree
Hide file tree
Showing 47 changed files with 944 additions and 805 deletions.
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
VUE_APP_I18N_LOCALE=en
VUE_APP_I18N_FALLBACK_LOCALE=en
VUE_APP_I18N_LOCALE=en-US
VUE_APP_I18N_FALLBACK_LOCALE=en-US
VUE_APP_CACHE_MAX_AGE=3600
VUE_APP_VIEW_SIZE=30
VUE_APP_UNFILLABLE_REASONS=[{"id": "NO_VARIANCE_LOG", "label": "No reason"}, {"id": "NOT_IN_STOCK", "label": "Not in stock"}]
Expand Down
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
### Related Issues
<!-- Put related issue number which this PR is closing. For example #123 -->

Closes #
#

### Short Description and Why It's Useful
<!-- Describe in a few words what is this Pull Request changing and why it's useful -->
Expand Down
329 changes: 133 additions & 196 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bopis",
"version": "2.20.0",
"version": "2.23.0",
"private": true,
"description": "HotWax BOPIS app",
"scripts": {
Expand All @@ -16,12 +16,12 @@
"@capacitor/ios": "^2.5.0",
"@casl/ability": "^6.0.0",
"@hotwax/app-version-info": "^1.0.0",
"@hotwax/apps-theme": "^1.1.0",
"@hotwax/dxp-components": "^1.11.0",
"@hotwax/oms-api": "^1.11.0",
"@ionic/core": "6.7.5",
"@ionic/vue": "6.7.5",
"@ionic/vue-router": "6.7.5",
"@hotwax/apps-theme": "^1.2.6",
"@hotwax/dxp-components": "^1.13.0",
"@hotwax/oms-api": "^1.14.0",
"@ionic/core": "^7.6.0",
"@ionic/vue": "^7.6.0",
"@ionic/vue-router": "^7.6.0",
"@shopify/app-bridge-utils": "^2.0.4",
"boon-js": "^2.0.3",
"core-js": "^3.6.5",
Expand Down
8 changes: 6 additions & 2 deletions src/adapter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import {
subscribeTopic,
unsubscribeTopic,
updateInstanceUrl,
updateToken
updateToken,
getAvailableTimeZones,
setUserTimeZone
} from '@hotwax/oms-api'

export {
Expand All @@ -43,5 +45,7 @@ export {
subscribeTopic,
unsubscribeTopic,
updateInstanceUrl,
updateToken
updateToken,
getAvailableTimeZones,
setUserTimeZone
}
29 changes: 17 additions & 12 deletions src/components/EditPickerModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
<div v-else>
<ion-radio-group :value="selectedPicker.id">
<ion-item v-for="(picker, index) in availablePickers" :key="index" @click="updateSelectedPicker(picker.id)">
<ion-label>
{{ picker.name }}
<p>{{ picker.id }}</p>
</ion-label>
<ion-radio slot="end" :value="picker.id" ></ion-radio>
<ion-radio :value="picker.id">
<ion-label>
{{ picker.name }}
<p>{{ picker.id }}</p>
</ion-label>
</ion-radio>
</ion-item>
</ion-radio-group>
</div>
Expand All @@ -43,19 +44,19 @@ import {
IonButtons,
IonButton,
IonContent,
IonHeader,
IonIcon,
IonFab,
IonFabButton,
IonTitle,
IonToolbar,
IonLabel,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonRadio,
IonRadioGroup,
IonSearchbar,
IonTitle,
IonToolbar,
alertController,
modalController
} from "@ionic/vue";
Expand Down Expand Up @@ -124,6 +125,10 @@ export default defineComponent({
partyId_op: 'contains',
partyId_ic: 'Y',
partyId_grp: '3',
groupName_value: this.queryString,
groupName_op: 'contains',
groupName_ic: 'Y',
groupName_grp: '4'
}
}
Expand All @@ -138,14 +143,14 @@ export default defineComponent({
orderBy: "firstName ASC",
filterByDate: "Y",
distinct: "Y",
fieldList: ["firstName", "lastName", "partyId"]
fieldList: ["firstName", "lastName", "partyId", "groupName"]
}
try {
const resp = await PicklistService.getAvailablePickers(payload);
if (resp.status === 200 && !hasError(resp)) {
this.availablePickers = resp.data.docs.map((picker: any) => ({
name: picker.firstName + ' ' + picker.lastName,
name: picker.groupName ? picker.groupName : `${picker.firstName} ${picker.lastName}`,
id: picker.partyId
}))
} else {
Expand Down
79 changes: 79 additions & 0 deletions src/components/InventoryDetailsPopover.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<template>
<ion-content>
<ion-list>
<ion-list-header>{{ translate("Inventory computation")}}</ion-list-header>
<ion-item>
<ion-label class="ion-text-wrap">{{ translate("Quantity on hand")}}</ion-label>
<ion-note slot="end">{{ getProductStock(item.productId).quantityOnHandTotal ?? '0' }}</ion-note>
</ion-item>
<ion-item>
<ion-label class="ion-text-wrap">{{ translate("Safety stock")}}</ion-label>
<ion-note slot="end">{{ getInventoryInformation(item.productId).minimumStock ?? '0' }}</ion-note>
</ion-item>
<ion-item>
<ion-label class="ion-text-wrap">{{ translate("Order reservations")}}</ion-label>
<ion-note slot="end">{{ getInventoryInformation(item.productId).reservedQuantity ?? '0' }}</ion-note>
</ion-item>
<ion-item lines="none">
<ion-label class="ion-text-wrap">{{ translate("Online ATP")}}</ion-label>
<ion-badge slot="end" color="success">{{ getInventoryInformation(item.productId).onlineAtp ?? '0' }}</ion-badge>
</ion-item>
</ion-list>
</ion-content>
</template>

<script lang="ts">
import {
IonBadge,
IonContent,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonNote
} from '@ionic/vue'
import { defineComponent } from 'vue';
import { useStore, mapGetters } from 'vuex';
import { translate } from '@hotwax/dxp-components';
export default defineComponent({
name: 'InventoryDetailsPopover',
components:{
IonBadge,
IonContent,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonNote,
},
props: ['item'],
computed: {
...mapGetters({
product: "product/getCurrent",
getProductStock: 'stock/getProductStock',
getInventoryInformation: 'stock/getInventoryInformation',
currentFacility: 'user/getCurrentFacility',
})
},
async beforeMount () {
const productId = this.item?.productId;
await this.store.dispatch('stock/fetchInventoryCount', { productId });
this.fetchReservedQuantity( this.item.productId );
},
methods: {
async fetchReservedQuantity(productId: any){
await this.store.dispatch('stock/fetchReservedQuantity', { productId });
},
},
setup () {
const store = useStore();
return {
store,
translate
}
}
})
</script>
5 changes: 1 addition & 4 deletions src/components/NotificationPreferenceModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
</div>
<ion-list v-else>
<ion-item :key="pref.enumId" v-for="pref in notificationPrefs">
<ion-label class="ion-text-wrap">{{ pref.description }}</ion-label>
<ion-toggle @click="toggleNotificationPref(pref.enumId, $event)" :checked="pref.isEnabled" slot="end" />
<ion-toggle label-placement="start" @click="toggleNotificationPref(pref.enumId, $event)" :checked="pref.isEnabled">{{ pref.description }}</ion-toggle>
</ion-item>
</ion-list>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
Expand All @@ -38,7 +37,6 @@ import {
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonTitle,
IonToggle,
Expand Down Expand Up @@ -67,7 +65,6 @@ export default defineComponent({
IonFabButton,
IonIcon,
IonItem,
IonLabel,
IonList,
IonTitle,
IonToggle,
Expand Down
2 changes: 1 addition & 1 deletion src/components/OrderItemRejHistoryModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<ion-list>
<ion-item v-for="(item, index) in orderRejectionHistory" :key="index">
<ion-thumbnail slot="start">
<ShopifyImg :src="getProduct(item.productId).mainImageUrl" size="small" />
<DxpShopifyImg :src="getProduct(item.productId).mainImageUrl" size="small" />
</ion-thumbnail>
<ion-label>
<h2>{{ getProductIdentificationValue(productIdentificationPref.primaryId, getProduct(item.productId)) }}</h2>
Expand Down
60 changes: 38 additions & 22 deletions src/components/ProductListItem.vue
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
<template>
<ion-item lines="none">
<ion-thumbnail slot="start">
<ShopifyImg :src="getProduct(item.productId).mainImageUrl" size="small" />
<DxpShopifyImg :src="getProduct(item.productId).mainImageUrl" size="small" />
</ion-thumbnail>
<ion-label class="ion-text-wrap">
<h2>{{ getProductIdentificationValue(productIdentificationPref.primaryId, getProduct(item.productId)) }}</h2>
<p class="ion-text-wrap">{{ getProductIdentificationValue(productIdentificationPref.secondaryId, getProduct(item.productId)) }}</p>
</ion-label>
<!-- Only show stock if its not a ship to store order -->
<div v-if="!isShipToStoreOrder">
<ion-note v-if="getProductStock(item.productId).quantityOnHandTotal >= 0" :color="updateColor(getProductStock(item.productId).quantityOnHandTotal)">
{{ getProductStock(item.productId).quantityOnHandTotal }} {{ translate('pieces in stock') }}
</ion-note>
<ion-spinner v-else-if="isFetchingStock" color="medium" name="crescent" />
<div slot="end" v-if="!isShipToStoreOrder">
<ion-spinner v-if="isFetchingStock" color="medium" name="crescent" />
<div v-else-if="getProductStock(item.productId).quantityOnHandTotal >= 0" class="atp-info">
<ion-note slot="end"> {{ translate("on hand", { count: getProductStock(item.productId).quantityOnHandTotal ?? '0' }) }} </ion-note>
<ion-button fill="clear" @click.stop="openInventoryDetailPopover($event)">
<ion-icon slot="icon-only" :icon="informationCircleOutline" color="medium" />
</ion-button>
</div>
<ion-button v-else fill="clear" @click.stop="fetchProductStock(item.productId)">
<ion-icon color="medium" slot="icon-only" :icon="cubeOutline"/>
<ion-icon color="medium" slot="icon-only" :icon="cubeOutline" />
</ion-button>
</div>
</div>
</ion-item>
</template>

<script lang="ts">
import { computed, defineComponent } from "vue";
import { IonButton, IonIcon, IonItem, IonLabel, IonNote, IonSpinner, IonThumbnail } from "@ionic/vue";
import { IonButton, IonIcon, IonItem, IonLabel, IonNote, IonSpinner, IonThumbnail, popoverController } from "@ionic/vue";
import { mapGetters, useStore } from 'vuex';
import { getProductIdentificationValue, ShopifyImg, translate, useProductIdentificationStore } from '@hotwax/dxp-components'
import { cubeOutline } from 'ionicons/icons'
import { getProductIdentificationValue, DxpShopifyImg, translate, useProductIdentificationStore } from '@hotwax/dxp-components'
import { cubeOutline, informationCircleOutline } from 'ionicons/icons'
import InventoryDetailsPopover from '@/components/InventoryDetailsPopover.vue'
export default defineComponent({
name: "ProductListItem",
Expand All @@ -37,33 +41,38 @@ export default defineComponent({
IonNote,
IonSpinner,
IonThumbnail,
ShopifyImg
DxpShopifyImg
},
data () {
return {
goodIdentificationTypeId: process.env.VUE_APP_PRDT_IDENT_TYPE_ID,
isFetchingStock: false
}
},
props: {
item: Object,
isShipToStoreOrder: {
type: Boolean,
default: false
isFetchingStock: false,
}
},
props: ['item', 'isShipToStoreOrder'],
computed: {
...mapGetters({
getProduct: 'product/getProduct',
getProductStock: 'stock/getProductStock'
product: "product/getCurrent",
getProductStock: 'stock/getProductStock',
currentFacility: 'user/getCurrentFacility',
})
},
methods: {
async fetchProductStock(productId: string) {
this.isFetchingStock = true
await this.store.dispatch('stock/fetchStock', { productId })
await this.store.dispatch('stock/fetchStock', { productId });
this.isFetchingStock = false
},
async openInventoryDetailPopover(Event: any){
const popover = await popoverController.create({
component: InventoryDetailsPopover,
event: Event,
showBackdrop: false,
componentProps: { item: this.item }
});
await popover.present();
},
updateColor(stock: number) {
return stock ? stock < 10 ? 'warning' : 'success' : 'danger';
}
Expand All @@ -76,6 +85,7 @@ export default defineComponent({
getProductIdentificationValue,
productIdentificationPref,
cubeOutline,
informationCircleOutline,
store,
translate
}
Expand All @@ -87,4 +97,10 @@ export default defineComponent({
ion-thumbnail > img {
object-fit: contain;
}
.atp-info {
display: flex;
align-items: center;
flex-direction: row;
}
</style>
5 changes: 1 addition & 4 deletions src/components/RejectOrderModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
<ion-list-header>{{ translate("Select reason") }}</ion-list-header>
<ion-radio-group v-model="rejectReasonId">
<ion-item v-for="reason in unfillableReasons" :key="reason.id">
<ion-radio slot="start" :value="reason.id" />
<ion-label>{{ translate(reason.label) }}</ion-label>
<ion-radio :value="reason.id" label-placement="end" justify="start">{{ translate(reason.label) }}</ion-radio>
</ion-item>
</ion-radio-group>
</ion-list>
Expand All @@ -40,7 +39,6 @@ import {
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonTitle,
Expand All @@ -66,7 +64,6 @@ export default defineComponent({
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonTitle,
Expand Down
Loading

0 comments on commit d44c387

Please sign in to comment.