fix: #8313 fixed ClaimLines format #1097

Merged
provira merged 5 commits from 8813-arreglarFormatoClaimLines into dev 2024-12-19 05:06:28 +00:00
30 changed files with 236 additions and 330 deletions
Showing only changes of commit c9aa06e471 - Show all commits

View File

@ -1,6 +1,5 @@
function focusFirstInput(input) { function focusFirstInput(input) {
input.focus(); input.focus();
return;
} }
export default { export default {
mounted: function () { mounted: function () {

View File

@ -293,6 +293,7 @@ defineExpose({
class="q-pa-md" class="q-pa-md"
:style="maxWidth ? 'max-width: ' + maxWidth : ''" :style="maxWidth ? 'max-width: ' + maxWidth : ''"
id="formModel" id="formModel"
:prevent-submit="$attrs['prevent-submit']"
> >
<QCard> <QCard>
<slot <slot

View File

@ -162,7 +162,9 @@ onMounted(() => {
: $props.defaultMode; : $props.defaultMode;
stateStore.rightDrawer = quasar.screen.gt.xs; stateStore.rightDrawer = quasar.screen.gt.xs;
columnsVisibilitySkipped.value = [ columnsVisibilitySkipped.value = [
...splittedColumns.value.columns.filter((c) => !c.visible).map((c) => c.name), ...splittedColumns.value.columns
.filter((c) => c.visible === false)
.map((c) => c.name),
...['tableActions'], ...['tableActions'],
]; ];
createForm.value = $props.create; createForm.value = $props.create;

View File

@ -152,7 +152,7 @@ onMounted(async () => {
<QCheckbox <QCheckbox
v-for="col in localColumns" v-for="col in localColumns"
:key="col.name" :key="col.name"
:label="col.label" :label="col.label ?? col.name"
v-model="col.visible" v-model="col.visible"
/> />
</div> </div>

View File

@ -51,10 +51,6 @@ const props = defineProps({
type: Object, type: Object,
default: null, default: null,
}, },
staticParams: {
type: Array,
default: () => [],
},
exprBuilder: { exprBuilder: {
type: Function, type: Function,
default: null, default: null,

View File

@ -264,6 +264,10 @@ input::-webkit-inner-spin-button {
.shrink { .shrink {
max-width: 75px; max-width: 75px;
} }
.number {
text-align: right;
width: 96px;
}
.expand { .expand {
max-width: 400px; max-width: 400px;
} }

View File

@ -189,6 +189,7 @@ async function getAmountPaid() {
:url-create="urlCreate" :url-create="urlCreate"
:mapper="onBeforeSave" :mapper="onBeforeSave"
@on-data-saved="onDataSaved" @on-data-saved="onDataSaved"
:prevent-submit="true"
> >
<template #form="{ data, validate }"> <template #form="{ data, validate }">
<span ref="closeButton" class="row justify-end close-icon" v-close-popup> <span ref="closeButton" class="row justify-end close-icon" v-close-popup>
@ -303,7 +304,7 @@ async function getAmountPaid() {
:label="t('globals.save')" :label="t('globals.save')"
:loading="formModelRef.isLoading" :loading="formModelRef.isLoading"
color="primary" color="primary"
type="submit" @click="formModelRef.save()"
/> />
</div> </div>
</template> </template>

View File

@ -1,10 +1,9 @@
<script setup> <script setup>
import { ref, computed, onMounted, watch } from 'vue'; import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue'; import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { useArrayData } from 'composables/useArrayData';
import { toCurrency } from 'filters/index'; import { toCurrency } from 'filters/index';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import axios from 'axios'; import axios from 'axios';
@ -15,31 +14,22 @@ import VnInput from 'src/components/common/VnInput.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue'; import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import ItemRequestFilter from './ItemRequestFilter.vue'; import ItemRequestFilter from './ItemRequestFilter.vue';
import RightMenu from 'src/components/common/RightMenu.vue'; import RightMenu from 'src/components/common/RightMenu.vue';
const { t } = useI18n(); const { t } = useI18n();
const { notify } = useNotify(); const { notify } = useNotify();
const stateStore = useStateStore(); const stateStore = useStateStore();
let filterParams = ref({});
const denyFormRef = ref(null); const denyFormRef = ref(null);
const denyRequestId = ref(null); const denyRequestId = ref(null);
const denyRequestIndex = ref(null); const denyRequestIndex = ref(null);
const itemRequestsOptions = ref([]); const itemRequestsOptions = ref([]);
const arrayData = useArrayData('ItemRequests', {
url: 'TicketRequests/filter',
userParams: filterParams,
order: ['shippedDate ASC', 'isOk ASC'],
});
const store = arrayData.store;
const userParams = { const userParams = {
state: 'pending', state: 'pending',
daysOnward: 7, daysOnward: 7,
}; };
const tableRef = ref(); const tableRef = ref();
watch( onMounted(async () => {
() => store.data, stateStore.rightDrawer = true;
(value) => (itemRequestsOptions.value = value) });
);
const columns = computed(() => [ const columns = computed(() => [
{ {
@ -223,11 +213,6 @@ const onDenyAccept = (_, responseData) => {
denyRequestIndex.value = null; denyRequestIndex.value = null;
tableRef.value.reload(); tableRef.value.reload();
}; };
onMounted(async () => {
await arrayData.fetch({ append: false });
stateStore.rightDrawer = true;
});
</script> </script>
<template> <template>
@ -244,10 +229,10 @@ onMounted(async () => {
:columns="columns" :columns="columns"
:user-params="userParams" :user-params="userParams"
:is-editable="true" :is-editable="true"
:right-search="false"
auto-load auto-load
:disable-option="{ card: true }" :disable-option="{ card: true }"
chip-locale="item.params" chip-locale="item.params"
:right-search="false"
> >
<template #column-ticketFk="{ row }"> <template #column-ticketFk="{ row }">
<span class="link"> <span class="link">
@ -306,14 +291,17 @@ onMounted(async () => {
<template #moreFilterPanel="{ params }"> <template #moreFilterPanel="{ params }">
<VnInputNumber <VnInputNumber
:label="t('params.scopeDays')" :label="t('params.scopeDays')"
v-model.number="params.scopeDays" v-model.number="params.daysOnward"
@keyup.enter="(evt) => handleScopeDays(evt.target.value)" @keyup.enter="(evt) => handleScopeDays(evt.target.value)"
@remove="handleScopeDays()" @remove="handleScopeDays()"
class="q-px-xs q-pr-lg" class="q-px-xs q-pr-lg"
filled filled
dense dense
lazy-rules
is-outlined
/> />
</template> </template>
<template #column-denyOptions="{ row, rowIndex }"> <template #column-denyOptions="{ row, rowIndex }">
<QIcon <QIcon
v-if="row.response?.length" v-if="row.response?.length"

View File

@ -6,7 +6,6 @@ import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue'; import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
@ -46,20 +45,6 @@ const exprBuilder = (param, value) => {
} }
}; };
const add = (paramsObj, key) => {
if (paramsObj[key] === undefined) {
paramsObj[key] = 1;
} else {
paramsObj[key]++;
}
};
const decrement = (paramsObj, key) => {
if (paramsObj[key] === 0) return;
paramsObj[key]--;
};
onMounted(async () => { onMounted(async () => {
if (arrayData.store?.userParams) { if (arrayData.store?.userParams) {
fieldFiltersValues.value = Object.entries(arrayData.store.userParams).map( fieldFiltersValues.value = Object.entries(arrayData.store.userParams).map(
@ -95,8 +80,7 @@ onMounted(async () => {
<template #tags="{ tag, formatFn }"> <template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs"> <div class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong> <strong>{{ t(`params.${tag.label}`) }}: </strong>
<span v-if="tag.label !== 'state'">{{ formatFn(tag.value) }}</span> <span>{{ formatFn(tag.value) }}</span>
<span v-else>{{ t(`${tag.value}`) }}</span>
</div> </div>
</template> </template>
<template #body="{ params, searchFn }"> <template #body="{ params, searchFn }">
@ -174,83 +158,6 @@ onMounted(async () => {
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem>
<QItemSection>
<QCheckbox
v-model="params.myTeam"
:label="t('params.myTeam')"
@update:model-value="searchFn()"
toggle-indeterminate
/>
</QItemSection>
</QItem>
<QCard bordered>
<QItem>
<QItemSection>
<VnInputDate
:label="t('params.from')"
v-model="params.from"
@update:model-value="searchFn()"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInputDate
:label="t('params.to')"
v-model="params.to"
@update:model-value="searchFn()"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput
v-model="params.scopeDays"
:label="t('globals.daysOnward')"
type="number"
dense
outlined
rounded
:min="0"
>
<template #append>
<QBtn
icon="add"
flat
dense
size="12px"
shortcut="+"
@click="add(params, 'scopeDays')"
/>
<QBtn
icon="remove"
flat
dense
size="12px"
@click="decrement(params, 'scopeDays')"
/>
</template>
</VnInput>
</QItemSection>
</QItem>
<QIcon name="info" style="position: absolute; top: 4px; right: 4px">
<QTooltip max-width="300px">
{{ t('dateFiltersTooltip') }}
</QTooltip>
</QIcon>
</QCard>
<QItem>
<QItemSection>
<QCheckbox
:label="t('params.mine')"
v-model="params.mine"
toggle-indeterminate
/>
</QItemSection>
</QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnSelect <VnSelect
@ -267,6 +174,16 @@ onMounted(async () => {
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem>
<QItemSection>
<VnInput
:label="t('params.daysOnward')"
v-model="params.daysOnward"
lazy-rules
is-outlined
/>
</QItemSection>
</QItem>
</template> </template>
</VnFilterPanel> </VnFilterPanel>
</template> </template>

View File

@ -78,29 +78,32 @@ async function setItemTypeData(data) {
{{ t('globals.summary.basicData') }} {{ t('globals.summary.basicData') }}
<QIcon name="open_in_new" /> <QIcon name="open_in_new" />
</router-link> </router-link>
<VnLv :label="t('summary.id')" :value="itemType.id" /> <VnLv :label="t('itemType.summary.id')" :value="itemType.id" />
<VnLv :label="t('shared.code')" :value="itemType.code" /> <VnLv :label="t('itemType.shared.code')" :value="itemType.code" />
<VnLv :label="t('shared.name')" :value="itemType.name" /> <VnLv :label="t('itemType.shared.name')" :value="itemType.name" />
<VnLv :label="t('shared.worker')"> <VnLv :label="t('itemType.shared.worker')">
<template #value> <template #value>
<span class="link">{{ itemType.worker?.firstName }}</span> <span class="link">{{ itemType.worker?.firstName }}</span>
<WorkerDescriptorProxy :id="itemType.worker?.id" /> <WorkerDescriptorProxy :id="itemType.worker?.id" />
</template> </template>
</VnLv> </VnLv>
<VnLv :label="t('shared.category')" :value="itemType.category?.name" />
<VnLv <VnLv
:label="t('shared.temperature')" :label="t('itemType.shared.category')"
:value="itemType.category?.name"
/>
<VnLv
:label="t('itemType.shared.temperature')"
:value="itemType.temperature?.name" :value="itemType.temperature?.name"
/> />
<VnLv :label="t('summary.life')" :value="itemType.life" /> <VnLv :label="t('itemType.summary.life')" :value="itemType.life" />
<VnLv :label="t('summary.promo')" :value="itemType.promo" /> <VnLv :label="t('itemType.summary.promo')" :value="itemType.promo" />
<VnLv <VnLv
:label="t('summary.itemPackingType')" :label="t('itemType.summary.itemPackingType')"
:value="itemType.itemPackingType?.description" :value="itemType.itemPackingType?.description"
/> />
<VnLv <VnLv
class="large-label" class="large-label"
:label="t('summary.isUnconventionalSize')" :label="t('itemType.summary.isUnconventionalSize')"
:value="itemType.isUnconventionalSize" :value="itemType.isUnconventionalSize"
/> />
</QCard> </QCard>

View File

@ -1,16 +1,17 @@
shared: itemType:
code: Code shared:
name: Name code: Code
worker: Worker name: Name
category: Category worker: Worker
temperature: Temperature category: Category
life: Life temperature: Temperature
itemPackingType: Item packing type life: Life
maxRefs: Maximum references itemPackingType: Item packing type
fragile: Fragile maxRefs: Maximum references
summary: fragile: Fragile
id: id summary:
life: Life id: id
promo: Promo life: Life
itemPackingType: Item packing type promo: Promo
isUnconventionalSize: Is unconventional size itemPackingType: Item packing type
isUnconventionalSize: Is unconventional size

View File

@ -1,16 +1,17 @@
shared: itemType:
code: Código shared:
name: Nombre code: Código
worker: Trabajador name: Nombre
category: Reino worker: Trabajador
temperature: Temperatura category: Reino
life: Vida temperature: Temperatura
itemPackingType: Tipo de embalaje life: Vida
maxRefs: Referencias máximas itemPackingType: Tipo de embalaje
fragile: Frágil maxRefs: Referencias máximas
summary: fragile: Frágil
id: id summary:
life: Vida id: id
promo: Promoción life: Vida
itemPackingType: Tipo de embalaje promo: Promoción
isUnconventionalSize: Es de tamaño poco convencional itemPackingType: Tipo de embalaje
isUnconventionalSize: Es de tamaño poco convencional

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, computed } from 'vue'; import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
@ -16,6 +16,7 @@ import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue';
import MonitorTicketFilter from './MonitorTicketFilter.vue'; import MonitorTicketFilter from './MonitorTicketFilter.vue';
import TicketProblems from 'src/components/TicketProblems.vue'; import TicketProblems from 'src/components/TicketProblems.vue';
import VnDateBadge from 'src/components/common/VnDateBadge.vue'; import VnDateBadge from 'src/components/common/VnDateBadge.vue';
import { useStateStore } from 'src/stores/useStateStore';
const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000; const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000;
const { t } = useI18n(); const { t } = useI18n();
@ -25,8 +26,9 @@ const provinceOpts = ref([]);
const stateOpts = ref([]); const stateOpts = ref([]);
const zoneOpts = ref([]); const zoneOpts = ref([]);
const DepartmentOpts = ref([]); const DepartmentOpts = ref([]);
const PayMethodOpts = ref([]);
const ItemPackingTypeOpts = ref([]); const ItemPackingTypeOpts = ref([]);
const visibleColumns = ref([]); const stateStore = useStateStore();
const { viewSummary } = useSummaryDialog(); const { viewSummary } = useSummaryDialog();
const [from, to] = dateRange(Date.vnNew()); const [from, to] = dateRange(Date.vnNew());
@ -37,6 +39,11 @@ const stateColors = {
alert: 'negative', alert: 'negative',
}; };
onMounted(() => {
stateStore.leftDrawer = false;
stateStore.rightDrawer = false;
});
function exprBuilder(param, value) { function exprBuilder(param, value) {
switch (param) { switch (param) {
case 'stateFk': case 'stateFk':
@ -217,7 +224,16 @@ const columns = computed(() => [
label: t('salesTicketsTable.payMethod'), label: t('salesTicketsTable.payMethod'),
name: 'payMethod', name: 'payMethod',
align: 'left', align: 'left',
columnFilter: false, columnFilter: {
component: 'select',
url: 'PayMethods',
attrs: {
options: PayMethodOpts.value,
optionValue: 'id',
optionLabel: 'name',
dense: true,
},
},
}, },
{ {
label: t('salesTicketsTable.total'), label: t('salesTicketsTable.total'),
@ -238,11 +254,8 @@ const columns = computed(() => [
align: 'left', align: 'left',
columnFilter: { columnFilter: {
component: 'select', component: 'select',
url: 'Departments',
attrs: { attrs: {
options: DepartmentOpts.value, options: DepartmentOpts.value,
optionValue: 'name',
optionLabel: 'name',
dense: true, dense: true,
}, },
}, },
@ -358,6 +371,15 @@ const openTab = (id) =>
auto-load auto-load
@on-fetch="(data) => (DepartmentOpts = data)" @on-fetch="(data) => (DepartmentOpts = data)"
/> />
<FetchData
url="PayMethods"
:filter="{
fields: ['id', 'name'],
order: 'id ASC',
}"
auto-load
@on-fetch="(data) => (PayMethodOpts = data)"
/>
<MonitorTicketSearchbar /> <MonitorTicketSearchbar />
<RightMenu> <RightMenu>
<template #right-panel> <template #right-panel>
@ -377,7 +399,7 @@ const openTab = (id) =>
auto-load auto-load
:row-click="({ id }) => openTab(id)" :row-click="({ id }) => openTab(id)"
:disable-option="{ card: true }" :disable-option="{ card: true }"
:user-params="{ from, to, scopeDays: 0, packing }" :user-params="{ from, to, scopeDays: 0 }"
> >
<template #top-left> <template #top-left>
<QBtn <QBtn

View File

@ -1,7 +1,7 @@
<script setup> <script setup>
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { onMounted, ref, computed, watch, provide } from 'vue'; import { onMounted, ref, computed, watch } from 'vue';
import axios from 'axios'; import axios from 'axios';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import VnPaginate from 'src/components/ui/VnPaginate.vue'; import VnPaginate from 'src/components/ui/VnPaginate.vue';
@ -87,16 +87,14 @@ watch(
:label="t('Search items')" :label="t('Search items')"
:info="t('You can search items by name or id')" :info="t('You can search items by name or id')"
/> />
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
<QScrollArea class="fit text-grey-8"> <OrderCatalogFilter
<OrderCatalogFilter :data-key="dataKey"
:data-key="dataKey" :tag-value="tagValue"
:tag-value="tagValue" :tags="tags"
:tags="tags" :initial-catalog-params="catalogParams"
:initial-catalog-params="catalogParams" />
/> </Teleport>
</QScrollArea>
</QDrawer>
<QPage class="column items-center q-pa-md" data-cy="orderCatalogPage"> <QPage class="column items-center q-pa-md" data-cy="orderCatalogPage">
<div class="full-width"> <div class="full-width">
<VnPaginate <VnPaginate

View File

@ -251,7 +251,7 @@ watch(
@on-fetch="(data) => (orderSummary.vat = data)" @on-fetch="(data) => (orderSummary.vat = data)"
auto-load auto-load
/> />
<QDrawer side="right" :width="265" v-model="stateStore.rightDrawer"> <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
<QCard <QCard
class="order-lines-summary q-pa-lg" class="order-lines-summary q-pa-lg"
v-if="orderSummary.vat && orderSummary.total" v-if="orderSummary.vat && orderSummary.total"
@ -266,7 +266,7 @@ watch(
<VnLv :label="t('VAT') + ': '" :value="toCurrency(orderSummary?.vat)" /> <VnLv :label="t('VAT') + ': '" :value="toCurrency(orderSummary?.vat)" />
<VnLv :label="t('total') + ': '" :value="toCurrency(orderSummary?.total)" /> <VnLv :label="t('total') + ': '" :value="toCurrency(orderSummary?.total)" />
</QCard> </QCard>
</QDrawer> </Teleport>
<VnTable <VnTable
ref="tableLinesRef" ref="tableLinesRef"

View File

@ -8,7 +8,7 @@ import SendEmailDialog from 'components/common/SendEmailDialog.vue';
import SupplierConsumptionFilter from './SupplierConsumptionFilter.vue'; import SupplierConsumptionFilter from './SupplierConsumptionFilter.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import { toDate } from 'src/filters'; import { dateRange, toDate } from 'src/filters';
import { dashIfEmpty } from 'src/filters'; import { dashIfEmpty } from 'src/filters';
import { usePrintService } from 'composables/usePrintService'; import { usePrintService } from 'composables/usePrintService';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
@ -35,14 +35,17 @@ const store = arrayData.store;
onUnmounted(() => state.unset('SupplierConsumption')); onUnmounted(() => state.unset('SupplierConsumption'));
const dateRanges = computed(() => { const dateRanges = computed(() => {
const { from, to } = arrayData.store?.userParams || {}; let { from, to } = arrayData.store?.userParams || {};
return { from, to }; return { from, to };
}); });
const reportParams = computed(() => ({ const reportParams = computed(() => {
recipientId: Number(route.params.id), return {
...dateRanges.value, recipientId: Number(route.params.id),
})); to: dateRange(dateRanges.value.to)[1],
from: dateRange(dateRanges.value.from)[1],
};
});
async function getSupplierConsumptionData() { async function getSupplierConsumptionData() {
await arrayData.fetch({ append: false }); await arrayData.fetch({ append: false });
@ -171,11 +174,9 @@ onMounted(async () => {
</div> </div>
</Teleport> </Teleport>
<QPage class="column items-center q-pa-md"> <QPage class="column items-center q-pa-md">
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
<QScrollArea class="fit text-grey-8"> <SupplierConsumptionFilter data-key="SupplierConsumption" />
<SupplierConsumptionFilter data-key="SupplierConsumption" /> </Teleport>
</QScrollArea>
</QDrawer>
<QTable <QTable
:rows="rows" :rows="rows"
row-key="id" row-key="id"

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, computed, onMounted, watch } from 'vue'; import { ref, computed, onMounted, nextTick } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
@ -10,37 +10,15 @@ import { useStateStore } from 'stores/useStateStore';
import { toCurrency } from 'filters/index'; import { toCurrency } from 'filters/index';
import { useRole } from 'src/composables/useRole'; import { useRole } from 'src/composables/useRole';
const $props = defineProps({ const haveNegatives = defineModel('haveNegatives', { type: Boolean, required: true });
formData: { const formData = defineModel({ type: Object, required: true });
type: Object,
required: true,
},
haveNegatives: {
type: Boolean,
required: true,
default: false,
},
});
const emit = defineEmits(['updateForm', 'update:haveNegatives']);
const stateStore = useStateStore(); const stateStore = useStateStore();
const { t } = useI18n(); const { t } = useI18n();
const { hasAny } = useRole(); const { hasAny } = useRole();
const _ticketData = ref($props.formData);
const ticketUpdateActions = ref(null); const ticketUpdateActions = ref(null);
const haveNegatives = computed({ const rows = computed(() => formData.value?.sale?.items || []);
get: () => $props.haveNegatives,
set: (val) => emit('update:haveNegatives', val),
});
const rows = computed(() => _ticketData.value?.sale?.items || []);
watch(
() => _ticketData.value,
(val) => emit('updateForm', val),
{ deep: true }
);
const columns = computed(() => [ const columns = computed(() => [
{ {
@ -57,24 +35,28 @@ const columns = computed(() => [
align: 'left', align: 'left',
hidden: true, hidden: true,
}, },
{
name: 'subName',
align: 'left',
required: true,
},
{ {
label: t('basicData.movable'), label: t('basicData.movable'),
name: 'movable', name: 'movable',
align: 'left',
}, },
{ {
required: true, required: true,
label: t('basicData.quantity'), label: t('basicData.quantity'),
name: 'quantity', name: 'quantity',
field: 'quantity', field: 'quantity',
align: 'left', classes: 'number',
}, },
{ {
required: true, required: true,
label: t('basicData.pricePPU'), label: t('basicData.pricePPU'),
name: 'price', name: 'price',
field: 'price', field: 'price',
align: 'left', classes: 'number',
format: (val) => toCurrency(val), format: (val) => toCurrency(val),
}, },
{ {
@ -82,7 +64,7 @@ const columns = computed(() => [
label: t('basicData.newPricePPU'), label: t('basicData.newPricePPU'),
name: 'newPrice', name: 'newPrice',
field: (row) => row.component.newPrice, field: (row) => row.component.newPrice,
align: 'left', classes: 'number',
format: (val) => toCurrency(val), format: (val) => toCurrency(val),
}, },
{ {
@ -90,14 +72,15 @@ const columns = computed(() => [
label: t('basicData.difference'), label: t('basicData.difference'),
name: 'difference', name: 'difference',
field: (row) => row.component.difference, field: (row) => row.component.difference,
align: 'left', classes: 'number',
format: (val) => toCurrency(val), format: (val) => toCurrency(val),
autoWidth: true,
}, },
]); ]);
const loadDefaultTicketAction = () => { const loadDefaultTicketAction = () => {
const isSalesAssistant = hasAny(['salesAssistant']); const isSalesAssistant = hasAny(['salesAssistant']);
_ticketData.value.option = isSalesAssistant ? 'mana' : 'renewPrices'; formData.value.option = isSalesAssistant ? 'mana' : 'renewPrices';
}; };
const totalPrice = computed(() => { const totalPrice = computed(() => {
@ -115,24 +98,25 @@ const totalDifference = computed(() => {
return rows.value.reduce((acc, item) => acc + item.component?.difference || 0, 0); return rows.value.reduce((acc, item) => acc + item.component?.difference || 0, 0);
}); });
const showMovableColumn = computed(() => (haveDifferences.value > 0 ? ['movable'] : [])); const showMovableColumn = computed(() => (haveDifferences.value > 0 ? ['movable'] : []));
const haveDifferences = computed(() => _ticketData.value.sale?.haveDifferences); const haveDifferences = computed(() => formData.value.sale?.haveDifferences);
const ticketHaveNegatives = () => { async function ticketHaveNegatives() {
let _haveNegatives = false; let _haveNegatives = false;
let haveNotNegatives = false; let haveNotNegatives = false;
_ticketData.value.withoutNegatives = false; formData.value.withoutNegatives = false;
_ticketData.value?.sale?.items.forEach((item) => { formData.value?.sale?.items.forEach((item) => {
if (item.quantity > item.movable) _haveNegatives = true; if (item.quantity > item.movable) _haveNegatives = true;
else haveNotNegatives = true; else haveNotNegatives = true;
}); });
haveNegatives.value = _haveNegatives && haveNotNegatives && haveDifferences.value; haveNegatives.value = _haveNegatives && haveNotNegatives && haveDifferences.value;
if (haveNegatives.value) _ticketData.value.withoutNegatives = true; await nextTick();
}; if (haveNegatives.value) formData.value.withoutNegatives = true;
}
onMounted(() => { onMounted(async () => {
stateStore.rightDrawer = true; stateStore.rightDrawer = true;
loadDefaultTicketAction(); loadDefaultTicketAction();
ticketHaveNegatives(); await ticketHaveNegatives();
}); });
</script> </script>
@ -189,7 +173,7 @@ onMounted(() => {
horizontal horizontal
> >
<QRadio <QRadio
v-model="_ticketData.option" v-model="formData.option"
:val="action.code" :val="action.code"
:label="action.description" :label="action.description"
dense dense
@ -206,7 +190,7 @@ onMounted(() => {
<QCardSection horizontal class="flex row items-center"> <QCardSection horizontal class="flex row items-center">
<QCheckbox <QCheckbox
:label="t('basicData.withoutNegatives')" :label="t('basicData.withoutNegatives')"
v-model="_ticketData.withoutNegatives" v-model="formData.withoutNegatives"
:toggle-indeterminate="false" :toggle-indeterminate="false"
/> />
<QIcon name="info" size="xs" class="q-ml-sm"> <QIcon name="info" size="xs" class="q-ml-sm">
@ -223,7 +207,7 @@ onMounted(() => {
:columns="columns" :columns="columns"
row-key="id" row-key="id"
:pagination="{ rowsPerPage: 0 }" :pagination="{ rowsPerPage: 0 }"
class="full-width q-mt-md" class="full-width"
:no-data-label="t('globals.noResults')" :no-data-label="t('globals.noResults')"
flat flat
> >
@ -236,21 +220,27 @@ onMounted(() => {
</QTd> </QTd>
</template> </template>
<template #body-cell-description="{ row }"> <template #body-cell-description="{ row }">
<QTd style="display: contents"> <QTd style="min-width: 120px; max-width: 120px">
<div class="column"> <div class="column q-pb-xs" style="min-width: 120px">
<span>{{ row.item.name }}</span> <span>{{ row.item.name }}</span>
<span class="color-vn-label">{{ row.item.subName }}</span> <FetchedTags :item="row.item" class="full-width" />
<FetchedTags :item="row.item" />
</div> </div>
</QTd> </QTd>
</template> </template>
<template #body-cell-movable="{ row }"> <template #body-cell-subName="{ row }">
<QTd> <QTd>
<QBadge <span class="color-vn-label">{{ row.item.subName }}</span>
v-if="_ticketData?.sale?.haveDifferences" </QTd>
</template>
<template #body-cell-movable="{ row }">
<QTd class="number">
<QChip
v-if="formData?.sale?.haveDifferences"
:text-color="row.quantity > row.movable ? 'black' : 'white'" :text-color="row.quantity > row.movable ? 'black' : 'white'"
:color="row.quantity > row.movable ? 'negative' : 'transparent'" :color="row.quantity > row.movable ? 'negative' : 'transparent'"
:label="row.movable" :label="row.movable"
dense
square
/> />
</QTd> </QTd>
</template> </template>

View File

@ -21,7 +21,6 @@ const formData = defineModel({
required: true, required: true,
}); });
const emit = defineEmits(['updateForm']);
const { validate } = useValidator(); const { validate } = useValidator();
const { notify } = useNotify(); const { notify } = useNotify();
const router = useRouter(); const router = useRouter();
@ -33,18 +32,11 @@ const canEditZone = useAcl().hasAny([
const agencyFetchRef = ref(); const agencyFetchRef = ref();
const warehousesOptions = ref([]); const warehousesOptions = ref([]);
const companiesOptions = ref([]); const companiesOptions = ref([]);
const currenciesOptions = ref([]);
const agenciesOptions = ref([]); const agenciesOptions = ref([]);
const zonesOptions = ref([]); const zonesOptions = ref([]);
const addresses = ref([]); const addresses = ref([]);
const zoneSelectRef = ref(); const zoneSelectRef = ref();
watch(
() => formData.value,
(val) => emit('updateForm', val),
{ deep: true }
);
onMounted(() => onFormModelInit()); onMounted(() => onFormModelInit());
const agencyByWarehouseFilter = computed(() => ({ const agencyByWarehouseFilter = computed(() => ({

View File

@ -155,18 +155,10 @@ onBeforeMount(async () => await getTicketData());
}" }"
> >
<QStep :name="1" :title="t('globals.pageTitles.basicData')" :done="step > 1"> <QStep :name="1" :title="t('globals.pageTitles.basicData')" :done="step > 1">
<TicketBasicDataForm <TicketBasicDataForm v-if="initialDataLoaded" v-model="formData" />
v-if="initialDataLoaded"
@update-form="($event) => (formData = $event)"
v-model="formData"
/>
</QStep> </QStep>
<QStep :name="2" :title="t('basicData.priceDifference')"> <QStep :name="2" :title="t('basicData.priceDifference')">
<TicketBasicData <TicketBasicData v-model="formData" v-model:have-negatives="haveNegatives" />
:form-data="formData"
v-model:haveNegatives="haveNegatives"
@update-form="($event) => (formData = $event)"
/>
</QStep> </QStep>
<template #navigation> <template #navigation>
<QStepperNavigation class="flex justify-between"> <QStepperNavigation class="flex justify-between">

View File

@ -1,6 +1,7 @@
<script setup> <script setup>
import axios from 'axios'; import axios from 'axios';
import { date, useQuasar } from 'quasar'; import { date, useQuasar } from 'quasar';
import { useStateStore } from 'src/stores/useStateStore';
import { computed, onMounted, reactive, ref } from 'vue'; import { computed, onMounted, reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
@ -8,7 +9,7 @@ import { useRouter } from 'vue-router';
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t } = useI18n();
const quasar = useQuasar(); const quasar = useQuasar();
const stateStore = useStateStore();
onMounted(async () => { onMounted(async () => {
await fetch(); await fetch();
}); });
@ -84,7 +85,7 @@ async function getVideoList(expeditionId, timed) {
</script> </script>
<template> <template>
<QDrawer show-if-above side="right"> <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
<QScrollArea class="fit"> <QScrollArea class="fit">
<QList bordered separator style="max-width: 318px"> <QList bordered separator style="max-width: 318px">
<QItem v-if="lastExpedition && videoList.length"> <QItem v-if="lastExpedition && videoList.length">
@ -150,7 +151,7 @@ async function getVideoList(expeditionId, timed) {
</QItem> </QItem>
</QList> </QList>
</QScrollArea> </QScrollArea>
</QDrawer> </Teleport>
<QCard> <QCard>
<QCarousel animated v-model="slide" height="max-content"> <QCarousel animated v-model="slide" height="max-content">

View File

@ -178,7 +178,7 @@ onMounted(() => {
@on-fetch="(data) => (components = data)" @on-fetch="(data) => (components = data)"
auto-load auto-load
/> />
<QDrawer side="right" :width="265" v-model="stateStore.rightDrawer"> <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
<QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black"> <QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black">
<QCardSection horizontal> <QCardSection horizontal>
<span class="text-weight-bold text-subtitle1 text-center full-width"> <span class="text-weight-bold text-subtitle1 text-center full-width">
@ -264,7 +264,7 @@ onMounted(() => {
<span>{{ toCurrency(theoricalCost, 'EUR', 2) }}</span> <span>{{ toCurrency(theoricalCost, 'EUR', 2) }}</span>
</QCardSection> </QCardSection>
</QCard> </QCard>
</QDrawer> </Teleport>
<VnTable <VnTable
ref="tableRef" ref="tableRef"
data-key="TicketComponents" data-key="TicketComponents"

View File

@ -617,7 +617,7 @@ watch(
</QBtnGroup> </QBtnGroup>
</template> </template>
</VnSubToolbar> </VnSubToolbar>
<QDrawer side="right" :width="265" v-model="stateStore.rightDrawer"> <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
<div <div
class="q-pa-md q-mb-md q-ma-md color-vn-text" class="q-pa-md q-mb-md q-ma-md color-vn-text"
style="border: 2px solid black" style="border: 2px solid black"
@ -638,8 +638,8 @@ watch(
<span class="q-mr-xs color-vn-label"> {{ t('basicData.total') }}: </span> <span class="q-mr-xs color-vn-label"> {{ t('basicData.total') }}: </span>
<span>{{ toCurrency(store.data?.totalWithVat) }}</span> <span>{{ toCurrency(store.data?.totalWithVat) }}</span>
</QCardSection> </QCardSection>
</div></QDrawer </div>
> </Teleport>
<VnTable <VnTable
ref="tableRef" ref="tableRef"
data-key="TicketSales" data-key="TicketSales"

View File

@ -100,11 +100,9 @@ onMounted(() => (stateStore.rightDrawer = true));
@on-fetch="(data) => applyVolumes(data)" @on-fetch="(data) => applyVolumes(data)"
auto-load auto-load
/> />
<QDrawer <Teleport
v-if="packingTypeVolume.length" to="#right-panel"
side="right" v-if="stateStore.isHeaderMounted() && packingTypeVolume.length"
:width="265"
v-model="stateStore.rightDrawer"
> >
<QCard <QCard
v-for="(packingType, index) in packingTypeVolume" v-for="(packingType, index) in packingTypeVolume"
@ -124,8 +122,7 @@ onMounted(() => (stateStore.rightDrawer = true));
<span> {{ t('volume.volume') }}: {{ packingType.volume }} </span> <span> {{ t('volume.volume') }}: {{ packingType.volume }} </span>
</QCardSection> </QCardSection>
</QCard> </QCard>
</QDrawer> </Teleport>
<VnTable <VnTable
ref="tableRef" ref="tableRef"
data-key="TicketVolume" data-key="TicketVolume"

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import axios from 'axios'; import axios from 'axios';
import { computed, ref, onMounted } from 'vue'; import { computed, ref, onBeforeMount } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
@ -46,7 +46,7 @@ const userParams = {
from: null, from: null,
to: null, to: null,
}; };
onMounted(() => { onBeforeMount(() => {
initializeFromQuery(); initializeFromQuery();
stateStore.rightDrawer = true; stateStore.rightDrawer = true;
if (!route.query.createForm) return; if (!route.query.createForm) return;

View File

@ -15,9 +15,6 @@ const columns = computed(() => [
name: 'paymentDate', name: 'paymentDate',
label: t('worker.balance.tableVisibleColumns.paymentDate'), label: t('worker.balance.tableVisibleColumns.paymentDate'),
create: true, create: true,
columnCreate: {
required: true,
},
component: 'date', component: 'date',
field: 'paymentDate', field: 'paymentDate',
cardVisible: true, cardVisible: true,
@ -27,9 +24,6 @@ const columns = computed(() => [
name: 'incomeTypeFk', name: 'incomeTypeFk',
label: t('worker.balance.tableVisibleColumns.incomeType'), label: t('worker.balance.tableVisibleColumns.incomeType'),
create: true, create: true,
columnCreate: {
required: true,
},
component: 'select', component: 'select',
attrs: { attrs: {
options: payrollComponents, options: payrollComponents,
@ -43,9 +37,6 @@ const columns = computed(() => [
name: 'debit', name: 'debit',
label: t('worker.balance.tableVisibleColumns.debit'), label: t('worker.balance.tableVisibleColumns.debit'),
create: true, create: true,
columnCreate: {
required: true,
},
component: 'input', component: 'input',
field: 'debit', field: 'debit',
cardVisible: true, cardVisible: true,
@ -55,9 +46,6 @@ const columns = computed(() => [
name: 'credit', name: 'credit',
label: t('worker.balance.tableVisibleColumns.credit'), label: t('worker.balance.tableVisibleColumns.credit'),
create: true, create: true,
columnCreate: {
required: true,
},
component: 'input', component: 'input',
field: 'credit', field: 'credit',
cardVisible: true, cardVisible: true,

View File

@ -23,6 +23,7 @@ const insertTag = () => {
workerPitCrudRef.value.insert(); workerPitCrudRef.value.insert();
}; };
const quasar = useQuasar(); const quasar = useQuasar();
const deleteRelative = async (id) => { const deleteRelative = async (id) => {
await new Promise((resolve) => { await new Promise((resolve) => {
quasar quasar
@ -62,7 +63,6 @@ const deleteRelative = async (id) => {
> >
<template #form="{ data }"> <template #form="{ data }">
<QCard class="q-px-lg q-py-lg"> <QCard class="q-px-lg q-py-lg">
<VnTitle :text="t('IRPF')" />
<VnRow> <VnRow>
<VnInput <VnInput
:label="t('familySituation')" :label="t('familySituation')"
@ -100,8 +100,12 @@ const deleteRelative = async (id) => {
:label="t(`spousePension`)" :label="t(`spousePension`)"
/> />
</VnRow> </VnRow>
<VnRow> <VnRow wrap>
<QCheckbox v-model="data.isDependend" :label="t(`isDependend`)" /> <QCheckbox
clearable
v-model="data.isDependend"
:label="t(`isDependend`)"
/>
<QCheckbox <QCheckbox
v-model="data.hasHousingPaymentBefore" v-model="data.hasHousingPaymentBefore"
:label="t(`hasHousingPaymentBefore`)" :label="t(`hasHousingPaymentBefore`)"
@ -127,7 +131,11 @@ const deleteRelative = async (id) => {
:filter="{ :filter="{
where: { workerFk: route.params.id }, where: { workerFk: route.params.id },
}" }"
:data-required="{ workerFk: route.params.id }" :data-required="{
workerFk: route.params.id,
isJointCustody: false,
isDependend: false,
}"
:has-sub-toolbar="false" :has-sub-toolbar="false"
> >
<template #body="{ rows }"> <template #body="{ rows }">

View File

@ -16,24 +16,14 @@ const actions = {
clone: async () => { clone: async () => {
const opts = { message: t('Zone cloned'), type: 'positive' }; const opts = { message: t('Zone cloned'), type: 'positive' };
try { const { data } = await axios.post(`Zones/${zoneId}/clone`, {});
const { data } = await axios.post(`Zones/${zoneId}/clone`, {}); notify(opts);
notify(opts); push(`/zone/${data.id}/basic-data`);
push(`/zone/${data.id}/basic-data`);
} catch (e) {
opts.message = t('It was not able to clone the zone');
opts.type = 'negative';
}
}, },
remove: async () => { remove: async () => {
try { await axios.post(`Zones/${zoneId}/deleteZone`);
await axios.post(`Zones/${zoneId}/deleteZone`); notify({ message: t('Zone deleted'), type: 'positive' });
push({ name: 'ZoneList' });
notify({ message: t('Zone deleted'), type: 'positive' });
push({ name: 'ZoneList' });
} catch (e) {
notify({ message: e.message, type: 'negative' });
}
}, },
}; };
function openConfirmDialog(callback) { function openConfirmDialog(callback) {

View File

@ -43,16 +43,14 @@ const onZoneEventFormClose = () => {
</script> </script>
<template> <template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
<QScrollArea class="fit text-grey-8"> <ZoneEventsPanel
<ZoneEventsPanel :first-day="firstDay"
:first-day="firstDay" :last-day="lastDay"
:last-day="lastDay" :events="events"
:events="events" v-model:formModeName="formModeName"
v-model:formModeName="formModeName" />
/> </Teleport>
</QScrollArea>
</QDrawer>
<QPage class="q-pa-md flex justify-center"> <QPage class="q-pa-md flex justify-center">
<ZoneCalendarGrid <ZoneCalendarGrid
v-model:events="events" v-model:events="events"

View File

@ -11,10 +11,6 @@ import { dashIfEmpty } from 'src/filters';
import { useWeekdayStore } from 'src/stores/useWeekdayStore'; import { useWeekdayStore } from 'src/stores/useWeekdayStore';
import { useVnConfirm } from 'composables/useVnConfirm'; import { useVnConfirm } from 'composables/useVnConfirm';
const formModeName = defineModel('formModeName', {
type: String,
required: true,
});
const props = defineProps({ const props = defineProps({
firstDay: { firstDay: {
type: Date, type: Date,
@ -31,8 +27,18 @@ const props = defineProps({
required: true, required: true,
default: () => [], default: () => [],
}, },
formModeName: {
type: String,
required: true,
default: 'include',
},
}); });
const formName = computed({
get: () => props.formModeName,
set: (value) => emit('update:formModeName', value),
});
const emit = defineEmits(['openZoneForm', 'update:formModeName']);
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const weekdayStore = useWeekdayStore(); const weekdayStore = useWeekdayStore();
@ -80,6 +86,15 @@ const deleteEvent = async (id) => {
await fetchData(); await fetchData();
}; };
const openInclusionForm = (event) => {
formName.value = 'include';
emit('openZoneForm', {
date: event.dated,
event,
isNewMode: false,
});
};
onMounted(async () => { onMounted(async () => {
weekdayStore.initStore(); weekdayStore.initStore();
}); });
@ -92,13 +107,13 @@ onMounted(async () => {
t('eventsPanel.editMode') t('eventsPanel.editMode')
}}</span> }}</span>
<QRadio <QRadio
v-model="formModeName" v-model="formName"
dense dense
val="include" val="include"
:label="t('eventsPanel.include')" :label="t('eventsPanel.include')"
/> />
<QRadio <QRadio
v-model="formModeName" v-model="formName"
dense dense
val="exclude" val="exclude"
:label="t('eventsPanel.exclude')" :label="t('eventsPanel.exclude')"

View File

@ -20,6 +20,7 @@ export default {
path: '', path: '',
name: 'MonitorMain', name: 'MonitorMain',
component: () => import('src/components/common/VnSectionMain.vue'), component: () => import('src/components/common/VnSectionMain.vue'),
props: (route) => ({ leftDrawer: route.name === 'MonitorClientsActions' }),
redirect: { name: 'MonitorTickets' }, redirect: { name: 'MonitorTickets' },
children: [ children: [
{ {