attempt fix to delivery carrier account - selecting collect account raising error
This commit is contained in:
parent
1da36c1e1c
commit
31892a892a
3 changed files with 71 additions and 107 deletions
|
|
@ -100,32 +100,24 @@ class CarrierAccountMixin(models.AbstractModel):
|
||||||
Returns:
|
Returns:
|
||||||
Tuple containing:
|
Tuple containing:
|
||||||
- partners: recordset of partners that can have valid accounts
|
- partners: recordset of partners that can have valid accounts
|
||||||
- is_third_party: boolean indicating if this is a third party billing mode
|
|
||||||
- invalid_partners: for third party mode, partners that cannot own the account
|
|
||||||
"""
|
"""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
invalid_partners = self.env["res.partner"].browse()
|
invalid_partners = self.env["res.partner"]
|
||||||
|
|
||||||
match self.delivery_billing_mode:
|
match self.delivery_billing_mode:
|
||||||
case "collect":
|
case "collect":
|
||||||
return (
|
return self.recipient_id | self.recipient_id.commercial_partner_id
|
||||||
self.recipient_id | self.recipient_id.commercial_partner_id,
|
|
||||||
False,
|
|
||||||
invalid_partners,
|
|
||||||
)
|
|
||||||
case "prepaid" | "ppc" | "no charge":
|
case "prepaid" | "ppc" | "no charge":
|
||||||
return (
|
return self.sender_id | self.sender_id.commercial_partner_id
|
||||||
self.sender_id | self.sender_id.commercial_partner_id,
|
|
||||||
False,
|
|
||||||
invalid_partners,
|
|
||||||
)
|
|
||||||
case "third party":
|
case "third party":
|
||||||
invalid_partners = (
|
invalid_partners = (
|
||||||
self.recipient_id | self.recipient_id.commercial_partner_id
|
self.recipient_id | self.recipient_id.commercial_partner_id
|
||||||
) | (self.sender_id | self.sender_id.commercial_partner_id)
|
) | (self.sender_id | self.sender_id.commercial_partner_id)
|
||||||
return self.env["res.partner"].browse(), True, invalid_partners
|
return self.env["res.partner"].search(
|
||||||
|
[("id", "not in", invalid_partners.ids)]
|
||||||
|
)
|
||||||
case _:
|
case _:
|
||||||
return self.env["res.partner"].browse(), False, invalid_partners
|
return self.env["res.partner"]
|
||||||
|
|
||||||
@api.depends(
|
@api.depends(
|
||||||
"sender_id",
|
"sender_id",
|
||||||
|
|
@ -134,40 +126,26 @@ class CarrierAccountMixin(models.AbstractModel):
|
||||||
)
|
)
|
||||||
def _compute_carrier_id(self):
|
def _compute_carrier_id(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
# Only set carrier if not already set
|
|
||||||
if not rec.carrier_id:
|
if not rec.carrier_id:
|
||||||
rec.carrier_id = rec._get_default_carrier()
|
rec.carrier_id = rec._get_default_carrier()
|
||||||
continue
|
elif (
|
||||||
|
rec.delivery_billing_mode
|
||||||
|
and rec.carrier_id not in rec.valid_carrier_ids
|
||||||
|
and not rec._has_valid_account_for_carrier()
|
||||||
|
):
|
||||||
|
rec.carrier_id = rec._get_default_carrier()
|
||||||
|
|
||||||
# Don't reset carrier if we're changing billing mode and there's a valid account
|
def _has_valid_account_for_carrier(self):
|
||||||
if rec.delivery_billing_mode:
|
"""Check if there's a valid account for the current carrier and billing mode."""
|
||||||
partners, is_third_party, invalid_partners = (
|
self.ensure_one()
|
||||||
rec._get_valid_carrier_partners()
|
if not self.carrier_id or not self.delivery_billing_mode:
|
||||||
)
|
return False
|
||||||
|
|
||||||
if is_third_party:
|
partners = self._get_valid_carrier_partners()
|
||||||
# For third party, check if there's any account for this carrier
|
valid_accounts = partners.mapped("carrier_account_ids").filtered(
|
||||||
# that doesn't belong to sender or recipient
|
lambda account: account.delivery_carrier_id == self.carrier_id
|
||||||
has_valid_account = bool(
|
)
|
||||||
self.env["delivery.carrier.account"].search_count(
|
return bool(valid_accounts)
|
||||||
[
|
|
||||||
("delivery_carrier_id", "=", rec.carrier_id.id),
|
|
||||||
("partner_id", "not in", invalid_partners.ids),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if has_valid_account:
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
# Check if there's a valid account for this carrier
|
|
||||||
if any(
|
|
||||||
account.delivery_carrier_id == rec.carrier_id
|
|
||||||
for account in partners.mapped("carrier_account_ids")
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
# If we get here, there's no valid account for this carrier
|
|
||||||
rec.carrier_id = rec._get_default_carrier()
|
|
||||||
|
|
||||||
def _get_default_carrier(self):
|
def _get_default_carrier(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
|
|
@ -253,69 +231,25 @@ class CarrierAccountMixin(models.AbstractModel):
|
||||||
)
|
)
|
||||||
def _compute_valid_carrier_account_ids(self):
|
def _compute_valid_carrier_account_ids(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
match rec.delivery_billing_mode:
|
partners = rec._get_valid_carrier_partners()
|
||||||
case "collect":
|
if rec.carrier_id and partners:
|
||||||
rec.valid_carrier_account_ids = (
|
rec.valid_carrier_account_ids = partners.mapped(
|
||||||
(rec.recipient_id | rec.recipient_id.commercial_partner_id)
|
"carrier_account_ids"
|
||||||
.mapped("carrier_account_ids")
|
).filtered(
|
||||||
.filtered(
|
lambda account: account.delivery_carrier_id == rec.carrier_id
|
||||||
lambda account: account.delivery_carrier_id
|
)
|
||||||
== rec.carrier_id
|
else:
|
||||||
)
|
rec.valid_carrier_account_ids = partners.mapped("carrier_account_ids")
|
||||||
)
|
|
||||||
case "third party":
|
|
||||||
rec.valid_carrier_account_ids = self.env[
|
|
||||||
"delivery.carrier.account"
|
|
||||||
].search(
|
|
||||||
[
|
|
||||||
("delivery_carrier_id", "=", rec.carrier_id.id),
|
|
||||||
(
|
|
||||||
"partner_id",
|
|
||||||
"not in",
|
|
||||||
[
|
|
||||||
rec.sender_id.id,
|
|
||||||
rec.sender_id.commercial_partner_id.id,
|
|
||||||
rec.recipient_id.id,
|
|
||||||
rec.recipient_id.commercial_partner_id.id,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
case "prepaid" | "ppc" | "no charge":
|
|
||||||
rec.valid_carrier_account_ids = (
|
|
||||||
(rec.sender_id | rec.sender_id.commercial_partner_id)
|
|
||||||
.mapped("carrier_account_ids")
|
|
||||||
.filtered(
|
|
||||||
lambda account: account.delivery_carrier_id
|
|
||||||
== rec.carrier_id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
case _:
|
|
||||||
rec.valid_carrier_account_ids = self.env[
|
|
||||||
"delivery.carrier.account"
|
|
||||||
].search([])
|
|
||||||
|
|
||||||
@api.depends("delivery_billing_mode", "sender_id", "recipient_id")
|
@api.depends("delivery_billing_mode", "sender_id", "recipient_id")
|
||||||
def _compute_valid_carrier_ids(self):
|
def _compute_valid_carrier_ids(self):
|
||||||
"""Compute all valid carriers for the current billing mode and partners."""
|
"""Compute all valid carriers for the current billing mode and partners."""
|
||||||
for rec in self:
|
for rec in self:
|
||||||
partners, is_third_party, invalid_partners = (
|
partners = rec._get_valid_carrier_partners()
|
||||||
rec._get_valid_carrier_partners()
|
rec.valid_carrier_ids = partners.mapped(
|
||||||
|
"carrier_account_ids.delivery_carrier_id"
|
||||||
)
|
)
|
||||||
|
|
||||||
if is_third_party:
|
|
||||||
# For third party, all carriers with accounts not belonging to sender/recipient are valid
|
|
||||||
accounts = self.env["delivery.carrier.account"].search(
|
|
||||||
[
|
|
||||||
("partner_id", "not in", invalid_partners.ids),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
rec.valid_carrier_ids = accounts.mapped("delivery_carrier_id")
|
|
||||||
else:
|
|
||||||
rec.valid_carrier_ids = partners.mapped(
|
|
||||||
"carrier_account_ids.delivery_carrier_id"
|
|
||||||
)
|
|
||||||
|
|
||||||
def _on_carrier_fields_changed(self):
|
def _on_carrier_fields_changed(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -325,8 +259,20 @@ class CarrierAccountMixin(models.AbstractModel):
|
||||||
if (
|
if (
|
||||||
rec.carrier_account_id
|
rec.carrier_account_id
|
||||||
and rec.delivery_billing_mode
|
and rec.delivery_billing_mode
|
||||||
|
and rec.valid_carrier_account_ids # Use the computed field directly
|
||||||
and rec.carrier_account_id not in rec.valid_carrier_account_ids
|
and rec.carrier_account_id not in rec.valid_carrier_account_ids
|
||||||
):
|
):
|
||||||
|
_logger.warning(
|
||||||
|
"Billing mode: %s, sender: %s (commercial: %s), recipient: %s (commercial: %s), account: %s, id: %s, valid: %s",
|
||||||
|
rec.delivery_billing_mode,
|
||||||
|
rec.sender_id.name,
|
||||||
|
rec.sender_id.commercial_partner_id.name,
|
||||||
|
rec.recipient_id.name,
|
||||||
|
rec.recipient_id.commercial_partner_id.name,
|
||||||
|
rec.carrier_account_id.partner_id.name,
|
||||||
|
rec.carrier_account_id.id,
|
||||||
|
rec.valid_carrier_account_ids.ids,
|
||||||
|
)
|
||||||
|
|
||||||
if rec.delivery_billing_mode == "collect":
|
if rec.delivery_billing_mode == "collect":
|
||||||
raise UserError(
|
raise UserError(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from .test_carrier_account_common import TestCarrierAccountCommon
|
from .test_carrier_account_common import TestCarrierAccountCommon
|
||||||
|
from odoo.tests import Form
|
||||||
|
|
||||||
|
|
||||||
class TestSalesOrder(TestCarrierAccountCommon):
|
class TestSalesOrder(TestCarrierAccountCommon):
|
||||||
|
|
@ -21,12 +22,13 @@ class TestSalesOrder(TestCarrierAccountCommon):
|
||||||
def test_prepaid_sale_order_line_gets_proper_name(self):
|
def test_prepaid_sale_order_line_gets_proper_name(self):
|
||||||
order = self.env["sale.order"].create({"partner_id": self.client_partner.id})
|
order = self.env["sale.order"].create({"partner_id": self.client_partner.id})
|
||||||
wiz = self._get_shipping_wizard(order)
|
wiz = self._get_shipping_wizard(order)
|
||||||
wiz.carrier_id = self.delivery_carrier_1
|
with Form(wiz) as form:
|
||||||
wiz.delivery_billing_mode = "prepaid"
|
form.carrier_id = self.delivery_carrier_2
|
||||||
|
form.delivery_billing_mode = "prepaid"
|
||||||
wiz.button_confirm()
|
wiz.button_confirm()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
order.order_line[0].name,
|
order.order_line[0].name,
|
||||||
f"{self.delivery_carrier_1.name} [PREPAID]",
|
f"{self.delivery_carrier_2.name} [PREPAID]",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_third_party_sale_order_line_gets_proper_name(self):
|
def test_third_party_sale_order_line_gets_proper_name(self):
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,25 @@ class ChooseDeliveryCarrier(models.TransientModel):
|
||||||
if self.delivery_billing_mode:
|
if self.delivery_billing_mode:
|
||||||
vals.update(delivery_billing_mode=self.delivery_billing_mode)
|
vals.update(delivery_billing_mode=self.delivery_billing_mode)
|
||||||
if self.carrier_account_id:
|
if self.carrier_account_id:
|
||||||
vals.update(carrier_account_id=self.carrier_account_id)
|
vals.update(carrier_account_id=self.carrier_account_id.id)
|
||||||
if self.carrier_id:
|
if self.carrier_id:
|
||||||
vals.update(carrier_id=self.carrier_id.id)
|
vals.update(carrier_id=self.carrier_id.id)
|
||||||
self.order_id.with_context(no_carrier_update=True).write(vals)
|
|
||||||
|
# Ensure we have a valid carrier account
|
||||||
|
if (
|
||||||
|
self.carrier_id
|
||||||
|
and self.delivery_billing_mode
|
||||||
|
and not self.carrier_account_id
|
||||||
|
):
|
||||||
|
# Force recompute of valid carrier accounts
|
||||||
|
self._compute_valid_carrier_account_ids()
|
||||||
|
default_account = self._get_default_carrier_account()
|
||||||
|
if default_account:
|
||||||
|
vals.update(carrier_account_id=default_account.id)
|
||||||
|
|
||||||
|
# Write values to the order before calling super
|
||||||
|
if vals:
|
||||||
|
self.order_id.with_context(no_carrier_update=True).write(vals)
|
||||||
|
|
||||||
res = super().button_confirm()
|
res = super().button_confirm()
|
||||||
return res
|
return res
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue