fix: migrate pending orders #121
|
@ -1,2 +1,5 @@
|
|||
debian
|
||||
node_modules
|
||||
node_modules
|
||||
.quasar
|
||||
build
|
||||
.vscode
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { ref, inject, onMounted } from 'vue';
|
||||
import { ref, inject } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
|
@ -11,8 +11,10 @@ import { useVnConfirm } from 'src/composables/useVnConfirm.js';
|
|||
import useNotify from 'src/composables/useNotify.js';
|
||||
import { useAppStore } from 'stores/app';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { onUserId } from 'src/utils/onUserId';
|
||||
|
||||
const jApi = inject('jApi');
|
||||
const api = inject('api');
|
||||
const { t } = useI18n();
|
||||
const { openConfirmationModal } = useVnConfirm();
|
||||
const { notify } = useNotify();
|
||||
|
@ -23,18 +25,48 @@ const router = useRouter();
|
|||
const loading = ref(false);
|
||||
const orders = ref([]);
|
||||
|
||||
const getOrders = async () => {
|
||||
const getOrders = async (clientFk) => {
|
||||
try {
|
||||
loading.value = true;
|
||||
orders.value = await jApi.query(
|
||||
`SELECT o.id, o.sent, o.deliveryMethodFk, o.taxableBase,
|
||||
a.nickname, am.description agency
|
||||
FROM myOrder o
|
||||
JOIN myAddress a ON a.id = o.addressFk
|
||||
JOIN vn.agencyMode am ON am.id = o.agencyModeFk
|
||||
WHERE NOT o.isConfirmed
|
||||
ORDER BY o.sent DESC`
|
||||
);
|
||||
|
||||
const filter = {
|
||||
where: {
|
||||
clientFk,
|
||||
isConfirmed: false,
|
||||
|
||||
source_app: 'WEB',
|
||||
},
|
||||
include: [
|
||||
jsegarra marked this conversation as resolved
jsegarra
commented
haces para que te traiga el objeto de address? haces para que te traiga el objeto de address?
Quiero decir, la relacion ya está con clave primaria, por tanto no haria falta ponerlo en el where
ldragan
commented
Coincido, pero así estaba la query y preferí no cambiarla. (La view Por lo que veo en Yo considero que remover esta parte del Por otro lado, lo más probable es que remover esta condición no cause ningún problema, y, aún si lo hiciera, el impacto debería ser mínimo, inmediatamente observable y fácil de resolver. Si estás a favor de quitar el Coincido, pero así estaba la query y preferí no cambiarla. (La view `myAddress` tiene incluido el filtro de `clientFk`).
Por lo que veo en `order.json`, el `join` se hace via el `address_id`, y no hay una garantía real y determinística de que el `address.clientFk` coincida con el `order.clientFk`— ello depende de que nunca se haga un `insert` o `update` "incorrecto" en algún lugar del código, para alguna defición de "correcto".
Yo considero que remover esta parte del `where` sería un refactor, y no es estrictamente parte de la migración. Estoy a favor, pero suelo preferir el camino conservador, y encarar los dos cambios en 2 PRs separados, para simplificar el debugging en el remoto caso de que ocurra un error inesperado por alguna incongruencia en la data.
Por otro lado, lo más probable es que remover esta condición no cause ningún problema, y, aún si lo hiciera, el impacto debería ser mínimo, inmediatamente observable y fácil de resolver.
Si estás a favor de quitar el `'address.clientFk': clientFk,`, entonces yo también :)
jsegarra
commented
Dale con todo y quitemosla Dale con todo y quitemosla
jsegarra
commented
y validamos con los tests y validamos con los tests
ldragan
commented
Awesome. Hecho :) Awesome. Hecho :)
|
||||
{
|
||||
relation: 'address',
|
||||
jsegarra
commented
este source_app no lo veo en la query origen este source_app no lo veo en la query origen
ldragan
commented
La query original se hacía contra
La view incluye el
La query original se hacía contra `myOrder` , que es una view:
```
MariaDB [(none)]> show create view `hedera`.`myOrder`;
*************************** 1. row ***************************
View: myOrder
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `hedera`.`myOrder` AS select `o`.`id` AS `id`,`o`.`date_send` AS `sent`,`o`.`customer_id` AS `clientFk`,`o`.`delivery_method_id` AS `deliveryMethodFk`,`o`.`agency_id` AS `agencyModeFk`,`o`.`address_id` AS `addressFk`,`o`.`company_id` AS `companyFk`,`o`.`note` AS `notes`,`o`.`source_app` AS `sourceApp`,`o`.`confirmed` AS `isConfirmed`,`o`.`date_make` AS `created`,`o`.`first_row_stamp` AS `firstRowStamp`,`o`.`confirm_date` AS `confirmed`,`o`.`taxableBase` AS `taxableBase`,`o`.`tax` AS `tax`,`o`.`total` AS `total` from `hedera`.`order` `o` where `o`.`customer_id` = `account`.`myUser_getId`() and `o`.`source_app` = 'WEB' and `o`.`confirmed` = 0 WITH CASCADED CHECK OPTION
character_set_client: utf8mb4
collation_connection: utf8mb4_unicode_ci
1 row in set (0.156 sec)
```
La view incluye el `source_app` y otros filtros:
```
where `o`.`customer_id` = `account`.`myUser_getId`() and `o`.`source_app` = 'WEB' and `o`.`confirmed` = 0
```
jsegarra
commented
Comentado por @alexm Comentado por @alexm
Puedes definirte una vista como un modelo normal
modules/worker/back/models/worker-department.json por ejemplo, es una vista
ldragan
commented
For the record, esto lo charlamos en la daily, y quedamos en ver si al equipo le parece bien dejar esto así, o hacer un cambio mayor, para agregar un modelo loopback sobre una view. Mi argumento a favor de dejar esto así es que, al largo plazo, lo mejor sería directamente ya no usar las views, y usar completamente lo que ofrece loopback (hacerlo "the loopback way", digamos). Por otro lado, la view incluye la llamada al For the record, esto lo charlamos en la daily, y quedamos en ver si al equipo le parece bien dejar esto así, o hacer un cambio mayor, para agregar un modelo loopback sobre una view.
Mi argumento a favor de dejar esto así es que, al largo plazo, lo mejor sería directamente ya no usar las views, y usar completamente lo que ofrece loopback (hacerlo "the loopback way", digamos).
Por otro lado, la view incluye la llamada al `myUser_getId()`, el antiguo método de autorización, que, considero, deberíamos apuntar a eliminar completamente. Usar la view implica usar una transacción de la DB y ejecutar un `'CALL account.myUser_loginWithName((SELECT name FROM account.user WHERE id = ?))',`, como lo hace `VnModel.rawSql`. Perdemos casi todos los beneficios de loopback.
|
||||
scope: {
|
||||
fields: ['nickname', 'city'],
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'agencyMode',
|
||||
scope: {
|
||||
fields: ['description'],
|
||||
}
|
||||
},
|
||||
],
|
||||
fields: [
|
||||
'id',
|
||||
'landed',
|
||||
'delivery_method_id',
|
||||
'taxableBase',
|
||||
'addressFk',
|
||||
'agencyModeFk'
|
||||
]
|
||||
};
|
||||
|
||||
const { data: salixOrders } = await api.get('Orders', {
|
||||
params: {
|
||||
filter: JSON.stringify(filter)
|
||||
}
|
||||
});
|
||||
|
||||
orders.value = salixOrders;
|
||||
|
||||
loading.value = false;
|
||||
} catch (error) {
|
||||
console.error('Error getting orders:', error);
|
||||
|
@ -43,14 +75,7 @@ const getOrders = async () => {
|
|||
|
||||
const removeOrder = async (id, index) => {
|
||||
try {
|
||||
await jApi.execQuery(
|
||||
`START TRANSACTION;
|
||||
DELETE FROM hedera.myOrder WHERE ((id = #id));
|
||||
COMMIT`,
|
||||
{
|
||||
id
|
||||
}
|
||||
);
|
||||
await api.delete(`Orders/${id}`);
|
||||
orders.value.splice(index, 1);
|
||||
jsegarra
commented
Lo veo bien, pero cuando tengamos un respiro miraria de hacer algo para que refresque haciendo un refetch por ejemplo. https://gitea.verdnatura.es/verdnatura/salix-front/src/branch/dev/src/components/VnTable/VnTable.vue#L311 Lo veo bien, pero cuando tengamos un respiro miraria de hacer algo para que refresque haciendo un refetch por ejemplo. https://gitea.verdnatura.es/verdnatura/salix-front/src/branch/dev/src/components/VnTable/VnTable.vue#L311
|
||||
notify(t('dataSaved'), 'positive');
|
||||
} catch (error) {
|
||||
|
@ -63,9 +88,8 @@ const loadOrder = orderId => {
|
|||
router.push({ name: 'catalog' });
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
getOrders();
|
||||
});
|
||||
onUserId(getOrders);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -93,11 +117,11 @@ onMounted(async () => {
|
|||
>
|
||||
<template #content>
|
||||
<QItemLabel class="text-bold q-mb-sm">
|
||||
{{ formatDateTitle(order.sent) }}
|
||||
{{ formatDateTitle(order.landed) }}
|
||||
</QItemLabel>
|
||||
<QItemLabel> #{{ order.id }} </QItemLabel>
|
||||
<QItemLabel>{{ order.nickname }}</QItemLabel>
|
||||
<QItemLabel>{{ order.agency }}</QItemLabel>
|
||||
<QItemLabel>{{ order.address.nickname }}</QItemLabel>
|
||||
<QItemLabel>{{ order.agencyMode.description }}</QItemLabel>
|
||||
<QItemLabel>{{ currency(order.taxableBase) }}</QItemLabel>
|
||||
</template>
|
||||
<template #actions>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { watch } from 'vue';
|
||||
|
||||
import { useUserStore } from 'stores/user';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
export const onUserId = (cb) => watch(
|
||||
() => userStore?.user?.id,
|
||||
async userId => {
|
||||
if (!userId) return;
|
||||
jsegarra
commented
Usando clausulas de guarda podemos quitar un nivel de indexación Usando clausulas de guarda podemos quitar un nivel de indexación
`
if (!userId) return;`
|
||||
try {
|
||||
await cb(userId);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
a nivel de BD funciona bien, pero como lo consultamos desde el front, mejor aplicamos del standard Booleano true/false