From 66ea876f159513cd8b26b9c44aceffef97a91d1e Mon Sep 17 00:00:00 2001 From: Trey <73353716+TreyWW@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:31:42 +0100 Subject: [PATCH 1/4] added AWS_ENABLED Signed-off-by: Trey <73353716+TreyWW@users.noreply.github.com> --- backend/service/boto3/handler.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/service/boto3/handler.py b/backend/service/boto3/handler.py index 0d59016a9..58365449c 100644 --- a/backend/service/boto3/handler.py +++ b/backend/service/boto3/handler.py @@ -49,10 +49,14 @@ def _initiate_session(self): boto3.set_stream_logger("", level=logging.INFO) def _initiate_clients(self): - if get_var("AWS_DISABLED"): + if get_var("AWS_DISABLED", "").lower() == "true": logger.info("The variable AWS_DISABLED is present, not initiating boto3") return + if not get_var("AWS_ENABLED"): + logger.error("The variable AWS_ENABLED is not present, not initiating boto3") + return + self._initiate_session() try: From 260c89ec6a1e290306b89ce6770093275cd862c2 Mon Sep 17 00:00:00 2001 From: Trey <73353716+TreyWW@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:40:58 +0100 Subject: [PATCH 2/4] added require_change_password to admin Signed-off-by: Trey <73353716+TreyWW@users.noreply.github.com> --- backend/admin.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/backend/admin.py b/backend/admin.py index d0506cf24..2b3653a87 100644 --- a/backend/admin.py +++ b/backend/admin.py @@ -114,7 +114,17 @@ class InvoiceURLAdmin(admin.ModelAdmin): fields = list(UserAdmin.fieldsets) # type: ignore[arg-type] fields[0] = ( None, - {"fields": ("username", "password", "logged_in_as_team", "awaiting_email_verification", "stripe_customer_id", "entitlements")}, + { + "fields": ( + "username", + "password", + "logged_in_as_team", + "awaiting_email_verification", + "stripe_customer_id", + "entitlements", + "require_change_password", + ) + }, ) UserAdmin.fieldsets = tuple(fields) admin.site.register(User, UserAdmin) From e3977c5050bdff72b472d39894e49a83d53c4bbf Mon Sep 17 00:00:00 2001 From: Trey <73353716+TreyWW@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:23:27 +0100 Subject: [PATCH 3/4] feat: added the ability to save as a default fields such as FROM name, address, etc (#490) Signed-off-by: Trey <73353716+TreyWW@users.noreply.github.com> --- backend/api/base/modal.py | 10 + .../api/invoices/create/set_destination.py | 4 +- ...ultvalues_invoice_from_address_and_more.py | 43 +++ backend/models.py | 7 + backend/service/defaults/update.py | 18 ++ .../invoices/common/create/get_page.py | 15 +- .../pages/clients/detail/client_defaults.html | 270 +++++++++++------- .../invoices/create/create_recurring.html | 4 +- .../pages/invoices/create/create_single.html | 4 +- .../destinations/_from_destination.html | 34 ++- .../create/destinations/_to_destination.html | 24 +- .../recurring/edit/edit_recurring.html | 4 +- 12 files changed, 304 insertions(+), 133 deletions(-) create mode 100644 backend/migrations/0061_defaultvalues_invoice_from_address_and_more.py diff --git a/backend/api/base/modal.py b/backend/api/base/modal.py index a168219f3..55921e97c 100644 --- a/backend/api/base/modal.py +++ b/backend/api/base/modal.py @@ -14,6 +14,7 @@ from backend.types.htmx import HtmxHttpRequest from backend.types.requests import WebRequest from backend.utils.feature_flags import get_feature_status +from backend.service.defaults.get import get_account_defaults # from backend.utils.quota_limit_ops import quota_usage_check_under @@ -91,6 +92,15 @@ def open_modal(request: WebRequest, modal_name, context_type=None, context_value context["from_city"] = invoice.self_city context["from_county"] = invoice.self_county context["from_country"] = invoice.self_country + elif context_type == "create_invoice_from": + defaults = get_account_defaults(request.actor) + + context["from_name"] = getattr(defaults, f"invoice_from_name") + context["from_company"] = getattr(defaults, f"invoice_from_company") + context["from_address"] = getattr(defaults, f"invoice_from_address") + context["from_city"] = getattr(defaults, f"invoice_from_city") + context["from_county"] = getattr(defaults, f"invoice_from_county") + context["from_country"] = getattr(defaults, f"invoice_from_country") elif context_type == "invoice": try: invoice = Invoice.objects.get(id=context_value) diff --git a/backend/api/invoices/create/set_destination.py b/backend/api/invoices/create/set_destination.py index 1998f4676..427854f75 100644 --- a/backend/api/invoices/create/set_destination.py +++ b/backend/api/invoices/create/set_destination.py @@ -12,7 +12,7 @@ def set_destination_to(request: HtmxHttpRequest): context: dict = {"swapping": True} - context.update({key: request.POST.get(key, "") for key in to_get}) + context.update({f"to_{key}": request.POST.get(key, "") for key in to_get}) use_existing = True if request.POST.get("use_existing") == "true" else False selected_client = request.POST.get("selected_client") if use_existing else None @@ -31,6 +31,6 @@ def set_destination_to(request: HtmxHttpRequest): def set_destination_from(request: HtmxHttpRequest): context: dict = {"swapping": True} - context.update({key: request.POST.get(key, "") for key in to_get}) + context.update({f"from_{key}": request.POST.get(key, "") for key in to_get}) return render(request, "pages/invoices/create/destinations/_from_destination.html", context) diff --git a/backend/migrations/0061_defaultvalues_invoice_from_address_and_more.py b/backend/migrations/0061_defaultvalues_invoice_from_address_and_more.py new file mode 100644 index 000000000..053b5b856 --- /dev/null +++ b/backend/migrations/0061_defaultvalues_invoice_from_address_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 5.1 on 2024-09-16 19:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("backend", "0060_user_require_change_password"), + ] + + operations = [ + migrations.AddField( + model_name="defaultvalues", + name="invoice_from_address", + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name="defaultvalues", + name="invoice_from_city", + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name="defaultvalues", + name="invoice_from_company", + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name="defaultvalues", + name="invoice_from_country", + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name="defaultvalues", + name="invoice_from_county", + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name="defaultvalues", + name="invoice_from_name", + field=models.CharField(blank=True, max_length=100, null=True), + ), + ] diff --git a/backend/models.py b/backend/models.py index 352335fb5..bec0d24d6 100644 --- a/backend/models.py +++ b/backend/models.py @@ -400,6 +400,13 @@ class InvoiceDateType(models.TextChoices): invoice_date_value = models.PositiveSmallIntegerField(default=15, null=False, blank=False) invoice_date_type = models.CharField(max_length=20, choices=InvoiceDateType.choices, default=InvoiceDateType.day_of_month) + invoice_from_name = models.CharField(max_length=100, null=True, blank=True) + invoice_from_company = models.CharField(max_length=100, null=True, blank=True) + invoice_from_address = models.CharField(max_length=100, null=True, blank=True) + invoice_from_city = models.CharField(max_length=100, null=True, blank=True) + invoice_from_county = models.CharField(max_length=100, null=True, blank=True) + invoice_from_country = models.CharField(max_length=100, null=True, blank=True) + def get_issue_and_due_dates(self, issue_date: date | str | None = None) -> tuple[str, str]: due: date issue: date diff --git a/backend/service/defaults/update.py b/backend/service/defaults/update.py index b29405f46..eba73a828 100644 --- a/backend/service/defaults/update.py +++ b/backend/service/defaults/update.py @@ -44,6 +44,24 @@ def change_client_defaults(request: WebRequest, defaults: DefaultValues) -> Clie else: return ClientDefaultsServiceResponse(error_message=logo_ok) + DETAIL_INPUTS = { + "name": {"max_len": 100}, + "company": {"max_len": 100}, + "address": {"max_len": 100}, + "city": {"max_len": 100}, + "county": {"max_len": 100}, + "country": {"max_len": 100}, + } + + for detail, value_dict in DETAIL_INPUTS.items(): + input_post = request.POST.get(f"invoice_from_{detail}", "") + + if len(input_post) > value_dict["max_len"]: + return ClientDefaultsServiceResponse( + error_message=f"Details - From {detail} is too long, max length is {value_dict['max_len']}" + ) + + setattr(defaults, f"invoice_from_{detail}", input_post) defaults.save() return ClientDefaultsServiceResponse(True) diff --git a/backend/service/invoices/common/create/get_page.py b/backend/service/invoices/common/create/get_page.py index 056c8d2c7..a205ad92f 100644 --- a/backend/service/invoices/common/create/get_page.py +++ b/backend/service/invoices/common/create/get_page.py @@ -37,7 +37,7 @@ def global_get_invoice_context(request: WebRequest) -> CreateInvoiceContextServi defaults = get_account_defaults(request.actor, client=None) for item in ["name", "company", "address", "city", "county", "country"]: - context[f"{item}"] = request.GET.get(f"from_{item}", "") + context[f"from_{item}"] = request.GET.get(f"from_{item}", "") if issue_date := request.GET.get("issue_date"): try: @@ -72,4 +72,17 @@ def global_get_invoice_context(request: WebRequest) -> CreateInvoiceContextServi if account_number := request.GET.get("account_number"): context["account_number"] = account_number + details_from = ["name", "company", "address", "city", "county", "country"] + + print(context) + + for detail in details_from: + detail_value = request.GET.get(f"from_{detail}", "") + + if not detail_value: + detail_value = getattr(defaults, f"invoice_from_{detail}") + + context[f"from_{detail}"] = detail_value + + print(context) return CreateInvoiceContextServiceResponse(True, CreateInvoiceContextTuple(defaults, context)) diff --git a/frontend/templates/pages/clients/detail/client_defaults.html b/frontend/templates/pages/clients/detail/client_defaults.html index c8dcf7608..27a86f65d 100644 --- a/frontend/templates/pages/clients/detail/client_defaults.html +++ b/frontend/templates/pages/clients/detail/client_defaults.html @@ -7,111 +7,189 @@ enctype="multipart/form-data" hx-encoding="multipart/form-data"> {% csrf_token %} -
-