5454from reporting .models .reporting_year import ReportingYear
5555from service .reporting_year_service import ReportingYearService
5656from django .conf import settings
57- from service .operation_designated_operator_timeline_service import OperationDesignatedOperatorTimelineService
57+ from service .operation_designated_operator_timeline_service import (
58+ OperationDesignatedOperatorTimelinePlus ,
59+ OperationDesignatedOperatorTimelineService ,
60+ )
5861from reporting .models .report import Report
5962
6063
6164class OperationService :
6265
6366 OPERATION_DEFAULT_START_DATE = datetime (2024 , 1 , 1 , tzinfo = ZoneInfo ("America/Vancouver" ))
67+ MIN_REPORTING_YEAR = 2024
6468
6569 @classmethod
6670 def get_if_authorized (
@@ -755,6 +759,7 @@ def handle_change_of_registration_purpose(
755759
756760 return payload
757761
762+ # list previous reportable operations methods:
758763 @staticmethod
759764 def get_valid_operation_regulated_products (operation : Operation , reporting_year : int ) -> QuerySet [RegulatedProduct ]:
760765 """
@@ -772,19 +777,31 @@ def _is_reportable_operation_year(
772777 ) -> bool :
773778 return operation_year not in added_operation_years and operation_year not in existing_reports
774779
780+ @classmethod
781+ def _is_designated_to_user_operator (
782+ cls ,
783+ designated_operator_timeline : OperationDesignatedOperatorTimelinePlus | None ,
784+ user_operator : UserOperator ,
785+ ) -> bool :
786+ return (
787+ designated_operator_timeline is not None
788+ and designated_operator_timeline .operator .id == user_operator .operator_id
789+ )
790+
775791 @classmethod
776792 def _get_previous_reporting_years (cls ) -> QuerySet [ReportingYear ]:
777793 """
778794 Returns reporting years that are eligible for the Start Past Report workflow
779795
780- Only reporting years prior to the current reporting year are returned
796+ Only reporting years from MIN_REPORTING_YEAR up to (but not including) the current
797+ reporting year are returned.
781798 """
782-
783799 current_reporting_year = ReportingYearService .get_current_reporting_year ()
784800
785- return ReportingYear .objects .filter (reporting_year__lt = current_reporting_year .reporting_year ).order_by (
786- "-reporting_year"
787- )
801+ return ReportingYear .objects .filter (
802+ reporting_year__gte = cls .MIN_REPORTING_YEAR ,
803+ reporting_year__lt = current_reporting_year .reporting_year ,
804+ ).order_by ("-reporting_year" )
788805
789806 @staticmethod
790807 def _get_registration_purposes_for_operation_type (
@@ -812,6 +829,29 @@ def _get_registration_purposes_for_operation_type(
812829
813830 raise ValueError (f"Unsupported operation type: { operation_type } " )
814831
832+ @classmethod
833+ def _add_reportable_operation (
834+ cls ,
835+ reportable_operations : list [dict ],
836+ added_operation_years : set [tuple [UUID , int ]],
837+ operation : Operation ,
838+ reporting_year : ReportingYear ,
839+ is_current_registered_fallback : bool ,
840+ ) -> None :
841+ """
842+ Adds a reportable operation/reporting year combination to the result set
843+ and tracks it to prevent duplicates.
844+ """
845+ operation_year = (operation .id , reporting_year .reporting_year )
846+
847+ reportable_operations .append (
848+ {
849+ ** cls ._build_reportable_operation_row (operation , reporting_year ),
850+ "is_current_registered_fallback" : is_current_registered_fallback ,
851+ }
852+ )
853+ added_operation_years .add (operation_year )
854+
815855 @classmethod
816856 def _build_reportable_operation_row (
817857 cls ,
@@ -897,6 +937,7 @@ def list_previous_reportable_operations(
897937 reporting_year .reporting_year ,
898938 )
899939
940+ # Skip combinations that have already have a report
900941 if not cls ._is_reportable_operation_year (
901942 operation_year ,
902943 added_operation_years ,
@@ -906,46 +947,41 @@ def list_previous_reportable_operations(
906947
907948 designated_operator_timeline = designations_lookup .get (operation_year )
908949
909- if (
910- designated_operator_timeline
911- and designated_operator_timeline .operator .id == user_operator .operator_id
950+ # Include operations designated to the user's operator for the reporting year
951+ if cls ._is_designated_to_user_operator (
952+ designated_operator_timeline ,
953+ user_operator ,
912954 ):
913- reportable_operations .append (
914- {
915- ** cls ._build_reportable_operation_row (
916- timeline .operation ,
917- reporting_year ,
918- ),
919- "is_current_registered_fallback" : False ,
920- }
955+ cls ._add_reportable_operation (
956+ reportable_operations ,
957+ added_operation_years ,
958+ timeline .operation ,
959+ reporting_year ,
960+ False ,
921961 )
922962
923- added_operation_years .add (operation_year )
924-
925963 for operation in current_registered_operations :
926964 for reporting_year in reporting_years :
927965 operation_year = (
928966 operation .id ,
929967 reporting_year .reporting_year ,
930968 )
931969
970+ # Skip combinations that have already have a report
932971 if not cls ._is_reportable_operation_year (
933972 operation_year ,
934973 added_operation_years ,
935974 existing_reports ,
936975 ):
937976 continue
938977
939- reportable_operations .append (
940- {
941- ** cls ._build_reportable_operation_row (
942- operation ,
943- reporting_year ,
944- ),
945- "is_current_registered_fallback" : True ,
946- }
978+ # Fall back to the current registered operator when no historical designation applies
979+ cls ._add_reportable_operation (
980+ reportable_operations ,
981+ added_operation_years ,
982+ operation ,
983+ reporting_year ,
984+ True ,
947985 )
948986
949- added_operation_years .add (operation_year )
950-
951987 return reportable_operations
0 commit comments