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

This commit is contained in:
PAU ROVIRA ROSALENY 2025-01-03 09:37:03 +00:00
commit e0a9a5ca72
49 changed files with 301 additions and 150 deletions

View File

@ -55,13 +55,6 @@ async function setCountry(countryFk, data) {
}
// Province
async function handleProvinces(data) {
provincesOptions.value = data;
if (postcodeFormData.countryFk) {
await fetchTowns();
}
}
async function setProvince(id, data) {
if (data.provinceFk === id) return;
const newProvince = provincesOptions.value.find((province) => province.id == id);

View File

@ -1,7 +1,7 @@
<script setup>
import axios from 'axios';
import { onMounted, onUnmounted, computed, ref, watch, nextTick } from 'vue';
import { onBeforeRouteLeave, useRouter } from 'vue-router';
import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { useState } from 'src/composables/useState';
@ -12,7 +12,6 @@ import SkeletonForm from 'components/ui/SkeletonForm.vue';
import VnConfirm from './ui/VnConfirm.vue';
import { tMobile } from 'src/composables/tMobile';
import { useArrayData } from 'src/composables/useArrayData';
import { useRoute } from 'vue-router';
const { push } = useRouter();
const quasar = useQuasar();

View File

@ -59,8 +59,8 @@ const $props = defineProps({
default: true,
},
bottom: {
type: Object,
default: null,
type: Boolean,
default: false,
},
cardClass: {
type: String,
@ -478,29 +478,6 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
/>
</QTd>
</template>
<template #bottom v-if="bottom">
<slot name="bottom-table">
<QBtn
@click="
() =>
createAsDialog
? (showForm = !showForm)
: handleOnDataSaved(create)
"
class="cursor-pointer fill-icon"
color="primary"
icon="add_circle"
size="md"
round
flat
shortcut="+"
:disabled="!disabledAttr"
/>
<QTooltip>
{{ createForm.title }}
</QTooltip>
</slot>
</template>
<template #item="{ row, colsMap }">
<component
:is="$props.redirect ? 'router-link' : 'span'"
@ -625,6 +602,27 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
</QTr>
</template>
</QTable>
<div class="full-width bottomButton" v-if="bottom">
<QBtn
@click="
() =>
createAsDialog
? (showForm = !showForm)
: handleOnDataSaved(create)
"
class="cursor-pointer fill-icon"
color="primary"
icon="add_circle"
size="md"
round
flat
shortcut="+"
:disabled="!disabledAttr"
/>
<QTooltip>
{{ createForm.title }}
</QTooltip>
</div>
</template>
</CrudModel>
<QPageSticky v-if="$props.create" :offset="[20, 20]" style="z-index: 2">

View File

@ -0,0 +1,56 @@
import { createWrapper, axios } from 'app/test/vitest/helper';
import EditForm from 'components/EditTableCellValueForm.vue';
import { vi, afterEach, beforeAll, describe, expect, it } from 'vitest';
const fieldA = 'fieldA';
const fieldB = 'fieldB';
describe('EditForm', () => {
let vm;
const mockRows = [
{ id: 1, itemFk: 101 },
{ id: 2, itemFk: 102 },
];
const mockFieldsOptions = [
{ label: 'Field A', field: fieldA, component: 'input', attrs: {} },
{ label: 'Field B', field: fieldB, component: 'date', attrs: {} },
];
const editUrl = '/api/edit';
beforeAll(() => {
vi.spyOn(axios, 'post').mockResolvedValue({ status: 200 });
vm = createWrapper(EditForm, {
props: {
rows: mockRows,
fieldsOptions: mockFieldsOptions,
editUrl,
},
}).vm;
});
afterEach(() => {
vi.clearAllMocks();
});
describe('onSubmit()', () => {
it('should call axios.post with the correct parameters in the payload', async () => {
const selectedField = { field: fieldA, component: 'input', attrs: {} };
const newValue = 'Test Value';
vm.selectedField = selectedField;
vm.newValue = newValue;
await vm.onSubmit();
const payload = axios.post.mock.calls[0][1];
expect(axios.post).toHaveBeenCalledWith(editUrl, expect.any(Object));
expect(payload.field).toEqual(fieldA);
expect(payload.newValue).toEqual(newValue);
expect(payload.lines).toEqual(expect.arrayContaining(mockRows));
expect(vm.isLoading).toEqual(false);
});
});
});

View File

@ -11,9 +11,9 @@ function getBadgeAttrs(date) {
let timeDiff = today - timeTicket;
if (timeDiff == 0) return { color: 'warning', 'text-color': 'black' };
if (timeDiff < 0) return { color: 'success', 'text-color': 'black' };
return { color: 'transparent', 'text-color': 'white' };
if (timeDiff == 0) return { color: 'warning', class: 'black-text-color' };
if (timeDiff < 0) return { color: 'success', class: 'black-text-color' };
return { color: 'transparent', class: 'normal-text-color' };
}
function formatShippedDate(date) {
@ -29,3 +29,11 @@ function formatShippedDate(date) {
{{ formatShippedDate(date) }}
</QBadge>
</template>
<style lang="scss">
.black-text-color {
color: var(--vn-black-text-color);
}
.normal-text-color {
color: var(--vn-text-color);
}
</style>

View File

@ -166,7 +166,11 @@ onMounted(() => {
const arrayDataKey =
$props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label);
const arrayData = useArrayData(arrayDataKey, { url: $props.url, searchUrl: false });
const arrayData = useArrayData(arrayDataKey, {
url: $props.url,
searchUrl: false,
mapKey: $attrs['map-key'],
});
function findKeyInOptions() {
if (!$props.options) return;

View File

@ -202,7 +202,11 @@ const getLocale = (label) => {
style="position: fixed; z-index: 1; right: 0; bottom: 0"
icon="search"
@click="search()"
></QBtn>
>
<QTooltip bottom anchor="bottom right">
{{ t('globals.search') }}
</QTooltip>
</QBtn>
<QForm @submit="search" id="filterPanelForm" @keyup.enter="search()">
<QList dense>
<QItem class="q-mt-xs">

View File

@ -54,6 +54,7 @@ function formatNumber(number) {
:offset="100"
:limit="5"
auto-load
map-key="smsFk"
>
<template #body="{ rows }">
<QCard

View File

@ -3,20 +3,21 @@
@import '@quasar/quasar-ui-qcalendar/src/QCalendarMonth.sass';
body.body--light {
--font-color: black;
--vn-header-color: #cecece;
--vn-page-color: #ffffff;
--vn-section-color: #e0e0e0;
--vn-section-hover-color: #b9b9b9;
--vn-text-color: var(--font-color);
--vn-text-color: black;
--vn-label-color: #5f5f5f;
--vn-accent-color: #e7e3e3;
--vn-empty-tag: #acacac;
--vn-black-text-color: black;
--vn-text-color-contrast: white;
background-color: var(--vn-page-color);
.q-header .q-toolbar {
color: var(--font-color);
color: var(--vn-text-color);
}
}
body.body--dark {
@ -28,6 +29,8 @@ body.body--dark {
--vn-label-color: #a8a8a8;
--vn-accent-color: #424242;
--vn-empty-tag: #2d2d2d;
--vn-black-text-color: black;
--vn-text-color-contrast: black;
background-color: var(--vn-page-color);
}
@ -86,6 +89,10 @@ select:-webkit-autofill {
background-color: var(--vn-section-hover-color);
}
.bg-vn-page {
background-color: var(--vn-page-color);
}
.color-vn-label {
color: var(--vn-label-color);
}
@ -151,7 +158,8 @@ select:-webkit-autofill {
.q-card,
.q-table,
.q-table__bottom,
.q-drawer {
.q-drawer,
.bottomButton {
background-color: var(--vn-section-color);
}
@ -188,7 +196,7 @@ select:-webkit-autofill {
.q-tooltip {
background-color: var(--vn-page-color);
color: var(--font-color);
color: var(--vn-text-color);
font-size: medium;
}

View File

@ -611,7 +611,7 @@ worker:
fi: DNI/NIE/NIF
birth: Birth
isFreelance: Freelance
isSsDiscounted: Bonificación SS
isSsDiscounted: SS Bonification
hasMachineryAuthorized: Machinery authorized
isDisable: Disable
notificationsManager:
@ -857,11 +857,11 @@ components:
value: Value
# ItemFixedPriceFilter
buyerFk: Buyer
warehouseFk: Warehouse
started: From
ended: To
mine: For me
hasMinPrice: Minimum price
warehouseFk: Warehouse
# LatestBuysFilter
salesPersonFk: Buyer
from: From

View File

@ -608,6 +608,15 @@ worker:
role: Rol
sipExtension: Extensión
locker: Taquilla
fiDueDate: F. caducidad DNI
sex: Sexo
seniority: Antigüedad
fi: DNI/NIE/NIF
birth: F. nacimiento
isFreelance: Autónomo
isSsDiscounted: Bonificación SS
hasMachineryAuthorized: Autorizado para maquinaria
isDisable: Deshabilitado
notificationsManager:
activeNotifications: Notificaciones activas
availableNotifications: Notificaciones disponibles
@ -849,6 +858,7 @@ components:
value: Valor
# ItemFixedPriceFilter
buyerFk: Comprador
warehouseFk: Almacen
started: Desde
ended: Hasta
mine: Para mi

View File

@ -50,7 +50,7 @@ const removeRole = async () => {
>
<template #menu>
<QItem v-ripple clickable @click="removeRole()">
<QItemSection>{{ t('Delete') }}</QItemSection>
<QItemSection>{{ t('globals.delete') }}</QItemSection>
</QItem>
</template>
<template #body="{ entity }">

View File

@ -84,6 +84,7 @@ const columns = computed(() => [
label: t('Creation date'),
format: ({ created }) => toDateHourMin(created),
cardVisible: true,
style: 'color: var(--vn-label-color)',
},
{
align: 'left',

View File

@ -2,7 +2,7 @@
import { ref, computed, onBeforeMount } from 'vue';
import axios from 'axios';
import { useI18n } from 'vue-i18n';
import { toDate } from 'src/filters/index';
import { dateRange, toDate } from 'src/filters/index';
import { useRoute } from 'vue-router';
import VnTable from 'components/VnTable/VnTable.vue';
@ -104,18 +104,12 @@ function getParams() {
};
}
const userParams = computed(() => {
const minDate = Date.vnNew();
minDate.setHours(0, 0, 0, 0);
minDate.setMonth(minDate.getMonth() - 2);
const maxDate = Date.vnNew();
maxDate.setHours(23, 59, 59, 59);
return {
campaign: campaignList.value[0]?.id,
from: minDate,
to: maxDate,
const campaign = campaignList.value[0]?.id;
const userParams = {
campaign,
...updateDateParams(campaign, { from: Date.vnNew(), to: Date.vnNew() }),
};
return userParams;
});
const openReportPdf = () => {
openReport(`Clients/${route.params.id}/campaign-metrics-pdf`, getParams());
@ -134,6 +128,23 @@ const sendCampaignMetricsEmail = ({ address }) => {
...getParams(),
});
};
const updateDateParams = (value, params) => {
if (!value) {
params.from = null;
params.to = null;
return;
}
const campaign = campaignList.value.find((c) => c.id === value);
if (!campaign) return;
const { dated, previousDays, scopeDays } = campaign;
const _date = new Date(dated);
const [from, to] = dateRange(_date);
params.from = new Date(from.setDate(from.getDate() - previousDays)).toISOString();
params.to = new Date(to.setDate(to.getDate() + scopeDays)).toISOString();
return params;
};
</script>
<template>
@ -144,7 +155,6 @@ const sendCampaignMetricsEmail = ({ address }) => {
:order="['itemTypeFk', 'itemName', 'itemSize', 'description']"
:columns="columns"
search-url="consumption"
:filter="filter"
:user-params="userParams"
:default-remove="false"
:default-reset="false"
@ -201,6 +211,7 @@ const sendCampaignMetricsEmail = ({ address }) => {
class="q-px-sm q-pt-none fit"
dense
option-label="code"
@update:model-value="(data) => updateDateParams(data, params)"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">

View File

@ -173,6 +173,8 @@ en:
phone: Phone
email: Email
zoneFk: Zone
socialName : Social name
name: Name
postcode: Postcode
es:
params:
@ -184,6 +186,8 @@ es:
phone: Teléfono
email: Email
zoneFk: Zona
socialName : Razón social
name: Nombre
postcode: CP
FI: NIF
Salesperson: Comercial

View File

@ -240,6 +240,7 @@ es:
defaulterSinced: Desde
Client: Cliente
Salesperson: Comercial
Departments: Departamentos
Country: País
P. Method: F. Pago
Balance D.: Saldo V.

View File

@ -74,8 +74,8 @@ const showEntryReport = () => {
</template>
<template #body="{ entity }">
<VnLv :label="t('globals.agency')" :value="entity.travel?.agency?.name" />
<VnLv :label="t('shipped')" :value="toDate(entity.travel?.shipped)" />
<VnLv :label="t('landed')" :value="toDate(entity.travel?.landed)" />
<VnLv :label="t('globals.shipped')" :value="toDate(entity.travel?.shipped)" />
<VnLv :label="t('globals.landed')" :value="toDate(entity.travel?.landed)" />
<VnLv
:label="t('globals.warehouseOut')"
:value="entity.travel?.warehouseOut?.name"

View File

@ -212,7 +212,7 @@ const fetchEntryBuys = async () => {
:label="t('entry.summary.travelAgency')"
:value="entry.travel.agency?.name"
/>
<VnLv :label="t('shipped')" :value="toDate(entry.travel.shipped)" />
<VnLv :label="t('globals.shipped')" :value="toDate(entry.travel.shipped)" />
<VnLv
:label="t('globals.warehouseOut')"
:value="entry.travel.warehouseOut?.name"
@ -222,7 +222,7 @@ const fetchEntryBuys = async () => {
v-model="entry.travel.isDelivered"
:disable="true"
/>
<VnLv :label="t('landed')" :value="toDate(entry.travel.landed)" />
<VnLv :label="t('globals.landed')" :value="toDate(entry.travel.landed)" />
<VnLv
:label="t('globals.warehouseIn')"
:value="entry.travel.warehouseIn?.name"

View File

@ -58,7 +58,7 @@ const tagValues = ref([]);
<QItem class="q-my-md">
<QItemSection>
<VnSelect
:label="t('components.itemsFilterPanel.supplierFk')"
:label="t('globals.params.supplierFk')"
v-model="params.supplierFk"
:options="suppliersOptions"
option-value="id"
@ -85,7 +85,7 @@ const tagValues = ref([]);
<QItem class="q-my-md">
<QItemSection>
<VnInputDate
:label="t('components.itemsFilterPanel.from')"
:label="t('components.itemsFilterPanel.started')"
v-model="params.from"
is-outlined
@update:model-value="searchFn()"
@ -95,7 +95,7 @@ const tagValues = ref([]);
<QItem class="q-my-md">
<QItemSection>
<VnInputDate
:label="t('components.itemsFilterPanel.to')"
:label="t('components.itemsFilterPanel.ended')"
v-model="params.to"
is-outlined
@update:model-value="searchFn()"
@ -113,7 +113,7 @@ const tagValues = ref([]);
</QItemSection>
<QItemSection>
<QCheckbox
:label="t('components.itemsFilterPanel.visible')"
:label="t('globals.visible')"
v-model="params.visible"
toggle-indeterminate
@update:model-value="searchFn()"

View File

@ -65,6 +65,6 @@ onMounted(async () => {
es:
Date: Fecha
params:
dated: Date
dated: Fecha
workerFk: Trabajador
</i18n>

View File

@ -161,7 +161,7 @@ const columns = computed(() => [
<QList>
<QItem>
<VnSelect
:label="t('code')"
:label="t('Code')"
class="full-width"
v-model="props.row['intrastatFk']"
:options="intrastats"

View File

@ -346,7 +346,7 @@ watchEffect(selectedRows);
<VnSelect
url="InvoiceOutSerials"
v-model="data.serial"
:label="t('invoiceIn.serial')"
:label="t('InvoiceIn.serial')"
:options="invoiceOutSerialsOptions"
option-label="description"
option-value="code"

View File

@ -203,6 +203,12 @@ const onIntrastatCreated = (response, formData) => {
v-model="data.hasKgPrice"
:label="t('item.basicData.hasKgPrice')"
/>
<QCheckbox
v-model="data.isCustomInspectionRequired"
:label="t('item.basicData.isCustomInspectionRequired')"
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<div>
<QCheckbox
v-model="data.isFragile"

View File

@ -10,21 +10,12 @@ import { dashIfEmpty } from 'src/filters';
import { toCurrency } from 'filters/index';
import { useArrayData } from 'composables/useArrayData';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import axios from 'axios';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
const { t } = useI18n();
const route = useRoute();
const from = ref();
const to = ref();
const hideInventory = ref(true);
const inventorySupplierFk = ref();
async function getInventorySupplier() {
inventorySupplierFk.value = (
await axios.get(`InventoryConfigs`)
)?.data[0]?.supplierFk;
}
const exprBuilder = (param, value) => {
switch (param) {
@ -49,10 +40,6 @@ const where = {
itemFk: route.params.id,
};
if (hideInventory.value) {
where.supplierFk = { neq: inventorySupplierFk };
}
const arrayData = useArrayData('ItemLastEntries', {
url: 'Items/lastEntriesFilter',
order: ['landed DESC', 'buyFk DESC'],
@ -110,7 +97,7 @@ const columns = computed(() => [
format: (val) => dashIfEmpty(val),
},
{
label: t('shelvings.packing'),
label: 'Packing',
name: 'packing',
field: 'packing',
align: 'center',
@ -182,15 +169,11 @@ const updateFilter = async () => {
const userFilter = arrayData.store.userFilter.where;
userFilter.landed = filter;
if (hideInventory.value) userFilter.supplierFk = { neq: inventorySupplierFk };
else delete userFilter.supplierFk;
await fetchItemLastEntries();
};
onMounted(async () => {
await getInventorySupplier();
const _from = Date.vnNew();
_from.setDate(_from.getDate() - 75);
from.value = getDate(_from, 'from');
@ -200,12 +183,16 @@ onMounted(async () => {
updateFilter();
watch([from, to, hideInventory], ([nFrom, nTo], [oFrom, oTo]) => {
watch([from, to], ([nFrom, nTo], [oFrom, oTo]) => {
if (nFrom && nFrom != oFrom) nFrom = getDate(new Date(nFrom), 'from');
if (nTo && nTo != oTo) nTo = getDate(new Date(nTo), 'to');
updateFilter();
});
});
function getBadgeClass(groupingMode, expectedGrouping) {
return groupingMode === expectedGrouping ? 'accent-badge' : 'simple-badge';
}
</script>
<template>
<VnSubToolbar>
@ -224,13 +211,6 @@ onMounted(async () => {
class="q-mr-lg"
data-cy="to"
/>
<QCheckbox
:label="t('Hide inventory supplier')"
v-model="hideInventory"
dense
class="q-mr-lg"
data-cy="hideInventory"
/>
</template>
</VnSubToolbar>
<QPage class="column items-center q-pa-xd">
@ -249,6 +229,11 @@ onMounted(async () => {
/>
</QTd>
</template>
<template #body-cell-warehouse="{ row }">
<QTd>
<span>{{ row.warehouse }}</span>
</QTd>
</template>
<template #body-cell-date="{ row }">
<QTd class="text-center">
<VnDateBadge :date="row.landed" />
@ -262,32 +247,37 @@ onMounted(async () => {
</div>
</QTd>
</template>
<template #body-cell-pvp="{ value }">
<QTd @click.stop class="text-center">
<span> {{ value }}</span>
<QTooltip> {{ t('lastEntries.grouping') }}/Packing </QTooltip></QTd
>
</template>
<template #body-cell-printedStickers="{ row }">
<QTd @click.stop class="text-center">
<span style="color: var(--vn-label-color)">
{{ row.printedStickers }}</span
>
</QTd>
</template>
<template #body-cell-packing="{ row }">
<QTd @click.stop>
<QBadge
class="center-content"
:class="getBadgeClass(row.groupingMode, 'packing')"
rounded
:color="row.groupingMode == 'packing' ? 'grey-13' : 'black'"
>
{{ dashIfEmpty(row.packing) }}
<QTooltip>{{ t('lastEntries.packing') }}</QTooltip>
<QTooltip>Packing</QTooltip>
</QBadge>
</QTd>
</template>
<template #body-cell-pvp="{ value }">
<QTd @click.stop class="text-center">
<span> {{ value }}</span>
<QTooltip>
{{ t('lastEntries.grouping') }}/{{ t('lastEntries.packing') }}
</QTooltip></QTd
>
</template>
<template #body-cell-grouping="{ row }">
<QTd @click.stop>
<QBadge
class="center-content"
:class="getBadgeClass(row.groupingMode, 'grouping')"
rounded
:color="row.groupingMode == 'grouping' ? 'grey-13' : 'black'"
>
{{ dashIfEmpty(row.grouping) }}
<QTooltip>{{ t('lastEntries.grouping') }}</QTooltip>
@ -315,13 +305,16 @@ onMounted(async () => {
</template>
<template #body-cell-supplier="{ row }">
<QTd @click.stop>
<div class="full-width flex justify-center">
<SupplierDescriptorProxy
:id="row.supplierFk"
class="q-ma-none"
<div class="full-width flex justify-left">
<QBadge
:class="
row.isInventorySupplier ? 'bg-vn-page' : 'transparent'
"
dense
/>
<span class="link">{{ row.supplier }}</span>
>
<SupplierDescriptorProxy :id="row.supplierFk" />
<span class="link">{{ row.supplier }}</span>
</QBadge>
</div>
</QTd>
</template>
@ -349,4 +342,13 @@ onMounted(async () => {
background-color: red;
}
}
.accent-badge {
background-color: var(--vn-label-color);
color: var(--vn-text-color-contrast);
}
.simple-badge {
background-color: transparent;
color: var(--vn-text-color);
font-size: 14px;
}
</style>

View File

@ -128,7 +128,7 @@ const submitTags = async (data) => {
<VnSelect
v-if="row.tag?.isFree === false"
:key="row.tagFk"
:label="t('Value')"
:label="t('itemTags.value')"
v-model="row.value"
:url="`Tags/${row.tagFk}/filterValue`"
option-label="value"

View File

@ -376,6 +376,8 @@ const columns = computed(() => [
<i18n>
es:
New item: Nuevo artículo
Create Item: Crear artículo
You can search by id: Puedes buscar por id
Preview: Vista previa
Regularize stock: Regularizar stock
</i18n>

View File

@ -201,6 +201,7 @@ en:
to: To
mine: For me
state: State
daysOnward: Days onward
myTeam: My team
dateFiltersTooltip: Cannot choose a range of dates and days onward at the same time
denied: Denied
@ -218,6 +219,7 @@ es:
to: Hasta
mine: Para mi
state: Estado
daysOnward: Días en adelante
myTeam: Mi equipo
dateFiltersTooltip: No se puede seleccionar un rango de fechas y días en adelante a la vez
denied: Denegada

View File

@ -158,6 +158,7 @@ item:
isFragileTooltip: Is shown at website, app that this item cannot travel (wreath, palms, ...)
isPhotoRequested: Do photo
isPhotoRequestedTooltip: This item does need a photo
isCustomInspectionRequired: Needs physical inspection (PIF)
description: Description
fixedPrice:
itemFk: Item ID

View File

@ -160,6 +160,7 @@ item:
isFragileTooltip: Se muestra en la web, app que este artículo no puede viajar (coronas, palmas, ...)
isPhotoRequested: Hacer foto
isPhotoRequestedTooltip: Este artículo necesita una foto
isCustomInspectionRequired: Necesita inspección física (PIF)
description: Descripción
fixedPrice:
itemFk: ID Artículo

View File

@ -1,6 +1,6 @@
<script setup>
import toCurrency from 'src/filters/toCurrency';
import { computed, inject, ref } from 'vue';
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import { useRoute } from 'vue-router';

View File

@ -128,6 +128,7 @@ en:
from: From
to: To
orderFk: Order
workerFk: Worker
sourceApp: Application
myTeam: My Team
isConfirmed: Is Confirmed
@ -151,6 +152,7 @@ es:
from: Desde
to: Hasta
orderFk: Cesta
workerFk: Trabajador
sourceApp: Aplicación
myTeam: Mi Equipo
isConfirmed: Confirmado

View File

@ -225,8 +225,8 @@ es:
params:
agencyModeFk: Agencia ruta
m3:
from: Desde
to: Hasta
From: Desde
To: Hasta
date: Fecha
agencyFk: Agencia Acuerdo
packages: Bultos

View File

@ -161,6 +161,7 @@ en:
warehouseFk: Warehouse
description: Description
m3:
scopeDays: Days Onward
vehicleFk: Vehicle
agencyModeFk: Agency
workerFk: Worker
@ -172,6 +173,7 @@ es:
warehouseFk: Almacén
description: Descripción
m3:
scopeDays: Días en adelante
vehicleFk: Vehículo
agencyModeFk: Agencia
workerFk: Trabajador

View File

@ -271,6 +271,8 @@ es:
Date: Fecha
Agency route: Agencia Ruta
Agency agreement: Agencia Acuerdo
From: Desde
To: Hasta
Packages: Bultos
Price: Precio
Received: Recibida

View File

@ -134,6 +134,7 @@ defineProps({
<i18n>
en:
params:
supplierFk: Supplier
search: General search
itemId: Item id
buyerId: Buyer
@ -143,6 +144,7 @@ en:
to: To
es:
params:
supplierFk: Proveedor
search: Búsqueda general
itemId: Id Artículo
buyerId: Comprador

View File

@ -149,7 +149,7 @@ const getUrl = (section) => `#/supplier/${entityId.value}/${section}`;
<VnLv :label="t('supplier.summary.taxNumber')" :value="supplier.nif" />
<VnLv :label="t('globals.street')" :value="supplier.street" />
<VnLv :label="t('supplier.summary.city')" :value="supplier.city" />
<VnLv :label="t('globals.postCode')" :value="supplier.postCode" />
<VnLv :label="t('globals.postcode')" :value="supplier.postCode" />
<VnLv
:label="t('supplier.summary.province')"
:value="supplier.province?.name"

View File

@ -1,5 +1,5 @@
<script setup>
import { ref, computed, onMounted, watch } from 'vue';
import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';

View File

@ -59,7 +59,7 @@ const columns = computed(() => [
},
{
label: t('basicData.item'),
name: 'packagingItemFk',
name: 'longName',
align: 'left',
cardVisible: true,
columnFilter: {
@ -321,12 +321,18 @@ onMounted(async () => {
"
order="created DESC"
>
<template #column-packagingItemFk="{ row }">
<template #column-freightItemName="{ row }">
<span class="link" @click.stop>
{{ row.packagingItemFk }}
{{ row.freightItemName }}
<ItemDescriptorProxy :id="row.packagingItemFk" />
</span>
</template>
<template #column-longName="{ row }">
<span class="link" @click.stop>
{{ row.longName }}
<ItemDescriptorProxy :id="row.itemFk" />
</span>
</template>
</VnTable>
<QDialog ref="newTicketDialogRef" transition-show="scale" transition-hide="scale">
<ExpeditionNewTicket

View File

@ -275,4 +275,5 @@ onMounted(() => (stateStore.rightDrawer = false));
New: Nueva
Denied: Denegada
Accepted: Aceptada
Create request: Crear petición de compra
</i18n>

View File

@ -54,6 +54,7 @@ const transfer = ref({
});
const tableRef = ref([]);
const canProceed = ref();
const isLoading = ref(false);
watch(
() => route.params.id,
@ -213,6 +214,9 @@ const updateQuantity = async ({ quantity, id }) => {
};
const addSale = async (sale) => {
if (isLoading.value) return;
isLoading.value = true;
const params = {
barcode: sale.itemFk,
quantity: sale.quantity,
@ -233,7 +237,7 @@ const addSale = async (sale) => {
sale.item = newSale.item;
notify('globals.dataSaved', 'positive');
window.location.reload();
arrayData.fetch({});
};
const updateConcept = async (sale) => {
@ -464,6 +468,7 @@ const addRow = (original = null) => {
};
const endNewRow = (row) => {
if (!row) return;
if (row.itemFk && row.quantity) {
row.isNew = false;
}

View File

@ -298,14 +298,19 @@ en:
to: To
salesPersonFk: Salesperson
stateFk: State
groupedStates: Grouped State
refFk: Invoice Ref.
scopeDays: Days onward
nickname: Nickname
myTeam: My team
pending: Pending
hasInvoice: Invoiced
hasRoute: Routed
problems: With problems
provinceFk: Province
agencyModeFk: Agency
warehouseFk: Warehouse
collectionFk: Collection
FREE: Free
ON_PREPARATION: On preparation
PACKED: Packed
@ -320,11 +325,19 @@ es:
to: Hasta
salesPersonFk: Comercial
stateFk: Estado
groupedStates: Estado agrupado
refFk: Ref. Factura
scopeDays: Días en adelante
nickname: Nombre mostrado
myTeam: Mi equipo
pending: Pendiente
hasInvoice: Facturado
hasRoute: Enrutado
problems: Con problemas
provinceFk: Provincia
agencyModeFk: Agencia
warehouseFk: Almacén
collectionFk: Colección
Customer ID: ID Cliente
Order ID: ID Pedido
From: Desde

View File

@ -11,9 +11,8 @@ import VnInput from 'src/components/common/VnInput.vue';
import EntryDescriptorProxy from '../Entry/Card/EntryDescriptorProxy.vue';
import { useStateStore } from 'stores/useStateStore';
import { toCurrency } from 'src/filters';
import { useArrayData } from 'composables/useArrayData';
import { toDate } from 'src/filters';
import { toDate, toCurrency } from 'src/filters';
import { usePrintService } from 'composables/usePrintService';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import axios from 'axios';
@ -128,6 +127,10 @@ const tableColumnComponents = {
component: 'span',
attrs: {},
},
isCustomInspectionRequired: {
component: 'span',
attrs: {},
},
};
const columns = computed(() => [
@ -589,7 +592,16 @@ const getColor = (percentage) => {
<QBtn flat class="link" dense>{{ entry.supplierName }}</QBtn>
<SupplierDescriptorProxy :id="entry.supplierFk" />
</QTd>
<QTd />
<QTd>
<QIcon
v-if="entry.isCustomInspectionRequired"
name="warning"
color="negative"
size="xs"
:title="t('requiresInspection')"
>
</QIcon>
</QTd>
<QTd>
<span>{{ toCurrency(entry.invoiceAmount) }}</span>
</QTd>
@ -704,12 +716,17 @@ en:
physicKg: Phy. KG
shipped: W. shipped
landed: W. landed
requiresInspection: Requires inspection
BIP: Boder Inspection Point
notes: Notes
es:
searchExtraCommunity: Buscar por envío extra comunitario
kg: KG Bloq.
physicKg: KG físico
shipped: F. envío
landed: F. llegada
notes: Notas
Open as PDF: Abrir como PDF
requiresInspection: Requiere inspección
BIP: Punto de Inspección Fronteriza
</i18n>

View File

@ -286,6 +286,7 @@ es:
Search travel: Buscar envio
Clone: Clonar
Add entry: Añadir Entrada
Create Travels: Crear envíos
</i18n>
<style lang="scss" scoped>
.is-active {

View File

@ -168,3 +168,8 @@ async function remove(row) {
</VnTable>
</QPage>
</template>
<i18n>
es:
Create new wagon: Crear nuevo vagón
</i18n>

View File

@ -59,7 +59,7 @@ const arrayData = useArrayData('ZoneEvents');
const exclusionGeoCreate = async () => {
const params = {
zoneFk: parseInt(route.params.id),
date: dated.value,
date: dated,
geoIds: tickedNodes.value,
};
await axios.post('Zones/exclusionGeo', params);

View File

@ -89,7 +89,7 @@ watch(
v-model="formData.geoFk"
url="Postcodes/location"
:fields="['geoFk', 'code', 'townFk', 'countryFk']"
sort-by="code, townFk"
:sort-by="['code ASC']"
option-value="geoFk"
option-label="code"
:filter-options="['code']"
@ -97,6 +97,7 @@ watch(
dense
outlined
rounded
map-key="geoFk"
>
<template #option="{ itemProps, opt }">
<QItem v-bind="itemProps">

View File

@ -41,6 +41,7 @@ summary:
basicData: Basic data
closeHour: Close hour
filterPanel:
name: Name
agencyModeFk: Agency
deliveryPanel:
pickup: Pick up

View File

@ -41,6 +41,7 @@ summary:
basicData: Datos básicos
closeHour: Hora de cierre
filterPanel:
name: Nombre
agencyModeFk: Agencia
deliveryPanel:
pickup: Recogida

View File

@ -1,20 +0,0 @@
describe('ItemLastEntries', () => {
beforeEach(() => {
cy.viewport(1280, 720);
cy.login('buyer');
cy.visit('/#/item/1/last-entries');
cy.intercept('GET', /.*lastEntriesFilter/).as('item');
cy.waitForElement('tbody');
});
it('should filter by agency', () => {
cy.get('tbody > tr')
.its('length')
.then((rowCount) => {
cy.get('[data-cy="hideInventory"]').click();
cy.wait('@item');
cy.waitForElement('tbody');
cy.get('tbody > tr').should('have.length.greaterThan', rowCount);
});
});
});