yuyu/core/management/commands/process_invoice.py
2022-09-27 13:37:09 +00:00

81 lines
3.1 KiB
Python

import logging
import traceback
from typing import Mapping, Dict, Iterable
from django.core.management import BaseCommand
from django.utils import timezone
from core.models import Invoice, InvoiceComponentMixin
from core.component import component, labels
from core.notification import send_notification_from_template, send_notification
from core.utils.dynamic_setting import get_dynamic_setting, BILLING_ENABLED, INVOICE_TAX, COMPANY_LOGO, COMPANY_NAME, \
COMPANY_ADDRESS
from yuyu import settings
LOG = logging.getLogger("yuyu_new_invoice")
class Command(BaseCommand):
help = 'Yuyu New Invoice'
def handle(self, *args, **options):
print("Processing Invoice")
try:
if not get_dynamic_setting(BILLING_ENABLED):
return
self.close_date = timezone.now()
self.tax_pertentage = get_dynamic_setting(INVOICE_TAX)
active_invoices = Invoice.objects.filter(state=Invoice.InvoiceState.IN_PROGRESS).all()
for active_invoice in active_invoices:
self.close_active_invoice(active_invoice)
except Exception:
send_notification(
project=None,
title='[Error] Error when processing Invoice',
short_description=f'There is an error when Processing Invoice',
content=f'There is an error when handling Processing Invoice \n {traceback.format_exc()}',
)
print("Processing Done")
def close_active_invoice(self, active_invoice: Invoice):
active_components_map: Dict[str, Iterable[InvoiceComponentMixin]] = {}
for label in labels.INVOICE_COMPONENT_LABELS:
active_components_map[label] = getattr(active_invoice, label).filter(end_date=None).all()
# Close Invoice Component
for active_component in active_components_map[label]:
active_component.close(self.close_date)
# Finish current invoice
active_invoice.close(self.close_date, self.tax_pertentage)
# Creating new Invoice
new_invoice = Invoice.objects.create(
project=active_invoice.project,
start_date=self.close_date,
state=Invoice.InvoiceState.IN_PROGRESS
)
new_invoice.save()
# Cloning active component to continue in next invoice
for label, active_components in active_components_map.items():
handler = component.INVOICE_HANDLER[label]
for active_component in active_components:
handler.roll(active_component, self.close_date, update_payload={
"invoice": new_invoice
}, fallback_price=True)
send_notification_from_template(
project=active_invoice.project,
title=settings.EMAIL_TAG + f' Your Invoice #{active_invoice.id} is Ready',
short_description=f'Invoice is ready with total of {active_invoice.total}',
template='invoice.html',
context={
'invoice': active_invoice,
'company_name': get_dynamic_setting(COMPANY_NAME),
'address': get_dynamic_setting(COMPANY_ADDRESS),
}
)