diff --git a/CHANGELOG.md b/CHANGELOG.md
index 250aa01a2..f1f911d62 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- (Item) => Se añade la opción de añadir un comentario del motivo de hacer una foto
+- (Worker) => Se añade la opción de crear un trabajador ajeno a la empresa
## [2418.01]
diff --git a/src/components/common/VnRadio.vue b/src/components/common/VnRadio.vue
new file mode 100644
index 000000000..4eeb9dbe9
--- /dev/null
+++ b/src/components/common/VnRadio.vue
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/src/components/ui/VnSubToolbar.vue b/src/components/ui/VnSubToolbar.vue
index c0d129613..8c86c056a 100644
--- a/src/components/ui/VnSubToolbar.vue
+++ b/src/components/ui/VnSubToolbar.vue
@@ -18,7 +18,7 @@ onMounted(() => {
const observer = new MutationObserver(
() =>
(hasContent.value =
- actions.value.childNodes.length + data.value.childNodes.length)
+ actions.value?.childNodes?.length + data.value?.childNodes?.length)
);
if (actions.value) observer.observe(actions.value, opts);
if (data.value) observer.observe(data.value, opts);
diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue
index 656f8d5fd..807ccdae4 100644
--- a/src/pages/Entry/Card/EntryDescriptor.vue
+++ b/src/pages/Entry/Card/EntryDescriptor.vue
@@ -34,7 +34,7 @@ const entryFilter = {
{
relation: 'travel',
scope: {
- fields: ['id', 'landed', 'agencyModeFk', 'warehouseOutFk'],
+ fields: ['id', 'landed', 'shipped', 'agencyModeFk', 'warehouseOutFk'],
include: [
{
relation: 'agency',
@@ -125,10 +125,8 @@ watch;
:label="t('entry.descriptor.agency')"
:value="entity.travel?.agency?.name"
/>
-
+
+
{
:value="entry.travel.agency.name"
/>
-
+
{
v-model="entry.travel.isDelivered"
:disable="true"
/>
-
+
{
-
+
useArrayData().store.data);
+const arrayData = useArrayData();
+const invoiceIn = computed(() => arrayData.store.data);
const userConfig = ref(null);
const invoiceId = computed(() => +route.params.id);
diff --git a/src/pages/InvoiceIn/Card/InvoiceInCorrective.vue b/src/pages/InvoiceIn/Card/InvoiceInCorrective.vue
index dc62440c8..7735747f9 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInCorrective.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInCorrective.vue
@@ -12,7 +12,7 @@ const { push, currentRoute } = useRouter();
const { t } = useI18n();
const invoiceId = +currentRoute.value.params.id;
-const arrayData = useArrayData(currentRoute.value.meta.moduleName);
+const arrayData = useArrayData();
const invoiceIn = computed(() => arrayData.store.data);
const invoiceInCorrectionRef = ref();
const filter = {
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
index c435bf368..68dc5be4b 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
@@ -27,9 +27,9 @@ const quasar = useQuasar();
const { hasAny } = useRole();
const { t } = useI18n();
const { openReport, sendEmail } = usePrintService();
-const { store } = useArrayData(currentRoute.value.meta.moduleName);
+const arrayData = useArrayData();
-const invoiceIn = computed(() => store.data);
+const invoiceIn = computed(() => arrayData.store.data);
const cardDescriptorRef = ref();
const correctionDialogRef = ref();
const entityId = computed(() => $props.id || +currentRoute.value.params.id);
@@ -184,7 +184,7 @@ async function toUnbook() {
: t('isNotLinked', { bookEntry });
quasar.notify({ type, message });
- if (!isLinked) store.data.isBooked = false;
+ if (!isLinked) arrayData.store.data.isBooked = false;
}
async function deleteInvoice() {
diff --git a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
index 67c197636..a7b9110f5 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
@@ -11,7 +11,8 @@ import { useArrayData } from 'src/composables/useArrayData';
const { t } = useI18n();
const route = useRoute();
-const currency = computed(() => useArrayData().store.data?.currency?.code);
+const arrayData = useArrayData();
+const currency = computed(() => arrayData.store.data?.currency?.code);
const invoceInIntrastat = ref([]);
const rowsSelected = ref([]);
const countries = ref([]);
diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
index b7f8adf50..428e7a7a1 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
@@ -14,9 +14,10 @@ import VnTitle from 'src/components/common/VnTitle.vue';
const props = defineProps({ id: { type: [Number, String], default: 0 } });
const { t } = useI18n();
const route = useRoute();
+const arrayData = useArrayData();
const entityId = computed(() => props.id || +route.params.id);
-const invoiceIn = computed(() => useArrayData().store.data);
+const invoiceIn = computed(() => arrayData.store.data);
const currency = computed(() => invoiceIn.value?.currency?.code);
const invoiceInUrl = ref();
const amountsNotMatch = ref(null);
diff --git a/src/pages/Worker/WorkerCreate.vue b/src/pages/Worker/WorkerCreate.vue
index 9d962e450..ebde15b72 100644
--- a/src/pages/Worker/WorkerCreate.vue
+++ b/src/pages/Worker/WorkerCreate.vue
@@ -1,59 +1,29 @@
-
- onFetchWorkerConfig(data)"
- :filter="workerConfigFilter"
- auto-load
- />
-
(companiesOptions = data)"
@@ -97,16 +65,31 @@ onMounted(async () => {
@on-fetch="(data) => (bankEntitiesOptions = data)"
auto-load
/>
-
-
+
+
+
+
+
+
$router.push({ path: `/worker/${id}` })"
>
-
+
{
:label="t('worker.create.lastName')"
:rules="validate('Worker.lastNames')"
/>
-
-
-
-
-
-
- handleLocation(data, location)"
- >
-
-
-
-
-
-
+
{
:rules="validate('Worker.email')"
/>
-
+
{
-
+
+
+
+
+
+
+ handleLocation(data, location)"
+ :disable="formData.isFreelance"
+ >
+
+
+
+
+
+
{
map-options
hide-selected
:rules="validate('Worker.payMethodFk')"
+ :disable="formData.isFreelance"
+ @update:model-value="(val) => !val && delete formData.payMethodFk"
/>
@@ -232,10 +222,11 @@ onMounted(async () => {
hide-selected
:roles-allowed-to-create="['salesAssistant', 'hr']"
:rules="validate('Worker.bankEntity')"
+ :disable="formData.isFreelance"
>
bankEntitiesOptions.push(data)"
/>
diff --git a/src/pages/Worker/locale/es.yml b/src/pages/Worker/locale/es.yml
index a960dffe6..f74cb4fdb 100644
--- a/src/pages/Worker/locale/es.yml
+++ b/src/pages/Worker/locale/es.yml
@@ -1,3 +1,5 @@
Search worker: Buscar trabajador
You can search by worker id or name: Puedes buscar por id o nombre del trabajador
Locker: Taquilla
+Internal: Interno
+External: Externo
diff --git a/test/cypress/integration/worker/workerCreate.spec.js b/test/cypress/integration/worker/workerCreate.spec.js
new file mode 100644
index 000000000..26ce899c8
--- /dev/null
+++ b/test/cypress/integration/worker/workerCreate.spec.js
@@ -0,0 +1,59 @@
+describe('WorkerCreate', () => {
+ const externalRadio = '.q-toolbar .q-radio:nth-child(2)';
+ const notification = '.q-notification__message';
+ const developerBossId = 120;
+
+ const internal = {
+ Fi: { val: '78457139E' },
+ 'Web user': { val: 'manolo' },
+ Name: { val: 'Manolo' },
+ 'Last name': { val: 'Hurtado' },
+ 'Personal email': { val: 'manolo@mydomain.com' },
+ Street: { val: 'S/ DEFAULTWORKERSTREET' },
+ Location: { val: 1, type: 'select' },
+ Phone: { val: '123456789' },
+ 'Worker code': { val: 'DWW' },
+ Boss: { val: developerBossId, type: 'select' },
+ Birth: { val: '2022-12-11T23:00:00.000Z', type: 'date', day: 11 },
+ };
+ const external = {
+ Fi: { val: 'Z4531219V' },
+ 'Web user': { val: 'pepe' },
+ Name: { val: 'PEPE' },
+ 'Last name': { val: 'GARCIA' },
+ 'Personal email': { val: 'pepe@gmail.com' },
+ 'Worker code': { val: 'PG' },
+ Boss: { val: developerBossId, type: 'select' },
+ };
+
+ beforeEach(() => {
+ cy.viewport(1280, 720);
+ cy.login('hr');
+ cy.visit('/#/worker/create');
+ });
+
+ it('should throw an error if a pay method has not been selected', () => {
+ cy.fillInForm(internal);
+ cy.saveCard();
+ cy.get(notification).should(
+ 'contains.text',
+ 'That payment method requires an IBAN'
+ );
+ });
+
+ it('should create an internal', () => {
+ cy.fillInForm({
+ ...internal,
+ 'Pay method': { val: 'PayMethod one', type: 'select' },
+ });
+ cy.saveCard();
+ cy.get(notification).should('contains.text', 'Data created');
+ });
+
+ it('should create an external', () => {
+ cy.get(externalRadio).click();
+ cy.fillInForm(external);
+ cy.saveCard();
+ cy.get(notification).should('contains.text', 'Data created');
+ });
+});
diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js
index 1e9292626..9808fd157 100644
--- a/test/cypress/integration/worker/workerList.spec.js
+++ b/test/cypress/integration/worker/workerList.spec.js
@@ -8,13 +8,13 @@ describe('WorkerList', () => {
});
it('should load workers', () => {
- cy.get(workerFieldNames).eq(0).should('have.text', 'jessicajones');
- cy.get(workerFieldNames).eq(1).should('have.text', 'brucebanner');
- cy.get(workerFieldNames).eq(2).should('have.text', 'charlesxavier');
+ cy.get(workerFieldNames).eq(2).should('have.text', 'jessicajones');
+ cy.get(workerFieldNames).eq(3).should('have.text', 'brucebanner');
+ cy.get(workerFieldNames).eq(4).should('have.text', 'charlesxavier');
});
it('should open the worker summary', () => {
- cy.openListSummary(0);
+ cy.openListSummary(2);
cy.get('.summaryHeader div').should('have.text', '1110 - Jessica Jones');
cy.get('.summary .header-link')
.eq(0)
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index a237622e6..055cb8021 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -86,6 +86,36 @@ Cypress.Commands.add('selectOption', (selector, option) => {
cy.get('.q-menu .q-item').contains(option).click();
});
+Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
+ const days = '.q-date__calendar-days .q-date__calendar-item--in';
+ cy.waitForElement('.q-form > .q-card');
+ cy.get(`${form} input`).each(([el]) => {
+ cy.wrap(el)
+ .invoke('attr', 'aria-label')
+ .then((ariaLabel) => {
+ const field = obj[ariaLabel];
+ if (!field) return;
+
+ const { type, val, day } = field;
+ switch (type) {
+ case 'select':
+ cy.wrap(el).type(val);
+ cy.get('.q-menu .q-item').contains(val).click();
+ break;
+ case 'date':
+ cy.wrap(el).click();
+ cy.get(days)
+ .eq(day ? day - 1 : 0)
+ .click();
+ break;
+ default:
+ cy.wrap(el).type(val);
+ break;
+ }
+ });
+ });
+});
+
Cypress.Commands.add('checkOption', (selector) => {
cy.get(selector).find('.q-checkbox__inner').click();
});
@@ -198,11 +228,15 @@ Cypress.Commands.add('closeSideMenu', (element) => {
Cypress.Commands.add('clearSearchbar', (element) => {
if (element) cy.waitForElement(element);
- cy.get('#searchbar > form > div:nth-child(1) > label > div:nth-child(1) input').clear();
+ cy.get(
+ '#searchbar > form > div:nth-child(1) > label > div:nth-child(1) input'
+ ).clear();
});
Cypress.Commands.add('writeSearchbar', (value) => {
- cy.get('#searchbar > form > div:nth-child(1) > label > div:nth-child(1) input').type(value);
+ cy.get('#searchbar > form > div:nth-child(1) > label > div:nth-child(1) input').type(
+ value
+ );
});
Cypress.Commands.add('validateContent', (selector, expectedValue) => {
cy.get(selector).should('have.text', expectedValue);