6321_negative_tickets #1371

Merged
jsegarra merged 222 commits from 6321_negative_tickets into dev 2025-02-11 09:04:31 +00:00
11 changed files with 260 additions and 143 deletions
Showing only changes of commit 5d71a16ec7 - Show all commits

View File

@ -25,11 +25,13 @@ const popupProxyRef = ref(null);
<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"> <template #default>
<QCard> <QPopupProxy ref="popupProxyRef" style="max-width: none">
<slot :popup="popupProxyRef"></slot> <QCard>
</QCard> <slot :popup="popupProxyRef"></slot>
</QPopupProxy> </QCard>
<QTooltip>{{ $t($props.tooltip) }}</QTooltip> </QPopupProxy>
<QTooltip>{{ $t($props.tooltip) }}</QTooltip>
</template>
</QBtn> </QBtn>
</template> </template>

View File

@ -25,10 +25,10 @@ const formattedValue = computed(() => props.value);
<style lang="scss" scoped> <style lang="scss" scoped>
.positive { .positive {
color: green; color: $secondary;
} }
.negative { .negative {
color: red; color: $negative;
} }
.neutral { .neutral {
color: orange; color: orange;

View File

@ -155,8 +155,6 @@ const gradientStyle = (value) => {
} }
return color; return color;
}; };
const tagColor = (match) => `color: ${!match ? 'red' : 'var(--vn-label-color)'}`;
const statusConditionalValue = (row) => { const statusConditionalValue = (row) => {
const total = MATCH_VALUES.reduce((acc, i) => acc + row[`match${i}`], 0); const total = MATCH_VALUES.reduce((acc, i) => acc + row[`match${i}`], 0);
return total; return total;
@ -274,13 +272,13 @@ const isSelectionAvailable = (itemProposal) => {
</QTd> </QTd>
</template> </template>
<template #column-tag5="{ row }"> <template #column-tag5="{ row }">
<span :style="tagColor(row.match5)">{{ row.value5 }}</span> <span :class="{ match: !row.match5 }">{{ row.value5 }}</span>
</template> </template>
<template #column-tag6="{ row }"> <template #column-tag6="{ row }">
<span :style="tagColor(row.match6)">{{ row.value6 }}</span> <span :class="{ match: !row.match6 }">{{ row.value6 }}</span>
</template> </template>
<template #column-tag7="{ row }"> <template #column-tag7="{ row }">
<span :style="tagColor(row.match7)">{{ row.value7 }}</span> <span :class="{ match: !row.match7 }">{{ row.value7 }}</span>
</template> </template>
<template #column-counter="{ row }"> <template #column-counter="{ row }">
<span <span

View File

@ -14,7 +14,7 @@ import VnImg from 'src/components/ui/VnImg.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import TicketSaleMoreActions from './TicketSaleMoreActions.vue'; import TicketSaleMoreActions from './TicketSaleMoreActions.vue';
import TicketTransfer from './TicketTransfer.vue'; import TicketTransferProxy from './TicketTransferProxy.vue';
import { toCurrency, toPercentage } from 'src/filters'; import { toCurrency, toPercentage } from 'src/filters';
import { useArrayData } from 'composables/useArrayData'; import { useArrayData } from 'composables/useArrayData';
@ -609,7 +609,7 @@ watch(
data-cy="ticketSaleTransferBtn" data-cy="ticketSaleTransferBtn"
> >
<QTooltip>{{ t('ticketSale.transferLines') }}</QTooltip> <QTooltip>{{ t('ticketSale.transferLines') }}</QTooltip>
<TicketTransfer <TicketTransferProxy
class="full-width" class="full-width"
:transfer="transfer" :transfer="transfer"
:ticket="store.data" :ticket="store.data"

View File

@ -0,0 +1,75 @@
<script setup>
import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import VnSelect from 'src/components/common/VnSelect.vue';
import { toDateFormat } from 'src/filters/date.js';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import split from './components/split';
const emit = defineEmits(['ticketTransfered']);
const $props = defineProps({
ticket: {
type: [Array, Object],
default: () => {},
},
});
const { t } = useI18n();
const splitDate = ref(Date.vnNew());
const agencySelected = ref(null);
const zoneSelected = ref(null);
const splitSelectedRows = async () => {
const tickets = Array.isArray($props.ticket) ? $props.ticket : [$props.ticket];
await split(tickets, splitDate.value);
emit('ticketTransfered', tickets);
};
const agencies = ref([]);
const handleDateChanged = async () => {
const { data: agencyData } = await axios.get('Agencies/getLanded', {
params: {
addressFk: 123,
agencyModeFk: 8,
warehouseFk: 1,
shipped: '2001-02-08T23:00:00.000Z',
},
});
if (!agencyData) agencies.value = [];
const { zoneFk } = agencyData;
const { data: zoneData } = await axios.get('Zones/Includingexpired', {
params: { filter: { fields: ['id', 'name'], where: { id: zoneFk } } },
});
agencies = zoneData;
if (zoneData.length === 1) zoneSelected.value = zoneData[0];
};
</script>
<template>
<VnInputDate
class="q-mr-sm"
:label="$t('New date')"
v-model="splitDate"
clearable
@update:model-value="handleDateChanged"
/>
<VnSelect
class="q-ml-sm"
:disable="splitDate"
:label="t('Agency')"
v-model="agencySelected"
:options="agencies"
/>
<QBtn class="q-mr-sm" color="primary" label="Split" @click="splitSelectedRows"></QBtn>
</template>
<style lang="scss">
.q-table__bottom.row.items-center.q-table__bottom--nodata {
border-top: none;
}
</style>
<i18n>
es:
Sales to transfer: Líneas a transferir
Destination ticket: Ticket destinatario
</i18n>

View File

@ -1,13 +1,10 @@
<script setup> <script setup>
import { ref, computed, onMounted } from 'vue'; import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import TicketTransferForm from './TicketTransferForm.vue'; import TicketTransferForm from './TicketTransferForm.vue';
import { toDateFormat } from 'src/filters/date.js'; import { toDateFormat } from 'src/filters/date.js';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import split from './components/split';
const emit = defineEmits(['ticketTransfered']); const emit = defineEmits(['ticketTransfered']);
const $props = defineProps({ const $props = defineProps({
@ -27,17 +24,12 @@ const $props = defineProps({
type: [Array, Object], type: [Array, Object],
default: () => {}, default: () => {},
}, },
split: {
type: Boolean,
default: false,
},
}); });
onMounted(() => (_transfer.value = $props.transfer)); onMounted(() => (_transfer.value = $props.transfer));
const { t } = useI18n(); const { t } = useI18n();
const transferFormRef = ref(null); const transferFormRef = ref(null);
const _transfer = ref(); const _transfer = ref();
const splitDate = ref(Date.vnNew());
const transferLinesColumns = computed(() => [ const transferLinesColumns = computed(() => [
{ {
label: t('ticketList.id'), label: t('ticketList.id'),
@ -93,87 +85,66 @@ const handleRowClick = (row) => {
transferFormRef.value.transferSales(ticketId); transferFormRef.value.transferSales(ticketId);
} }
}; };
const splitSelectedRows = async () => {
const tickets = Array.isArray($props.ticket) ? $props.ticket : [$props.ticket];
await split(tickets, splitDate.value);
emit('ticketTransfered', tickets);
};
</script> </script>
<template> <template>
<QPopupProxy ref="popupProxyRef" data-cy="ticketTransferPopup"> <QTable
<div class="flex row items-center q-ma-lg" v-if="$props.split"> :rows="transfer.sales"
<QBtn :columns="transferLinesColumns"
class="q-mr-sm" :title="t('Sales to transfer')"
color="primary" row-key="id"
label="Split" :pagination="{ rowsPerPage: 0 }"
@click="splitSelectedRows" class="full-width q-mt-md"
></QBtn> :no-data-label="t('globals.noResults')"
<VnInputDate :label="$t('New date')" v-model="splitDate"></VnInputDate> >
</div> <template #body-cell-quantity="{ row }">
<div v-else> <QTd @click.stop>
<QSeparator class="q-my-lg" color="primary" /> <VnInput
<QCard class="full-width q-px-md" style="display: flex; width: 80vw"> v-model.number="row.quantity"
<QTable :clearable="false"
:rows="transfer.sales" style="max-width: 60px"
:columns="transferLinesColumns" />
:title="t('Sales to transfer')" </QTd>
row-key="id" </template>
:pagination="{ rowsPerPage: 0 }" </QTable>
class="full-width q-mt-md" <QSeparator vertical spaced />
:no-data-label="t('globals.noResults')" <QTable
> v-if="transfer.lastActiveTickets"
<template #body-cell-quantity="{ row }"> :rows="transfer.lastActiveTickets"
<QTd @click.stop> :columns="destinationTicketColumns"
<VnInput :title="t('Destination ticket')"
v-model.number="row.quantity" row-key="id"
:clearable="false" class="full-width q-mt-md"
style="max-width: 60px" @row-click="(_, row) => handleRowClick(row)"
/> :no-data-label="t('globals.noResults')"
</QTd> :pagination="{ rowsPerPage: 0 }"
</template> >
</QTable> <template #body-cell-address="{ row }">
<QSeparator vertical spaced /> <QTd @click.stop>
<QTable <span>
v-if="transfer.lastActiveTickets" {{ row.nickname }}
:rows="transfer.lastActiveTickets" {{ row.name }}
:columns="destinationTicketColumns" {{ row.street }}
:title="t('Destination ticket')" {{ row.postalCode }}
row-key="id" {{ row.city }}
class="full-width q-mt-md" </span>
@row-click="(_, row) => handleRowClick(row)" <QTooltip>
:no-data-label="t('globals.noResults')" {{ row.nickname }}
:pagination="{ rowsPerPage: 0 }" {{ row.name }}
> {{ row.street }}
<template #body-cell-address="{ row }"> {{ row.postalCode }}
<QTd @click.stop> {{ row.city }}
<span> </QTooltip>
{{ row.nickname }} </QTd>
{{ row.name }} </template>
{{ row.street }}
{{ row.postalCode }}
{{ row.city }}
</span>
<QTooltip>
{{ row.nickname }}
{{ row.name }}
{{ row.street }}
{{ row.postalCode }}
{{ 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>
</div>
</QPopupProxy>
</template> </template>
<style lang="scss"> <style lang="scss">
.q-table__bottom.row.items-center.q-table__bottom--nodata { .q-table__bottom.row.items-center.q-table__bottom--nodata {

View File

@ -0,0 +1,54 @@
<script setup>
import { ref } from 'vue';
import TicketTransfer from './TicketTransfer.vue';
import Split from './TicketSplit.vue';
const emit = defineEmits(['ticketTransfered']);
const $props = defineProps({
mana: {
type: Number,
default: null,
},
newPrice: {
type: Number,
default: 0,
},
transfer: {
type: Object,
default: () => {},
},
ticket: {
type: [Array, Object],
default: () => {},
},
split: {
type: Boolean,
default: false,
},
});
const popupProxyRef = ref(null);
const splitRef = ref(null);
const transferRef = ref(null);
</script>
<template>
<QPopupProxy ref="popupProxyRef" data-cy="ticketTransferPopup">
<div class="flex row items-center q-ma-lg" v-if="$props.split">
<Split
ref="splitRef"
@splitSelectedRows="splitSelectedRows"
:ticket="$props.ticket"
/>
</div>
<div v-else>
<TicketTransfer
ref="transferRef"
:ticket="$props.ticket"
:sales="$props.sales"
:transfer="$props.transfer"
/>
</div>
</QPopupProxy>
</template>

View File

@ -4,7 +4,7 @@ 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 TicketTransfer from '../Card/TicketTransfer.vue'; import TicketTransferProxy from '../Card/TicketTransferProxy.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 { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
@ -27,7 +27,6 @@ const showProposalDialog = ref(false);
const showChangeQuantityDialog = ref(false); const showChangeQuantityDialog = ref(false);
const selectedRows = ref([]); const selectedRows = ref([]);
const route = useRoute(); const route = useRoute();
const itemLack = ref(null);
onMounted(() => { onMounted(() => {
stateStore.rightDrawer = false; stateStore.rightDrawer = false;
}); });
@ -88,6 +87,24 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
auto-load auto-load
/> />
<QIcon size="md" name="exposure" color="negative" />
<QIcon size="md" name="edit" color="negative" />
<QIcon size="md" name="shopping_cart" color="negative" />
<QIcon size="md" name="production_quantity_limits" color="negative" />
<QIcon size="md" name="playlist_add" color="negative" />
<QIcon size="md" name="task_alt" color="negative" />
<QIcon size="md" name="fact_check" color="negative" />
<QIcon size="md" name="inventory" color="negative" />
<QIcon size="md" name="receipt_long" color="negative" />
<QIcon size="md" name="sync" color="negative" />
<QIcon size="md" name="confirmation_number" color="negative" />
<QIcon size="md" name="airplane_ticket" color="negative" />
<QBadge color="negative" floating>
<!-- <QIcon size="md" name="highlight_off" color="white" /> -->
<QIcon size="md" name="edit" color="white" />
<QIcon size="md" name="sync" color="white" />
</QBadge>
<QIcon size="md" name="confirmation_number" color="negative" />
<TicketLackTable <TicketLackTable
ref="tableRef" ref="tableRef"
:filter="filterTable" :filter="filterTable"
@ -101,17 +118,22 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
icon="vn:splitline" icon="vn:splitline"
:disable="!(selectedRows.length === 1)" :disable="!(selectedRows.length === 1)"
> >
<QTooltip>{{ t('ticketSale.transferLines') }} </QTooltip> <template #default>
<TicketTransfer <QIcon name="vn:splitline" />
ref="transferFormRef" <QIcon name="vn:item" />
split="true"
:ticket="selectedRows" <QTooltip>{{ t('ticketSale.transferLines') }} </QTooltip>
:transfer="{ <TicketTransferProxy
sales: selectedRows, ref="transferFormRef"
lastActiveTickets: selectedRows.map((row) => row.id), split="true"
}" :ticket="selectedRows"
@ticket-transfered="reload" :transfer="{
></TicketTransfer> sales: selectedRows,
lastActiveTickets: selectedRows.map((row) => row.id),
}"
@ticket-transfered="reload"
></TicketTransferProxy>
</template>
</QBtn> </QBtn>
<QBtn <QBtn
color="primary" color="primary"
@ -129,7 +151,7 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
</QBtn> </QBtn>
<VnPopupProxy <VnPopupProxy
data-cy="changeItem" data-cy="changeItem"
icon="refresh" icon="sync"
: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')"
@ -143,7 +165,7 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
</VnPopupProxy> </VnPopupProxy>
<VnPopupProxy <VnPopupProxy
data-cy="changeState" data-cy="changeState"
icon="refresh" icon="sync"
: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')"
@ -157,7 +179,7 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
</VnPopupProxy> </VnPopupProxy>
<VnPopupProxy <VnPopupProxy
data-cy="changeQuantity" data-cy="changeQuantity"
icon="refresh" icon="sync"
: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')"

View File

@ -10,10 +10,9 @@ import { useState } from 'src/composables/useState';
import { useRole } from 'src/composables/useRole'; import { useRole } from 'src/composables/useRole';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import RightMenu from 'src/components/common/RightMenu.vue'; import RightMenu from 'src/components/common/RightMenu.vue';
const router = useRouter();
import VnImg from 'src/components/ui/VnImg.vue';
import TicketLackFilter from './TicketLackFilter.vue'; import TicketLackFilter from './TicketLackFilter.vue';
const router = useRouter();
const stateStore = useStateStore(); const stateStore = useStateStore();
const { t } = useI18n(); const { t } = useI18n();
const selectedRows = ref([]); const selectedRows = ref([]);
@ -130,7 +129,7 @@ const columns = computed(() => [
actions: [ actions: [
{ {
title: t('Open details'), title: t('Open details'),
icon: 'preview', icon: 'edit',
action: redirectToCreateView, action: redirectToCreateView,
isPrimary: true, isPrimary: true,
}, },
@ -173,24 +172,19 @@ onBeforeMount(() => {
selection: 'multiple', selection: 'multiple',
}" }"
> >
<template #column-itemFk="{ row }">
<div
style="display: flex; justify-content: space-around; align-items: center"
>
<span @click.stop>{{ row.itemFk }}</span>
</div>
</template>
<template #column-longName="{ row }"> <template #column-longName="{ row }">
<span class="link" @click.stop> <span class="link" @click.stop>
{{ row.longName }} {{ row.longName }}
<ItemDescriptorProxy :id="row.itemFk" /> <ItemDescriptorProxy :id="row.itemFk" />
</span> </span>
</template> </template>
<template #column-itemFk="{ row }">
<div
style="display: flex; justify-content: space-around; align-items: center"
>
<span class="link" @click.stop>{{ row.itemFk }}</span>
<VnImg
style="width: 50px; height: 50px; float: inline-end"
:id="row.itemFk"
class="rounded"
></VnImg>
</div>
</template>
</VnTable> </VnTable>
</template> </template>

View File

@ -1,7 +1,6 @@
<script setup> <script setup>
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 VnImg from 'src/components/ui/VnImg.vue';
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
@ -14,6 +13,7 @@ import VnTable from 'src/components/VnTable/VnTable.vue';
import TicketDescriptorProxy from '../Card/TicketDescriptorProxy.vue'; import TicketDescriptorProxy from '../Card/TicketDescriptorProxy.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue'; import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
const $props = defineProps({ const $props = defineProps({
filter: { filter: {
@ -240,13 +240,13 @@ function onBuysFetched(data) {
> >
<template #top-left> <template #top-left>
<div style="display: flex; align-items: center" v-if="itemLack"> <div style="display: flex; align-items: center" v-if="itemLack">
<VnImg :id="itemLack.itemFk" class="rounded image-wrapper"></VnImg> <!-- <VnImg :id="itemLack.itemFk" class="rounded image-wrapper"></VnImg> -->
<div class="flex column" style="align-items: center"> <div class="flex column" style="align-items: center">
<QBadge <QBadge
ref="badgeLackRef" ref="badgeLackRef"
class="q-ml-xs" class="q-ml-xs"
text-color="white" text-color="white"
:color="itemLack.lack === 0 ? 'green' : 'red'" :color="itemLack.lack !== 0 ? 'green' : 'red'"
:label="itemLack.lack" :label="itemLack.lack"
/> />
</div> </div>
@ -254,8 +254,8 @@ function onBuysFetched(data) {
<QBtn flat class="link text-blue"> <QBtn flat class="link text-blue">
{{ item?.longName ?? item.name }} {{ item?.longName ?? item.name }}
<ItemDescriptorProxy :id="entityId" /> <ItemDescriptorProxy :id="entityId" />
<FetchedTags class="q-ml-md" :item="item" :columns="7" />
</QBtn> </QBtn>
<FetchedTags class="q-ml-md" :item="item" :columns="7" />
</div> </div>
</div> </div>
</template> </template>
@ -324,16 +324,17 @@ function onBuysFetched(data) {
</div></QTd </div></QTd
> >
</template> </template>
<template #column-nickname="{ row }">
<span class="link" @click.stop>
{{ row.nickname }}
<CustomerDescriptorProxy :id="row.itemFk" />
</span>
</template>
<template #column-ticketFk="{ row }"> <template #column-ticketFk="{ row }">
<QBadge <span class="q-pa-sm link">
class="q-pa-sm"
:class="{ link: hasToIgnore(row) }"
:color="rowColor(row)"
>
{{ row.id }} {{ row.id }}
<TicketDescriptorProxy :id="row.id" /> <TicketDescriptorProxy :id="row.id" />
</QBadge> </span>
</template> </template>
<template #column-alertLevelCode="props"> <template #column-alertLevelCode="props">
<VnSelect <VnSelect

View File

@ -243,7 +243,7 @@ export default {
name: 'TicketNegative', name: 'TicketNegative',
meta: { meta: {
title: 'negative', title: 'negative',
icon: 'view_list', icon: 'exposure',
}, },
// redirect: { name: 'TicketNegative' }, // redirect: { name: 'TicketNegative' },
component: () => component: () =>