Skip to content

Commit

Permalink
IMN-587 - Upgrade agreement fix (#619)
Browse files Browse the repository at this point in the history
Co-authored-by: Eric Camellini <[email protected]>
Co-authored-by: Alessio Gallitano <[email protected]>
  • Loading branch information
3 people authored Jun 17, 2024
1 parent 75e7ddf commit 66e5348
Show file tree
Hide file tree
Showing 7 changed files with 923 additions and 135 deletions.
17 changes: 13 additions & 4 deletions packages/agreement-process/src/services/agreementService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,9 @@ export function agreementServiceBuilder(

const newState = agreementStateByFlags(
nextStateByAttributes,
// TODO this should actually recalculate flags and consider them
// in the calculation of the new state, otherwise a suspended agreement
// that was upgraded will become active - https://pagopa.atlassian.net/browse/IMN-626
undefined,
undefined,
suspendedByPlatform
Expand Down Expand Up @@ -503,10 +506,14 @@ export function agreementServiceBuilder(
);

const archivedAgreementsUpdates: Array<CreateEvent<AgreementEvent>> =
/*
/*
This condition can only check if state is ACTIVE
at this point the SUSPENDED state is not available
after validateActiveOrPendingAgreement validation
at this point the SUSPENDED state is not available
after validateActiveOrPendingAgreement validation.
TODO: this will not be true anymore if https://pagopa.atlassian.net/browse/IMN-626
is confirmed and gets fixed - the agreement could also be in SUSPENDED state.
Remove the comment at that point.
*/
isActiveOrSuspended(submittedAgreement.state)
? agreements.map((agreement) =>
Expand Down Expand Up @@ -603,7 +610,9 @@ export function agreementServiceBuilder(

const [agreement, events] = await createUpgradeOrNewDraft({
agreement: agreementToBeUpgraded,
descriptorId: newDescriptor.id,
newDescriptor,
eservice,
consumer,
readModelService,
canBeUpgraded: verifiedValid && declaredValid,
copyFile: fileManager.copy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ export const createSubmissionUpdateAgreementSeed = (
const stamps = calculateStamps(agreement, newState, createStamp(userId));
const isActivation = newState === agreementState.active;

/* As we do in the upgrade, we copy suspendedByProducer, suspendedByProducer, and suspendedAt
event if the agreement was never activated before and thus never suspended.
In this way, if this is an agreement that was upgraded, we keep suspension flags
from the original agreement before the upgrade, so that if it is being activated
by the producer, it will be suspended right away if the original
agreement was suspended by the consumer, and viceversa. */
return isActivation
? {
state: newState,
Expand All @@ -71,6 +77,7 @@ export const createSubmissionUpdateAgreementSeed = (
),
suspendedByConsumer: agreement.suspendedByConsumer,
suspendedByProducer: agreement.suspendedByProducer,
suspendedAt: agreement.suspendedAt,
suspendedByPlatform,
consumerNotes: payload.consumerNotes,
stamps,
Expand All @@ -80,8 +87,9 @@ export const createSubmissionUpdateAgreementSeed = (
certifiedAttributes: [],
declaredAttributes: [],
verifiedAttributes: [],
suspendedByConsumer: undefined,
suspendedByProducer: undefined,
suspendedByConsumer: agreement.suspendedByConsumer,
suspendedByProducer: agreement.suspendedByProducer,
suspendedAt: agreement.suspendedAt,
suspendedByPlatform,
consumerNotes: payload.consumerNotes,
stamps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,35 @@ import { FileManager, Logger, CreateEvent } from "pagopa-interop-commons";
import {
WithMetadata,
Agreement,
DescriptorId,
AgreementEvent,
agreementState,
generateId,
AgreementId,
UserId,
Descriptor,
EService,
Tenant,
} from "pagopa-interop-models";
import {
toCreateEventAgreementArchivedByUpgrade,
toCreateEventAgreementUpgraded,
toCreateEventAgreementAdded,
} from "../model/domain/toEvent.js";
import { verifyConflictingAgreements } from "../model/domain/validators.js";
import {
matchingCertifiedAttributes,
matchingDeclaredAttributes,
matchingVerifiedAttributes,
verifyConflictingAgreements,
} from "../model/domain/validators.js";
import { createStamp } from "./agreementStampUtils.js";
import { createAndCopyDocumentsForClonedAgreement } from "./agreementService.js";
import { ReadModelService } from "./readModelService.js";

export async function createUpgradeOrNewDraft({
agreement,
descriptorId,
eservice,
newDescriptor,
consumer,
readModelService,
canBeUpgraded,
copyFile,
Expand All @@ -30,14 +39,17 @@ export async function createUpgradeOrNewDraft({
logger,
}: {
agreement: WithMetadata<Agreement>;
descriptorId: DescriptorId;
eservice: EService;
newDescriptor: Descriptor;
consumer: Tenant;
readModelService: ReadModelService;
canBeUpgraded: boolean;
copyFile: FileManager["copy"];
userId: UserId;
correlationId: string;
logger: Logger;
}): Promise<[Agreement, Array<CreateEvent<AgreementEvent>>]> {
const newAgreementId = generateId<AgreementId>();
if (canBeUpgraded) {
// upgradeAgreement
const stamp = createStamp(userId);
Expand All @@ -49,24 +61,40 @@ export async function createUpgradeOrNewDraft({
archiving: stamp,
},
};
const newAgreementId = generateId<AgreementId>();
const upgraded: Agreement = {
...agreement.data,
id: newAgreementId,
descriptorId,
state: agreement.data.state,
createdAt: new Date(),
updatedAt: undefined,
rejectionReason: undefined,
stamps: {
...agreement.data.stamps,
upgrade: stamp,
},
descriptorId: newDescriptor.id,
eserviceId: agreement.data.eserviceId,
producerId: agreement.data.producerId,
consumerId: agreement.data.consumerId,
consumerNotes: agreement.data.consumerNotes,
consumerDocuments: await createAndCopyDocumentsForClonedAgreement(
newAgreementId,
agreement.data,
copyFile,
logger
),
// TODO generate a new contract here - https://pagopa.atlassian.net/browse/IMN-622
contract: agreement.data.contract,
verifiedAttributes: matchingVerifiedAttributes(
eservice,
newDescriptor,
consumer
),
certifiedAttributes: matchingCertifiedAttributes(newDescriptor, consumer),
declaredAttributes: matchingDeclaredAttributes(newDescriptor, consumer),
suspendedByConsumer: agreement.data.suspendedByConsumer,
suspendedByProducer: agreement.data.suspendedByProducer,
suspendedAt: agreement.data.suspendedAt,
suspendedByPlatform: undefined,
updatedAt: undefined,
rejectionReason: undefined,
stamps: {
...agreement.data.stamps,
upgrade: stamp,
},
};

return [
Expand All @@ -89,20 +117,41 @@ export async function createUpgradeOrNewDraft({
readModelService
);

const id = generateId<AgreementId>();
const newAgreement: Agreement = {
...agreement.data,
id,
descriptorId,
id: newAgreementId,
state: agreementState.draft,
createdAt: new Date(),
descriptorId: newDescriptor.id,
eserviceId: agreement.data.eserviceId,
producerId: agreement.data.producerId,
consumerId: agreement.data.consumerId,
consumerNotes: agreement.data.consumerNotes,
consumerDocuments: await createAndCopyDocumentsForClonedAgreement(
id,
newAgreementId,
agreement.data,
copyFile,
logger
),
stamps: {},
suspendedByPlatform: undefined,
updatedAt: undefined,
rejectionReason: undefined,
contract: undefined,
verifiedAttributes: [],
certifiedAttributes: [],
declaredAttributes: [],
/* We copy suspendedByProducer, suspendedByProducer, suspendedAt, and
the corresponding stamps, even if this is a Draft Agreement and suspension
should not make sense on a Draft Agreement.
In this way, when the new agreement gets activated
by the producer, it will be suspended right away if the original
agreement was suspended by the consumer, and viceversa. */
suspendedByConsumer: agreement.data.suspendedByConsumer,
suspendedByProducer: agreement.data.suspendedByProducer,
suspendedAt: agreement.data.suspendedAt,
stamps: {
suspensionByConsumer: agreement.data.stamps.suspensionByConsumer,
suspensionByProducer: agreement.data.stamps.suspensionByProducer,
},
};

const createEvent = toCreateEventAgreementAdded(
Expand Down
Loading

0 comments on commit 66e5348

Please sign in to comment.