Skip to content

Commit

Permalink
purchase_sale_inter_company: improve code and add more test
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastienbeau committed Nov 28, 2022
1 parent 452bd33 commit f41bfd3
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 28 deletions.
57 changes: 34 additions & 23 deletions purchase_sale_inter_company/models/purchase_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
class PurchaseOrder(models.Model):
_inherit = "purchase.order"

intercompany_sale_id = fields.Many2one(
comodel_name="sale.order",
string="Destination Sale Order",
# Even if it's a One2many, it's in reality a One2one
# sql constraint on sale order to garanti the unicity
intercompany_sale_id = fields.One2many(
"sale.order",
"auto_purchase_order_id",
readonly=True,
copy=False,
)
Expand Down Expand Up @@ -88,28 +90,24 @@ def _inter_company_create_sale_order(self, dest_company):
"purchase price list currency."
)
)
# if a sale order has already been generated
# delete it and force the same number
force_number = False
if self.intercompany_sale_id and self.intercompany_sale_id.state in [
"draft",
"cancel",
]:
force_number = self.intercompany_sale_id.name
self.intercompany_sale_id.with_context(force_delete=True).unlink()

# Delete existing sale if needed
force_name = self._get_name_and_delete_existing_sale_name()

# create the SO and generate its lines from the PO lines
sale_order_data = self._prepare_sale_order_data(
self.name, company_partner, dest_company, self.dest_address_id
)
if force_number:
sale_order_data["name"] = force_number

if force_name:
sale_order_data["name"] = force_name

sale_order = (
self.env["sale.order"]
.with_user(intercompany_user.id)
.sudo()
.create(sale_order_data)
)
self.write({"intercompany_sale_id": sale_order.id})
for purchase_line in self.order_line:
sale_line_data = self._prepare_sale_order_line_data(
purchase_line, dest_company, sale_order
Expand All @@ -124,6 +122,18 @@ def _inter_company_create_sale_order(self, dest_company):
if dest_company.sale_auto_validation:
sale_order.with_user(intercompany_user.id).sudo().action_confirm()

def _get_name_and_delete_existing_sale_name(self):
"""If a previous sale order have been generated, we update it.
for this we delete the existing one and create a new one.
This method will delete and return the name of the existing sale order"""
self.ensure_one()
if self.intercompany_sale_id:
if self.intercompany_sale_id.state == "cancel":
name = self.intercompany_sale_id.name
self.intercompany_sale_id.with_context(force_delete=True).unlink()
return name
return None

def _prepare_sale_order_data(
self, name, partner, dest_company, direct_delivery_address
):
Expand Down Expand Up @@ -194,8 +204,9 @@ def _prepare_sale_order_line_data(self, purchase_line, dest_company, sale_order)
return new_line._convert_to_write(new_line._cache)

def button_cancel(self):
if self.intercompany_sale_id:
if self.intercompany_sale_id.state not in ["draft", "sent", "cancel"]:
sudo_self = self.sudo()
if sudo_self.intercompany_sale_id:
if sudo_self.intercompany_sale_id.state not in ["draft", "sent", "cancel"]:
raise UserError(
_(
"You can not cancel your purchase order %s.\n"
Expand All @@ -205,12 +216,12 @@ def button_cancel(self):
"ask your supplier to cancel his sale order."
)
% (
self.name,
self.intercompany_sale_id.name,
self.partner_id.name,
self.intercompany_sale_id.state,
sudo_self.name,
sudo_self.intercompany_sale_id.name,
sudo_self.partner_id.name,
sudo_self.intercompany_sale_id.state,
)
)
self.intercompany_sale_id.sudo().action_cancel()
self.write({"partner_ref": False})
sudo_self.intercompany_sale_id.action_cancel()
self.write({"partner_ref": False})
return super().button_cancel()
21 changes: 19 additions & 2 deletions purchase_sale_inter_company/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
# Copyright 2018-2019 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models
from odoo import _, fields, models
from odoo.exceptions import UserError


class SaleOrder(models.Model):
Expand All @@ -16,12 +17,28 @@ class SaleOrder(models.Model):
copy=False,
)

_sql_constraints = [
(
"auto_purchase_order_id_uniq",
"unique (auto_purchase_order_id)",
"The auto_purchase_order_id must be unique !",
)
]

def action_confirm(self):
for order in self.filtered("auto_purchase_order_id"):
for line in order.order_line.sudo():
if line.auto_purchase_line_id:
line.auto_purchase_line_id.price_unit = line.price_unit
return super(SaleOrder, self).action_confirm()
return super().action_confirm()

def unlink(self):
for record in self:
if not self._context.get("force_delete") and record.auto_purchase_order_id:
raise UserError(
_("You can not delete a intercompany sale, please cancel it")
)
return super().unlink()


class SaleOrderLine(models.Model):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ def _approve_po(self):
.search([("auto_purchase_order_id", "=", self.purchase_company_a.id)])
)

def _reset_to_draft_po(self):
self.purchase_company_a.with_user(self.user_company_a).button_cancel()
self.purchase_company_a.with_user(self.user_company_a).button_draft()

def test_purchase_sale_inter_company(self):
self.purchase_company_a.notes = "Test note"
sale = self._approve_po()
Expand Down Expand Up @@ -214,10 +218,21 @@ def test_update_po(self):
self.company_b.sale_auto_validation = False
old_sale = self._approve_po()
old_sale_name = old_sale.name
self.purchase_company_a.button_cancel()
self._reset_to_draft_po()
self.purchase_company_a.order_line.product_qty = 5.0
self.company_b.sale_auto_validation = True
new_sale = self._approve_po()
self.assertEqual(new_sale.order_line.product_uom_qty, 5.0)
self.assertEqual(new_sale.state, "sale")
self.assertEqual(new_sale.state, "draft")
self.assertEqual(new_sale.name, old_sale_name)

def test_update_po_with_validate_so(self):
sale = self._approve_po()
self.assertEqual(sale.state, "sale")
with self.assertRaises(UserError):
self._reset_to_draft_po()

def test_so_can_not_be_deleted(self):
self.company_b.sale_auto_validation = False
sale = self._approve_po()
with self.assertRaises(UserError):
sale.unlink()

0 comments on commit f41bfd3

Please sign in to comment.