diff --git a/corehq/apps/accounting/bootstrap/config/remove_free_50_sms_sep_2023.py b/corehq/apps/accounting/bootstrap/config/remove_free_50_sms_sep_2023.py new file mode 100644 index 000000000000..7e80937b2523 --- /dev/null +++ b/corehq/apps/accounting/bootstrap/config/remove_free_50_sms_sep_2023.py @@ -0,0 +1,30 @@ +from decimal import Decimal + +from corehq.apps.accounting.models import FeatureType, SoftwarePlanEdition + +BOOTSTRAP_CONFIG = { + (SoftwarePlanEdition.STANDARD, False, False): { + 'role': 'standard_plan_v1', + 'product_rate_monthly_fee': Decimal('300.00'), + 'feature_rates': { + FeatureType.USER: dict(monthly_limit=125, per_excess_fee=Decimal('2.00')), + FeatureType.SMS: dict(monthly_limit=0), + }, + }, + (SoftwarePlanEdition.PRO, False, False): { + 'role': 'pro_plan_v1', + 'product_rate_monthly_fee': Decimal('600.00'), + 'feature_rates': { + FeatureType.USER: dict(monthly_limit=250, per_excess_fee=Decimal('2.00')), + FeatureType.SMS: dict(monthly_limit=0), + }, + }, + (SoftwarePlanEdition.ADVANCED, False, False): { + 'role': 'advanced_plan_v0', + 'product_rate_monthly_fee': Decimal('1200.00'), + 'feature_rates': { + FeatureType.USER: dict(monthly_limit=500, per_excess_fee=Decimal('2.00')), + FeatureType.SMS: dict(monthly_limit=0), + } + }, +} diff --git a/corehq/apps/accounting/bootstrap/utils.py b/corehq/apps/accounting/bootstrap/utils.py index 76b1d64ccfc3..819d1d388fc8 100644 --- a/corehq/apps/accounting/bootstrap/utils.py +++ b/corehq/apps/accounting/bootstrap/utils.py @@ -8,11 +8,7 @@ log_accounting_info, ) -FEATURE_TYPES = [ - FeatureType.USER, - FeatureType.SMS, - FeatureType.WEB_USER, -] +FEATURE_TYPES = list(dict(FeatureType.CHOICES)) def ensure_plans(config, verbose, apps): diff --git a/corehq/apps/accounting/migrations/0085_remove_free_50_sms.py b/corehq/apps/accounting/migrations/0085_remove_free_50_sms.py new file mode 100644 index 000000000000..17c7c3ad6681 --- /dev/null +++ b/corehq/apps/accounting/migrations/0085_remove_free_50_sms.py @@ -0,0 +1,21 @@ +from django.db import migrations + +from corehq.apps.accounting.bootstrap.config.remove_free_50_sms_sep_2023 import ( + BOOTSTRAP_CONFIG, +) +from corehq.apps.accounting.bootstrap.utils import ensure_plans + + +def _bootstrap_new_standard_pricing(apps, schema_editor): + ensure_plans(BOOTSTRAP_CONFIG, verbose=True, apps=apps) + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounting', '0084_copy_cases_priv'), + ] + + operations = [ + migrations.RunPython(_bootstrap_new_standard_pricing), + ] diff --git a/corehq/apps/accounting/tests/test_invoicing.py b/corehq/apps/accounting/tests/test_invoicing.py index 51878cba3853..5603e1b167ce 100644 --- a/corehq/apps/accounting/tests/test_invoicing.py +++ b/corehq/apps/accounting/tests/test_invoicing.py @@ -562,6 +562,7 @@ def num_users(): class TestSmsLineItem(BaseInvoiceTestCase): + is_using_test_plans = True @classmethod def setUpClass(cls): @@ -654,7 +655,13 @@ def test_multipart_under_limit(self): self.assertEqual(sms_line_item.subtotal, Decimal('0.0000')) self.assertEqual(sms_line_item.total, Decimal('0.0000')) - def test_multipart_over_limit(self): + def test_multipart_over_limit_and_part_of_the_billable_is_under_limit(self): + """ + In this test, we particularly test the scenario that + half of the billable is within the limit, the remaining half exceeds the limit. + So it's crucial to use test plan in this test instead of default plan whose limit is 0. + """ + def _set_billable_date_sent_day(sms_billable, day): sms_billable.date_sent = datetime.date( sms_billable.date_sent.year, diff --git a/migrations.lock b/migrations.lock index 00037bc4ff24..5e99d35d13c6 100644 --- a/migrations.lock +++ b/migrations.lock @@ -104,6 +104,7 @@ accounting 0082_application_error_report_priv 0083_data_dictionary_priv 0084_copy_cases_priv + 0085_remove_free_50_sms admin 0001_initial 0002_logentry_remove_auto_add