feat: #7103 created test for VnSearchbar #1256

Merged
provira merged 14 commits from 7103-testVnSearchbar into dev 2025-01-22 11:15:21 +00:00
41 changed files with 290 additions and 178 deletions
Showing only changes of commit df403e35e6 - Show all commits

View File

@ -105,6 +105,7 @@ const manageDate = (date) => {
:rules="mixinRules" :rules="mixinRules"
:clearable="false" :clearable="false"
@click="isPopupOpen = !isPopupOpen" @click="isPopupOpen = !isPopupOpen"
@keydown="isPopupOpen = false"
hide-bottom-space hide-bottom-space
> >
<template #append> <template #append>

View File

@ -79,6 +79,7 @@ function dateToTime(newDate) {
style="min-width: 100px" style="min-width: 100px"
:rules="mixinRules" :rules="mixinRules"
@click="isPopupOpen = !isPopupOpen" @click="isPopupOpen = !isPopupOpen"
@keydown="isPopupOpen = false"
type="time" type="time"
hide-bottom-space hide-bottom-space
> >

View File

@ -294,7 +294,7 @@ async function onScroll({ to, direction, from, index }) {
} }
} }
defineExpose({ opts: myOptions }); defineExpose({ opts: myOptions, vnSelectRef });
function handleKeyDown(event) { function handleKeyDown(event) {
if (event.key === 'Tab' && !event.shiftKey) { if (event.key === 'Tab' && !event.shiftKey) {

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed } from 'vue'; import { ref, computed } from 'vue';
import { useRole } from 'src/composables/useRole'; import { useRole } from 'src/composables/useRole';
import { useAcl } from 'src/composables/useAcl'; import { useAcl } from 'src/composables/useAcl';
@ -7,6 +7,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
const emit = defineEmits(['update:modelValue']); const emit = defineEmits(['update:modelValue']);
const value = defineModel({ type: [String, Number, Object] }); const value = defineModel({ type: [String, Number, Object] });
const select = ref(null);
const $props = defineProps({ const $props = defineProps({
rolesAllowedToCreate: { rolesAllowedToCreate: {
type: Array, type: Array,
@ -33,10 +34,13 @@ const isAllowedToCreate = computed(() => {
if ($props.acls.length) return acl.hasAny($props.acls); if ($props.acls.length) return acl.hasAny($props.acls);
return role.hasAny($props.rolesAllowedToCreate); return role.hasAny($props.rolesAllowedToCreate);
}); });
defineExpose({ vnSelectDialogRef: select });
</script> </script>
<template> <template>
<VnSelect <VnSelect
ref="select"
v-model="value" v-model="value"
v-bind="$attrs" v-bind="$attrs"
@update:model-value="(...args) => emit('update:modelValue', ...args)" @update:model-value="(...args) => emit('update:modelValue', ...args)"

View File

@ -7,7 +7,9 @@ import { isDialogOpened } from 'src/filters';
const arrayDataStore = useArrayDataStore(); const arrayDataStore = useArrayDataStore();
export function useArrayData(key = useRoute().meta.moduleName, userOptions) { export function useArrayData(key, userOptions) {
key ??= useRoute().meta.moduleName;
if (!key) throw new Error('ArrayData: A key is required to use this composable'); if (!key) throw new Error('ArrayData: A key is required to use this composable');
if (!arrayDataStore.get(key)) arrayDataStore.set(key); if (!arrayDataStore.get(key)) arrayDataStore.set(key);

View File

@ -310,6 +310,14 @@ input::-webkit-inner-spin-button {
.no-visible { .no-visible {
visibility: hidden; visibility: hidden;
} }
.q-item > .q-item__section:has(.q-checkbox) {
max-width: min-content;
}
.row > .column:has(.q-checkbox) {
max-width: min-content;
}
.q-field__inner { .q-field__inner {
.q-field__control { .q-field__control {
min-height: auto !important; min-height: auto !important;

View File

@ -16,6 +16,7 @@ import getUpdatedValues from './getUpdatedValues';
import getParamWhere from './getParamWhere'; import getParamWhere from './getParamWhere';
import parsePhone from './parsePhone'; import parsePhone from './parsePhone';
import isDialogOpened from './isDialogOpened'; import isDialogOpened from './isDialogOpened';
import toCelsius from './toCelsius';
export { export {
getUpdatedValues, getUpdatedValues,
@ -36,4 +37,5 @@ export {
dashIfEmpty, dashIfEmpty,
dateRange, dateRange,
getParamWhere, getParamWhere,
toCelsius,
}; };

3
src/filters/toCelsius.js Normal file
View File

@ -0,0 +1,3 @@
export default function toCelsius(value) {
return value ? `${value}°C` : '';
}

View File

@ -704,6 +704,7 @@ travel:
totalEntries: Total entries totalEntries: Total entries
totalEntriesTooltip: Total entries totalEntriesTooltip: Total entries
daysOnward: Landed days onwards daysOnward: Landed days onwards
awb: AWB
summary: summary:
entryId: Entry Id entryId: Entry Id
freight: Freight freight: Freight

View File

@ -700,6 +700,7 @@ travel:
totalEntries: totalEntries:
totalEntriesTooltip: Entradas totales totalEntriesTooltip: Entradas totales
daysOnward: Días de llegada en adelante daysOnward: Días de llegada en adelante
awb: AWB
summary: summary:
entryId: Id entrada entryId: Id entrada
freight: Porte freight: Porte

View File

@ -38,7 +38,7 @@ const getBankEntities = (data, formData) => {
hide-selected hide-selected
option-label="name" option-label="name"
option-value="id" option-value="id"
v-model="data.payMethod" v-model="data.payMethodFk"
/> />
<VnInput :label="t('Due day')" clearable v-model="data.dueDay" /> <VnInput :label="t('Due day')" clearable v-model="data.dueDay" />
</VnRow> </VnRow>

View File

@ -59,6 +59,7 @@ const columns = computed(() => [
</script> </script>
<template> <template>
<VnTable <VnTable
:user-filter="{ include: filter.include }"
ref="tableRef" ref="tableRef"
data-key="ClientCredit" data-key="ClientCredit"
url="ClientCredits" url="ClientCredits"

View File

@ -84,6 +84,7 @@ const columns = computed(() => [
component: 'number', component: 'number',
autofocus: true, autofocus: true,
required: true, required: true,
positive: false,
}, },
format: ({ amount }) => toCurrency(amount), format: ({ amount }) => toCurrency(amount),
create: true, create: true,

View File

@ -431,7 +431,7 @@ function handleLocation(data, location) {
:label="t('customer.summary.salesPerson')" :label="t('customer.summary.salesPerson')"
v-model="data.salesPersonFk" v-model="data.salesPersonFk"
:params="{ :params="{
departmentCodes: ['VT', 'shopping'], departmentCodes: ['VT'],
}" }"
:has-avatar="true" :has-avatar="true"
:id-value="data.salesPersonFk" :id-value="data.salesPersonFk"

View File

@ -3,7 +3,6 @@ import { ref } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRole } from 'src/composables/useRole'; import { useRole } from 'src/composables/useRole';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
@ -11,7 +10,7 @@ import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue'; import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
import FilterTravelForm from 'src/components/FilterTravelForm.vue'; import FilterTravelForm from 'src/components/FilterTravelForm.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import { toDate } from 'src/filters'; import { toDate } from 'src/filters';
const route = useRoute(); const route = useRoute();
@ -26,6 +25,7 @@ const onFilterTravelSelected = (formData, id) => {
formData.travelFk = id; formData.travelFk = id;
}; };
</script> </script>
<template> <template>
<FetchData <FetchData
ref="companiesRef" ref="companiesRef"
@ -93,14 +93,13 @@ const onFilterTravelSelected = (formData, id) => {
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
<QItemSection> <QItemSection>
<QItemLabel <QItemLabel>
>{{ scope.opt?.agencyModeName }} - {{ scope.opt?.agencyModeName }} -
{{ scope.opt?.warehouseInName }} ({{ {{ scope.opt?.warehouseInName }}
toDate(scope.opt?.shipped) ({{ toDate(scope.opt?.shipped) }})
}}) &#x2192; {{ scope.opt?.warehouseOutName }} ({{ {{ scope.opt?.warehouseOutName }}
toDate(scope.opt?.landed) ({{ toDate(scope.opt?.landed) }})
}})</QItemLabel </QItemLabel>
>
</QItemSection> </QItemSection>
</QItem> </QItem>
</template> </template>
@ -126,6 +125,13 @@ const onFilterTravelSelected = (formData, id) => {
/> />
</VnRow> </VnRow>
<VnRow> <VnRow>
<VnInputNumber
:label="t('entry.summary.commission')"
v-model="data.commission"
step="1"
autofocus
:positive="false"
/>
<VnSelect <VnSelect
:label="t('entry.summary.currency')" :label="t('entry.summary.currency')"
v-model="data.currencyFk" v-model="data.currencyFk"
@ -133,12 +139,23 @@ const onFilterTravelSelected = (formData, id) => {
option-value="id" option-value="id"
option-label="code" option-label="code"
/> />
<QInput </VnRow>
:label="t('entry.summary.commission')" <VnRow>
v-model="data.commission" <VnInputNumber
type="number" v-model="data.initialTemperature"
autofocus name="initialTemperature"
min="0" :label="t('entry.basicData.initialTemperature')"
:step="0.5"
:decimal-places="2"
:positive="false"
/>
<VnInputNumber
v-model="data.finalTemperature"
name="finalTemperature"
:label="t('entry.basicData.finalTemperature')"
:step="0.5"
:decimal-places="2"
:positive="false"
/> />
</VnRow> </VnRow>
<VnRow> <VnRow>

View File

@ -7,7 +7,7 @@ import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'src/components/ui/VnLv.vue';
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue'; import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
import { toDate, toCurrency } from 'src/filters'; import { toDate, toCurrency, toCelsius } from 'src/filters';
import { getUrl } from 'src/composables/getUrl'; import { getUrl } from 'src/composables/getUrl';
import axios from 'axios'; import axios from 'axios';
import FetchedTags from 'src/components/ui/FetchedTags.vue'; import FetchedTags from 'src/components/ui/FetchedTags.vue';
@ -193,6 +193,14 @@ const fetchEntryBuys = async () => {
:label="t('entry.summary.invoiceNumber')" :label="t('entry.summary.invoiceNumber')"
:value="entry.invoiceNumber" :value="entry.invoiceNumber"
/> />
<VnLv
:label="t('entry.basicData.initialTemperature')"
:value="toCelsius(entry.initialTemperature)"
/>
<VnLv
:label="t('entry.basicData.finalTemperature')"
:value="toCelsius(entry.finalTemperature)"
/>
</QCard> </QCard>
<QCard class="vn-one"> <QCard class="vn-one">
<VnTitle <VnTitle

View File

@ -3,7 +3,7 @@ import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import EntryFilter from './EntryFilter.vue'; import EntryFilter from './EntryFilter.vue';
import VnTable from 'components/VnTable/VnTable.vue'; import VnTable from 'components/VnTable/VnTable.vue';
import { toDate } from 'src/filters'; import { toCelsius, toDate } from 'src/filters';
import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import EntrySummary from './Card/EntrySummary.vue'; import EntrySummary from './Card/EntrySummary.vue';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue'; import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
@ -157,6 +157,20 @@ const columns = computed(() => [
name: 'invoiceAmount', name: 'invoiceAmount',
cardVisible: true, cardVisible: true,
}, },
{
align: 'left',
name: 'initialTemperature',
label: t('entry.basicData.initialTemperature'),
field: 'initialTemperature',
format: (row) => toCelsius(row.initialTemperature),
},
{
align: 'left',
name: 'finalTemperature',
label: t('entry.basicData.finalTemperature'),
field: 'finalTemperature',
format: (row) => toCelsius(row.finalTemperature),
},
{ {
label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'), label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
name: 'isExcludedFromAvailable', name: 'isExcludedFromAvailable',
@ -188,7 +202,7 @@ const columns = computed(() => [
:array-data-props="{ :array-data-props="{
url: 'Entries/filter', url: 'Entries/filter',
order: 'id DESC', order: 'id DESC',
userFilter: 'entryFilter', userFilter: entryFilter,
}" }"
> >
<template #rightMenu> <template #rightMenu>

View File

@ -40,6 +40,8 @@ entry:
observation: Observation observation: Observation
booked: Booked booked: Booked
excludedFromAvailable: Inventory excludedFromAvailable: Inventory
initialTemperature: Ini °C
finalTemperature: Fin °C
buys: buys:
observations: Observations observations: Observations
packagingFk: Box packagingFk: Box

View File

@ -41,6 +41,8 @@ entry:
commission: Comisión commission: Comisión
booked: Asentado booked: Asentado
excludedFromAvailable: Inventario excludedFromAvailable: Inventario
initialTemperature: Ini °C
finalTemperature: Fin °C
buys: buys:
observations: Observaciónes observations: Observaciónes
packagingFk: Embalaje packagingFk: Embalaje

View File

@ -6,24 +6,16 @@ import axios from 'axios';
import { toCurrency, toDate } from 'src/filters'; import { toCurrency, toDate } from 'src/filters';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'src/components/ui/VnLv.vue';
import CardDescriptor from 'components/ui/CardDescriptor.vue'; import CardDescriptor from 'components/ui/CardDescriptor.vue';
import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import { useCapitalize } from 'src/composables/useCapitalize';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue'; import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
import InvoiceInDescriptorMenu from './InvoiceInDescriptorMenu.vue'; import InvoiceInDescriptorMenu from './InvoiceInDescriptorMenu.vue';
const $props = defineProps({ id: { type: Number, default: null } }); const $props = defineProps({ id: { type: Number, default: null } });
const { push, currentRoute } = useRouter(); const { currentRoute } = useRouter();
const { t } = useI18n(); const { t } = useI18n();
const cardDescriptorRef = ref(); const cardDescriptorRef = ref();
const correctionDialogRef = ref();
const entityId = computed(() => $props.id || +currentRoute.value.params.id); const entityId = computed(() => $props.id || +currentRoute.value.params.id);
const totalAmount = ref(); const totalAmount = ref();
const config = ref();
const cplusRectificationTypes = ref([]);
const siiTypeInvoiceIns = ref([]);
const invoiceCorrectionTypes = ref([]);
const filter = { const filter = {
include: [ include: [
@ -85,12 +77,6 @@ const routes = reactive({
return { name: 'EntryCard', params: { id } }; return { name: 'EntryCard', params: { id } };
}, },
}); });
const correctionFormData = reactive({
invoiceReason: 2,
invoiceType: 2,
invoiceClass: 6,
});
const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));
onBeforeMount(async () => { onBeforeMount(async () => {
await setInvoiceCorrection(entityId.value); await setInvoiceCorrection(entityId.value);
@ -122,38 +108,8 @@ async function setInvoiceCorrection(id) {
(corrected) => corrected.correctingFk (corrected) => corrected.correctingFk
); );
} }
const createInvoiceInCorrection = async () => {
const { data: correctingId } = await axios.post(
'InvoiceIns/corrective',
Object.assign(correctionFormData, { id: entityId.value })
);
push({ path: `/invoice-in/${correctingId}/summary` });
};
</script> </script>
<template> <template>
<FetchData
url="InvoiceInConfigs"
:where="{ fields: ['sageWithholdingFk'] }"
auto-load
@on-fetch="(data) => (config = data)"
/>
<FetchData
url="CplusRectificationTypes"
@on-fetch="(data) => (cplusRectificationTypes = data)"
auto-load
/>
<FetchData
url="SiiTypeInvoiceIns"
:where="{ code: { like: 'R%' } }"
@on-fetch="(data) => (siiTypeInvoiceIns = data)"
auto-load
/>
<FetchData
url="InvoiceCorrectionTypes"
@on-fetch="(data) => (invoiceCorrectionTypes = data)"
auto-load
/>
<CardDescriptor <CardDescriptor
ref="cardDescriptorRef" ref="cardDescriptorRef"
module="InvoiceIn" module="InvoiceIn"
@ -167,7 +123,10 @@ const createInvoiceInCorrection = async () => {
</template> </template>
<template #body="{ entity }"> <template #body="{ entity }">
<VnLv :label="t('invoicein.list.issued')" :value="toDate(entity.issued)" /> <VnLv :label="t('invoicein.list.issued')" :value="toDate(entity.issued)" />
<VnLv :label="t('invoicein.summary.bookedDate')" :value="toDate(entity.booked)" /> <VnLv
:label="t('invoicein.summary.bookedDate')"
:value="toDate(entity.booked)"
/>
<VnLv :label="t('invoicein.list.amount')" :value="toCurrency(totalAmount)" /> <VnLv :label="t('invoicein.list.amount')" :value="toCurrency(totalAmount)" />
<VnLv :label="t('invoicein.list.supplier')"> <VnLv :label="t('invoicein.list.supplier')">
<template #value> <template #value>
@ -227,65 +186,6 @@ const createInvoiceInCorrection = async () => {
</QCardActions> </QCardActions>
</template> </template>
</CardDescriptor> </CardDescriptor>
<QDialog ref="correctionDialogRef">
<QCard>
<QCardSection>
<QItem class="q-px-none">
<span class="text-primary text-h6 full-width">
{{ t('Create rectificative invoice') }}
</span>
<QBtn icon="close" flat round dense v-close-popup />
</QItem>
</QCardSection>
<QCardSection>
<QItem>
<QItemSection>
<QInput
:label="t('Original invoice')"
v-model="entityId"
readonly
/>
<VnSelect
:label="`${useCapitalize(t('globals.class'))}`"
v-model="correctionFormData.invoiceClass"
:options="siiTypeInvoiceIns"
option-value="id"
option-label="code"
:required="true"
/>
</QItemSection>
<QItemSection>
<VnSelect
:label="`${useCapitalize(t('globals.type'))}`"
v-model="correctionFormData.invoiceType"
:options="cplusRectificationTypes"
option-value="id"
option-label="description"
:required="true"
/>
<VnSelect
:label="`${useCapitalize(t('globals.reason'))}`"
v-model="correctionFormData.invoiceReason"
:options="invoiceCorrectionTypes"
option-value="id"
option-label="description"
:required="true"
/>
</QItemSection>
</QItem>
</QCardSection>
<QCardActions class="justify-end q-mr-sm">
<QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
<QBtn
:label="t('globals.save')"
color="primary"
v-close-popup
@click="createInvoiceInCorrection"
:disable="isNotFilled"
/>
</QCardActions>
</QCard>
</QDialog>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.q-dialog { .q-dialog {

View File

@ -8,9 +8,12 @@ import { useAcl } from 'src/composables/useAcl';
import { downloadFile } from 'src/composables/downloadFile'; import { downloadFile } from 'src/composables/downloadFile';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import { usePrintService } from 'composables/usePrintService'; import { usePrintService } from 'composables/usePrintService';
import { useCapitalize } from 'src/composables/useCapitalize';
import VnConfirm from 'src/components/ui/VnConfirm.vue'; import VnConfirm from 'src/components/ui/VnConfirm.vue';
import SendEmailDialog from 'components/common/SendEmailDialog.vue'; import SendEmailDialog from 'components/common/SendEmailDialog.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import InvoiceInToBook from '../InvoiceInToBook.vue'; import InvoiceInToBook from '../InvoiceInToBook.vue';
import FetchData from 'src/components/FetchData.vue';
const { hasAny } = useAcl(); const { hasAny } = useAcl();
const { t } = useI18n(); const { t } = useI18n();
@ -31,6 +34,10 @@ const correctionDialogRef = ref();
const invoiceInCorrection = reactive({ correcting: [], corrected: null }); const invoiceInCorrection = reactive({ correcting: [], corrected: null });
const entityId = computed(() => $props.invoice.id || +currentRoute.value.params.id); const entityId = computed(() => $props.invoice.id || +currentRoute.value.params.id);
const invoiceIn = computed(() => arrayData.store.data); const invoiceIn = computed(() => arrayData.store.data);
const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));
const invoiceCorrectionTypes = ref([]);
const cplusRectificationTypes = ref([]);
const siiTypeInvoiceIns = ref([]);
const actions = { const actions = {
unbook: { unbook: {
title: t('assertAction', { action: t('invoicein.descriptorMenu.unbook') }), title: t('assertAction', { action: t('invoicein.descriptorMenu.unbook') }),
@ -48,6 +55,11 @@ const actions = {
sendPdf: { cb: sendPdfInvoiceConfirmation }, sendPdf: { cb: sendPdfInvoiceConfirmation },
correct: { cb: () => correctionDialogRef.value.show() }, correct: { cb: () => correctionDialogRef.value.show() },
}; };
const correctionFormData = reactive({
invoiceReason: 2,
invoiceType: 2,
invoiceClass: 8,
});
const canEditProp = (props) => const canEditProp = (props) =>
hasAny([{ model: 'InvoiceIn', props, accessType: 'WRITE' }]); hasAny([{ model: 'InvoiceIn', props, accessType: 'WRITE' }]);
@ -133,9 +145,39 @@ function sendPdfInvoice({ address }) {
recipient: address, recipient: address,
}); });
} }
const createInvoiceInCorrection = async () => {
const { data: correctingId } = await axios.post(
'InvoiceIns/corrective',
Object.assign(correctionFormData, { id: entityId.value })
);
push({ path: `/invoice-in/${correctingId}/summary` });
};
</script> </script>
<template> <template>
<FetchData
url="InvoiceCorrectionTypes"
@on-fetch="(data) => (invoiceCorrectionTypes = data)"
auto-load
/>
<FetchData
url="CplusRectificationTypes"
@on-fetch="(data) => (cplusRectificationTypes = data)"
auto-load
/>
<FetchData
url="SiiTypeInvoiceIns"
:where="{ code: { like: 'R%' } }"
@on-fetch="(data) => (siiTypeInvoiceIns = data)"
auto-load
/>
<FetchData
url="InvoiceInConfigs"
:where="{ fields: ['sageWithholdingFk'] }"
auto-load
@on-fetch="(data) => (config = data)"
/>
<InvoiceInToBook> <InvoiceInToBook>
<template #content="{ book }"> <template #content="{ book }">
<QItem <QItem
@ -162,7 +204,7 @@ function sendPdfInvoice({ address }) {
v-if="canEditProp('deleteById')" v-if="canEditProp('deleteById')"
v-ripple v-ripple
clickable clickable
@click="triggerMenu('invoicein.descriptorMenu.delete')" @click="triggerMenu('delete')"
> >
<QItemSection>{{ t('invoicein.descriptorMenu.deleteInvoice') }}</QItemSection> <QItemSection>{{ t('invoicein.descriptorMenu.deleteInvoice') }}</QItemSection>
</QItem> </QItem>
@ -192,6 +234,79 @@ function sendPdfInvoice({ address }) {
<QItem v-if="invoice.dmsFk" v-ripple clickable @click="downloadFile(invoice.dmsFk)"> <QItem v-if="invoice.dmsFk" v-ripple clickable @click="downloadFile(invoice.dmsFk)">
<QItemSection>{{ t('components.smartCard.downloadFile') }}</QItemSection> <QItemSection>{{ t('components.smartCard.downloadFile') }}</QItemSection>
</QItem> </QItem>
<QDialog ref="correctionDialogRef">
<QCard>
<QCardSection>
<QItem class="q-px-none">
<span class="text-primary text-h6 full-width">
{{ t('Create rectificative invoice') }}
</span>
<QBtn icon="close" flat round dense v-close-popup />
</QItem>
</QCardSection>
<QCardSection>
<QItem>
<QItemSection>
<QInput
:label="t('Original invoice')"
v-model="entityId"
readonly
/>
<VnSelect
:label="`${useCapitalize(t('globals.class'))}`"
v-model="correctionFormData.invoiceClass"
:options="siiTypeInvoiceIns"
option-value="id"
option-label="code"
:required="true"
/>
</QItemSection>
<QItemSection>
<VnSelect
:label="`${useCapitalize(t('globals.type'))}`"
v-model="correctionFormData.invoiceType"
:options="cplusRectificationTypes"
option-value="id"
option-label="description"
:required="true"
>
<template #option="{ itemProps, opt }">
<QItem v-bind="itemProps">
{{ console.log('opt: ', opt) }}
<QItemSection>
<QItemLabel
>{{ opt.id }} -
{{ opt.description }}</QItemLabel
>
</QItemSection>
</QItem>
<div></div>
</template>
</VnSelect>
<VnSelect
:label="`${useCapitalize(t('globals.reason'))}`"
v-model="correctionFormData.invoiceReason"
:options="invoiceCorrectionTypes"
option-value="id"
option-label="description"
:required="true"
/>
</QItemSection>
</QItem>
</QCardSection>
<QCardActions class="justify-end q-mr-sm">
<QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
<QBtn
:label="t('globals.save')"
color="primary"
v-close-popup
@click="createInvoiceInCorrection"
:disable="isNotFilled"
/>
</QCardActions>
</QCard>
</QDialog>
</template> </template>
<i18n> <i18n>

View File

@ -25,6 +25,7 @@ const sageTaxTypes = ref([]);
const sageTransactionTypes = ref([]); const sageTransactionTypes = ref([]);
const rowsSelected = ref([]); const rowsSelected = ref([]);
const invoiceInFormRef = ref(); const invoiceInFormRef = ref();
const expenseRef = ref();
defineProps({ defineProps({
actionIcon: { actionIcon: {
@ -128,7 +129,7 @@ function autocompleteExpense(evt, row, col) {
({ id }) => id == useAccountShortToStandard(param) ({ id }) => id == useAccountShortToStandard(param)
); );
if (lookup) row[col.model] = lookup; expenseRef.value.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
} }
</script> </script>
<template> <template>
@ -167,6 +168,7 @@ function autocompleteExpense(evt, row, col) {
<template #body-cell-expense="{ row, col }"> <template #body-cell-expense="{ row, col }">
<QTd> <QTd>
<VnSelectDialog <VnSelectDialog
ref="expenseRef"
v-model="row[col.model]" v-model="row[col.model]"
:options="col.options" :options="col.options"
:option-value="col.optionValue" :option-value="col.optionValue"

View File

@ -68,6 +68,8 @@ function handleLocation(data, location) {
'supplierActivityFk', 'supplierActivityFk',
'healthRegister', 'healthRegister',
'street', 'street',
'isVies',
'isTrucker',
], ],
include: [ include: [
{ {

View File

@ -54,7 +54,6 @@ const transfer = ref({
}); });
const tableRef = ref([]); const tableRef = ref([]);
const canProceed = ref(); const canProceed = ref();
const isLoading = ref(false);
watch( watch(
() => route.params.id, () => route.params.id,
@ -197,6 +196,7 @@ const changeQuantity = async (sale) => {
try { try {
if (!rowToUpdate.value) return; if (!rowToUpdate.value) return;
rowToUpdate.value = null; rowToUpdate.value = null;
sale.isNew = false;
await updateQuantity(sale); await updateQuantity(sale);
} catch (e) { } catch (e) {
const { quantity } = tableRef.value.CrudModelRef.originalData.find( const { quantity } = tableRef.value.CrudModelRef.originalData.find(
@ -214,9 +214,6 @@ const updateQuantity = async ({ quantity, id }) => {
}; };
const addSale = async (sale) => { const addSale = async (sale) => {
if (isLoading.value) return;
isLoading.value = true;
const params = { const params = {
barcode: sale.itemFk, barcode: sale.itemFk,
quantity: sale.quantity, quantity: sale.quantity,
@ -237,6 +234,7 @@ const addSale = async (sale) => {
sale.item = newSale.item; sale.item = newSale.item;
notify('globals.dataSaved', 'positive'); notify('globals.dataSaved', 'positive');
sale.isNew = false;
arrayData.fetch({}); arrayData.fetch({});
}; };
@ -754,6 +752,7 @@ watch(
option-label="name" option-label="name"
option-value="id" option-value="id"
v-model="row.itemFk" v-model="row.itemFk"
:use-like="false"
@update:model-value="updateItem(row)" @update:model-value="updateItem(row)"
> >
<template #option="scope"> <template #option="scope">

View File

@ -166,8 +166,10 @@ async function handleSave() {
v-model="row.ticketServiceTypeFk" v-model="row.ticketServiceTypeFk"
:options="ticketServiceOptions" :options="ticketServiceOptions"
option-label="name" option-label="name"
:roles-allowed-to-create="['administrative']"
option-value="id" option-value="id"
hide-selected hide-selected
sort-by="name ASC"
> >
<template #form> <template #form>
<TicketCreateServiceType <TicketCreateServiceType

View File

@ -9,7 +9,7 @@ import VnTitle from 'src/components/common/VnTitle.vue';
import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue'; import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'src/components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import { toDate, toCurrency } from 'src/filters'; import { toDate, toCurrency, toCelsius } from 'src/filters';
import axios from 'axios'; import axios from 'axios';
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue'; import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
@ -97,6 +97,20 @@ const entriesTableColumns = computed(() => {
showValue: true, showValue: true,
}, },
{ label: 'm³', field: 'm3', name: 'm3', align: 'left', showValue: true }, { label: 'm³', field: 'm3', name: 'm3', align: 'left', showValue: true },
{
label: t('entry.basicData.initialTemperature'),
field: 'initialTemperature',
name: 'initialTemperature',
align: 'left',
format: (val) => toCelsius(val),
},
{
label: t('entry.basicData.finalTemperature'),
field: 'finalTemperature',
name: 'finalTemperature',
align: 'left',
format: (val) => toCelsius(val),
},
{ {
label: '', label: '',
field: 'observation', field: 'observation',
@ -127,14 +141,14 @@ const thermographsTableColumns = computed(() => {
field: 'maxTemperature', field: 'maxTemperature',
name: 'maxTemperature', name: 'maxTemperature',
align: 'left', align: 'left',
format: (val) => (val ? `${val}°` : ''), format: (val) => toCelsius(val),
}, },
{ {
label: t('globals.minTemperature'), label: t('globals.minTemperature'),
field: 'minTemperature', field: 'minTemperature',
name: 'minTemperature', name: 'minTemperature',
align: 'left', align: 'left',
format: (val) => (val ? `${val}°` : ''), format: (val) => toCelsius(val),
}, },
{ {
label: t('globals.state'), label: t('globals.state'),

View File

@ -10,7 +10,7 @@ import FetchData from 'src/components/FetchData.vue';
import axios from 'axios'; import axios from 'axios';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import { toDate } from 'src/filters'; import { toDate, toCelsius } from 'src/filters';
import { downloadFile } from 'src/composables/downloadFile'; import { downloadFile } from 'src/composables/downloadFile';
const route = useRoute(); const route = useRoute();
@ -52,14 +52,14 @@ const TableColumns = computed(() => {
field: 'maxTemperature', field: 'maxTemperature',
name: 'maxTemperature', name: 'maxTemperature',
align: 'left', align: 'left',
format: (val) => (val ? `${val}°` : ''), format: (val) => toCelsius(val),
}, },
{ {
label: t('globals.minTemperature'), label: t('globals.minTemperature'),
field: 'minTemperature', field: 'minTemperature',
name: 'minTemperature', name: 'minTemperature',
align: 'left', align: 'left',
format: (val) => (val ? `${val}°` : ''), format: (val) => toCelsius(val),
}, },
{ {
label: t('globals.state'), label: t('globals.state'),

View File

@ -79,6 +79,13 @@ const columns = computed(() => [
cardVisible: true, cardVisible: true,
create: true, create: true,
}, },
{
align: 'left',
name: 'awb',
label: t('travel.travelList.tableVisibleColumns.awb'),
columnFilter: false,
format: (row) => row.awbCode,
},
{ {
align: 'left', align: 'left',
name: 'warehouseInFk', name: 'warehouseInFk',

View File

@ -27,7 +27,7 @@ const initialData = computed(() => {
return { return {
userFk: routeId.value, userFk: routeId.value,
deviceProductionFk: null, deviceProductionFk: null,
simSerialNumber: null, simFk: null,
}; };
}); });
@ -42,7 +42,7 @@ const deallocatePDA = async (deviceProductionFk) => {
function reloadData() { function reloadData() {
initialData.value.deviceProductionFk = null; initialData.value.deviceProductionFk = null;
initialData.value.simSerialNumber = null; initialData.value.simFk = null;
paginate.value.fetch(); paginate.value.fetch();
} }
</script> </script>
@ -89,7 +89,7 @@ function reloadData() {
/> />
<VnInput <VnInput
:label="t('Current SIM')" :label="t('Current SIM')"
:model-value="row?.simSerialNumber" :model-value="row?.simFk"
disable disable
/> />
<QBtn <QBtn
@ -150,7 +150,7 @@ function reloadData() {
</template> </template>
</VnSelect> </VnSelect>
<VnInput <VnInput
v-model="data.simSerialNumber" v-model="data.simFk"
:label="t('SIM serial number')" :label="t('SIM serial number')"
id="simSerialNumber" id="simSerialNumber"
use-input use-input

View File

@ -283,21 +283,22 @@ const fetchWeekData = async () => {
year: selectedDateYear.value, year: selectedDateYear.value,
week: selectedWeekNumber.value, week: selectedWeekNumber.value,
}; };
const mail = ( try {
await axiosNoError.get(`Workers/${route.params.id}/mail`, { const [{ data: mailData }, { data: countData }] = await Promise.all([
axiosNoError.get(`Workers/${route.params.id}/mail`, {
params: { filter: { where } }, params: { filter: { where } },
}) }),
).data[0]; axiosNoError.get('WorkerTimeControlMails/count', { params: { where } }),
]);
if (!mail) state.value = null; const mail = mailData[0];
else {
state.value = mail.state; state.value = mail?.state;
reason.value = mail.reason; reason.value = mail?.reason;
canResend.value = !!countData.count;
} catch {
state.value = null;
} }
canResend.value = !!(
await axiosNoError.get('WorkerTimeControlMails/count', { params: { where } })
).data.count;
}; };
const setHours = (data) => { const setHours = (data) => {

View File

@ -1,5 +1,6 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
describe('ClaimPhoto', () => { // redmine.verdnatura.es/issues/8417
describe.skip('ClaimPhoto', () => {
beforeEach(() => { beforeEach(() => {
const claimId = 1; const claimId = 1;
cy.login('developer'); cy.login('developer');

View File

@ -8,8 +8,8 @@ describe('EntryMy when is supplier', () => {
}, },
}); });
}); });
// https://redmine.verdnatura.es/issues/8418
it('should open buyLabel when is supplier', () => { it.skip('should open buyLabel when is supplier', () => {
cy.get( cy.get(
'[to="/null/3"] > .q-card > .column > .q-btn > .q-btn__content > .q-icon' '[to="/null/3"] > .q-card > .column > .q-btn > .q-btn__content > .q-icon'
).click(); ).click();

View File

@ -1,6 +1,6 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
// https://redmine.verdnatura.es/issues/8419
describe('InvoiceInCorrective', () => { describe.skip('InvoiceInCorrective', () => {
const createCorrective = '.q-menu > .q-list > :nth-child(6) > .q-item__section'; const createCorrective = '.q-menu > .q-list > :nth-child(6) > .q-item__section';
const rectificativeSection = '.q-drawer-container .q-list > a:nth-child(6)'; const rectificativeSection = '.q-drawer-container .q-list > a:nth-child(6)';
const saveDialog = '.q-card > .q-card__actions > .q-btn--standard '; const saveDialog = '.q-card > .q-card__actions > .q-btn--standard ';

View File

@ -21,8 +21,8 @@ describe('InvoiceInList', () => {
cy.url().should('include', `/invoice-in/${id}/summary`); cy.url().should('include', `/invoice-in/${id}/summary`);
}); });
}); });
// https://redmine.verdnatura.es/issues/8420
it('should open the details', () => { it.skip('should open the details', () => {
cy.get(firstDetailBtn).click(); cy.get(firstDetailBtn).click();
cy.get(summaryHeaders).eq(1).contains('Basic data'); cy.get(summaryHeaders).eq(1).contains('Basic data');
cy.get(summaryHeaders).eq(4).contains('Vat'); cy.get(summaryHeaders).eq(4).contains('Vat');

View File

@ -35,8 +35,8 @@ describe('InvoiceOut summary', () => {
cy.dataCy('VnConfirm_confirm').click(); cy.dataCy('VnConfirm_confirm').click();
cy.checkNotification('InvoiceOut deleted'); cy.checkNotification('InvoiceOut deleted');
}); });
// https://redmine.verdnatura.es/issues/8415
it('should transfer the invoice ', () => { it.skip('should transfer the invoice ', () => {
cy.typeSearchbar('T1111111{enter}'); cy.typeSearchbar('T1111111{enter}');
cy.dataCy('descriptor-more-opts').click(); cy.dataCy('descriptor-more-opts').click();
cy.get('.q-menu > .q-list > :nth-child(1)').click(); cy.get('.q-menu > .q-list > :nth-child(1)').click();

View File

@ -15,8 +15,8 @@ describe('Item list', () => {
cy.get('.q-menu .q-item').contains('Anthurium').click(); cy.get('.q-menu .q-item').contains('Anthurium').click();
cy.get('.q-virtual-scroll__content > :nth-child(4) > :nth-child(4)').click(); cy.get('.q-virtual-scroll__content > :nth-child(4) > :nth-child(4)').click();
}); });
// https://redmine.verdnatura.es/issues/8421
it('should create an item', () => { it.skip('should create an item', () => {
const data = { const data = {
Description: { val: `Test item` }, Description: { val: `Test item` },
Type: { val: `Crisantemo`, type: 'select' }, Type: { val: `Crisantemo`, type: 'select' },

View File

@ -18,8 +18,8 @@ describe('Item tag', () => {
+cy.dataCy('crudModelDefaultSaveBtn').click(); +cy.dataCy('crudModelDefaultSaveBtn').click();
cy.checkNotification("The tag or priority can't be repeated for an item"); cy.checkNotification("The tag or priority can't be repeated for an item");
}); });
// https://redmine.verdnatura.es/issues/8422
it('should add a new tag', () => { it.skip('should add a new tag', () => {
cy.get('.q-page').should('be.visible'); cy.get('.q-page').should('be.visible');
cy.get('.q-page-sticky > div').click(); cy.get('.q-page-sticky > div').click();
cy.get('.q-page-sticky > div').click(); cy.get('.q-page-sticky > div').click();

View File

@ -1,6 +1,6 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
// https://redmine.verdnatura.es/issues/8423
describe('Ticket expedtion', () => { describe.skip('Ticket expedtion', () => {
const tableContent = '.q-table .q-virtual-scroll__content'; const tableContent = '.q-table .q-virtual-scroll__content';
const stateTd = 'td:nth-child(9)'; const stateTd = 'td:nth-child(9)';

View File

@ -30,8 +30,8 @@ describe('TicketList', () => {
cy.get(firstRow).find('.q-btn:first').click(); cy.get(firstRow).find('.q-btn:first').click();
cy.get('@windowOpen').should('be.calledWithMatch', /\/ticket\/\d+\/sale/); cy.get('@windowOpen').should('be.calledWithMatch', /\/ticket\/\d+\/sale/);
}); });
// https://redmine.verdnatura.es/issues/8424
it('should open ticket summary', () => { it.skip('should open ticket summary', () => {
searchResults(); searchResults();
cy.get(firstRow).find('.q-btn:last').click(); cy.get(firstRow).find('.q-btn:last').click();
cy.dataCy('ticketSummary').should('exist'); cy.dataCy('ticketSummary').should('exist');

View File

@ -53,7 +53,8 @@ describe('VnLocation', () => {
cy.waitForElement('.q-card'); cy.waitForElement('.q-card');
cy.get(inputLocation).click(); cy.get(inputLocation).click();
}); });
it('Show all options', function () { // https://redmine.verdnatura.es/issues/8436
it.skip('Show all options', function () {
cy.get(locationOptions).should('have.length.at.least', 5); cy.get(locationOptions).should('have.length.at.least', 5);
}); });
it('input filter location as "al"', function () { it('input filter location as "al"', function () {

View File

@ -18,8 +18,8 @@ describe('ZoneWarehouse', () => {
cy.get(saveBtn).click(); cy.get(saveBtn).click();
cy.checkNotification(dataError); cy.checkNotification(dataError);
}); });
// https://redmine.verdnatura.es/issues/8425
it('should create & remove a warehouse', () => { it.skip('should create & remove a warehouse', () => {
cy.addBtnClick(); cy.addBtnClick();
cy.fillInForm(data); cy.fillInForm(data);
cy.get(saveBtn).click(); cy.get(saveBtn).click();