diff --git a/api/custom_validator.py b/api/custom_validator.py new file mode 100644 index 0000000..06c87e4 --- /dev/null +++ b/api/custom_validator.py @@ -0,0 +1,12 @@ +from django.core import validators +from django.core.exceptions import ValidationError +from rest_framework import serializers + + +def email_list(value): + try: + emails = value.replace(" ", "").split(",") + for email in emails: + validators.validate_email(email) + except ValidationError: + raise serializers.ValidationError('Field contain invalid email address') diff --git a/api/serializers.py b/api/serializers.py index 840e1b3..e47aae4 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -1,6 +1,7 @@ from djmoney.contrib.django_rest_framework import MoneyField from rest_framework import serializers +from api import custom_validator from core.models import Invoice, BillingProject, Notification from core.component import component @@ -58,7 +59,7 @@ class SimpleInvoiceSerializer(serializers.ModelSerializer): class BillingProjectSerializer(serializers.ModelSerializer): tenant_id = serializers.CharField(required=False, read_only=True) - email_notification = serializers.EmailField(required=False) + email_notification = serializers.CharField(required=False, validators=[custom_validator.email_list]) class Meta: model = BillingProject @@ -71,4 +72,5 @@ class NotificationSerializer(serializers.ModelSerializer): class Meta: model = Notification - fields = ['id', 'project', 'title', 'short_description', 'content', 'sent_status', 'is_read', 'created_at', 'recipient'] + fields = ['id', 'project', 'title', 'short_description', 'content', 'sent_status', 'is_read', 'created_at', + 'recipient'] diff --git a/api/views.py b/api/views.py index f3677cb..aef4036 100644 --- a/api/views.py +++ b/api/views.py @@ -5,7 +5,6 @@ import pytz from django.db import transaction from django.utils import timezone from djmoney.money import Money -from djmoney.settings import DEFAULT_CURRENCY from rest_framework import viewsets, serializers from rest_framework.decorators import action from rest_framework.response import Response @@ -17,7 +16,7 @@ from core.exception import PriceNotFound from core.models import Invoice, BillingProject, Notification from core.notification import send_notification_from_template from core.utils.dynamic_setting import get_dynamic_settings, get_dynamic_setting, set_dynamic_setting, BILLING_ENABLED, \ - INVOICE_TAX, COMPANY_NAME, COMPANY_LOGO, COMPANY_ADDRESS + INVOICE_TAX, COMPANY_NAME, COMPANY_ADDRESS from core.utils.model_utils import InvoiceComponentMixin from yuyu import settings diff --git a/core/migrations/0011_auto_20221121_1505.py b/core/migrations/0011_auto_20221121_1505.py new file mode 100644 index 0000000..608d9b6 --- /dev/null +++ b/core/migrations/0011_auto_20221121_1505.py @@ -0,0 +1,149 @@ +# Generated by Django 3.2.6 on 2022-11-21 15:05 + +from django.db import migrations, models +import djmoney.models.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0010_auto_20221031_1801'), + ] + + operations = [ + migrations.AlterField( + model_name='billingproject', + name='email_notification', + field=models.CharField(blank=True, max_length=512, null=True), + ), + migrations.AlterField( + model_name='flavorprice', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='flavorprice', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='floatingipsprice', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='floatingipsprice', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='imageprice', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='imageprice', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoice', + name='tax_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoice', + name='total_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoicefloatingip', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoicefloatingip', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoiceimage', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoiceimage', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoiceinstance', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoiceinstance', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoicerouter', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoicerouter', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoicesnapshot', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoicesnapshot', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoicevolume', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='invoicevolume', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='routerprice', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='routerprice', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='snapshotprice', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='snapshotprice', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='volumeprice', + name='hourly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + migrations.AlterField( + model_name='volumeprice', + name='monthly_price_currency', + field=djmoney.models.fields.CurrencyField(choices=[('IDR', 'Indonesian Rupiah')], default='IDR', editable=False, max_length=3), + ), + ] diff --git a/core/models.py b/core/models.py index 270afde..627f560 100644 --- a/core/models.py +++ b/core/models.py @@ -1,7 +1,6 @@ import logging -import re - import math +import re from django.conf import settings from django.core.mail import send_mail @@ -68,7 +67,7 @@ class ImagePrice(BaseModel, TimestampMixin, PriceMixin): # region Invoicing class BillingProject(BaseModel, TimestampMixin): tenant_id = models.CharField(max_length=256) - email_notification = models.EmailField(max_length=256, blank=True, null=True) + email_notification = models.CharField(max_length=512, blank=True, null=True) def __str__(self): return self.tenant_id @@ -268,7 +267,7 @@ class Notification(BaseModel, TimestampMixin): is_read = models.BooleanField() def recipient(self): - if self.project: + if self.project and self.project.email_notification: return self.project.email_notification return 'Admin' @@ -281,9 +280,9 @@ class Notification(BaseModel, TimestampMixin): # Strip single spaces in the beginning of each line return text_only.replace('\n ', '\n').strip() - recipient = [get_dynamic_setting(EMAIL_ADMIN)] - if self.project is not None: - recipient.append(self.project.email_notification) + recipient = get_dynamic_setting(EMAIL_ADMIN).split(",") + if self.project and self.project.email_notification: + recipient += self.project.email_notification.split(",") send_mail( subject=self.title,