diff --git a/src/components/common/FormModel.vue b/src/components/common/FormModel.vue
index fc5d1217..99ab9da1 100644
--- a/src/components/common/FormModel.vue
+++ b/src/components/common/FormModel.vue
@@ -69,6 +69,10 @@ const props = defineProps({
filter: {
type: Object,
default: null
+ },
+ dataRequired: {
+ type: Object,
+ default: () => {}
}
});
@@ -122,9 +126,10 @@ onMounted(async () => {
async function fetch() {
try {
- let { data } = await api.get(props.url, {
- params: { filter: JSON.stringify(props.filter) }
- });
+ const params = props.filter
+ ? { filter: JSON.stringify(props.filter) }
+ : {};
+ let { data } = await api.get(props.url, { params });
if (Array.isArray(data)) data = data[0] ?? {};
formData.value = { ...data };
emit('onDataFetched', formData.value);
@@ -144,9 +149,10 @@ async function save() {
isLoading.value = true;
try {
- const body = props.mapper
+ let body = props.mapper
? props.mapper(formData.value, originalData.value)
: formData.value;
+ body = { ...body, ...props.dataRequired };
const method = props.urlCreate ? 'post' : 'patch';
const url = props.urlCreate || props.urlUpdate || props.url;
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/Admin/NewsDetails.vue b/src/pages/Admin/NewsDetails.vue
index 92c3f797..15adb2a6 100644
--- a/src/pages/Admin/NewsDetails.vue
+++ b/src/pages/Admin/NewsDetails.vue
@@ -7,19 +7,21 @@ import VnImg from 'src/components/ui/VnImg.vue';
import VnForm from 'src/components/common/VnForm.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue';
+import FormModel from 'src/components/common/FormModel.vue';
import { useAppStore } from 'stores/app';
+import { useUserStore } from 'stores/user';
import { storeToRefs } from 'pinia';
-const jApi = inject('jApi');
+const api = inject('api');
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const appStore = useAppStore();
+const userStore = useUserStore();
const { isHeaderMounted } = storeToRefs(appStore);
const newsTags = ref([]);
-const pks = computed(() => ({ id: route.params.id }));
const isEditMode = !!route.params.id;
const formData = ref(
!route.params.id
@@ -32,22 +34,25 @@ const formData = ref(
: undefined
);
-const fetchNewDataSql = computed(() => {
+const initialFetchUrl = computed(() => {
if (!route.params.id) return undefined;
- return {
- query: `
- SELECT id, title, text, tag, priority, image
- FROM news WHERE id = #id`,
- params: { id: route.params.id }
- };
+ return `news/${route.params.id}`;
+});
+
+const urlUpdate = computed(() => {
+ if (!route.params.id) return undefined;
+ return `news/${route.params.id}`;
+});
+
+const urlCreate = computed(() => {
+ if (route.params.id) return undefined;
+ return 'news';
});
const getNewsTag = async () => {
try {
- newsTags.value = await jApi.query(
- `SELECT name, description FROM newsTag
- ORDER BY description`
- );
+ const { data } = await api.get('newsTags');
+ newsTags.value = data;
} catch (error) {
console.error('Error getting newsTag:', error);
}
@@ -73,19 +78,14 @@ onMounted(async () => {
{{ t('back') }}
-
@@ -215,7 +215,7 @@ onMounted(async () => {
}"
/>
-
+
diff --git a/src/pages/Admin/NewsView.vue b/src/pages/Admin/NewsView.vue
index 27bef4db..73537115 100644
--- a/src/pages/Admin/NewsView.vue
+++ b/src/pages/Admin/NewsView.vue
@@ -5,47 +5,31 @@ import { useI18n } from 'vue-i18n';
import CardList from 'src/components/ui/CardList.vue';
import VnImg from 'src/components/ui/VnImg.vue';
import VnList from 'src/components/ui/VnList.vue';
+import FetchData from 'src/components/common/FetchData.vue';
import { useAppStore } from 'stores/app';
import { storeToRefs } from 'pinia';
import { useVnConfirm } from 'src/composables/useVnConfirm.js';
import useNotify from 'src/composables/useNotify.js';
-const jApi = inject('jApi');
+const api = inject('api');
const { t } = useI18n();
const appStore = useAppStore();
const { openConfirmationModal } = useVnConfirm();
const { isHeaderMounted } = storeToRefs(appStore);
const { notify } = useNotify();
-const loading = ref(false);
+const loading = ref(true);
const news = ref([]);
-const getNews = async () => {
- try {
- loading.value = true;
- news.value = await jApi.query(
- `SELECT n.id, u.nickname, n.priority, n.image, n.title
- FROM news n
- JOIN account.user u ON u.id = n.userFk
- ORDER BY priority, n.created DESC`
- );
- loading.value = false;
- } catch (error) {
- console.error('Error getting news:', error);
- }
+const onFetch = data => {
+ news.value = data;
+ loading.value = false;
};
const deleteNew = async (id, index) => {
try {
- await jApi.execQuery(
- `START TRANSACTION;
- DELETE FROM hedera.news WHERE ((id = #id));
- COMMIT`,
- {
- id
- }
- );
+ await api.delete(`news/${id}`);
news.value.splice(index, 1);
notify(t('dataSaved'), 'positive');
} catch (error) {
@@ -57,6 +41,7 @@ onMounted(async () => getNews());
+
{
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() {
diff --git a/src/stores/user.js b/src/stores/user.js
index 8f170752..8b75f124 100644
--- a/src/stores/user.js
+++ b/src/stores/user.js
@@ -296,6 +296,8 @@ export const useUserStore = defineStore('user', () => {
tokenConfig.value = null;
};
+ const userId = computed(() => user.value?.id);
+
watch(
[mainUser, supplantedUser],
() => (user.value = supplantedUser.value || mainUser.value),
@@ -336,6 +338,7 @@ export const useUserStore = defineStore('user', () => {
updateUserLang,
init,
$reset,
- onLogin
+ onLogin,
+ userId
};
});