From 8521ced40c6b0e68277059014f2e06d4e8a4f995 Mon Sep 17 00:00:00 2001 From: Lakshit Jain <108322669+ljain112@users.noreply.github.com> Date: Wed, 15 Jan 2025 14:52:25 +0530 Subject: [PATCH] fix: use currency defined in plan for subscription invoice (#45104) (cherry picked from commit a4453fb77b458dfde91b5330a798d44024da722f) # Conflicts: # erpnext/accounts/doctype/subscription/subscription.py # erpnext/accounts/doctype/subscription/test_subscription.py --- .../doctype/subscription/subscription.py | 5 + .../doctype/subscription/test_subscription.py | 134 ++++++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index a08eb4dda7d..a5c1a16b332 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -369,8 +369,13 @@ class Subscription(Document): if frappe.db.get_value("Supplier", self.party, "tax_withholding_category"): invoice.apply_tds = 1 +<<<<<<< HEAD ### Add party currency to invoice invoice.currency = get_party_account_currency(self.party_type, self.party, self.company) +======= + # Add currency to invoice + invoice.currency = frappe.db.get_value("Subscription Plan", {"name": self.plans[0].plan}, "currency") +>>>>>>> a4453fb77b (fix: use currency defined in plan for subscription invoice (#45104)) ## Add dimensions in invoice for subscription: accounting_dimensions = get_accounting_dimensions() diff --git a/erpnext/accounts/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py index 26dcb2413f4..6fe8ba52938 100644 --- a/erpnext/accounts/doctype/subscription/test_subscription.py +++ b/erpnext/accounts/doctype/subscription/test_subscription.py @@ -693,6 +693,7 @@ class TestSubscription(FrappeTestCase): currency = frappe.db.get_value("Sales Invoice", subscription.invoices[0].invoice, "currency") self.assertEqual(currency, "USD") +<<<<<<< HEAD def test_plan_rate_for_midmonth_start_date(self): subscription = frappe.new_doc("Subscription") subscription.party_type = "Supplier" @@ -704,6 +705,38 @@ class TestSubscription(FrappeTestCase): subscription.end_date = "2024-02-27" subscription.append("plans", {"plan": "_Test Plan Name 4", "qty": 1}) subscription.save() +======= + @IntegrationTestCase.change_settings( + "Accounts Settings", + {"allow_multi_currency_invoices_against_single_party_account": 1}, + ) + def test_multi_currency_subscription_with_default_company_currency(self): + party = "Test Subscription Customer Multi Currency" + frappe.db.set_value("Customer", party, "default_currency", "USD") + subscription = create_subscription( + start_date="2018-01-01", + generate_invoice_at="Beginning of the current subscription period", + plans=[{"plan": "_Test Plan Multicurrency", "qty": 1, "currency": "USD"}], + party=party, + ) + + subscription.process(posting_date="2018-01-01") + self.assertEqual(len(subscription.invoices), 1) + self.assertEqual(subscription.status, "Unpaid") + + # Check the currency of the created invoice + currency = frappe.db.get_value("Sales Invoice", subscription.invoices[0].name, "currency") + self.assertEqual(currency, "USD") + + def test_subscription_recovery(self): + """Test if Subscription recovers when start/end date run out of sync with created invoices.""" + subscription = create_subscription( + start_date="2021-01-01", + submit_invoice=0, + generate_new_invoices_past_due_date=1, + party="_Test Subscription Customer John Doe", + ) +>>>>>>> a4453fb77b (fix: use currency defined in plan for subscription invoice (#45104)) subscription.process() @@ -727,3 +760,104 @@ class TestSubscription(FrappeTestCase): subscription.force_fetch_subscription_updates() subscription.reload() self.assertEqual(len(subscription.invoices), 0) +<<<<<<< HEAD +======= + + +def make_plans(): + create_plan(plan_name="_Test Plan Name", cost=900, currency="INR") + create_plan(plan_name="_Test Plan Name 2", cost=1999, currency="INR") + create_plan( + plan_name="_Test Plan Name 3", + cost=1999, + billing_interval="Day", + billing_interval_count=14, + currency="INR", + ) + create_plan( + plan_name="_Test Plan Name 4", + cost=20000, + billing_interval="Month", + billing_interval_count=3, + currency="INR", + ) + create_plan(plan_name="_Test Plan Multicurrency", cost=50, billing_interval="Month", currency="USD") + + +def create_plan(**kwargs): + if not frappe.db.exists("Subscription Plan", kwargs.get("plan_name")): + plan = frappe.new_doc("Subscription Plan") + plan.plan_name = kwargs.get("plan_name") or "_Test Plan Name" + plan.item = kwargs.get("item") or "_Test Non Stock Item" + plan.price_determination = kwargs.get("price_determination") or "Fixed Rate" + plan.cost = kwargs.get("cost") or 1000 + plan.billing_interval = kwargs.get("billing_interval") or "Month" + plan.billing_interval_count = kwargs.get("billing_interval_count") or 1 + plan.currency = kwargs.get("currency") + plan.insert() + + +def create_parties(): + if not frappe.db.exists("Supplier", "_Test Supplier"): + supplier = frappe.new_doc("Supplier") + supplier.supplier_name = "_Test Supplier" + supplier.supplier_group = "All Supplier Groups" + supplier.insert() + + if not frappe.db.exists("Customer", "_Test Subscription Customer"): + customer = frappe.new_doc("Customer") + customer.customer_name = "_Test Subscription Customer" + customer.default_currency = "USD" + customer.append("accounts", {"company": "_Test Company", "account": "_Test Receivable USD - _TC"}) + customer.insert() + + if not frappe.db.exists("Customer", "_Test Subscription Customer Multi Currency"): + customer = frappe.new_doc("Customer") + customer.customer_name = "Test Subscription Customer Multi Currency" + customer.default_currency = "USD" + customer.insert() + + if not frappe.db.exists("Customer", "_Test Subscription Customer John Doe"): + customer = frappe.new_doc("Customer") + customer.customer_name = "_Test Subscription Customer John Doe" + customer.append("accounts", {"company": "_Test Company", "account": "_Test Receivable - _TC"}) + customer.insert() + + +def reset_settings(): + settings = frappe.get_single("Subscription Settings") + settings.grace_period = 0 + settings.cancel_after_grace = 0 + settings.save() + + +def create_subscription(**kwargs): + subscription = frappe.new_doc("Subscription") + subscription.party_type = (kwargs.get("party_type") or "Customer",) + subscription.company = kwargs.get("company") or "_Test Company" + subscription.party = kwargs.get("party") or "_Test Customer" + subscription.trial_period_start = kwargs.get("trial_period_start") + subscription.trial_period_end = kwargs.get("trial_period_end") + subscription.start_date = kwargs.get("start_date") + subscription.generate_invoice_at = kwargs.get("generate_invoice_at") + subscription.additional_discount_percentage = kwargs.get("additional_discount_percentage") + subscription.additional_discount_amount = kwargs.get("additional_discount_amount") + subscription.follow_calendar_months = kwargs.get("follow_calendar_months") + subscription.generate_new_invoices_past_due_date = kwargs.get("generate_new_invoices_past_due_date") + subscription.submit_invoice = kwargs.get("submit_invoice") + subscription.days_until_due = kwargs.get("days_until_due") + subscription.number_of_days = kwargs.get("number_of_days") + + if not kwargs.get("plans"): + subscription.append("plans", {"plan": "_Test Plan Name", "qty": 1}) + else: + for plan in kwargs.get("plans"): + subscription.append("plans", plan) + + if kwargs.get("do_not_save"): + return subscription + + subscription.save() + + return subscription +>>>>>>> a4453fb77b (fix: use currency defined in plan for subscription invoice (#45104))