[ENH] delivery_carrier_partner_account: Add ppc billing mode.

Adds a Prepaid & Charge billing mode to carrier.account.mixin and
overrides the stock.picking method that sets the shipping cost on sales
orders after shipping. This modifies the behaviour of "invoicing policy"
on delivery.carrier when a delivery billing mode is selected on the SO
or picking.
This commit is contained in:
Marc Durepos 2024-11-21 16:33:18 -05:00
parent a365609f21
commit c8bbeac919
4 changed files with 51 additions and 6 deletions

View file

@ -28,13 +28,15 @@ class CarrierAccountMixin(models.AbstractModel):
delivery_billing_mode = fields.Selection(
[
("no charge", "No Charge"),
("ppc", "Prepaid & Charge"),
("prepaid", "Prepaid"),
("collect", "Collect"),
("third party", "Third Party"),
],
help=_(
"""
Prepaid: The shipper will pay the carrier (and may bill the client).
Prepaid: The shipper will pay the carrier and the client pays the estimate.
Prepaid & Charge: The shipper will pay the carrier and bill the client based on the actual price paid.
Collect: The recipient will be billed (account information needed)
Third Party: A third party will be billed (account information needed)
"""
@ -93,7 +95,7 @@ class CarrierAccountMixin(models.AbstractModel):
),
]
)
if rec.delivery_billing_mode == "prepaid":
if rec.delivery_billing_mode in ["prepaid", "ppc"]:
rec.valid_carrier_account_ids = (
rec.sender_id.carrier_account_ids.filtered(
lambda account: account.delivery_carrier_id == rec.carrier_id
@ -114,7 +116,7 @@ class CarrierAccountMixin(models.AbstractModel):
When it is third party, any account matching the carrier_id is fine.
When it is prepaid, we select the company's account.
When it is prepaid or ppc, we select the company's account.
"""
for rec in self:
if rec.delivery_billing_mode == "collect":
@ -135,7 +137,7 @@ class CarrierAccountMixin(models.AbstractModel):
if rec.delivery_billing_mode == "third party":
if rec.carrier_account_id not in rec.valid_carrier_account_ids:
rec.carrier_account_id = False
if rec.delivery_billing_mode == "prepaid":
if rec.delivery_billing_mode in ["prepaid", "ppc"]:
rec.carrier_account_id = (
self.env["delivery.carrier.account"]
.search([("partner_id", "=", rec.sender_id.id)])

View file

@ -32,8 +32,12 @@ class SalesOrder(models.Model):
def _create_delivery_line(self, carrier, price_unit):
line = super()._create_delivery_line(carrier, price_unit)
name = line.name
delivery_billing_mode = self.env.context.get("delivery_billing_mode", False)
carrier_account = self.env.context.get("carrier_account", False)
delivery_billing_mode = self.delivery_billing_mode or self.env.context.get(
"delivery_billing_mode", False
)
carrier_account = self.carrier_account_id or self.env.context.get(
"carrier_account", False
)
if delivery_billing_mode:
name = name + f" [{delivery_billing_mode.upper()}]"
if delivery_billing_mode in ["collect", "third party"] and carrier_account:

View file

@ -29,3 +29,17 @@ class Picking(models.Model):
def _inverse_delivery_billing_mode(self):
pass
def _add_delivery_cost_to_so(self):
self.ensure_one()
if not self.delivery_billing_mode or self.delivery_billing_mode != "ppc":
super()._add_delivery_cost_to_so()
else:
sale_order = self.sale_id
delivery_lines = self._get_matching_delivery_lines()
if not delivery_lines:
delivery_lines = sale_order.with_context(
delivery_billing_mode="ppc", carrier_account=self.carrier_account_id
)._create_delivery_line(self.carrier_id, self.carrier_price)
vals = self._prepare_sale_delivery_line_vals()
delivery_lines[0].write(vals)

View file

@ -22,6 +22,17 @@ class TestCarrierAccountMixin(TestCarrierAccountCommon):
)
self.assertEqual(picking.carrier_account_id, self.sender_account_2)
def test_compute_account_ppc_order(self):
picking = self.env["stock.picking"].create(
{
"partner_id": self.client_partner.id,
"carrier_id": self.delivery_carrier_2.id,
"picking_type_id": self.env.ref("stock.warehouse0").out_type_id.id,
"delivery_billing_mode": "ppc",
}
)
self.assertEqual(picking.carrier_account_id, self.sender_account_2)
def test_compute_account_third_party_order(self):
picking = self.env["stock.picking"].create(
{
@ -76,6 +87,20 @@ class TestCarrierAccountMixin(TestCarrierAccountCommon):
self.third_party_account_1,
)
def test_incorrect_ppc_account(self):
with self.assertRaises(UserError):
self._create_sale_order(
"ppc",
self.delivery_carrier_1,
self.client_account_1,
)
with self.assertRaises(UserError):
self._create_sale_order(
"ppc",
self.delivery_carrier_1,
self.third_party_account_1,
)
def test_incorrect_third_party_account(self):
with self.assertRaises(UserError):
self._create_sale_order(