#6321 - Negative ticket #158

Open
jsegarra wants to merge 220 commits from 6321_negative_tickets into dev
8 changed files with 131 additions and 114 deletions
Showing only changes of commit 85a0e328e3 - Show all commits

View File

@ -1,7 +1,7 @@
<script setup> <script setup>
import { useI18n } from 'vue-i18n'; import { ref } from 'vue';
const { t } = useI18n();
const $props = defineProps({ defineProps({
icon: { icon: {
type: String, type: String,
default: 'refresh', default: 'refresh',
@ -19,16 +19,17 @@ const $props = defineProps({
default: 'primary', default: 'primary',
}, },
}); });
const popupProxyRef = ref(null);
</script> </script>
<template> <template>
<QBtn :color="$props.color" :icon="$props.icon" :label="t($props.label)"> <QBtn :color="$props.color" :icon="$props.icon" :label="$t($props.label)">
<QPopupProxy ref="popupProxyRef" style="max-width: none"> <QPopupProxy ref="popupProxyRef" style="max-width: none">
jgallego marked this conversation as resolved
Review

Contenedor para QPopupProxy con mas personalziación

Contenedor para QPopupProxy con mas personalziación
<QCard> <QCard>
<slot></slot> <slot :popup="popupProxyRef"></slot>
</QCard> </QCard>
</QPopupProxy> </QPopupProxy>
<QTooltip>{{ t($props.tooltip) }}</QTooltip> <QTooltip>{{ $t($props.tooltip) }}</QTooltip>
</QBtn> </QBtn>
</template> </template>

View File

@ -1,23 +1,21 @@
<script setup> <script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue'; import { computed, onMounted, onUnmounted, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import ChangeQuantityDialog from 'pages/Ticket/Negative/components/ChangeQuantityDialog.vue'; import ChangeQuantityDialog from './components/ChangeQuantityDialog.vue';
import ChangeStateDialog from 'pages/Ticket/Negative/components/ChangeStateDialog.vue'; import ChangeStateDialog from './components/ChangeStateDialog.vue';
import ChangeItemDialog from 'pages/Ticket/Negative/components/ChangeItemDialog.vue'; import ChangeItemDialog from './components/ChangeItemDialog.vue';
import FetchedTags from 'components/ui/FetchedTags.vue'; import FetchedTags from 'components/ui/FetchedTags.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import TicketTransfer from '../Card/TicketTransfer.vue'; import TicketTransfer from '../Card/TicketTransfer.vue';
import TicketMassiveUpdate from '../Card/TicketMassiveUpdate.vue';
import VnPaginate from 'src/components/ui/VnPaginate.vue'; import VnPaginate from 'src/components/ui/VnPaginate.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';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
// import { useArrayData } from 'src/composables/useArrayData';
import VnImg from 'src/components/ui/VnImg.vue'; import VnImg from 'src/components/ui/VnImg.vue';
import TicketLackTable from './TicketLackTable.vue'; import TicketLackTable from './TicketLackTable.vue';
import ItemProposalProxy from 'src/pages/Item/components/ItemProposalProxy.vue'; import ItemProposalProxy from 'src/pages/Item/components/ItemProposalProxy.vue';
import { toCurrency } from 'filters/index'; import VnPopupProxy from 'src/components/common/VnPopupProxy.vue';
const { t } = useI18n(); const { t } = useI18n();
const URL_KEY = 'Tickets/ItemLack'; const URL_KEY = 'Tickets/ItemLack';
@ -25,9 +23,9 @@ const editableStates = ref([]);
const stateStore = useStateStore(); const stateStore = useStateStore();
const proposalDialogRef = ref(); const proposalDialogRef = ref();
const tableRef = ref(); const tableRef = ref();
const changeItemDialogRef = ref(); const changeItemDialogRef = ref(null);
const changeStateDialogRef = ref(); const changeStateDialogRef = ref(null);
const changeQuantityDialogRef = ref(); const changeQuantityDialogRef = ref(null);
const showProposalDialog = ref(false); const showProposalDialog = ref(false);
const showChangeQuantityDialog = ref(false); const showChangeQuantityDialog = ref(false);
const showFree = ref(true); const showFree = ref(true);
@ -109,6 +107,11 @@ function onBuysFetched(data) {
function onTicketLackFetched(data) { function onTicketLackFetched(data) {
itemLack.value = data[0]; itemLack.value = data[0];
} }
const closeDialogs = (refs, evt) => {
changeItemDialogRef.value.hide();
changeQuantityDialogRef.value.hide();
changeStateDialogRef.value.hide();
};
</script> </script>
<template> <template>
@ -139,42 +142,43 @@ function onTicketLackFetched(data) {
<VnSubToolbar> <VnSubToolbar>
<template #st-data> <template #st-data>
<QBtnGroup push style="column-gap: 1px"> <QBtnGroup push style="column-gap: 1px">
{{ selectedRows.length }} <VnPopupProxy
<TicketMassiveUpdate
:disable="selectedRows.length < 1" :disable="selectedRows.length < 1"
:label="t('negative.buttonsUpdate.item')" :label="t('negative.buttonsUpdate.item')"
:tooltip="t('negative.detail.modal.changeItem.title')" :tooltip="t('negative.detail.modal.changeItem.title')"
> >
<template v-slot="{ popup }">
<ChangeItemDialog <ChangeItemDialog
ref="changeItemDialogRef" ref="changeItemDialogRef"
@update-item="changeItemDialogRef.hide()" @update-item="popup.hide()"
:selected-rows="selectedRows" :selected-rows="selectedRows"
></ChangeItemDialog> /></template>
</TicketMassiveUpdate> </VnPopupProxy>
<TicketMassiveUpdate <VnPopupProxy
:disable="selectedRows.length < 1" :disable="selectedRows.length < 1"
:label="t('negative.buttonsUpdate.state')" :label="t('negative.buttonsUpdate.state')"
:tooltip="t('negative.detail.modal.changeState.title')" :tooltip="t('negative.detail.modal.changeState.title')"
> >
<template v-slot="{ popup }">
<ChangeStateDialog <ChangeStateDialog
ref="changeStateDialogRef" ref="changeStateDialogRef"
@update-state="changeStateDialogRef.hide()" @update-state="popup.hide()"
:selected-rows="selectedRows" :selected-rows="selectedRows"
></ChangeStateDialog> /></template>
</TicketMassiveUpdate> </VnPopupProxy>
<TicketMassiveUpdate <VnPopupProxy
:disable="selectedRows.length < 1" :disable="selectedRows.length < 1"
:label="t('negative.buttonsUpdate.quantity')" :label="t('negative.buttonsUpdate.quantity')"
:tooltip="t('negative.detail.modal.changeQuantity.title')" :tooltip="t('negative.detail.modal.changeQuantity.title')"
@click="showChangeQuantityDialog = true" @click="showChangeQuantityDialog = true"
> >
<template v-slot="{ popup }">
<ChangeQuantityDialog <ChangeQuantityDialog
ref="changeQuantityDialogRef" ref="changeQuantityDialogRef"
@update-quantity="changeQuantityDialogRef.hide()" @update-quantity="popup.hide()"
:selected-rows="selectedRows" :selected-rows="selectedRows"
> /></template>
</ChangeQuantityDialog> </VnPopupProxy>
</TicketMassiveUpdate>
<QBtn <QBtn
color="primary" color="primary"
icon="vn:splitline" icon="vn:splitline"
@ -223,13 +227,7 @@ function onTicketLackFetched(data) {
<template #body> <template #body>
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<VnImg :id="item.id" class="rounded image-wrapper"></VnImg> <VnImg :id="item.id" class="rounded image-wrapper"></VnImg>
<div <div class="flex column" style="align-items: center">
style="
display: flex;
align-items: center;
flex-direction: column;
"
>
<QBadge <QBadge
ref="badgeLackRef" ref="badgeLackRef"
class="q-ml-xs" class="q-ml-xs"
@ -238,19 +236,14 @@ function onTicketLackFetched(data) {
:color="itemLack.lack === 0 ? 'green' : 'red'" :color="itemLack.lack === 0 ? 'green' : 'red'"
:label="itemLack.lack" :label="itemLack.lack"
/> />
<!-- <QBadge
color="secondary"
class="q-ml-xs q-mt-xs"
v-if="itemLack"
:label="toCurrency(itemLack.quantity * itemLack.price)"
outline
/> -->
</div> </div>
<div class="flex column left" style="align-items: flex-start">
<QBtn flat class="link text-blue"> <QBtn flat class="link text-blue">
{{ item.longName }} {{ item?.longName ?? item.name }}
<ItemDescriptorProxy :id="entityId" /> <ItemDescriptorProxy :id="entityId" />
</QBtn> </QBtn>
<FetchedTags class="q-ml-md" :item="item" :columns="3" /> <FetchedTags class="q-ml-md" :item="item" :columns="7" />
</div>
</div> </div>
</template> </template>
</VnPaginate> </VnPaginate>

View File

@ -23,7 +23,7 @@ watch(
(v) => { (v) => {
filterLack.value.where = v; filterLack.value.where = v;
tableRef.value.reload(filterLack); tableRef.value.reload(filterLack);
} },
); );
const filterLack = ref({ const filterLack = ref({
@ -78,8 +78,38 @@ const saveChange = async (field, { rowIndex, row }) => {
}; };
const entityId = computed(() => route.params.id); const entityId = computed(() => route.params.id);
const item = ref({}); const item = ref({});
const rowColor = (row) => {
if (!row.hasToIgnore) return 'negative';
return 'transparent';
};
// const textRowColor = (row) => {
// if (row.hasToIgnore) return 'black';
// return 'white';
// };
const columns = computed(() => [ const columns = computed(() => [
{
align: 'left',
label: t('negative.detail.isBasket'),
name: 'isBasket',
cardVisible: true,
create: true,
component: 'checkbox',
attrs: ({ row }) => {
return {
'toggle-indeterminate': true,
};
},
columnClass: 'shrink',
},
{
align: 'left',
label: t('negative.detail.hasSubstitution'),
name: 'hasSubstitution',
cardVisible: true,
create: true,
component: 'checkbox',
columnClass: 'shrink',
},
{ {
name: 'status', name: 'status',
align: 'left', align: 'left',
@ -139,19 +169,6 @@ const columns = computed(() => [
align: 'left', align: 'left',
sortable: true, sortable: true,
// columnFilter: {
// columnField: {
// component: 'select',
// event: getInputEvents,
// attrs: {
// event: (v) => console.error(v),
// options: editableStates.value,
// 'option-value': 'id',
// 'option-label': 'name',
// // },
// },
// },
}, },
{ {
name: 'zoneName', name: 'zoneName',
@ -177,13 +194,7 @@ const columns = computed(() => [
type: 'number', type: 'number',
}, },
]); ]);
const itemLackForm = ref();
const reload = async (data) => {
// window.location.reload();
console.error(data);
};
defineExpose({ reload });
const emit = defineEmits(['update:selection']); const emit = defineEmits(['update:selection']);
const tableRef = ref(null); const tableRef = ref(null);
@ -291,8 +302,10 @@ function onTicketLackFetched(data) {
</QIcon></QTd </QIcon></QTd
> >
</template> </template>
<template #column-ticketFk="{ row }" <template #column-ticketFk="{ row }">
><span class="link">{{ row.ticketFk }}</span> <QBadge class="q-pa-sm" :color="rowColor(row)">
{{ row.ticketFk }}
</QBadge>
<TicketDescriptorProxy :id="row.ticketFk" <TicketDescriptorProxy :id="row.ticketFk"
/></template> /></template>
<template #column-zoneName="{ row }"> <template #column-zoneName="{ row }">

View File

@ -3,10 +3,8 @@ import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; 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';
const emit = defineEmits(['update-item']); const emit = defineEmits(['update-item']);
const editableItems = ref([]);
const { t } = useI18n(); const { t } = useI18n();
const showChangeItemDialog = ref(false); const showChangeItemDialog = ref(false);
const newItem = ref(null); const newItem = ref(null);
@ -16,31 +14,29 @@ const $props = defineProps({
default: () => [], default: () => [],
}, },
}); });
const updateItem = async () => { const updateItem = async () => {
try { try {
showChangeItemDialog.value = true; showChangeItemDialog.value = true;
const rowsToUpdate = $props.selectedRows.map(({ ticketFk }) => const rowsToUpdate = $props.selectedRows.map(({ saleFk }) =>
axios.post(`Tickets/state`, { axios.post(`Sales/${saleFk}/updateConcept`, {
ticketFk, newConcept: newItem.value,
code: newItem.value, }),
})
); );
await Promise.all(rowsToUpdate); await Promise.allSettled(rowsToUpdate);
emit('update-item');
emit('update-item', newItem.value);
} catch (err) { } catch (err) {
console.error('Error updating item:', err);
return err; return err;
} }
}; };
</script> </script>
<template> <template>
<FetchData
url="State/editableStates"
@on-fetch="(data) => (editableItems = data)"
auto-load
/>
<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 }}
<span>{{ t('negative.detail.modal.changeItem.title') }}</span> <span>{{ t('negative.detail.modal.changeItem.title') }}</span>
<VnSelect <VnSelect
url="Items/WithName" url="Items/WithName"
@ -50,7 +46,6 @@ const updateItem = async () => {
option-label="name" option-label="name"
option-value="id" option-value="id"
v-model="newItem" v-model="newItem"
@update:model-value="updateItem(row)"
> >
</VnSelect> </VnSelect>
</QCardSection> </QCardSection>
@ -75,7 +70,9 @@ const updateItem = async () => {
} }
.grid-style-transition { .grid-style-transition {
transition: transform 0.28s, background-color 0.28s; transition:
transform 0.28s,
background-color 0.28s;
} }
#true { #true {

View File

@ -15,16 +15,17 @@ const $props = defineProps({
}); });
const emit = defineEmits(['update-quantity']); const emit = defineEmits(['update-quantity']);
const updateQuantity = async () => { const updateQuantity = async () => {
try {
showChangeQuantityDialog.value = true; showChangeQuantityDialog.value = true;
const rowsToUpdate = $props.selectedRows.map(({ saleFk }) => const rowsToUpdate = $props.selectedRows.map(({ saleFk }) =>
axios.post(`Sales/${saleFk}/updateQuantity`, { axios.post(`Sales/${saleFk}/updateQuantity`, {
quantity: +newQuantity.value, quantity: +newQuantity.value,
}) }),
); );
try { const results = await Promise.allSettled(rowsToUpdate);
await Promise.all(rowsToUpdate); console.log(results);
emit('update-quantity'); emit('update-quantity', newQuantity.value);
} catch (err) { } catch (err) {
return err; return err;
} }
@ -63,7 +64,9 @@ const updateQuantity = async () => {
} }
.grid-style-transition { .grid-style-transition {
transition: transform 0.28s, background-color 0.28s; transition:
transform 0.28s,
background-color 0.28s;
} }
#true { #true {

View File

@ -23,10 +23,11 @@ const updateState = async () => {
axios.post(`Tickets/state`, { axios.post(`Tickets/state`, {
ticketFk, ticketFk,
code: newState.value, code: newState.value,
}) }),
); );
await Promise.all(rowsToUpdate); const results = await Promise.allSettled(rowsToUpdate);
emit('update-state'); console.log(results);
emit('update-state', newState.value);
} catch (err) { } catch (err) {
return err; return err;
} }
@ -71,7 +72,9 @@ const updateState = async () => {
} }
.grid-style-transition { .grid-style-transition {
transition: transform 0.28s, background-color 0.28s; transition:
transform 0.28s,
background-color 0.28s;
} }
#true { #true {

View File

@ -238,16 +238,18 @@ negative:
isRookie: 'Is rookie' isRookie: 'Is rookie'
turno: 'Turn line' turno: 'Turn line'
showFree: Show Free lines showFree: Show Free lines
isBasket: 'Basket'
hasSubstitution: 'Has substitution'
modal: modal:
changeItem:
title: Update item reference
placeholder: New item
changeState: changeState:
title: Update tickets state title: Update tickets state
placeholder: New state placeholder: New state
changeQuantity: changeQuantity:
title: Update tickets quantity title: Update tickets quantity
placeholder: New quantity placeholder: New quantity
changeItem:
title: Update tickets item
placeholder: New item
split: split:
title: Are you sure you want to split selected tickets? title: Are you sure you want to split selected tickets?
subTitle: Confirm split action subTitle: Confirm split action

View File

@ -239,7 +239,7 @@ negative:
totalNegative: 'Total negativos' totalNegative: 'Total negativos'
days: Rango de dias days: Rango de dias
buttonsUpdate: buttonsUpdate:
jsegarra marked this conversation as resolved
Review

porqu ealgunos llevan comillas y otros no?

porqu ealgunos llevan comillas y otros no?
Review

Está mal, en su momento hizo falta pero unos cambios a posterior ya no lo requerían. No lo había visto.
Si que seria bueno, comentarlo en la próxima reunión porque el criterio que veo es que se usan cuando se les pasa una variable para renderizar

Está mal, en su momento hizo falta pero unos cambios a posterior ya no lo requerían. No lo había visto. Si que seria bueno, comentarlo en la próxima reunión porque el criterio que veo es que se usan cuando se les pasa una variable para renderizar
itemProposal: artículo item: artículo
state: Estado state: Estado
quantity: Cantidad quantity: Cantidad
modalOrigin: modalOrigin:
@ -266,7 +266,12 @@ negative:
isRookie: 'Cliente nuevo' isRookie: 'Cliente nuevo'
turno: 'Linea turno' turno: 'Linea turno'
showFree: Solo estado libre showFree: Solo estado libre
isBasket: 'Cesta'
jsegarra marked this conversation as resolved Outdated

o ponemos comillas a todos o a ninguno

o ponemos comillas a todos o a ninguno

Cierto, esta se va a la basura

Cierto, esta se va a la basura
hasSubstitution: 'Tiene sustitución'
modal: modal:
changeItem:
title: Actualizar referencia artículo
placeholder: Nuevo articulo
changeState: changeState:
title: Actualizar estado title: Actualizar estado
placeholder: Nuevo estado placeholder: Nuevo estado