Metadata-Version: 2.1
Name: odoo-addon-purchase_order_line_import_sheet_file
Version: 17.0.1.0.0.2
Requires-Python: >=3.10
Requires-Dist: odoo>=17.0a,<17.1dev
Summary: Import purchase order lines from a spreadsheet
Home-page: https://github.com/OCA/purchase-workflow
License: AGPL-3
Author: ForgeFlow, Odoo Community Association (OCA)
Author-email: support@odoo-community.org
Classifier: Programming Language :: Python
Classifier: Framework :: Odoo
Classifier: Framework :: Odoo :: 17.0
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
Description-Content-Type: text/x-rst

.. image:: https://odoo-community.org/readme-banner-image
   :target: https://odoo-community.org/get-involved?utm_source=readme
   :alt: Odoo Community Association

==========================
Purchase Order Line Import
==========================

.. 
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !! This file is generated by oca-gen-addon-readme !!
   !! changes will be overwritten.                   !!
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !! source digest: sha256:57e9e3b85970df49bc39c8ec20e5fdcd7af2ea3c1cf381fea887b7a76ba77dd8
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
    :target: https://odoo-community.org/page/development-status
    :alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
    :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
    :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github
    :target: https://github.com/OCA/purchase-workflow/tree/17.0/purchase_order_line_import_sheet_file
    :alt: OCA/purchase-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
    :target: https://translation.odoo-community.org/projects/purchase-workflow-17-0/purchase-workflow-17-0-purchase_order_line_import_sheet_file
    :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
    :target: https://runboat.odoo-community.org/builds?repo=OCA/purchase-workflow&target_branch=17.0
    :alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

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**

.. contents::
   :local:

Usage
=====

1. Open a request for quotation in the *RFQ* or *RFQ Sent* state.
2. Click **Import Lines**.
3. 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.
4. 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.

Development
===========

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:

.. code:: python

   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:

.. code:: python

       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)]

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/purchase-workflow/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 <https://github.com/OCA/purchase-workflow/issues/new?body=module:%20purchase_order_line_import_sheet_file%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* ForgeFlow

Contributors
------------

- `ForgeFlow <https://www.forgeflow.com>`__:

  - Andreu Orensanz <andreu.orensanz@forgeflow.com>

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
   :alt: Odoo Community Association
   :target: https://odoo-community.org

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 <https://github.com/OCA/purchase-workflow/tree/17.0/purchase_order_line_import_sheet_file>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
