#6321 - Negative ticket #158

Open
jsegarra wants to merge 156 commits from 6321_negative_tickets into dev
6 changed files with 244 additions and 232 deletions
Showing only changes of commit 9ec1c5ff4b - Show all commits

View File

@ -9,6 +9,9 @@ import VnLv from 'src/components/ui/VnLv.vue';
import { toCurrency } from 'filters/index'; import { toCurrency } from 'filters/index';
import VnStockValueDisplay from 'src/components/ui/VnStockValueDisplay.vue'; import VnStockValueDisplay from 'src/components/ui/VnStockValueDisplay.vue';
import { useDialogPluginComponent } from 'quasar'; import { useDialogPluginComponent } from 'quasar';
import VnTable from 'src/components/VnTable/VnTable.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const MATCH_VALUES = [5, 6, 7, 8]; const MATCH_VALUES = [5, 6, 7, 8];
const { t } = useI18n(); const { t } = useI18n();
@ -79,12 +82,23 @@ const columns = computed(() => [
label: t('proposal.available'), label: t('proposal.available'),
name: 'available', name: 'available',
field: 'available', field: 'available',
columnClass: 'shrink',
columnFilter: {
component: 'input',
type: 'number',
columnClass: 'shrink',
},
}, },
{ {
...defaultColumnAttrs, ...defaultColumnAttrs,
label: t('proposal.difference'), label: t('proposal.difference'),
name: 'difference', name: 'difference',
field: (item) => (item.id % 2 === 0 ? 10 : -10), format: (item) => (item.id % 2 === 0 ? 10 : -10),
columnFilter: {
component: 'input',
type: 'number',
columnClass: 'shrink',
},
}, },
{ {
...defaultColumnAttrs, ...defaultColumnAttrs,
@ -106,6 +120,8 @@ const columns = computed(() => [
label: t('proposal.longName'), label: t('proposal.longName'),
name: 'longName', name: 'longName',
field: 'longName', field: 'longName',
columnClass: 'expand',
columnFilter: { class: 'expand' },
}, },
// { // {
// ...defaultColumnAttrs, // ...defaultColumnAttrs,
@ -152,12 +168,22 @@ const columns = computed(() => [
label: t('proposal.price2'), label: t('proposal.price2'),
name: 'price2', name: 'price2',
field: 'price2', field: 'price2',
columnFilter: {
component: 'input',
type: 'number',
class: 'expand',
},
}, },
{ {
...defaultColumnAttrs, ...defaultColumnAttrs,
label: t('proposal.minQuantity'), label: t('proposal.minQuantity'),
name: 'minQuantity', name: 'minQuantity',
field: 'minQuantity', field: 'minQuantity',
columnFilter: {
component: 'input',
type: 'number',
class: 'expand',
},
}, },
{ {
...defaultColumnAttrs, ...defaultColumnAttrs,
@ -200,82 +226,15 @@ onUnmounted(() => {});
</script> </script>
<template> <template>
<QPopupProxy ref="popupProxyRef"> <QPopupProxy ref="popupProxyRef">
<QCard> <QCard style="min-width: 500px">
<!-- {{ itemLack }} -->
<QCardSection v-if="false" class="row items-center q-pb-none">
<VnLv class="image">
<template #label>
<QImg
:src="`/api/Images/catalog/50x50/${item.id}/download?access_token=${token}`"
spinner-color="primary"
:ratio="1"
height="50px"
width="50px"
class="image remove-bg"
:alt="'asdads'"
/>
</template>
<template #value>
<QBtn flat class="link text-blue">
{{ item.longName }}
<ItemDescriptorProxy :id="item.id" />
</QBtn>
<FetchedTags class="q-ml-md" :item="item" :max-length="5" />
</template>
</VnLv>
<QSpace />
<QBtn icon="close" flat round dense v-close-popup />
</QCardSection>
<QCardSection
v-if="false"
class="row items-center justify-center column items-stretch"
>
<span class="text-h6 text-grey">
<!-- {{ currentTicket }} -->
<!-- {{
t('proposal.title', {
ticketFk: currentTicket.ticketFk,
saleFk: currentTicket.saleFk,
})
}} -->
</span>
</QCardSection>
<QCardActions v-if="$props.replaceAction">
<!-- <QBtn
:label="t('globals.removeSelection')"
color="primary"
flat
:disable="proposalSelected.length < 1 || quantity === 0"
@click="proposalSelected = []"
/> -->
<QBtn
:label="t('globals.replace')"
color="primary"
:loading="isLoading"
@click="confirm"
:disable="proposalSelected.length < 1 || quantity === 0"
unelevated
/>
<QInput
v-model.number="quantity"
v-if="quantity > -1"
@update:model-value="(val) => (quantity = val)"
type="number"
min="0"
:label="t('proposal.quantityToReplace')"
class="q-ml-lg"
/>
</QCardActions>
<QCardSection class="row items-center justify-center column items-stretch"> <QCardSection class="row items-center justify-center column items-stretch">
<!-- <VnRow style="display: flex"> --> <!-- <VnRow style="display: flex"> -->
<div> <div style="width: 62vw">
<!-- {{ proposalSelected }} --> <!-- {{ proposalSelected }} -->
{{ $props.itemLack.itemFk }} {{ $props.itemLack.itemFk }}
{{ $props.itemLack.warehouseFk }} {{ $props.itemLack.warehouseFk }}
<VnPaginate <!-- {{ rows[1].available }} -->
:append="false" <VnTable
data-key="ItemsGetSimilar" data-key="ItemsGetSimilar"
url="Items/getSimilar" url="Items/getSimilar"
:filter="{ :filter="{
@ -285,44 +244,53 @@ onUnmounted(() => {});
}, },
}" }"
auto-load auto-load
>
<template #body="{ rows }">
<!-- {{ rows[1].available }} -->
<QTable
:rows="rows"
:columns="columns" :columns="columns"
row-key="id"
selection="single"
disa
:pagination="{ rowsPerPage: 0 }"
class="full-width q-mt-md" class="full-width q-mt-md"
:no-data-label="t('globals.noResults')"
v-model:selected="proposalSelected" v-model:selected="proposalSelected"
:dense="$q.screen.lt.md" row-key="id"
flat :is-editable="false"
:grid="$q.screen.lt.md" :right-search="false"
auto-load :without-header="false"
:rows-per-page-options="[0]" :disable-option="{ card: true, table: true }"
hide-pagination :table="{
hide-bottom 'row-key': 'id',
selection: 'multiple',
}"
> >
<template #top-left>
<div v-if="$props.replaceAction" style="display: flex">
<QBtn
:label="t('globals.replace')"
color="primary"
:loading="isLoading"
@click="confirm"
:disable="
proposalSelected.length < 1 || quantity === 0
"
unelevated
/>
<VnInputNumber
v-model.number="quantity"
v-if="quantity > -1"
@update:model-value="(val) => (quantity = val)"
type="number"
min="0"
:label="t('proposal.quantityToReplace')"
class="q-ml-lg"
/></div
></template>
<!-- <template #body="scope">{{ scope }}</template> -->
<template #body-selection="scope"> <template #body-selection="scope">
<QTd align="center" v-if="$props.replaceAction" <QTd align="center" v-if="$props.replaceAction"
><QCheckbox ><QCheckbox
v-model="scope.selected" v-model="scope.selected"
:disable=" :disable="
!( !(scope.row.available >= itemLack.lack * -1)
scope.row.available >=
itemLack.lack * -1
)
" "
> >
<QTooltip <QTooltip
v-if=" v-if="
!( !(scope.row.available >= itemLack.lack * -1)
scope.row.available >=
itemLack.lack * -1
)
" "
> >
Nop</QTooltip Nop</QTooltip
@ -353,8 +321,8 @@ onUnmounted(() => {});
</QTd> </QTd>
</QTr> --> </QTr> -->
</template> </template>
<template #body-cell-longName="{ row, value }"> <template #column-longName="{ row, value }">
<QTd align="left" class="text-primary"> <!-- <QTd align="left" class="text-primary"> -->
<QTooltip> <QTooltip>
{{ row.id }} {{ row.id }}
</QTooltip> </QTooltip>
@ -365,15 +333,16 @@ onUnmounted(() => {});
height="50px" height="50px"
width="50px" width="50px"
class="image remove-bg" class="image remove-bg"
:alt="'asdads'" /> :alt="'asdads'"
/>
<QBtn flat color="blue" dense>{{ value }}</QBtn> <QBtn flat color="blue" dense>{{ value }}</QBtn>
<ItemDescriptorProxy :id="row.id" /> <ItemDescriptorProxy :id="row.id" />
<FetchedTags :item="row" :max-length="5" <FetchedTags :item="row" :max-length="5" />
/></QTd> <!-- </QTd> -->
</template> </template>
<template #body-cell-status="{ value }"> <template #column-status="{ value }">
<QTd class="col" align="center"> <!-- <QTd class="col" align="center"> -->
<div <div
:style="{ background: gradientStyle(value) }" :style="{ background: gradientStyle(value) }"
class="compatibility" class="compatibility"
@ -382,32 +351,31 @@ onUnmounted(() => {});
{{ compatibilityItem(value) }} {{ compatibilityItem(value) }}
</QTooltip> </QTooltip>
</div> </div>
</QTd> <!-- </QTd> -->
</template> </template>
<!-- <template #body-cell-tags="{ row }"> <!-- <template #column-tags="{ row }">
<QTd class="col" align="center"> </QTd> <QTd class="col" align="center"> </QTd>
</template> --> </template> -->
<template #body-cell-price2="{ row, value }"> <template #column-price2="{ row }">
<QTd <!-- <QTd
class="col" class="col"
align="center" align="center"
:class="[conditionalValuePrice(value)]" :class="[conditionalValuePrice(value)]"
> > -->
<QTooltip> <QTooltip>
{{ toCurrency(row.price2) }} {{ toCurrency(row.price2) }}
</QTooltip> </QTooltip>
{{ toCurrency(row.price2) }} {{ toCurrency(row.price2) }}
</QTd> <!-- </QTd> -->
</template> </template>
<template #body-cell-difference="{ value }"> <template #column-difference="{ row }">
<QTd class="col" align="left"> <pre>{{ row.difference }}</pre>
<VnStockValueDisplay :value="value" /> <!-- <QTd class="col" align="left"> -->
</QTd> <!-- <VnStockValueDisplay :value="value" /> -->
<!-- </QTd> -->
</template> </template>
</QTable> </VnTable>
</template>
</VnPaginate>
</div> </div>
</QCardSection> </QCardSection>
</QCard> </QCard>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, ref } from 'vue'; import { computed, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useSession } from 'composables/useSession'; import { useSession } from 'composables/useSession';
import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useSummaryDialog } from 'src/composables/useSummaryDialog';
@ -17,7 +17,13 @@ import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputDate from 'components/common/VnInputDate.vue';
import VnTable from 'components/VnTable/VnTable.vue'; import VnTable from 'components/VnTable/VnTable.vue';
const $props = defineProps({
filter: {
type: Object,
default: () => ({}),
},
});
watch($props.filter, (v) => (filterLack.value.where = v));
const { t } = useI18n(); const { t } = useI18n();
const { viewSummary } = useSummaryDialog(); const { viewSummary } = useSummaryDialog();
const quasar = useQuasar(); const quasar = useQuasar();
@ -27,7 +33,7 @@ const tableRef = ref([]);
const confirmationDialog = ref(false); const confirmationDialog = ref(false);
const startingDate = ref(null); const startingDate = ref(null);
const router = useRouter(); const router = useRouter();
const routeFilter = { const filterLack = ref({
include: [ include: [
{ {
relation: 'workers', relation: 'workers',
@ -36,7 +42,8 @@ const routeFilter = {
}, },
}, },
], ],
}; where: { alertLevel: 'FREE' },
});
const columns = computed(() => [ const columns = computed(() => [
{ {
align: 'left', align: 'left',
@ -306,7 +313,7 @@ const openTicketsDialog = (id) => {
:columns="columns" :columns="columns"
:right-search="false" :right-search="false"
:is-editable="true" :is-editable="true"
:filter="routeFilter" :filter="filterLack"
redirect="route" redirect="route"
:row-click="false" :row-click="false"
:create="{ :create="{

View File

@ -34,7 +34,7 @@ const emit = defineEmits(['refreshData']);
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t } = useI18n();
const QPopupProxyRef = ref(null); const popupProxyRef = ref(null);
const transferLinesColumns = computed(() => [ const transferLinesColumns = computed(() => [
{ {
@ -102,7 +102,7 @@ const transferSales = async (ticketId) => {
</script> </script>
<template> <template>
<QPopupProxy :breakpoint="600" ref="QPopupProxyRef"> <QPopupProxy ref="popupProxyRef">
<QCard class="full-width q-px-md" style="display: flex; width: 100vw"> <QCard class="full-width q-px-md" style="display: flex; width: 100vw">
<QTable <QTable
v-if="transfer.sales" v-if="transfer.sales"

View File

@ -1,7 +1,6 @@
<script setup> <script setup>
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'; import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { QBtn, QCheckbox } from 'quasar';
import axios from 'axios'; import axios from 'axios';
import ChangeQuantityDialog from 'pages/Ticket/Negative/components/ChangeQuantityDialog.vue'; import ChangeQuantityDialog from 'pages/Ticket/Negative/components/ChangeQuantityDialog.vue';
import ChangeStateDialog from 'pages/Ticket/Negative/components/ChangeStateDialog.vue'; import ChangeStateDialog from 'pages/Ticket/Negative/components/ChangeStateDialog.vue';
@ -196,8 +195,8 @@ const replaceItem = () => {
sales: selectedRows, sales: selectedRows,
lastActiveTickets: selectedRows.map((row) => row.ticketFk), lastActiveTickets: selectedRows.map((row) => row.ticketFk),
}" }"
></TicketTransfer ></TicketTransfer>
></QBtn> </QBtn>
<QBtn color="primary" @click="showProposalDialog = true"> <QBtn color="primary" @click="showProposalDialog = true">
<QIcon name="import_export" class="rotate-90"></QIcon> <QIcon name="import_export" class="rotate-90"></QIcon>
<ItemProposal <ItemProposal
@ -217,7 +216,7 @@ const replaceItem = () => {
</template> </template>
</VnSubToolbar> </VnSubToolbar>
<QPage> <QPage>
<div class="full-width q-pa-md"> <div class="full-width q-pa-md" style="padding-bottom: 0px">
<!-- <p>item:{{ item }}</p> <!-- <p>item:{{ item }}</p>
<p>itemLack:{{ itemLack }}</p> <p>itemLack:{{ itemLack }}</p>
<p>selectedRows:{{ selectedRows }}</p> <p>selectedRows:{{ selectedRows }}</p>
@ -229,31 +228,32 @@ const replaceItem = () => {
@on-fetch="copyOriginalRowsData" @on-fetch="copyOriginalRowsData"
auto-load auto-load
> >
<template #body="{ rows }"> <template #body>
<!-- <VnLv > <!-- <VnLv >
<template #label> --> <template #label> -->
<div class="q-mb-lg image" 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>
<QBtn flat class="link text-blue">
{{ item.longName }}
<ItemDescriptorProxy :id="entityId" />
</QBtn>
<QBadge <QBadge
class="q-ml-xs"
v-if="itemLack" v-if="itemLack"
text-color="white" text-color="white"
:color="itemLack.lack === 0 ? 'green' : 'red'" :color="itemLack.lack === 0 ? 'green' : 'red'"
:label="itemLack.lack" :label="itemLack.lack"
/> />
<QBtn flat class="link text-blue">
{{ item.longName }}
<ItemDescriptorProxy :id="entityId" />
</QBtn>
<FetchedTags class="q-ml-md" :item="item" :max-length="5" /> <FetchedTags class="q-ml-md" :item="item" :max-length="5" />
</div> </div>
{{ rows }} <!-- {{ rows }} -->
<!-- </template> <!-- </template>
<template #value> </template> <template #value> </template>
</VnLv> --> </VnLv> -->
</template> </template>
</VnPaginate> </VnPaginate>
</div> </div>
<TicketLackTable></TicketLackTable> <TicketLackTable :filter="{ alertLevel: showFree }"></TicketLackTable>
</QPage> </QPage>
<!--<HandleSplited <!--<HandleSplited
@ -273,4 +273,7 @@ const replaceItem = () => {
opacity: 0; opacity: 0;
background-color: $primary; background-color: $primary;
} }
.q-table.q-table__container > div:first-child {
border-radius: unset;
}
</style> </style>

View File

@ -12,8 +12,10 @@ import { useState } from 'src/composables/useState';
import { useRole } from 'src/composables/useRole'; import { useRole } from 'src/composables/useRole';
import TicketMassiveUpdate from '../Card/TicketMassiveUpdate.vue'; import TicketMassiveUpdate from '../Card/TicketMassiveUpdate.vue';
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';
const router = useRouter(); const router = useRouter();
import VnImg from 'src/components/ui/VnImg.vue'; import VnImg from 'src/components/ui/VnImg.vue';
import TicketLackFilter from './TicketLackFilter.vue';
const stateStore = useStateStore(); const stateStore = useStateStore();
const { t } = useI18n(); const { t } = useI18n();
@ -67,7 +69,8 @@ const columns = computed(() => [
format: ({ itemFk }) => itemFk, format: ({ itemFk }) => itemFk,
sortable: true, sortable: true,
columnFilter: { columnFilter: {
component: 'number', component: 'input',
type: 'number',
columnClass: 'shrink', columnClass: 'shrink',
}, },
}, },
@ -115,7 +118,8 @@ const columns = computed(() => [
sortable: true, sortable: true,
cardVisible: true, cardVisible: true,
columnFilter: { columnFilter: {
component: 'number', component: 'input',
type: 'number',
columnClass: 'shrink', columnClass: 'shrink',
}, },
}, },
@ -133,7 +137,8 @@ const columns = computed(() => [
label: t('negative.lack'), label: t('negative.lack'),
field: ({ lack }) => lack, field: ({ lack }) => lack,
columnFilter: { columnFilter: {
component: 'number', component: 'input',
type: 'number',
columnClass: 'shrink', columnClass: 'shrink',
}, },
sortable: true, sortable: true,
@ -198,7 +203,11 @@ onBeforeMount(() => {
<!-- </QBtnGroup> --> <!-- </QBtnGroup> -->
</template> </template>
</VnSubToolbar> </VnSubToolbar>
<div class="list"> <RightMenu>
<template #right-panel>
<TicketLackFilter data-key="NegativeList" />
</template>
</RightMenu>
<VnTable <VnTable
ref="tableRef" ref="tableRef"
data-key="NegativeList" data-key="NegativeList"
@ -208,7 +217,7 @@ onBeforeMount(() => {
auto-load auto-load
:columns="columns" :columns="columns"
default-mode="table" default-mode="table"
:right-search="true" :right-search="false"
:is-editable="false" :is-editable="false"
:use-model="true" :use-model="true"
:row-click="redirectToCreateView" :row-click="redirectToCreateView"
@ -230,7 +239,6 @@ onBeforeMount(() => {
<!-- </QTd> --> <!-- </QTd> -->
</template> </template>
</VnTable> </VnTable>
</div>
</QPage> </QPage>
</template> </template>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, ref } 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';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'src/components/FetchData.vue';
@ -14,7 +14,30 @@ import { useRoute } from 'vue-router';
import VnTable from 'src/components/VnTable/VnTable.vue'; import VnTable from 'src/components/VnTable/VnTable.vue';
import TicketDescriptorProxy from '../Card/TicketDescriptorProxy.vue'; import TicketDescriptorProxy from '../Card/TicketDescriptorProxy.vue';
const rowsSelected = ref([]); const rowsSelected = ref([]);
const $props = defineProps({
filter: {
type: Object,
default: () => ({}),
},
});
watch(
() => $props.filter,
(v) => {
filterLack.value.where = v;
tableRef.value.reload(filterLack);
}
);
const filterLack = ref({
include: [
{
relation: 'workers',
scope: {
fields: ['id', 'firstName'],
},
},
],
where: { alertLevel: 'FRasdEE' },
});
const { t } = useI18n(); const { t } = useI18n();
const URL_KEY = 'Tickets/ItemLack'; const URL_KEY = 'Tickets/ItemLack';
const editableStates = ref([]); const editableStates = ref([]);
@ -75,7 +98,8 @@ const columns = computed(() => [
align: 'left', align: 'left',
sortable: true, sortable: true,
columnFilter: { columnFilter: {
component: 'number', component: 'input',
type: 'number',
}, },
columnClass: 'shrink', columnClass: 'shrink',
}, },
@ -85,7 +109,8 @@ const columns = computed(() => [
align: 'left', align: 'left',
sortable: true, sortable: true,
columnFilter: { columnFilter: {
component: 'number', component: 'input',
type: 'number',
}, },
columnClass: 'shrink', columnClass: 'shrink',
}, },
@ -155,8 +180,9 @@ const columns = computed(() => [
align: 'left', align: 'left',
sortable: true, sortable: true,
columnFilter: { columnFilter: {
component: 'number', component: 'input',
columnClass: 'shrink', type: 'number',
class: 'expand',
}, },
}, },
]); ]);
@ -217,7 +243,7 @@ const tableRef = ref(null);
:create="false" :create="false"
:create-as-dialog="false" :create-as-dialog="false"
:use-model="true" :use-model="true"
:filter="routeFilter" :filter="filterLack"
:table="{ :table="{
'row-key': 'id', 'row-key': 'id',
selection: 'multiple', selection: 'multiple',