Purchase Order Line Import

This module adds an Import Lines button to requests for quotation.
It opens a wizard that reads a spreadsheet (XLSX, XLS, ODS or CSV) and
adds one purchase order line per row to the current request for
quotation.
The spreadsheet supports these columns:
| Column |
Required |
Purchase order line field |
| Internal Reference |
Yes |
product_id, by the product
internal reference |
| Quantity |
Yes |
product_qty |
| Description |
No |
name |
| Unit Price |
No |
price_unit |
| Analytic Account |
No |
analytic_distribution, 100% to
the account |
An empty optional cell keeps the value Odoo computes for the line: the
default description of the product and the vendor price. The analytic
account is searched by code or by name.
All the rows are checked before any line is created: if any of them has
an error, nothing is imported and every error is reported with its row
number.
Table of contents
- Open a request for quotation in the RFQ or RFQ Sent state.
- Click Import Lines.
- Click Download Template to get an empty spreadsheet with the
supported columns. The required columns are highlighted, and each
header has a comment that describes it.
- Fill in one row per line, upload the file and click Import.
The first row of the file must hold the column names. A column is
recognized by its name in the language of the user, in English, or by
its technical key (default_code, product_qty, name,
price_unit, analytic_account), regardless of the case. The order
of the columns does not matter.
The imported lines are added after the existing ones, and a message on
the order records the file they come from.
The wizard purchase.order.line.import is built to be extended. Each
row of the file reaches the hooks as a dictionary that maps the column
keys to the cell values, already stripped, and only holds the columns
present in the file. A hook that raises a UserError reports its
message as the error of that row, and the import goes on checking the
next rows.
- _get_import_columns(): the columns the file accepts. Each one is a
dictionary with key, label, help and required.
- _prepare_order_line_vals(row): the values of the purchase order
line created for a row.
- _create_order_lines(vals_list): creates the lines of all the rows
once every row is valid, after the existing lines of the order.
- _get_product_domain(row) and _get_product(row): the search of
the product of a row.
- _get_product_qty(row): the quantity of a row.
- _get_analytic_account_domain(row) and
_get_analytic_distribution(row): the search of the analytic
account of a row, and the analytic distribution it gives.
- _parse_float(value, label): converts a cell to a number, with the
separators inferred by base_import.
A new column is added by extending _get_import_columns(), and its
value is used in _prepare_order_line_vals(). It is then part of the
downloaded template and recognized in the uploaded files, by its label
or by its key:
from odoo import _, models
class PurchaseOrderLineImport(models.TransientModel):
_inherit = "purchase.order.line.import"
def _get_import_columns(self):
columns = super()._get_import_columns()
columns.append(
{
"key": "discount",
"label": _("Discount"),
"help": _("Discount in %."),
"required": False,
}
)
return columns
def _prepare_order_line_vals(self, row):
vals = super()._prepare_order_line_vals(row)
if row.get("discount"):
vals["discount"] = self._parse_float(row["discount"], _("Discount"))
return vals
The search of an existing column is changed through its domain method,
for instance to accept only the products the vendor of the order sells:
def _get_product_domain(self, row):
domain = super()._get_product_domain(row)
partner = self.order_id.partner_id.commercial_partner_id
return domain + [("seller_ids.partner_id", "=", partner.id)]
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
feedback.
Do not contact contributors directly about support or help with technical issues.
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the OCA/purchase-workflow project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.