0
0
Fork 0

feat: updates ItemProposal

This commit is contained in:
Javier Segarra 2024-09-11 23:17:38 +02:00
parent 373ca0b3f1
commit 9ec1c5ff4b
6 changed files with 244 additions and 232 deletions

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,57 +244,66 @@ onUnmounted(() => {});
}, },
}" }"
auto-load auto-load
:columns="columns"
class="full-width q-mt-md"
v-model:selected="proposalSelected"
row-key="id"
:is-editable="false"
:right-search="false"
:without-header="false"
:disable-option="{ card: true, table: true }"
:table="{
'row-key': 'id',
selection: 'multiple',
}"
> >
<template #body="{ rows }"> <template #top-left>
<!-- {{ rows[1].available }} --> <div v-if="$props.replaceAction" style="display: flex">
<QTable <QBtn
:rows="rows" :label="t('globals.replace')"
:columns="columns" color="primary"
row-key="id" :loading="isLoading"
selection="single" @click="confirm"
disa :disable="
:pagination="{ rowsPerPage: 0 }" proposalSelected.length < 1 || quantity === 0
class="full-width q-mt-md" "
:no-data-label="t('globals.noResults')" unelevated
v-model:selected="proposalSelected" />
:dense="$q.screen.lt.md" <VnInputNumber
flat v-model.number="quantity"
:grid="$q.screen.lt.md" v-if="quantity > -1"
auto-load @update:model-value="(val) => (quantity = val)"
:rows-per-page-options="[0]" type="number"
hide-pagination min="0"
hide-bottom :label="t('proposal.quantityToReplace')"
> class="q-ml-lg"
<template #body-selection="scope"> /></div
<QTd align="center" v-if="$props.replaceAction" ></template>
><QCheckbox <!-- <template #body="scope">{{ scope }}</template> -->
v-model="scope.selected" <template #body-selection="scope">
:disable=" <QTd align="center" v-if="$props.replaceAction"
!( ><QCheckbox
scope.row.available >= v-model="scope.selected"
itemLack.lack * -1 :disable="
) !(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
" >
> </QCheckbox>
Nop</QTooltip <!-- <div v-else class="q-ml-sm">
>
</QCheckbox>
<!-- <div v-else class="q-ml-sm">
<QIcon name="info" size="sm"></QIcon> <QIcon name="info" size="sm"></QIcon>
</div </div
>--></QTd >--></QTd
> >
</template> </template>
<template #top-row> <template #top-row>
<!-- <QTr> <!-- <QTr>
<QTd /> <QTd />
<QTd <QTd
v-for="(col, index) in cols" v-for="(col, index) in cols"
@ -352,62 +320,62 @@ 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>
<QImg <QImg
:src="`/api/Images/catalog/50x50/${row.id}/download?access_token=${token}`" :src="`/api/Images/catalog/50x50/${row.id}/download?access_token=${token}`"
spinner-color="primary" spinner-color="primary"
:ratio="1" :ratio="1"
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"
> >
<QTooltip> <QTooltip>
{{ 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 #body-cell-difference="{ value }">
<QTd class="col" align="left">
<VnStockValueDisplay :value="value" />
</QTd>
</template>
</QTable>
</template> </template>
</VnPaginate> <template #column-difference="{ row }">
<pre>{{ row.difference }}</pre>
<!-- <QTd class="col" align="left"> -->
<!-- <VnStockValueDisplay :value="value" /> -->
<!-- </QTd> -->
</template>
</VnTable>
</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,39 +203,42 @@ onBeforeMount(() => {
<!-- </QBtnGroup> --> <!-- </QBtnGroup> -->
</template> </template>
</VnSubToolbar> </VnSubToolbar>
<div class="list"> <RightMenu>
<VnTable <template #right-panel>
ref="tableRef" <TicketLackFilter data-key="NegativeList" />
data-key="NegativeList" </template>
:url="`Tickets/itemLack`" </RightMenu>
:order="['itemFk DESC, date DESC, timed DESC']" <VnTable
:user-params="negativeParams" ref="tableRef"
auto-load data-key="NegativeList"
:columns="columns" :url="`Tickets/itemLack`"
default-mode="table" :order="['itemFk DESC, date DESC, timed DESC']"
:right-search="true" :user-params="negativeParams"
:is-editable="false" auto-load
:use-model="true" :columns="columns"
:row-click="redirectToCreateView" default-mode="table"
v-model:selected="selectedRows" :right-search="false"
:create="false" :is-editable="false"
:table="{ :use-model="true"
'row-key': 'itemFk', :row-click="redirectToCreateView"
selection: 'multiple', v-model:selected="selectedRows"
}" :create="false"
> :table="{
<template #column-itemFk="{ row }"> 'row-key': 'itemFk',
<!-- <QTd style="height: 76px; flex-direction: row; display: flex"> --> selection: 'multiple',
{{ row.itemFk }} }"
<VnImg >
style="width: 50px; height: 50px; float: inline-end" <template #column-itemFk="{ row }">
:id="row.itemFk" <!-- <QTd style="height: 76px; flex-direction: row; display: flex"> -->
class="rounded" {{ row.itemFk }}
></VnImg> <VnImg
<!-- </QTd> --> style="width: 50px; height: 50px; float: inline-end"
</template> :id="row.itemFk"
</VnTable> class="rounded"
</div> ></VnImg>
<!-- </QTd> -->
</template>
</VnTable>
</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',