[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:
parent
a365609f21
commit
c8bbeac919
4 changed files with 51 additions and 6 deletions
|
|
@ -28,13 +28,15 @@ class CarrierAccountMixin(models.AbstractModel):
|
||||||
delivery_billing_mode = fields.Selection(
|
delivery_billing_mode = fields.Selection(
|
||||||
[
|
[
|
||||||
("no charge", "No Charge"),
|
("no charge", "No Charge"),
|
||||||
|
("ppc", "Prepaid & Charge"),
|
||||||
("prepaid", "Prepaid"),
|
("prepaid", "Prepaid"),
|
||||||
("collect", "Collect"),
|
("collect", "Collect"),
|
||||||
("third party", "Third Party"),
|
("third party", "Third Party"),
|
||||||
],
|
],
|
||||||
help=_(
|
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)
|
Collect: The recipient will be billed (account information needed)
|
||||||
Third Party: A third party 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.valid_carrier_account_ids = (
|
||||||
rec.sender_id.carrier_account_ids.filtered(
|
rec.sender_id.carrier_account_ids.filtered(
|
||||||
lambda account: account.delivery_carrier_id == rec.carrier_id
|
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 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:
|
for rec in self:
|
||||||
if rec.delivery_billing_mode == "collect":
|
if rec.delivery_billing_mode == "collect":
|
||||||
|
|
@ -135,7 +137,7 @@ class CarrierAccountMixin(models.AbstractModel):
|
||||||
if rec.delivery_billing_mode == "third party":
|
if rec.delivery_billing_mode == "third party":
|
||||||
if rec.carrier_account_id not in rec.valid_carrier_account_ids:
|
if rec.carrier_account_id not in rec.valid_carrier_account_ids:
|
||||||
rec.carrier_account_id = False
|
rec.carrier_account_id = False
|
||||||
if rec.delivery_billing_mode == "prepaid":
|
if rec.delivery_billing_mode in ["prepaid", "ppc"]:
|
||||||
rec.carrier_account_id = (
|
rec.carrier_account_id = (
|
||||||
self.env["delivery.carrier.account"]
|
self.env["delivery.carrier.account"]
|
||||||
.search([("partner_id", "=", rec.sender_id.id)])
|
.search([("partner_id", "=", rec.sender_id.id)])
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,12 @@ class SalesOrder(models.Model):
|
||||||
def _create_delivery_line(self, carrier, price_unit):
|
def _create_delivery_line(self, carrier, price_unit):
|
||||||
line = super()._create_delivery_line(carrier, price_unit)
|
line = super()._create_delivery_line(carrier, price_unit)
|
||||||
name = line.name
|
name = line.name
|
||||||
delivery_billing_mode = self.env.context.get("delivery_billing_mode", False)
|
delivery_billing_mode = self.delivery_billing_mode or self.env.context.get(
|
||||||
carrier_account = self.env.context.get("carrier_account", False)
|
"delivery_billing_mode", False
|
||||||
|
)
|
||||||
|
carrier_account = self.carrier_account_id or self.env.context.get(
|
||||||
|
"carrier_account", False
|
||||||
|
)
|
||||||
if delivery_billing_mode:
|
if delivery_billing_mode:
|
||||||
name = name + f" [{delivery_billing_mode.upper()}]"
|
name = name + f" [{delivery_billing_mode.upper()}]"
|
||||||
if delivery_billing_mode in ["collect", "third party"] and carrier_account:
|
if delivery_billing_mode in ["collect", "third party"] and carrier_account:
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,17 @@ class Picking(models.Model):
|
||||||
|
|
||||||
def _inverse_delivery_billing_mode(self):
|
def _inverse_delivery_billing_mode(self):
|
||||||
pass
|
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)
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,17 @@ class TestCarrierAccountMixin(TestCarrierAccountCommon):
|
||||||
)
|
)
|
||||||
self.assertEqual(picking.carrier_account_id, self.sender_account_2)
|
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):
|
def test_compute_account_third_party_order(self):
|
||||||
picking = self.env["stock.picking"].create(
|
picking = self.env["stock.picking"].create(
|
||||||
{
|
{
|
||||||
|
|
@ -76,6 +87,20 @@ class TestCarrierAccountMixin(TestCarrierAccountCommon):
|
||||||
self.third_party_account_1,
|
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):
|
def test_incorrect_third_party_account(self):
|
||||||
with self.assertRaises(UserError):
|
with self.assertRaises(UserError):
|
||||||
self._create_sale_order(
|
self._create_sale_order(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue