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

This commit is contained in:
Jose Antonio Tubau 2025-01-24 14:47:15 +00:00
commit 023a3b541a
73 changed files with 1526 additions and 1680 deletions

4
.gitignore vendored
View File

@ -29,5 +29,5 @@ yarn-error.log*
*.sln
# Cypress directories and files
/tests/cypress/videos
/tests/cypress/screenshots
/test/cypress/videos
/test/cypress/screenshots

View File

@ -1,6 +1,6 @@
<script setup>
import axios from 'axios';
import { computed, ref, watch } from 'vue';
import { computed, ref, useAttrs, watch } from 'vue';
import { useRouter, onBeforeRouteLeave } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
@ -17,6 +17,7 @@ const quasar = useQuasar();
const stateStore = useStateStore();
const { t } = useI18n();
const { validate } = useValidator();
const $attrs = useAttrs();
const $props = defineProps({
model: {
@ -113,9 +114,11 @@ onBeforeRouteLeave((to, from, next) => {
});
async function fetch(data) {
resetData(data);
emit('onFetch', data);
return data;
const keyData = $attrs['key-data'];
const rows = keyData ? data[keyData] : data;
resetData(rows);
emit('onFetch', rows);
return rows;
}
function resetData(data) {

View File

@ -12,6 +12,7 @@ const props = defineProps({
baseUrl: { type: String, default: undefined },
customUrl: { type: String, default: undefined },
filter: { type: Object, default: () => {} },
userFilter: { type: Object, default: () => {} },
descriptor: { type: Object, required: true },
filterPanel: { type: Object, default: undefined },
searchDataKey: { type: String, default: undefined },
@ -32,6 +33,7 @@ const url = computed(() => {
const arrayData = useArrayData(props.dataKey, {
url: url.value,
filter: props.filter,
userFilter: props.userFilter,
});
onBeforeMount(async () => {

View File

@ -41,7 +41,7 @@ const card = toRef(props, 'item');
</div>
</div>
<div class="content">
<span class="link">
<span class="link" @click.stop>
{{ card.name }}
<ItemDescriptorProxy :id="card.id" />
</span>

View File

@ -190,7 +190,10 @@ const getLocale = (label) => {
const globalLocale = `globals.params.${param}`;
if (te(globalLocale)) return t(globalLocale);
else if (te(t(`params.${param}`)));
else return t(`${route.meta.moduleName.toLowerCase()}.params.${param}`);
else {
const camelCaseModuleName = route.meta.moduleName.charAt(0).toLowerCase() + route.meta.moduleName.slice(1);
return t(`${camelCaseModuleName}.params.${param}`);
}
};
</script>

View File

@ -78,6 +78,10 @@ const props = defineProps({
type: String,
default: '',
},
keyData: {
type: String,
default: undefined,
},
});
const emit = defineEmits(['onFetch', 'onPaginate', 'onChange']);
@ -255,7 +259,7 @@ defineExpose({
:disable="disableInfiniteScroll || !store.hasMoreData"
v-bind="$attrs"
>
<slot name="body" :rows="store.data"></slot>
<slot name="body" :rows="keyData ? store.data[keyData] : store.data"></slot>
<div v-if="isLoading" class="spinner info-row q-pa-md text-center">
<QSpinner color="primary" size="md" />
</div>

View File

@ -170,10 +170,9 @@ export function useArrayData(key, userOptions) {
async function addOrder(field, direction = 'ASC') {
const newOrder = field + ' ' + direction;
let order = store.order || [];
if (typeof order == 'string') order = [order];
const order = toArray(store.order);
let index = order.findIndex((o) => o.split(' ')[0] === field);
let index = getOrderIndex(order, field);
if (index > -1) {
order[index] = newOrder;
} else {
@ -190,16 +189,24 @@ export function useArrayData(key, userOptions) {
}
async function deleteOrder(field) {
let order = store.order ?? [];
if (typeof order == 'string') order = [order];
const index = order.findIndex((o) => o.split(' ')[0] === field);
const order = toArray(store.order);
const index = getOrderIndex(order, field);
if (index > -1) order.splice(index, 1);
store.order = order;
fetch({});
}
function getOrderIndex(order, field) {
return order.findIndex((o) => o.split(' ')[0] === field);
}
function toArray(str = []) {
if (!str) return [];
if (Array.isArray(str)) return str;
if (typeof str === 'string') return str.split(',').map((item) => item.trim());
}
function sanitizerParams(params, exprBuilder) {
for (const param in params) {
if (params[param] === '' || params[param] === null) {
@ -290,8 +297,7 @@ export function useArrayData(key, userOptions) {
Object.assign(params, store.userParams);
if (params.filter) params.filter.skip = store.skip;
if (store?.order && typeof store?.order == 'string') store.order = [store.order];
if (store.order?.length) params.filter.order = [...store.order];
if (store.order) params.filter.order = toArray(store.order);
else delete params.filter.order;
return { filter, params, limit: filter.limit };

View File

@ -312,11 +312,11 @@ input::-webkit-inner-spin-button {
}
.q-item > .q-item__section:has(.q-checkbox) {
max-width: min-content;
max-width: fit-content;
}
.row > .column:has(.q-checkbox) {
max-width: min-content;
max-width: fit-content;
}
.q-field__inner {
.q-field__control {

View File

@ -2,9 +2,10 @@ globals:
lang:
es: Spanish
en: English
quantity: Quantity
language: Language
quantity: Quantity
entity: Entity
preview: Preview
user: User
details: Details
collapseMenu: Collapse lateral menu
@ -36,7 +37,6 @@ globals:
confirm: Confirm
assign: Assign
back: Back
downloadPdf: Download PDF
yes: 'Yes'
no: 'No'
noChanges: No changes to save
@ -60,6 +60,7 @@ globals:
downloadCSVSuccess: CSV downloaded successfully
reference: Reference
agency: Agency
entry: Entry
warehouseOut: Warehouse Out
warehouseIn: Warehouse In
landed: Landed
@ -68,11 +69,11 @@ globals:
amount: Amount
packages: Packages
download: Download
downloadPdf: Download PDF
selectRows: 'Select all { numberRows } row(s)'
allRows: 'All { numberRows } row(s)'
markAll: Mark all
requiredField: Required field
valueCantBeEmpty: Value cannot be empty
class: clase
type: Type
reason: reason
@ -82,6 +83,9 @@ globals:
warehouse: Warehouse
company: Company
fieldRequired: Field required
valueCantBeEmpty: Value cannot be empty
Value can't be blank: Value cannot be blank
Value can't be null: Value cannot be null
allowedFilesText: 'Allowed file types: { allowedContentTypes }'
smsSent: SMS sent
confirmDeletion: Confirm deletion
@ -131,6 +135,26 @@ globals:
medium: Medium
big: Big
email: Email
supplier: Supplier
ticketList: Ticket List
created: Created
worker: Worker
now: Now
name: Name
new: New
comment: Comment
observations: Observations
goToModuleIndex: Go to module index
createInvoiceIn: Create invoice in
myAccount: My account
noOne: No one
maxTemperature: Max
minTemperature: Min
changePass: Change password
deleteConfirmTitle: Delete selected elements
changeState: Change state
raid: 'Raid {daysInForward} days'
isVies: Vies
pageTitles:
logIn: Login
addressEdit: Update address
@ -152,13 +176,14 @@ globals:
subRoles: Subroles
inheritedRoles: Inherited Roles
customers: Customers
customerCreate: New customer
createCustomer: Create customer
createOrder: New order
list: List
webPayments: Web Payments
extendedList: Extended list
notifications: Notifications
defaulter: Defaulter
customerCreate: New customer
createOrder: New order
fiscalData: Fiscal data
billingData: Billing data
consignees: Consignees
@ -194,27 +219,28 @@ globals:
claims: Claims
claimCreate: New claim
lines: Lines
photos: Photos
development: Development
photos: Photos
action: Action
invoiceOuts: Invoice out
negativeBases: Negative Bases
globalInvoicing: Global invoicing
invoiceOutCreate: Create invoice out
order: Orders
orderList: List
orderCreate: New order
catalog: Catalog
volume: Volume
shelving: Shelving
shelvingList: Shelving List
shelvingCreate: New shelving
invoiceIns: Invoices In
invoiceInCreate: Create invoice in
vat: VAT
labeler: Labeler
dueDay: Due day
intrastat: Intrastat
corrective: Corrective
order: Orders
orderList: List
orderCreate: New order
catalog: Catalog
volume: Volume
workers: Workers
workerCreate: New worker
department: Department
@ -227,10 +253,10 @@ globals:
wagonsList: Wagons List
wagonCreate: Create wagon
wagonEdit: Edit wagon
wagonCounter: Trolley counter
typesList: Types List
typeCreate: Create type
typeEdit: Edit type
wagonCounter: Trolley counter
roadmap: Roadmap
stops: Stops
routes: Routes
@ -239,21 +265,16 @@ globals:
routeCreate: New route
RouteRoadmap: Roadmaps
RouteRoadmapCreate: Create roadmap
RouteExtendedList: Router
autonomous: Autonomous
suppliers: Suppliers
supplier: Supplier
expedition: Expedition
services: Service
components: Components
pictures: Pictures
packages: Packages
tracking: Tracking
labeler: Labeler
supplierCreate: New supplier
accounts: Accounts
addresses: Addresses
agencyTerm: Agency agreement
travel: Travels
create: Create
extraCommunity: Extra community
travelCreate: New travel
history: Log
@ -261,14 +282,13 @@ globals:
items: Items
diary: Diary
tags: Tags
create: Create
buyRequest: Buy requests
fixedPrice: Fixed prices
buyRequest: Buy requests
wasteBreakdown: Waste breakdown
itemCreate: New item
barcode: Barcodes
tax: Tax
botanical: Botanical
barcode: Barcodes
itemTypeCreate: New item type
family: Item Type
lastEntries: Last entries
@ -284,13 +304,20 @@ globals:
formation: Formation
locations: Locations
warehouses: Warehouses
saleTracking: Sale tracking
roles: Roles
connections: Connections
acls: ACLs
mailForwarding: Mail forwarding
mailAlias: Mail alias
privileges: Privileges
observation: Notes
expedition: Expedition
saleTracking: Sale tracking
services: Service
tracking: Tracking
components: Components
pictures: Pictures
packages: Packages
ldap: LDAP
samba: Samba
twoFactor: Two factor
@ -301,27 +328,12 @@ globals:
serial: Serial
medical: Mutual
pit: IRPF
RouteExtendedList: Router
wasteRecalc: Waste recaclulate
operator: Operator
parking: Parking
supplier: Supplier
created: Created
worker: Worker
now: Now
name: Name
new: New
comment: Comment
observations: Observations
goToModuleIndex: Go to module index
unsavedPopup:
title: Unsaved changes will be lost
subtitle: Are you sure exit without saving?
createInvoiceIn: Create invoice in
myAccount: My account
noOne: No one
maxTemperature: Max
minTemperature: Min
params:
clientFk: Client id
salesPersonFk: Sales person
@ -339,19 +351,13 @@ globals:
supplierFk: Supplier
supplierRef: Supplier ref
serial: Serial
amount: Importe
amount: Amount
awbCode: AWB
correctedFk: Rectified
correctingFk: Rectificative
daysOnward: Days onward
countryFk: Country
companyFk: Company
changePass: Change password
setPass: Set password
deleteConfirmTitle: Delete selected elements
changeState: Change state
raid: 'Raid {daysInForward} days'
isVies: Vies
errors:
statusUnauthorized: Access denied
statusInternalServerError: An internal server error has ocurred
@ -491,21 +497,6 @@ invoiceOut:
comercial: Comercial
errors:
downloadCsvFailed: CSV download failed
shelving:
list:
parking: Parking
priority: Priority
newShelving: New Shelving
summary:
recyclable: Recyclable
parking:
pickingOrder: Picking order
sector: Sector
row: Row
column: Column
searchBar:
info: You can search by parking code
label: Search parking...
department:
chat: Chat
bossDepartment: Boss Department
@ -697,6 +688,9 @@ supplier:
consumption:
entry: Entry
travel:
search: Search travel
searchInfo: You can search by travel id or name
id: Id
travelList:
tableVisibleColumns:
ref: Reference
@ -727,62 +721,6 @@ travel:
destination: Destination
thermograph: Thermograph
travelFileDescription: 'Travel id { travelId }'
item:
descriptor:
buyer: Buyer
color: Color
category: Category
available: Available
warehouseText: 'Calculated on the warehouse of { warehouseName }'
itemDiary: Item diary
list:
id: Identifier
stems: Stems
category: Category
typeName: Type
isActive: Active
userName: Buyer
weightByPiece: Weight/Piece
stemMultiplier: Multiplier
fixedPrice:
itemFk: Item ID
groupingPrice: Grouping price
packingPrice: Packing price
hasMinPrice: Has min price
minPrice: Min price
started: Started
ended: Ended
create:
priority: Priority
buyRequest:
requester: Requester
requested: Requested
attender: Atender
achieved: Achieved
concept: Concept
summary:
otherData: Other data
tax: Tax
botanical: Botanical
barcode: Barcode
completeName: Complete name
family: Familiy
stems: Stems
multiplier: Multiplier
buyer: Buyer
doPhoto: Do photo
intrastatCode: Intrastat code
ref: Reference
relevance: Relevance
weight: Weight (gram)/stem
units: Units/box
expense: Expense
generic: Generic
recycledPlastic: Recycled plastic
nonRecycledPlastic: Non recycled plastic
minSalesQuantity: Min sales quantity
genus: Genus
specie: Specie
components:
topbar: {}
itemsFilterPanel:

View File

@ -5,6 +5,7 @@ globals:
language: Idioma
quantity: Cantidad
entity: Entidad
preview: Vista previa
user: Usuario
details: Detalles
collapseMenu: Contraer menú lateral
@ -54,11 +55,12 @@ globals:
today: Hoy
yesterday: Ayer
dateFormat: es-ES
noSelectedRows: No tienes ninguna línea seleccionada
microsip: Abrir en MicroSIP
noSelectedRows: No tienes ninguna línea seleccionada
downloadCSVSuccess: Descarga de CSV exitosa
reference: Referencia
agency: Agencia
entry: Entrada
warehouseOut: Alm. salida
warehouseIn: Alm. entrada
landed: F. entrega
@ -133,6 +135,26 @@ globals:
medium: Mediano/a
big: Grande
email: Correo
supplier: Proveedor
ticketList: Listado de tickets
created: Fecha creación
worker: Trabajador
now: Ahora
name: Nombre
new: Nuevo
comment: Comentario
observations: Observaciones
goToModuleIndex: Ir al índice del módulo
createInvoiceIn: Crear factura recibida
myAccount: Mi cuenta
noOne: Nadie
maxTemperature: Máx
minTemperature: Mín
changePass: Cambiar contraseña
deleteConfirmTitle: Eliminar los elementos seleccionados
changeState: Cambiar estado
raid: 'Redada {daysInForward} días'
isVies: Vies
pageTitles:
logIn: Inicio de sesión
addressEdit: Modificar consignatario
@ -155,17 +177,17 @@ globals:
inheritedRoles: Roles heredados
customers: Clientes
customerCreate: Nuevo cliente
createCustomer: Crear cliente
createOrder: Nuevo pedido
list: Listado
webPayments: Pagos Web
extendedList: Listado extendido
notifications: Notificaciones
defaulter: Morosos
createCustomer: Crear cliente
fiscalData: Datos fiscales
billingData: Forma de pago
consignees: Consignatarios
'address-create': Nuevo consignatario
address-create: Nuevo consignatario
notes: Notas
credits: Créditos
greuges: Greuges
@ -231,10 +253,10 @@ globals:
wagonsList: Listado vagones
wagonCreate: Crear tipo
wagonEdit: Editar tipo
wagonCounter: Contador de carros
typesList: Listado tipos
typeCreate: Crear tipo
typeEdit: Editar tipo
wagonCounter: Contador de carros
roadmap: Troncales
stops: Paradas
routes: Rutas
@ -243,8 +265,8 @@ globals:
routeCreate: Nueva ruta
RouteRoadmap: Troncales
RouteRoadmapCreate: Crear troncal
autonomous: Autónomos
RouteExtendedList: Enrutador
autonomous: Autónomos
suppliers: Proveedores
supplier: Proveedor
supplierCreate: Nuevo proveedor
@ -309,23 +331,9 @@ globals:
wasteRecalc: Recalcular mermas
operator: Operario
parking: Parking
supplier: Proveedor
created: Fecha creación
worker: Trabajador
now: Ahora
name: Nombre
new: Nuevo
comment: Comentario
observations: Observaciones
goToModuleIndex: Ir al índice del módulo
unsavedPopup:
title: Los cambios que no haya guardado se perderán
subtitle: ¿Seguro que quiere salir sin guardar?
createInvoiceIn: Crear factura recibida
myAccount: Mi cuenta
noOne: Nadie
maxTemperature: Máx
minTemperature: Mín
params:
clientFk: Id cliente
salesPersonFk: Comercial
@ -348,12 +356,6 @@ globals:
packing: ITP
countryFk: País
companyFk: Empresa
changePass: Cambiar contraseña
setPass: Establecer contraseña
deleteConfirmTitle: Eliminar los elementos seleccionados
changeState: Cambiar estado
raid: 'Redada {daysInForward} días'
isVies: Vies
errors:
statusUnauthorized: Acceso denegado
statusInternalServerError: Ha ocurrido un error interno del servidor
@ -448,11 +450,15 @@ ticket:
attender: Consignatario
create:
address: Dirección
invoiceOut:
card:
issued: Fecha emisión
customerCard: Ficha del cliente
ticketList: Listado de tickets
order:
field:
salesPersonFk: Comercial
form:
clientFk: Cliente
addressFk: Dirección
agencyModeFk: Agencia
list:
newOrder: Nuevo Pedido
summary:
issued: Fecha
dued: Fecha límite
@ -463,47 +469,6 @@ invoiceOut:
fee: Cuota
tickets: Tickets
totalWithVat: Importe
globalInvoices:
errors:
chooseValidClient: Selecciona un cliente válido
chooseValidCompany: Selecciona una empresa válida
chooseValidPrinter: Selecciona una impresora válida
chooseValidSerialType: Selecciona una tipo de serie válida
fillDates: La fecha de la factura y la fecha máxima deben estar completas
invoiceDateLessThanMaxDate: La fecha de la factura no puede ser menor que la fecha máxima
invoiceWithFutureDate: Existe una factura con una fecha futura
noTicketsToInvoice: No existen tickets para facturar
criticalInvoiceError: Error crítico en la facturación proceso detenido
invalidSerialTypeForAll: El tipo de serie debe ser global cuando se facturan todos los clientes
table:
addressId: Id dirección
streetAddress: Dirección fiscal
statusCard:
percentageText: '{getPercentage}% {getAddressNumber} de {getNAddresses}'
pdfsNumberText: '{nPdfs} de {totalPdfs} PDFs'
negativeBases:
clientId: Id cliente
base: Base
active: Activo
hasToInvoice: Facturar
verifiedData: Datos comprobados
comercial: Comercial
errors:
downloadCsvFailed: Error al descargar CSV
shelving:
list:
parking: Parking
priority: Prioridad
newShelving: Nuevo Carro
summary:
recyclable: Reciclable
parking:
pickingOrder: Orden de recogida
row: Fila
column: Columna
searchBar:
info: Puedes buscar por código de parking
label: Buscar parking...
department:
chat: Chat
bossDepartment: Jefe de departamento
@ -693,6 +658,9 @@ supplier:
consumption:
entry: Entrada
travel:
search: Buscar envío
searchInfo: Buscar envío por id o nombre
id: Id
travelList:
tableVisibleColumns:
ref: Referencia
@ -723,62 +691,6 @@ travel:
destination: Destino
thermograph: Termógrafo
travelFileDescription: 'Id envío { travelId }'
item:
descriptor:
buyer: Comprador
color: Color
category: Categoría
available: Disponible
warehouseText: 'Calculado sobre el almacén de { warehouseName }'
itemDiary: Registro de compra-venta
list:
id: Identificador
stems: Tallos
category: Reino
typeName: Tipo
isActive: Activo
weightByPiece: Peso (gramos)/tallo
userName: Comprador
stemMultiplier: Multiplicador
fixedPrice:
itemFk: ID Artículo
groupingPrice: Precio grouping
packingPrice: Precio packing
hasMinPrice: Tiene precio mínimo
minPrice: Precio min
started: Inicio
ended: Fin
create:
priority: Prioridad
summary:
otherData: Otros datos
tax: IVA
botanical: Botánico
barcode: Código de barras
completeName: Nombre completo
family: Familia
stems: Tallos
multiplier: Multiplicador
buyer: Comprador
doPhoto: Hacer foto
intrastatCode: Código intrastat
ref: Referencia
relevance: Relevancia
weight: Peso (gramos)/tallo
units: Unidades/caja
expense: Gasto
generic: Genérico
recycledPlastic: Plástico reciclado
nonRecycledPlastic: Plástico no reciclado
minSalesQuantity: Cantidad mínima de venta
genus: Genus
specie: Specie
buyRequest:
requester: Solicitante
requested: Solicitado
attender: Comprador
achieved: Conseguido
concept: Concepto
components:
topbar: {}
itemsFilterPanel:

View File

@ -153,6 +153,7 @@ const updateDateParams = (value, params) => {
data-key="CustomerConsumption"
url="Clients/consumption"
:order="['itemTypeFk', 'itemName', 'itemSize', 'description']"
:filter="{ where: { clientFk: route.params.id } }"
:columns="columns"
search-url="consumption"
:user-params="userParams"

View File

@ -187,14 +187,18 @@ const debtWarning = computed(() => {
</QBtn>
<QBtn
:to="{
name: 'AccountSummary',
params: { id: entity.id },
name: 'OrderList',
query: {
createForm: JSON.stringify({
clientFk: entity.id,
}),
},
}"
size="md"
icon="face"
icon="vn:basketadd"
color="primary"
>
<QTooltip>{{ t('Go to user') }}</QTooltip>
<QTooltip>{{ t('globals.pageTitles.createOrder') }}</QTooltip>
</QBtn>
<QBtn
v-if="entity.supplier"
@ -218,14 +222,9 @@ en:
unpaidDated: 'Date {dated}'
unpaidAmount: 'Amount {amount}'
es:
Go to module index: Ir al índice del módulo
Customer ticket list: Listado de tickets del cliente
Customer invoice out list: Listado de facturas del cliente
New order: Nuevo pedido
New ticket: Nuevo ticket
Go to user: Ir al usuario
Go to supplier: Ir al proveedor
Customer unpaid: Cliente impago
Unpaid: Impagado
unpaidDated: 'Fecha {dated}'
unpaidAmount: 'Importe {amount}'

View File

@ -51,7 +51,6 @@ const openCreateForm = (type) => {
};
const clientFk = {
ticket: 'clientId',
order: 'clientFk',
};
const key = clientFk[type];
if (!key) return;
@ -70,11 +69,6 @@ const openCreateForm = (type) => {
{{ t('globals.pageTitles.createTicket') }}
</QItemSection>
</QItem>
<QItem v-ripple clickable @click="openCreateForm('order')">
<QItemSection>
{{ t('globals.pageTitles.createOrder') }}
</QItemSection>
</QItem>
<QItem v-ripple clickable>
<QItemSection @click="showSmsDialog()">{{ t('Send SMS') }}</QItemSection>
</QItem>

View File

@ -50,7 +50,8 @@ const filterClientFindOne = {
>
<template #form="{ data }">
<VnRow>
<QCheckbox :label="t('Unpaid client')" v-model="data.unpaid" />
<QCheckbox :label="t('Unpaid client')" v-model="data.unpaid"
data-cy="UnpaidCheckBox" />
</VnRow>
<VnRow class="row q-gutter-md q-mb-md" v-show="data.unpaid">

View File

@ -408,7 +408,7 @@ function handleLocation(data, location) {
order: ['id DESC'],
}"
>
<template #rightMenu>
<template #advanced-menu>
<CustomerFilter data-key="CustomerList" />
</template>
<template #body>

View File

@ -11,14 +11,14 @@ import VnInput from 'src/components/common/VnInput.vue';
import CustomerDefaulterAddObservation from './CustomerDefaulterAddObservation.vue';
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
import VnTable from 'src/components/VnTable/VnTable.vue';
import { useArrayData } from 'src/composables/useArrayData';
const { t } = useI18n();
const quasar = useQuasar();
const dataRef = ref(null);
const balanceDueTotal = ref(0);
const selected = ref([]);
const arrayData = useArrayData('CustomerDefaulter');
const columns = computed(() => [
{
align: 'left',
@ -165,26 +165,37 @@ const viewAddObservation = (rowsSelected) => {
});
};
const onFetch = async (data) => {
balanceDueTotal.value = data.reduce((acc, { amount = 0 }) => acc + amount, 0);
};
function exprBuilder(param, value) {
switch (param) {
case 'clientFk':
return { [`d.${param}`]: value };
case 'creditInsurance':
case 'amount':
case 'workerFk':
case 'departmentFk':
case 'countryFk':
case 'payMethod':
case 'salesPersonFk':
case 'creditInsurance':
case 'countryFk':
return { [`c.${param}`]: value };
case 'payMethod':
return { [`c.payMethodFk`]: value };
case 'workerFk':
return { [`co.${param}`]: value };
case 'departmentFk':
return { [`wd.${param}`]: value };
case 'amount':
case 'clientFk':
return { [`d.${param}`]: value };
case 'created':
return { 'd.created': { between: dateRange(value) } };
case 'defaulterSinced':
return { 'd.defaulterSinced': { between: dateRange(value) } };
case 'isWorker': {
if (value == undefined) return;
const search = value ? 'worker' : { neq: 'worker' };
return { 'c.businessTypeFk': search };
}
case 'hasRecovery': {
if (value == undefined) return;
const search = value ? null : { neq: null };
return { 'r.finished': search };
}
case 'observation':
return { 'co.text': { like: `%${value}%` } };
}
}
</script>
@ -192,7 +203,7 @@ function exprBuilder(param, value) {
<template>
<VnSubToolbar>
<template #st-data>
<CustomerBalanceDueTotal :amount="balanceDueTotal" />
<CustomerBalanceDueTotal :amount="arrayData.store.data?.amount" />
</template>
<template #st-actions>
<QBtn
@ -211,8 +222,6 @@ function exprBuilder(param, value) {
url="Defaulters/filter"
:expr-builder="exprBuilder"
:columns="columns"
@on-fetch="onFetch"
:use-model="true"
:table="{
'row-key': 'clientFk',
selection: 'multiple',
@ -221,6 +230,7 @@ function exprBuilder(param, value) {
:disable-option="{ card: true }"
auto-load
:order="['amount DESC']"
key-data="defaulters"
>
<template #column-clientFk="{ row }">
<span class="link" @click.stop>

View File

@ -214,7 +214,7 @@ const toCustomerSamples = () => {
<template #custom-buttons>
<QBtn
:disabled="isLoading || !sampleType?.hasPreview"
:label="t('Preview')"
:label="t('globals.preview')"
:loading="isLoading"
@click.stop="getPreview()"
color="primary"
@ -353,7 +353,6 @@ es:
Its only used when sample is sent: Se utiliza únicamente cuando se envía la plantilla
To who should the recipient replay?: ¿A quien debería responder el destinatario?
Edit address: Editar dirección
Preview: Vista previa
Email cannot be blank: Debes introducir un email
Choose a sample: Selecciona una plantilla
Choose a company: Selecciona una empresa

View File

@ -147,7 +147,7 @@ es:
Supplier card: Ficha del proveedor
All travels with current agency: Todos los envíos con la agencia actual
All entries with current supplier: Todas las entradas con el proveedor actual
Go to module index: Ir al índice del modulo
Show entry report: Ver informe del pedido
Inventory entry: Es inventario
Virtual entry: Es una redada
</i18n>

View File

@ -205,7 +205,7 @@ const columns = computed(() => [
userFilter: entryFilter,
}"
>
<template #rightMenu>
<template #advanced-menu>
<EntryFilter data-key="EntryList" />
</template>
<template #body>
@ -231,7 +231,7 @@ const columns = computed(() => [
>
<QTooltip>{{
t(
'entry.list.tableVisibleColumns.isExcludedFromAvailable'
'entry.list.tableVisibleColumns.isExcludedFromAvailable',
)
}}</QTooltip>
</QIcon>

View File

@ -1,19 +1,11 @@
<script setup>
import InvoiceOutDescriptor from './InvoiceOutDescriptor.vue';
import VnCard from 'components/common/VnCard.vue';
import InvoiceOutFilter from '../InvoiceOutFilter.vue';
import VnCardBeta from 'components/common/VnCardBeta.vue';
</script>
<template>
<VnCard
<VnCardBeta
data-key="InvoiceOut"
base-url="InvoiceOuts"
:descriptor="InvoiceOutDescriptor"
:filter-panel="InvoiceOutFilter"
search-data-key="InvoiceOutList"
:searchbar-props="{
url: 'InvoiceOuts/filter',
label: 'Search invoice',
info: 'You can search by invoice reference',
}"
/>
</template>

View File

@ -3,7 +3,6 @@ import { ref, computed, watchEffect } from 'vue';
import { useI18n } from 'vue-i18n';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { usePrintService } from 'src/composables/usePrintService';
@ -12,12 +11,12 @@ import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
import { toCurrency, toDate } from 'src/filters/index';
import { QBtn } from 'quasar';
import axios from 'axios';
import RightMenu from 'src/components/common/RightMenu.vue';
import InvoiceOutFilter from './InvoiceOutFilter.vue';
import VnRow from 'src/components/ui/VnRow.vue';
import VnRadio from 'src/components/common/VnRadio.vue';
import VnInput from 'src/components/common/VnInput.vue';
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
import VnSection from 'src/components/common/VnSection.vue';
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
@ -30,9 +29,11 @@ const MODEL = 'InvoiceOuts';
const { openReport } = usePrintService();
const addressOptions = ref([]);
const selectedOption = ref('ticket');
const dataKey = 'InvoiceOutList';
async function fetchClientAddress(id) {
const { data } = await axios.get(
`Clients/${id}/addresses?filter[order]=isActive DESC`
`Clients/${id}/addresses?filter[order]=isActive DESC`,
);
addressOptions.value = data;
}
@ -180,16 +181,19 @@ watchEffect(selectedRows);
</script>
<template>
<VnSearchbar
:info="t('youCanSearchByInvoiceReference')"
:label="t('Search invoice')"
data-key="invoiceOutList"
/>
<RightMenu>
<template #right-panel>
<InvoiceOutFilter data-key="invoiceOutList" />
<VnSection
:data-key="dataKey"
:columns="columns"
prefix="invoiceOut"
:array-data-props="{
url: 'InvoiceOuts/filter',
order: ['id DESC'],
}"
>
<template #advanced-menu>
<InvoiceOutFilter data-key="InvoiceOutList" />
</template>
</RightMenu>
<template #body>
<VnSubToolbar>
<template #st-actions>
<QBtn
@ -199,14 +203,13 @@ watchEffect(selectedRows);
:disable="!hasSelectedCards"
data-cy="InvoiceOutDownloadPdfBtn"
>
<QTooltip>{{ t('downloadPdf') }}</QTooltip>
<QTooltip>{{ t('globals.downloadPdf') }}</QTooltip>
</QBtn>
</template>
</VnSubToolbar>
<VnTable
ref="tableRef"
data-key="invoiceOutList"
:url="`${MODEL}/filter`"
:data-key="dataKey"
:create="{
urlCreate: 'InvoiceOuts/createManualInvoice',
title: t('createManualInvoice'),
@ -215,7 +218,6 @@ watchEffect(selectedRows);
}"
:right-search="false"
v-model:selected="selectedRows"
order="id DESC"
:columns="columns"
redirect="invoice-out"
:table="{
@ -293,13 +295,17 @@ watchEffect(selectedRows);
<QItemLabel
:class="{
'color-vn-label':
!scope.opt?.isActive,
!scope.opt
?.isActive,
}"
>
{{
`${
!scope.opt?.isActive
? t('inactive')
!scope.opt
?.isActive
? t(
'inactive',
)
: ''
} `
}}
@ -308,19 +314,26 @@ watchEffect(selectedRows);
}}</span>
<span
v-if="
scope.opt?.province ||
scope.opt
?.province ||
scope.opt?.city ||
scope.opt?.street
"
>
, {{ scope.opt?.street }},
,
{{
scope.opt?.street
}},
{{ scope.opt?.city }},
{{
scope.opt?.province?.name
scope.opt
?.province
?.name
}}
-
{{
scope.opt?.agencyMode
scope.opt
?.agencyMode
?.name
}}
</span>
@ -383,7 +396,9 @@ watchEffect(selectedRows);
<VnSelect
url="TaxAreas"
v-model="data.taxArea"
:label="t('invoiceOutList.tableVisibleColumns.taxArea')"
:label="
t('invoiceOutList.tableVisibleColumns.taxArea')
"
:options="taxAreasOptions"
option-label="code"
option-value="code"
@ -398,6 +413,8 @@ watchEffect(selectedRows);
</template>
</VnTable>
</template>
</VnSection>
</template>
<style lang="scss" scoped>
#formModel .vn-row {

View File

@ -39,7 +39,7 @@ const columns = computed(() => [
{
align: 'left',
name: 'country',
label: t('negativeBases.country'),
label: t('invoiceOut.negativeBases.country'),
component: 'select',
attrs: {
url: 'Countries',
@ -53,7 +53,7 @@ const columns = computed(() => [
{
align: 'left',
name: 'clientId',
label: t('negativeBases.clientId'),
label: t('invoiceOut.negativeBases.clientId'),
cardVisible: true,
},
{
@ -85,28 +85,28 @@ const columns = computed(() => [
{
align: 'left',
name: 'taxableBase',
label: t('negativeBases.base'),
label: t('invoiceOut.negativeBases.base'),
},
{
align: 'left',
name: 'ticketFk',
label: t('negativeBases.ticketId'),
label: t('invoiceOut.negativeBases.ticketId'),
cardVisible: true,
},
{
align: 'left',
name: 'isActive',
label: t('negativeBases.active'),
label: t('invoiceOut.negativeBases.active'),
},
{
align: 'left',
name: 'hasToInvoice',
label: t('negativeBases.hasToInvoice'),
label: t('invoiceOut.negativeBases.hasToInvoice'),
},
{
align: 'left',
name: 'hasVerifiedData',
label: t('negativeBases.verifiedData'),
label: t('invoiceOut.negativeBases.verifiedData'),
},
{
align: 'left',

View File

@ -105,28 +105,3 @@ const props = defineProps({
</template>
</VnFilterPanel>
</template>
<i18n>
en:
params:
from: From
to: To
company: Company
country: Country
clientId: Client Id
clientSocialName: Client
amount: Amount
comercialName: Comercial
es:
params:
from: Desde
to: Hasta
company: Empresa
country: País
clientId: Id cliente
clientSocialName: Cliente
amount: Importe
comercialName: Comercial
Date is required: La fecha es requerida
</i18n>

View File

@ -1,3 +1,60 @@
invoiceOut:
search: Search invoice
searchInfo: You can search by invoice reference
params:
company: Company
country: Country
clientId: Client ID
clientSocialName: Client
taxableBase: Base
ticketFk: Ticket
isActive: Active
hasToInvoice: Has to invoice
hasVerifiedData: Verified data
workerName: Worker
card:
issued: Issued
customerCard: Customer card
ticketList: Ticket List
summary:
issued: Issued
dued: Due
booked: Booked
taxBreakdown: Tax breakdown
taxableBase: Taxable base
rate: Rate
fee: Fee
tickets: Tickets
totalWithVat: Amount
globalInvoices:
errors:
chooseValidClient: Choose a valid client
chooseValidCompany: Choose a valid company
chooseValidPrinter: Choose a valid printer
chooseValidSerialType: Choose a serial type
fillDates: Invoice date and the max date should be filled
invoiceDateLessThanMaxDate: Invoice date can not be less than max date
invoiceWithFutureDate: Exists an invoice with a future date
noTicketsToInvoice: There are not tickets to invoice
criticalInvoiceError: 'Critical invoicing error, process stopped'
invalidSerialTypeForAll: The serial type must be global when invoicing all clients
table:
addressId: Address id
streetAddress: Street
statusCard:
percentageText: '{getPercentage}% {getAddressNumber} of {getNAddresses}'
pdfsNumberText: '{nPdfs} of {totalPdfs} PDFs'
negativeBases:
country: Country
clientId: Client Id
base: Base
ticketId: Ticket
active: Active
hasToInvoice: Has to Invoice
verifiedData: Verified Data
comercial: Commercial
errors:
downloadCsvFailed: CSV download failed
invoiceOutModule:
customer: Client
amount: Amount
@ -14,26 +71,3 @@ invoiceOutList:
ticket: Ticket
taxArea: Tax area
customsAgent: Custom Agent
DownloadPdf: Download PDF
InvoiceOutSummary: Summary
negativeBases:
country: Country
clientId: Client ID
base: Base
ticketId: Ticket
active: Active
hasToInvoice: Has to invoice
verifiedData: Verified data
commercial: Commercial
invoiceout:
params:
company: Company
country: Country
clientId: Client ID
clientSocialName: Client
taxableBase: Base
ticketFk: Ticket
isActive: Active
hasToInvoice: Has to invoice
hasVerifiedData: Verified data
workerName: Worker

View File

@ -1,5 +1,60 @@
Search invoice: Buscar factura emitida
You can search by invoice reference: Puedes buscar por referencia de la factura
invoiceOut:
search: Buscar factura emitida
searchInfo: Puedes buscar por referencia de la factura
params:
company: Empresa
country: País
clientId: ID del cliente
clientSocialName: Cliente
taxableBase: Base
ticketFk: Ticket
isActive: Activo
hasToInvoice: Debe facturar
hasVerifiedData: Datos verificados
workerName: Comercial
card:
issued: Fecha emisión
customerCard: Ficha del cliente
ticketList: Listado de tickets
summary:
issued: Fecha
dued: Fecha límite
booked: Contabilizada
taxBreakdown: Desglose impositivo
taxableBase: Base imp.
rate: Tarifa
fee: Cuota
tickets: Tickets
totalWithVat: Importe
globalInvoices:
errors:
chooseValidClient: Selecciona un cliente válido
chooseValidCompany: Selecciona una empresa válida
chooseValidPrinter: Selecciona una impresora válida
chooseValidSerialType: Selecciona una tipo de serie válida
fillDates: La fecha de la factura y la fecha máxima deben estar completas
invoiceDateLessThanMaxDate: La fecha de la factura no puede ser menor que la fecha máxima
invoiceWithFutureDate: Existe una factura con una fecha futura
noTicketsToInvoice: No existen tickets para facturar
criticalInvoiceError: Error crítico en la facturación proceso detenido
invalidSerialTypeForAll: El tipo de serie debe ser global cuando se facturan todos los clientes
table:
addressId: Id dirección
streetAddress: Dirección fiscal
statusCard:
percentageText: '{getPercentage}% {getAddressNumber} de {getNAddresses}'
pdfsNumberText: '{nPdfs} de {totalPdfs} PDFs'
negativeBases:
country: País
clientId: Id cliente
base: Base
ticketId: Ticket
active: Activo
hasToInvoice: Facturar
verifiedData: Datos comprobados
comercial: Comercial
errors:
downloadCsvFailed: Error al descargar CSV
invoiceOutModule:
customer: Cliente
amount: Importe
@ -16,27 +71,3 @@ invoiceOutList:
ticket: Ticket
taxArea: Area
customsAgent: Agente de aduanas
DownloadPdf: Descargar PDF
InvoiceOutSummary: Resumen
negativeBases:
country: País
clientId: ID del cliente
client: Cliente
base: Base
ticketId: Ticket
active: Activo
hasToInvoice: Debe facturar
verifiedData: Datos verificados
commercial: Comercial
invoiceout:
params:
company: Empresa
country: País
clientId: ID del cliente
clientSocialName: Cliente
taxableBase: Base
ticketFk: Ticket
isActive: Activo
hasToInvoice: Debe facturar
hasVerifiedData: Datos verificados
workerName: Comercial

View File

@ -1,19 +1,11 @@
<script setup>
import VnCard from 'components/common/VnCard.vue';
import VnCardBeta from 'components/common/VnCardBeta.vue';
import ItemDescriptor from './ItemDescriptor.vue';
import ItemListFilter from '../ItemListFilter.vue';
</script>
<template>
<VnCard
<VnCardBeta
data-key="Item"
base-url="Items"
:descriptor="ItemDescriptor"
:filter-panel="ItemListFilter"
search-data-key="ItemList"
:searchbar-props="{
url: 'Items/filter',
label: 'searchbar.label',
info: 'searchbar.info',
}"
/>
</template>

View File

@ -6,18 +6,17 @@ import VnImg from 'src/components/ui/VnImg.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import { toDate } from 'src/filters';
import FetchedTags from 'src/components/ui/FetchedTags.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import ItemSummary from '../Item/Card/ItemSummary.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue';
import ItemTypeDescriptorProxy from './ItemType/Card/ItemTypeDescriptorProxy.vue';
import { cloneItem } from 'src/pages/Item/composables/cloneItem';
import RightMenu from 'src/components/common/RightMenu.vue';
import ItemListFilter from './ItemListFilter.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import axios from 'axios';
import VnSection from 'src/components/common/VnSection.vue';
const entityId = computed(() => route.params.id);
const { openCloneDialog } = cloneItem();
@ -25,9 +24,11 @@ const { viewSummary } = useSummaryDialog();
const { t } = useI18n();
const tableRef = ref();
const route = useRoute();
const dataKey = 'ItemList';
const validPriorities = ref([]);
const defaultTag = ref();
const defaultPriority = ref();
const itemFilter = {
include: [
{
@ -324,22 +325,29 @@ onBeforeMount(async () => {
});
});
</script>
<template>
<VnSearchbar
data-key="ItemList"
:label="t('item.searchbar.label')"
:info="t('item.searchbar.info')"
/>
<RightMenu>
<template #right-panel>
<VnSection
:data-key="dataKey"
:columns="columns"
prefix="item"
:array-data-props="{
url: 'Items/filter',
order: ['isActive DESC', 'name', 'id'],
userFilter: itemFilter,
}"
>
<template #advanced-menu>
<ItemListFilter data-key="ItemList" />
</template>
</RightMenu>
<template #body>
<VnTable
v-if="defaultTag"
ref="tableRef"
data-key="ItemList"
url="Items/filter"
:data-key="dataKey"
:columns="columns"
:right-search="false"
redirect="Item"
:create="{
urlCreate: 'Items/new',
title: t('item.list.newItem'),
@ -350,12 +358,7 @@ onBeforeMount(async () => {
priority: defaultPriority,
},
}"
:order="['isActive DESC', 'name', 'id']"
:columns="columns"
redirect="Item"
:is-editable="false"
:right-search="false"
:filter="itemFilter"
>
<template #column-image="{ row }">
<VnImg
@ -391,7 +394,7 @@ onBeforeMount(async () => {
{{ row?.subName.toUpperCase() }}
</div>
</div>
<FetchedTags :item="row" />
<FetchedTags :item="row" :columns="3" />
</template>
<template #more-create-dialog="{ data }">
<VnInput
@ -413,7 +416,9 @@ onBeforeMount(async () => {
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
<QItemLabel caption> #{{ scope.opt?.id }} </QItemLabel>
<QItemLabel caption>
#{{ scope.opt?.id }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
@ -457,7 +462,9 @@ onBeforeMount(async () => {
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.description }}</QItemLabel>
<QItemLabel caption> #{{ scope.opt?.id }} </QItemLabel>
<QItemLabel caption>
#{{ scope.opt?.id }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
@ -485,6 +492,8 @@ onBeforeMount(async () => {
</template>
</VnTable>
</template>
</VnSection>
</template>
<style lang="scss" scoped>
.subName {
text-transform: uppercase;
@ -497,5 +506,4 @@ es:
New item: Nuevo artículo
Create Item: Crear artículo
You can search by id: Puedes buscar por id
Preview: Vista previa
</i18n>

View File

@ -1,7 +1,6 @@
<script setup>
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { onMounted } from 'vue';
import { useStateStore } from 'stores/useStateStore';
import FetchData from 'components/FetchData.vue';
@ -233,7 +232,7 @@ onMounted(async () => {
<QItemSection>
<VnSelect
:label="t('params.buyerFk')"
v-model="params.buyerFk"
v-model="params.workerFk"
@update:model-value="searchFn()"
:options="buyersOptions"
option-value="id"

View File

@ -1,20 +1,12 @@
<script setup>
import VnCard from 'components/common/VnCard.vue';
import VnCardBeta from 'components/common/VnCardBeta.vue';
import ItemTypeDescriptor from 'src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue';
import ItemTypeFilter from 'src/pages/Item/ItemType/ItemTypeFilter.vue';
import ItemTypeSearchbar from '../ItemTypeSearchbar.vue';
</script>
<template>
<VnCard
<VnCardBeta
data-key="ItemTypeSummary"
base-url="ItemTypes"
:descriptor="ItemTypeDescriptor"
:filter-panel="ItemTypeFilter"
search-data-key="ItemTypeList"
search-url="ItemTypes"
>
<template #searchbar>
<ItemTypeSearchbar />
</template>
</VnCard>
/>
</template>

View File

@ -63,7 +63,3 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity
</CardDescriptor>
</template>
<i18n>
es:
Go to module index: Ir al índice del módulo
</i18n>

View File

@ -1,90 +0,0 @@
<script setup>
import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n();
const props = defineProps({
dataKey: {
type: String,
required: true,
},
});
const emit = defineEmits(['search']);
const exprBuilder = (param, value) => {
switch (param) {
case 'name':
return {
name: { like: `%${value}%` },
};
case 'code':
return {
code: { like: `%${value}%` },
};
case 'search':
if (value) {
if (!isNaN(value)) {
return { id: value };
} else {
return {
or: [
{
name: {
like: `%${value}%`,
},
},
{
code: {
like: `%${value}%`,
},
},
],
};
}
}
}
};
</script>
<template>
<VnFilterPanel
:data-key="props.dataKey"
:search-button="true"
@search="emit('search')"
search-url="table"
:expr-builder="exprBuilder"
>
<template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span>
</div>
</template>
<template #body="{ params }">
<QItem>
<QItemSection>
<VnInput :label="t('Name')" v-model="params.name" is-outlined />
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput v-model="params.code" :label="t('Code')" is-outlined />
</QItemSection>
</QItem>
</template>
</VnFilterPanel>
</template>
<i18n>
en:
params:
name: Name
code: Code
es:
params:
name: Nombre
code: Código
Name: Nombre
Code: Código
</i18n>

View File

@ -1,19 +0,0 @@
<script setup>
import VnSearchbar from 'components/ui/VnSearchbar.vue';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
</script>
<template>
<VnSearchbar
data-key="ItemTypeList"
url="ItemTypes"
:label="t('Search item type')"
:info="t('Search itemType by id, name or code')"
/>
</template>
<i18n>
es:
Search item type: Buscar familia
Search itemType by id, name or code: Buscar familia por id, nombre o código
</i18n>

View File

@ -15,3 +15,5 @@ itemType:
promo: Promo
itemPackingType: Item packing type
isUnconventionalSize: Is unconventional size
search: Search item type
searchInfo: Search item type by id, name or code

View File

@ -15,3 +15,5 @@ itemType:
promo: Promoción
itemPackingType: Tipo de embalaje
isUnconventionalSize: Es de tamaño poco convencional
search: Buscar familia
searchInfo: Buscar familia por id, nombre o código

View File

@ -1,17 +1,50 @@
<script setup>
import { useI18n } from 'vue-i18n';
import { ref, computed } from 'vue';
import ItemTypeSearchbar from 'src/pages/Item/ItemType/ItemTypeSearchbar.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import FetchData from 'components/FetchData.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
import ItemTypeFilter from './ItemType/ItemTypeFilter.vue';
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
import VnSection from 'src/components/common/VnSection.vue';
const { t } = useI18n();
const tableRef = ref();
const itemCategoriesOptions = ref([]);
const temperatureOptions = ref([]);
const dataKey = 'ItemTypeList';
const exprBuilder = (param, value) => {
switch (param) {
case 'name':
return {
name: { like: `%${value}%` },
};
case 'code':
return {
code: { like: `%${value}%` },
};
case 'search':
if (value) {
if (!isNaN(value)) {
return { id: value };
} else {
return {
or: [
{
name: {
like: `%${value}%`,
},
},
{
code: {
like: `%${value}%`,
},
},
],
};
}
}
}
};
const columns = computed(() => [
{
@ -103,23 +136,15 @@ const columns = computed(() => [
@on-fetch="(data) => (temperatureOptions = data)"
auto-load
/>
<RightMenu>
<template #right-panel>
<ItemTypeFilter data-key="ItemTypeList" />
</template>
</RightMenu>
<ItemTypeSearchbar />
<VnTable
ref="tableRef"
data-key="ItemTypeList"
url="ItemTypes"
:create="{
urlCreate: 'ItemTypes',
title: t('Create ItemTypes'),
onDataSaved: () => tableRef.reload(),
formInitialData: {},
}"
:user-filter="{
<VnSection
:data-key="dataKey"
:columns="columns"
prefix="itemType"
:array-data-props="{
url: 'ItemTypes',
order: 'name ASC',
exprBuilder,
userFilter: {
include: {
relation: 'worker',
scope: {
@ -132,11 +157,21 @@ const columns = computed(() => [
},
},
},
},
}"
>
<template #body>
<VnTable
ref="tableRef"
:data-key="dataKey"
:create="{
urlCreate: 'ItemTypes',
title: t('Create ItemTypes'),
onDataSaved: () => tableRef.reload(),
formInitialData: {},
}"
order="name ASC"
:columns="columns"
auto-load
:right-search="false"
redirect="item/item-type"
>
<template #column-workerFk="{ row }">
@ -147,6 +182,8 @@ const columns = computed(() => [
</template>
</VnTable>
</template>
</VnSection>
</template>
<i18n>
es:

View File

@ -180,44 +180,46 @@ item:
intrastat: Intrastat
origin: Origin
buyRequest:
ticketId: 'Ticket ID'
shipped: 'Shipped'
requester: 'Requester'
requested: 'Requested'
price: 'Price'
attender: 'Attender'
item: 'Item'
achieved: 'Achieved'
concept: 'Concept'
state: 'State'
ticketId: Ticket ID
shipped: Shipped
requester: Requester
requested: Requested
price: Price
attender: Attender
item: Item
achieved: Achieved
concept: Concept
state: State
summary:
basicData: 'Basic data'
otherData: 'Other data'
description: 'Description'
tax: 'Tax'
tags: 'Tags'
botanical: 'Botanical'
barcode: 'Barcode'
name: 'Nombre'
completeName: 'Nombre completo'
family: 'Familia'
size: 'Medida'
origin: 'Origen'
stems: 'Tallos'
multiplier: 'Multiplicador'
buyer: 'Comprador'
doPhoto: 'Do photo'
intrastatCode: 'Código intrastat'
basicData: Basic data
otherData: Other data
description: Description
tax: Tax
tags: Tags
botanical: Botanical
barcode: Barcode
name: Name
completeName: Complete name
family: Family
size: Size
origin: Origin
stems: Stems
multiplier: Multiplier
buyer: Buyer
doPhoto: Do photo
intrastatCode: Intrastat code
intrastat: 'Intrastat'
ref: 'Referencia'
relevance: 'Relevancia'
weight: 'Peso (gramos)/tallo'
units: 'Unidades/caja'
expense: 'Gasto'
generic: 'Genérico'
recycledPlastic: 'Plástico reciclado'
nonRecycledPlastic: 'Plástico no reciclado'
minSalesQuantity: 'Cantidad mínima de venta'
genus: 'Genus'
specie: 'Specie'
ref: Reference
relevance: Relevance
weight: Weight (gram)/stem
units: Units/box
expense: Expense
generic: Generic
recycledPlastic: Recycled plastic
nonRecycledPlastic: Non recycled plastic
minSalesQuantity: Min sales quantity
genus: Genus
specie: Specie
search: 'Search item'
searchInfo: 'You can search by id'
regularizeStock: Regularize stock

View File

@ -73,9 +73,6 @@ itemTags:
addTag: Añadir etiqueta
tag: Etiqueta
value: Valor
searchbar:
label: Buscar artículo
info: Buscar por id de artículo
itemType:
shared:
code: Código
@ -108,9 +105,6 @@ item:
concept: Concepto
denyOptions: Denegado
scopeDays: Días en adelante
searchbar:
label: Buscar artículo
info: Puedes buscar por id
descriptor:
item: Artículo
buyer: Comprador
@ -182,35 +176,35 @@ item:
intrastat: Intrastat
origin: Origen
summary:
basicData: 'Datos básicos'
otherData: 'Otros datos'
description: 'Descripción'
tax: 'IVA'
tags: 'Etiquetas'
botanical: 'Botánico'
barcode: 'Código de barras'
name: 'Nombre'
completeName: 'Nombre completo'
family: 'Familia'
size: 'Medida'
origin: 'Origen'
stems: 'Tallos'
multiplier: 'Multiplicador'
buyer: 'Comprador'
doPhoto: 'Hacer foto'
intrastatCode: 'Código intrastat'
intrastat: 'Intrastat'
ref: 'Referencia'
relevance: 'Relevancia'
weight: 'Peso (gramos)/tallo'
units: 'Unidades/caja'
expense: 'Gasto'
generic: 'Genérico'
recycledPlastic: 'Plástico reciclado'
nonRecycledPlastic: 'Plástico no reciclado'
minSalesQuantity: 'Cantidad mínima de venta'
genus: 'Genus'
specie: 'Specie'
basicData: Datos básicos
otherData: Otros datos
description: Descripción
tax: IVA
tags: Etiquetas
botanical: Botánico
barcode: Código de barras
name: Nombre
completeName: Nombre completo
family: Familia
size: Medida
origin: Origen
stems: Tallos
multiplier: Multiplicador
buyer: Comprador
doPhoto: Hacer foto
intrastatCode: Código intrastat
intrastat: Intrastat
ref: Referencia
relevance: Relevancia
weight: Peso (gramos)/tallo
units: Unidades/caja
expense: Gasto
generic: Genérico
recycledPlastic: Plástico reciclado
nonRecycledPlastic: Plástico no reciclado
minSalesQuantity: Cantidad mínima de venta
genus: Genus
specie: Specie
regularizeStock: Regularizar stock
buyRequest:
ticketId: 'ID Ticket'
@ -223,3 +217,5 @@ item:
achieved: 'Conseguido'
concept: 'Concepto'
state: 'Estado'
search: 'Buscar artículo'
searchInfo: 'Puedes buscar por id'

View File

@ -290,7 +290,7 @@ const columns = computed(() => [
},
},
{
title: t('salesTicketsTable.preview'),
title: t('globals.preview'),
icon: 'preview',
color: 'primary',
action: (row) => viewSummary(row.id, TicketSummary),

View File

@ -33,7 +33,6 @@ salesTicketsTable:
isFragile: Is fragile
zone: Zone
goToLines: Go to lines
preview: Preview
total: Total
preparation: H.Prep
payMethod: Pay method

View File

@ -115,6 +115,7 @@ const removeTagGroupParam = (params, search, valIndex) => {
} else {
params.tagGroups.splice(valIndex, 1);
}
search();
};
const setCategoryList = (data) => {

View File

@ -136,7 +136,7 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
title: t('InvoiceOutSummary'),
title: t('globals.pageTitles.summary'),
icon: 'preview',
action: (row) => viewSummary(row.id, OrderSummary),
isPrimary: true,

View File

@ -1,19 +1,12 @@
<script setup>
import VnCard from 'components/common/VnCard.vue';
import VnCardBeta from 'components/common/VnCardBeta.vue';
import ParkingDescriptor from 'pages/Parking/Card/ParkingDescriptor.vue';
import ParkingFilter from 'pages/Parking/ParkingFilter.vue';
</script>
<template>
<VnCard
<VnCardBeta
data-key="Parking"
base-url="Parkings"
:descriptor="ParkingDescriptor"
:filter-panel="ParkingFilter"
search-data-key="ParkingList"
:searchbar-props="{
url: 'Parkings',
label: 'parking.searchBar.label',
info: 'parking.searchBar.info',
}"
/>
</template>

View File

@ -5,17 +5,17 @@ import { useI18n } from 'vue-i18n';
import { useStateStore } from 'stores/useStateStore';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import VnPaginate from 'components/ui/VnPaginate.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import CardList from 'components/ui/CardList.vue';
import VnLv from 'components/ui/VnLv.vue';
import ParkingFilter from './ParkingFilter.vue';
import ParkingSummary from './Card/ParkingSummary.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
import VnSection from 'src/components/common/VnSection.vue';
const stateStore = useStateStore();
const { push } = useRouter();
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
const dataKey = 'ParkingList';
onMounted(() => (stateStore.rightDrawer = true));
onUnmounted(() => (stateStore.rightDrawer = false));
@ -37,38 +37,38 @@ function exprBuilder(param, value) {
</script>
<template>
<template>
<VnSearchbar
data-key="ParkingList"
:label="t('Search parking')"
:info="t('You can search by parking code')"
/>
</template>
<RightMenu>
<template #right-panel>
<VnSection
:data-key="dataKey"
prefix="parking"
:array-data-props="{
url: 'Parkings',
order: ['code'],
userFilter: filter,
exprBuilder,
}"
>
<template #advanced-menu>
<ParkingFilter data-key="ParkingList" />
</template>
</RightMenu>
<template #body>
<QPage class="column items-center q-pa-md">
<div class="vn-card-list">
<VnPaginate
data-key="ParkingList"
url="Parkings"
:user-filter="filter"
:expr-builder="exprBuilder"
:limit="20"
order="code"
>
<VnPaginate :data-key="dataKey">
<template #body="{ rows }">
<CardList
v-for="row of rows"
:key="row.id"
:id="row.id"
:title="row.code"
@click="push({ path: `/parking/${row.id}` })"
@click="
push({ path: `/shelving/parking/${row.id}/summary` })
"
>
<template #list-items>
<VnLv label="Sector" :value="row.sector?.description" />
<VnLv
label="Sector"
:value="row.sector?.description"
/>
<VnLv
:label="t('parking.pickingOrder')"
:value="row.pickingOrder"
@ -87,8 +87,5 @@ function exprBuilder(param, value) {
</div>
</QPage>
</template>
<i18n>
es:
Search parking: Buscar parking
You can search by parking code: Puede buscar por el código del parking
</i18n>
</VnSection>
</template>

View File

@ -0,0 +1,7 @@
parking:
pickingOrder: Picking order
sector: Sector
row: Row
column: Column
search: Search parking
searchInfo: You can search by parking code

View File

@ -0,0 +1,7 @@
parking:
pickingOrder: Orden de recogida
row: Fila
sector: Sector
column: Columna
search: Buscar parking
searchInfo: Puedes buscar por código de parking

View File

@ -142,7 +142,7 @@ const total = computed(() => {
const openDmsUploadDialog = async () => {
dmsDialog.value.rowsToCreateInvoiceIn = selectedRows.value
.filter(
(agencyTerm) => agencyTerm.supplierFk === selectedRows.value?.[0].supplierFk
(agencyTerm) => agencyTerm.supplierFk === selectedRows.value?.[0].supplierFk,
)
.map((agencyTerm) => ({
routeFk: agencyTerm.routeFk,
@ -277,5 +277,4 @@ es:
Price: Precio
Received: Recibida
Autonomous: Autónomos
Preview: Vista previa
</i18n>

View File

@ -112,7 +112,7 @@ const removeSelection = async () => {
await Promise.all(
selectedRows.value.map((roadmap) => {
axios.delete(`Roadmaps/${roadmap.id}`);
})
}),
);
};
@ -236,6 +236,5 @@ es:
Plate: Matrícula
Price: Precio
Observations: Observaciones
Preview: Vista previa
Select the estimated date of departure (ETD): Selecciona la fecha estimada de salida
</i18n>

View File

@ -33,7 +33,6 @@ route:
Mark as served: Mark as served
Download selected routes as PDF: Download selected routes as PDF
Add ticket: Add ticket
Preview: Preview
Summary: Summary
Route is closed: Route is closed
Route is not served: Route is not served

View File

@ -33,7 +33,7 @@ route:
Mark as served: Marcar como servidas
Download selected routes as PDF: Descargar rutas seleccionadas como PDF
Add ticket: Añadir tickets
Preview: Vista previa
preview: Vista previa
Summary: Resumen
Route is closed: La ruta está cerrada
Route is not served: La ruta no está servida

View File

@ -1,19 +1,12 @@
<script setup>
import VnCard from 'components/common/VnCard.vue';
import VnCardBeta from 'components/common/VnCardBeta.vue';
import ShelvingDescriptor from 'pages/Shelving/Card/ShelvingDescriptor.vue';
import ShelvingFilter from './ShelvingFilter.vue';
import ShelvingSearchbar from './ShelvingSearchbar.vue';
</script>
<template>
<VnCard
<VnCardBeta
data-key="Shelving"
base-url="Shelvings"
:descriptor="ShelvingDescriptor"
:filter-panel="ShelvingFilter"
search-data-key="ShelvingList"
>
<template #searchbar>
<ShelvingSearchbar />
</template>
</VnCard>
/>
</template>

View File

@ -6,13 +6,14 @@ import VnLv from 'components/ui/VnLv.vue';
import { useRouter } from 'vue-router';
import ShelvingFilter from 'pages/Shelving/Card/ShelvingFilter.vue';
import ShelvingSummary from 'pages/Shelving/Card/ShelvingSummary.vue';
import ShelvingSearchbar from 'pages/Shelving/Card/ShelvingSearchbar.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import RightMenu from 'src/components/common/RightMenu.vue';
import VnSection from 'src/components/common/VnSection.vue';
const router = useRouter();
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
const dataKey = 'ShelvingList';
const filter = {
include: [{ relation: 'parking' }],
};
@ -34,21 +35,23 @@ function exprBuilder(param, value) {
</script>
<template>
<ShelvingSearchbar />
<RightMenu>
<template #right-panel>
<VnSection
:data-key="dataKey"
prefix="shelving"
:array-data-props="{
url: 'Shelvings',
order: ['code'],
userFilter: filter,
exprBuilder,
}"
>
<template #advanced-menu>
<ShelvingFilter data-key="ShelvingList" />
</template>
</RightMenu>
<template #body>
<QPage class="column items-center q-pa-md">
<div class="vn-card-list">
<VnPaginate
data-key="ShelvingList"
url="Shelvings"
:filter="filter"
:expr-builder="exprBuilder"
:limit="20"
>
<VnPaginate :data-key="dataKey">
<template #body="{ rows }">
<CardList
v-for="row of rows"
@ -89,3 +92,5 @@ function exprBuilder(param, value) {
</QPageSticky>
</QPage>
</template>
</VnSection>
</template>

View File

@ -0,0 +1,9 @@
shelving:
list:
parking: Parking
priority: Priority
newShelving: New Shelving
summary:
recyclable: Recyclable
search: Search shelving
searchInfo: You can search by shelving reference

View File

@ -0,0 +1,9 @@
shelving:
list:
parking: Parking
priority: Prioridad
newShelving: Nuevo Carro
summary:
recyclable: Reciclable
search: Buscar carro
searchInfo: Puedes buscar por referencia del carro

View File

@ -188,7 +188,6 @@ const getEntryQueryParams = (supplier) => {
es:
All entries with current supplier: Todas las entradas con proveedor actual
Go to client: Ir a cliente
Go to module index: Ir al índice del módulo
Inactive supplier: Proveedor inactivo
Unverified supplier: Proveedor no verificado
</i18n>

View File

@ -239,7 +239,6 @@ function ticketFilter(ticket) {
<i18n>
es:
This ticket is deleted: Este ticket está eliminado
Go to module index: Ir al índice del modulo
Client inactive: Cliente inactivo
Client not checked: Cliente no verificado
Client has debt: Cliente con deuda

View File

@ -1,9 +1,8 @@
<script setup>
import VnCard from 'components/common/VnCard.vue';
import TravelDescriptor from './TravelDescriptor.vue';
import TravelFilter from '../TravelFilter.vue';
import VnCardBeta from 'src/components/common/VnCardBeta.vue';
const filter = {
const userFilter = {
fields: [
'id',
'ref',
@ -14,6 +13,9 @@ const filter = {
'warehouseOutFk',
'cargoSupplierFk',
'agencyModeFk',
'isRaid',
'isDelivered',
'isReceived',
],
include: [
{
@ -32,17 +34,10 @@ const filter = {
};
</script>
<template>
<VnCard
<VnCardBeta
data-key="Travel"
base-url="Travels"
search-data-key="TravelList"
:filter="filter"
:descriptor="TravelDescriptor"
:filter-panel="TravelFilter"
:searchbar-props="{
url: 'Travels/filter',
searchUrl: 'table',
label: 'Search travel',
}"
:user-filter="userFilter"
/>
</template>

View File

@ -85,7 +85,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
<i18n>
es:
Go to module index: Ir al índice del módulo
The travel will be deleted: El envío será eliminado
Do you want to delete this travel?: ¿Quieres eliminar este envío?
All travels with current agency: Todos los envíos con la agencia actual

View File

@ -5,18 +5,18 @@ import { useRouter, useRoute } from 'vue-router';
import VnTable from 'components/VnTable/VnTable.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import TravelSummary from './Card/TravelSummary.vue';
import VnSearchbar from 'components/ui/VnSearchbar.vue';
import { toDate } from 'src/filters';
import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
import RightMenu from 'src/components/common/RightMenu.vue';
import TravelFilter from './TravelFilter.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import VnSection from 'src/components/common/VnSection.vue';
const { viewSummary } = useSummaryDialog();
const router = useRouter();
const { t } = useI18n();
const route = useRoute();
const tableRef = ref();
const dataKey = 'TravelList';
const $props = defineProps({
id: {
type: Number,
@ -196,21 +196,23 @@ const columns = computed(() => [
</script>
<template>
<VnSearchbar
:info="t('You can search by travel id or name')"
:label="t('Search travel')"
data-key="TravelList"
/>
<RightMenu>
<template #right-panel>
<VnSection
:data-key="dataKey"
:columns="columns"
prefix="travel"
:array-data-props="{
url: 'Travels/filter',
order: ['landed DESC'],
userParams: { daysOnward: 7 },
}"
>
<template #advanced-menu>
<TravelFilter data-key="TravelList" />
</template>
</RightMenu>
<template #body>
<VnTable
ref="tableRef"
data-key="TravelList"
url="Travels/filter"
redirect="travel"
:data-key="dataKey"
:create="{
urlCreate: 'Travels',
title: t('Create Travels'),
@ -220,8 +222,7 @@ const columns = computed(() => [
},
}"
:right-search="false"
:user-params="{ daysOnward: 7 }"
order="landed DESC"
redirect="travel"
:columns="columns"
:is-editable="false"
>
@ -281,6 +282,8 @@ const columns = computed(() => [
</template>
</VnTable>
</template>
</VnSection>
</template>
<i18n>
en:
Add entry: Add entry

View File

@ -11,7 +11,7 @@ const { t } = useI18n();
const counters = ref({
alquilerBandeja: { count: 0, id: 96001, title: 'CC Bandeja', isTray: true },
bandejaRota: { count: 0, id: 88381, title: 'CC Bandeja Rota', isTray: true },
carryOficial: { count: 0, id: 96000, title: 'CC Carry OFICIAL TAG5' },
carryOficial: { count: 0, id: 96000, title: 'CC Carry OFICIAL TAG6' },
candadoRojo: { count: 0, id: 96002, title: 'CC Carry NO OFICIAL' },
sacadores: { count: 0, id: 142260, title: 'CC Sacadores' },
sinChapa: { count: 0, id: 2214, title: 'DC Carry Sin Placa CC' },

View File

@ -10,6 +10,7 @@ import axios from 'axios';
import VnImg from 'src/components/ui/VnImg.vue';
import EditPictureForm from 'components/EditPictureForm.vue';
import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
const $props = defineProps({
id: {
@ -115,10 +116,13 @@ const handlePhotoUpdated = (evt = false) => {
:value="entity.user?.emailUser?.email"
copy
/>
<VnLv
:label="t('worker.list.department')"
:value="entity.department ? entity.department.department.name : null"
/>
<VnLv :label="t('worker.list.department')">
<template #value>
<span class="link" v-text="entity.department?.department?.name" />
<DepartmentDescriptorProxy :id="entity.department?.department?.id" />
</template>
</VnLv>
<VnLv :value="entity.phone">
<template #label>
{{ t('globals.phone') }}

View File

@ -66,7 +66,3 @@ const setData = (entity) => {
</CardDescriptor>
</template>
<i18n>
es:
Go to module index: Ir al índice del módulo
</i18n>

View File

@ -90,7 +90,7 @@ const redirectToZoneSummary = (id) => {
color="primary"
@click.stop="viewSummary(props.row.id, ZoneSummary)"
>
<QTooltip>{{ t('zoneClosingTable.preview') }}</QTooltip>
<QTooltip>{{ t('globals.preview') }}</QTooltip>
</QIcon>
</div>
</QTd>

View File

@ -50,8 +50,7 @@ deliveryPanel:
postcode: Postcode
query: Query
noEventsWarning: No service for the specified zone
zoneClosingTable:
preview: Preview
warehouses:
deleteTitle: This item will be deleted
deleteSubtitle: Are you sure you want to continue?

View File

@ -13,9 +13,7 @@ import Travel from './travel';
import Order from './order';
import Entry from './entry';
import roadmap from './roadmap';
import Parking from './parking';
import Agency from './agency';
import ItemType from './itemType';
import Zone from './zone';
import Account from './account';
import Monitor from './monitor';
@ -36,9 +34,7 @@ export default [
invoiceIn,
Entry,
roadmap,
Parking,
Agency,
ItemType,
Zone,
Account,
Monitor,

View File

@ -1,34 +1,60 @@
import { RouterView } from 'vue-router';
const invoiceOutCard = {
name: 'InvoiceOutCard',
path: ':id',
component: () => import('src/pages/InvoiceOut/Card/InvoiceOutCard.vue'),
redirect: { name: 'InvoiceOutSummary' },
meta: {
menu: [],
},
children: [
{
path: 'summary',
name: 'InvoiceOutSummary',
meta: {
title: 'summary',
icon: 'launch',
},
component: () => import('src/pages/InvoiceOut/Card/InvoiceOutSummary.vue'),
}
],
};
export default {
path: '/invoice-out',
name: 'InvoiceOut',
path: '/invoice-out',
meta: {
title: 'invoiceOuts',
icon: 'vn:invoice-out',
moduleName: 'InvoiceOut',
menu: ['InvoiceOutList', 'InvoiceOutGlobal', 'InvoiceOutNegativeBases'],
},
component: RouterView,
redirect: { name: 'InvoiceOutMain' },
menus: {
main: ['InvoiceOutList', 'InvoiceOutGlobal', 'InvoiceOutNegativeBases'],
card: [],
},
children: [
{
name: 'InvoiceOutMain',
path: '',
component: () => import('src/components/common/VnModule.vue'),
redirect: { name: 'InvoiceOutIndexMain' },
children: [
{
path: '',
name: 'InvoiceOutMain',
component: () => import('src/components/common/VnModule.vue'),
name: 'InvoiceOutIndexMain',
redirect: { name: 'InvoiceOutList' },
component: () => import('src/pages/InvoiceOut/InvoiceOutList.vue'),
children: [
{
path: 'list',
name: 'InvoiceOutList',
path: 'list',
meta: {
title: 'list',
icon: 'view_list',
},
component: () => import('src/pages/InvoiceOut/InvoiceOutList.vue'),
},
invoiceOutCard,
],
},
{
path: 'global-invoicing',
@ -51,22 +77,5 @@ export default {
},
],
},
{
name: 'InvoiceOutCard',
path: ':id',
component: () => import('src/pages/InvoiceOut/Card/InvoiceOutCard.vue'),
redirect: { name: 'InvoiceOutSummary' },
children: [
{
name: 'InvoiceOutSummary',
path: 'summary',
meta: {
title: 'summary',
},
component: () =>
import('src/pages/InvoiceOut/Card/InvoiceOutSummary.vue'),
},
],
},
],
};

View File

@ -1,109 +1,23 @@
import { RouterView } from 'vue-router';
export default {
path: '/item',
name: 'Item',
meta: {
title: 'items',
icon: 'vn:item',
moduleName: 'Item',
keyBinding: 'a',
},
component: RouterView,
redirect: { name: 'ItemMain' },
menus: {
main: [
'ItemList',
'WasteBreakdown',
'ItemFixedPrice',
'ItemRequest',
'ItemTypeList',
],
card: [
'ItemBasicData',
'ItemLog',
'ItemDiary',
'ItemTags',
'ItemTax',
'ItemBotanical',
'ItemBarcode',
'ItemShelving',
'ItemLastEntries',
'ItemTags',
],
},
children: [
{
path: '',
name: 'ItemMain',
component: () => import('src/components/common/VnModule.vue'),
redirect: { name: 'ItemList' },
children: [
{
path: 'list',
name: 'ItemList',
meta: {
title: 'list',
icon: 'view_list',
},
component: () => import('src/pages/Item/ItemList.vue'),
},
{
path: 'request',
name: 'ItemRequest',
meta: {
title: 'buyRequest',
icon: 'vn:buyrequest',
},
component: () => import('src/pages/Item/ItemRequest.vue'),
},
{
path: 'waste-breakdown',
name: 'WasteBreakdown',
meta: {
title: 'wasteBreakdown',
icon: 'vn:claims',
},
beforeEnter: (to, from, next) => {
next({ name: 'ItemList' });
window.location.href =
'https://grafana.verdnatura.es/d/TTNXQAxVk';
},
},
{
path: 'fixed-price',
name: 'ItemFixedPrice',
meta: {
title: 'fixedPrice',
icon: 'vn:fixedPrice',
},
component: () => import('src/pages/Item/ItemFixedPrice.vue'),
},
{
path: 'create',
name: 'ItemCreate',
meta: {
title: 'itemCreate',
},
component: () => import('src/pages/Item/ItemCreate.vue'),
},
{
path: 'item-type-list',
name: 'ItemTypeList',
meta: {
title: 'family',
icon: 'contact_support',
},
component: () => import('src/pages/Item/ItemTypeList.vue'),
},
],
},
{
const itemCard = {
name: 'ItemCard',
path: ':id',
component: () => import('src/pages/Item/Card/ItemCard.vue'),
redirect: { name: 'ItemSummary' },
meta: {
menu: [
'ItemBasicData',
'ItemTags',
'ItemLastEntries',
'ItemTax',
'ItemBotanical',
'ItemShelving',
'ItemBarcode',
'ItemDiary',
'ItemLog',
],
},
children: [
{
name: 'ItemSummary',
@ -155,7 +69,7 @@ export default {
name: 'ItemBotanical',
meta: {
title: 'botanical',
icon: 'local_florist',
icon: 'vn:botanical',
},
component: () => import('src/pages/Item/Card/ItemBotanical.vue'),
},
@ -196,6 +110,138 @@ export default {
component: () => import('src/pages/Item/Card/ItemLog.vue'),
},
],
};
const itemTypeCard = {
name: 'ItemTypeCard',
path: ':id',
component: () => import('src/pages/Item/ItemType/Card/ItemTypeCard.vue'),
redirect: { name: 'ItemTypeSummary' },
meta: {
menu: ['ItemTypeBasicData', 'ItemTypeLog'],
},
children: [
{
path: 'summary',
name: 'ItemTypeSummary',
meta: {
title: 'summary',
icon: 'launch',
},
component: () => import('src/pages/Item/ItemType/Card/ItemTypeSummary.vue'),
},
{
path: 'basic-data',
name: 'ItemTypeBasicData',
meta: {
title: 'basicData',
icon: 'vn:settings',
},
component: () => import('src/pages/Item/ItemType/Card/ItemTypeBasicData.vue'),
},
{
path: 'log',
name: 'ItemTypeLog',
meta: {
title: 'log',
icon: 'vn:History',
},
component: () => import('src/pages/Item/ItemType/Card/ItemTypeLog.vue'),
},
],
};
export default {
name: 'Item',
path: '/item',
meta: {
title: 'items',
icon: 'vn:item',
moduleName: 'Item',
keyBinding: 'a',
menu: [
'ItemList',
'WasteBreakdown',
'ItemFixedPrice',
'ItemRequest',
'ItemTypeList',
],
},
component: RouterView,
redirect: { name: 'ItemMain' },
children: [
{
name: 'ItemMain',
path: '',
component: () => import('src/components/common/VnModule.vue'),
redirect: { name: 'ItemIndexMain' },
children: [
{
path: '',
name: 'ItemIndexMain',
redirect: { name: 'ItemList' },
component: () => import('src/pages/Item/ItemList.vue'),
children: [
{
name: 'ItemList',
path: 'list',
meta: {
title: 'list',
icon: 'view_list',
},
},
itemCard,
],
},
{
path: 'request',
name: 'ItemRequest',
meta: {
title: 'buyRequest',
icon: 'vn:buyrequest',
},
component: () => import('src/pages/Item/ItemRequest.vue'),
},
{
path: 'waste-breakdown',
name: 'WasteBreakdown',
meta: {
title: 'wasteBreakdown',
icon: 'vn:claims',
},
beforeEnter: (to, from, next) => {
next({ name: 'ItemList' });
window.location.href =
'https://grafana.verdnatura.es/d/TTNXQAxVk';
},
},
{
path: 'fixed-price',
name: 'ItemFixedPrice',
meta: {
title: 'fixedPrice',
icon: 'vn:fixedPrice',
},
component: () => import('src/pages/Item/ItemFixedPrice.vue'),
},
{
path: 'item-type',
name: 'ItemTypeMain',
redirect: { name: 'ItemTypeList' },
component: () => import('src/pages/Item/ItemTypeList.vue'),
children: [
{
name: 'ItemTypeList',
path: 'list',
meta: {
title: 'family',
icon: 'contact_support',
},
},
itemTypeCard,
],
},
],
},
],
};

View File

@ -1,56 +0,0 @@
import { RouterView } from 'vue-router';
export default {
path: '/item/item-type',
name: 'ItemType',
meta: {
title: 'itemType',
icon: 'contact_support',
moduleName: 'ItemType',
},
component: RouterView,
redirect: { name: 'ItemTypeList' },
menus: {
main: [],
card: ['ItemTypeBasicData', 'ItemTypeLog'],
},
children: [
{
name: 'ItemTypeCard',
path: ':id',
component: () => import('src/pages/Item/ItemType/Card/ItemTypeCard.vue'),
redirect: { name: 'ItemTypeSummary' },
children: [
{
name: 'ItemTypeSummary',
path: 'summary',
meta: {
title: 'summary',
},
component: () =>
import('src/pages/Item/ItemType/Card/ItemTypeSummary.vue'),
},
{
name: 'ItemTypeBasicData',
path: 'basic-data',
meta: {
title: 'basicData',
icon: 'vn:settings',
},
component: () =>
import('src/pages/Item/ItemType/Card/ItemTypeBasicData.vue'),
},
{
path: 'log',
name: 'ItemTypeLog',
meta: {
title: 'log',
icon: 'vn:History',
},
component: () =>
import('src/pages/Item/ItemType/Card/ItemTypeLog.vue'),
},
],
},
],
};

View File

@ -1,54 +0,0 @@
import { RouterView } from 'vue-router';
export default {
path: '/parking',
name: 'Parking',
meta: {
title: 'parking',
icon: 'garage_home',
moduleName: 'Parking',
},
component: RouterView,
redirect: { name: 'ParkingCard' },
menus: {
main: [],
card: ['ParkingBasicData', 'ParkingLog'],
},
children: [
{
path: '/parking/:id',
name: 'ParkingCard',
component: () => import('src/pages/Parking/Card/ParkingCard.vue'),
redirect: { name: 'ParkingSummary' },
children: [
{
name: 'ParkingSummary',
path: 'summary',
meta: {
title: 'summary',
icon: 'view_list',
},
component: () => import('src/pages/Parking/Card/ParkingSummary.vue'),
},
{
name: 'ParkingBasicData',
path: 'basic-data',
meta: {
title: 'basicData',
icon: 'vn:settings',
},
component: () => import('pages/Parking/Card/ParkingBasicData.vue'),
},
{
name: 'ParkingLog',
path: 'log',
meta: {
title: 'log',
icon: 'history',
},
component: () => import('src/pages/Parking/Card/ParkingLog.vue'),
},
],
},
],
};

View File

@ -1,62 +1,45 @@
import { RouterView } from 'vue-router';
export default {
path: '/shelving',
name: 'Shelving',
const parkingCard = {
name: 'ParkingCard',
path: ':id',
component: () => import('src/pages/Parking/Card/ParkingCard.vue'),
redirect: { name: 'ParkingSummary' },
meta: {
title: 'shelving',
icon: 'vn:inventory',
moduleName: 'Shelving',
},
component: RouterView,
redirect: { name: 'ShelvingMain' },
menus: {
main: ['ShelvingList', 'ParkingList'],
card: ['ShelvingBasicData', 'ShelvingLog'],
menu: ['ParkingBasicData', 'ParkingLog'],
},
children: [
{
path: '',
name: 'ShelvingMain',
component: () => import('src/components/common/VnModule.vue'),
redirect: { name: 'ShelvingList' },
children: [
{
path: 'list',
name: 'ShelvingList',
path: 'summary',
name: 'ParkingSummary',
meta: {
title: 'list',
icon: 'view_list',
title: 'summary',
icon: 'launch',
},
component: () => import('src/pages/Shelving/ShelvingList.vue'),
component: () => import('src/pages/Parking/Card/ParkingSummary.vue'),
},
{
path: 'create',
name: 'ShelvingCreate',
path: 'basic-data',
name: 'ParkingBasicData',
meta: {
title: 'shelvingCreate',
icon: 'add',
title: 'basicData',
icon: 'vn:settings',
},
component: () => import('src/pages/Shelving/Card/ShelvingForm.vue'),
component: () => import('src/pages/Parking/Card/ParkingBasicData.vue'),
},
{
path: '/parking',
redirect: { name: 'ParkingList' },
children: [
{
path: 'list',
name: 'ParkingList',
path: 'log',
name: 'ParkingLog',
meta: {
title: 'parkingList',
icon: 'view_list',
title: 'log',
icon: 'history',
},
component: () => import('src/pages/Parking/ParkingList.vue'),
component: () => import('src/pages/Parking/Card/ParkingLog.vue'),
},
],
},
],
},
{
};
const shelvingCard = {
name: 'ShelvingLayout',
path: ':id',
component: () => import('pages/Shelving/Card/ShelvingCard.vue'),
@ -89,6 +72,73 @@ export default {
component: () => import('src/pages/Shelving/Card/ShelvingLog.vue'),
},
],
};
export default {
path: '/shelving',
name: 'Shelving',
meta: {
title: 'shelving',
icon: 'vn:inventory',
moduleName: 'Shelving',
},
component: RouterView,
redirect: { name: 'ShelvingMain' },
menus: {
main: ['ShelvingList', 'ParkingMain'],
card: ['ShelvingBasicData', 'ShelvingLog'],
},
children: [
{
path: '',
name: 'ShelvingMain',
component: () => import('src/components/common/VnModule.vue'),
redirect: { name: 'ShelvingSection' },
children: [
{
path: '',
name: 'ShelvingSection',
redirect: { name: 'ShelvingList' },
component: () => import('src/pages/Shelving/ShelvingList.vue'),
children: [
{
path: 'list',
name: 'ShelvingList',
meta: {
title: 'list',
icon: 'view_list',
},
},
shelvingCard,
],
},
{
path: 'create',
name: 'ShelvingCreate',
meta: {
title: 'shelvingCreate',
icon: 'add',
},
component: () => import('src/pages/Shelving/Card/ShelvingForm.vue'),
},
{
path: 'parking',
name: 'ParkingMain',
redirect: { name: 'ParkingList' },
meta: {
title: 'parkingList',
icon: 'view_list',
},
component: () => import('src/pages/Parking/ParkingList.vue'),
children: [
{
path: 'list',
name: 'ParkingList',
},
parkingCard,
],
},
],
},
],
};

View File

@ -1,60 +1,13 @@
import { RouterView } from 'vue-router';
export default {
path: '/travel',
name: 'Travel',
meta: {
title: 'travel',
icon: 'local_airport',
moduleName: 'Travel',
},
component: RouterView,
redirect: { name: 'TravelMain' },
menus: {
main: ['TravelList', 'ExtraCommunity'],
card: ['TravelBasicData', 'TravelHistory', 'TravelThermographs'],
},
children: [
{
path: '',
name: 'TravelMain',
component: () => import('src/components/common/VnModule.vue'),
redirect: { name: 'TravelList' },
children: [
{
path: 'list',
name: 'TravelList',
meta: {
title: 'list',
icon: 'view_list',
},
component: () => import('src/pages/Travel/TravelList.vue'),
},
{
path: 'extra-community',
name: 'ExtraCommunity',
meta: {
title: 'extraCommunity',
icon: 'vn:shipment',
},
component: () => import('src/pages/Travel/ExtraCommunity.vue'),
},
{
path: 'create',
name: 'TravelCreate',
meta: {
title: 'travelCreate',
icon: 'add',
},
component: () => import('src/pages/Travel/TravelCreate.vue'),
},
],
},
{
const travelCard = {
name: 'TravelCard',
path: ':id',
component: () => import('src/pages/Travel/Card/TravelCard.vue'),
redirect: { name: 'TravelSummary' },
meta: {
menu: ['TravelBasicData', 'TravelHistory', 'TravelThermographs'],
},
children: [
{
name: 'TravelSummary',
@ -119,6 +72,62 @@ export default {
},
],
},
]
};
export default {
path: '/travel',
name: 'Travel',
meta: {
title: 'travel',
icon: 'local_airport',
moduleName: 'Travel',
menu: ['TravelList', 'ExtraCommunity'],
},
component: RouterView,
redirect: { name: 'TravelMain' },
children: [
{
path: '',
name: 'TravelMain',
component: () => import('src/components/common/VnModule.vue'),
redirect: { name: 'TravelIndexMain' },
children: [
{
path: '',
name: 'TravelIndexMain',
redirect: { name: 'TravelList' },
component: () => import('src/pages/Travel/TravelList.vue'),
children: [
{
name: 'TravelList',
path: 'list',
meta: {
title: 'list',
icon: 'view_list',
},
},
travelCard,
],
},
{
path: 'extra-community',
name: 'ExtraCommunity',
meta: {
title: 'extraCommunity',
icon: 'vn:shipment',
},
component: () => import('src/pages/Travel/ExtraCommunity.vue'),
},
{
path: 'create',
name: 'TravelCreate',
meta: {
title: 'travelCreate',
icon: 'add',
},
component: () => import('src/pages/Travel/TravelCreate.vue'),
},
],
},
],

View File

@ -9,12 +9,10 @@ import invoiceIn from './modules/invoiceIn';
import wagon from './modules/wagon';
import supplier from './modules/supplier';
import travel from './modules/travel';
import ItemType from './modules/itemType';
import shelving from 'src/router/modules/shelving';
import order from 'src/router/modules/order';
import entry from 'src/router/modules/entry';
import roadmap from 'src/router/modules/roadmap';
import parking from 'src/router/modules/parking';
import agency from 'src/router/modules/agency';
import zone from 'src/router/modules/zone';
import account from './modules/account';
@ -86,9 +84,7 @@ const routes = [
travel,
roadmap,
entry,
parking,
agency,
ItemType,
zone,
account,
{

View File

@ -15,7 +15,7 @@ describe('Client list', () => {
});
});
it.skip('Client list create new client', () => {
it('Client list create new client', () => {
cy.addBtnClick();
const randomInt = Math.floor(Math.random() * 90) + 10;

View File

@ -1,5 +1,6 @@
/// <reference types="cypress" />
describe('Client unpaid', () => {
const UnpaidCheckBox = '[data-cy="UnpaidCheckBox"]';
beforeEach(() => {
cy.viewport(1280, 720);
cy.login('developer');
@ -7,7 +8,7 @@ describe('Client unpaid', () => {
it('Should add unpaid', () => {
cy.visit('#/customer/1102/others/unpaid');
cy.get('.q-card').should('be.visible');
cy.get('.q-checkbox__inner').click();
cy.get(UnpaidCheckBox).click();
cy.dataCy('customerUnpaidAmount').find('input').type('100');
cy.dataCy('customerUnpaidDate').find('input').type('01/01/2001');
cy.get('.q-btn-group > .q-btn--standard').click();