hotfix-sepaCore #2678

Merged
carlossa merged 7 commits from hotfix-sepaCore into master 2024-07-05 05:52:16 +00:00
11 changed files with 103 additions and 62 deletions
Showing only changes of commit 33a1928f62 - Show all commits

8
Jenkinsfile vendored
View File

@ -121,7 +121,7 @@ pipeline {
steps { steps {
script { script {
def packageJson = readJSON file: 'package.json' def packageJson = readJSON file: 'package.json'
env.VERSION = "${packageJson.version}-vn${env.BUILD_ID}" env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
} }
sh 'docker-compose build back' sh 'docker-compose build back'
} }
@ -159,7 +159,7 @@ pipeline {
steps { steps {
script { script {
def packageJson = readJSON file: 'package.json' def packageJson = readJSON file: 'package.json'
env.VERSION = "${packageJson.version}-vn${env.BUILD_ID}" env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
} }
sh 'gulp build' sh 'gulp build'
sh 'docker-compose build front' sh 'docker-compose build front'
@ -179,7 +179,7 @@ pipeline {
steps { steps {
script { script {
def packageJson = readJSON file: 'package.json' def packageJson = readJSON file: 'package.json'
env.VERSION = "${packageJson.version}-vn${env.BUILD_ID}" env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
} }
sh 'docker login --username $CREDENTIALS_USR --password $CREDENTIALS_PSW $REGISTRY' sh 'docker login --username $CREDENTIALS_USR --password $CREDENTIALS_PSW $REGISTRY'
sh 'docker-compose push' sh 'docker-compose push'
@ -210,7 +210,7 @@ pipeline {
steps { steps {
script { script {
def packageJson = readJSON file: 'package.json' def packageJson = readJSON file: 'package.json'
env.VERSION = "${packageJson.version}-vn${env.BUILD_ID}" env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
} }
withKubeConfig([ withKubeConfig([
serverUrl: "$KUBERNETES_API", serverUrl: "$KUBERNETES_API",

View File

@ -1711,7 +1711,7 @@ INSERT INTO `ACL` VALUES (570,'InvoiceOut','canCreatePdf','WRITE','ALLOW','ROLE'
INSERT INTO `ACL` VALUES (571,'Supplier','editPayMethodCheck','WRITE','ALLOW','ROLE','financial'); INSERT INTO `ACL` VALUES (571,'Supplier','editPayMethodCheck','WRITE','ALLOW','ROLE','financial');
INSERT INTO `ACL` VALUES (572,'Worker','isTeamBoss','WRITE','ALLOW','ROLE','teamBoss'); INSERT INTO `ACL` VALUES (572,'Worker','isTeamBoss','WRITE','ALLOW','ROLE','teamBoss');
INSERT INTO `ACL` VALUES (573,'Worker','forceIsSubordinate','READ','ALLOW','ROLE','hr'); INSERT INTO `ACL` VALUES (573,'Worker','forceIsSubordinate','READ','ALLOW','ROLE','hr');
INSERT INTO `ACL` VALUES (574,'Claim','editState','WRITE','ALLOW','ROLE','claimManager'); INSERT INTO `ACL` VALUES (574,'Claim','editPickup','WRITE','ALLOW','ROLE','claimManager');
INSERT INTO `ACL` VALUES (577,'Claim','findOne','READ','ALLOW','ROLE','salesPerson'); INSERT INTO `ACL` VALUES (577,'Claim','findOne','READ','ALLOW','ROLE','salesPerson');
INSERT INTO `ACL` VALUES (579,'Claim','updateClaim','WRITE','ALLOW','ROLE','salesPerson'); INSERT INTO `ACL` VALUES (579,'Claim','updateClaim','WRITE','ALLOW','ROLE','salesPerson');
INSERT INTO `ACL` VALUES (580,'Claim','regularizeClaim','WRITE','ALLOW','ROLE','claimManager'); INSERT INTO `ACL` VALUES (580,'Claim','regularizeClaim','WRITE','ALLOW','ROLE','claimManager');

View File

@ -3126,6 +3126,18 @@ INSERT INTO `vn`.`entryDms`(`entryFk`, `dmsFk`, `editorFk`)
VALUES VALUES
(1, 9, 9); (1, 9, 9);
INSERT INTO vn.entryType (code,description,isInformal)
VALUES ('devaluation','Devaluation',0),
('internal','Internal',1),
('inventory','Inventory',1),
('life','Life',1),
('packaging','Packaging',0),
('payment','Refund',0),
('product','Product',0),
('regularization','Regularization',1),
('return','Return',0),
('transport','Delivery',0);
INSERT INTO `vn`.`cmr` (id,truckPlate,observations,senderInstruccions,paymentInstruccions,specialAgreements,companyFk,addressToFk,addressFromFk,supplierFk,packagesList,merchandiseDetail,state) INSERT INTO `vn`.`cmr` (id,truckPlate,observations,senderInstruccions,paymentInstruccions,specialAgreements,companyFk,addressToFk,addressFromFk,supplierFk,packagesList,merchandiseDetail,state)
VALUES (1,'123456A','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet',442,1,2,1,'Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet'), VALUES (1,'123456A','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet',442,1,2,1,'Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet'),
(2,'123456N','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet',69,3,4,2,'Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet'), (2,'123456N','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet',69,3,4,2,'Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet','Lorem ipsum dolor sit amet'),

View File

@ -13,7 +13,15 @@ trig:BEGIN
LEAVE trig; LEAVE trig;
END IF; END IF;
CALL entry_isEditable(OLD.entryFk); IF NOT (NEW.entryFk <=> OLD.entryFk) OR
NOT (NEW.quantity <=> OLD.quantity) OR
NOT (NEW.buyingValue <=> OLD.buyingValue) OR
NOT (NEW.packing <=> OLD.packing)
THEN
CALL entry_isEditable(OLD.entryFk);
END IF;
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();
SELECT defaultEntry INTO vDefaultEntry SELECT defaultEntry INTO vDefaultEntry

View File

@ -8,9 +8,20 @@ BEGIN
DECLARE vHasDistinctWarehouses BOOL; DECLARE vHasDistinctWarehouses BOOL;
DECLARE vTotalBuy INT; DECLARE vTotalBuy INT;
IF NEW.isBooked = OLD.isBooked THEN IF NEW.isBooked = OLD.isBooked AND (
NOT (NEW.supplierFk <=> OLD.supplierFk) OR
NOT (NEW.dated <=> OLD.dated) OR
NOT (NEW.invoiceNumber <=> OLD.invoiceNumber) OR
NOT (NEW.travelFk <=> OLD.travelFk) OR
NOT (NEW.companyFk <=> OLD.companyFk) OR
NOT (NEW.invoiceInFk <=> OLD.invoiceInFk) OR
NOT (NEW.invoiceAmount <=> OLD.invoiceAmount) OR
NOT (NEW.typeFk <=> OLD.typeFk)
) THEN
CALL entry_isEditable(OLD.id); CALL entry_isEditable(OLD.id);
ELSE ELSE
IF NEW.isBooked THEN IF NEW.isBooked THEN
SELECT COUNT(*) INTO vTotalBuy SELECT COUNT(*) INTO vTotalBuy
FROM buy FROM buy

View File

@ -0,0 +1,8 @@
INSERT INTO salix.ACL
SET
model = 'Ticket',
property = 'editZone',
accessType = 'WRITE',
permission = 'ALLOW',
principalType = 'ROLE',
principalId = 'buyer';

View File

@ -69,30 +69,26 @@ module.exports = Self => {
} }
} }
}, myOptions); }, myOptions);
// Get sales person from claim client
const salesPerson = claim.client().salesPersonUser();
const changedPickup = args.pickup != claim.pickup; const changedPickup = args.pickup && args.pickup != claim.pickup;
// Validate when claimState has been changed
if (args.claimStateFk) { if (args.claimStateFk) {
const canEditOldState = await models.ClaimState.isEditable(ctx, claim.claimStateFk, myOptions); const canEditOldState = await models.ClaimState.isEditable(ctx, claim.claimStateFk, myOptions);
const canEditNewState = await models.ClaimState.isEditable(ctx, args.claimStateFk, myOptions); const canEditNewState = await models.ClaimState.isEditable(ctx, args.claimStateFk, myOptions);
const canEditState = await models.ACL.checkAccessAcl(ctx, 'Claim', 'editState', 'WRITE'); const canEditPickup = await models.ACL.checkAccessAcl(ctx, 'Claim', 'editPickup', 'WRITE');
if (!canEditOldState || !canEditNewState || changedPickup && !canEditState) if (!canEditOldState || !canEditNewState || (changedPickup && !canEditPickup))
throw new UserError(`You don't have enough privileges to change that field`); throw new UserError(`You don't have enough privileges to change that field`);
} }
delete args.ctx; delete args.ctx;
const updatedClaim = await claim.updateAttributes(args, myOptions); const updatedClaim = await claim.updateAttributes(args, myOptions);
// When pickup has been changed const salesPerson = claim.client().salesPersonUser();
if (salesPerson) { if (salesPerson) {
if (changedPickup && updatedClaim.pickup) if (changedPickup && updatedClaim.pickup)
await notifyPickUp(ctx, salesPerson.id, claim); await notifyPickUp(ctx, salesPerson.id, claim);
// When claimState has been changed
if (args.claimStateFk) { if (args.claimStateFk) {
const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions); const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions);
await notifyStateChange(ctx, salesPerson.id, claim, newState.description); await notifyStateChange(ctx, salesPerson.id, claim, newState.description);
@ -113,7 +109,7 @@ module.exports = Self => {
async function notifyStateChange(ctx, workerId, claim, newState) { async function notifyStateChange(ctx, workerId, claim, newState) {
const models = Self.app.models; const models = Self.app.models;
const url = await models.Url.getUrl(); const url = await models.Url.getUrl();
const $t = ctx.req.__; // $translate const $t = ctx.req.__;
const message = $t(`Claim state has changed to`, { const message = $t(`Claim state has changed to`, {
claimId: claim.id, claimId: claim.id,

View File

@ -11,7 +11,7 @@ export default class Controller extends Section {
fields: ['id', 'countryFk', 'taxClassFk'], fields: ['id', 'countryFk', 'taxClassFk'],
include: [{ include: [{
relation: 'country', relation: 'country',
scope: {fields: ['country']} scope: {fields: ['name']}
}] }]
}; };

View File

@ -35,7 +35,7 @@
label="Country" label="Country"
ng-model="filter.countryFk" ng-model="filter.countryFk"
url="countries" url="countries"
show-field="country" show-field="name"
value-field="id"> value-field="id">
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>

View File

@ -72,16 +72,20 @@ module.exports = Self => {
const salesPerson = sale.ticket().client().salesPersonUser(); const salesPerson = sale.ticket().client().salesPersonUser();
if (salesPerson) { if (salesPerson) {
const url = await Self.app.models.Url.getUrl(); const url = await Self.app.models.Url.getUrl();
const message = $t('Changed sale quantity', { const change = $t('Changes in sales', {
ticketId: sale.ticket().id,
itemId: sale.itemFk, itemId: sale.itemFk,
concept: sale.concept, concept: sale.concept,
oldQuantity: oldQuantity, oldQuantity: oldQuantity,
newQuantity: newQuantity, newQuantity: newQuantity,
ticketUrl: `${url}ticket/${sale.ticket().id}/sale`,
itemUrl: `${url}item/${sale.itemFk}/summary` itemUrl: `${url}item/${sale.itemFk}/summary`
}); });
const message = $t('Changed sale quantity', {
ticketId: sale.ticket().id,
changes: change,
ticketUrl: `${url}ticket/${sale.ticket().id}/sale`,
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions);
} }

View File

@ -26,6 +26,7 @@ module.exports = Self => {
const models = Self.app.models; const models = Self.app.models;
const myOptions = {}; const myOptions = {};
let tx; let tx;
let newStateOrder;
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
@ -40,11 +41,16 @@ module.exports = Self => {
throw new UserError('State cannot be blank'); throw new UserError('State cannot be blank');
if (params.stateFk) { if (params.stateFk) {
const {code} = await models.State.findById(params.stateFk, {fields: ['code']}, myOptions); const {code, order} = await models.State.findById(
params.stateFk,
{fields: ['code', 'order']},
myOptions);
params.code = code; params.code = code;
newStateOrder = order;
} else { } else {
const {id} = await models.State.findOne({where: {code: params.code}}, myOptions); const {id, order} = await models.State.findOne({where: {code: params.code}}, myOptions);
params.stateFk = id; params.stateFk = id;
newStateOrder = order;
} }
if (!params.userFk) { if (!params.userFk) {
@ -75,50 +81,46 @@ module.exports = Self => {
}, myOptions); }, myOptions);
const salesPersonFk = ticket.client().salesPersonFk; const salesPersonFk = ticket.client().salesPersonFk;
if (salesPersonFk) { const stateChecked = await models.State.findOne({fields: ['order'], where: {code: 'CHECKED'}});
if (salesPersonFk && newStateOrder >= stateChecked.order) {
const sales = await Self.rawSql(` const sales = await Self.rawSql(`
SELECT DISTINCT s.id, SELECT DISTINCT s.id,
s.itemFk, s.itemFk,
s.concept, s.concept,
s.originalQuantity AS oldQuantity, s.originalQuantity AS oldQuantity,
s.quantity AS newQuantity s.quantity AS newQuantity
FROM vn.sale s FROM vn.sale s
JOIN vn.saleTracking st ON st.saleFk = s.id WHERE s.ticketFk = ?
JOIN vn.ticket t ON t.id = s.ticketFk AND s.originalQuantity IS NOT NULL
JOIN vn.client c ON c.id = t.clientFk AND s.originalQuantity <> s.quantity
JOIN vn.ticketState ts ON ts.ticketFk = t.id
JOIN vn.state s2 ON s2.id = ts.stateFk
WHERE s.ticketFk = ?
AND st.isChecked
AND s.originalQuantity IS NOT NULL
AND s.originalQuantity <> s.quantity
AND s2.\`order\` < (SELECT \`order\` FROM vn.state WHERE code = 'CHECKED')
ORDER BY st.created DESC
`, [params.ticketFk], myOptions); `, [params.ticketFk], myOptions);
let changes = ''; if (sales.length) {
const url = await models.Url.getUrl(); let changes = '';
const $t = ctx.req.__; const url = await models.Url.getUrl();
for (let sale of sales) { const $t = ctx.req.__;
changes += `\r\n-` + $t('Changes in sales', { for (let sale of sales) {
itemId: sale.itemFk, changes += `\r\n-` + $t('Changes in sales', {
concept: sale.concept, itemId: sale.itemFk,
oldQuantity: sale.oldQuantity, concept: sale.concept,
newQuantity: sale.newQuantity, oldQuantity: sale.oldQuantity,
itemUrl: `${url}item/${sale.itemFk}/summary` newQuantity: sale.newQuantity,
}); itemUrl: `${url}item/${sale.itemFk}/summary`
const currentSale = await models.Sale.findById(sale.id, null, myOptions); });
await currentSale.updateAttributes({ const currentSale = await models.Sale.findById(sale.id, null, myOptions);
originalQuantity: currentSale.quantity await currentSale.updateAttributes({
}, myOptions); originalQuantity: currentSale.quantity
} }, myOptions);
}
const message = $t('Changed sale quantity', { const message = $t('Changed sale quantity', {
ticketId: ticket.id, ticketId: ticket.id,
changes: changes, changes: changes,
ticketUrl: `${url}ticket/${ticket.id}/sale` ticketUrl: `${url}ticket/${ticket.id}/sale`
}); });
await models.Chat.sendCheckingPresence(ctx, salesPersonFk, message, myOptions); await models.Chat.sendCheckingPresence(ctx, salesPersonFk, message, myOptions);
}
} }
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticket.id, params.code], myOptions); await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticket.id, params.code], myOptions);