Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: 1745 milestone values persist #1814

Merged
merged 9 commits into from
Aug 1, 2023
9 changes: 7 additions & 2 deletions app/components/Form/Functions/getMilestoneFilteredSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@ export const getMilestoneFilteredSchema = (
const newDataObject: any = {};

for (const key of Object.keys(filteredSchema.properties)) {
const [updatedFormData, prevFormData] = [
Sepehr-Sobhani marked this conversation as resolved.
Show resolved Hide resolved
formChange?.newFormData?.[key],
formChange?.formChangeByPreviousFormChangeId?.newFormData?.[key],
];
if (
formChange?.newFormData?.[key] ===
formChange?.formChangeByPreviousFormChangeId?.newFormData?.[key]
updatedFormData === prevFormData ||
(updatedFormData === undefined && prevFormData === null) ||
(updatedFormData === null && prevFormData === undefined)
)
delete filteredSchema.properties[key];
else newDataObject[key] = formChange.newFormData?.[key];
Expand Down
6 changes: 5 additions & 1 deletion app/lib/theme/ReadOnlyFieldTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ const FieldTemplate: React.FC<FieldTemplateProps> = ({
id,
uiSchema,
}) => {
const isAdjustableCalculatedValueWidget =
uiSchema?.["ui:widget"] &&
uiSchema["ui:widget"] === "AdjustableCalculatedValueWidget";

return (
<div>
<div
className={
uiSchema.calculatedValueFormContextProperty
isAdjustableCalculatedValueWidget
? "adjustable-calculated-value-widget"
: "definition-container"
}
Expand Down
64 changes: 47 additions & 17 deletions schema/deploy/functions/handle_milestone_form_change_commit.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ create or replace function cif_private.handle_milestone_form_change_commit(fc ci
returns int as $$
declare
reporting_requirement_record_id int;
report_is_eligible_for_expenses boolean;
adjusted_or_calculated_gross_amount numeric;
adjusted_or_calculated_net_amount numeric;
begin

-- If there is no change in the form data, return the form_change record and do not touch the associated table.
if (fc.new_form_data = '{}') then
return fc.form_data_record_id; -- can be null if creating with empty form data...problem?
end if;

report_is_eligible_for_expenses := fc.new_form_data->>'reportType' in (select name from cif.report_type where has_expenses=true);
adjusted_or_calculated_gross_amount := coalesce((fc.new_form_data->>'adjustedGrossAmount')::numeric, (fc.new_form_data->>'calculatedGrossAmount')::numeric);
adjusted_or_calculated_net_amount := coalesce((fc.new_form_data->>'adjustedNetAmount')::numeric, (fc.new_form_data->>'calculatedNetAmount')::numeric);

if (fc.change_status = 'committed') then
raise exception 'Cannot commit form_change. It has already been committed.';
end if;
Expand Down Expand Up @@ -56,17 +63,20 @@ begin
(fc.new_form_data->>'totalEligibleExpenses')::numeric
);

insert into cif.payment(
reporting_requirement_id,
gross_amount,
net_amount,
date_sent_to_csnr
) values (
reporting_requirement_record_id,
coalesce((fc.new_form_data->>'adjustedGrossAmount')::numeric, (fc.new_form_data->>'calculatedGrossAmount')::numeric),
coalesce((fc.new_form_data->>'adjustedNetAmount')::numeric, (fc.new_form_data->>'calculatedNetAmount')::numeric),
(fc.new_form_data->>'dateSentToCsnr')::timestamptz
);
-- Only create a payment if the report type is eligible for expenses
if report_is_eligible_for_expenses then
insert into cif.payment(
reporting_requirement_id,
gross_amount,
net_amount,
date_sent_to_csnr
) values (
reporting_requirement_record_id,
adjusted_or_calculated_gross_amount,
adjusted_or_calculated_net_amount,
(fc.new_form_data->>'dateSentToCsnr')::timestamptz
);
end if;

update cif.form_change set form_data_record_id = reporting_requirement_record_id where id = fc.id;

Expand All @@ -89,12 +99,32 @@ begin
total_eligible_expenses = (fc.new_form_data->>'totalEligibleExpenses')::numeric
where mr.reporting_requirement_id = fc.form_data_record_id;


update cif.payment py set
gross_amount = coalesce((fc.new_form_data->>'adjustedGrossAmount')::numeric, (fc.new_form_data->>'calculatedGrossAmount')::numeric),
net_amount = coalesce((fc.new_form_data->>'adjustedNetAmount')::numeric, (fc.new_form_data->>'calculatedNetAmount')::numeric),
date_sent_to_csnr = (fc.new_form_data->>'dateSentToCsnr')::timestamptz
where py.reporting_requirement_id = fc.form_data_record_id;
if report_is_eligible_for_expenses then
-- This part is covering the case where the user changes the report type from a non-expense report type to an expense report type (or vice versa)
-- if there's a payment record with the same reporting_requirement_id, we update it
if exists(select 1 from cif.payment where reporting_requirement_id = fc.form_data_record_id and archived_at is null) then
update cif.payment set
gross_amount = adjusted_or_calculated_gross_amount,
net_amount = adjusted_or_calculated_net_amount,
Sepehr-Sobhani marked this conversation as resolved.
Show resolved Hide resolved
date_sent_to_csnr = (fc.new_form_data->>'dateSentToCsnr')::timestamptz
where reporting_requirement_id = fc.form_data_record_id;
-- otherwise we create a new payment record
else
insert into cif.payment(
reporting_requirement_id,
gross_amount,
net_amount,
date_sent_to_csnr
) values (
reporting_requirement_record_id,
adjusted_or_calculated_gross_amount,
adjusted_or_calculated_net_amount,
(fc.new_form_data->>'dateSentToCsnr')::timestamptz
);
end if;
else
update cif.payment set archived_at = now() where reporting_requirement_id = fc.form_data_record_id;
end if;

elsif fc.operation = 'archive' then

Expand Down
119 changes: 119 additions & 0 deletions schema/deploy/functions/handle_milestone_form_change_commit@1.10.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
-- Deploy cif:functions/handle_milestone_form_change_commit to pg
-- requires: tables/form_change

begin;

create or replace function cif_private.handle_milestone_form_change_commit(fc cif.form_change)
returns int as $$
declare
reporting_requirement_record_id int;
begin

-- If there is no change in the form data, return the form_change record and do not touch the associated table.
if (fc.new_form_data = '{}') then
return fc.form_data_record_id; -- can be null if creating with empty form data...problem?
end if;

if (fc.change_status = 'committed') then
raise exception 'Cannot commit form_change. It has already been committed.';
end if;

reporting_requirement_record_id := fc.form_data_record_id;

if fc.operation = 'create' then

insert into cif.reporting_requirement(
project_id,
report_type,
report_due_date,
submitted_date,
comments,
reporting_requirement_index,
description
) values (
(select form_data_record_id from cif.form_change pfc where form_data_table_name = 'project' and pfc.project_revision_id = fc.project_revision_id),
(fc.new_form_data->>'reportType'),
(fc.new_form_data->>'reportDueDate')::timestamptz,
(fc.new_form_data->>'submittedDate')::timestamptz,
(fc.new_form_data->>'comments'),
(fc.new_form_data->>'reportingRequirementIndex')::int,
(fc.new_form_data->>'description')
) returning id into reporting_requirement_record_id;

insert into cif.milestone_report(
reporting_requirement_id,
substantial_completion_date,
certified_by,
certifier_professional_designation,
maximum_amount,
total_eligible_expenses
) values (
reporting_requirement_record_id,
(fc.new_form_data->>'substantialCompletionDate')::timestamptz,
(fc.new_form_data->>'certifiedBy'),
(fc.new_form_data->>'certifierProfessionalDesignation'),
(fc.new_form_data->>'maximumAmount')::numeric,
(fc.new_form_data->>'totalEligibleExpenses')::numeric
);

insert into cif.payment(
reporting_requirement_id,
gross_amount,
net_amount,
date_sent_to_csnr
) values (
reporting_requirement_record_id,
coalesce((fc.new_form_data->>'adjustedGrossAmount')::numeric, (fc.new_form_data->>'calculatedGrossAmount')::numeric),
coalesce((fc.new_form_data->>'adjustedNetAmount')::numeric, (fc.new_form_data->>'calculatedNetAmount')::numeric),
(fc.new_form_data->>'dateSentToCsnr')::timestamptz
);

update cif.form_change set form_data_record_id = reporting_requirement_record_id where id = fc.id;

elsif fc.operation = 'update' then

update cif.reporting_requirement rr set
report_type = (fc.new_form_data->>'reportType'),
report_due_date = (fc.new_form_data->>'reportDueDate')::timestamptz,
submitted_date = (fc.new_form_data->>'submittedDate')::timestamptz,
comments = (fc.new_form_data->>'comments'),
reporting_requirement_index = (fc.new_form_data->>'reportingRequirementIndex')::int,
description = (fc.new_form_data->>'description')
where rr.id = fc.form_data_record_id;

update cif.milestone_report mr set
substantial_completion_date = (fc.new_form_data->>'substantialCompletionDate')::timestamptz,
certified_by = (fc.new_form_data->>'certifiedBy'),
certifier_professional_designation = (fc.new_form_data->>'certifierProfessionalDesignation'),
maximum_amount = (fc.new_form_data->>'maximumAmount')::numeric,
total_eligible_expenses = (fc.new_form_data->>'totalEligibleExpenses')::numeric
where mr.reporting_requirement_id = fc.form_data_record_id;


update cif.payment py set
gross_amount = coalesce((fc.new_form_data->>'adjustedGrossAmount')::numeric, (fc.new_form_data->>'calculatedGrossAmount')::numeric),
net_amount = coalesce((fc.new_form_data->>'adjustedNetAmount')::numeric, (fc.new_form_data->>'calculatedNetAmount')::numeric),
date_sent_to_csnr = (fc.new_form_data->>'dateSentToCsnr')::timestamptz
where py.reporting_requirement_id = fc.form_data_record_id;

elsif fc.operation = 'archive' then

update cif.reporting_requirement set archived_at = now() where id = fc.form_data_record_id;
update cif.milestone_report set archived_at = now() where reporting_requirement_id = fc.form_data_record_id;
update cif.payment set archived_at = now() where reporting_requirement_id = fc.form_data_record_id;

end if;

return reporting_requirement_record_id;
end;
$$ language plpgsql volatile;

grant execute on function cif_private.handle_milestone_form_change_commit to cif_internal, cif_external, cif_admin;

comment on function cif_private.handle_milestone_form_change_commit
is $$
The custom function used to parse milestone form_change data into table data.
The data within the single form_change record is parsed into the reporting_requirement, milestone_report and payment tables.
$$;

commit;
21 changes: 13 additions & 8 deletions schema/deploy/mutations/update_milestone_form_change.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@ $$

select cif.update_form_change($1, $2);

-- remove the totalEligibleExpenses field if the reportType is not General Milestone
update cif.form_change
set new_form_data = new_form_data - 'totalEligibleExpenses'
where id = $1
and new_form_data->>'reportType' not in ('General Milestone', 'Interim Summary Report');

update cif.form_change set
new_form_data = new_form_data || jsonb_build_object(
'calculatedGrossAmount',cif.form_change_calculated_gross_amount_this_milestone((select row(form_change.*)::cif.form_change from cif.form_change where id = row_id)),
'calculatedNetAmount',cif.form_change_calculated_net_amount_this_milestone((select row(form_change.*)::cif.form_change from cif.form_change where id = row_id)),
'calculatedHoldbackAmount',cif.form_change_calculated_holdback_amount_this_milestone((select row(form_change.*)::cif.form_change from cif.form_change where id = row_id)))
where id=row_id
returning *;
update cif.form_change
set new_form_data = case
-- remove expense related values from new_form_data if report type is not eligible for expenses
when (new_form_data->>'reportType') in (select name from cif.report_type where has_expenses=false) then
new_form_data - 'calculatedGrossAmount' - 'calculatedNetAmount' - 'calculatedHoldbackAmount' - 'adjustedGrossAmount' - 'adjustedNetAmount' - 'adjustedHoldbackAmount' - 'dateSentToCsnr' - 'maximumAmount'
else
new_form_data || jsonb_build_object(
'calculatedGrossAmount',cif.form_change_calculated_gross_amount_this_milestone((select row(form_change.*)::cif.form_change from cif.form_change where id = row_id)),
'calculatedNetAmount',cif.form_change_calculated_net_amount_this_milestone((select row(form_change.*)::cif.form_change from cif.form_change where id = row_id)),
'calculatedHoldbackAmount',cif.form_change_calculated_holdback_amount_this_milestone((select row(form_change.*)::cif.form_change from cif.form_change where id = row_id)))
end
where id=$1
returning *;

$$ language sql volatile;

Expand Down
33 changes: 33 additions & 0 deletions schema/deploy/mutations/update_milestone_form_change@1.10.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- Deploy cif:mutations/update_milestone_form_change to pg


begin;

create or replace function cif.update_milestone_form_change(row_id int, form_change_patch cif.form_change)
returns cif.form_change
as
$$

select cif.update_form_change($1, $2);

-- remove the totalEligibleExpenses field if the reportType is not General Milestone
update cif.form_change
set new_form_data = new_form_data - 'totalEligibleExpenses'
where id = $1
and new_form_data->>'reportType' not in ('General Milestone', 'Interim Summary Report');

update cif.form_change set
new_form_data = new_form_data || jsonb_build_object(
'calculatedGrossAmount',cif.form_change_calculated_gross_amount_this_milestone((select row(form_change.*)::cif.form_change from cif.form_change where id = row_id)),
'calculatedNetAmount',cif.form_change_calculated_net_amount_this_milestone((select row(form_change.*)::cif.form_change from cif.form_change where id = row_id)),
'calculatedHoldbackAmount',cif.form_change_calculated_holdback_amount_this_milestone((select row(form_change.*)::cif.form_change from cif.form_change where id = row_id)))
where id=row_id
returning *;

$$ language sql volatile;

grant execute on function cif.update_milestone_form_change to cif_internal, cif_external, cif_admin;

comment on function cif.update_milestone_form_change(int, cif.form_change) is 'Custom mutation that updates the milestone form change (adds calculated values to new_form_data)';

commit;
Loading
Loading