refactor: use Salix to create or edit an Order #132

Merged
jsegarra merged 16 commits from ldragan/hedera-web:taro/sc into beta 2025-04-16 22:01:49 +00:00
7 changed files with 191 additions and 108 deletions

View File

@ -168,6 +168,7 @@ export default {
// Errors // Errors
errors: { errors: {
statusUnauthorized: 'Accés denegat', 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'
} }
}; };

View File

@ -200,6 +200,7 @@ export default {
// Errors // Errors
errors: { errors: {
statusUnauthorized: 'Access denied', statusUnauthorized: 'Access denied',
tokenConfig: 'Error fetching token config' tokenConfig: 'Error fetching token config',
orderNotOwnedByUser: 'The order belongs to another user'
} }
}; };

View File

@ -200,6 +200,7 @@ export default {
// Errors // Errors
errors: { errors: {
statusUnauthorized: 'Acceso denegado', 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'
} }
}; };

View File

@ -172,6 +172,7 @@ export default {
errors: { errors: {
statusUnauthorized: 'Accès refusé', statusUnauthorized: 'Accès refusé',
tokenConfig: 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'
} }
}; };

View File

@ -166,6 +166,7 @@ export default {
// Errors // Errors
errors: { errors: {
statusUnauthorized: 'Acesso negado', 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'
} }
}; };

View File

@ -7,15 +7,18 @@ import VnSelect from 'src/components/common/VnSelect.vue';
import { formatDateTitle, formatDate } from 'src/lib/filters.js'; import { formatDateTitle, formatDate } from 'src/lib/filters.js';
import useNotify from 'src/composables/useNotify.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 { useAppStore } from 'stores/app';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
const jApi = inject('jApi'); const api = inject('api');
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const { notify } = useNotify(); const { notify } = useNotify();
const appStore = useAppStore(); const appStore = useAppStore();
const userStore = useUserStore();
const { localeDates, isMobile } = storeToRefs(appStore); const { localeDates, isMobile } = storeToRefs(appStore);
const stepperRef = ref(null); const stepperRef = ref(null);
@ -148,38 +151,103 @@ const validateStep = (formField, errorMessage) => {
return validation; return validation;
}; };
const getAddresses = async () => { const getAddresses = async (clientFk) => {
try { try {
ldragan marked this conversation as resolved Outdated

TODO: revisar permisos de Address

TODO: revisar permisos de Address
addresses.value = await jApi.query( const filter = {
`SELECT a.id, a.nickname, p.name province, a.city, a.street, a.isActive, c.name where: {
FROM myAddress a clientFk,
LEFT JOIN vn.province p ON p.id = a.provinceFk isActive: true,
JOIN vn.country c ON c.id = p.countryFk },
WHERE a.isActive` 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) { } catch (error) {
console.error('Error getting addresses:', 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 () => { const getAgencies = async () => {
try { try {
const { results } = await jApi.execQuery( const agenciesInZone = await getAgenciesInZone();
`CALL vn.zone_getAgency(#address, #date); const results = agenciesInZone
SELECT DISTINCT a.agencyModeFk id, a.description .filter(agency => agency.deliveryMethod === 'AGENCY' || agency.deliveryMethod === 'DELIVERY');
FROM tmp.zoneGetAgency a
JOIN vn.deliveryMethod d agencies.value = results;
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;
if (agencies.value && agencies.value.length && defaultValues.value) { if (agencies.value && agencies.value.length && defaultValues.value) {
const found = agencies.value.find( const found = agencies.value.find(
@ -196,22 +264,10 @@ const getAgencies = async () => {
const getWarehouses = async () => { const getWarehouses = async () => {
try { try {
const { results } = await jApi.execQuery( const agenciesInZone = await getAgenciesInZone();
`CALL vn.zone_getAgency(#address, #date); const results = agenciesInZone.filter(agency => agency.deliveryMethod === 'PICKUP');
SELECT DISTINCT a.agencyModeFk id, a.description
FROM tmp.zoneGetAgency a warehouses.value = results;
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;
if (!warehouses.value || !warehouses.value.length) { if (!warehouses.value || !warehouses.value.length) {
notify(t('noWarehousesAvailableForDate'), 'negative'); notify(t('noWarehousesAvailableForDate'), 'negative');
@ -260,32 +316,60 @@ const onPreviousStep = async stepIndex => {
} }
}; };
const configureOrder = (orderId) => api.post(
Review

async?

async?
Review

No es necesario porque no usamos await dentro de configureOreder.

Preferís que lo agregue, igualmente?

No es necesario porque no usamos `await` dentro de `configureOreder`. Preferís que lo agregue, igualmente?
Review

Esta bien, no lo había visto. De la otra manera seria redundante

Esta bien, no lo había visto. De la otra manera seria redundante
'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(

await?

await?

Done

Done
'Orders',
{
sourceApp: 'WEB',
landed: new Date(orderForm.value.date),
clientFk: userId,
companyFk,
addressFk: orderForm.value.address,
agencyModeFk: orderForm.value.agency,
},
)
};
const submit = async () => { const submit = async () => {
loading.value = true; 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 { try {
const { date, ...restOfForm } = orderForm.value; if (!id) {
const _date = new Date(date); const order = await createOrder(userId);
resultSet = await jApi.execQuery(query, { ...restOfForm, date: _date }); const orderId = order.data.id;
if (id) { await configureOrder(orderId);
notify(t('orderUpdated'), 'positive');
if (route.query.continue === 'catalog') { appStore.loadIntoBasket(orderId);
router.push({ name: 'catalog' }); router.push({ name: 'catalog' });
} else {
router.push({ name: 'basket', params: { id } });
}
} else { } else {
const orderId = resultSet.results[1].data[0]['@orderId']; await configureOrder(id);
appStore.loadIntoBasket(orderId);
notify(t('orderUpdated'), 'positive');
if (route.query.continue === 'catalog') {
router.push({ name: 'catalog' }); router.push({ name: 'catalog' });
} else {
router.push({ name: 'basket', params: { id } });
}
} }
} catch (error) { } catch (error) {
console.error('Error submitting order:', error); console.error('Error submitting order:', error);
@ -295,10 +379,8 @@ const submit = async () => {
}; };
const getDefaultValues = async () => { const getDefaultValues = async () => {
return await jApi.query( const { data: myBasketDefaults } = await api.get('Clients/myBasketDefaults');
`SELECT deliveryMethod, agencyModeFk, addressFk, defaultAgencyFk return myBasketDefaults;
FROM myBasketDefaults`
);
}; };
onMounted(async () => { onMounted(async () => {
@ -308,17 +390,11 @@ onMounted(async () => {
if (route.params.id) { if (route.params.id) {
notify(t('rememberReconfiguringImpact'), 'warning'); notify(t('rememberReconfiguringImpact'), 'warning');
const [order] = await jApi.query( const order = await getOrder(route.params.id);
`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 }
);
if (order) { if (order) {
orderForm.value.method = order.deliveryMethod; orderForm.value.method = order.deliveryMethod.code;
orderForm.value.date = formatDate(order.sent, 'YYYY/MM/DD'); orderForm.value.date = formatDate(order.landed, 'YYYY/MM/DD');
orderForm.value.agency = order.agencyModeFk; orderForm.value.agency = order.agencyModeFk;
orderForm.value.address = order.addressFk; orderForm.value.address = order.addressFk;
} }
@ -326,10 +402,10 @@ onMounted(async () => {
const [_defaultValues] = await getDefaultValues(); const [_defaultValues] = await getDefaultValues();
if (_defaultValues) defaultValues.value = _defaultValues; if (_defaultValues) defaultValues.value = _defaultValues;
} }
getAddresses();
}); });
onUserId(getAddresses);
watch( watch(
() => orderForm.value.method, () => orderForm.value.method,
() => { () => {

View File

@ -81,14 +81,6 @@ export const useAppStore = defineStore('hedera', {
this.basketOrderId = localStorage.getItem(storageOrderName); this.basketOrderId = localStorage.getItem(storageOrderName);
}, },
async checkOrder(orderId) {
const resultSet = await jApi.execQuery(
'CALL myOrder_checkConfig(#id)',
{ id: orderId }
);
resultSet.fetchValue();
},
async check(checkoutContinue) { async check(checkoutContinue) {
if (this.basketOrderId) { if (this.basketOrderId) {
return await this.checkRedirect(checkoutContinue); return await this.checkRedirect(checkoutContinue);
@ -99,26 +91,36 @@ export const useAppStore = defineStore('hedera', {
}, },
async checkRedirect(checkoutContinue) { async checkRedirect(checkoutContinue) {
try { const orderId = this.basketOrderId;
await this.checkOrder(this.basketOrderId); const myOrder_checkConfig = await api.post('applications/myOrder_checkConfig/execute-proc', {
return true; schema: 'hedera',
} catch (err) { params: [orderId],
switch (err.code) { }, {
case 'orderConfirmed': validateStatus: () => true,
case 'orderNotOwnedByUser': });
this.unloadOrder();
await this.redirect(); if (myOrder_checkConfig.status >= 200 && myOrder_checkConfig.status < 300) {
break; return true;
default:
this.router.push({
name: 'checkout',
params: { id: this.basketOrderId },
query: { continue: checkoutContinue }
});
notify(err.message, 'negative');
}
return false;
} }
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() { async redirect() {