From ab993fa2e589e4bb82232c794ef9230e6aeb2b7b Mon Sep 17 00:00:00 2001 From: Tiago-da-Silva23 Date: Thu, 2 Nov 2023 18:25:03 +0000 Subject: [PATCH 1/5] refactor: implemented ISO format in the used dates, refactor: refactored the RevenueConfiguration filter, refactor: added partner_percentage and RevenueConfiguration dates to the export file --- .../management/commands/export_split_revenue.py | 8 ++++---- apps/shared_revenue/services/split_execution.py | 17 +++++++++++++---- apps/shared_revenue/services/split_export.py | 3 +++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/apps/shared_revenue/management/commands/export_split_revenue.py b/apps/shared_revenue/management/commands/export_split_revenue.py index 9fc57ec..6168211 100644 --- a/apps/shared_revenue/management/commands/export_split_revenue.py +++ b/apps/shared_revenue/management/commands/export_split_revenue.py @@ -37,10 +37,10 @@ def handle(self, *args, **options) -> str | None: try: start = time.time() self.stdout.write("\nStarting file export...\n") - start_date = datetime.strptime(options["start_date"], "%d/%m/%Y") - end_date = datetime.strptime(options["end_date"], "%d/%m/%Y") + ( - timedelta(days=1) - timedelta(milliseconds=1) - ) + start_date = datetime.strptime(options["start_date"], "%Y/%m/%d").isoformat() + end_date = ( + datetime.strptime(options["end_date"], "%Y/%m/%d") + (timedelta(days=1) - timedelta(milliseconds=1)) + ).isoformat() product_id = options.get("product_id") organization_code = options.get("organization_code") kwargs = { diff --git a/apps/shared_revenue/services/split_execution.py b/apps/shared_revenue/services/split_execution.py index e1a0d3f..1e6580a 100644 --- a/apps/shared_revenue/services/split_execution.py +++ b/apps/shared_revenue/services/split_execution.py @@ -53,7 +53,9 @@ def _filter_revenue_configurations(self, **kwargs) -> list[RevenueConfiguration] try: configurations = RevenueConfiguration.objects.filter( - Q(start_date__isnull=True) | Q(end_date__isnull=True) | Q(end_date__gte=self.start_date), + Q(start_date__isnull=True) + | Q(end_date__isnull=True) + | Q(start_date__lte=self.end_date) & Q(end_date__gte=self.start_date) ) if kwargs: new_kwargs = kwargs @@ -90,12 +92,15 @@ def _assembly_each_result( return { "product_name": item.description, - "transaction_date": item.transaction.transaction_date, + "transaction_date": item.transaction.transaction_date.isoformat(), "total_amount_include_vat": item.transaction.total_amount_include_vat, "total_amount_exclude_vat": item.transaction.total_amount_exclude_vat, "organization_code": configuration.organization.short_name, "amount_for_nau": item.transaction.total_amount_include_vat * (1 - configuration.partner_percentage), "amount_for_organization": item.transaction.total_amount_include_vat * configuration.partner_percentage, + "partner_percentage": configuration.partner_percentage, + "configuration_start_date": configuration.start_date, + "configuration_end_date": configuration.end_date, } def _calculate_transactions( @@ -118,8 +123,12 @@ def _calculate_transactions( for item in transaction_items: for configuration in configurations: - result = self._assembly_each_result(item=item, configuration=configuration) - split_results.append(result) + if (None in [configuration.start_date, configuration.end_date]) or ( + configuration.start_date <= item.transaction.transaction_date + and configuration.end_date >= item.transaction.transaction_date + ): + result = self._assembly_each_result(item=item, configuration=configuration) + split_results.append(result) return split_results diff --git a/apps/shared_revenue/services/split_export.py b/apps/shared_revenue/services/split_export.py index 3399ff6..07e2756 100644 --- a/apps/shared_revenue/services/split_export.py +++ b/apps/shared_revenue/services/split_export.py @@ -65,6 +65,9 @@ def export_split_to_xlsx( "organization_code", "amount_for_nau", "amount_for_organization", + "partner_percentage", + "configuration_start_date", + "configuration_end_date", ], ) except Exception as e: From 77808e088cc80129f9d058391ca0cf4749e71996 Mon Sep 17 00:00:00 2001 From: Tiago-da-Silva23 Date: Mon, 6 Nov 2023 11:04:25 +0000 Subject: [PATCH 2/5] refactor: adjusted the populate for more compliance data --- apps/util/populate_db.py | 46 +++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/apps/util/populate_db.py b/apps/util/populate_db.py index 8d57fad..b07f390 100644 --- a/apps/util/populate_db.py +++ b/apps/util/populate_db.py @@ -11,42 +11,37 @@ from apps.billing.factories import TransactionFactory, TransactionItemFactory -def generate_revenue_configuration( - organization, -) -> RevenueConfigurationFactory: - """ - Generates and populates RevenueConfiguration model. + +def populate_shared_revenue(organization, product_ids: list[str]) -> None: """ + Populates shared_revenue module, creates RevenueConfiguration + """ - revenue_configuration = RevenueConfigurationFactory.create( + for product_id in product_ids: + RevenueConfigurationFactory.create( organization=organization, + product_id=product_id, partner_percentage=0.70 ) - - return revenue_configuration - - -def populate_shared_revenue(organization) -> None: - """ - - Starts populate of shared_revenue module, creates RevenueConfiguration and ShareExecution - """ - - revenue_configuration = generate_revenue_configuration( - organization, - ) - return revenue_configuration -def populate_billing(organization) -> None: +def populate_billing(organization) -> list[str]: """ Populates billing module, creates five transactions per organization and one TransactionItem per Transaction """ amount_of_transactions = 5 transactions = TransactionFactory.create_batch(amount_of_transactions) + product_ids = [] for transaction in transactions: - TransactionItemFactory.create(transaction=transaction) + item: TransactionItemFactory = TransactionItemFactory.create( + transaction=transaction, + organization_code=organization.short_name, + ) + if not item.product_id in product_ids: + product_ids.append(item.product_id) + + return product_ids def populate(): @@ -60,8 +55,11 @@ def populate(): for organization in organizations: OrganizationContactFactory.create(organization=organization) OrganizationAddressFactory.create(organization=organization) - populate_shared_revenue(organization=organization) - populate_billing(organization=organization) + product_ids = populate_billing(organization=organization) + populate_shared_revenue( + product_ids=product_ids, + organization=organization, + ) except Exception as e: raise e From 3e7ef6e5cc2e52ef038cb7f07418ba86163d8556 Mon Sep 17 00:00:00 2001 From: Tiago-da-Silva23 Date: Mon, 6 Nov 2023 11:05:44 +0000 Subject: [PATCH 3/5] refactor: adjusted start_date to build an older available configuration --- apps/shared_revenue/factories.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/shared_revenue/factories.py b/apps/shared_revenue/factories.py index 2138cc2..d32d9e1 100644 --- a/apps/shared_revenue/factories.py +++ b/apps/shared_revenue/factories.py @@ -18,7 +18,7 @@ class Meta: f"course-v1:UPorto+CBN{random.choice(string.ascii_uppercase)}{random.choice(string.ascii_uppercase)}F+2023_T3" ) start_date = factory.Faker( - "date_time_between", start_date="now", end_date="+30d", tzinfo=timezone.get_current_timezone() + "date_time_between", start_date="-10d", end_date="+30d", tzinfo=timezone.get_current_timezone() ) end_date = factory.Faker( "date_time_between", start_date="+40d", end_date="+70d", tzinfo=timezone.get_current_timezone() From 1b69f865d273b5f8c46dd7c9f596875576825505 Mon Sep 17 00:00:00 2001 From: Tiago-da-Silva23 Date: Mon, 6 Nov 2023 11:06:55 +0000 Subject: [PATCH 4/5] refactor: adjusted the product_id and product_code in the TransactionItem --- apps/billing/factories.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/billing/factories.py b/apps/billing/factories.py index 39d4442..b6b6bba 100644 --- a/apps/billing/factories.py +++ b/apps/billing/factories.py @@ -1,3 +1,5 @@ +import random +import string from decimal import Decimal import factory @@ -48,8 +50,11 @@ class Meta: vat_tax = factory.Faker("pydecimal", min_value=1, max_value=100, left_digits=3, right_digits=2) amount_exclude_vat = factory.Faker("pydecimal", min_value=1, max_value=100, left_digits=5, right_digits=2) organization_code = factory.LazyAttribute(lambda obj: slugify(obj.description)) - product_code = factory.Faker("ean13") - product_id = factory.Faker("uuid4") + product_code = "".join([random.choice(string.ascii_uppercase) for _ in range(5)]) + + @factory.lazy_attribute + def product_id(self): + return f"course-v1:{self.organization_code}+{self.product_code}+2023_T3" # Assuming 20% VAT @factory.lazy_attribute From e6693a91de983ffce551c746c3cd2f0cf335aab9 Mon Sep 17 00:00:00 2001 From: Tiago-da-Silva23 Date: Mon, 6 Nov 2023 11:09:00 +0000 Subject: [PATCH 5/5] refactor: adjusted the date format, refactor: adjusted the split logic --- .../commands/export_split_revenue.py | 6 +----- apps/shared_revenue/models.py | 2 +- .../shared_revenue/services/split_execution.py | 18 ++++++++++-------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/apps/shared_revenue/management/commands/export_split_revenue.py b/apps/shared_revenue/management/commands/export_split_revenue.py index 6168211..dfa17be 100644 --- a/apps/shared_revenue/management/commands/export_split_revenue.py +++ b/apps/shared_revenue/management/commands/export_split_revenue.py @@ -43,11 +43,7 @@ def handle(self, *args, **options) -> str | None: ).isoformat() product_id = options.get("product_id") organization_code = options.get("organization_code") - kwargs = { - k: v - for k, v in {"product_id": product_id, "organization_code": organization_code}.items() - if v not in ["", None] - } + kwargs = {k: v for k, v in {"product_id": product_id, "organization_code": organization_code}.items() if v} SplitExportService().export_split_to_xlsx( start_date=start_date, end_date=end_date, diff --git a/apps/shared_revenue/models.py b/apps/shared_revenue/models.py index db22c26..96bc661 100644 --- a/apps/shared_revenue/models.py +++ b/apps/shared_revenue/models.py @@ -62,7 +62,7 @@ def check_each_configuration( configuration, ) -> bool: - id = self.id if self.id is not None else -1 + id = self.id if configuration.id == id: return True diff --git a/apps/shared_revenue/services/split_execution.py b/apps/shared_revenue/services/split_execution.py index 1e6580a..03b1c4f 100644 --- a/apps/shared_revenue/services/split_execution.py +++ b/apps/shared_revenue/services/split_execution.py @@ -36,8 +36,9 @@ def _filter_transaction_items(self, **kwargs) -> list[TransactionItem]: transactions = Transaction.objects.filter(transaction_date__range=[self.start_date, self.end_date]) transaction_items: list[TransactionItem] = [] for transaction in transactions: - kwargs["transaction"] = transaction - transaction_items += TransactionItem.objects.filter(**kwargs) + items = transaction.transaction_items.all() + if items: + transaction_items.append(items[0]) return transaction_items except Exception as e: @@ -95,7 +96,7 @@ def _assembly_each_result( "transaction_date": item.transaction.transaction_date.isoformat(), "total_amount_include_vat": item.transaction.total_amount_include_vat, "total_amount_exclude_vat": item.transaction.total_amount_exclude_vat, - "organization_code": configuration.organization.short_name, + "organization_code": item.organization_code, "amount_for_nau": item.transaction.total_amount_include_vat * (1 - configuration.partner_percentage), "amount_for_organization": item.transaction.total_amount_include_vat * configuration.partner_percentage, "partner_percentage": configuration.partner_percentage, @@ -123,10 +124,11 @@ def _calculate_transactions( for item in transaction_items: for configuration in configurations: - if (None in [configuration.start_date, configuration.end_date]) or ( - configuration.start_date <= item.transaction.transaction_date - and configuration.end_date >= item.transaction.transaction_date - ): + if item.organization_code == configuration.organization.short_name: + if None not in [configuration.start_date, configuration.end_date]: + if not configuration.start_date <= item.transaction.transaction_date <= configuration.end_date: + continue + result = self._assembly_each_result(item=item, configuration=configuration) split_results.append(result) @@ -140,8 +142,8 @@ def execute_split_steps(self, **kwargs) -> list[Dict]: list[Dict]: All the calculated split results """ try: - transaction_items: list[TransactionItem] = self._filter_transaction_items(**kwargs) configurations: list[RevenueConfiguration] = self._filter_revenue_configurations(**kwargs) + transaction_items: list[TransactionItem] = self._filter_transaction_items(**kwargs) split_results = self._calculate_transactions( transaction_items=transaction_items, configurations=configurations,