diff --git a/puppet/zulip/files/cron.d/invoice-plans b/puppet/zulip/files/cron.d/invoice-plans new file mode 100644 index 0000000000..bbf53ec3bf --- /dev/null +++ b/puppet/zulip/files/cron.d/invoice-plans @@ -0,0 +1,5 @@ +SHELL=/bin/bash +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +USER=zulip + +0 22 * * * zulip /home/zulip/deployments/current/manage.py invoice_plans diff --git a/puppet/zulip_ops/manifests/prod_app_frontend.pp b/puppet/zulip_ops/manifests/prod_app_frontend.pp index ed7991998f..c205dd66d5 100644 --- a/puppet/zulip_ops/manifests/prod_app_frontend.pp +++ b/puppet/zulip_ops/manifests/prod_app_frontend.pp @@ -38,6 +38,16 @@ class zulip_ops::prod_app_frontend { mode => '0644', source => 'puppet:///modules/zulip/cron.d/calculate-first-visible-message-id', } + + # TODO: This should ideally move to a prod_app_frontend_once.pp + file { '/etc/cron.d/invoice-plans': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + source => 'puppet:///modules/zulip/cron.d/invoice-plans', + } + # Prod has our Apple Push Notifications Service private key at # /etc/ssl/django-private/apns-dist.pem } diff --git a/zerver/tests/test_management_commands.py b/zerver/tests/test_management_commands.py index a903503387..8d35567cfa 100644 --- a/zerver/tests/test_management_commands.py +++ b/zerver/tests/test_management_commands.py @@ -389,3 +389,12 @@ class TestConvertMattermostData(ZulipTestCase): mattermost_data_dir=os.path.realpath(mm_fixtures), output_dir=os.path.realpath(output_dir), ) + +class TestInvoicePlans(ZulipTestCase): + COMMAND_NAME = 'invoice_plans' + + def test_if_command_calls_invoice_plans_as_needed(self) -> None: + with patch('zilencer.management.commands.invoice_plans.invoice_plans_as_needed') as m: + call_command(self.COMMAND_NAME) + + m.assert_called_once() diff --git a/zilencer/management/commands/invoice_plans.py b/zilencer/management/commands/invoice_plans.py new file mode 100644 index 0000000000..8ecd9e5dc2 --- /dev/null +++ b/zilencer/management/commands/invoice_plans.py @@ -0,0 +1,14 @@ +from typing import Any + +from django.conf import settings + +from zerver.lib.management import ZulipBaseCommand +if settings.BILLING_ENABLED: + from corporate.lib.stripe import invoice_plans_as_needed + +class Command(ZulipBaseCommand): + help = """Generates invoices for customers if needed.""" + + def handle(self, *args: Any, **options: Any) -> None: + if settings.BILLING_ENABLED: + invoice_plans_as_needed()