Merge branch 'dev' into 7266-buyLabelSupplier
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Guillermo Bonet 2024-10-29 06:03:07 +00:00
commit b8ecf40777
14 changed files with 221 additions and 44 deletions

View File

@ -313,6 +313,7 @@ globals:
changePass: Change password
deleteConfirmTitle: Delete selected elements
changeState: Change state
raid: 'Raid {daysInForward} days'
errors:
statusUnauthorized: Access denied
statusInternalServerError: An internal server error has ocurred
@ -370,7 +371,6 @@ entry:
companyFk: Company
travelFk: Travel
isExcludedFromAvailable: Inventory
isRaid: Raid
invoiceAmount: Import
summary:
commission: Commission
@ -381,7 +381,6 @@ entry:
ordered: Ordered
confirmed: Confirmed
booked: Booked
raid: Raid
excludedFromAvailable: Inventory
travelReference: Reference
travelAgency: Agency
@ -414,7 +413,6 @@ entry:
ordered: Ordered
confirmed: Confirmed
booked: Booked
raid: Raid
excludedFromAvailable: Inventory
agency: Agency
warehouseOut: Warehouse Out
@ -477,7 +475,6 @@ entry:
packingOut: Package out
landing: Landing
isExcludedFromAvailable: Es inventory
isRaid: Raid
ticket:
pageTitles:
tickets: Tickets
@ -1041,6 +1038,7 @@ travel:
warehouseIn: Warehouse In
delivered: Delivered
received: Received
daysInForward: Days in forward
thermographs:
code: Code
temperature: Temperature

View File

@ -317,6 +317,7 @@ globals:
changePass: Cambiar contraseña
deleteConfirmTitle: Eliminar los elementos seleccionados
changeState: Cambiar estado
raid: 'Redada {daysInForward} días'
errors:
statusUnauthorized: Acceso denegado
statusInternalServerError: Ha ocurrido un error interno del servidor
@ -372,7 +373,6 @@ entry:
companyFk: Empresa
travelFk: Envio
isExcludedFromAvailable: Inventario
isRaid: Redada
invoiceAmount: Importe
summary:
commission: Comisión
@ -383,7 +383,6 @@ entry:
ordered: Pedida
confirmed: Confirmada
booked: Contabilizada
raid: Redada
excludedFromAvailable: Inventario
travelReference: Referencia
travelAgency: Agencia
@ -416,7 +415,6 @@ entry:
ordered: Pedida
confirmed: Confirmado
booked: Asentado
raid: Redada
excludedFromAvailable: Inventario
agency: Agencia
warehouseOut: Alm. salida
@ -479,7 +477,6 @@ entry:
packingOut: Embalaje envíos
landing: Llegada
isExcludedFromAvailable: Es inventario
isRaid: Redada
ticket:
pageTitles:
tickets: Tickets
@ -1039,6 +1036,7 @@ travel:
warehouseIn: Alm. entrada
delivered: Enviada
received: Recibida
daysInForward: Días redada
thermographs:
code: Código
temperature: Temperatura

View File

@ -168,7 +168,6 @@ const onFilterTravelSelected = (formData, id) => {
v-model="data.isExcludedFromAvailable"
:label="t('entry.basicData.excludedFromAvailable')"
/>
<QCheckbox v-model="data.isRaid" :label="t('entry.basicData.raid')" />
<QCheckbox
v-if="isAdministrative()"
v-model="data.isBooked"

View File

@ -7,7 +7,6 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import useCardDescription from 'src/composables/useCardDescription';
import { useState } from 'src/composables/useState';
import { toDate } from 'src/filters';
import { usePrintService } from 'composables/usePrintService';
import { getUrl } from 'src/composables/getUrl';
@ -23,7 +22,6 @@ const $props = defineProps({
const route = useRoute();
const { t } = useI18n();
const { openReport } = usePrintService();
const state = useState();
const entryDescriptorRef = ref(null);
const url = ref();
@ -32,7 +30,14 @@ const entryFilter = {
{
relation: 'travel',
scope: {
fields: ['id', 'landed', 'shipped', 'agencyModeFk', 'warehouseOutFk'],
fields: [
'id',
'landed',
'shipped',
'agencyModeFk',
'warehouseOutFk',
'daysInForward',
],
include: [
{
relation: 'agency',
@ -75,8 +80,6 @@ const data = ref(useCardDescription());
const setData = (entity) =>
(data.value = useCardDescription(entity.supplier?.nickname, entity.id));
const currentEntry = computed(() => state.get('entry'));
const getEntryRedirectionFilter = (entry) => {
let entryTravel = entry && entry.travel;
@ -133,10 +136,10 @@ watch;
:value="entity.travel?.warehouseOut?.name"
/>
</template>
<template #icons>
<template #icons="{ entity }">
<QCardActions class="q-gutter-x-md">
<QIcon
v-if="currentEntry?.isExcludedFromAvailable"
v-if="entity?.isExcludedFromAvailable"
name="vn:inventory"
color="primary"
size="xs"
@ -144,12 +147,18 @@ watch;
<QTooltip>{{ t('Inventory entry') }}</QTooltip>
</QIcon>
<QIcon
v-if="currentEntry?.isRaid"
v-if="entity?.travel?.daysInForward"
name="vn:net"
color="primary"
size="xs"
>
<QTooltip>{{ t('Virtual entry') }}</QTooltip>
<QTooltip>
{{
t('globals.raid', {
daysInForward: entity?.travel?.daysInForward,
})
}}</QTooltip
>
</QIcon>
</QCardActions>
</template>

View File

@ -259,11 +259,6 @@ const fetchEntryBuys = async () => {
v-model="entry.isBooked"
:disable="true"
/>
<QCheckbox
:label="t('entry.summary.raid')"
v-model="entry.isRaid"
:disable="true"
/>
<QCheckbox
:label="t('entry.summary.excludedFromAvailable')"
v-model="entry.isExcludedFromAvailable"

View File

@ -41,6 +41,10 @@ const entryFilter = {
};
const columns = computed(() => [
{
name: 'status',
columnFilter: false,
},
{
align: 'left',
label: t('entry.list.tableVisibleColumns.id'),
@ -154,27 +158,8 @@ const columns = computed(() => [
cardVisible: true,
},
{
align: 'left',
label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
name: 'isExcludedFromAvailable',
chip: {
color: null,
condition: (value) => value,
icon: 'vn:inventory',
},
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('entry.list.tableVisibleColumns.isRaid'),
name: 'isRaid',
chip: {
color: null,
condition: (value) => value,
icon: 'vn:net',
},
columnFilter: {
inWhere: true,
},
@ -225,6 +210,26 @@ onMounted(async () => {
auto-load
:right-search="false"
>
<template #column-status="{ row }">
<div class="row q-gutter-xs">
<QIcon
v-if="!!row.isExcludedFromAvailable"
name="vn:inventory"
color="primary"
>
<QTooltip>{{
t('entry.list.tableVisibleColumns.isExcludedFromAvailable')
}}</QTooltip>
</QIcon>
<QIcon v-if="!!row.daysInForward" name="vn:net" color="primary">
<QTooltip>
{{
t('globals.raid', { daysInForward: row.daysInForward })
}}</QTooltip
>
</QIcon>
</div>
</template>
<template #column-supplierFk="{ row }">
<span class="link" @click.stop>
{{ row.supplierName }}

View File

@ -1,7 +1,6 @@
entryList:
list:
inventoryEntry: Inventory entry
virtualEntry: Virtual entry
entryFilter:
filter:
search: General search

View File

@ -4,7 +4,6 @@ You can search by entry reference: Puedes buscar por referencia de la entrada
entryList:
list:
inventoryEntry: Es inventario
virtualEntry: Es una redada
entryFilter:
filter:
search: Búsqueda general

View File

@ -72,6 +72,16 @@ const agenciesOptions = ref([]);
</VnRow>
<VnRow>
<VnInput v-model="data.m3" label="m3" />
<VnInput
:label="t('travel.basicData.daysInForward')"
v-model="data.daysInForward"
>
<template #append>
<QIcon name="info" class="cursor-info">
<QTooltip>{{ t('raidDays') }}</QTooltip>
</QIcon>
</template>
</VnInput>
</VnRow>
<VnRow>
<QCheckbox
@ -86,3 +96,10 @@ const agenciesOptions = ref([]);
</template>
</FormModel>
</template>
<i18n>
es:
raidDays: Al rellenarlo, generamos una redada. Indica los días que un travel se moverá automáticamente en el tiempo
en:
raidDays: When filling, a raid is generated. Enter the number of days the travel will automatically forward in time
</i18n>

View File

@ -32,6 +32,7 @@ const filter = {
'warehouseOutFk',
'cargoSupplierFk',
'agencyModeFk',
'daysInForward',
],
include: [
{
@ -77,6 +78,22 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
<VnLv :label="t('globals.landed')" :value="toDate(entity.landed)" />
<VnLv :label="t('globals.totalEntries')" :value="entity.totalEntries" />
</template>
<template #icons="{ entity }">
<QCardActions class="q-gutter-x-md">
<QIcon
v-if="entity.daysInForward"
name="vn:net"
color="primary"
size="xs"
>
<QTooltip>
{{
t('globals.raid', { daysInForward: entity.daysInForward })
}}</QTooltip
>
</QIcon>
</QCardActions>
</template>
<template #actions="{ entity }">
<QCardActions>
<QBtn

View File

@ -303,6 +303,10 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
<VnLv :label="t('globals.reference')" :value="travel.ref" />
<VnLv label="m³" :value="travel.m3" />
<VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
<VnLv
:label="t('travel.basicData.daysInForward')"
:value="travel?.daysInForward"
/>
</QCard>
<QCard class="full-width">
<VnTitle :text="t('travel.summary.entries')" />

View File

@ -45,6 +45,10 @@ const redirectCreateEntryView = (travelData) => {
};
const columns = computed(() => [
{
name: 'status',
columnFilter: false,
},
{
align: 'left',
name: 'id',
@ -221,6 +225,17 @@ const columns = computed(() => [
:is-editable="false"
:use-model="true"
>
<template #column-status="{ row }">
<div class="row">
<QIcon v-if="!!row.daysInForward" name="vn:net" color="primary">
<QTooltip>
{{
t('globals.raid', { daysInForward: row.daysInForward })
}}</QTooltip
>
</QIcon>
</div>
</template>
<template #column-shipped="{ row }">
<QBadge
text-color="black"

View File

@ -0,0 +1,120 @@
import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest';
import { createWrapper, axios } from 'app/test/vitest/helper';
import TicketAdvance from 'pages/Ticket/TicketAdvance.vue';
import { Notify } from 'quasar';
import { nextTick } from 'vue';
describe('TicketAdvance', () => {
let wrapper;
let vm;
beforeAll(() => {
vi.spyOn(axios, 'get').mockImplementation(() => ({ data: [] }));
wrapper = createWrapper(TicketAdvance);
vm = wrapper.vm;
vi.spyOn(vm.vnTableRef, 'reload').mockImplementation(() => vi.fn());
vm.vnTableRef.value = { params: {} };
});
beforeEach(() => {
Notify.create = vi.fn();
});
afterEach(() => {
vi.clearAllMocks();
});
describe('requestComponentUpdate()', () => {
const mockTicket = {
futureId: 1,
futureClientFk: 1,
nickname: 'test',
futureAddressFk: 1,
futureAgencyModeFk: 1,
futureWarehouseFk: 1,
futureCompanyFk: 1,
landed: '2023-01-02',
zoneFk: 1,
};
const mockParams = {
clientFk: 1,
nickname: 'test',
agencyModeFk: 1,
addressFk: 1,
zoneFk: 1,
warehouseFk: 1,
companyFk: 1,
landed: '2023-01-02',
shipped: '2023-01-01',
isDeleted: false,
isWithoutNegatives: false,
newTicket: undefined,
keepPrice: true,
};
const queryResult = 'tickets/1/componentUpdate';
it('should return query and params when ticket has no landed', async () => {
vm.vnTableRef.params.dateToAdvance = '2023-01-01';
await nextTick();
const mockLanded = { landed: '2023-01-02', zoneFk: 1 };
vi.spyOn(vm, 'getLanded').mockResolvedValue(mockLanded);
const { query, params } = await vm.requestComponentUpdate(mockTicket, false);
expect(query).toBe(queryResult);
expect(params).toEqual(mockParams);
});
it('should return query and params when ticket has landed', async () => {
const { query, params } = await vm.requestComponentUpdate(mockTicket, false);
expect(query).toBe(queryResult);
expect(params).toEqual(mockParams);
});
});
describe('moveTicketsAdvance()', () => {
it('should move tickets and notify success', async () => {
const tickets = [
{
id: 1,
futureId: 2,
futureShipped: '2023-01-01',
shipped: '2023-01-02',
workerFk: 1,
},
{
id: 2,
futureId: 3,
futureShipped: '2023-01-01',
shipped: '2023-01-02',
workerFk: 1,
},
];
vm.selectedTickets = tickets;
vi.spyOn(axios, 'post').mockResolvedValue({});
await vm.moveTicketsAdvance();
expect(axios.post).toHaveBeenCalledOnce('Tickets/merge', {
tickets: [
{
originId: 2,
destinationId: 1,
originShipped: '2023-01-01',
destinationShipped: '2023-01-02',
workerFk: 1,
},
{
originId: 3,
destinationId: 2,
originShipped: '2023-01-01',
destinationShipped: '2023-01-02',
workerFk: 1,
},
],
});
expect(vm.vnTableRef.reload).toHaveBeenCalled();
expect(Notify.create).toHaveBeenCalled();
expect(vm.selectedTickets).toEqual([]);
});
});
});

View File

@ -70,8 +70,10 @@ class FormDataMock {
vi.fn();
}
}
global.FormData = FormDataMock;
global.URL = class URL {};
global.Date.vnNew = () => new Date(Date.UTC(2001, 0, 1, 11));
export function createWrapper(component, options) {
const defaultOptions = {