Skip to content

Commit

Permalink
Merge pull request #277 from rafaelurben/dev
Browse files Browse the repository at this point in the history
v1.8.3
  • Loading branch information
rafaelurben authored Jul 12, 2024
2 parents aa7f291 + deb2433 commit bf5778d
Show file tree
Hide file tree
Showing 20 changed files with 445 additions and 154 deletions.
2 changes: 1 addition & 1 deletion _version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.8.2
1.8.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Generated by Django 5.0.4 on 2024-04-17 23:03

from django.db import migrations, models


def migrate_address_fields(apps, schema_editor):
PaymentReceiver = apps.get_model("kmuhelper", "PaymentReceiver")
for receiver in PaymentReceiver.objects.all():
receiver.invoice_street = receiver.invoice_address_1[:70]

_index = receiver.invoice_address_2.index(" ")
receiver.invoice_postcode = receiver.invoice_address_2[:_index]
receiver.invoice_city = receiver.invoice_address_2[_index + 1 : _index + 36]

receiver.save()


def migrate_address_fields_reverse(apps, schema_editor):
PaymentReceiver = apps.get_model("kmuhelper", "PaymentReceiver")
for receiver in PaymentReceiver.objects.all():
receiver.invoice_address_1 = (
f"{receiver.invoice_street} {receiver.invoice_street_nr}".strip()
)
receiver.invoice_address_2 = (
f"{receiver.invoice_postcode} {receiver.invoice_city}".strip()
)
receiver.save()


class Migration(migrations.Migration):
dependencies = [
("kmuhelper", "0114_adminlogentry_alter_order_payment_conditions"),
]

operations = [
migrations.AddField(
model_name="paymentreceiver",
name="invoice_city",
field=models.CharField(default="", max_length=35, verbose_name="Ort"),
preserve_default=False,
),
migrations.AddField(
model_name="paymentreceiver",
name="invoice_postcode",
field=models.CharField(
default="", max_length=16, verbose_name="Postleitzahl"
),
preserve_default=False,
),
migrations.AddField(
model_name="paymentreceiver",
name="invoice_street",
field=models.CharField(
default="",
help_text="Strasse oder Postfach",
max_length=70,
verbose_name="Strasse",
),
preserve_default=False,
),
migrations.AddField(
model_name="paymentreceiver",
name="invoice_street_nr",
field=models.CharField(
blank=True, default="", max_length=16, verbose_name="Hausnummer"
),
preserve_default=False,
),
migrations.RunPython(
code=migrate_address_fields,
reverse_code=migrate_address_fields_reverse,
elidable=True,
),
migrations.RemoveField(
model_name="paymentreceiver",
name="invoice_address_1",
),
migrations.RemoveField(
model_name="paymentreceiver",
name="invoice_address_2",
),
migrations.AlterField(
model_name="paymentreceiver",
name="invoice_country",
field=models.CharField(
choices=[("CH", "Schweiz"), ("LI", "Liechtenstein")],
default="CH",
max_length=2,
verbose_name="Land",
),
),
migrations.AlterField(
model_name="paymentreceiver",
name="invoice_name",
field=models.CharField(
help_text="Name / Firma", max_length=70, verbose_name="Kontoinhaber"
),
),
]
35 changes: 32 additions & 3 deletions kmuhelper/modules/integrations/woocommerce/api/products.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@
from kmuhelper.modules.integrations.woocommerce.api._utils import preparestring


def parse_product_name(wc_obj):
"""
This method is a workaround because the WooCommerce REST API sometimes includes the variation options
in the product name of the variation and sometimes doesn't:
The attributes are not included in the title if the product has 3+ attributes or 2+ attributes and one of the
attributes contains 2+ words.
See source code for details:
https://github.com/woocommerce/woocommerce/blob/43d9f10200e3d2132b472aa46b63398f79ce06ac/plugins/woocommerce/includes/data-stores/class-wc-product-variation-data-store-cpt.php#L294C1-L298C38
To potentially solve this problem in WooCommerce directly, see
https://wordpress.org/support/topic/help-with-variation-display-in-cart/#post-9158977
"""

name = preparestring(wc_obj["name"])
if wc_obj["type"] != "variation" or len(wc_obj["attributes"]) <= 1:
return name

attr_str = ", ".join([a["option"] for a in wc_obj["attributes"]])

if attr_str not in name:
return f"{name} - {attr_str}"
return name


class WCProductsAPI(WC_BaseObjectAPI):
LOG_PREFIX = "[deep_pink4][KMUHelper WooCommerce Products][/] -"

Expand All @@ -19,10 +45,13 @@ def update_object_from_data(
try:
db_obj.selling_price = float(wc_obj["regular_price"])
except ValueError:
self.log("[red]Failed to convert regular_price to float![/]")
self.log(
f"[red]Failed to convert regular_price ({wc_obj['regular_price']}) to float![/]"
)
db_obj.selling_price = 0

db_obj.article_number = wc_obj["sku"]
db_obj.name = preparestring(wc_obj["name"])
db_obj.name = parse_product_name(wc_obj)
db_obj.short_description = preparestring(wc_obj["short_description"])
db_obj.description = preparestring(wc_obj["description"])
db_obj.image_url = (
Expand Down Expand Up @@ -59,7 +88,7 @@ def create_object_from_data(self, wc_obj: dict):
db_obj = models.Product.objects.create(
woocommerceid=wc_obj["id"],
article_number=wc_obj["sku"],
name=preparestring(wc_obj["name"]),
name=parse_product_name(wc_obj),
short_description=preparestring(wc_obj["short_description"]),
description=preparestring(wc_obj["description"]),
selling_price=selling_price,
Expand Down
13 changes: 6 additions & 7 deletions kmuhelper/modules/integrations/woocommerce/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def wc_auth_end(request):
@login_required(login_url=reverse_lazy("kmuhelper:login"))
@require_all_kmuhelper_perms(["change_setting"])
def wc_auth_start(request):
shopurl = settings.get_db_setting("wc-url", "Bestätigt")
shopurl = settings.get_db_setting("wc-url", None)

if not shopurl or not shopurl.startswith("http"):
messages.error(
Expand All @@ -97,18 +97,17 @@ def wc_auth_start(request):
)
return redirect(reverse("kmuhelper:wc-settings"))

current_host = "https://" + request.get_host()

if current_host.endswith("localhost"):
messages.error(request, gettext("Cannot set up while on localhost!"))
if not request.is_secure():
# WooCommerce only accepts callback_urls via SSL
messages.error(request, gettext("Setting up WooCommerce is only possible when connected via HTTPS!"))
return redirect(reverse("kmuhelper:wc-settings"))

params = {
"app_name": "KMUHelper",
"scope": "read",
"user_id": randint(100000, 999999),
"return_url": current_host + reverse("kmuhelper:wc-auth-end"),
"callback_url": current_host + reverse("kmuhelper:wc-auth-key"),
"return_url": request.build_absolute_uri(reverse("kmuhelper:wc-auth-end")),
"callback_url": request.build_absolute_uri(reverse("kmuhelper:wc-auth-key")),
}
query_string = urlencode(params)

Expand Down
22 changes: 12 additions & 10 deletions kmuhelper/modules/main/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.utils import timezone
from django.utils.html import format_html
from django.utils.translation import gettext_lazy, ngettext

from kmuhelper import constants
from kmuhelper.modules.integrations.woocommerce.api import (
WCCustomersAPI,
Expand Down Expand Up @@ -43,9 +44,9 @@
@admin.register(ContactPerson)
class ContactPersonAdmin(CustomModelAdmin):
fieldsets = [
(None, {"fields": ["is_default"]}),
(_("Name"), {"fields": ["name"]}),
(_("Kontaktinformationen"), {"fields": ["phone", "email"]}),
(_("Optionen"), {"fields": ["is_default"]}),
]

ordering = ("name",)
Expand Down Expand Up @@ -1358,27 +1359,26 @@ def wc_update(self, request, queryset):
@admin.register(PaymentReceiver)
class PaymentReceiverAdmin(CustomModelAdmin):
fieldsets = [
(None, {"fields": ["internal_name"]}),
(None, {"fields": ["is_default", "internal_name"]}),
(
_("Anzeigeinformationen"),
{"fields": ["display_name", "display_address_1", "display_address_2"]},
),
(_("Zahlungsinformationen"), {"fields": ["mode", "qriban", "iban"]}),
(
_("Rechnungsadresse"),
_("Rechnungsadresse / Zahlbar an"),
{
"fields": [
"invoice_name",
"invoice_address_1",
"invoice_address_2",
("invoice_street", "invoice_street_nr"),
("invoice_postcode", "invoice_city"),
"invoice_country",
]
},
),
(_("Optionen"), {"fields": ["invoice_display_mode", "is_default"]}),
(
_("Weitere Informationen & Darstellung"),
{"fields": ["swiss_uid", "website", "logourl"]},
_("Weitere Darstellungsoptionen"),
{"fields": ["invoice_display_mode", "swiss_uid", "website", "logourl"]},
),
]

Expand All @@ -1401,8 +1401,10 @@ class PaymentReceiverAdmin(CustomModelAdmin):
"display_address_1",
"display_address_2",
"invoice_name",
"invoice_address_1",
"invoice_address_2",
"invoice_street",
"invoice_street_nr",
"invoice_postcode",
"invoice_city",
"invoice_country",
"swiss_uid",
"website",
Expand Down
43 changes: 29 additions & 14 deletions kmuhelper/modules/main/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from datetime import datetime, timedelta
from random import randint

import requests
from django.contrib import admin, messages
from django.core.validators import RegexValidator, MinValueValidator, MaxValueValidator
from django.db import models
Expand All @@ -14,9 +15,8 @@
gettext_lazy,
gettext,
npgettext,
pgettext_lazy,
)
from rich import print

from kmuhelper import settings, constants
from kmuhelper.modules.emails.models import EMail, Attachment
from kmuhelper.modules.integrations.woocommerce.mixins import WooCommerceModelMixin
Expand All @@ -25,6 +25,7 @@
from kmuhelper.overrides import CustomModel
from kmuhelper.translations import langselect, I18N_HELP_TEXT, Language
from kmuhelper.utils import runden, formatprice, modulo10rekursiv, faq
from rich import print

_ = gettext_lazy

Expand Down Expand Up @@ -1973,28 +1974,33 @@ class PaymentReceiver(CustomModel):
# Payment information

invoice_name = models.CharField(
verbose_name=_("Name"),
verbose_name=_("Kontoinhaber"),
max_length=70,
help_text=_("In QR-Rechnung 'Zahlbar an' - Kontoinhaber / Firma"),
help_text=_("Name / Firma"),
)
invoice_address_1 = models.CharField(
verbose_name=_("Adresszeile 1"),
invoice_street = models.CharField(
verbose_name=pgettext_lazy("address", "Strasse"),
max_length=70,
help_text=_(
"In QR-Rechnung 'Zahlbar an' - Strasse und Hausnummer oder 'Postfach'"
),
help_text=_("Strasse oder Postfach"),
)
invoice_address_2 = models.CharField(
verbose_name=_("Adresszeile 2"),
max_length=70,
help_text=_("In QR-Rechnung 'Zahlbar an' - PLZ und Ort"),
invoice_street_nr = models.CharField(
verbose_name=pgettext_lazy("address", "Hausnummer"),
max_length=16,
blank=True,
)
invoice_postcode = models.CharField(
verbose_name=pgettext_lazy("address", "Postleitzahl"),
max_length=16,
)
invoice_city = models.CharField(
verbose_name=pgettext_lazy("address", "Ort"),
max_length=35,
)
invoice_country = models.CharField(
verbose_name=_("Land"),
max_length=2,
choices=constants.COUNTRIES,
default="CH",
help_text=_("In QR-Rechnung 'Zahlbar an'"),
)

# Default
Expand Down Expand Up @@ -2097,6 +2103,15 @@ def clean(self):
errors["swiss_uid"] = ValidationError(
_("Die UID ist ungültig!"), code="invalid"
)
if self.logourl:
try:
response = requests.get(self.logourl)
response.raise_for_status()
except requests.RequestException as e:
errors["logourl"] = ValidationError(
_("An dieser Adresse konnte kein Bild abgerufen werden! Fehler: %s")
% str(e)
)

if errors:
raise ValidationError(errors)
Expand Down
Loading

0 comments on commit bf5778d

Please sign in to comment.