Implement billing address creation via odoo
This commit is contained in:
parent
81932c4da0
commit
e646bae158
3 changed files with 67 additions and 18 deletions
|
@ -1,7 +1,7 @@
|
|||
import rules
|
||||
import urlman
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.db import models, transaction
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
@ -9,6 +9,7 @@ from django_scopes import ScopedManager, scopes_disabled
|
|||
|
||||
from servala.core import rules as perms
|
||||
from servala.core.models.mixins import ServalaModelMixin
|
||||
from servala.core.odoo import CLIENT
|
||||
|
||||
|
||||
class Organization(ServalaModelMixin, models.Model):
|
||||
|
@ -125,9 +126,63 @@ class BillingEntity(ServalaModelMixin, models.Model):
|
|||
return self.name
|
||||
|
||||
@classmethod
|
||||
def create_from_data(cls, odoo_data):
|
||||
instance = BillingEntity.objects.create(name=odoo_data.get("name"))
|
||||
# TODO implement odoo creation from data
|
||||
@transaction.atomic
|
||||
def create_from_data(cls, name, odoo_data):
|
||||
"""
|
||||
Creates a BillingEntity and corresponding Odoo records.
|
||||
|
||||
This method creates a `res.partner` record in Odoo with `company_type='company'`
|
||||
for the main company, and another `res.partner` record with `company_type='person'`
|
||||
and `type='invoice'` (linked via `parent_id` to the first record) for the
|
||||
invoice address. The IDs of these Odoo records are stored in the BillingEntity.
|
||||
|
||||
Args:
|
||||
odoo_data (dict): A dictionary containing the data for creating
|
||||
the BillingEntity and Odoo records.
|
||||
|
||||
Expected keys in `odoo_data`:
|
||||
- `invoice_street` (str): Street for the invoice address.
|
||||
- `invoice_street2` (str): Second line of street address for the invoice address.
|
||||
- `invoice_city` (str): City for the invoice address.
|
||||
- `invoice_zip` (str): ZIP/Postal code for the invoice address.
|
||||
- `invoice_country` (int): Odoo `res.country` ID for the invoice address country.
|
||||
- `invoice_email` (str): Email address for the invoice contact.
|
||||
- `invoice_phone` (str): Phone number for the invoice contact.
|
||||
"""
|
||||
instance = cls.objects.create(name=name)
|
||||
company_payload = {
|
||||
"name": odoo_data.get("company_name", name),
|
||||
"company_type": "company",
|
||||
}
|
||||
if vat := odoo_data.get("invoice_vat"):
|
||||
company_payload["vat"] = vat
|
||||
company_id = CLIENT.execute("res.partner", "create", [company_payload])
|
||||
instance.odoo_company_id = company_id
|
||||
|
||||
invoice_address_payload = {
|
||||
"name": name,
|
||||
"company_type": "person",
|
||||
"type": "invoice",
|
||||
"parent_id": company_id,
|
||||
}
|
||||
invoice_optional_fields = {
|
||||
"street": odoo_data.get("invoice_street"),
|
||||
"street2": odoo_data.get("invoice_street2"),
|
||||
"city": odoo_data.get("invoice_city"),
|
||||
"zip": odoo_data.get("invoice_zip"),
|
||||
"country_id": odoo_data.get("invoice_country"),
|
||||
"email": odoo_data.get("invoice_email"),
|
||||
}
|
||||
invoice_address_payload.update(
|
||||
{k: v for k, v in invoice_optional_fields.items() if v is not None}
|
||||
)
|
||||
|
||||
invoice_address_id = CLIENT.execute(
|
||||
"res.partner", "create", [invoice_address_payload]
|
||||
)
|
||||
instance.odoo_invoice_id = invoice_address_id
|
||||
|
||||
instance.save(update_fields=["odoo_company_id", "odoo_invoice_id"])
|
||||
return instance
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -39,9 +39,7 @@ class OrganizationCreateForm(OrganizationForm):
|
|||
choices=get_odoo_countries(),
|
||||
)
|
||||
invoice_email = forms.EmailField(label=_("Billing Email"), required=False)
|
||||
invoice_phone = forms.CharField(
|
||||
label=_("Billing Phone"), required=False, max_length=30
|
||||
)
|
||||
invoice_phone = forms.CharField(label=_("Phone"), required=False, max_length=30)
|
||||
invoice_vat = forms.CharField(label=_("VAT ID"), required=False, max_length=50)
|
||||
|
||||
class Meta(OrganizationForm.Meta):
|
||||
|
@ -77,18 +75,13 @@ class OrganizationCreateForm(OrganizationForm):
|
|||
if not self.is_bound and "billing_processing_choice" not in self.initial:
|
||||
self.fields["billing_processing_choice"].initial = "existing"
|
||||
else:
|
||||
# No existing Odoo addresses. Force 'new' choice.
|
||||
self.fields["billing_processing_choice"].choices = [
|
||||
("new", _("Create a new billing address")),
|
||||
]
|
||||
self.fields["billing_processing_choice"].initial = "new"
|
||||
self.fields["billing_processing_choice"].widget = forms.HiddenInput()
|
||||
self.fields.pop("billing_processing_choice")
|
||||
self.fields["existing_odoo_address_id"].widget = forms.HiddenInput()
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
choice = cleaned_data.get("billing_processing_choice")
|
||||
if choice == "new":
|
||||
if not choice or choice == "new":
|
||||
required_fields = [
|
||||
"invoice_street",
|
||||
"invoice_city",
|
||||
|
|
|
@ -22,13 +22,14 @@ class OrganizationCreateView(AutoPermissionRequiredMixin, CreateView):
|
|||
billing_choice = form.cleaned_data.get("billing_processing_choice")
|
||||
billing_entity = None
|
||||
|
||||
if billing_choice == "new":
|
||||
if not billing_choice or billing_choice == "new":
|
||||
billing_entity = BillingEntity.create_from_data(
|
||||
form.cleaned_data["name"],
|
||||
{
|
||||
key[3:]: value
|
||||
key: value
|
||||
for key, value in form.cleaned_data.items()
|
||||
if key.startswith("ba_")
|
||||
}
|
||||
if key.startswith("invoice_")
|
||||
},
|
||||
)
|
||||
elif odoo_id := form.cleaned_data.get("existing_odoo_address_id"):
|
||||
billing_entity = BillingEntity.objects.filter(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue