diff --git a/db/changes/10240-allSaints/00-supplier_contact.sql b/db/changes/10240-allSaints/00-supplier_contact.sql new file mode 100644 index 0000000000..5054366b0f --- /dev/null +++ b/db/changes/10240-allSaints/00-supplier_contact.sql @@ -0,0 +1,24 @@ +CREATE TABLE `vn`.`supplierContact` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `supplierFk` INT(11) NULL DEFAULT NULL, + `phone` VARCHAR(16) NULL DEFAULT NULL, + `mobile` VARCHAR(16) NULL DEFAULT NULL, + `email` VARCHAR(255) NULL DEFAULT NULL, + `observation` TEXT NULL DEFAULT NULL, + `name` VARCHAR(255) NULL DEFAULT NULL, + PRIMARY KEY (`id`)) +ENGINE = InnoDB; + + +ALTER TABLE `vn`.`supplierContact` +ADD CONSTRAINT `supplier_id` + FOREIGN KEY (`supplierFk`) + REFERENCES `vn`.`supplier` (`id`) + ON DELETE CASCADE + ON UPDATE CASCADE; + +INSERT INTO vn.supplierContact(supplierFk,phone,mobile,email,observation,`name`) + SELECT r.Id_Proveedor,c.Telefono,c.Movil,c.email,c.Notas,concat(c.Nombre," ", IFNULL(c.Apellidos,"")) + FROM vn2008.Contactos c + JOIN vn2008.Relaciones r ON r.Id_Contacto = c.Id_Contacto + JOIN vn.supplier s ON s.id = r.Id_Proveedor; \ No newline at end of file diff --git a/db/changes/10250/00-ACL.sql b/db/changes/10250/00-ACL.sql new file mode 100644 index 0000000000..c9d8fd456f --- /dev/null +++ b/db/changes/10250/00-ACL.sql @@ -0,0 +1,2 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('supplier', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative'); +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('SupplierContact', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative'); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index cde3710502..427de3a2d2 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1217,6 +1217,13 @@ INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif` (2, 'Farmer King', 'The farmer', 4000020002, 1, 'B22222222', 1, 0, CURDATE(), 1, 'supplier address 2', 'SILLA', 2, 43022, 1, 2, 10, 93, 8), (442, 'Verdnatura Levante SL', 'Verdnatura', 5115000442, 1, 'C33333333', 0, 0, CURDATE(), 1, 'supplier address 3', 'SILLA', 1, 43022, 1, 2, 15, NULL, NULL); +INSERT INTO `vn`.`supplierContact`(`id`, `supplierFk`, `phone`, `mobile`, `email`, `observation`, `name`) + VALUES + (1, 1, 123121212, 654789123, 'supplier1@email.es', 'observation1', 'the boss'), + (2, 1, 987456132, NULL, NULL, NULL, 'the salesperson'), + (3, 2, 321654987, NULL, 'supplier2@email.es', NULL, NULL), + (4, 442, 321654987, NULL, NULL, 'observation442', NULL); + INSERT INTO `cache`.`cache_calc`(`id`, `cache_id`, `cacheName`, `params`, `last_refresh`, `expires`, `created`, `connection_id`) VALUES (1, 2, 'available', CONCAT_WS('/',1,CURDATE()), CURRENT_TIMESTAMP(), DATE_ADD(CURRENT_TIMESTAMP(),INTERVAL 15 MINUTE), CURDATE(), NULL), diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index f34491ba3b..52e359687d 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -912,5 +912,16 @@ export default { alias: 'vn-supplier-descriptor vn-label-value[label="Alias"]', clientButton: 'vn-supplier-descriptor vn-icon[icon="person"]', entriesButton: 'vn-supplier-descriptor vn-icon[icon="icon-entry"]', + }, + supplierContact: { + anyContact: 'vn-supplier-contact > form > vn-card > div', + addNewContact: 'vn-supplier-contact vn-icon[icon="add_circle"]', + thirdContactName: 'vn-supplier-contact div:nth-child(3) vn-textfield[ng-model="contact.name"]', + thirdContactPhone: 'vn-supplier-contact div:nth-child(3) vn-textfield[ng-model="contact.phone"]', + thirdContactMobile: 'vn-supplier-contact div:nth-child(3) vn-textfield[ng-model="contact.mobile"]', + thirdContactEmail: 'vn-supplier-contact div:nth-child(3) vn-textfield[ng-model="contact.email"]', + thirdContactNotes: 'vn-supplier-contact div:nth-child(3) vn-textfield[ng-model="contact.observation"]', + saveButton: 'vn-supplier-contact button[type="submit"]', + thirdContactDeleteButton: 'vn-supplier-contact div:nth-child(3) vn-icon-button[icon="delete"]' } }; diff --git a/e2e/paths/13-supplier/01_summary_and_descriptor.spec.js b/e2e/paths/13-supplier/01_summary_and_descriptor.spec.js index 953a9ee283..21609fced6 100644 --- a/e2e/paths/13-supplier/01_summary_and_descriptor.spec.js +++ b/e2e/paths/13-supplier/01_summary_and_descriptor.spec.js @@ -1,7 +1,7 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -describe('Supplier descriptor path', () => { +describe('Supplier summary & descriptor path', () => { let browser; let page; diff --git a/e2e/paths/13-supplier/02_contact.spec.js b/e2e/paths/13-supplier/02_contact.spec.js new file mode 100644 index 0000000000..9a102cf936 --- /dev/null +++ b/e2e/paths/13-supplier/02_contact.spec.js @@ -0,0 +1,84 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('Supplier contact path', () => { + let browser; + let page; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('administrative', 'supplier'); + await page.accessToSearchResult('1'); + await page.accessToSection('supplier.card.contact'); + }); + + afterAll(async() => { + await browser.close(); + }); + + it('should create a new contact', async() => { + await page.waitToClick(selectors.supplierContact.addNewContact); + await page.write(selectors.supplierContact.thirdContactName, 'The tester'); + await page.write(selectors.supplierContact.thirdContactPhone, '99 999 99 99'); + await page.write(selectors.supplierContact.thirdContactMobile, '555 55 55 55'); + await page.write(selectors.supplierContact.thirdContactEmail, 'testing@puppeteer.com'); + await page.write(selectors.supplierContact.thirdContactNotes, 'the end to end integration tester'); + await page.waitToClick(selectors.supplierContact.saveButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toBe('Data saved!'); + }); + + it(`should reload the section and count the contacts`, async() => { + await page.reloadSection('supplier.card.contact'); + const result = await page.countElement(selectors.supplierContact.anyContact); + + expect(result).toEqual(3); + }); + + it(`should check the new contact name was saved correctly`, async() => { + const result = await page.waitToGetProperty(selectors.supplierContact.thirdContactName, 'value'); + + expect(result).toContain('The tester'); + }); + + it(`should check the new contact phone was saved correctly`, async() => { + const result = await page.waitToGetProperty(selectors.supplierContact.thirdContactPhone, 'value'); + + expect(result).toContain('99 999 99 99'); + }); + + it(`should check the new contact mobile was saved correctly`, async() => { + const result = await page.waitToGetProperty(selectors.supplierContact.thirdContactMobile, 'value'); + + expect(result).toContain('555 55 55 55'); + }); + + it(`should check the new contact email was saved correctly`, async() => { + const result = await page.waitToGetProperty(selectors.supplierContact.thirdContactEmail, 'value'); + + expect(result).toContain('testing@puppeteer.com'); + }); + + it(`should check the new contact note was saved correctly`, async() => { + const result = await page.waitToGetProperty(selectors.supplierContact.thirdContactNotes, 'value'); + + expect(result).toContain('the end to end integration tester'); + }); + + it(`should remove the created contact`, async() => { + await page.waitToClick(selectors.supplierContact.thirdContactDeleteButton, 'value'); + await page.waitToClick(selectors.supplierContact.saveButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toBe('Data saved!'); + }); + + it(`should reload the section and count the amount of contacts went back to 2`, async() => { + await page.reloadSection('supplier.card.contact'); + const result = await page.countElement(selectors.supplierContact.anyContact); + + expect(result).toEqual(2); + }); +}); diff --git a/modules/supplier/back/model-config.json b/modules/supplier/back/model-config.json index c1963a8cf2..34d152bc6b 100644 --- a/modules/supplier/back/model-config.json +++ b/modules/supplier/back/model-config.json @@ -7,5 +7,8 @@ }, "SupplierLog": { "dataSource": "vn" + }, + "SupplierContact": { + "dataSource": "vn" } } diff --git a/modules/supplier/back/models/supplier-contact.json b/modules/supplier/back/models/supplier-contact.json new file mode 100644 index 0000000000..accb2acd6b --- /dev/null +++ b/modules/supplier/back/models/supplier-contact.json @@ -0,0 +1,49 @@ +{ + "name": "SupplierContact", + "base": "VnModel", + "options": { + "mysql": { + "table": "supplierContact" + } + }, + "properties": { + "id": { + "type": "Number", + "id": true, + "description": "Identifier" + }, + "supplierFk": { + "type": "String" + }, + "phone": { + "type": "String" + }, + "mobile": { + "type": "String" + }, + "email": { + "type": "String" + }, + "observation": { + "type": "String" + }, + "name": { + "type": "String" + } + }, + "relations": { + "supplier": { + "type": "belongsTo", + "model": "Supplier", + "foreignKey": "supplierFk" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} \ No newline at end of file diff --git a/modules/supplier/front/contact/index.html b/modules/supplier/front/contact/index.html new file mode 100644 index 0000000000..4a791a4bca --- /dev/null +++ b/modules/supplier/front/contact/index.html @@ -0,0 +1,74 @@ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + +
\ No newline at end of file diff --git a/modules/supplier/front/contact/index.js b/modules/supplier/front/contact/index.js new file mode 100644 index 0000000000..48db3d5267 --- /dev/null +++ b/modules/supplier/front/contact/index.js @@ -0,0 +1,27 @@ +import ngModule from '../module'; +import './style.scss'; +import Section from 'salix/components/section'; + +class Controller extends Section { + add() { + this.$.model.insert({ + supplierFk: this.supplier.id + }); + } + + onSubmit() { + this.$.watcher.check(); + this.$.model.save().then(() => { + this.$.watcher.notifySaved(); + this.$.watcher.updateOriginalData(); + }); + } +} + +ngModule.vnComponent('vnSupplierContact', { + template: require('./index.html'), + controller: Controller, + bindings: { + supplier: '<' + } +}); diff --git a/modules/supplier/front/contact/style.scss b/modules/supplier/front/contact/style.scss new file mode 100644 index 0000000000..84e98050df --- /dev/null +++ b/modules/supplier/front/contact/style.scss @@ -0,0 +1,10 @@ +@import "variables"; + + +.contact { + max-width: $width-lg; + margin-bottom: 10px; + padding-right: 10px; + padding-left: 10px; + border: 1px solid $color-marginal; +} diff --git a/modules/supplier/front/index.js b/modules/supplier/front/index.js index a4017bbd98..2b7d735415 100644 --- a/modules/supplier/front/index.js +++ b/modules/supplier/front/index.js @@ -7,3 +7,4 @@ import './index/'; import './search-panel'; import './log'; import './summary'; +import './contact'; diff --git a/modules/supplier/front/routes.json b/modules/supplier/front/routes.json index 24e8d86925..d679dd9798 100644 --- a/modules/supplier/front/routes.json +++ b/modules/supplier/front/routes.json @@ -9,6 +9,7 @@ {"state": "supplier.index", "icon": "icon-supplier"} ], "card": [ + {"state": "supplier.card.contact", "icon": "contact_phone"}, {"state": "supplier.card.log", "icon": "history"} ] }, @@ -19,17 +20,20 @@ "abstract": true, "component": "vn-supplier", "description": "Suppliers" - }, { + }, + { "url": "/index?q", "state": "supplier.index", "component": "vn-supplier-index", "description": "Suppliers" - }, { + }, + { "url": "/:id", "state": "supplier.card", "abstract": true, "component": "vn-supplier-card" - }, { + }, + { "url": "/summary", "state": "supplier.card.summary", "component": "vn-supplier-summary", @@ -37,11 +41,21 @@ "params": { "supplier": "$ctrl.supplier" } - }, { + }, + { "url" : "/log", "state": "supplier.card.log", "component": "vn-supplier-log", "description": "Log" + }, + { + "url": "/contact", + "state": "supplier.card.contact", + "component": "vn-supplier-contact", + "description": "Contacts", + "params": { + "supplier": "$ctrl.supplier" + } } ] } \ No newline at end of file