From 1fa6f283eccda777a5d1c71fdde35fb9a8fa8281 Mon Sep 17 00:00:00 2001 From: Bryan Nelson Date: Fri, 16 Aug 2024 11:18:34 -0400 Subject: [PATCH 1/3] Add EdgeDB trigger to appropriately create financial/narrative reports upon project creation --- dbschema/project.esdl | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/dbschema/project.esdl b/dbschema/project.esdl index 99fca0f65c..b524c9719a 100644 --- a/dbschema/project.esdl +++ b/dbschema/project.esdl @@ -119,6 +119,41 @@ module default { projectContext := __new__.projectContext, } ); + + trigger createPeriodicReportsOnInsert after insert for each do ( + with + interval := (select + if __new__.financialReportPeriod = default::ReportPeriod.Monthly then '1' else '3'), + reportRanges := Project::create_periodic_report_ranges( + __new__.mouStart, + __new__.mouEnd, + interval + ) + for reportRange in reportRanges + union ( + (insert default::FinancialReport { + createdAt := datetime_of_statement(), + modifiedAt := datetime_of_statement(), + createdBy := assert_exists(global currentActor), + modifiedBy := assert_exists(global currentActor), + project := __new__, + projectContext := __new__.projectContext, + container := __new__, + period := reportRange + #receivedDate := __new__.financialReportReceivedAt, //TODO - what is this at the project level? + }), + (insert default::NarrativeReport { + createdAt := datetime_of_statement(), + modifiedAt := datetime_of_statement(), + createdBy := assert_exists(global currentActor), + modifiedBy := assert_exists(global currentActor), + project := __new__, + projectContext := __new__.projectContext, + container := __new__, + period := reportRange + }) + ) + ) } abstract type TranslationProject extending Project { @@ -206,4 +241,22 @@ module Project { on target delete allow; }; } + + # creates the ranges for the given start and end dates based upon the given month interval + function create_periodic_report_ranges(startDate: cal::local_date, endDate: cal::local_date, + monthInterval: str) -> set of range + using ( + with + reportingPeriod := range(startDate, endDate), + reportPeriodStartDates := range_unpack(reportingPeriod, (monthInterval ++ ' month')), + reportPeriodRanges := ( + for firstDayOfMonth in reportPeriodStartDates + union ( + with + firstDayOfNextMonth := (select firstDayOfMonth + (monthInterval ++ ' month')), + lastDayOfMonth := firstDayOfNextMonth - '1 day' + select range(firstDayOfMonth, lastDayOfMonth) + )) + select reportPeriodRanges + ) } From c6d712033cccbd9fe4d1bd93dbf1aa43511ca8c9 Mon Sep 17 00:00:00 2001 From: Bryan Nelson Date: Wed, 11 Sep 2024 14:09:49 -0400 Subject: [PATCH 2/3] Adds `addRemovePeriodicReports` trigger in `Project` schema - Handles periodic report date ranges expanding and shrinking - Handles periodic report frequency changing --- dbschema/project.esdl | 145 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 3 deletions(-) diff --git a/dbschema/project.esdl b/dbschema/project.esdl index b524c9719a..67dc0f4f3f 100644 --- a/dbschema/project.esdl +++ b/dbschema/project.esdl @@ -120,7 +120,7 @@ module default { } ); - trigger createPeriodicReportsOnInsert after insert for each do ( + trigger createPeriodicReports after insert for each do ( with interval := (select if __new__.financialReportPeriod = default::ReportPeriod.Monthly then '1' else '3'), @@ -140,7 +140,6 @@ module default { projectContext := __new__.projectContext, container := __new__, period := reportRange - #receivedDate := __new__.financialReportReceivedAt, //TODO - what is this at the project level? }), (insert default::NarrativeReport { createdAt := datetime_of_statement(), @@ -153,7 +152,107 @@ module default { period := reportRange }) ) - ) + ); + + trigger addRemovePeriodicReports after update for each + when ( + __old__.mouStart != __new__.mouStart + or __old__.mouEnd != __new__.mouEnd + or __old__.financialReportPeriod != __new__.financialReportPeriod + ) + do ( + with + existingReportPeriods := ( + select FinancialReport + filter .container.id = __old__.id + ).period, + interval := ( + select (if __new__.financialReportPeriod = default::ReportPeriod.Monthly then '1' else '3') + ), + requestedReportPeriods := Project::create_periodic_report_ranges( + __new__.mouStart, + __new__.mouEnd, + interval + ) + if __old__.financialReportPeriod != __new__.financialReportPeriod ( + with + reportPeriodsWithoutFiles := ( + select existingReportPeriods + filter not exists .reportFile + ), + deletedReportPeriods : = ( + for reportPeriod in reportPeriodsWithoutFiles + union ( + delete reportPeriod + ) + ) + for reportPeriod in requestedReportPeriods + union ( + (insert default::FinancialReport { + createdAt := datetime_of_statement(), + modifiedAt := datetime_of_statement(), + createdBy := assert_exists(global currentActor), + modifiedBy := assert_exists(global currentActor), + project := __new__, + projectContext := __new__.projectContext, + container := __new__, + period := reportPeriod + }), + (insert default::NarrativeReport { + createdAt := datetime_of_statement(), + modifiedAt := datetime_of_statement(), + createdBy := assert_exists(global currentActor), + modifiedBy := assert_exists(global currentActor), + project := __new__, + projectContext := __new__.projectContext, + container := __new__, + period := reportPeriod + }) + ) + ) else ( + with + requestedReportPeriodsForInsertion := ( + select requestedReportPeriods + filter requestedReportPeriods not in existingReportPeriods + ), + requestedReportPeriodsForDeletion := ( + select existingReportPeriods + filter existingReportPeriods not in requestedReportPeriods + ), + applicableReportPeriodsForDeletion := ( + select PeriodicReport[is FinancialReport | NarrativeReport] + filter .period in requestedReportPeriodsForDeletion + and not exists .reportFile + ), + insertedReportPeriods := (for reportPeriod in requestedReportPeriodsForInsertion + union ( + (insert default::FinancialReport { + createdAt := datetime_of_statement(), + modifiedAt := datetime_of_statement(), + createdBy := assert_exists(global currentActor), + modifiedBy := assert_exists(global currentActor), + project := __new__, + projectContext := __new__.projectContext, + container := __new__, + period := reportPeriod + }), + (insert default::NarrativeReport { + createdAt := datetime_of_statement(), + modifiedAt := datetime_of_statement(), + createdBy := assert_exists(global currentActor), + modifiedBy := assert_exists(global currentActor), + project := __new__, + projectContext := __new__.projectContext, + container := __new__, + period := reportPeriod + }) + )) + for reportPeriod in applicableReportPeriodsForDeletion + union ( + delete reportPeriod + ) + ) + ); } abstract type TranslationProject extending Project { @@ -259,4 +358,44 @@ module Project { )) select reportPeriodRanges ) + + # TODO - Toying with the idea of abstracting some of this logic in some capacity... + # function insertReportPeriods(existingReportPeriods: set of range, + # requestedReportPeriods: set of range) -> optional str + # using ( + # with + # reportPeriodsWithoutFiles := ( + # select existingReportPeriods + # filter not exists .reportFile + # ), + # deletedReportPeriods : = ( + # for reportPeriod in reportPeriodsWithoutFiles + # union ( + # delete reportPeriod + # ) + # ) + # for reportPeriod in requestedReportPeriods + # union ( + # (insert default::FinancialReport { + # createdAt := datetime_of_statement(), + # modifiedAt := datetime_of_statement(), + # createdBy := assert_exists(global currentActor), + # modifiedBy := assert_exists(global currentActor), + # project := __new__, + # projectContext := __new__.projectContext, + # container := __new__, + # period := reportPeriod + # }), + # (insert default::NarrativeReport { + # createdAt := datetime_of_statement(), + # modifiedAt := datetime_of_statement(), + # createdBy := assert_exists(global currentActor), + # modifiedBy := assert_exists(global currentActor), + # project := __new__, + # projectContext := __new__.projectContext, + # container := __new__, + # period := reportPeriod + # }) + # ) + # ) } From 436412b30784966fa4aa2ec94284643870b3a5e2 Mon Sep 17 00:00:00 2001 From: Bryan Nelson Date: Wed, 11 Sep 2024 17:30:30 -0400 Subject: [PATCH 3/3] WIP --- dbschema/project.esdl | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/dbschema/project.esdl b/dbschema/project.esdl index 67dc0f4f3f..9ea288de63 100644 --- a/dbschema/project.esdl +++ b/dbschema/project.esdl @@ -156,16 +156,16 @@ module default { trigger addRemovePeriodicReports after update for each when ( - __old__.mouStart != __new__.mouStart - or __old__.mouEnd != __new__.mouEnd - or __old__.financialReportPeriod != __new__.financialReportPeriod + __old__.mouStart ?!= __new__.mouStart + or __old__.mouEnd ?!= __new__.mouEnd + or __old__.financialReportPeriod ?!= __new__.financialReportPeriod ) do ( with - existingReportPeriods := ( - select FinancialReport + existingReports := ( + select PeriodicReport filter .container.id = __old__.id - ).period, + ), interval := ( select (if __new__.financialReportPeriod = default::ReportPeriod.Monthly then '1' else '3') ), @@ -174,13 +174,13 @@ module default { __new__.mouEnd, interval ) - if __old__.financialReportPeriod != __new__.financialReportPeriod ( + select (if __old__.financialReportPeriod ?!= __new__.financialReportPeriod then ( with reportPeriodsWithoutFiles := ( - select existingReportPeriods + select existingReports filter not exists .reportFile ), - deletedReportPeriods : = ( + deletedReportPeriods := ( for reportPeriod in reportPeriodsWithoutFiles union ( delete reportPeriod @@ -213,14 +213,14 @@ module default { with requestedReportPeriodsForInsertion := ( select requestedReportPeriods - filter requestedReportPeriods not in existingReportPeriods + filter requestedReportPeriods not in existingReports.period ), requestedReportPeriodsForDeletion := ( - select existingReportPeriods - filter existingReportPeriods not in requestedReportPeriods + select existingReports.period + filter existingReports.period not in requestedReportPeriods ), - applicableReportPeriodsForDeletion := ( - select PeriodicReport[is FinancialReport | NarrativeReport] + applicableReportsForDeletion := ( + select PeriodicReport filter .period in requestedReportPeriodsForDeletion and not exists .reportFile ), @@ -247,11 +247,13 @@ module default { period := reportPeriod }) )) - for reportPeriod in applicableReportPeriodsForDeletion + for report in applicableReportsForDeletion union ( - delete reportPeriod + delete report + # filter report is typeof default::FinancialReport + # or report is typeof default::NarrativeReport ) - ) + )) ); }