Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 5334-editDepartment
This commit is contained in:
commit
9ee653dbd1
|
@ -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`);
|
||||
|
||||
|
|
|
@ -44,4 +44,4 @@
|
|||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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 = '*';
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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`);
|
||||
}
|
||||
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
vn-id="watcher"
|
||||
data="$ctrl.dms">
|
||||
</vn-watcher>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="$ctrl.onSubmit()"
|
||||
|
@ -29,7 +34,7 @@
|
|||
<vn-autocomplete vn-one required="true"
|
||||
label="Warehouse"
|
||||
ng-model="$ctrl.dms.warehouseId"
|
||||
url="Warehouses"
|
||||
data="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
form="form"
|
||||
save="patch">
|
||||
</vn-watcher>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form name="form" ng-submit="watcher.submit()" class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
|
@ -152,14 +157,14 @@
|
|||
<vn-autocomplete
|
||||
label="Warehouse Out"
|
||||
ng-model="$ctrl.travelFilterParams.warehouseOutFk"
|
||||
url="Warehouses"
|
||||
data="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
label="Warehouse In"
|
||||
ng-model="$ctrl.travelFilterParams.warehouseInFk"
|
||||
url="Warehouses"
|
||||
data="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<vn-descriptor-content
|
||||
module="item"
|
||||
description="$ctrl.item.name"
|
||||
|
@ -108,7 +113,9 @@
|
|||
<vn-autocomplete
|
||||
label="Warehouse"
|
||||
ng-model="$ctrl.warehouseFk"
|
||||
url="Warehouses">
|
||||
data="warehouses"
|
||||
show-field="name"
|
||||
value="id">
|
||||
</vn-autocomplete>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-textfield
|
||||
|
@ -35,7 +40,9 @@
|
|||
vn-one
|
||||
label="Warehouse"
|
||||
ng-model="filter.warehouseFk"
|
||||
url="Warehouses">
|
||||
data="warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-textfield
|
||||
|
@ -83,7 +88,7 @@
|
|||
vn-one
|
||||
label="Warehouse"
|
||||
ng-model="filter.warehouseFk"
|
||||
url="Warehouses">
|
||||
data="Warehouses">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Agencies"
|
||||
data="agencies">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-textfield
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-textfield
|
||||
|
@ -79,7 +84,7 @@
|
|||
vn-one
|
||||
label="Warehouse"
|
||||
ng-model="filter.warehouseFk"
|
||||
url="Warehouses"
|
||||
data="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
|
@ -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,
|
||||
|
|
|
@ -39,7 +39,6 @@ module.exports = Self => {
|
|||
const ticketToDelete = await models.Ticket.findById(id, {fields: ['isDeleted']}, myOptions);
|
||||
if (ticketToDelete.isDeleted) return false;
|
||||
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const isEditable = await Self.isEditable(ctx, id, myOptions);
|
||||
|
||||
if (!isEditable)
|
||||
|
@ -54,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}
|
||||
|
@ -63,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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-date-picker
|
||||
|
@ -49,7 +54,9 @@
|
|||
vn-one
|
||||
label="Warehouse"
|
||||
ng-model="filter.warehouseFk"
|
||||
url="Warehouses"
|
||||
data="warehouses"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
required="true">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
order="name"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form name="form">
|
||||
<vn-card class="vn-w-md vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
|
@ -25,7 +30,7 @@
|
|||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
required="true"
|
||||
url="Warehouses"
|
||||
data="Warehouses"
|
||||
label="Warehouse"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
vn-id="watcher"
|
||||
data="$ctrl.dms">
|
||||
</vn-watcher>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="$ctrl.onSubmit()"
|
||||
|
@ -29,7 +34,7 @@
|
|||
<vn-autocomplete vn-one required="true"
|
||||
label="Warehouse"
|
||||
ng-model="$ctrl.dms.warehouseId"
|
||||
url="Warehouses"
|
||||
data="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-date-picker
|
||||
|
@ -83,7 +88,9 @@
|
|||
vn-one
|
||||
label="Warehouse"
|
||||
ng-model="filter.warehouseFk"
|
||||
url="Warehouses"
|
||||
data="warehouses"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
required="true">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
|
|
|
@ -491,7 +491,7 @@
|
|||
<vn-confirm
|
||||
vn-id="claimSure"
|
||||
message="Do you want to create a claim?"
|
||||
on-accept="$ctrl.createClaim()">
|
||||
on-accept="$ctrl.onCreateClaimAccepted()">
|
||||
</vn-confirm>
|
||||
|
||||
<vn-menu vn-id="moreOptions">
|
||||
|
@ -513,7 +513,7 @@
|
|||
</vn-item>
|
||||
<vn-item translate
|
||||
name="claim"
|
||||
ng-click="claimSure.show()"
|
||||
ng-click="$ctrl.createClaim()"
|
||||
ng-if="$ctrl.isClaimable">
|
||||
Add claim
|
||||
</vn-item>
|
||||
|
|
|
@ -203,7 +203,7 @@ class Controller extends Section {
|
|||
if (pastDays >= this.ticketConfig[0].daysForWarningClaim)
|
||||
this.$.claimConfirm.show();
|
||||
else
|
||||
this.onCreateClaimAccepted();
|
||||
this.$.claimSure.show();
|
||||
}
|
||||
|
||||
onCreateClaimAccepted() {
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-textfield
|
||||
|
@ -102,7 +107,7 @@
|
|||
vn-one
|
||||
label="Warehouse"
|
||||
ng-model="filter.warehouseFk"
|
||||
url="Warehouses">
|
||||
data="Warehouses">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
|
@ -52,14 +57,14 @@
|
|||
<vn-autocomplete vn-one
|
||||
label="Warehouse Out"
|
||||
ng-model="filter.warehouseOutFk"
|
||||
url="Warehouses"
|
||||
data="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
label="Warehouse In"
|
||||
ng-model="filter.warehouseInFk"
|
||||
url="Warehouses"
|
||||
data="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(?,?,?)`;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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`);
|
||||
|
|
|
@ -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`);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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`);
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
vn-id="watcher"
|
||||
data="$ctrl.dms">
|
||||
</vn-watcher>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="$ctrl.onSubmit()"
|
||||
|
|
|
@ -17,6 +17,7 @@ describe('Client', () => {
|
|||
$element = $compile(`<vn-worker-dms-create></vn-worker-dms-create>`)($rootScope);
|
||||
controller = $element.controller('vnWorkerDmsCreate');
|
||||
controller._worker = {id: 1101, name: 'Bruce wayne'};
|
||||
$httpBackend.whenRoute('GET', `Warehouses?filter=%7B%7D`).respond([{$oldData: {}}]);
|
||||
}));
|
||||
|
||||
describe('worker() setter', () => {
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
vn-id="watcher"
|
||||
data="$ctrl.dms">
|
||||
</vn-watcher>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="$ctrl.onSubmit()"
|
||||
|
@ -29,7 +34,7 @@
|
|||
<vn-autocomplete vn-one required="true"
|
||||
label="Warehouse"
|
||||
ng-model="$ctrl.dms.warehouseId"
|
||||
url="Warehouses"
|
||||
data="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
|
|
|
@ -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
|
||||
]
|
||||
));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue