Merge branch 'dev' into 6321_negative_tickets

This commit is contained in:
Javier Segarra 2025-01-30 00:08:58 +01:00
parent 07ad4b1655
commit 31d829ac05
14 changed files with 96 additions and 137 deletions

View File

@ -14,8 +14,8 @@ export default defineConfig({
downloadsFolder: 'test/cypress/downloads', downloadsFolder: 'test/cypress/downloads',
video: false, video: false,
specPattern: 'test/cypress/integration/**/*.spec.js', specPattern: 'test/cypress/integration/**/*.spec.js',
experimentalRunAllSpecs: true, experimentalRunAllSpecs: false,
watchForFileChanges: true, watchForFileChanges: false,
reporter: 'cypress-mochawesome-reporter', reporter: 'cypress-mochawesome-reporter',
reporterOptions: { reporterOptions: {
charts: true, charts: true,

View File

@ -30,7 +30,6 @@ export default configure(function (/* ctx */) {
// --> boot files are part of "main.js" // --> boot files are part of "main.js"
// https://v2.quasar.dev/quasar-cli/boot-files // https://v2.quasar.dev/quasar-cli/boot-files
boot: ['i18n', 'axios', 'vnDate', 'validations', 'quasar', 'quasar.defaults'], boot: ['i18n', 'axios', 'vnDate', 'validations', 'quasar', 'quasar.defaults'],
importStrategy: 'auto',
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
css: ['app.scss'], css: ['app.scss'],

View File

@ -334,8 +334,8 @@ function handleKeyDown(event) {
} }
function getCaption(opt) { function getCaption(opt) {
if (optionCaption.value === false && typeof optionCaption.value !== 'string') return; if (optionCaption.value === false) return;
return '' + (opt[optionCaption.value] || opt[optionValue.value]); return opt[optionCaption.value] || opt[optionValue.value];
} }
</script> </script>

View File

@ -273,6 +273,7 @@ input::-webkit-inner-spin-button {
} }
td { td {
font-size: 11pt; font-size: 11pt;
border-top: 1px solid var(--vn-page-color);
border-collapse: collapse; border-collapse: collapse;
} }
} }

View File

@ -105,37 +105,25 @@ const columns = computed(() => [
{ {
align: 'left', align: 'left',
sortable: true, sortable: true,
label: t('proposal.tag5'), label: t('item.list.color'),
name: 'tag5', name: 'tag5',
field: 'value5', field: 'value5',
// format: (val) => val,
style: "color: 'red'",
columnClass: 'expand', columnClass: 'expand',
}, },
{ {
align: 'left', align: 'left',
sortable: true, sortable: true,
label: t('proposal.tag6'), label: t('item.list.stems'),
name: 'tag6', name: 'tag6',
field: 'value6', field: 'value6',
// format: (val) => val,
attrs: ({ model }) => {
return {
style: `color: var(--vn-label-color)`,
};
},
style: (row) => `color: var(--vn-label-color)`,
columnClass: 'expand', columnClass: 'expand',
}, },
{ {
align: 'left', align: 'left',
sortable: true, sortable: true,
label: t('proposal.tag7'), label: t('item.list.producer'),
name: 'tag7', name: 'tag7',
field: 'value7', field: 'value7',
// format: (val) => val,
style: "color: 'red'",
columnClass: 'expand', columnClass: 'expand',
}, },

View File

@ -130,6 +130,7 @@ item:
origin: Orig. origin: Orig.
userName: Buyer userName: Buyer
weight: Weight weight: Weight
color: Color
weightByPiece: Weight/stem weightByPiece: Weight/stem
stemMultiplier: Multiplier stemMultiplier: Multiplier
producer: Producer producer: Producer

View File

@ -135,6 +135,7 @@ item:
size: Medida size: Medida
origin: Orig. origin: Orig.
weight: Peso weight: Peso
color: Color
weightByPiece: Peso/tallo weightByPiece: Peso/tallo
userName: Comprador userName: Comprador
stemMultiplier: Multiplicador stemMultiplier: Multiplicador

View File

@ -34,7 +34,6 @@ const $props = defineProps({
onMounted(() => (_transfer.value = $props.transfer)); onMounted(() => (_transfer.value = $props.transfer));
const { t } = useI18n(); const { t } = useI18n();
const QPopupProxyRef = ref(null);
const transferFormRef = ref(null); const transferFormRef = ref(null);
const _transfer = ref(); const _transfer = ref();
const splitDate = ref(Date.vnNew()); const splitDate = ref(Date.vnNew());
@ -110,71 +109,68 @@ const splitSelectedRows = async () => {
></QBtn> ></QBtn>
<VnInputDate :label="$t('New date')" v-model="splitDate"></VnInputDate> <VnInputDate :label="$t('New date')" v-model="splitDate"></VnInputDate>
</div> </div>
<QSeparator class="q-my-lg" color="primary" /> <div v-else>
<QCard <QSeparator class="q-my-lg" color="primary" />
v-if="!$props.split" <QCard class="full-width q-px-md" style="display: flex; width: 80vw">
class="full-width q-px-md" <QTable
style="display: flex; width: 80vw" :rows="transfer.sales"
> :columns="transferLinesColumns"
{{ ticket }}- {{ transfer }} :title="t('Sales to transfer')"
<QTable row-key="id"
:rows="transfer.sales" :pagination="{ rowsPerPage: 0 }"
:columns="transferLinesColumns" class="full-width q-mt-md"
:title="t('Sales to transfer')" :no-data-label="t('globals.noResults')"
row-key="id" >
:pagination="{ rowsPerPage: 0 }" <template #body-cell-quantity="{ row }">
class="full-width q-mt-md" <QTd @click.stop>
:no-data-label="t('globals.noResults')" <VnInput
> v-model.number="row.quantity"
<template #body-cell-quantity="{ row }"> :clearable="false"
<QTd @click.stop> style="max-width: 60px"
<VnInput />
v-model.number="row.quantity" </QTd>
:clearable="false" </template>
style="max-width: 60px" </QTable>
/> <QSeparator vertical spaced />
</QTd> <QTable
</template> v-if="transfer.lastActiveTickets"
</QTable> :rows="transfer.lastActiveTickets"
<QSeparator vertical spaced /> :columns="destinationTicketColumns"
<QTable :title="t('Destination ticket')"
v-if="transfer.lastActiveTickets" row-key="id"
:rows="transfer.lastActiveTickets" class="full-width q-mt-md"
:columns="destinationTicketColumns" @row-click="(_, row) => handleRowClick(row)"
:title="t('Destination ticket')" :no-data-label="t('globals.noResults')"
row-key="id" :pagination="{ rowsPerPage: 0 }"
class="full-width q-mt-md" >
@row-click="(_, row) => handleRowClick(row)" <template #body-cell-address="{ row }">
:no-data-label="t('globals.noResults')" <QTd @click.stop>
:pagination="{ rowsPerPage: 0 }" <span>
> {{ row.nickname }}
<template #body-cell-address="{ row }"> {{ row.name }}
<QTd @click.stop> {{ row.street }}
<span> {{ row.postalCode }}
{{ row.nickname }} {{ row.city }}
{{ row.name }} </span>
{{ row.street }} <QTooltip>
{{ row.postalCode }} {{ row.nickname }}
{{ row.city }} {{ row.name }}
</span> {{ row.street }}
<QTooltip> {{ row.postalCode }}
{{ row.nickname }} {{ row.city }}
{{ row.name }} </QTooltip>
{{ row.street }} </QTd>
{{ row.postalCode }} </template>
{{ row.city }}
</QTooltip>
</QTd>
</template>
<template #no-data> <template #no-data>
<TicketTransferForm ref="transferFormRef" v-bind="$props" /> <TicketTransferForm ref="transferFormRef" v-bind="$props" />
</template> </template>
<template #bottom> <template #bottom>
<TicketTransferForm ref="transferFormRef" v-bind="$props" /> <TicketTransferForm ref="transferFormRef" v-bind="$props" />
</template> </template>
</QTable> </QTable>
</QCard> </QCard>
</div>
</QPopupProxy> </QPopupProxy>
</template> </template>
<style lang="scss"> <style lang="scss">
@ -186,6 +182,4 @@ const splitSelectedRows = async () => {
es: es:
Sales to transfer: Líneas a transferir Sales to transfer: Líneas a transferir
Destination ticket: Ticket destinatario Destination ticket: Ticket destinatario
Transfer to ticket: Transferir a ticket
New ticket: Nuevo ticket
</i18n> </i18n>

View File

@ -1,8 +1,9 @@
import axios from 'axios'; import axios from 'axios';
import notifyResults from 'src/utils/notifyResults';
export default async function (data) { export default async function (data) {
const reducedData = data.reduce((acc, item) => { const reducedData = data.reduce((acc, item) => {
const existing = acc.find((obj) => obj.ticketFk === item.id); const existing = acc.find(({ ticketFk }) => ticketFk === item.id);
if (existing) { if (existing) {
existing.sales.push(item.saleFk); existing.sales.push(item.saleFk);
} else { } else {
@ -11,29 +12,11 @@ export default async function (data) {
return acc; return acc;
}, []); }, []);
console.log(reducedData);
const promises = reducedData.map((params) => axios.post(`Tickets/split`, params)); const promises = reducedData.map((params) => axios.post(`Tickets/split`, params));
const results = await Promise.allSettled(promises); const results = await Promise.allSettled(promises);
// results.forEach((result, index) => { notifyResults(results, 'ticketFk');
// if (result.status === 'fulfilled') {
// console.log(`Promise ${index + 1} fulfilled:`, result.value.data);
// // Mostrar notificación de éxito
// Notify.create({
// type: 'positive',
// message: `Operación ${index + 1} completada con éxito.`,
// });
// } else {
// console.error(`Promise ${index + 1} rejected:`, result.reason);
// // Mostrar notificación de error
// Notify.create({
// type: 'negative',
// message: `Operación ${index + 1} fallida: ${result.reason.message}`,
// });
// }
// });
return results; return results;
} }

View File

@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n';
import ChangeQuantityDialog from './components/ChangeQuantityDialog.vue'; import ChangeQuantityDialog from './components/ChangeQuantityDialog.vue';
import ChangeStateDialog from './components/ChangeStateDialog.vue'; import ChangeStateDialog from './components/ChangeStateDialog.vue';
import ChangeItemDialog from './components/ChangeItemDialog.vue'; import ChangeItemDialog from './components/ChangeItemDialog.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import TicketTransfer from '../Card/TicketTransfer.vue'; import TicketTransfer from '../Card/TicketTransfer.vue';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'src/components/FetchData.vue';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
@ -167,7 +166,6 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
<TicketTransfer <TicketTransfer
ref="transferFormRef" ref="transferFormRef"
split="true" split="true"
class="full-width"
:ticket="selectedRows" :ticket="selectedRows"
:transfer="{ :transfer="{
sales: selectedRows, sales: selectedRows,
@ -175,7 +173,11 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
}" }"
></TicketTransfer> ></TicketTransfer>
</QBtn> </QBtn>
<QBtn color="primary" @click="showProposalDialog = true"> <QBtn
color="primary"
@click="showProposalDialog = true"
:disable="selectedRows.length < 1"
>
<QIcon <QIcon
name="import_export" name="import_export"
class="rotate-90" class="rotate-90"

View File

@ -1,12 +1,10 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import handlePromiseResults from './notifyResults'; import notifyResults from 'src/utils/notifyResults';
const emit = defineEmits(['update-item']); const emit = defineEmits(['update-item']);
const { t } = useI18n();
const showChangeItemDialog = ref(false); const showChangeItemDialog = ref(false);
const newItem = ref(null); const newItem = ref(null);
const $props = defineProps({ const $props = defineProps({
@ -27,7 +25,7 @@ const updateItem = async () => {
}), }),
); );
const result = await Promise.allSettled(rowsToUpdate); const result = await Promise.allSettled(rowsToUpdate);
handlePromiseResults(result, 'saleFk'); notifyResults(result, 'saleFk');
emit('update-item', newItem.value); emit('update-item', newItem.value);
} catch (err) { } catch (err) {
console.error('Error updating item:', err); console.error('Error updating item:', err);
@ -40,7 +38,7 @@ const updateItem = async () => {
<QCard class="q-pa-sm"> <QCard class="q-pa-sm">
<QCardSection class="row items-center justify-center column items-stretch"> <QCardSection class="row items-center justify-center column items-stretch">
{{ showChangeItemDialog }} {{ showChangeItemDialog }}
<span>{{ t('negative.detail.modal.changeItem.title') }}</span> <span>{{ $t('negative.detail.modal.changeItem.title') }}</span>
<VnSelect <VnSelect
url="Items/WithName" url="Items/WithName"
:fields="['id', 'name']" :fields="['id', 'name']"
@ -53,9 +51,9 @@ const updateItem = async () => {
</VnSelect> </VnSelect>
</QCardSection> </QCardSection>
<QCardActions align="right"> <QCardActions align="right">
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup /> <QBtn :label="$t('globals.cancel')" color="primary" flat v-close-popup />
<QBtn <QBtn
:label="t('globals.confirm')" :label="$t('globals.confirm')"
color="primary" color="primary"
:disable="!newItem" :disable="!newItem"
@click="updateItem" @click="updateItem"

View File

@ -1,11 +1,9 @@
<script setup> <script setup>
import { ref, defineEmits } from 'vue'; import { ref, defineEmits } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import handlePromiseResults from './notifyResults'; import notifyResults from 'src/utils/notifyResults';
const { t } = useI18n();
const showChangeQuantityDialog = ref(false); const showChangeQuantityDialog = ref(false);
const newQuantity = ref(null); const newQuantity = ref(null);
const $props = defineProps({ const $props = defineProps({
@ -26,7 +24,7 @@ const updateQuantity = async () => {
); );
const result = await Promise.allSettled(rowsToUpdate); const result = await Promise.allSettled(rowsToUpdate);
handlePromiseResults(result, 'saleFk'); notifyResults(result, 'saleFk');
emit('update-quantity', newQuantity.value); emit('update-quantity', newQuantity.value);
} catch (err) { } catch (err) {
@ -38,18 +36,18 @@ const updateQuantity = async () => {
<template> <template>
<QCard class="q-pa-sm"> <QCard class="q-pa-sm">
<QCardSection class="row items-center justify-center column items-stretch"> <QCardSection class="row items-center justify-center column items-stretch">
<span>{{ t('negative.detail.modal.changeQuantity.title') }}</span> <span>{{ $t('negative.detail.modal.changeQuantity.title') }}</span>
<VnInput <VnInput
type="number" type="number"
:min="0" :min="0"
:label="t('negative.detail.modal.changeQuantity.placeholder')" :label="$t('negative.detail.modal.changeQuantity.placeholder')"
v-model="newQuantity" v-model="newQuantity"
/> />
</QCardSection> </QCardSection>
<QCardActions align="right"> <QCardActions align="right">
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup /> <QBtn :label="$t('globals.cancel')" color="primary" flat v-close-popup />
<QBtn <QBtn
:label="t('globals.confirm')" :label="$t('globals.confirm')"
color="primary" color="primary"
:disable="!newQuantity || newQuantity < 0" :disable="!newQuantity || newQuantity < 0"
@click="updateQuantity" @click="updateQuantity"

View File

@ -1,14 +1,12 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import handlePromiseResults from './notifyResults'; import notifyResults from 'src/utils/notifyResults';
const emit = defineEmits(['update-state']); const emit = defineEmits(['update-state']);
const editableStates = ref([]); const editableStates = ref([]);
const { t } = useI18n();
const showChangeStateDialog = ref(false); const showChangeStateDialog = ref(false);
const newState = ref(null); const newState = ref(null);
const $props = defineProps({ const $props = defineProps({
@ -27,7 +25,7 @@ const updateState = async () => {
}), }),
); );
const result = await Promise.allSettled(rowsToUpdate); const result = await Promise.allSettled(rowsToUpdate);
handlePromiseResults(result, 'ticketFk'); notifyResults(result, 'ticketFk');
emit('update-state', newState.value); emit('update-state', newState.value);
} catch (err) { } catch (err) {
@ -44,9 +42,9 @@ const updateState = async () => {
/> />
<QCard class="q-pa-sm"> <QCard class="q-pa-sm">
<QCardSection class="row items-center justify-center column items-stretch"> <QCardSection class="row items-center justify-center column items-stretch">
<span>{{ t('negative.detail.modal.changeState.title') }}</span> <span>{{ $t('negative.detail.modal.changeState.title') }}</span>
<VnSelect <VnSelect
:label="t('negative.detail.modal.changeState.placeholder')" :label="$t('negative.detail.modal.changeState.placeholder')"
v-model="newState" v-model="newState"
:options="editableStates" :options="editableStates"
option-label="name" option-label="name"
@ -54,9 +52,9 @@ const updateState = async () => {
/> />
</QCardSection> </QCardSection>
<QCardActions align="right"> <QCardActions align="right">
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup /> <QBtn :label="$t('globals.cancel')" color="primary" flat v-close-popup />
<QBtn <QBtn
:label="t('globals.confirm')" :label="$t('globals.confirm')"
color="primary" color="primary"
:disable="!newState" :disable="!newState"
@click="updateState" @click="updateState"

View File

@ -4,16 +4,12 @@ export default function (results, key) {
results.forEach((result, index) => { results.forEach((result, index) => {
if (result.status === 'fulfilled') { if (result.status === 'fulfilled') {
const data = JSON.parse(result.value.config.data); const data = JSON.parse(result.value.config.data);
console.log(`Promise ${index + 1} fulfilled:`, result.value);
// Mostrar notificación de éxito
Notify.create({ Notify.create({
type: 'positive', type: 'positive',
message: `Operación (${index + 1}) ${data[key]} completada con éxito.`, message: `Operación (${index + 1}) ${data[key]} completada con éxito.`,
}); });
} else { } else {
const data = JSON.parse(result.reason.config.data); const data = JSON.parse(result.reason.config.data);
console.error(`Promise ${index + 1} rejected:`, result.reason);
// Mostrar notificación de error
Notify.create({ Notify.create({
type: 'negative', type: 'negative',
message: `Operación (${index + 1}) ${data[key]} fallida: ${result.reason.message}`, message: `Operación (${index + 1}) ${data[key]} fallida: ${result.reason.message}`,