diff --git a/src/i18n/ca-ES/index.js b/src/i18n/ca-ES/index.js index 48d214e0..02f060ea 100644 --- a/src/i18n/ca-ES/index.js +++ b/src/i18n/ca-ES/index.js @@ -168,6 +168,7 @@ export default { // Errors errors: { statusUnauthorized: 'Accés denegat', - tokenConfig: 'Error al obtenir la configuració del token' + tokenConfig: 'Error al obtenir la configuració del token', + orderNotOwnedByUser: 'The order belongs to another user' } }; diff --git a/src/i18n/en-US/index.js b/src/i18n/en-US/index.js index 80107dd5..fba57ab0 100644 --- a/src/i18n/en-US/index.js +++ b/src/i18n/en-US/index.js @@ -200,6 +200,7 @@ export default { // Errors errors: { statusUnauthorized: 'Access denied', - tokenConfig: 'Error fetching token config' + tokenConfig: 'Error fetching token config', + orderNotOwnedByUser: 'The order belongs to another user' } }; diff --git a/src/i18n/es-ES/index.js b/src/i18n/es-ES/index.js index 15639c2d..67248e94 100644 --- a/src/i18n/es-ES/index.js +++ b/src/i18n/es-ES/index.js @@ -200,6 +200,7 @@ export default { // Errors errors: { statusUnauthorized: 'Acceso denegado', - tokenConfig: 'Error al obtener configuración de token' + tokenConfig: 'Error al obtener configuración de token', + orderNotOwnedByUser: 'The order belongs to another user' } }; diff --git a/src/i18n/fr-FR/index.js b/src/i18n/fr-FR/index.js index 2eea9a38..9881c440 100644 --- a/src/i18n/fr-FR/index.js +++ b/src/i18n/fr-FR/index.js @@ -172,6 +172,7 @@ export default { errors: { statusUnauthorized: 'Accès refusé', tokenConfig: - 'Erreur lors de la récupération de la configuration du jeton' + 'Erreur lors de la récupération de la configuration du jeton', + orderNotOwnedByUser: 'The order belongs to another user' } }; diff --git a/src/i18n/pt-PT/index.js b/src/i18n/pt-PT/index.js index 460335e0..ecbed192 100644 --- a/src/i18n/pt-PT/index.js +++ b/src/i18n/pt-PT/index.js @@ -166,6 +166,7 @@ export default { // Errors errors: { statusUnauthorized: 'Acesso negado', - tokenConfig: 'Erro ao obter configuração do token' + tokenConfig: 'Erro ao obter configuração do token', + orderNotOwnedByUser: 'The order belongs to another user' } }; diff --git a/src/pages/Ecomerce/CheckoutView.vue b/src/pages/Ecomerce/CheckoutView.vue index ad4eaf9e..3143264c 100644 --- a/src/pages/Ecomerce/CheckoutView.vue +++ b/src/pages/Ecomerce/CheckoutView.vue @@ -7,15 +7,18 @@ import VnSelect from 'src/components/common/VnSelect.vue'; import { formatDateTitle, formatDate } from 'src/lib/filters.js'; import useNotify from 'src/composables/useNotify.js'; +import { onUserId } from 'src/utils/onUserId'; +import { useUserStore } from 'stores/user'; import { useAppStore } from 'stores/app'; import { storeToRefs } from 'pinia'; -const jApi = inject('jApi'); +const api = inject('api'); const { t } = useI18n(); const route = useRoute(); const router = useRouter(); const { notify } = useNotify(); const appStore = useAppStore(); +const userStore = useUserStore(); const { localeDates, isMobile } = storeToRefs(appStore); const stepperRef = ref(null); @@ -148,38 +151,103 @@ const validateStep = (formField, errorMessage) => { return validation; }; -const getAddresses = async () => { +const getAddresses = async (clientFk) => { try { - addresses.value = await jApi.query( - `SELECT a.id, a.nickname, p.name province, a.city, a.street, a.isActive, c.name - FROM myAddress a - LEFT JOIN vn.province p ON p.id = a.provinceFk - JOIN vn.country c ON c.id = p.countryFk - WHERE a.isActive` - ); + const filter = { + where: { + clientFk, + isActive: true, + }, + include: [ + { + relation: 'province', + scope: { + fields: ['name', 'countryFk'], + include: [ + 'country', + { + relation: 'country', + scope: { + fields: ['name'], + }, + }, + ], + }, + }, + ], + fields: [ + 'id', + 'nickname', + 'city', + 'street', + 'isActive', + 'provinceFk', + ] + }; + + const { data: myAddresses } = await api.get('Addresses', { + params: { + filter: JSON.stringify(filter) + } + }); + + addresses.value = myAddresses; } catch (error) { console.error('Error getting addresses:', error); } }; +const getOrder = async (orderId) => { + const { data } = await api.get(`Orders/${orderId}`, { + params: { + filter: JSON.stringify({ + include: [ + { + relation: 'deliveryMethod', + scope: { + fields: ['code'], + }, + }, + ], + fields: [ + 'id', + 'delivery_method_id', + 'landed', + 'agencyModeFk', + 'addressFk', + ] + }) + } + }); + return data; +}; + +const getAgenciesInZone = async () => { + const agenciesInZone = await api.get('Agencies/landsThatDay', { + params: { + addressFk: orderForm.value.address, + landed: new Date(orderForm.value.date), + } + }); + const deliveryMethods = await api.get('DeliveryMethods'); + + return agenciesInZone.data + .filter(agency => agency.isVisible) + .map(agency => ({ + id: agency.agencyModeFk, + description: agency.description, + deliveryMethod: deliveryMethods.data.find(dm => dm.id === agency.deliveryMethodFk).code, + })) + .toSorted((a, b) => a.description.localeCompare(b.description)); +}; + const getAgencies = async () => { try { - const { results } = await jApi.execQuery( - `CALL vn.zone_getAgency(#address, #date); - SELECT DISTINCT a.agencyModeFk id, a.description - FROM tmp.zoneGetAgency a - JOIN vn.deliveryMethod d - ON d.id = a.deliveryMethodFk - WHERE d.code IN ('AGENCY', 'DELIVERY') - AND a.isVisible - ORDER BY a.description; - DROP TEMPORARY TABLE tmp.zoneGetAgency`, - { - address: orderForm.value.address, - date: new Date(orderForm.value.date) - } - ); - agencies.value = results[1].data; + const agenciesInZone = await getAgenciesInZone(); + const results = agenciesInZone + .filter(agency => agency.deliveryMethod === 'AGENCY' || agency.deliveryMethod === 'DELIVERY'); + + agencies.value = results; if (agencies.value && agencies.value.length && defaultValues.value) { const found = agencies.value.find( @@ -196,22 +264,10 @@ const getAgencies = async () => { const getWarehouses = async () => { try { - const { results } = await jApi.execQuery( - `CALL vn.zone_getAgency(#address, #date); - SELECT DISTINCT a.agencyModeFk id, a.description - FROM tmp.zoneGetAgency a - JOIN vn.deliveryMethod d - ON d.id = a.deliveryMethodFk - WHERE d.code IN ('PICKUP') - AND a.isVisible - ORDER BY a.description; - DROP TEMPORARY TABLE tmp.zoneGetAgency;`, - { - address: orderForm.value.address, - date: new Date(orderForm.value.date) - } - ); - warehouses.value = results[1].data; + const agenciesInZone = await getAgenciesInZone(); + const results = agenciesInZone.filter(agency => agency.deliveryMethod === 'PICKUP'); + + warehouses.value = results; if (!warehouses.value || !warehouses.value.length) { notify(t('noWarehousesAvailableForDate'), 'negative'); @@ -260,32 +316,60 @@ const onPreviousStep = async stepIndex => { } }; +const configureOrder = (orderId) => api.post( + 'applications/myOrder_configure/execute-proc', + { + schema: 'hedera', + params: [ + orderId, + new Date(orderForm.value.date), + orderForm.value.method, + orderForm.value.agency, + orderForm.value.address, + ], + }, +); + +const createOrder = async (userId) => { + const orderConfig = await api.get('OrderConfigs'); + + const companyFk = orderConfig.data[0]?.defaultCompanyFk; + + return await api.post( + 'Orders', + { + sourceApp: 'WEB', + landed: new Date(orderForm.value.date), + clientFk: userId, + companyFk, + addressFk: orderForm.value.address, + agencyModeFk: orderForm.value.agency, + }, + ) +}; + const submit = async () => { loading.value = true; - let query = - 'CALL myOrder_create(@orderId, #date, #method, #agency, #address); SELECT @orderId;'; - if (id) { - orderForm.value.id = id; - query = - 'CALL myOrder_configure(#id, #date, #method, #agency, #address)'; - } - let resultSet; + const userId = userStore.user.id; + try { - const { date, ...restOfForm } = orderForm.value; - const _date = new Date(date); - resultSet = await jApi.execQuery(query, { ...restOfForm, date: _date }); - if (id) { - notify(t('orderUpdated'), 'positive'); - if (route.query.continue === 'catalog') { - router.push({ name: 'catalog' }); - } else { - router.push({ name: 'basket', params: { id } }); - } + if (!id) { + const order = await createOrder(userId); + const orderId = order.data.id; + await configureOrder(orderId); + + appStore.loadIntoBasket(orderId); + router.push({ name: 'catalog' }); } else { - const orderId = resultSet.results[1].data[0]['@orderId']; - appStore.loadIntoBasket(orderId); + await configureOrder(id); + + notify(t('orderUpdated'), 'positive'); + if (route.query.continue === 'catalog') { router.push({ name: 'catalog' }); + } else { + router.push({ name: 'basket', params: { id } }); + } } } catch (error) { console.error('Error submitting order:', error); @@ -295,10 +379,8 @@ const submit = async () => { }; const getDefaultValues = async () => { - return await jApi.query( - `SELECT deliveryMethod, agencyModeFk, addressFk, defaultAgencyFk - FROM myBasketDefaults` - ); + const { data: myBasketDefaults } = await api.get('Clients/myBasketDefaults'); + return myBasketDefaults; }; onMounted(async () => { @@ -308,17 +390,11 @@ onMounted(async () => { if (route.params.id) { notify(t('rememberReconfiguringImpact'), 'warning'); - const [order] = await jApi.query( - `SELECT m.code deliveryMethod, o.sent, o.agencyModeFk, o.addressFk - FROM myOrder o - JOIN vn.deliveryMethod m ON m.id = o.deliveryMethodFk - WHERE o.id = #id`, - { id: route.params.id } - ); + const order = await getOrder(route.params.id); if (order) { - orderForm.value.method = order.deliveryMethod; - orderForm.value.date = formatDate(order.sent, 'YYYY/MM/DD'); + orderForm.value.method = order.deliveryMethod.code; + orderForm.value.date = formatDate(order.landed, 'YYYY/MM/DD'); orderForm.value.agency = order.agencyModeFk; orderForm.value.address = order.addressFk; } @@ -326,10 +402,10 @@ onMounted(async () => { const [_defaultValues] = await getDefaultValues(); if (_defaultValues) defaultValues.value = _defaultValues; } - - getAddresses(); }); +onUserId(getAddresses); + watch( () => orderForm.value.method, () => { diff --git a/src/stores/app.js b/src/stores/app.js index d5183dc8..ad0babd8 100644 --- a/src/stores/app.js +++ b/src/stores/app.js @@ -81,14 +81,6 @@ export const useAppStore = defineStore('hedera', { this.basketOrderId = localStorage.getItem(storageOrderName); }, - async checkOrder(orderId) { - const resultSet = await jApi.execQuery( - 'CALL myOrder_checkConfig(#id)', - { id: orderId } - ); - resultSet.fetchValue(); - }, - async check(checkoutContinue) { if (this.basketOrderId) { return await this.checkRedirect(checkoutContinue); @@ -99,26 +91,36 @@ export const useAppStore = defineStore('hedera', { }, async checkRedirect(checkoutContinue) { - try { - await this.checkOrder(this.basketOrderId); - return true; - } catch (err) { - switch (err.code) { - case 'orderConfirmed': - case 'orderNotOwnedByUser': - this.unloadOrder(); - await this.redirect(); - break; - default: - this.router.push({ - name: 'checkout', - params: { id: this.basketOrderId }, - query: { continue: checkoutContinue } - }); - notify(err.message, 'negative'); - } - return false; + const orderId = this.basketOrderId; + const myOrder_checkConfig = await api.post('applications/myOrder_checkConfig/execute-proc', { + schema: 'hedera', + params: [orderId], + }, { + validateStatus: () => true, + }); + + if (myOrder_checkConfig.status >= 200 && myOrder_checkConfig.status < 300) { + return true; } + + switch (myOrder_checkConfig.data.error?.message) { + case 'orderNotOwnedByUser': + notify(t(`errors.orderNotOwnedByUser`), 'negative'); + case 'orderConfirmed': + case 'orderNotOwnedByUser': + this.unloadOrder(); + await this.redirect(); + break; + default: + this.router.push({ + name: 'checkout', + params: { id: this.basketOrderId }, + query: { continue: checkoutContinue } + }); + notify(myOrder_checkConfig.data.error.message, 'negative'); + } + + return false; }, async redirect() {