diff --git a/hypha/apply/activity/adapters/activity_feed.py b/hypha/apply/activity/adapters/activity_feed.py index a8335198bb..dabc294873 100644 --- a/hypha/apply/activity/adapters/activity_feed.py +++ b/hypha/apply/activity/adapters/activity_feed.py @@ -8,6 +8,7 @@ from hypha.apply.activity.options import MESSAGES from hypha.apply.projects.utils import ( get_invoice_public_status, + get_invoice_status_display_value, get_project_public_status, get_project_status_display_value, ) @@ -66,6 +67,7 @@ class ActivityAdapter(AdapterBase): MESSAGES.DISABLED_REPORTING: _("Reporting disabled"), MESSAGES.BATCH_DELETE_SUBMISSION: "handle_batch_delete_submission", MESSAGES.BATCH_ARCHIVE_SUBMISSION: "handle_batch_archive_submission", + MESSAGES.BATCH_UPDATE_INVOICE_STATUS: "handle_batch_update_invoice_status", MESSAGES.ARCHIVE_SUBMISSION: _( "{user} has archived the submission: {source.title}" ), @@ -164,6 +166,16 @@ def handle_batch_archive_submission(self, sources, **kwargs): title=submissions_text ) + def handle_batch_update_invoice_status(self, sources, invoices, **kwargs): + invoice_numbers = ", ".join([invoice.invoice_number for invoice in invoices]) + invoice_status = invoices[0].status if invoices else "" + return _( + "Successfully updated status to {invoice_status} for invoices: {invoice_numbers}" + ).format( + invoice_status=get_invoice_status_display_value(invoice_status), + invoice_numbers=invoice_numbers, + ) + def handle_paf_assignment(self, source, paf_approvals, **kwargs): if hasattr(paf_approvals, "__iter__"): # paf_approvals has to be iterable users = ", ".join( diff --git a/hypha/apply/activity/adapters/base.py b/hypha/apply/activity/adapters/base.py index 535a3a2eab..6889e34272 100644 --- a/hypha/apply/activity/adapters/base.py +++ b/hypha/apply/activity/adapters/base.py @@ -36,6 +36,7 @@ MESSAGES.CREATE_REMINDER: "reminder", MESSAGES.DELETE_REMINDER: "reminder", MESSAGES.REVIEW_REMINDER: "reminder", + MESSAGES.BATCH_UPDATE_INVOICE_STATUS: "invoices", } diff --git a/hypha/apply/activity/options.py b/hypha/apply/activity/options.py index 5aa17b9d57..2675ec57c2 100644 --- a/hypha/apply/activity/options.py +++ b/hypha/apply/activity/options.py @@ -73,6 +73,10 @@ class MESSAGES(TextChoices): "BATCH_ARCHIVE_SUBMISSION", _("batch archive submissions"), ) + BATCH_UPDATE_INVOICE_STATUS = ( + "BATCH_INVOICE_STATUS_UPDATE", + _("batch update invoice status"), + ) STAFF_ACCOUNT_CREATED = "STAFF_ACCOUNT_CREATED", _("created new account") STAFF_ACCOUNT_EDITED = "STAFF_ACCOUNT_EDITED", _("edited account") ARCHIVE_SUBMISSION = "ARCHIVE_SUBMISSION", _("archived submission") diff --git a/hypha/apply/projects/service_utils.py b/hypha/apply/projects/service_utils.py index 52911d8246..db23ab5436 100644 --- a/hypha/apply/projects/service_utils.py +++ b/hypha/apply/projects/service_utils.py @@ -158,4 +158,3 @@ def batch_update_invoices_status(invoices, user, status): for invoice in invoices: invoice.status = status invoice.save(update_fields=["status"]) - # notify about batch invoice status update diff --git a/hypha/apply/projects/views/payment.py b/hypha/apply/projects/views/payment.py index d1b7a346c1..ca348b84a5 100644 --- a/hypha/apply/projects/views/payment.py +++ b/hypha/apply/projects/views/payment.py @@ -444,11 +444,28 @@ class BatchUpdateInvoiceStatusView(DelegatedViewMixin, FormView): def form_valid(self, form): new_status = form.cleaned_data["invoice_action"] invoices = form.cleaned_data["invoices"] + invoices_old_statuses = {invoice: invoice.status for invoice in invoices} batch_update_invoices_status( invoices=invoices, user=self.request.user, status=new_status, ) + + # add activity feed for batch update invoice status + projects = Project.objects.filter( + id__in=[invoice.project.id for invoice in invoices] + ) + messenger( + MESSAGES.BATCH_UPDATE_INVOICE_STATUS, + request=self.request, + user=self.request.user, + sources=projects, + related=invoices, + ) + + # update tasks for selected invoices + for invoice, old_status in invoices_old_statuses.items(): + handle_tasks_on_invoice_update(old_status, invoice) return super().form_valid(form) def form_invalid(self, form):