-
-
-
-
- #{{ scope.opt?.id }}
- {{ scope.opt?.nickname }}
-
-
-
-
-
O
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{{ scope.opt?.id }} -
+ {{ scope.opt?.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ `${
+ !scope.opt?.isActive
+ ? t('inactive')
+ : ''
+ } `
+ }}
+ {{
+ scope.opt?.nickname
+ }}
+
+ , {{ scope.opt?.street }},
+ {{ scope.opt?.city }},
+ {{
+ scope.opt?.province?.name
+ }}
+ -
+ {{
+ scope.opt?.agencyMode
+ ?.name
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.opt?.code }} -
+ {{ scope.opt?.description }}
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
-en:
- searchInvoice: Search issued invoice
- fileDenied: Browser denied file download...
- fileAllowed: Successful download of CSV file
- youCanSearchByInvoiceReference: You can search by invoice reference
- createInvoice: Make invoice
- Create manual invoice: Create manual invoice
-es:
- searchInvoice: Buscar factura emitida
- fileDenied: El navegador denegó la descarga de archivos...
- fileAllowed: Descarga exitosa de archivo CSV
- youCanSearchByInvoiceReference: Puedes buscar por referencia de la factura
- createInvoice: Crear factura
- Create manual invoice: Crear factura manual
+ en:
+ invoiceId: Invoice ID
+ youCanSearchByInvoiceReference: You can search by invoice reference
+ createManualInvoice: Create Manual Invoice
+ inactive: (Inactive)
+
+ es:
+ invoiceId: ID de factura
+ youCanSearchByInvoiceReference: Puedes buscar por referencia de la factura
+ createManualInvoice: Crear factura manual
+ inactive: (Inactivo)
diff --git a/src/pages/InvoiceOut/locale/en.yml b/src/pages/InvoiceOut/locale/en.yml
index 5ad92ed09..8cefe8bdc 100644
--- a/src/pages/InvoiceOut/locale/en.yml
+++ b/src/pages/InvoiceOut/locale/en.yml
@@ -2,6 +2,7 @@ invoiceOutModule:
customer: Client
amount: Amount
company: Company
+ address: Address
invoiceOutList:
tableVisibleColumns:
id: ID
@@ -15,11 +16,11 @@ invoiceOutList:
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
\ No newline at end of file
+ country: Country
+ clientId: Client ID
+ base: Base
+ ticketId: Ticket
+ active: Active
+ hasToInvoice: Has to invoice
+ verifiedData: Verified data
+ commercial: Commercial
diff --git a/src/pages/InvoiceOut/locale/es.yml b/src/pages/InvoiceOut/locale/es.yml
index feb9050fa..106168a5d 100644
--- a/src/pages/InvoiceOut/locale/es.yml
+++ b/src/pages/InvoiceOut/locale/es.yml
@@ -4,6 +4,7 @@ invoiceOutModule:
customer: Cliente
amount: Importe
company: Empresa
+ address: Consignatario
invoiceOutList:
tableVisibleColumns:
id: ID
diff --git a/src/pages/Monitor/Ticket/MonitorTickets.vue b/src/pages/Monitor/Ticket/MonitorTickets.vue
index 253316a09..e5fea3003 100644
--- a/src/pages/Monitor/Ticket/MonitorTickets.vue
+++ b/src/pages/Monitor/Ticket/MonitorTickets.vue
@@ -15,6 +15,7 @@ import { toCurrency, dateRange, dashIfEmpty } from 'src/filters';
import RightMenu from 'src/components/common/RightMenu.vue';
import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue';
import MonitorTicketFilter from './MonitorTicketFilter.vue';
+import TicketProblems from 'src/components/TicketProblems.vue';
const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000; // 2min in ms
const { t } = useI18n();
@@ -23,9 +24,15 @@ const tableRef = ref(null);
const provinceOpts = ref([]);
const stateOpts = ref([]);
const zoneOpts = ref([]);
-const visibleColumns = ref([]);
const { viewSummary } = useSummaryDialog();
+
const [from, to] = dateRange(Date.vnNew());
+const stateColors = {
+ notice: 'info',
+ success: 'positive',
+ warning: 'warning',
+ alert: 'negative',
+};
function exprBuilder(param, value) {
switch (param) {
@@ -220,7 +227,7 @@ const columns = computed(() => [
{
title: t('salesTicketsTable.goToLines'),
icon: 'vn:lines',
- color: 'priamry',
+ color: 'primary',
action: (row) => openTab(row.id),
isPrimary: true,
attrs: {
@@ -231,7 +238,7 @@ const columns = computed(() => [
{
title: t('salesTicketsTable.preview'),
icon: 'preview',
- color: 'priamry',
+ color: 'primary',
action: (row) => viewSummary(row.id, TicketSummary),
isPrimary: true,
attrs: {
@@ -249,10 +256,10 @@ const getBadgeAttrs = (date) => {
let timeTicket = new Date(date);
timeTicket.setHours(0, 0, 0, 0);
- let comparation = today - timeTicket;
+ let timeDiff = today - timeTicket;
- if (comparation == 0) return { color: 'warning', 'text-color': 'black' };
- if (comparation < 0) return { color: 'success', 'text-color': 'black' };
+ if (timeDiff == 0) return { color: 'warning', 'text-color': 'black' };
+ if (timeDiff < 0) return { color: 'success', 'text-color': 'black' };
return { color: 'transparent', 'text-color': 'white' };
};
@@ -267,13 +274,6 @@ const autoRefreshHandler = (value) => {
}
};
-const stateColors = {
- notice: 'info',
- success: 'positive',
- warning: 'warning',
- alert: 'negative',
-};
-
const totalPriceColor = (ticket) => {
const total = parseInt(ticket.totalWithVat);
if (total > 0 && total < 50) return 'warning';
@@ -281,10 +281,10 @@ const totalPriceColor = (ticket) => {
const formatShippedDate = (date) => {
if (!date) return '-';
- const split1 = date.split('T');
- const [year, month, day] = split1[0].split('-');
- const _date = new Date(year, month - 1, day);
- return toDateFormat(_date);
+ const dateSplit = date.split('T');
+ const [year, month, day] = dateSplit[0].split('-');
+ const newDate = new Date(year, month - 1, day);
+ return toDateFormat(newDate);
};
const openTab = (id) =>
@@ -332,7 +332,6 @@ const openTab = (id) =>
:expr-builder="exprBuilder"
:offset="50"
:columns="columns"
- :visible-columns="visibleColumns"
:right-search="false"
default-mode="table"
auto-load
@@ -362,61 +361,7 @@ const openTab = (id) =>
-
-
- {{ $t('salesTicketsTable.noVerifiedData') }}
-
-
- {{ $t('salesTicketsTable.purchaseRequest') }}
-
-
- {{ $t('salesTicketsTable.notVisible') }}
-
-
- {{ $t('salesTicketsTable.clientFrozen') }}
-
-
- {{ $t('salesTicketsTable.risk') }}: {{ row.risk }}
-
-
- {{ $t('salesTicketsTable.componentLack') }}
-
-
- {{ $t('salesTicketsTable.tooLittle') }}
-
-
+
@@ -471,7 +416,7 @@ const openTab = (id) =>
-
+
{{ row.zoneName }}
diff --git a/src/pages/Order/Card/CatalogFilterValueDialog.vue b/src/pages/Order/Card/CatalogFilterValueDialog.vue
index 53bb87f8d..b91e7d229 100644
--- a/src/pages/Order/Card/CatalogFilterValueDialog.vue
+++ b/src/pages/Order/Card/CatalogFilterValueDialog.vue
@@ -49,7 +49,7 @@ const getSelectedTagValues = async (tag) => {
-
+
{
:emit-value="false"
use-input
@update:model-value="getSelectedTagValues"
+ data-cy="catalogFilterValueDialogTagSelect"
/>
{
:disable="!value"
is-outlined
class="col"
+ data-cy="catalogFilterValueDialogValueInput"
/>
-
+
diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue
index 6202a6f90..1dd569fb5 100644
--- a/src/pages/Order/Card/OrderCatalogFilter.vue
+++ b/src/pages/Order/Card/OrderCatalogFilter.vue
@@ -178,6 +178,7 @@ function addOrder(value, field, params) {
? resetCategory(params, searchFn)
: removeTagGroupParam(params, searchFn, valIndex)
"
+ data-cy="catalogFilterCustomTag"
>
{{
@@ -211,6 +212,7 @@ function addOrder(value, field, params) {
:name="category.icon"
class="category-icon"
@click="selectCategory(params, category, searchFn)"
+ data-cy="catalogFilterCategory"
>
{{ t(category.name) }}
@@ -234,6 +236,7 @@ function addOrder(value, field, params) {
sort-by="name ASC"
:disable="!params.categoryFk"
@update:model-value="searchFn()"
+ data-cy="catalogFilterType"
>
@@ -285,6 +288,7 @@ function addOrder(value, field, params) {
:is-clearable="false"
v-model="searchByTag"
@keyup.enter="(val) => onSearchByTag(val, params)"
+ data-cy="catalogFilterValueInput"
>
@@ -297,6 +301,7 @@ function addOrder(value, field, params) {
color="primary"
size="md"
dense
+ data-cy="catalogFilterValueDialogBtn"
/>
import { useRouter } from 'vue-router';
-import { onMounted, ref } from 'vue';
+import { reactive, onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import { useState } from 'composables/useState';
@@ -9,7 +9,6 @@ import VnRow from 'components/ui/VnRow.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import { useDialogPluginComponent } from 'quasar';
-import { reactive } from 'vue';
const { t } = useI18n();
const state = useState();
@@ -48,10 +47,6 @@ const fetchAgencyList = async (landed, addressFk) => {
agencyList.value = data;
};
-// const fetchOrderDetails = (order) => {
-// fetchAddressList(order?.addressFk);
-// fetchAgencyList(order?.landed, order?.addressFk);
-// };
const $props = defineProps({
clientFk: {
type: Number,
@@ -63,39 +58,6 @@ const initialFormState = reactive({
addressId: null,
clientFk: $props.clientFk,
});
-// const orderMapper = (order) => {
-// return {
-// addressId: order.addressFk,
-// agencyModeId: order.agencyModeFk,
-// landed: new Date(order.landed).toISOString(),
-// };
-// };
-// const orderFilter = {
-// include: [
-// { relation: 'agencyMode', scope: { fields: ['name'] } },
-// {
-// relation: 'address',
-// scope: { fields: ['nickname'] },
-// },
-// { relation: 'rows', scope: { fields: ['id'] } },
-// {
-// relation: 'client',
-// scope: {
-// fields: [
-// 'salesPersonFk',
-// 'name',
-// 'isActive',
-// 'isFreezed',
-// 'isTaxDataChecked',
-// ],
-// include: {
-// relation: 'salesPersonUser',
-// scope: { fields: ['id', 'name'] },
-// },
-// },
-// },
-// ],
-// };
const onClientChange = async (clientId = $props.clientFk) => {
const { data } = await axios.get(`Clients/${clientId}`);
diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue
index 547842960..1a79be8bc 100644
--- a/src/pages/Supplier/Card/SupplierFiscalData.vue
+++ b/src/pages/Supplier/Card/SupplierFiscalData.vue
@@ -9,6 +9,7 @@ import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnLocation from 'src/components/common/VnLocation.vue';
+import VnAccountNumber from 'src/components/common/VnAccountNumber.vue';
const route = useRoute();
const { t } = useI18n();
@@ -100,10 +101,13 @@ function handleLocation(data, location) {
/>
-
{{ entity.ticketState.state.name }}
@@ -174,7 +175,7 @@ function ticketFilter(ticket) {
{{ t('Client Frozen') }}
{
dense
style="width: 50%"
@click="save()"
+ data-cy="saveManaBtn"
>
{{ t('globals.save') }}
diff --git a/src/pages/Ticket/Card/TicketNotes.vue b/src/pages/Ticket/Card/TicketNotes.vue
index 6861cf000..f558b71cc 100644
--- a/src/pages/Ticket/Card/TicketNotes.vue
+++ b/src/pages/Ticket/Card/TicketNotes.vue
@@ -80,12 +80,14 @@ async function handleSave() {
option-value="id"
v-model="row.observationTypeFk"
:disable="!!row.id"
+ data-cy="ticketNotesObservationType"
/>
{{ t('ticketNotes.removeNote') }}
@@ -107,6 +110,7 @@ async function handleSave() {
class="fill-icon-on-hover q-ml-md"
color="primary"
@click="ticketNotesCrudRef.insert()"
+ data-cy="ticketNotesAddNoteBtn"
>
{{ t('ticketNotes.addNote') }}
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index ff428c72c..19cfdee2c 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -555,6 +555,7 @@ watch(
color="primary"
:disable="!isTicketEditable || ticketState === 'OK'"
@click="changeTicketState('OK')"
+ data-cy="ticketSaleOkStateBtn"
>
{{ t(`Change ticket state to 'Ok'`) }}
@@ -563,6 +564,7 @@ watch(
color="primary"
:label="t('ticketList.state')"
:disable="!isTicketEditable"
+ data-cy="ticketSaleStateDropdown"
>
{{ t('Transfer lines') }}
-
+
{{ t('ticketSale.reserved') }}
@@ -832,7 +842,14 @@ watch(
-
+
{{ t('Add item to basket') }}
diff --git a/src/pages/Ticket/Card/TicketSaleMoreActions.vue b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
index 2dafd8512..4cc96e9e2 100644
--- a/src/pages/Ticket/Card/TicketSaleMoreActions.vue
+++ b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
@@ -177,6 +177,7 @@ const createRefund = async (withWarehouse) => {
color="primary"
:label="t('ticketSale.more')"
:disable="disable"
+ data-cy="ticketSaleMoreActionsDropdown"
>
{{ t('Select lines to see the options') }}
@@ -188,6 +189,7 @@ const createRefund = async (withWarehouse) => {
v-close-popup
v-ripple
@click="showSmsDialog('productNotAvailable')"
+ data-cy="sendShortageSMSItem"
>
{{ t('Send shortage SMS') }}
@@ -199,12 +201,18 @@ const createRefund = async (withWarehouse) => {
v-close-popup
v-ripple
@click="calculateSalePrice()"
+ data-cy="recalculatePriceItem"
>
{{ t('Recalculate price') }}
-
+
{{ t('Update discount') }}
@@ -213,6 +221,7 @@ const createRefund = async (withWarehouse) => {
v-model.number="newDiscount"
:label="t('ticketSale.discount')"
type="number"
+ data-cy="ticketSaleDiscountInput"
/>
@@ -222,6 +231,7 @@ const createRefund = async (withWarehouse) => {
v-close-popup
v-ripple
@click="createClaim()"
+ data-cy="createClaimItem"
>
{{ t('Add claim') }}
@@ -233,6 +243,7 @@ const createRefund = async (withWarehouse) => {
v-close-popup
v-ripple
@click="setReserved(true)"
+ data-cy="markAsReservedItem"
>
{{ t('Mark as reserved') }}
@@ -244,12 +255,13 @@ const createRefund = async (withWarehouse) => {
v-close-popup
v-ripple
@click="setReserved(false)"
+ data-cy="unmarkAsReservedItem"
>
{{ t('Unmark as reserved') }}
-
+
{{ t('Refund') }}
@@ -258,12 +270,22 @@ const createRefund = async (withWarehouse) => {
-
+
{{ t('with warehouse') }}
-
+
{{ t('without warehouse') }}
diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue
index 5bda60cba..2f5f69e1c 100644
--- a/src/pages/Ticket/Card/TicketSummary.vue
+++ b/src/pages/Ticket/Card/TicketSummary.vue
@@ -96,6 +96,7 @@ function toTicketUrl(section) {
ref="summaryRef"
:url="`Tickets/${entityId}/summary`"
data-key="TicketSummary"
+ data-cy="ticketSummary"
>
(_transfer.value = $props.transfer));
-
+
@@ -72,6 +74,7 @@ defineExpose({ transferSales });
color="primary"
class="full-width q-my-lg"
@click="transferSales()"
+ data-cy="ticketTransferNewTicketBtn"
/>
diff --git a/src/pages/Ticket/TicketAdvance.vue b/src/pages/Ticket/TicketAdvance.vue
index 8de602b37..71e3926ac 100644
--- a/src/pages/Ticket/TicketAdvance.vue
+++ b/src/pages/Ticket/TicketAdvance.vue
@@ -215,7 +215,7 @@ const requestComponentUpdate = async (ticket, isWithoutNegatives) => {
if (!newLanded) {
notify(t('advanceTickets.noDeliveryZone'), 'negative');
- return;
+ throw new Error(t('advanceTickets.noDeliveryZone'));
}
ticket.landed = newLanded.landed;
@@ -299,10 +299,10 @@ const splitTickets = async () => {
const { query, params } = await requestComponentUpdate(ticket, true);
await axios.post(query, params);
progressAdd(ticket.futureId);
- } catch (error) {
+ } catch (e) {
splitErrors.value.push({
id: ticket.futureId,
- reason: error.response?.data?.error?.message,
+ reason: e.message || e.response?.data?.error?.message,
});
progressAdd(ticket.futureId);
}
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index 6f6c556ca..2fe4fcddc 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -22,6 +22,7 @@ import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorP
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import { toTimeFormat } from 'src/filters/date';
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
+import TicketProblems from 'src/components/TicketProblems.vue';
const route = useRoute();
const router = useRouter();
@@ -455,6 +456,7 @@ function setReference(data) {
data-key="TicketList"
:label="t('Search ticket')"
:info="t('You can search by ticket id or alias')"
+ data-cy="ticketListSearchBar"
/>
@@ -482,68 +484,10 @@ function setReference(data) {
'row-key': 'id',
selection: 'multiple',
}"
+ data-cy="ticketListTable"
>
-
-
-
- {{ t('No verified data') }}
-
-
-
-
- {{ t('Purchase request') }}
-
-
-
-
- {{ t('Not visible') }}
-
-
-
-
- {{ t('Client frozen') }}
-
-
-
- {{ t('Risk') }}: {{ row.risk }}
-
-
-
- {{ t('Component lack') }}
-
-
-
-
- {{ t('Rounding') }}
-
-
-
+
diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue
index f4331ccb2..be1a12406 100644
--- a/src/pages/Travel/Card/TravelSummary.vue
+++ b/src/pages/Travel/Card/TravelSummary.vue
@@ -300,10 +300,6 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
-
diff --git a/src/pages/Worker/Card/WorkerPit.vue b/src/pages/Worker/Card/WorkerPit.vue
new file mode 100644
index 000000000..c58196c7b
--- /dev/null
+++ b/src/pages/Worker/Card/WorkerPit.vue
@@ -0,0 +1,263 @@
+
+
+
+ (disabilityGradesOptions = data)"
+ auto-load
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+es:
+ familySituation: Situación familiar
+ disabilityGrades: Discapacidad
+ geographicMobilityDate: Movilidad geografica
+ childPension: Pensión hijos
+ spousePension: Pensión cónyuge
+ isDependend: Ayuda / Movilidad reducida
+ spouseNif: NIF cónyuge
+ hasHousingPaymentBefore: Pagos vivienda anterior 2011
+ hasHousingPaymentAfter: Pagos vivienda posterior 2011
+ hasExtendedWorking: Prolongación actividad laboral
+ isDescendant: Descen/Ascen
+ disabilityGradeFk: Discapacidad
+ birthed: Año nacimiento
+ adoptionYear: Año adopción
+ isJointCustody: Computo por entero
+ Relatives: Relacionados
+en:
+ familySituation: Family Situation
+ disabilityGrades: Disability Grades
+ geographicMobilityDate: Geographic Mobility Date
+ childPension: Child Pension
+ spousePension: Spouse Pension
+ isDependend: Dependent Suport / Reduced Mobility
+ spouseNif: Spouse NIF (Tax ID)
+ hasHousingPaymentBefore: Housing Payments Before 2011
+ hasHousingPaymentAfter: Housing Payments After 2011
+ hasExtendedWorking: Extended Work Activity
+ isDescendant: Descendant/Ascendant
+ disabilityGradeFk: Disability Grade
+ birthed: Birth Year
+ adoptionYear: Adoption Year
+ isJointCustody: Joint custody
+ Relatives: Relatives
+
diff --git a/src/router/modules/Supplier.js b/src/router/modules/Supplier.js
index 143d7c824..c08fb5961 100644
--- a/src/router/modules/Supplier.js
+++ b/src/router/modules/Supplier.js
@@ -113,7 +113,7 @@ export default {
name: 'SupplierAccounts',
meta: {
title: 'accounts',
- icon: 'vn:account',
+ icon: 'vn:credit',
},
component: () =>
import('src/pages/Supplier/Card/SupplierAccounts.vue'),
diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js
index d1feff23d..925019734 100644
--- a/src/router/modules/worker.js
+++ b/src/router/modules/worker.js
@@ -24,6 +24,7 @@ export default {
'WorkerDms',
'WorkerTimeControl',
'WorkerLocker',
+ 'WorkerPit',
'WorkerBalance',
'WorkerFormation',
'WorkerMedical',
@@ -216,6 +217,15 @@ export default {
},
component: () => import('src/pages/Worker/Card/WorkerMedical.vue'),
},
+ {
+ name: 'WorkerPit',
+ path: 'pit',
+ meta: {
+ title: 'pit',
+ icon: 'lock',
+ },
+ component: () => import('src/pages/Worker/Card/WorkerPit.vue'),
+ },
{
name: 'WorkerOperator',
path: 'operator',
diff --git a/src/stores/invoiceOutGlobal.js b/src/stores/invoiceOutGlobal.js
index 35f834f3d..332494aa8 100644
--- a/src/stores/invoiceOutGlobal.js
+++ b/src/stores/invoiceOutGlobal.js
@@ -162,6 +162,15 @@ export const useInvoiceOutGlobalStore = defineStore({
);
throw new Error('Invalid Serial Type');
}
+
+ if (clientsToInvoice === 'all' && params.serialType !== 'global') {
+ notify(
+ 'invoiceOut.globalInvoices.errors.invalidSerialTypeForAll',
+ 'negative'
+ );
+ throw new Error('For "all" clients, the serialType must be "global"');
+ }
+
if (!params.companyFk) {
notify('invoiceOut.globalInvoices.errors.chooseValidCompany', 'negative');
throw new Error('Invalid company');
diff --git a/test/cypress/integration/Order/orderCatalog.spec.js b/test/cypress/integration/Order/orderCatalog.spec.js
new file mode 100644
index 000000000..45eda6f1f
--- /dev/null
+++ b/test/cypress/integration/Order/orderCatalog.spec.js
@@ -0,0 +1,112 @@
+///
+describe('OrderCatalog', () => {
+ beforeEach(() => {
+ cy.login('developer');
+ cy.viewport(1920, 720);
+ cy.visit('/#/order/8/catalog');
+ });
+
+ const checkCustomFilterTag = (filterName = 'Plant') => {
+ cy.dataCy('catalogFilterCustomTag').should('exist');
+ cy.dataCy('catalogFilterCustomTag').contains(filterName);
+ };
+
+ const checkFilterTag = (filterName = 'Plant') => {
+ cy.dataCy('vnFilterPanelChip').should('exist');
+ cy.dataCy('vnFilterPanelChip').contains(filterName);
+ };
+
+ const selectCategory = (categoryIndex = 1, categoryName = 'Plant') => {
+ cy.get(
+ `div.q-page-container div:nth-of-type(${categoryIndex}) > [data-cy='catalogFilterCategory']`
+ ).should('exist');
+ cy.get(
+ `div.q-page-container div:nth-of-type(${categoryIndex}) > [data-cy='catalogFilterCategory']`
+ ).click();
+ checkCustomFilterTag(categoryName);
+ };
+
+ const searchByCustomTagInput = (option) => {
+ cy.dataCy('catalogFilterValueInput').find('input').last().focus();
+ cy.dataCy('catalogFilterValueInput').find('input').last().type(option);
+ cy.dataCy('catalogFilterValueInput').find('input').last().type('{enter}');
+ checkCustomFilterTag(option);
+ };
+
+ const selectTypeFilter = (option) => {
+ cy.selectOption(
+ 'div.q-page-container div.list > div:nth-of-type(2) div:nth-of-type(3)',
+ option
+ );
+ checkFilterTag(option);
+ };
+
+ it('Shows empty state', () => {
+ cy.dataCy('orderCatalogPage').should('exist');
+ cy.dataCy('orderCatalogPage').contains('No data to display');
+ });
+
+ it('filter by category', () => {
+ selectCategory();
+ cy.dataCy('orderCatalogItem').should('exist');
+ });
+
+ it('filters by type', () => {
+ selectCategory();
+ selectTypeFilter('Anthurium');
+ });
+
+ it('filters by custom value select', () => {
+ selectCategory();
+ searchByCustomTagInput('Silver');
+ });
+
+ it('filters by custom value dialog', () => {
+ Cypress.on('uncaught:exception', (err) => {
+ if (err.message.includes('canceled')) {
+ return false;
+ }
+ });
+ selectCategory();
+ cy.dataCy('catalogFilterValueDialogBtn').should('exist');
+ cy.dataCy('catalogFilterValueDialogBtn').last().click();
+ cy.dataCy('catalogFilterValueDialogTagSelect').should('exist');
+ cy.selectOption("[data-cy='catalogFilterValueDialogTagSelect']", 'Tallos');
+ cy.dataCy('catalogFilterValueDialogValueInput').find('input').focus();
+ cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('2');
+ cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('{enter}');
+ checkCustomFilterTag('2');
+ });
+
+ it('removes a secondary tag', () => {
+ selectCategory();
+ selectTypeFilter('Anthurium');
+ cy.dataCy('vnFilterPanelChip').should('exist');
+ cy.get(
+ "div.q-page-container [data-cy='vnFilterPanelChip'] > i.q-chip__icon--remove"
+ )
+ .contains('cancel')
+ .should('exist');
+ cy.get(
+ "div.q-page-container [data-cy='vnFilterPanelChip'] > i.q-chip__icon--remove"
+ )
+ .contains('cancel')
+ .click();
+ cy.dataCy('vnFilterPanelChip').should('not.exist');
+ });
+
+ it('Removes category tag', () => {
+ selectCategory();
+ cy.get(
+ "div.q-page-container [data-cy='catalogFilterCustomTag'] > i.q-chip__icon--remove"
+ )
+ .contains('cancel')
+ .should('exist');
+ cy.get(
+ "div.q-page-container [data-cy='catalogFilterCustomTag'] > i.q-chip__icon--remove"
+ )
+ .contains('cancel')
+ .click();
+ cy.dataCy('catalogFilterCustomTag').should('not.exist');
+ });
+});
diff --git a/test/cypress/integration/client/clientBasicData.spec.js b/test/cypress/integration/client/clientBasicData.spec.js
index efaad33c2..bed28dc22 100644
--- a/test/cypress/integration/client/clientBasicData.spec.js
+++ b/test/cypress/integration/client/clientBasicData.spec.js
@@ -7,8 +7,8 @@ describe('Client basic data', () => {
});
it('Should load layout', () => {
cy.get('.q-card').should('be.visible');
- cy.dataCy('customerPhone').filter('input').should('be.visible');
- cy.dataCy('customerPhone').filter('input').type('123456789');
+ cy.dataCy('customerPhone').find('input').should('be.visible');
+ cy.dataCy('customerPhone').find('input').type('123456789');
cy.get('.q-btn-group > .q-btn--standard').click();
cy.intercept('PATCH', '/api/Clients/1102', (req) => {
const { body } = req;
diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js
index e89b5fc77..ce07deb16 100644
--- a/test/cypress/integration/client/clientList.spec.js
+++ b/test/cypress/integration/client/clientList.spec.js
@@ -22,10 +22,10 @@ describe('Client list', () => {
const data = {
Name: { val: `Name ${randomInt}` },
'Social name': { val: `TEST ${randomInt}` },
- 'Tax number': { val: `20852${randomInt.length}3Z` },
+ 'Tax number': { val: `20852${randomInt}3Z` },
'Web user': { val: `user_test_${randomInt}` },
Street: { val: `C/ STREET ${randomInt}` },
- Email: { val: 'user.test@1.com' },
+ Email: { val: `user.test${randomInt}@cypress.com` },
'Sales person': { val: 'employee', type: 'select' },
Location: { val: '46000, Valencia(Province one), España', type: 'select' },
'Business type': { val: 'Otros', type: 'select' },
@@ -34,7 +34,7 @@ describe('Client list', () => {
cy.get('.q-mt-lg > .q-btn--standard').click();
- cy.checkNotification('Data saved');
+ cy.checkNotification('Data created');
cy.url().should('include', '/summary');
});
it('Client list search client', () => {
diff --git a/test/cypress/integration/ticket/ticketList.spec.js b/test/cypress/integration/ticket/ticketList.spec.js
new file mode 100644
index 000000000..c1d1a0655
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketList.spec.js
@@ -0,0 +1,55 @@
+///
+describe('TicketList', () => {
+ const firstRow = 'tbody > :nth-child(1)';
+
+ beforeEach(() => {
+ cy.login('developer');
+ cy.viewport(1920, 1080);
+ cy.visit('/#/ticket/list');
+ });
+
+ const searchResults = (search) => {
+ cy.dataCy('vnSearchBar').find('input').focus();
+ if (search) cy.dataCy('vnSearchBar').find('input').type(search);
+ cy.dataCy('vnSearchBar').find('input').type('{enter}');
+ cy.dataCy('ticketListTable').should('exist');
+ cy.get(firstRow).should('exist');
+ };
+
+ it('should search results', () => {
+ cy.dataCy('ticketListTable').should('not.exist');
+ cy.get('.q-field__control').should('exist');
+ searchResults();
+ });
+
+ it('should open ticket sales', () => {
+ searchResults();
+ cy.window().then((win) => {
+ cy.stub(win, 'open').as('windowOpen');
+ });
+ cy.get(firstRow).find('.q-btn:first').click();
+ cy.get('@windowOpen').should('be.calledWithMatch', /\/ticket\/\d+\/sale/);
+ });
+
+ it('should open ticket summary', () => {
+ searchResults();
+ cy.get(firstRow).find('.q-btn:last').click();
+ cy.dataCy('ticketSummary').should('exist');
+ });
+
+ it.only('Client list create new client', () => {
+ cy.dataCy('vnTableCreateBtn').should('exist');
+ cy.dataCy('vnTableCreateBtn').click();
+ const data = {
+ Customer: { val: 1, type: 'select' },
+ Warehouse: { val: 'Warehouse One', type: 'select' },
+ Address: { val: 'employee', type: 'select' },
+ Landed: { val: '01-01-2024', type: 'date' },
+ };
+ cy.fillInForm(data);
+ cy.dataCy('Agency_select').click();
+ cy.dataCy('FormModelPopup_save').click();
+ cy.checkNotification('Data created');
+ cy.url().should('match', /\/ticket\/\d+\/summary/);
+ });
+});
diff --git a/test/cypress/integration/ticket/ticketNotes.spec.js b/test/cypress/integration/ticket/ticketNotes.spec.js
new file mode 100644
index 000000000..ef196c783
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketNotes.spec.js
@@ -0,0 +1,25 @@
+///
+describe('TicketRequest', () => {
+ beforeEach(() => {
+ cy.login('developer');
+ cy.viewport(1920, 1080);
+ cy.visit('/#/ticket/31/observation');
+ });
+
+ it('Creates and deletes a note', () => {
+ cy.dataCy('ticketNotesAddNoteBtn').should('exist');
+ cy.dataCy('ticketNotesAddNoteBtn').click();
+ cy.dataCy('ticketNotesObservationType').should('exist');
+ cy.selectOption('[data-cy="ticketNotesObservationType"]:last', 'Weight');
+ cy.dataCy('ticketNotesDescription').should('exist');
+ cy.get('[data-cy="ticketNotesDescription"]:last').type(
+ 'This is a note description'
+ );
+ cy.dataCy('crudModelDefaultSaveBtn').click();
+ cy.checkNotification('Data saved');
+ cy.dataCy('ticketNotesRemoveNoteBtn').should('exist');
+ cy.dataCy('ticketNotesRemoveNoteBtn').click();
+ cy.dataCy('VnConfirm_confirm').click();
+ cy.checkNotification('Data saved');
+ });
+});
diff --git a/test/cypress/integration/ticket/ticketRequest.spec.js b/test/cypress/integration/ticket/ticketRequest.spec.js
new file mode 100644
index 000000000..b9dc509ef
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketRequest.spec.js
@@ -0,0 +1,22 @@
+///
+describe('TicketRequest', () => {
+ beforeEach(() => {
+ cy.login('developer');
+ cy.viewport(1920, 1080);
+ cy.visit('/#/ticket/31/request');
+ });
+
+ it('Creates a new request', () => {
+ cy.dataCy('vnTableCreateBtn').should('exist');
+ cy.dataCy('vnTableCreateBtn').click();
+ const data = {
+ Description: { val: 'Purchase description' },
+ Atender: { val: 'buyerNick', type: 'select' },
+ Quantity: { val: 2 },
+ Price: { val: 123 },
+ };
+ cy.fillInForm(data);
+ cy.get('.q-mt-lg > .q-btn--standard').click();
+ cy.checkNotification('Data created');
+ });
+});
diff --git a/test/cypress/integration/ticket/ticketSale.spec.js b/test/cypress/integration/ticket/ticketSale.spec.js
new file mode 100644
index 000000000..60f31dbf6
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketSale.spec.js
@@ -0,0 +1,131 @@
+///
+
+const c = require('croppie');
+
+describe('TicketSale', () => {
+ beforeEach(() => {
+ cy.login('developer');
+ cy.viewport(1920, 1080);
+ cy.visit('/#/ticket/31/sale');
+ });
+
+ const firstRow = 'tbody > :nth-child(1)';
+
+ const selectFirstRow = () => {
+ cy.waitForElement(firstRow);
+ cy.get(firstRow).find('.q-checkbox__inner').click();
+ };
+
+ it('it should add item to basket', () => {
+ cy.window().then((win) => {
+ cy.stub(win, 'open').as('windowOpen');
+ });
+ cy.dataCy('ticketSaleAddToBasketBtn').should('exist');
+ cy.dataCy('ticketSaleAddToBasketBtn').click();
+ cy.get('@windowOpen').should('be.calledWithMatch', /\/order\/\d+\/catalog/);
+ });
+
+ it('should send SMS', () => {
+ selectFirstRow();
+ cy.dataCy('ticketSaleMoreActionsDropdown').click();
+ cy.waitForElement('[data-cy="sendShortageSMSItem"]');
+ cy.dataCy('sendShortageSMSItem').should('exist');
+ cy.dataCy('sendShortageSMSItem').click();
+ cy.dataCy('vnSmsDialog').should('exist');
+ cy.dataCy('sendSmsBtn').click();
+ cy.checkNotification('SMS sent');
+ });
+
+ it('should recalculate price when "Recalculate price" is clicked', () => {
+ cy.intercept('POST', '**/recalculatePrice').as('recalculatePrice');
+ selectFirstRow();
+ cy.dataCy('ticketSaleMoreActionsDropdown').click();
+ cy.waitForElement('[data-cy="recalculatePriceItem"]');
+ cy.dataCy('recalculatePriceItem').should('exist');
+ cy.dataCy('recalculatePriceItem').click();
+ cy.wait('@recalculatePrice').its('response.statusCode').should('eq', 200);
+ cy.checkNotification('Data saved');
+ });
+
+ it('should update discount when "Update discount" is clicked', () => {
+ selectFirstRow();
+ cy.dataCy('ticketSaleMoreActionsDropdown').click();
+ cy.waitForElement('[data-cy="updateDiscountItem"]');
+ cy.dataCy('updateDiscountItem').should('exist');
+ cy.dataCy('updateDiscountItem').click();
+ cy.waitForElement('[data-cy="ticketSaleDiscountInput"]');
+ cy.dataCy('ticketSaleDiscountInput').find('input').focus();
+ cy.dataCy('ticketSaleDiscountInput').find('input').type('10');
+ cy.dataCy('saveManaBtn').click();
+ cy.waitForElement('.q-notification__message');
+ cy.checkNotification('Data saved');
+ });
+
+ it('adds claim', () => {
+ selectFirstRow();
+ cy.dataCy('ticketSaleMoreActionsDropdown').click();
+ cy.dataCy('createClaimItem').click();
+ cy.dataCy('VnConfirm_confirm').click();
+ cy.url().should('match', /\/claim\/\d+\/basic-data/);
+ // Delete created claim to avoid cluttering the database
+ cy.dataCy('descriptor-more-opts').click();
+ cy.dataCy('deleteClaim').click();
+ cy.dataCy('VnConfirm_confirm').click();
+ cy.checkNotification('Data deleted');
+ });
+
+ it('marks row as reserved', () => {
+ selectFirstRow();
+ cy.dataCy('ticketSaleMoreActionsDropdown').click();
+ cy.waitForElement('[data-cy="markAsReservedItem"]');
+ cy.dataCy('markAsReservedItem').click();
+ cy.dataCy('ticketSaleReservedIcon').should('exist');
+ });
+
+ it('unmarks row as reserved', () => {
+ selectFirstRow();
+ cy.dataCy('ticketSaleMoreActionsDropdown').click();
+ cy.waitForElement('[data-cy="unmarkAsReservedItem"]');
+ cy.dataCy('unmarkAsReservedItem').click();
+ cy.dataCy('ticketSaleReservedIcon').should('not.exist');
+ });
+
+ it('refunds row with warehouse', () => {
+ selectFirstRow();
+ cy.dataCy('ticketSaleMoreActionsDropdown').click();
+ cy.dataCy('ticketSaleRefundItem').click();
+ cy.dataCy('ticketSaleRefundWithWarehouse').click();
+ cy.checkNotification('The following refund ticket have been created');
+ });
+
+ it('refunds row without warehouse', () => {
+ selectFirstRow();
+ cy.dataCy('ticketSaleMoreActionsDropdown').click();
+ cy.dataCy('ticketSaleRefundItem').click();
+ cy.dataCy('ticketSaleRefundWithoutWarehouse').click();
+ cy.checkNotification('The following refund ticket have been created');
+ });
+
+ it('transfers ticket', () => {
+ cy.visit('/#/ticket/32/sale');
+ selectFirstRow();
+ cy.dataCy('ticketSaleTransferBtn').click();
+ cy.dataCy('ticketTransferPopup').should('exist');
+ cy.dataCy('ticketTransferNewTicketBtn').click();
+ // existen 3 elementos "tbody" necesito checkear que el segundo elemento tbody tenga una row sola
+ cy.get('tbody').eq(1).find('tr').should('have.length', 1);
+ selectFirstRow();
+ cy.dataCy('ticketSaleTransferBtn').click();
+ cy.dataCy('ticketTransferPopup').should('exist');
+ cy.dataCy('ticketTransferDestinationTicketInput').find('input').focus();
+ cy.dataCy('ticketTransferDestinationTicketInput').find('input').type('32');
+ cy.dataCy('ticketTransferTransferBtn').click();
+ // checkear que la url contenga /ticket/1000002/sale
+ cy.url().should('match', /\/ticket\/32\/sale/);
+ });
+
+ it('should redirect to ticket logs', () => {
+ cy.get(firstRow).find('.q-btn:last').click();
+ cy.url().should('match', /\/ticket\/31\/log/);
+ });
+});
diff --git a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js b/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
new file mode 100644
index 000000000..000c2151d
--- /dev/null
+++ b/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
@@ -0,0 +1,39 @@
+describe('VnInput Component', () => {
+ beforeEach(() => {
+ cy.login('developer');
+ cy.viewport(1920, 1080);
+ cy.visit('/#/supplier/1/fiscal-data');
+ cy.domContentLoad();
+ });
+
+ it('should replace character at cursor position in insert mode', () => {
+ // Simula escribir en el input
+ cy.dataCy('supplierFiscalDataAccount').clear();
+ cy.dataCy('supplierFiscalDataAccount').type('4100000001');
+ // Coloca el cursor en la posición 0
+ cy.dataCy('supplierFiscalDataAccount').type('{movetostart}');
+ // Escribe un número y verifica que se reemplace correctamente
+ cy.dataCy('supplierFiscalDataAccount').type('999');
+ cy.dataCy('supplierFiscalDataAccount')
+ .should('have.value', '9990000001');
+ });
+
+ it('should replace character at cursor position in insert mode', () => {
+ // Simula escribir en el input
+ cy.dataCy('supplierFiscalDataAccount').clear();
+ cy.dataCy('supplierFiscalDataAccount').type('4100000001');
+ // Coloca el cursor en la posición 0
+ cy.dataCy('supplierFiscalDataAccount').type('{movetostart}');
+ // Escribe un número y verifica que se reemplace correctamente en la posicion incial
+ cy.dataCy('supplierFiscalDataAccount').type('999');
+ cy.dataCy('supplierFiscalDataAccount')
+ .should('have.value', '9990000001');
+ });
+
+ it('should respect maxlength prop', () => {
+ cy.dataCy('supplierFiscalDataAccount').clear();
+ cy.dataCy('supplierFiscalDataAccount').type('123456789012345');
+ cy.dataCy('supplierFiscalDataAccount')
+ .should('have.value', '1234567890'); // asumiendo que maxlength es 10
+ });
+});
diff --git a/test/cypress/integration/vnComponent/vnBreadcrumbs.spec.js b/test/cypress/integration/vnComponent/VnBreadcrumbs.spec.js
similarity index 100%
rename from test/cypress/integration/vnComponent/vnBreadcrumbs.spec.js
rename to test/cypress/integration/vnComponent/VnBreadcrumbs.spec.js
diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/VnLocation.spec.js
similarity index 69%
rename from test/cypress/integration/vnComponent/vnLocation.spec.js
rename to test/cypress/integration/vnComponent/VnLocation.spec.js
index 06c23f4ee..82d12a1e4 100644
--- a/test/cypress/integration/vnComponent/vnLocation.spec.js
+++ b/test/cypress/integration/vnComponent/VnLocation.spec.js
@@ -1,3 +1,5 @@
+const { randomNumber, randomString } = require('../../support');
+
describe('VnLocation', () => {
const locationOptions = '[role="listbox"] > div.q-virtual-scroll__content > .q-item';
const dialogInputs = '.q-dialog label input';
@@ -41,11 +43,9 @@ describe('VnLocation', () => {
province
);
cy.get(
- `${createForm.prefix} > :nth-child(4) > .q-select > ${createForm.sufix} > :nth-child(3) > .q-icon`
+ `${createForm.prefix} > :nth-child(4) > .q-select > ${createForm.sufix} > :nth-child(3) `
).click();
- cy.get(
- `#q-portal--dialog--5 > .q-dialog > ${createForm.prefix} > .vn-row > .q-select > ${createForm.sufix} > :nth-child(1) input`
- ).should('have.value', province);
+ cy.dataCy('locationProvince').should('have.value', province);
});
});
describe('Worker Create', () => {
@@ -99,7 +99,7 @@ describe('VnLocation', () => {
});
it('Create postCode', () => {
- const postCode = '1234475';
+ const postCode = Math.floor(100000 + Math.random() * 900000);
const province = 'Valencia';
cy.get(createLocationButton).click();
cy.get('.q-card > h1').should('have.text', 'New postcode');
@@ -115,22 +115,64 @@ describe('VnLocation', () => {
checkVnLocation(postCode, province);
});
- it('Create city', () => {
- const postCode = '9011';
- const province = 'Saskatchew';
+
+ it('Create city without country', () => {
+ const postCode = randomNumber();
+ const province = randomString({ length: 4 });
cy.get(createLocationButton).click();
cy.get(dialogInputs).eq(0).type(postCode);
- cy.get(
- `${createForm.prefix} > :nth-child(4) > .q-select > ${createForm.sufix} > :nth-child(2) > .q-icon`
- ).click();
- cy.selectOption('#q-portal--dialog--3 .q-select', 'one');
- cy.get('#q-portal--dialog--3 .q-input').type(province);
- cy.get('#q-portal--dialog--3 .q-btn--standard').click();
- cy.get('#q-portal--dialog--1 .q-btn--standard').click();
+ cy.dataCy('City_icon').click();
+ cy.selectOption('[data-cy="locationProvince"]:last', 'Province one');
+ cy.dataCy('cityName').type(province);
+ cy.dataCy('FormModelPopup_save').eq(1).click();
+ cy.dataCy('FormModelPopup_save').eq(0).click();
+
cy.waitForElement('.q-form');
checkVnLocation(postCode, province);
});
+ it('Create city with country', () => {
+ const cityName = 'Saskatchew'.concat(Math.random(1 * 100));
+ cy.get(createLocationButton).click();
+ cy.selectOption(
+ `${createForm.prefix} > :nth-child(5) > :nth-child(3) `,
+ 'Italia'
+ );
+ cy.dataCy('City_icon').click();
+ cy.selectOption('[data-cy="locationProvince"]:last', 'Province four');
+ cy.countSelectOptions('[data-cy="locationProvince"]:last', 1);
+
+ cy.dataCy('cityName').type(cityName);
+ cy.dataCy('FormModelPopup_save').eq(1).click();
+ });
+
+ it('Create province without country', () => {
+ const provinceName = 'Saskatchew'.concat(Math.random(1 * 100));
+ cy.get(createLocationButton).click();
+ cy.dataCy('Province_icon').click();
+ cy.selectOption('[data-cy="autonomyProvince"] ', 'Autonomy one');
+ cy.countSelectOptions('[data-cy="autonomyProvince"]', 4);
+ cy.dataCy('provinceName').type(provinceName);
+
+ cy.dataCy('FormModelPopup_save').eq(1).click();
+ });
+
+ it('Create province with country', () => {
+ const provinceName = 'Saskatchew'.concat(Math.random(1 * 100));
+ cy.get(createLocationButton).click();
+ cy.selectOption(
+ `${createForm.prefix} > :nth-child(5) > :nth-child(3) `,
+ 'España'
+ );
+ cy.dataCy('Province_icon').click();
+
+ cy.selectOption('[data-cy="autonomyProvince"] ', 'Autonomy one');
+ cy.countSelectOptions('[data-cy="autonomyProvince"]', 2);
+
+ cy.dataCy('provinceName').type(provinceName);
+ cy.dataCy('FormModelPopup_save').eq(1).click();
+ });
+
function checkVnLocation(postCode, province) {
cy.get(`${createForm.prefix}`).should('not.exist');
cy.get('.q-form > .q-card > .vn-row:nth-child(6)')
diff --git a/test/cypress/integration/vnComponent/vnLog.spec.js b/test/cypress/integration/vnComponent/VnLog.spec.js
similarity index 100%
rename from test/cypress/integration/vnComponent/vnLog.spec.js
rename to test/cypress/integration/vnComponent/VnLog.spec.js
diff --git a/test/cypress/integration/vnComponent/vnSearchBar.spec.js b/test/cypress/integration/vnComponent/VnSearchBar.spec.js
similarity index 100%
rename from test/cypress/integration/vnComponent/vnSearchBar.spec.js
rename to test/cypress/integration/vnComponent/VnSearchBar.spec.js
diff --git a/test/cypress/integration/worker/workerPit.spec.js b/test/cypress/integration/worker/workerPit.spec.js
new file mode 100644
index 000000000..cc3a87637
--- /dev/null
+++ b/test/cypress/integration/worker/workerPit.spec.js
@@ -0,0 +1,40 @@
+describe('WorkerPit', () => {
+ const familySituationInput = '[data-cy="Family Situation_input"]';
+ const familySituation = '1';
+ const childPensionInput = '[data-cy="Child Pension_input"]';
+ const childPension = '120';
+ const spouseNifInput = '[data-cy="Spouse Pension_input"]';
+ const spouseNif = '65117125P';
+ const spousePensionInput = '[data-cy="Spouse Pension_input"]';
+ const spousePension = '120';
+ const addRelative = '[data-cy="addRelative"]';
+ const isDescendantSelect = '[data-cy="Descendant/Ascendant_select"]';
+ const birthedInput = '[data-cy="Birth Year_input"]';
+ const birthed = '2002';
+ const adoptionYearInput = '[data-cy="Adoption Year_input"]';
+ const adoptionYear = '2004';
+ const saveRelative = '[data-cy="workerPitRelativeSaveBtn"]';
+ const savePIT = '#st-actions > .q-btn-group > .q-btn--standard';
+
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('developer');
+ cy.visit(`/#/worker/1107/pit`);
+ });
+
+ it('complete PIT', () => {
+ cy.get(familySituationInput).type(familySituation);
+ cy.get(childPensionInput).type(childPension);
+ cy.get(spouseNifInput).type(spouseNif);
+ cy.get(spousePensionInput).type(spousePension);
+ cy.get(savePIT).click();
+ });
+
+ it('complete relative', () => {
+ cy.get(addRelative).click();
+ cy.get(isDescendantSelect).type('{downArrow}{downArrow}{enter}');
+ cy.get(birthedInput).type(birthed);
+ cy.get(adoptionYearInput).type(adoptionYear);
+ cy.get(saveRelative).click();
+ });
+});
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index cb1d3de44..2b13a7144 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -86,11 +86,17 @@ Cypress.Commands.add('getValue', (selector) => {
});
// Fill Inputs
-Cypress.Commands.add('selectOption', (selector, option) => {
+Cypress.Commands.add('selectOption', (selector, option, timeout) => {
cy.waitForElement(selector);
cy.get(selector).click();
+ cy.wait(timeout || 1000);
cy.get('.q-menu .q-item').contains(option).click();
});
+Cypress.Commands.add('countSelectOptions', (selector, option) => {
+ cy.waitForElement(selector);
+ cy.get(selector).click();
+ cy.get('.q-menu .q-item').should('have.length', option);
+});
Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
cy.waitForElement('.q-form > .q-card');
@@ -104,14 +110,14 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
const { type, val } = field;
switch (type) {
case 'select':
- cy.wrap(el).type(val);
+ cy.get(el).click();
cy.get('.q-menu .q-item').contains(val).click();
break;
case 'date':
- cy.wrap(el).type(val.split('-').join(''));
+ cy.get(el).type(val.split('-').join(''));
break;
case 'time':
- cy.wrap(el).click();
+ cy.get(el).click();
cy.get('.q-time .q-time__clock').contains(val.h).click();
cy.get('.q-time .q-time__clock').contains(val.m).click();
cy.get('.q-time .q-time__link').contains(val.x).click();
diff --git a/test/cypress/support/index.js b/test/cypress/support/index.js
index 4385698ec..c57c1a303 100644
--- a/test/cypress/support/index.js
+++ b/test/cypress/support/index.js
@@ -15,3 +15,19 @@
import './commands';
+function randomString(options = { length: 10 }) {
+ let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+ return randomizeValue(possible, options);
+}
+
+function randomNumber(options = { length: 10 }) {
+ let possible = '0123456789';
+ return randomizeValue(possible, options);
+}
+
+function randomizeValue(characterSet, options) {
+ return Array.from({ length: options.length }, () =>
+ characterSet.charAt(Math.floor(Math.random() * characterSet.length))
+ ).join('');
+}
+export { randomString, randomNumber, randomizeValue };
diff --git a/test/vitest/__tests__/composables/downloadFile.spec.js b/test/vitest/__tests__/composables/downloadFile.spec.js
index f611479bf..f53b56b3e 100644
--- a/test/vitest/__tests__/composables/downloadFile.spec.js
+++ b/test/vitest/__tests__/composables/downloadFile.spec.js
@@ -1,25 +1,36 @@
-import { vi, describe, expect, it } from 'vitest';
+import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest';
import { axios } from 'app/test/vitest/helper';
import { downloadFile } from 'src/composables/downloadFile';
import { useSession } from 'src/composables/useSession';
-
const session = useSession();
const token = session.getToken();
describe('downloadFile', () => {
+ const baseUrl = 'http://localhost:9000';
+ let defaulCreateObjectURL;
+
+ beforeAll(() => {
+ defaulCreateObjectURL = window.URL.createObjectURL;
+ window.URL.createObjectURL = vi.fn(() => 'blob:http://localhost:9000/blob-id');
+ });
+
+ afterAll(() => (window.URL.createObjectURL = defaulCreateObjectURL));
+
it('should open a new window to download the file', async () => {
- const url = 'http://localhost:9000';
-
- vi.spyOn(axios, 'get').mockResolvedValueOnce({ data: url });
-
- const mockWindowOpen = vi.spyOn(window, 'open');
+ const res = {
+ data: new Blob(['file content'], { type: 'application/octet-stream' }),
+ headers: { 'content-disposition': 'attachment; filename="test-file.txt"' },
+ };
+ vi.spyOn(axios, 'get').mockImplementation((url) => {
+ if (url == 'Urls/getUrl') return Promise.resolve({ data: baseUrl });
+ else if (url.includes('downloadFile')) return Promise.resolve(res);
+ });
await downloadFile(1);
- expect(mockWindowOpen).toHaveBeenCalledWith(
- `${url}/api/dms/1/downloadFile?access_token=${token}`
+ expect(axios.get).toHaveBeenCalledWith(
+ `${baseUrl}/api/dms/1/downloadFile?access_token=${token}`,
+ { responseType: 'blob' }
);
-
- mockWindowOpen.mockRestore();
});
});