diff --git a/CHANGELOG.md b/CHANGELOG.md index 6adcf94f3..75e807a7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [2322.01] - 2023-06-08 +## [2324.01] - 2023-06-08 + +### Added +- + + +### Changed +- + +### Fixed +- + + + +## [2322.01] - 2023-06-01 ### Added - (Tickets -> Crear Factura) Al facturar se envia automáticamente el pdf al cliente diff --git a/back/methods/image/download.js b/back/methods/image/download.js index 3a8bcf30e..c4037b809 100644 --- a/back/methods/image/download.js +++ b/back/methods/image/download.js @@ -67,7 +67,7 @@ module.exports = Self => { if (!image) return false; - const hasReadRole = models.ImageCollection.hasReadRole(ctx, collection); + const hasReadRole = await models.ImageCollection.hasReadRole(ctx, collection); if (!hasReadRole) throw new UserError(`You don't have enough privileges`); diff --git a/back/models/dms-type.json b/back/models/dms-type.json index c7a1815fe..de3d564b4 100644 --- a/back/models/dms-type.json +++ b/back/models/dms-type.json @@ -44,4 +44,4 @@ "principalId": "$everyone", "permission": "ALLOW" }] -} \ No newline at end of file +} diff --git a/back/models/image-collection.js b/back/models/image-collection.js index 2c4d274ee..69905beca 100644 --- a/back/models/image-collection.js +++ b/back/models/image-collection.js @@ -9,10 +9,11 @@ module.exports = Self => { * @return {boolean} True for user with read privileges */ Self.hasReadRole = async(ctx, name, options) => { - const collection = await Self.findOne({where: {name}}, { + const collection = await Self.findOne({ include: { relation: 'readRole' - } + }, + where: {name} }, options); return await hasRole(ctx, collection, options); diff --git a/db/changes/230202/00-itemConfig.sql b/db/.archive/230202/00-itemConfig.sql similarity index 100% rename from db/changes/230202/00-itemConfig.sql rename to db/.archive/230202/00-itemConfig.sql diff --git a/db/changes/230401/00-ACL.sql b/db/.archive/230401/00-ACL.sql similarity index 100% rename from db/changes/230401/00-ACL.sql rename to db/.archive/230401/00-ACL.sql diff --git a/db/changes/230401/00-ACL_tag_update.sql b/db/.archive/230401/00-ACL_tag_update.sql similarity index 100% rename from db/changes/230401/00-ACL_tag_update.sql rename to db/.archive/230401/00-ACL_tag_update.sql diff --git a/db/changes/230401/00-createWorker.sql b/db/.archive/230401/00-createWorker.sql similarity index 100% rename from db/changes/230401/00-createWorker.sql rename to db/.archive/230401/00-createWorker.sql diff --git a/db/changes/230401/00-ticket_canAdvance.sql b/db/.archive/230401/00-ticket_canAdvance.sql similarity index 100% rename from db/changes/230401/00-ticket_canAdvance.sql rename to db/.archive/230401/00-ticket_canAdvance.sql diff --git a/db/changes/230401/00-updateIsToBeMailed.sql b/db/.archive/230401/00-updateIsToBeMailed.sql similarity index 100% rename from db/changes/230401/00-updateIsToBeMailed.sql rename to db/.archive/230401/00-updateIsToBeMailed.sql diff --git a/db/changes/230403/00-clienteCompensado.sql b/db/.archive/230403/00-clienteCompensado.sql similarity index 100% rename from db/changes/230403/00-clienteCompensado.sql rename to db/.archive/230403/00-clienteCompensado.sql diff --git a/db/changes/230404/00-ticket_canAdvance.sql b/db/.archive/230404/00-ticket_canAdvance.sql similarity index 100% rename from db/changes/230404/00-ticket_canAdvance.sql rename to db/.archive/230404/00-ticket_canAdvance.sql diff --git a/db/changes/230601/00-acl_claim.sql b/db/.archive/230601/00-acl_claim.sql similarity index 100% rename from db/changes/230601/00-acl_claim.sql rename to db/.archive/230601/00-acl_claim.sql diff --git a/db/changes/230601/00-acl_notifications.sql b/db/.archive/230601/00-acl_notifications.sql similarity index 100% rename from db/changes/230601/00-acl_notifications.sql rename to db/.archive/230601/00-acl_notifications.sql diff --git a/db/changes/230601/00-itemConfig_warehouseFk.sql b/db/.archive/230601/00-itemConfig_warehouseFk.sql similarity index 100% rename from db/changes/230601/00-itemConfig_warehouseFk.sql rename to db/.archive/230601/00-itemConfig_warehouseFk.sql diff --git a/db/changes/230601/00-uniqueKeyNotificationSubscription.sql b/db/.archive/230601/00-uniqueKeyNotificationSubscription.sql similarity index 100% rename from db/changes/230601/00-uniqueKeyNotificationSubscription.sql rename to db/.archive/230601/00-uniqueKeyNotificationSubscription.sql diff --git a/db/changes/230601/01-alter_notSubs.sql b/db/.archive/230601/01-alter_notSubs.sql similarity index 100% rename from db/changes/230601/01-alter_notSubs.sql rename to db/.archive/230601/01-alter_notSubs.sql diff --git a/db/changes/230801/00-acl_itemConfig.sql b/db/.archive/230801/00-acl_itemConfig.sql similarity index 100% rename from db/changes/230801/00-acl_itemConfig.sql rename to db/.archive/230801/00-acl_itemConfig.sql diff --git a/db/changes/230801/00-supplierIsVies.sql b/db/.archive/230801/00-supplierIsVies.sql similarity index 100% rename from db/changes/230801/00-supplierIsVies.sql rename to db/.archive/230801/00-supplierIsVies.sql diff --git a/db/changes/230801/00-workerLocker.sql b/db/.archive/230801/00-workerLocker.sql similarity index 100% rename from db/changes/230801/00-workerLocker.sql rename to db/.archive/230801/00-workerLocker.sql diff --git a/db/changes/230801/01-sage_supplierAdd.sql b/db/.archive/230801/01-sage_supplierAdd.sql similarity index 100% rename from db/changes/230801/01-sage_supplierAdd.sql rename to db/.archive/230801/01-sage_supplierAdd.sql diff --git a/db/changes/231001/00-delivery.sql b/db/.archive/231001/00-delivery.sql similarity index 100% rename from db/changes/231001/00-delivery.sql rename to db/.archive/231001/00-delivery.sql diff --git a/db/changes/231001/00-invoiceOut.sql b/db/.archive/231001/00-invoiceOut.sql similarity index 100% rename from db/changes/231001/00-invoiceOut.sql rename to db/.archive/231001/00-invoiceOut.sql diff --git a/db/changes/231001/00-invoiceOut_getWeight.sql b/db/.archive/231001/00-invoiceOut_getWeight.sql similarity index 100% rename from db/changes/231001/00-invoiceOut_getWeight.sql rename to db/.archive/231001/00-invoiceOut_getWeight.sql diff --git a/db/changes/231001/00-report.sql b/db/.archive/231001/00-report.sql similarity index 100% rename from db/changes/231001/00-report.sql rename to db/.archive/231001/00-report.sql diff --git a/db/changes/231001/01-invoiceOut_getMaxIssued.sql b/db/.archive/231001/01-invoiceOut_getMaxIssued.sql similarity index 100% rename from db/changes/231001/01-invoiceOut_getMaxIssued.sql rename to db/.archive/231001/01-invoiceOut_getMaxIssued.sql diff --git a/db/changes/231001/02-invoiceOut_new.sql b/db/.archive/231001/02-invoiceOut_new.sql similarity index 100% rename from db/changes/231001/02-invoiceOut_new.sql rename to db/.archive/231001/02-invoiceOut_new.sql diff --git a/db/changes/231001/03-ticketPackaging_add.sql b/db/.archive/231001/03-ticketPackaging_add.sql similarity index 100% rename from db/changes/231001/03-ticketPackaging_add.sql rename to db/.archive/231001/03-ticketPackaging_add.sql diff --git a/db/changes/231801/00-client_setRatingAcl.sql b/db/changes/231801/00-client_setRatingAcl.sql index b041b131a..6687b11ec 100644 --- a/db/changes/231801/00-client_setRatingAcl.sql +++ b/db/changes/231801/00-client_setRatingAcl.sql @@ -27,7 +27,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp ('Client', 'summary', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'updateAddress', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'updateFiscalData', '*', 'ALLOW', 'ROLE', 'employee'), - ('Client', 'updateUser', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'uploadFile', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'campaignMetricsPdf', '*', 'ALLOW', 'ROLE', 'employee'), ('Client', 'campaignMetricsEmail', '*', 'ALLOW', 'ROLE', 'employee'), diff --git a/db/changes/232201/.gitkeep b/db/changes/232401/.gitkeep similarity index 100% rename from db/changes/232201/.gitkeep rename to db/changes/232401/.gitkeep diff --git a/db/changes/232401/00-useSpecificsAcls.sql b/db/changes/232401/00-useSpecificsAcls.sql new file mode 100644 index 000000000..0d17ca948 --- /dev/null +++ b/db/changes/232401/00-useSpecificsAcls.sql @@ -0,0 +1,121 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'), + ('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'deliveryBoss'), + ('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'buyer'), + ('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'claimManager'), + ('Ticket', 'deleteTicketWithPartPrepared', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Ticket', 'editZone', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'), + ('State', 'editableStates', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'production'), + ('State', 'isSomeEditable', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('State', 'isAllEditable', 'READ', 'ALLOW', 'ROLE', 'production'), + ('State', 'isAllEditable', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'administrative'), + ('Agency', 'seeExpired', 'READ', 'ALLOW', 'ROLE', 'productionBoss'), + ('Claim', 'createAfterDeadline', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Client', 'editAddressLogifloraAllowed', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Client', 'editFiscalDataWithoutTaxDataCheck', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Client', 'editVerifiedDataWithoutTaxDataCheck', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'), + ('Client', 'editCredit', 'WRITE', 'ALLOW', 'ROLE', 'financialBoss'), + ('Client', 'isNotEditableCredit', 'WRITE', 'ALLOW', 'ROLE', 'financialBoss'), + ('InvoiceOut', 'canCreatePdf', 'WRITE', 'ALLOW', 'ROLE', 'invoicing'), + ('Supplier', 'editPayMethodCheck', 'WRITE', 'ALLOW', 'ROLE', 'financial'), + ('Worker', 'isTeamBoss', 'WRITE', 'ALLOW', 'ROLE', 'teamBoss'), + ('Worker', 'forceIsSubordinate', 'READ', 'ALLOW', 'ROLE', 'hr'), + ('Claim', 'editState', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'); + +DELETE FROM `salix`.`ACL` + WHERE + model = 'Claim' + AND property = '*' + AND accessType = '*'; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Claim', 'find', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'findById', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'findOne', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'getSummary', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'updateClaim', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'regularizeClaim', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'updateClaimDestination', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'downloadFile', 'READ', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'), + ('Claim', 'filter', 'READ', 'ALLOW', 'ROLE', 'salesPerson'), + ('Claim', 'logs', 'READ', 'ALLOW', 'ROLE', 'claimManager'); + +DELETE FROM `salix`.`ACL` + WHERE + model = 'Ticket' + AND property = '*' + AND accessType = '*'; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Ticket', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getVolume', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getTotalVolume', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'summary', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'priceDifference', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'componentUpdate', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'new', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'isEditable', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'setDeleted', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'restore', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getSales', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getSalesPersonMana', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'makeInvoice', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'updateEditableTicket', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'updateDiscount', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'transferSales', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'sendSms', 'WRITE', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'isLocked', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'freightCost', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'getComponentsSum', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Ticket', 'updateAttributes', 'WRITE', 'ALLOW', 'ROLE', 'delivery'), -- Change Priority in Route tickets + ('Ticket', 'deliveryNoteCsv', 'READ', 'ALLOW', 'ROLE', 'employee'); + +DELETE FROM `salix`.`ACL` + WHERE + model = 'State' + AND property = '*' + AND accessType = 'READ'; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('State', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('State', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('State', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'); + +DELETE FROM `salix`.`ACL` + WHERE + model = 'Worker' + AND property = '*' + AND accessType = 'READ'; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Worker', 'find', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'findById', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'findOne', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'getWorkedHours', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'active', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'activeWithRole', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'hr'), + ('Worker', 'contracts', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'holidays', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'activeContract', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('Worker', 'activeWithInheritedRole', 'READ', 'ALLOW', 'ROLE', 'employee'); + +DELETE FROM `salix`.`ACL` + WHERE model = 'Client' + AND property = 'updateUser' + AND accessType = '*'; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 1304a6ec7..15fa96a79 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2332,26 +2332,26 @@ INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`, ` INSERT INTO `vn`.`dmsType`(`id`, `name`, `path`, `readRoleFk`, `writeRoleFk`, `code`) VALUES - (1, 'Facturas Recibidas', 'recibidas', NULL, NULL, 'invoiceIn'), - (2, 'Doc oficial', 'oficial', NULL, NULL, 'officialDoc'), - (3, 'Laboral', 'laboral', 37, 37, 'hhrrData'), - (4, 'Albaranes recibidos', 'entradas', NULL, NULL, 'deliveryNote'), - (5, 'Otros', 'otros', 1, 1, 'miscellaneous'), - (6, 'Pruebas', 'pruebas', NULL, NULL, 'tests'), - (7, 'IAE Clientes', 'IAE_Clientes', 1, 1, 'economicActivitiesTax'), - (8, 'Fiscal', 'fiscal', NULL, NULL, 'fiscal'), - (9, 'Vehiculos', 'vehiculos', NULL, NULL, 'vehicles'), - (10, 'Plantillas', 'plantillas', NULL, NULL, 'templates'), - (11, 'Contratos', 'contratos', NULL, NULL, 'contracts'), - (12, 'ley de pagos', 'ley pagos', 1, 1, 'paymentsLaw'), - (13, 'Basura', 'basura', 1, 1, 'trash'), - (14, 'Ticket', 'tickets', 1, 1, 'ticket'), - (15, 'Presupuestos', 'Presupuestos', NULL, NULL, 'budgets'), - (16, 'Logistica', 'logistica', NULL, NULL, 'logistics'), - (17, 'cmr', 'cmr', NULL, NULL, 'cmr'), - (18, 'dua', 'dua', NULL, NULL, 'dua'), - (19, 'inmovilizado', 'inmovilizado', NULL, NULL, 'fixedAssets'), - (20, 'Reclamación', 'reclamacion', 1, 1, 'claim'); + (1, 'Facturas Recibidas', 'recibidas', NULL, NULL, 'invoiceIn'), + (2, 'Doc oficial', 'oficial', NULL, NULL, 'officialDoc'), + (3, 'Laboral', 'laboral', 37, 37, 'hhrrData'), + (4, 'Albaranes recibidos', 'entradas', NULL, NULL, 'deliveryNote'), + (5, 'Otros', 'otros', 1, 1, 'miscellaneous'), + (6, 'Pruebas', 'pruebas', NULL, NULL, 'tests'), + (7, 'IAE Clientes', 'IAE_Clientes', 1, 1, 'economicActivitiesTax'), + (8, 'Fiscal', 'fiscal', NULL, NULL, 'fiscal'), + (9, 'Vehiculos', 'vehiculos', NULL, NULL, 'vehicles'), + (10, 'Plantillas', 'plantillas', NULL, NULL, 'templates'), + (11, 'Contratos', 'contratos', NULL, NULL, 'contracts'), + (12, 'ley de pagos', 'ley pagos', 1, 1, 'paymentsLaw'), + (13, 'Basura', 'basura', 1, 1, 'trash'), + (14, 'Ticket', 'tickets', 1, 1, 'ticket'), + (15, 'Presupuestos', 'Presupuestos', NULL, NULL, 'budgets'), + (16, 'Logistica', 'logistica', NULL, NULL, 'logistics'), + (17, 'cmr', 'cmr', NULL, NULL, 'cmr'), + (18, 'dua', 'dua', NULL, NULL, 'dua'), + (19, 'inmovilizado', 'inmovilizado', NULL, NULL, 'fixedAssets'), + (20, 'Reclamación', 'reclamacion', 1, 1, 'claim'); INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`) VALUES diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 086909ebf..dcd9211f9 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -625,6 +625,7 @@ export default { selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check', secondSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(2) vn-check[ng-model="sale.checked"]', thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[ng-model="sale.checked"]', + fourthSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(4) vn-check[ng-model="sale.checked"]', deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]', transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]', moveToTicketInput: 'form vn-input-number[ng-model="$ctrl.transfer.ticketId"] input', diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index 2158eec8b..2c9646708 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -251,7 +251,6 @@ describe('Ticket Edit sale path', () => { await page.waitToClick(selectors.ticketSales.moreMenu); await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim); await page.waitToClick(selectors.globalItems.acceptButton); - await page.waitToClick(selectors.globalItems.acceptButton); await page.waitForState('claim.card.basicData'); }); diff --git a/e2e/paths/06-claim/05_summary.spec.js b/e2e/paths/06-claim/05_summary.spec.js index 758dc2ee3..9656ea656 100644 --- a/e2e/paths/06-claim/05_summary.spec.js +++ b/e2e/paths/06-claim/05_summary.spec.js @@ -17,7 +17,7 @@ describe('Claim summary path', () => { }); it('should navigate to the target claim summary section', async() => { - await page.loginAndModule('employee', 'claim'); + await page.loginAndModule('salesPerson', 'claim'); await page.accessToSearchResult(claimId); await page.waitForState('claim.card.summary'); }); diff --git a/e2e/paths/06-claim/06_descriptor.spec.js b/e2e/paths/06-claim/06_descriptor.spec.js index 0826bad63..059bd68dd 100644 --- a/e2e/paths/06-claim/06_descriptor.spec.js +++ b/e2e/paths/06-claim/06_descriptor.spec.js @@ -16,7 +16,7 @@ describe('Claim descriptor path', () => { }); it('should now navigate to the target claim summary section', async() => { - await page.loginAndModule('employee', 'claim'); + await page.loginAndModule('salesPerson', 'claim'); await page.accessToSearchResult(claimId); await page.waitForState('claim.card.summary'); }); diff --git a/front/salix/components/descriptor/style.scss b/front/salix/components/descriptor/style.scss index 27f482f26..b96e900c4 100644 --- a/front/salix/components/descriptor/style.scss +++ b/front/salix/components/descriptor/style.scss @@ -7,22 +7,24 @@ vn-descriptor-content { .photo { position: relative; + width: 100%; + text-align: center; + overflow: hidden; & > img[ng-src] { min-height: 16em; display: block; - max-width: 100%; height: 256px; } vn-float-button { - position: absolute; - margin: 1em; - bottom: 0; + position: absolute; + margin: 1em; + bottom: 0; right: 0 } } - + & > vn-spinner { display: block; height: 40px; @@ -39,7 +41,7 @@ vn-descriptor-content { align-items: stretch; color: $color-font-dark; - & > a, + & > a, & > vn-icon-button { display: flex; min-width: 45px; @@ -89,7 +91,7 @@ vn-descriptor-content { display: flex; align-items: center; justify-content: center; - + & > vn-icon { padding: $spacing-xs $spacing-sm; font-size: 1.5rem; diff --git a/loopback/locale/en.json b/loopback/locale/en.json index e950b981b..14ffffeb5 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -171,5 +171,7 @@ "Added observation": "Added observation", "Comment added to client": "Comment added to client", "This ticket is already a refund": "This ticket is already a refund", - "A claim with that sale already exists": "A claim with that sale already exists" + "A claim with that sale already exists": "A claim with that sale already exists", + "Can't transfer claimed sales": "Can't transfer claimed sales", + "Invalid quantity": "Invalid quantity" } diff --git a/modules/claim/back/methods/claim/createFromSales.js b/modules/claim/back/methods/claim/createFromSales.js index 10d0b9b28..07bdb30aa 100644 --- a/modules/claim/back/methods/claim/createFromSales.js +++ b/modules/claim/back/methods/claim/createFromSales.js @@ -59,12 +59,14 @@ module.exports = Self => { const landedPlusWeek = new Date(ticket.landed); landedPlusWeek.setDate(landedPlusWeek.getDate() + 7); - const hasClaimManagerRole = await models.VnUser.hasRole(userId, 'claimManager', myOptions); const isClaimable = landedPlusWeek >= Date.vnNew(); + const canCreateClaimAfterDeadline = + await models.ACL.checkAccessAcl(ctx, 'Claim', 'createAfterDeadline', 'WRITE'); + if (ticket.isDeleted) throw new UserError(`You can't create a claim for a removed ticket`); - if (!isClaimable && !hasClaimManagerRole) + if (!isClaimable && !canCreateClaimAfterDeadline) throw new UserError(`You can't create a claim from a ticket delivered more than seven days ago`); const newClaim = await Self.create({ diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index f10c68b21..cc7392e39 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -46,7 +46,6 @@ module.exports = Self => { Self.updateClaim = async(ctx, id, options) => { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; const args = ctx.args; let tx; const myOptions = {}; @@ -81,9 +80,9 @@ module.exports = Self => { if (args.claimStateFk) { const canEditOldState = await models.ClaimState.isEditable(ctx, claim.claimStateFk, myOptions); const canEditNewState = await models.ClaimState.isEditable(ctx, args.claimStateFk, myOptions); - const isClaimManager = await models.VnUser.hasRole(userId, 'claimManager', myOptions); + const canEditState = await models.ACL.checkAccessAcl(ctx, 'Claim', 'editState', 'WRITE'); - if (!canEditOldState || !canEditNewState || changedHasToPickUp && !isClaimManager) + if (!canEditOldState || !canEditNewState || changedHasToPickUp && !canEditState) throw new UserError(`You don't have enough privileges to change that field`); } diff --git a/modules/client/back/methods/client/updateAddress.js b/modules/client/back/methods/client/updateAddress.js index e521870fd..7342b28f1 100644 --- a/modules/client/back/methods/client/updateAddress.js +++ b/modules/client/back/methods/client/updateAddress.js @@ -87,15 +87,15 @@ module.exports = function(Self) { Self.updateAddress = async(ctx, clientId, addressId, options) => { const models = Self.app.models; const args = ctx.args; - const userId = ctx.req.accessToken.userId; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', myOptions); + const canEditAddressLogifloraAllowed = + await models.ACL.checkAccessAcl(ctx, 'Client', 'editAddressLogifloraAllowed'); - if (args.isLogifloraAllowed && !isSalesAssistant) + if (args.isLogifloraAllowed && !canEditAddressLogifloraAllowed) throw new UserError(`You don't have enough privileges`); const address = await models.Address.findOne({ diff --git a/modules/client/back/methods/client/updateFiscalData.js b/modules/client/back/methods/client/updateFiscalData.js index c63dc3991..697c567a3 100644 --- a/modules/client/back/methods/client/updateFiscalData.js +++ b/modules/client/back/methods/client/updateFiscalData.js @@ -131,9 +131,10 @@ module.exports = Self => { myOptions.transaction = tx; } try { - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', myOptions); + const canEditNotTaxDataChecked = + await models.ACL.checkAccessAcl(ctx, 'Client', 'editFiscalDataWithoutTaxDataCheck', 'WRITE'); const client = await models.Client.findById(clientId, null, myOptions); - if (!isSalesAssistant && client.isTaxDataChecked) + if (!canEditNotTaxDataChecked && client.isTaxDataChecked) throw new UserError(`Not enough privileges to edit a client with verified data`); // Sage data validation const taxDataChecked = args.isTaxDataChecked; diff --git a/modules/client/back/methods/client/updateUser.js b/modules/client/back/methods/client/updateUser.js index 479b4da47..55f1accdd 100644 --- a/modules/client/back/methods/client/updateUser.js +++ b/modules/client/back/methods/client/updateUser.js @@ -2,6 +2,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('updateUser', { description: 'Updates the user information', + accessType: 'WRITE', accepts: [ { arg: 'id', @@ -32,7 +33,6 @@ module.exports = Self => { Self.updateUser = async function(ctx, id, options) { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; let tx; const myOptions = {}; @@ -45,9 +45,8 @@ module.exports = Self => { } try { - const isSalesPerson = await models.VnUser.hasRole(userId, 'salesPerson', myOptions); - - if (!isSalesPerson) + const canEdit = await models.ACL.checkAccessAcl(ctx, 'Client', 'updateUser', 'WRITE'); + if (!canEdit) throw new UserError(`Not enough privileges to edit a client`); const isClient = await models.Client.findById(id, null, myOptions); diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 56adc8b03..7b577fa98 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -218,9 +218,9 @@ module.exports = Self => { const models = Self.app.models; const loopBackContext = LoopBackContext.getCurrentContext(); - const userId = loopBackContext.active.accessToken.userId; + const accessToken = {req: loopBackContext.active.accessToken}; - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', ctx.options); + const editVerifiedDataWithoutTaxDataChecked = models.ACL.checkAccessAcl(accessToken, 'Client', 'editVerifiedDataWithoutTaxDataCheck', 'WRITE'); const hasChanges = orgData && changes; const isTaxDataChecked = hasChanges && (changes.isTaxDataChecked || orgData.isTaxDataChecked); @@ -232,8 +232,8 @@ module.exports = Self => { const sageTransactionType = hasChanges && (changes.sageTransactionTypeFk || orgData.sageTransactionTypeFk); const sageTransactionTypeChanged = hasChanges && orgData.sageTransactionTypeFk != sageTransactionType; - const cantEditVerifiedData = isTaxDataCheckedChanged && !isSalesAssistant; - const cantChangeSageData = (sageTaxTypeChanged || sageTransactionTypeChanged) && !isSalesAssistant; + const cantEditVerifiedData = isTaxDataCheckedChanged && !editVerifiedDataWithoutTaxDataChecked; + const cantChangeSageData = (sageTaxTypeChanged || sageTransactionTypeChanged) && !editVerifiedDataWithoutTaxDataChecked; if (cantEditVerifiedData || cantChangeSageData) throw new UserError(`You don't have enough privileges`); @@ -401,9 +401,10 @@ module.exports = Self => { Self.changeCredit = async function changeCredit(ctx, finalState, changes) { const models = Self.app.models; const userId = ctx.options.accessToken.userId; + const accessToken = {req: {accessToken: ctx.options.accessToken} }; - const isFinancialBoss = await models.VnUser.hasRole(userId, 'financialBoss', ctx.options); - if (!isFinancialBoss) { + const canEditCredit = await models.ACL.checkAccessAcl(accessToken, 'Client', 'editCredit', 'WRITE'); + if (!canEditCredit) { const lastCredit = await models.ClientCredit.findOne({ where: { clientFk: finalState.id @@ -412,10 +413,9 @@ module.exports = Self => { }, ctx.options); const lastAmount = lastCredit && lastCredit.amount; - const lastWorkerId = lastCredit && lastCredit.workerFk; - const lastWorkerIsFinancialBoss = await models.VnUser.hasRole(lastWorkerId, 'financialBoss', ctx.options); + const lastCreditIsNotEditable = !await models.ACL.checkAccessAcl(accessToken, 'Client', 'isNotEditableCredit', 'WRITE'); - if (lastAmount == 0 && lastWorkerIsFinancialBoss) + if (lastAmount == 0 && lastCreditIsNotEditable) throw new UserError(`You can't change the credit set to zero from a financialBoss`); const creditLimits = await models.ClientCreditLimit.find({ diff --git a/modules/client/front/dms/edit/index.html b/modules/client/front/dms/edit/index.html index 87d69fdcd..58899df2b 100644 --- a/modules/client/front/dms/edit/index.html +++ b/modules/client/front/dms/edit/index.html @@ -2,6 +2,11 @@ vn-id="watcher" data="$ctrl.dms"> + +
diff --git a/modules/entry/front/basic-data/index.html b/modules/entry/front/basic-data/index.html index 0b3537fac..888205320 100644 --- a/modules/entry/front/basic-data/index.html +++ b/modules/entry/front/basic-data/index.html @@ -5,6 +5,11 @@ form="form" save="patch"> + + @@ -152,14 +157,14 @@ diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index a9c151ae4..dfdb3c1a7 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -25,7 +25,6 @@ module.exports = Self => { Self.createPdf = async function(ctx, id, options) { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; if (process.env.NODE_ENV == 'test') throw new UserError(`Action not allowed on the test environment`); @@ -43,9 +42,9 @@ module.exports = Self => { try { const invoiceOut = await Self.findById(id, null, myOptions); - const hasInvoicing = await models.VnUser.hasRole(userId, 'invoicing', myOptions); + const canCreatePdf = await models.ACL.checkAccessAcl(ctx, 'InvoiceOut', 'canCreatePdf', 'WRITE'); - if (invoiceOut.hasPdf && !hasInvoicing) + if (invoiceOut.hasPdf && !canCreatePdf) throw new UserError(`You don't have enough privileges`); await invoiceOut.updateAttributes({ diff --git a/modules/item/front/descriptor/index.html b/modules/item/front/descriptor/index.html index 8e85e043f..7c442d364 100644 --- a/modules/item/front/descriptor/index.html +++ b/modules/item/front/descriptor/index.html @@ -1,3 +1,8 @@ + + + data="warehouses" + show-field="name" + value="id"> diff --git a/modules/item/front/request-search-panel/index.html b/modules/item/front/request-search-panel/index.html index dfafb02f3..a76684776 100644 --- a/modules/item/front/request-search-panel/index.html +++ b/modules/item/front/request-search-panel/index.html @@ -1,4 +1,9 @@
+ + + data="warehouses" + show-field="name" + value-field="id"> diff --git a/modules/monitor/front/index/search-panel/index.html b/modules/monitor/front/index/search-panel/index.html index 5458202d2..822f84922 100644 --- a/modules/monitor/front/index/search-panel/index.html +++ b/modules/monitor/front/index/search-panel/index.html @@ -1,4 +1,9 @@
+ + + data="Warehouses"> + + + + diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index ae3eb4bcc..e113e5d59 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -99,18 +99,20 @@ module.exports = Self => { Self.observe('before save', async function(ctx) { if (ctx.isNewInstance) return; - const loopbackContext = LoopBackContext.getCurrentContext(); const changes = ctx.data || ctx.instance; const orgData = ctx.currentInstance; - const userId = loopbackContext.active.accessToken.userId; + const loopBackContext = LoopBackContext.getCurrentContext(); + const accessToken = {req: loopBackContext.active.accessToken}; + + const editPayMethodCheck = + await Self.app.models.ACL.checkAccessAcl(accessToken, 'Supplier', 'editPayMethodCheck', 'WRITE'); - const isNotFinancial = !await Self.app.models.VnUser.hasRole(userId, 'financial'); const isPayMethodChecked = changes.isPayMethodChecked || orgData.isPayMethodChecked; const hasChanges = orgData && changes; const isPayMethodCheckedChanged = hasChanges && orgData.isPayMethodChecked != isPayMethodChecked; - if (isNotFinancial && isPayMethodCheckedChanged) + if (!editPayMethodCheck && isPayMethodCheckedChanged) throw new UserError('You can not modify is pay method checked'); }); diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 4778f6b6d..80adb0bd1 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -64,7 +64,7 @@ describe('sale updateQuantity()', () => { try { const options = {transaction: tx}; - const isRoleAdvanced = await models.Ticket.isRoleAdvanced(ctx, options); + const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); expect(isRoleAdvanced).toEqual(true); diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index d2927c65c..421c74702 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -64,7 +64,7 @@ module.exports = Self => { const sale = await models.Sale.findById(id, filter, myOptions); - const isRoleAdvanced = await models.Ticket.isRoleAdvanced(ctx, myOptions); + const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); if (newQuantity > sale.quantity && !isRoleAdvanced) throw new UserError('The new quantity should be smaller than the old one'); diff --git a/modules/ticket/back/methods/state/editableStates.js b/modules/ticket/back/methods/state/editableStates.js index 487814dd2..1ddfbffa2 100644 --- a/modules/ticket/back/methods/state/editableStates.js +++ b/modules/ticket/back/methods/state/editableStates.js @@ -19,13 +19,11 @@ module.exports = Self => { Self.editableStates = async(ctx, filter, options) => { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; const myOptions = {...(options || {})}; - const isProduction = await models.VnUser.hasRole(userId, 'production', myOptions); - const isAdministrative = await models.VnUser.hasRole(userId, 'administrative', myOptions); + const seeEditableStates = await models.ACL.checkAccessAcl(ctx, 'State', 'seeEditableStates', 'READ'); - if (!isProduction && !isAdministrative) + if (!seeEditableStates) filter = mergeFilters(filter, {where: {alertLevel: 0}}); const states = await models.State.find(filter, myOptions); diff --git a/modules/ticket/back/methods/state/isEditable.js b/modules/ticket/back/methods/state/isEditable.js index 730e6b9eb..ec246c61f 100644 --- a/modules/ticket/back/methods/state/isEditable.js +++ b/modules/ticket/back/methods/state/isEditable.js @@ -19,22 +19,23 @@ module.exports = Self => { }); Self.isEditable = async(ctx, stateId, options) => { - const accessToken = ctx.req.accessToken; const models = Self.app.models; - const userId = accessToken.userId; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const isProduction = await models.VnUser.hasRole(userId, 'production', myOptions); - const isSalesPerson = await models.VnUser.hasRole(userId, 'salesPerson', myOptions); - const isAdministrative = await models.VnUser.hasRole(userId, 'administrative', myOptions); + const isAllEditable = await models.ACL.checkAccessAcl(ctx, 'State', 'isAllEditable', 'READ'); + const state = await models.State.findById(stateId, null, myOptions); + const isSomeEditable = ( + await models.ACL.checkAccessAcl(ctx, 'State', 'isSomeEditable', 'READ') + && ( + state.code == 'PICKER_DESIGNED' || state.code == 'PRINTED' + ) + ); - const salesPersonAllowed = (isSalesPerson && (state.code == 'PICKER_DESIGNED' || state.code == 'PRINTED')); - - const isAllowed = isProduction || isAdministrative || salesPersonAllowed || state.alertLevel == 0; + const isAllowed = isAllEditable || isSomeEditable || state.alertLevel == 0; return isAllowed; }; }; diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index b03301204..dac8e4f52 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -121,8 +121,8 @@ module.exports = Self => { if (!isEditable) throw new UserError(`The sales of this ticket can't be modified`); - const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions); - if (!isDeliveryBoss) { + const editZone = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'editZone', 'WRITE'); + if (!editZone) { const zoneShipped = await models.Agency.getShipped( ctx, args.landed, diff --git a/modules/ticket/back/methods/ticket/isEditable.js b/modules/ticket/back/methods/ticket/isEditable.js index d8fbb86ce..13bd4d57f 100644 --- a/modules/ticket/back/methods/ticket/isEditable.js +++ b/modules/ticket/back/methods/ticket/isEditable.js @@ -30,7 +30,7 @@ module.exports = Self => { where: {ticketFk: id} }, myOptions); - const isRoleAdvanced = await models.Ticket.isRoleAdvanced(ctx, myOptions); + const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); const alertLevel = state ? state.alertLevel : null; const ticket = await models.Ticket.findById(id, { diff --git a/modules/ticket/back/methods/ticket/isRoleAdvanced.js b/modules/ticket/back/methods/ticket/isRoleAdvanced.js deleted file mode 100644 index d6186a0c9..000000000 --- a/modules/ticket/back/methods/ticket/isRoleAdvanced.js +++ /dev/null @@ -1,32 +0,0 @@ -module.exports = Self => { - Self.remoteMethodCtx('isRoleAdvanced', { - description: 'Check if a ticket is editable', - accessType: 'READ', - returns: { - type: 'boolean', - root: true - }, - http: { - path: `/isRoleAdvanced`, - verb: 'GET' - } - }); - - Self.isRoleAdvanced = async(ctx, options) => { - const models = Self.app.models; - const userId = ctx.req.accessToken.userId; - const myOptions = {}; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', myOptions); - const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions); - const isBuyer = await models.VnUser.hasRole(userId, 'buyer', myOptions); - const isClaimManager = await models.VnUser.hasRole(userId, 'claimManager', myOptions); - - const isRoleAdvanced = isSalesAssistant || isDeliveryBoss || isBuyer || isClaimManager; - - return isRoleAdvanced; - }; -}; diff --git a/modules/ticket/back/methods/ticket/merge.js b/modules/ticket/back/methods/ticket/merge.js index 8aaca1085..9a6f859f7 100644 --- a/modules/ticket/back/methods/ticket/merge.js +++ b/modules/ticket/back/methods/ticket/merge.js @@ -63,10 +63,11 @@ module.exports = Self => { newInstance: {mergedTicket: ticket.originId} }; - await models.TicketLog.create(ticketDestinationLogRecord, myOptions); await models.Sale.updateAll({ticketFk: ticket.originId}, {ticketFk: ticket.destinationId}, myOptions); - await models.Ticket.setDeleted(ctx, ticket.originId, myOptions); - await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message); + if (await models.Ticket.setDeleted(ctx, ticket.originId, myOptions)) { + await models.TicketLog.create(ticketDestinationLogRecord, myOptions); + await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message); + } } if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 16812dcb0..27fdb9160 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -60,7 +60,6 @@ module.exports = Self => { Self.priceDifference = async(ctx, options) => { const args = ctx.args; const models = Self.app.models; - const userId = ctx.req.accessToken.userId; const myOptions = {}; let tx; @@ -78,8 +77,8 @@ module.exports = Self => { if (!isEditable) throw new UserError(`The sales of this ticket can't be modified`); - const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions); - if (!isDeliveryBoss) { + const editZone = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'editZone', 'WRITE'); + if (!editZone) { const zoneShipped = await models.Agency.getShipped( ctx, args.landed, diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index 2889160d1..228e2e765 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -36,7 +36,9 @@ module.exports = Self => { } try { - const userId = ctx.req.accessToken.userId; + const ticketToDelete = await models.Ticket.findById(id, {fields: ['isDeleted']}, myOptions); + if (ticketToDelete.isDeleted) return false; + const isEditable = await Self.isEditable(ctx, id, myOptions); if (!isEditable) @@ -51,7 +53,8 @@ module.exports = Self => { throw new UserError($t('Tickets with associated refunds', {id: ticketRefunds[0].id})); // Check if has sales with shelving - const isSalesAssistant = await models.VnUser.hasRole(userId, 'salesAssistant', myOptions); + const canDeleteTicketWithPartPrepared = + await models.ACL.checkAccessAcl(ctx, 'Ticket', 'deleteTicketWithPartPrepared', 'WRITE'); const sales = await models.Sale.find({ include: {relation: 'itemShelvingSale'}, where: {ticketFk: id} @@ -60,7 +63,7 @@ module.exports = Self => { return sale.itemShelvingSale(); }); - if (hasItemShelvingSales && !isSalesAssistant) + if (hasItemShelvingSales && !canDeleteTicketWithPartPrepared) throw new UserError(`You cannot delete a ticket that part of it is being prepared`); // Check for existing claim diff --git a/modules/ticket/back/methods/ticket/transferSales.js b/modules/ticket/back/methods/ticket/transferSales.js index e3137487f..5737e628f 100644 --- a/modules/ticket/back/methods/ticket/transferSales.js +++ b/modules/ticket/back/methods/ticket/transferSales.js @@ -3,6 +3,7 @@ let UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('transferSales', { description: 'Transfer sales to a new or a given ticket', + accessType: 'WRITE', accepts: [{ arg: 'id', type: 'number', diff --git a/modules/ticket/back/methods/ticket/updateDiscount.js b/modules/ticket/back/methods/ticket/updateDiscount.js index 8300db886..4b31c0ce4 100644 --- a/modules/ticket/back/methods/ticket/updateDiscount.js +++ b/modules/ticket/back/methods/ticket/updateDiscount.js @@ -85,17 +85,14 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; const isLocked = await models.Ticket.isLocked(id, myOptions); - const roles = await models.VnUser.getRoles(userId, myOptions); - const hasAllowedRoles = roles.filter(role => - role == 'salesPerson' || role == 'claimManager' - ); + const canEditDiscount = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'editDiscount'); const state = await Self.app.models.TicketState.findOne({ where: {ticketFk: id} }, myOptions); const alertLevel = state ? state.alertLevel : null; - if (isLocked || (!hasAllowedRoles && alertLevel > 0)) + if (isLocked || (!canEditDiscount && alertLevel > 0)) throw new UserError(`The sales of this ticket can't be modified`); const usesMana = await models.Sale.usesMana(ctx, myOptions); diff --git a/modules/ticket/back/models/ticket-methods.js b/modules/ticket/back/models/ticket-methods.js index 3992e7307..e5a8e8d94 100644 --- a/modules/ticket/back/models/ticket-methods.js +++ b/modules/ticket/back/models/ticket-methods.js @@ -36,7 +36,6 @@ module.exports = function(Self) { require('../methods/ticket/getTicketsFuture')(Self); require('../methods/ticket/merge')(Self); require('../methods/ticket/getTicketsAdvance')(Self); - require('../methods/ticket/isRoleAdvanced')(Self); require('../methods/ticket/collectionLabel')(Self); require('../methods/ticket/expeditionPalletLabel')(Self); require('../methods/ticket/saveSign')(Self); diff --git a/modules/ticket/front/advance-search-panel/index.html b/modules/ticket/front/advance-search-panel/index.html index ee18c26f9..c2f5ecd8f 100644 --- a/modules/ticket/front/advance-search-panel/index.html +++ b/modules/ticket/front/advance-search-panel/index.html @@ -1,4 +1,9 @@
+ + diff --git a/modules/ticket/front/basic-data/step-one/index.html b/modules/ticket/front/basic-data/step-one/index.html index 498630b87..73df8c370 100644 --- a/modules/ticket/front/basic-data/step-one/index.html +++ b/modules/ticket/front/basic-data/step-one/index.html @@ -4,6 +4,11 @@ order="name" auto-load="true"> + + @@ -25,7 +30,7 @@ + + diff --git a/modules/ticket/front/future-search-panel/index.html b/modules/ticket/front/future-search-panel/index.html index 18b574f2a..d873fbc37 100644 --- a/modules/ticket/front/future-search-panel/index.html +++ b/modules/ticket/front/future-search-panel/index.html @@ -1,4 +1,9 @@
+ + diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index b2c0db18d..7d14a4fa3 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -61,20 +61,20 @@ - Visible - Available - Id - Quantity - Item - Price - Disc - Amount - Packaging + Visible + Available + Id + Quantity + Item + Price + Disc + Amount + Packaging - + @@ -481,7 +481,7 @@ on-accept="$ctrl.transferSales($ctrl.transfer.ticketId)"> - + on-accept="$ctrl.onCreateClaimAccepted()"> @@ -513,9 +513,9 @@ - Add claim + Add claim = this.ticketConfig[0].daysForWarningClaim) this.$.claimConfirm.show(); else - this.onCreateClaimAccepted(); + this.$.claimSure.show(); } onCreateClaimAccepted() { diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 5fb3b3df3..9da8e6e7c 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -758,5 +758,15 @@ describe('Ticket', () => { expect(controller.$.editDiscount.hide).toHaveBeenCalledWith(); }); }); + + describe('sortBy()', () => { + it('should set reverse and propertyName properties', () => { + const propertyName = 'id'; + controller.sortBy(propertyName); + + expect(controller.propertyName).toEqual(propertyName); + expect(controller.reverse).toEqual(false); + }); + }); }); }); diff --git a/modules/ticket/front/search-panel/index.html b/modules/ticket/front/search-panel/index.html index 7002f3dd6..d22b06a46 100644 --- a/modules/ticket/front/search-panel/index.html +++ b/modules/ticket/front/search-panel/index.html @@ -1,4 +1,9 @@
+ + + data="Warehouses"> + + diff --git a/modules/worker/back/methods/worker-dms/specs/downloadFile.spec.js b/modules/worker/back/methods/worker-dms/specs/downloadFile.spec.js index ac8e4539f..bdeec215c 100644 --- a/modules/worker/back/methods/worker-dms/specs/downloadFile.spec.js +++ b/modules/worker/back/methods/worker-dms/specs/downloadFile.spec.js @@ -1,4 +1,4 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('worker-dms downloadFile()', () => { let dmsId = 4; @@ -6,7 +6,7 @@ describe('worker-dms downloadFile()', () => { it('should return a response for an employee with text content-type', async() => { let workerId = 1106; let ctx = {req: {accessToken: {userId: workerId}}}; - const result = await app.models.WorkerDms.downloadFile(ctx, dmsId); + const result = await models.WorkerDms.downloadFile(ctx, dmsId); expect(result[1]).toEqual('text/plain'); }); @@ -17,7 +17,7 @@ describe('worker-dms downloadFile()', () => { let error; try { - await app.models.WorkerDms.downloadFile(ctx, dmsId); + await models.WorkerDms.downloadFile(ctx, dmsId); } catch (e) { error = e; } diff --git a/modules/worker/back/methods/worker-time-control/addTimeEntry.js b/modules/worker/back/methods/worker-time-control/addTimeEntry.js index 01a5a16ee..bcc96985f 100644 --- a/modules/worker/back/methods/worker-time-control/addTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/addTimeEntry.js @@ -40,10 +40,10 @@ module.exports = Self => { Object.assign(myOptions, options); const isSubordinate = await models.Worker.isSubordinate(ctx, workerId, myOptions); - const isTeamBoss = await models.VnUser.hasRole(currentUserId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); const isHimself = currentUserId == workerId; - if (isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss)) + if (!isSubordinate || (isSubordinate && isHimself && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); query = `CALL vn.workerTimeControl_clockIn(?,?,?)`; diff --git a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js index 1dcd12f5b..80482901f 100644 --- a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js @@ -32,7 +32,7 @@ module.exports = Self => { const targetTimeEntry = await Self.findById(id, null, myOptions); const isSubordinate = await models.Worker.isSubordinate(ctx, targetTimeEntry.userFk, myOptions); - const isTeamBoss = await models.VnUser.hasRole(currentUserId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); const isHimself = currentUserId == targetTimeEntry.userFk; if (isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss)) diff --git a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js index 344421311..8231be7bb 100644 --- a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js @@ -38,7 +38,7 @@ module.exports = Self => { const targetTimeEntry = await Self.findById(id, null, myOptions); const isSubordinate = await models.Worker.isSubordinate(ctx, targetTimeEntry.userFk, myOptions); - const isTeamBoss = await models.VnUser.hasRole(currentUserId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); const isHimself = currentUserId == targetTimeEntry.userFk; const notAllowed = isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss); diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index f53164a50..cb2cf8330 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -53,7 +53,7 @@ module.exports = Self => { try { const isSubordinate = await models.Worker.isSubordinate(ctx, id, myOptions); - const isTeamBoss = await models.VnUser.hasRole(userId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); if (!isSubordinate || (isSubordinate && userId == id && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); diff --git a/modules/worker/back/methods/worker/deleteAbsence.js b/modules/worker/back/methods/worker/deleteAbsence.js index 2d0078ba7..c315f5178 100644 --- a/modules/worker/back/methods/worker/deleteAbsence.js +++ b/modules/worker/back/methods/worker/deleteAbsence.js @@ -40,7 +40,7 @@ module.exports = Self => { try { const isSubordinate = await models.Worker.isSubordinate(ctx, id, myOptions); - const isTeamBoss = await models.VnUser.hasRole(userId, 'teamBoss', myOptions); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); if (!isSubordinate || (isSubordinate && userId == id && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); diff --git a/modules/worker/back/methods/worker/isSubordinate.js b/modules/worker/back/methods/worker/isSubordinate.js index 6c17ad0d0..53adc68b7 100644 --- a/modules/worker/back/methods/worker/isSubordinate.js +++ b/modules/worker/back/methods/worker/isSubordinate.js @@ -25,22 +25,15 @@ module.exports = Self => { Self.isSubordinate = async(ctx, id, options) => { const models = Self.app.models; - const myUserId = ctx.req.accessToken.userId; - const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); const mySubordinates = await Self.mySubordinates(ctx, myOptions); - const isSubordinate = mySubordinates.find(subordinate => { - return subordinate.workerFk == id; - }); + const isSubordinate = mySubordinates.some(subordinate => subordinate.workerFk == id); + const forceIsSubordinate = await models.ACL.checkAccessAcl(ctx, 'Worker', 'forceIsSubordinate', 'READ'); - const isHr = await models.VnUser.hasRole(myUserId, 'hr', myOptions); - if (isHr || isSubordinate) - return true; - - return false; + return forceIsSubordinate || isSubordinate; }; }; diff --git a/modules/worker/back/methods/worker/updateAbsence.js b/modules/worker/back/methods/worker/updateAbsence.js index d904c2c14..5e13097a0 100644 --- a/modules/worker/back/methods/worker/updateAbsence.js +++ b/modules/worker/back/methods/worker/updateAbsence.js @@ -30,7 +30,7 @@ module.exports = Self => { const models = Self.app.models; const userId = ctx.req.accessToken.userId; const isSubordinate = await models.Worker.isSubordinate(ctx, id); - const isTeamBoss = await models.VnUser.hasRole(userId, 'teamBoss'); + const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE'); if (!isSubordinate || (isSubordinate && userId == id && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); diff --git a/modules/worker/front/dms/create/index.html b/modules/worker/front/dms/create/index.html index 3495bf260..96f39ea6b 100644 --- a/modules/worker/front/dms/create/index.html +++ b/modules/worker/front/dms/create/index.html @@ -3,6 +3,11 @@ vn-id="watcher" data="$ctrl.dms"> + + { $element = $compile(``)($rootScope); controller = $element.controller('vnWorkerDmsCreate'); controller._worker = {id: 1101, name: 'Bruce wayne'}; + $httpBackend.whenRoute('GET', `Warehouses?filter=%7B%7D`).respond([{$oldData: {}}]); })); describe('worker() setter', () => { diff --git a/modules/worker/front/dms/edit/index.html b/modules/worker/front/dms/edit/index.html index 2ac96851c..e4939b4ea 100644 --- a/modules/worker/front/dms/edit/index.html +++ b/modules/worker/front/dms/edit/index.html @@ -2,6 +2,11 @@ vn-id="watcher" data="$ctrl.dms"> + + diff --git a/modules/zone/back/methods/agency/getLanded.js b/modules/zone/back/methods/agency/getLanded.js index cdde3b155..ebaa2db62 100644 --- a/modules/zone/back/methods/agency/getLanded.js +++ b/modules/zone/back/methods/agency/getLanded.js @@ -35,19 +35,13 @@ module.exports = Self => { }); Self.getLanded = async(ctx, shipped, addressFk, agencyModeFk, warehouseFk, options) => { + const models = Self.app.models; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const userId = ctx.req.accessToken.userId; - const models = Self.app.models; - const roles = await models.VnUser.getRoles(userId); - const canSeeExpired = roles.filter(role => - role == 'productionBoss' || role == 'administrative' - ); - let showExpired = false; - if (canSeeExpired.length) showExpired = true; + const canSeeExpired = await models.ACL.checkAccessAcl(ctx, 'Agency', 'seeExpired', 'READ'); const stmts = []; stmts.push(new ParameterizedSQL( @@ -56,7 +50,7 @@ module.exports = Self => { addressFk, agencyModeFk, warehouseFk, - showExpired + canSeeExpired ] )); diff --git a/modules/zone/back/methods/zone/includingExpired.js b/modules/zone/back/methods/zone/includingExpired.js index 59e4079c2..f9e7fd038 100644 --- a/modules/zone/back/methods/zone/includingExpired.js +++ b/modules/zone/back/methods/zone/includingExpired.js @@ -24,7 +24,6 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - const userId = ctx.req.accessToken.userId; const conn = Self.dataSource.connector; const models = Self.app.models; const where = filter.where; @@ -36,10 +35,7 @@ module.exports = Self => { && where.agencyModeFk && where.warehouseFk; if (filterByAvailability) { - const roles = await models.VnUser.getRoles(userId, myOptions); - const canSeeExpired = roles.filter(role => - role == 'productionBoss' || role == 'administrative' - ); + const canSeeExpired = await models.ACL.checkAccessAcl(ctx, 'Agency', 'seeExpired'); let showExpired = false; if (canSeeExpired.length) showExpired = true; diff --git a/package.json b/package.json index d068d6615..7a0dc5b7c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.22.01", + "version": "23.24.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0",