diff --git a/.env.example b/.env.example index 6002fc9c..0e210be3 100644 --- a/.env.example +++ b/.env.example @@ -9,7 +9,7 @@ VUE_APP_POLL_TIME=10000 VUE_APP_ORDER_FILTERS=["orderTypeId: SALES_ORDER", "facilityId:PRE_ORDER_PARKING OR facilityId:BACKORDER_PARKING", "orderStatusId: ORDER_APPROVED", "!orderItemStatusId: ITEM_CANCELLED" ] VUE_APP_BASE_URL= VUE_APP_ORDER_IN_BRKRNG_FILTERS=["orderTypeId: SALES_ORDER", "facilityId: _NA_", "orderStatusId: ORDER_APPROVED", "!orderItemStatusId: ITEM_CANCELLED" ] -VUE_APP_PERMISSION_ID= +VUE_APP_PERMISSION_ID="PREORDER_APP_VIEW" VUE_APP_ALIAS= VUE_APP_CTGRY_AND_BRKRNG_JOB=["JOB_REL_PREODR_CAT", "JOB_BKR_ORD", "JOB_RLS_ORD_DTE"] VUE_APP_DEFAULT_ALIAS= diff --git a/package-lock.json b/package-lock.json index 66c862dd..0681a1c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "preorder-app", - "version": "1.17.0", + "version": "1.19.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "preorder-app", - "version": "1.17.0", + "version": "1.19.0", "dependencies": { "@capacitor/android": "^2.5.0", "@capacitor/core": "^2.4.7", @@ -14,7 +14,7 @@ "@casl/ability": "^6.0.0", "@hotwax/app-version-info": "^1.0.0", "@hotwax/apps-theme": "^1.2.6", - "@hotwax/dxp-components": "1.13.0", + "@hotwax/dxp-components": "^1.15.4", "@hotwax/oms-api": "1.14.0", "@ionic/core": "^7.6.0", "@ionic/vue": "^7.6.0", @@ -2802,9 +2802,9 @@ "integrity": "sha512-zpUjGoY7LBlKeiP0V7tonrmoey8HQ5THQmyixQ+IDtrjmEJNBjynW/Ef3gC0FUNNPuVqxWPZdT5CVgaETLGTwg==" }, "node_modules/@hotwax/dxp-components": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@hotwax/dxp-components/-/dxp-components-1.13.0.tgz", - "integrity": "sha512-AkzHpGIWYFURIAKaqioNZdkaeJBaJHs+ep+5ibLyEj+Ex+GsyMsI9L1NVO+tl91ECkCNx02QjHPhMfpo0osQ3w==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/@hotwax/dxp-components/-/dxp-components-1.15.4.tgz", + "integrity": "sha512-dlgexo/QBLnLlPkq1zwfWBIPiVtmZKsRcPcCAwe+eFz9qPwyQORdzKb6YjX1WgtRU72GYMv345eA+HuaSY6H5w==", "dependencies": { "@hotwax/oms-api": "^1.8.1", "@ionic/core": "^7.6.0", @@ -2815,7 +2815,8 @@ "pinia-plugin-persistedstate": "^3.1.0", "register-service-worker": "^1.7.2", "vue": "^3.3.4", - "vue-i18n": "^9.2.2" + "vue-i18n": "^9.2.2", + "vue-markdown-render": "^2.2.1" } }, "node_modules/@hotwax/dxp-components/node_modules/@intlify/core-base": { @@ -2859,16 +2860,6 @@ "url": "https://github.com/sponsors/kazupon" } }, - "node_modules/@hotwax/dxp-components/node_modules/@ionic/core": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.8.2.tgz", - "integrity": "sha512-1Iwe4XSaEYD0u7U/AnnKYNRXmPxx/doTl6pExXq/nlEd7q0AykRkPEy5rClqrQcJOrgFogAx1FwSObfgm0xnNw==", - "dependencies": { - "@stencil/core": "^4.12.2", - "ionicons": "^7.2.2", - "tslib": "^2.1.0" - } - }, "node_modules/@hotwax/dxp-components/node_modules/pinia": { "version": "2.0.36", "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.36.tgz", @@ -2927,11 +2918,6 @@ } } }, - "node_modules/@hotwax/dxp-components/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, "node_modules/@hotwax/dxp-components/node_modules/vue-i18n": { "version": "9.10.2", "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.10.2.tgz", @@ -11683,6 +11669,14 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/listr2": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", @@ -12097,6 +12091,37 @@ "semver": "bin/semver.js" } }, + "node_modules/markdown-it": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", + "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -12113,6 +12138,11 @@ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -16123,6 +16153,11 @@ "node": ">=4.2.0" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -17002,6 +17037,17 @@ "node": ">=8" } }, + "node_modules/vue-markdown-render": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vue-markdown-render/-/vue-markdown-render-2.2.1.tgz", + "integrity": "sha512-XkYnC0PMdbs6Vy6j/gZXSvCuOS0787Se5COwXlepRqiqPiunyCIeTPQAO2XnB4Yl04EOHXwLx5y6IuszMWSgyQ==", + "dependencies": { + "markdown-it": "^13.0.2" + }, + "peerDependencies": { + "vue": "^3.3.4" + } + }, "node_modules/vue-router": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz", diff --git a/package.json b/package.json index 5a97adf1..314b0a16 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "preorder-app", - "version": "1.17.0", + "version": "1.19.0", "private": true, "description": "HotWax Commece Pre-order App", "scripts": { @@ -19,7 +19,7 @@ "@casl/ability": "^6.0.0", "@hotwax/app-version-info": "^1.0.0", "@hotwax/apps-theme": "^1.2.6", - "@hotwax/dxp-components": "1.13.0", + "@hotwax/dxp-components": "^1.15.4", "@hotwax/oms-api": "1.14.0", "@ionic/core": "^7.6.0", "@ionic/vue": "^7.6.0", diff --git a/src/authorization/Actions.ts b/src/authorization/Actions.ts index 1cc819ad..8e1eac09 100644 --- a/src/authorization/Actions.ts +++ b/src/authorization/Actions.ts @@ -1,3 +1,4 @@ export default { "APP_INV_CNFG_UPDT": "APP_INV_CNFG_UPDT", + "APP_COMMERCE_VIEW": "APP_COMMERCE_VIEW" } \ No newline at end of file diff --git a/src/authorization/Rules.ts b/src/authorization/Rules.ts index d2e8f294..6d91d6f9 100644 --- a/src/authorization/Rules.ts +++ b/src/authorization/Rules.ts @@ -4,5 +4,8 @@ export default { "APP_CATALOG_VIEW": "", "APP_PRDT_DTLS_VIEW": "", "APP_CTLG_PRDT_DTLS_VIEW": "", - "APP_INV_CNFG_UPDT": "COMMON_ADMIN" + "APP_COMMERCE_VIEW": "COMMERCEUSER_VIEW", + "MERCHANDISING_ADMIN": "MERCHANDISING_ADMIN", + "PREORDER_APP_VIEW": "PREORDER_APP_VIEW", + "APP_INV_CNFG_UPDT": "COMMON_ADMIN", } as any \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index b4a2924a..a1431f8c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -29,7 +29,7 @@ import '@ionic/vue/css/display.css'; import './theme/variables.css'; import { dxpComponents } from '@hotwax/dxp-components' import { login, logout, loader } from './user-utils'; -import permissionPlugin from '@/authorization'; +import permissionPlugin, { Actions, hasPermission } from '@/authorization'; import permissionRules from '@/authorization/Rules'; import permissionActions from '@/authorization/Actions'; import { setUserTimeZone, getAvailableTimeZones, setUserLocale} from '@/adapter' @@ -49,6 +49,7 @@ const app = createApp(App) actions: permissionActions }) .use(dxpComponents, { + Actions, defaultImgUrl: require("@/assets/images/defaultImage.png"), login, logout, @@ -61,7 +62,8 @@ const app = createApp(App) setUserTimeZone, getAvailableTimeZones, getProductIdentificationPref, - setProductIdentificationPref + setProductIdentificationPref, + hasPermission }); // Filters are removed in Vue 3 and global filter introduced https://v3.vuejs.org/guide/migration/filters.html#global-filters diff --git a/src/services/UserService.ts b/src/services/UserService.ts index 91c30033..4559cb41 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -21,17 +21,21 @@ const setUserPreference = async (payload: any): Promise => { }); } -const getEComStores = async (token: any, partyId: any): Promise => { +const getEComStores = async (token: any, partyId: any, isAdminUser = false): Promise => { try { const params = { "inputFields": { - "storeName_op": "not-empty", - "partyId": partyId + "storeName_op": "not-empty" }, "fieldList": ["productStoreId", "storeName"], "entityName": "ProductStoreAndRole", "distinct": "Y", - "noConditionFind": "Y" + "noConditionFind": "Y", + "filterByDate": 'Y' + } as any; + + if(!isAdminUser) { + params.inputFields['partyId'] = partyId } const baseURL = store.getters['user/getBaseUrl']; diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index 04323e67..6f90bdda 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -49,17 +49,31 @@ const actions: ActionTree = { } } - // Getting user profile - const userProfile = await UserService.getUserProfile(token); - userProfile.stores = await UserService.getEComStores(token, userProfile.partyId); - - // Getting user preferred store - let preferredStore = userProfile.stores[0]; - const preferredStoreId = await UserService.getPreferredStore(token); - if (preferredStoreId) { - const store = userProfile.stores.find((store: any) => store.productStoreId === preferredStoreId); - store && (preferredStore = store) - } + const isAdminUser = appPermissions.some((appPermission: any) => appPermission?.action === "MERCHANDISING_ADMIN"); + + // Getting user profile + const userProfile = await UserService.getUserProfile(token); + userProfile.stores = await UserService.getEComStores(token, userProfile.partyId, isAdminUser); + + // Getting user preferred store + let preferredStore = userProfile.stores[0]; + const preferredStoreId = await UserService.getPreferredStore(token); + if (preferredStoreId) { + const store = userProfile.stores.find((store: any) => store.productStoreId === preferredStoreId); + store && (preferredStore = store) + } + + setPermissions(appPermissions); + if (userProfile.userTimeZone) { + Settings.defaultZone = userProfile.userTimeZone; + } + + // TODO user single mutation + commit(types.USER_CURRENT_ECOM_STORE_UPDATED, preferredStore); + commit(types.USER_INFO_UPDATED, userProfile); + commit(types.USER_TOKEN_CHANGED, { newToken: token }); + commit(types.USER_PERMISSIONS_UPDATED, appPermissions); + updateToken(token); // Get product identification from api using dxp-component await useProductIdentificationStore().getIdentificationPref(preferredStoreId) diff --git a/src/views/order-popover.vue b/src/views/order-popover.vue index a17073d3..0b7b7871 100644 --- a/src/views/order-popover.vue +++ b/src/views/order-popover.vue @@ -32,7 +32,7 @@ export default defineComponent({ orderId: item.orderId, orderItemSeqId: item.orderItemSeqId, changeReasonEnumId: "RELEASED", - toFacilityId: "_NA_" // TODO Make it configurable + toFacilityId: "RELEASED_ORD_PARKING" // TODO Make it configurable }) }, async cancelItem (item: any) { diff --git a/src/views/orders.vue b/src/views/orders.vue index 7621ee26..13c6edbb 100644 --- a/src/views/orders.vue +++ b/src/views/orders.vue @@ -285,6 +285,7 @@ export default defineComponent({ selectedItemsCount: 'order/getSelectedItemsCount', userProfile: 'user/getUserProfile', query: 'order/getQuery', + currentEComStore: 'user/getCurrentEComStore', }), }, async ionViewWillEnter() { @@ -319,13 +320,14 @@ export default defineComponent({ }, async releaseItems() { emitter.emit("presentLoader") - const selectedItems = this.getSelectedItemsToRelease("_NA_", "RELEASED"); // TODO Make it configurable + const selectedItems = this.getSelectedItemsToRelease("RELEASED_ORD_PARKING", "RELEASED"); // TODO Make it configurable const json = JSON.stringify(selectedItems); const blob = new Blob([json], { type: 'application/json'}); const formData = new FormData(); const fileName = "ReleaseItems_" + Date.now() +".json"; formData.append("uploadedFile", blob, fileName); formData.append("configId", "MDM_REL_ORD_ITM_JSON"); + formData.append("param_productStoreId", this.currentEComStore.productStoreId); this.deselectSelectedItems(); return this.store.dispatch("order/releaseItems", { headers: { @@ -346,6 +348,7 @@ export default defineComponent({ const fileName = "CancelItems_" + Date.now() +".json"; formData.append("uploadedFile", blob, fileName); formData.append("configId", "MDM_CAN_ORD_ITM_JSON"); + formData.append("param_productStoreId", this.currentEComStore.productStoreId); this.deselectSelectedItems(); return this.store.dispatch("order/cancelItems", { headers: { diff --git a/src/views/product-details.vue b/src/views/product-details.vue index eb42b039..590db3fa 100644 --- a/src/views/product-details.vue +++ b/src/views/product-details.vue @@ -436,7 +436,7 @@ export default defineComponent({ orderId: item.orderId, orderItemSeqId: item.orderItemSeqId, changeReasonEnumId: "RELEASED", - toFacilityId: "_NA_" // TODO Make it configurable + toFacilityId: "RELEASED_ORD_PARKING" // TODO Make it configurable } }) selectedItems = [...selectedItems, ...items]; @@ -447,6 +447,8 @@ export default defineComponent({ const fileName = "ReleaseItems_" + Date.now() +".json"; formData.append("uploadedFile", blob, fileName); formData.append("configId", "MDM_REL_ORD_ITM_JSON"); + formData.append("param_productStoreId", this.currentEComStore.productStoreId); + return this.store.dispatch("order/releaseItems", { headers: { 'Content-Type': 'multipart/form-data;' @@ -475,6 +477,7 @@ export default defineComponent({ const fileName = "CancelItems_" + Date.now() +".json"; formData.append("uploadedFile", blob, fileName); formData.append("configId", "MDM_CAN_ORD_ITM_JSON"); + formData.append("param_productStoreId", this.currentEComStore.productStoreId); return this.store.dispatch("order/cancelItems", { headers: { 'Content-Type': 'multipart/form-data;' diff --git a/src/views/promise-date-modal.vue b/src/views/promise-date-modal.vue index 7582adf0..7dfcf474 100644 --- a/src/views/promise-date-modal.vue +++ b/src/views/promise-date-modal.vue @@ -53,6 +53,7 @@ export default defineComponent({ ...mapGetters({ jobTotal: 'job/getTotal', getSelectedItemsToUpdatePromiseDate: 'order/getSelectedItemsToUpdatePromiseDate', + currentEComStore: 'user/getCurrentEComStore', }), disableUpdate(): boolean { return this.promisedDatetime === '' || (this.item && this.item.promisedDatetime && DateTime.fromFormat(this.item.promisedDatetime, "yyyy-MM-dd hh:mm:ss.SSS").toFormat("yyyy-MM-dd") === this.promisedDatetime); @@ -94,6 +95,7 @@ export default defineComponent({ const fileName = "UpdatePromiseDateItems_" + Date.now() +".json"; formData.append("uploadedFile", blob, fileName); formData.append("configId", "MDM_UPD_ORD_ITM_JSON"); + formData.append("param_productStoreId", this.currentEComStore.productStoreId); return this.store.dispatch("order/updatePromiseDateItems", { headers: { 'Content-Type': 'multipart/form-data;' diff --git a/src/views/warehouse-modal.vue b/src/views/warehouse-modal.vue index 31492143..3a3579b1 100644 --- a/src/views/warehouse-modal.vue +++ b/src/views/warehouse-modal.vue @@ -145,6 +145,7 @@ export default defineComponent({ const fileName = "ReleaseItemsToWarehouse_" + Date.now() +".json"; formData.append("uploadedFile", blob, fileName); formData.append("configId", "MDM_REL_ORD_ITM_JSON"); + formData.append("param_productStoreId", this.currentEComStore.productStoreId); return this.store.dispatch("order/releaseItems", { headers: { 'Content-Type': 'multipart/form-data;'