Skip to content

Commit 9c7aaf9

Browse files
authored
Merge pull request #257 from IntersectMBO/qa
from Qa to prep prod
2 parents 826e577 + 117a98f commit 9c7aaf9

File tree

16 files changed

+457
-6
lines changed

16 files changed

+457
-6
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const { ValidationError } = require('@strapi/utils').errors;
2+
3+
async function isLocked(contactInfoId) {
4+
if (!contactInfoId) return false;
5+
6+
const relatedBds = await strapi.entityService.findMany('api::bd.bd', {
7+
filters: {
8+
bd_contact_information: contactInfoId,
9+
},
10+
fields: ['id', 'submitted_for_vote'],
11+
});
12+
13+
return relatedBds.some(bd => !!bd.submitted_for_vote);
14+
}
15+
16+
module.exports = {
17+
async beforeUpdate(event) {
18+
const { where } = event.params;
19+
const isVotingLocked = await isLocked(where.id);
20+
if (isVotingLocked) {
21+
throw new ValidationError('Cannot update contact information because related proposal has already been submitted for voting.');
22+
}
23+
},
24+
25+
async beforeDelete(event) {
26+
const { where } = event.params;
27+
const isVotingLocked = await isLocked(where.id);
28+
if (isVotingLocked) {
29+
throw new ValidationError('Cannot delete contact information because related proposal has already been submitted for voting.');
30+
}
31+
},
32+
33+
async beforeCreate(event) {
34+
const { data } = event.params;
35+
36+
if (!data) return;
37+
38+
const bdId = data.bd;
39+
40+
if (!bdId) return;
41+
42+
const relatedBd = await strapi.entityService.findOne('api::bd.bd', bdId, {
43+
fields: ['submitted_for_vote'],
44+
});
45+
46+
if (relatedBd?.submitted_for_vote) {
47+
throw new ValidationError('Cannot create contact information because related proposal has already been submitted for voting.');
48+
}
49+
},
50+
};
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
const { ValidationError } = require('@strapi/utils').errors;
2+
3+
async function isLocked(costingId) {
4+
if (!costingId) return false;
5+
const relatedBds = await strapi.entityService.findMany('api::bd.bd', {
6+
filters: {
7+
bd_costing: costingId,
8+
},
9+
fields: ['id', 'submitted_for_vote'],
10+
});
11+
return relatedBds.some(bd => !!bd.submitted_for_vote);
12+
}
13+
14+
module.exports = {
15+
async beforeUpdate(event) {
16+
const { where } = event.params;
17+
const isVotingLocked = await isLocked(where.id);
18+
if (isVotingLocked) {
19+
throw new ValidationError('Cannot update costing because related proposal has already been submitted for voting.');
20+
}
21+
},
22+
23+
async beforeDelete(event) {
24+
const { where } = event.params;
25+
const isVotingLocked = await isLocked(where.id);
26+
if (isVotingLocked) {
27+
throw new ValidationError('Cannot delete costing because related proposal has already been submitted for voting.');
28+
}
29+
},
30+
31+
async beforeCreate(event) {
32+
const { data } = event.params;
33+
if (!data) return;
34+
35+
const bdId = data.bd;
36+
37+
if (!bdId) return;
38+
39+
const relatedBd = await strapi.entityService.findOne('api::bd.bd', bdId, {
40+
fields: ['submitted_for_vote'],
41+
});
42+
43+
if (relatedBd?.submitted_for_vote) {
44+
throw new ValidationError('Cannot create costing because related proposal has already been submitted for voting.');
45+
}
46+
},
47+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const { ValidationError } = require('@strapi/utils').errors;
2+
3+
async function isLocked(furtherInfoId) {
4+
if (!furtherInfoId) return false;
5+
6+
const relatedBds = await strapi.entityService.findMany('api::bd.bd', {
7+
filters: {
8+
bd_further_information: furtherInfoId,
9+
},
10+
fields: ['id', 'submitted_for_vote'],
11+
});
12+
13+
return relatedBds.some(bd => !!bd.submitted_for_vote);
14+
}
15+
16+
module.exports = {
17+
async beforeUpdate(event) {
18+
const { where } = event.params;
19+
const isVotingLocked = await isLocked(where.id);
20+
if (isVotingLocked) {
21+
throw new ValidationError('Cannot update further information because related proposal has already been submitted for voting.');
22+
}
23+
},
24+
25+
async beforeDelete(event) {
26+
const { where } = event.params;
27+
const isVotingLocked = await isLocked(where.id);
28+
if (isVotingLocked) {
29+
throw new ValidationError('Cannot delete further information because related proposal has already been submitted for voting.');
30+
}
31+
},
32+
};
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
const { ValidationError } = require('@strapi/utils').errors;
2+
3+
async function isVotingLockedFromPoolId(bd_poll_id) {
4+
if (!bd_poll_id) return false;
5+
6+
const pool = await strapi.entityService.findOne('api::bd-poll.bd-poll', bd_poll_id, {
7+
fields: ['bd_proposal_id'],
8+
});
9+
10+
const bdId = pool?.bd_proposal_id;
11+
if (!bdId) return false;
12+
13+
const bd = await strapi.entityService.findOne('api::bd.bd', bdId, {
14+
fields: ['submitted_for_vote'],
15+
});
16+
17+
return !!bd?.submitted_for_vote;
18+
}
19+
20+
21+
module.exports = {
22+
async beforeCreate(event) {
23+
const { data } = event.params;
24+
const isLocked = await isVotingLockedFromPoolId(data.bd_poll_id);
25+
if (isLocked) {
26+
throw new ValidationError('Creating poll votes is not allowed after the proposal has been submitted for voting.');
27+
}
28+
},
29+
30+
async beforeUpdate(event) {
31+
const { where } = event.params;
32+
33+
const voteEntry = await strapi.entityService.findOne('api::bd-poll-vote.bd-poll-vote', where.id, {
34+
fields: ['bd_poll_id'],
35+
});
36+
37+
const isLocked = await isVotingLockedFromPoolId(voteEntry?.bd_poll_id);
38+
if (isLocked) {
39+
throw new ValidationError('Modifying poll votes is not allowed after the proposal has been submitted for voting.');
40+
}
41+
},
42+
43+
async beforeDelete(event) {
44+
const { where } = event.params;
45+
46+
const voteEntry = await strapi.entityService.findOne('api::bd-poll-vote.bd-poll-vote', where.id, {
47+
fields: ['bd_poll_id'],
48+
});
49+
50+
const isLocked = await isVotingLockedFromPoolId(voteEntry?.bd_poll_id);
51+
if (isLocked) {
52+
throw new ValidationError('Deleting poll votes is not allowed after the proposal has been submitted for voting.');
53+
}
54+
},
55+
};
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const { ValidationError } = require('@strapi/utils').errors;
2+
3+
module.exports = {
4+
async beforeUpdate(event) {
5+
const { where } = event.params;
6+
7+
const existingPool = await strapi.entityService.findOne('api::bd-pool.bd-pool', where.id, {
8+
fields: ['bd_proposal_id'],
9+
});
10+
const bdId = existingPool?.bd_proposal_id;
11+
if (!bdId) return;
12+
const relatedBd = await strapi.entityService.findOne('api::bd.bd', bdId, {
13+
fields: ['submitted_for_vote'],
14+
});
15+
if (relatedBd?.submitted_for_vote) {
16+
throw new ValidationError('Update is not allowed because the related BD entry has already been submitted for voting.');
17+
}
18+
},
19+
async beforeDelete(event) {
20+
const { where } = event.params;
21+
const existingPool = await strapi.entityService.findOne('api::bd-pool.bd-pool', where.id, {
22+
fields: ['bd_proposal_id'],
23+
});
24+
const bdId = existingPool?.bd_proposal_id;
25+
if (!bdId) return;
26+
const relatedBd = await strapi.entityService.findOne('api::bd.bd', bdId, {
27+
fields: ['submitted_for_vote'],
28+
});
29+
if (relatedBd?.submitted_for_vote) {
30+
throw new ValidationError('Deletion is not allowed because the related BD entry has already been submitted for voting.');
31+
}
32+
},
33+
async beforeCreate(event) {
34+
const { data } = event;
35+
const bdId = data.bd_proposal_id;
36+
if (!bdId) return;
37+
const relatedBd = await strapi.entityService.findOne('api::bd.bd', bdId, {
38+
fields: ['submitted_for_vote'],
39+
});
40+
if (relatedBd?.submitted_for_vote) {
41+
throw new ValidationError('Creation is not allowed because the related BD entry has already been submitted for voting.');
42+
}
43+
},
44+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const { ValidationError } = require('@strapi/utils').errors;
2+
3+
async function isLocked(detailId) {
4+
if (!detailId) return false;
5+
6+
const relatedBds = await strapi.entityService.findMany('api::bd.bd', {
7+
filters: {
8+
bd_proposal_detail: detailId,
9+
},
10+
fields: ['id', 'submitted_for_vote'],
11+
});
12+
13+
return relatedBds.some(bd => !!bd.submitted_for_vote);
14+
}
15+
16+
module.exports = {
17+
async beforeUpdate(event) {
18+
const { where } = event.params;
19+
const isVotingLocked = await isLocked(where.id);
20+
if (isVotingLocked) {
21+
throw new ValidationError('Cannot update proposal detail because related proposal has already been submitted for voting.');
22+
}
23+
},
24+
25+
async beforeDelete(event) {
26+
const { where } = event.params;
27+
const isVotingLocked = await isLocked(where.id);
28+
if (isVotingLocked) {
29+
throw new ValidationError('Cannot delete proposal detail because related proposal has already been submitted for voting.');
30+
}
31+
}
32+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const { ValidationError } = require('@strapi/utils').errors;
2+
3+
async function isLocked(ownershipId) {
4+
if (!ownershipId) return false;
5+
6+
const relatedBds = await strapi.entityService.findMany('api::bd.bd', {
7+
filters: {
8+
bd_proposal_ownership: ownershipId,
9+
},
10+
fields: ['id', 'submitted_for_vote'],
11+
});
12+
13+
return relatedBds.some(bd => !!bd.submitted_for_vote);
14+
}
15+
16+
module.exports = {
17+
async beforeUpdate(event) {
18+
const { where } = event.params;
19+
const isVotingLocked = await isLocked(where.id);
20+
if (isVotingLocked) {
21+
throw new ValidationError('Cannot update proposal ownership because related proposal has already been submitted for voting.');
22+
}
23+
},
24+
25+
async beforeDelete(event) {
26+
const { where } = event.params;
27+
const isVotingLocked = await isLocked(where.id);
28+
if (isVotingLocked) {
29+
throw new ValidationError('Cannot delete proposal ownership because related proposal has already been submitted for voting.');
30+
}
31+
},
32+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const { ValidationError } = require('@strapi/utils').errors;
2+
3+
async function isLocked(psapbId) {
4+
if (!psapbId) return false;
5+
6+
const relatedBds = await strapi.entityService.findMany('api::bd.bd', {
7+
filters: {
8+
bd_psapb: psapbId,
9+
},
10+
fields: ['id', 'submitted_for_vote'],
11+
});
12+
13+
return relatedBds.some(bd => !!bd.submitted_for_vote);
14+
}
15+
16+
module.exports = {
17+
async beforeUpdate(event) {
18+
const { where } = event.params;
19+
const isVotingLocked = await isLocked(where.id);
20+
if (isVotingLocked) {
21+
throw new ValidationError('Cannot update PSAPB section because related proposal has already been submitted for voting.');
22+
}
23+
},
24+
25+
async beforeDelete(event) {
26+
const { where } = event.params;
27+
const isVotingLocked = await isLocked(where.id);
28+
if (isVotingLocked) {
29+
throw new ValidationError('Cannot delete PSAPB section because related proposal has already been submitted for voting.');
30+
}
31+
},
32+
};
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
const { ValidationError } = require('@strapi/utils').errors;
2+
const _ = require('lodash');
3+
4+
const IGNORED_FIELDS = [
5+
'updatedAt',
6+
'updatedBy',
7+
'creator',
8+
'bd_costing',
9+
'bd_proposal_detail',
10+
'bd_contact_information',
11+
'bd_further_information',
12+
'bd_psapb',
13+
'bd_proposal_ownership',
14+
'old_ver',
15+
];
16+
17+
module.exports = {
18+
async beforeUpdate(event) {
19+
const { where, data } = event.params;
20+
21+
const existingEntry = await strapi.entityService.findOne('api::bd.bd', where.id);
22+
23+
if (!existingEntry?.submitted_for_vote) return;
24+
25+
// Ukloni prop_comments_number i ignorisana polja
26+
const fieldsToCheck = Object.keys(data).filter(
27+
key => key !== 'prop_comments_number' && !IGNORED_FIELDS.includes(key)
28+
);
29+
30+
const changedFields = [];
31+
32+
for (const key of fieldsToCheck) {
33+
const newVal = data[key];
34+
const oldVal = existingEntry[key];
35+
36+
if (!_.isEqual(newVal, oldVal)) {
37+
changedFields.push({
38+
field: key,
39+
from: oldVal,
40+
to: newVal
41+
});
42+
}
43+
}
44+
45+
if (changedFields.length > 0) {
46+
const fieldList = changedFields.map(f => `${f.field} (from: ${JSON.stringify(f.from)}, to: ${JSON.stringify(f.to)})`);
47+
throw new ValidationError(
48+
`Only "prop_comments_number" can be changed after submission for voting. Changed fields: ${fieldList.join('; ')}`
49+
);
50+
}
51+
},
52+
async beforeDelete(event) {
53+
const { where } = event.params;
54+
55+
const existingEntry = await strapi.entityService.findOne('api::bd.bd', where.id, {
56+
fields: ['submitted_for_vote'],
57+
});
58+
59+
if (existingEntry?.submitted_for_vote) {
60+
throw new ValidationError('Deletion is not allowed because this entry has already been submitted for voting.');
61+
}
62+
},
63+
};

0 commit comments

Comments
 (0)