-
-
Notifications
You must be signed in to change notification settings - Fork 343
[IMP] sale_order_import: allow creating invoice/delivery partners on the fly #1341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 18.0
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -62,6 +62,9 @@ class SaleOrderImport(models.TransientModel): | |||||||||
| skip_error_lines = fields.Boolean( | ||||||||||
| help="Ignore and push all error lines to the chatter when importing if enabled." | ||||||||||
| ) | ||||||||||
| # Allow creating invoice/shipping partners on import | ||||||||||
| create_missing_invoice_partner = fields.Boolean(default=False) | ||||||||||
| create_missing_shipping_partner = fields.Boolean(default=False) | ||||||||||
|
|
||||||||||
| @api.onchange("order_file") | ||||||||||
| def order_file_change(self): | ||||||||||
|
|
@@ -196,6 +199,11 @@ def parse_pdf_order(self, order_file, detect_doc_type=False): | |||||||||
| # 'name': 'Camptocamp', | ||||||||||
| # 'email': 'luc@camptocamp.com', | ||||||||||
| # }, | ||||||||||
| # 'invoice_to': { # Same structure and fields as 'partner'; completely optional | ||||||||||
| # 'vat': 'FR25499247138', | ||||||||||
| # 'name': 'Camptocamp', | ||||||||||
| # 'email': 'luc@camptocamp.com', | ||||||||||
| # }, | ||||||||||
| # 'ship_to': { | ||||||||||
| # 'partner': partner_dict, | ||||||||||
| # 'address': { | ||||||||||
|
|
@@ -260,18 +268,34 @@ def _prepare_order(self, parsed_order, price_source): | |||||||||
| so_vals = soo.play_onchanges(so_vals, ["partner_id"]) | ||||||||||
| so_vals["order_line"] = [] | ||||||||||
| if parsed_order.get("ship_to"): | ||||||||||
| shipping_partner = bdio._match_shipping_partner( | ||||||||||
| parsed_order["ship_to"], partner, parsed_order["chatter_msg"] | ||||||||||
| ) | ||||||||||
| try: | ||||||||||
| shipping_partner = bdio._match_shipping_partner( | ||||||||||
| parsed_order["ship_to"], partner, parsed_order["chatter_msg"] | ||||||||||
| ) | ||||||||||
| except UserError: | ||||||||||
| if not self._can_create_missing_shipping_partner(): | ||||||||||
| raise | ||||||||||
| shipping_partner = self._create_missing_shipping_partner( | ||||||||||
| parsed_order["ship_to"], partner, parsed_order["chatter_msg"] | ||||||||||
| ) | ||||||||||
| so_vals["partner_shipping_id"] = shipping_partner.id | ||||||||||
|
|
||||||||||
| if parsed_order.get("delivery_detail"): | ||||||||||
| so_vals.update(parsed_order.get("delivery_detail")) | ||||||||||
|
|
||||||||||
| if parsed_order.get("invoice_to"): | ||||||||||
| invoicing_partner = bdio._match_partner( | ||||||||||
| parsed_order["invoice_to"], parsed_order["chatter_msg"], partner_type="" | ||||||||||
| ) | ||||||||||
| try: | ||||||||||
| invoicing_partner = bdio._match_partner( | ||||||||||
| parsed_order["invoice_to"], | ||||||||||
| parsed_order["chatter_msg"], | ||||||||||
| partner_type="", | ||||||||||
| ) | ||||||||||
| except UserError: | ||||||||||
| if not self._can_create_missing_invoice_partner(): | ||||||||||
| raise | ||||||||||
| invoicing_partner = self._create_missing_invoice_partner( | ||||||||||
| parsed_order["invoice_to"], partner, parsed_order["chatter_msg"] | ||||||||||
| ) | ||||||||||
| so_vals["partner_invoice_id"] = invoicing_partner.id | ||||||||||
| if parsed_order.get("date"): | ||||||||||
| so_vals["date_order"] = parsed_order["date"] | ||||||||||
|
|
@@ -399,9 +423,16 @@ def import_order_button(self): | |||||||||
| commercial_partner = partner.commercial_partner_id | ||||||||||
| partner_shipping_id = False | ||||||||||
| if parsed_order.get("ship_to"): | ||||||||||
| partner_shipping_id = bdio._match_shipping_partner( | ||||||||||
| parsed_order["ship_to"], partner, [] | ||||||||||
| ).id | ||||||||||
| try: | ||||||||||
| partner_shipping_id = bdio._match_shipping_partner( | ||||||||||
| parsed_order["ship_to"], partner, [] | ||||||||||
| ).id | ||||||||||
| except UserError: | ||||||||||
| if not self._can_create_missing_shipping_partner(): | ||||||||||
| raise | ||||||||||
| partner_shipping_id = self._create_missing_shipping_partner( | ||||||||||
| parsed_order["ship_to"], partner, [] | ||||||||||
| ).id | ||||||||||
| existing_quotations = self.env["sale.order"].search( | ||||||||||
| self._search_existing_order_domain( | ||||||||||
| parsed_order, commercial_partner, [("state", "in", ("draft", "sent"))] | ||||||||||
|
|
@@ -465,9 +496,16 @@ def _prepare_update_order_vals(self, parsed_order, order, partner): | |||||||||
| ) | ||||||||||
| vals = {"partner_id": partner.id} | ||||||||||
| if parsed_order.get("ship_to"): | ||||||||||
| shipping_partner = bdio._match_shipping_partner( | ||||||||||
| parsed_order["ship_to"], partner, parsed_order["chatter_msg"] | ||||||||||
| ) | ||||||||||
| try: | ||||||||||
| shipping_partner = bdio._match_shipping_partner( | ||||||||||
| parsed_order["ship_to"], partner, parsed_order["chatter_msg"] | ||||||||||
| ) | ||||||||||
| except UserError: | ||||||||||
| if not self._can_create_missing_shipping_partner(): | ||||||||||
| raise | ||||||||||
| shipping_partner = self._create_missing_shipping_partner( | ||||||||||
| parsed_order["ship_to"], partner, parsed_order["chatter_msg"] | ||||||||||
| ) | ||||||||||
| vals["partner_shipping_id"] = shipping_partner.id | ||||||||||
| if parsed_order.get("order_ref"): | ||||||||||
| vals["client_order_ref"] = parsed_order["order_ref"] | ||||||||||
|
|
@@ -712,3 +750,101 @@ def _post_error_lines_message(self, parsed_order, order): | |||||||||
| }, | ||||||||||
| subtype_id=self.env.ref("mail.mt_note").id, | ||||||||||
| ) | ||||||||||
|
|
||||||||||
| def _can_create_missing_invoice_partner(self) -> bool: | ||||||||||
| """Checks if the current importer allows invoice address creation | ||||||||||
|
|
||||||||||
| When called upon a record, checks field "create_missing_invoice_partner". | ||||||||||
| When called upon an empty recordset (eg: as a model method), checks context's | ||||||||||
| key "create_missing_invoice_partner". | ||||||||||
|
|
||||||||||
| Hook method, can be overridden by inheriting modules. | ||||||||||
| """ | ||||||||||
| if self: | ||||||||||
| return self.create_missing_invoice_partner | ||||||||||
| return bool(self.env.context.get("create_missing_invoice_partner")) | ||||||||||
|
Comment on lines
+763
to
+765
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no need for a specific flag:
Suggested change
|
||||||||||
|
|
||||||||||
| def _create_missing_invoice_partner(self, invoice_to_dict, partner, chatter_msg): | ||||||||||
| """Creates a new invoice partner for the current import""" | ||||||||||
| vals = self._create_missing_invoice_partner_values( | ||||||||||
| invoice_to_dict, partner, chatter_msg | ||||||||||
| ) | ||||||||||
| invoice_partner = self.env["res.partner"].create(vals) | ||||||||||
| chatter_msg.append( | ||||||||||
| self.env._("Created invoice partner '%s'", invoice_partner.display_name) | ||||||||||
| ) | ||||||||||
| return invoice_partner | ||||||||||
|
|
||||||||||
| def _create_missing_invoice_partner_values( | ||||||||||
| self, invoice_to_dict, partner, chatter_msg | ||||||||||
| ): | ||||||||||
| """Prepares a new invoice partner's values for the current import""" | ||||||||||
| vals = invoice_to_dict.copy() | ||||||||||
| vals["type"] = "invoice" | ||||||||||
| vals["parent_id"] = partner.id | ||||||||||
| if country_code := vals.pop("country_code", None): | ||||||||||
| country = self.env["res.country"].search( | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not using |
||||||||||
| [("code", "=", country_code)], limit=1 | ||||||||||
| ) | ||||||||||
| if country: | ||||||||||
| vals["country_id"] = country.id | ||||||||||
| if state_code := vals.pop("state_code", None) and vals.get("country_id"): | ||||||||||
| state = self.env["res.country.state"].search( | ||||||||||
| [ | ||||||||||
| ("code", "=", state_code), | ||||||||||
| ("country_id", "=", vals["country_id"]), | ||||||||||
| ], | ||||||||||
| limit=1, | ||||||||||
| ) | ||||||||||
| if state: | ||||||||||
| vals["state_id"] = state.id | ||||||||||
| return vals | ||||||||||
|
|
||||||||||
| def _can_create_missing_shipping_partner(self) -> bool: | ||||||||||
| """Checks if the current importer allows shipping address creation | ||||||||||
|
|
||||||||||
| When called upon a record, checks field "create_missing_shipping_partner". | ||||||||||
| When called upon an empty recordset (eg: as a model method), checks context's | ||||||||||
| key "create_missing_shipping_partner". | ||||||||||
|
|
||||||||||
| Hook method, can be overridden by inheriting modules. | ||||||||||
| """ | ||||||||||
| if self: | ||||||||||
| return self.create_missing_shipping_partner | ||||||||||
| return bool(self.env.context.get("create_missing_shipping_partner")) | ||||||||||
|
Comment on lines
+812
to
+814
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
|
||||||||||
| def _create_missing_shipping_partner(self, ship_to_dict, partner, chatter_msg): | ||||||||||
| """Creates a new shipping partner for the current import""" | ||||||||||
| vals = self._create_missing_shipping_partner_values( | ||||||||||
| ship_to_dict, partner, chatter_msg | ||||||||||
| ) | ||||||||||
| shipping_partner = self.env["res.partner"].create(vals) | ||||||||||
| chatter_msg.append( | ||||||||||
| self.env._("Created shipping partner '%s'", shipping_partner.display_name) | ||||||||||
| ) | ||||||||||
| return shipping_partner | ||||||||||
|
|
||||||||||
| def _create_missing_shipping_partner_values( | ||||||||||
| self, ship_to_dict, partner, chatter_msg | ||||||||||
| ): | ||||||||||
| """Prepares a new shipping partner's values for the current import""" | ||||||||||
| vals = ship_to_dict.copy() | ||||||||||
| vals["type"] = "delivery" | ||||||||||
| vals["parent_id"] = partner.id | ||||||||||
| if country_code := vals.pop("country_code", None): | ||||||||||
| country = self.env["res.country"].search( | ||||||||||
| [("code", "=", country_code)], limit=1 | ||||||||||
| ) | ||||||||||
| if country: | ||||||||||
| vals["country_id"] = country.id | ||||||||||
| if state_code := vals.pop("state_code", None) and vals.get("country_id"): | ||||||||||
| state = self.env["res.country.state"].search( | ||||||||||
| [ | ||||||||||
| ("code", "=", state_code), | ||||||||||
| ("country_id", "=", vals["country_id"]), | ||||||||||
| ], | ||||||||||
| limit=1, | ||||||||||
| ) | ||||||||||
| if state: | ||||||||||
| vals["state_id"] = state.id | ||||||||||
| return vals | ||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wiz must be initialized