[tryton-debian-vcs] tryton-modules-purchase branch debian updated. debian/2.8.1-1-5-g0fae285

git repository hosting tryton-debian-vcs at m9s.biz
Mon Nov 25 19:36:47 UTC 2013


The following commit has been merged in the debian branch:
http://debian.tryton.org/gitweb/?p=packages/tryton-modules-purchase.git;a=commitdiff;h=debian/2.8.1-1-5-g0fae285

commit 0fae2857708937e9eb94ed5407bced0806b41a67
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Mon Nov 25 20:30:23 2013 +0100

    Releasing debian version 3.0.0-1.

diff --git a/debian/changelog b/debian/changelog
index 5a7a166..bb596fb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+tryton-modules-purchase (3.0.0-1) unstable; urgency=low
+
+  * Merging upstream version 3.0.0.
+  * Updating to standards version 3.9.5, no changes needed.
+  * Changing to buildsystem pybuild.
+  * Adding python-sql to Depends.
+
+ -- Mathias Behrle <mathiasb at m9s.biz>  Mon, 25 Nov 2013 17:54:57 +0100
+
 tryton-modules-purchase (2.8.1-1) unstable; urgency=low
 
   * Merging upstream version 2.8.1.
commit 87db2739a8b0870fc0fe99b9f703e133b5830e4d
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Mon Nov 25 17:45:48 2013 +0100

    Adding python-sql to Depends.

diff --git a/debian/control b/debian/control
index 110e59d..30cf8e9 100644
--- a/debian/control
+++ b/debian/control
@@ -22,7 +22,8 @@ Depends:
  tryton-modules-currency (>= ${version:major}),
  tryton-modules-party (>= ${version:major}),
  tryton-modules-product (>= ${version:major}),
- tryton-modules-stock (>= ${version:major}), python-pkg-resources
+ tryton-modules-stock (>= ${version:major}),
+ python-sql, python-pkg-resources
 Description: Tryton Application Platform (Purchase Module)
  Tryton is a high-level general purpose application platform written in Python
  and using PostgreSQL as database engine. It is the core base of a complete
commit cef1ac8308f3297d5242de7656cb8ba045767f86
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Sun Nov 24 19:51:52 2013 +0100

    Changing to buildsystem pybuild.

diff --git a/debian/control b/debian/control
index 0f33439..110e59d 100644
--- a/debian/control
+++ b/debian/control
@@ -3,7 +3,8 @@ Section: python
 Priority: optional
 Maintainer: Debian Tryton Maintainers <maintainers at debian.tryton.org>
 Uploaders: Mathias Behrle <mathiasb at m9s.biz>
-Build-Depends: debhelper (>= 9), python (>= 2.6.6-3~), python-setuptools
+Build-Depends:
+ debhelper (>= 9), python (>= 2.6.6-3~), python-setuptools, dh-python
 Standards-Version: 3.9.5
 Homepage: http://www.tryton.org/
 Vcs-Browser: http://debian.tryton.org/gitweb/?p=packages/tryton-modules-purchase.git
diff --git a/debian/rules b/debian/rules
index 30074ad..5b8c326 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,24 +1,17 @@
 #!/usr/bin/make -f
 
-MAJOR := $(shell python setup.py --version | awk -F "." '{print $$1 "." $$2}')
-PACKAGE_NAME := $(shell python setup.py --name)
-
-%:
-	dh ${@} --with python2
+# needed for pbuilder
+export LC_ALL=C.UTF-8
 
-override_dh_auto_clean:
-	dh_auto_clean
+MAJOR := $(shell python setup.py --version | awk -F "." '{print $$1 "." $$2}')
+PACKAGE_NAME := tryton-modules-$(shell python setup.py --name | sed s/^trytond_// | sed s/_/-/g)
+export PYBUILD_DESTDIR_python2=debian/${PACKAGE_NAME}
 
-override_dh_auto_build:
-	mv $(PACKAGE_NAME).egg-info $(PACKAGE_NAME).hen-info
-	mv PKG-INFO PKG-INFO.hen
-	dh_auto_build
+# Don't run tests for Tryton modules, they try to download dependencies from pypi
+export PYBUILD_DISABLE_python2.7=test
 
-override_dh_auto_install:
-	dh_auto_install
-	rm -rf *.egg-info
-	mv $(PACKAGE_NAME).hen-info $(PACKAGE_NAME).egg-info
-	mv PKG-INFO.hen PKG-INFO
+%:
+	dh ${@} --with python2 --buildsystem=pybuild
 
 override_dh_gencontrol:
 	dh_gencontrol -- -Vversion:major="$(MAJOR)"
commit 7ef5b399851798b24a6a4308719eadb27ba8b628
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Sun Nov 24 19:14:21 2013 +0100

    Updating to standards version 3.9.5, no changes needed.

diff --git a/debian/control b/debian/control
index 00c798c..0f33439 100644
--- a/debian/control
+++ b/debian/control
@@ -4,7 +4,7 @@ Priority: optional
 Maintainer: Debian Tryton Maintainers <maintainers at debian.tryton.org>
 Uploaders: Mathias Behrle <mathiasb at m9s.biz>
 Build-Depends: debhelper (>= 9), python (>= 2.6.6-3~), python-setuptools
-Standards-Version: 3.9.4
+Standards-Version: 3.9.5
 Homepage: http://www.tryton.org/
 Vcs-Browser: http://debian.tryton.org/gitweb/?p=packages/tryton-modules-purchase.git
 Vcs-Git: git://debian.tryton.org/packages/tryton-modules-purchase.git
commit 4c194cf90fecb08e526cc7e75a1685825dd42797
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Sun Nov 24 17:27:52 2013 +0100

    Merging upstream version 3.0.0.

diff --git a/CHANGELOG b/CHANGELOG
index 2672ce9..91a5c28 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
-Version 2.8.1 - 2013-10-01
+Version 3.0.0 - 2013-10-21
 * Bug fixes (see mercurial logs for details)
+* Replace reference copying by relate
 
 Version 2.8.0 - 2013-04-22
 * Bug fixes (see mercurial logs for details)
diff --git a/INSTALL b/INSTALL
index c52e5fb..dea2f76 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,6 +6,7 @@ Prerequisites
 
  * Python 2.6 or later (http://www.python.org/)
  * trytond (http://www.tryton.org/)
+ * python-sql (http://code.google.com/p/python-sql/)
  * trytond_company (http://www.tryton.org/)
  * trytond_party (http://www.tryton.org/)
  * trytond_stock (http://www.tryton.org/)
diff --git a/MANIFEST.in b/MANIFEST.in
index 2569955..fc0b03e 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -10,3 +10,4 @@ include view/*.xml
 include *.odt
 include locale/*.po
 include doc/*
+include tests/*.rst
diff --git a/PKG-INFO b/PKG-INFO
index f5fde0f..d117bd0 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: trytond_purchase
-Version: 2.8.1
+Version: 3.0.0
 Summary: Tryton module for purchase
 Home-page: http://www.tryton.org/
 Author: Tryton
 Author-email: UNKNOWN
 License: GPL-3
-Download-URL: http://downloads.tryton.org/2.8/
+Download-URL: http://downloads.tryton.org/3.0/
 Description: trytond_purchase
         ================
         
@@ -59,6 +59,7 @@ Classifier: Natural Language :: English
 Classifier: Natural Language :: French
 Classifier: Natural Language :: German
 Classifier: Natural Language :: Russian
+Classifier: Natural Language :: Slovenian
 Classifier: Natural Language :: Spanish
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python :: 2.6
diff --git a/__init__.py b/__init__.py
index f5f710c..810de6c 100644
--- a/__init__.py
+++ b/__init__.py
@@ -3,9 +3,10 @@
 
 from trytond.pool import Pool
 from .purchase import *
+from .product import *
+from .stock import *
 from .configuration import *
 from .invoice import *
-from .stock import *
 
 
 def register():
diff --git a/configuration.py b/configuration.py
index 4987a16..c7f038d 100644
--- a/configuration.py
+++ b/configuration.py
@@ -12,7 +12,7 @@ class Configuration(ModelSingleton, ModelSQL, ModelView):
     purchase_sequence = fields.Property(fields.Many2One('ir.sequence',
             'Purchase Reference Sequence', domain=[
                 ('company', 'in',
-                    [Eval('context', {}).get('company', 0), None]),
+                    [Eval('context', {}).get('company', -1), None]),
                 ('code', '=', 'purchase.purchase'),
                 ], required=True))
     purchase_invoice_method = fields.Property(fields.Selection([
@@ -20,5 +20,5 @@ class Configuration(ModelSingleton, ModelSQL, ModelView):
                 ('order', 'Based On Order'),
                 ('shipment', 'Based On Shipment'),
                 ], 'Invoice Method', states={
-                'required': Bool(Eval('context', {}).get('company', 0)),
+                'required': Bool(Eval('context', {}).get('company')),
                 }))
diff --git a/invoice.py b/invoice.py
index 9199d59..5650f2a 100644
--- a/invoice.py
+++ b/invoice.py
@@ -1,14 +1,29 @@
 #This file is part of Tryton.  The COPYRIGHT file at the top level of
 #this repository contains the full copyright notices and license terms.
+from functools import wraps
+from sql import Table
+
 from trytond.model import ModelView, Workflow, fields
 from trytond.pool import Pool, PoolMeta
 from trytond.transaction import Transaction
-from trytond.backend import TableHandler
+from trytond import backend
 
 __all__ = ['Invoice', 'InvoiceLine']
 __metaclass__ = PoolMeta
 
 
+def process_purchase(func):
+    @wraps(func)
+    def wrapper(cls, invoices):
+        pool = Pool()
+        Purchase = pool.get('purchase.purchase')
+        func(cls, invoices)
+        with Transaction().set_user(0, set_context=True):
+            Purchase.process([p for i in cls.browse(invoices)
+                    for p in i.purchases])
+    return wrapper
+
+
 class Invoice:
     __name__ = 'account.invoice'
     purchase_exception_state = fields.Function(fields.Selection([
@@ -52,11 +67,14 @@ class Invoice:
 
     @classmethod
     def delete(cls, invoices):
+        pool = Pool()
+        Purchase_Invoice = pool.get('purchase.purchase-account.invoice')
+        purchase_invoice = Purchase_Invoice.__table__()
         cursor = Transaction().cursor
         if invoices:
-            cursor.execute('SELECT id FROM purchase_invoices_rel '
-                'WHERE invoice IN (' + ','.join(('%s',) * len(invoices)) + ')',
-                [i.id for i in invoices])
+            cursor.execute(*purchase_invoice.select(purchase_invoice.id,
+                    where=purchase_invoice.invoice.in_(
+                        [i.id for i in invoices])))
             if cursor.fetchone():
                 cls.raise_user_error('delete_purchase_invoice')
         super(Invoice, cls).delete(invoices)
@@ -84,22 +102,19 @@ class Invoice:
         return super(Invoice, cls).draft(invoices)
 
     @classmethod
+    @process_purchase
+    def post(cls, invoices):
+        super(Invoice, cls).post(invoices)
+
+    @classmethod
+    @process_purchase
     def paid(cls, invoices):
-        pool = Pool()
-        Purchase = pool.get('purchase.purchase')
         super(Invoice, cls).paid(invoices)
-        with Transaction().set_user(0, set_context=True):
-            Purchase.process([p for i in cls.browse(invoices)
-                    for p in i.purchases])
 
     @classmethod
+    @process_purchase
     def cancel(cls, invoices):
-        pool = Pool()
-        Purchase = pool.get('purchase.purchase')
         super(Invoice, cls).cancel(invoices)
-        with Transaction().set_user(0, set_context=True):
-            Purchase.process([p for i in cls.browse(invoices)
-                    for p in i.purchases])
 
 
 class InvoiceLine:
@@ -107,22 +122,34 @@ class InvoiceLine:
 
     @classmethod
     def __register__(cls, module_name):
+        TableHandler = backend.get('TableHandler')
         cursor = Transaction().cursor
+        sql_table = cls.__table__()
 
         super(InvoiceLine, cls).__register__(module_name)
 
         # Migration from 2.6: remove purchase_lines
-        rel_table = 'purchase_line_invoice_lines_rel'
-        if TableHandler.table_exist(cursor, rel_table):
-            cursor.execute('SELECT purchase_line, invoice_line '
-                'FROM "' + rel_table + '"')
+        rel_table_name = 'purchase_line_invoice_lines_rel'
+        if TableHandler.table_exist(cursor, rel_table_name):
+            rel_table = Table(rel_table_name)
+            cursor.execute(*rel_table.select(
+                    rel_table.purchase_line, rel_table.invoice_line))
             for purchase_line, invoice_line in cursor.fetchall():
-                cursor.execute('UPDATE "' + cls._table + '" '
-                    'SET origin = %s '
-                    'WHERE id = %s',
-                    ('purchase.line,%s' % purchase_line, invoice_line))
+                cursor.execute(*sql_table.update(
+                        columns=[sql_table.origin],
+                        values=['purchase.line,%s' % purchase_line],
+                        where=sql_table.id == invoice_line))
             TableHandler.drop_table(cursor,
-                'purchase.line-account.invoice.line', rel_table)
+                'purchase.line-account.invoice.line', rel_table_name)
+
+    @property
+    def origin_name(self):
+        pool = Pool()
+        PurchaseLine = pool.get('purchase.line')
+        name = super(InvoiceLine, self).origin_name
+        if isinstance(self.origin, PurchaseLine):
+            name = self.origin.purchase.rec_name
+        return name
 
     @classmethod
     def _get_origin(cls):
diff --git a/locale/bg_BG.po b/locale/bg_BG.po
index 81b3e2a..6d5eff1 100644
--- a/locale/bg_BG.po
+++ b/locale/bg_BG.po
@@ -755,6 +755,11 @@ msgid "Purchases"
 msgstr "Покупки"
 
 #, fuzzy
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr "Покупки"
+
+#, fuzzy
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr "Връщане"
diff --git a/locale/ca_ES.po b/locale/ca_ES.po
index 4630c52..a0868ad 100644
--- a/locale/ca_ES.po
+++ b/locale/ca_ES.po
@@ -352,7 +352,7 @@ msgstr "Codi"
 
 msgctxt "field:purchase.product_supplier,company:"
 msgid "Company"
-msgstr "Companyia"
+msgstr "Empresa"
 
 msgctxt "field:purchase.product_supplier,create_date:"
 msgid "Create Date"
@@ -755,6 +755,10 @@ msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
 msgstr "Compres"
 
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr "Compres"
+
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr "Retorna"
@@ -956,7 +960,7 @@ msgstr "IVA:"
 
 msgctxt "selection:account.invoice,purchase_exception_state:"
 msgid ""
-msgstr " "
+msgstr ""
 
 msgctxt "selection:account.invoice,purchase_exception_state:"
 msgid "Ignored"
@@ -1060,7 +1064,7 @@ msgstr "Pressupost"
 
 msgctxt "selection:stock.move,purchase_exception_state:"
 msgid ""
-msgstr " "
+msgstr ""
 
 msgctxt "selection:stock.move,purchase_exception_state:"
 msgid "Ignored"
diff --git a/locale/cs_CZ.po b/locale/cs_CZ.po
index 0bfa52d..20c0770 100644
--- a/locale/cs_CZ.po
+++ b/locale/cs_CZ.po
@@ -747,6 +747,10 @@ msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
 msgstr ""
 
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr ""
+
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr ""
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 7d7b74c..ce5d0a1 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -767,6 +767,10 @@ msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
 msgstr "Einkäufe"
 
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr "Einkäufe"
+
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr "Rückgaben"
diff --git a/locale/es_AR.po b/locale/es_AR.po
index 00c6b16..e96b3a4 100644
--- a/locale/es_AR.po
+++ b/locale/es_AR.po
@@ -367,7 +367,7 @@ msgstr "Usuario creación"
 
 msgctxt "field:purchase.product_supplier,currency:"
 msgid "Currency"
-msgstr "Divisa"
+msgstr "Moneda"
 
 msgctxt "field:purchase.product_supplier,delivery_time:"
 msgid "Delivery Time"
@@ -463,11 +463,11 @@ msgstr "Usuario creación"
 
 msgctxt "field:purchase.purchase,currency:"
 msgid "Currency"
-msgstr "Divisa"
+msgstr "Moneda"
 
 msgctxt "field:purchase.purchase,currency_digits:"
 msgid "Currency Digits"
-msgstr "Dígitos de divisa"
+msgstr "Dígitos de moneda"
 
 msgctxt "field:purchase.purchase,description:"
 msgid "Description"
@@ -535,7 +535,7 @@ msgstr "Referencia"
 
 msgctxt "field:purchase.purchase,shipment_returns:"
 msgid "Shipment Returns"
-msgstr "Envío de devolución"
+msgstr "Remitos de devolución"
 
 msgctxt "field:purchase.purchase,shipment_state:"
 msgid "Shipment State"
@@ -543,7 +543,7 @@ msgstr "Estado de envío"
 
 msgctxt "field:purchase.purchase,shipments:"
 msgid "Shipments"
-msgstr "Envíos"
+msgstr "Remitos"
 
 msgctxt "field:purchase.purchase,state:"
 msgid "State"
@@ -691,7 +691,7 @@ msgstr "Compra"
 
 msgctxt "field:stock.move,purchase_currency:"
 msgid "Purchase Currency"
-msgstr "Divisa de compra"
+msgstr "Moneda de compra"
 
 msgctxt "field:stock.move,purchase_exception_state:"
 msgid "Exception State"
@@ -760,13 +760,17 @@ msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
 msgstr "Compras"
 
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr "Compras"
+
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr "Devolución"
 
 msgctxt "model:ir.action,name:act_shipment_form"
 msgid "Shipments"
-msgstr "Envíos"
+msgstr "Remitos"
 
 msgctxt "model:ir.action,name:report_purchase"
 msgid "Purchase"
@@ -778,7 +782,7 @@ msgstr "Gestionar excepción de factura"
 
 msgctxt "model:ir.action,name:wizard_shipment_handle_exception"
 msgid "Handle Shipment Exception"
-msgstr "Gestionar excepción de envío"
+msgstr "Gestionar excepción de remito"
 
 msgctxt "model:ir.action.act_window.domain,name:act_purchase_form_domain_all"
 msgid "All"
@@ -841,7 +845,7 @@ msgstr "Gestionar excepción de factura"
 
 msgctxt "model:purchase.handle.shipment.exception.ask,name:"
 msgid "Handle Shipment Exception"
-msgstr "Gestionar excepción de envío"
+msgstr "Gestionar excepción de remito"
 
 msgctxt "model:purchase.line,name:"
 msgid "Purchase Line"
@@ -977,7 +981,7 @@ msgstr "Basado en la orden"
 
 msgctxt "selection:purchase.configuration,purchase_invoice_method:"
 msgid "Based On Shipment"
-msgstr "Basado en el envío"
+msgstr "Basado en el Remito"
 
 msgctxt "selection:purchase.configuration,purchase_invoice_method:"
 msgid "Manual"
@@ -1005,7 +1009,7 @@ msgstr "Basado en la orden"
 
 msgctxt "selection:purchase.purchase,invoice_method:"
 msgid "Based On Shipment"
-msgstr "Basado en el envío"
+msgstr "Basado en el Remito"
 
 msgctxt "selection:purchase.purchase,invoice_method:"
 msgid "Manual"
@@ -1101,7 +1105,7 @@ msgstr "Seleccione movimientos a recrear"
 
 msgctxt "view:purchase.handle.shipment.exception.ask:"
 msgid "Handle shipment Exception"
-msgstr "Gestionar excepción de envío"
+msgstr "Gestionar excepción de remito"
 
 msgctxt "view:purchase.line:"
 msgid "General"
@@ -1157,7 +1161,7 @@ msgstr "Gestionar excepción de factura"
 
 msgctxt "view:purchase.purchase:"
 msgid "Handle Shipment Exception"
-msgstr "Gestionar excepción de envío"
+msgstr "Gestionar excepción de remito"
 
 msgctxt "view:purchase.purchase:"
 msgid "Invoices"
@@ -1181,7 +1185,7 @@ msgstr "Presupuestar"
 
 msgctxt "view:purchase.purchase:"
 msgid "Shipments"
-msgstr "Envíos"
+msgstr "Remitos"
 
 msgctxt "view:stock.move:"
 msgid "Moves"
diff --git a/locale/es_CO.po b/locale/es_CO.po
index f848145..dd98df9 100644
--- a/locale/es_CO.po
+++ b/locale/es_CO.po
@@ -47,7 +47,7 @@ msgstr ""
 
 msgctxt "error:purchase.purchase:"
 msgid "Missing \"Account Payable\" on party \"%s\"."
-msgstr "Falta \"Cuenta por Pagar\" en el tercero \"%s\"."
+msgstr "Falta la \"Cuenta por Pagar\" en el tercero \"%s\"."
 
 msgctxt "error:purchase.purchase:"
 msgid "Purchase \"%s\" must be cancelled before deletion."
@@ -144,7 +144,7 @@ msgstr "Recrear Movimientos"
 
 msgctxt "field:purchase.line,amount:"
 msgid "Amount"
-msgstr "Cantidad"
+msgstr "Subtotal"
 
 msgctxt "field:purchase.line,create_date:"
 msgid "Create Date"
@@ -244,7 +244,7 @@ msgstr "Dígitos de Unidad"
 
 msgctxt "field:purchase.line,unit_price:"
 msgid "Unit Price"
-msgstr "Precio unitario"
+msgstr "Precio Unitario"
 
 msgctxt "field:purchase.line,write_date:"
 msgid "Write Date"
@@ -372,7 +372,7 @@ msgstr "Moneda"
 
 msgctxt "field:purchase.product_supplier,delivery_time:"
 msgid "Delivery Time"
-msgstr "Tiempo de Envío"
+msgstr "Tiempo de Entrega"
 
 msgctxt "field:purchase.product_supplier,id:"
 msgid "ID"
@@ -500,7 +500,7 @@ msgstr "Facturas Ignoradas"
 
 msgctxt "field:purchase.purchase,invoices_recreated:"
 msgid "Recreated Invoices"
-msgstr "Facturas recreadas"
+msgstr "Facturas Recreadas"
 
 msgctxt "field:purchase.purchase,lines:"
 msgid "Lines"
@@ -560,7 +560,7 @@ msgstr "Impuesto"
 
 msgctxt "field:purchase.purchase,tax_amount_cache:"
 msgid "Tax Cache"
-msgstr "Impuestos Precalculado"
+msgstr "Caché de Impuestos"
 
 msgctxt "field:purchase.purchase,total_amount:"
 msgid "Total"
@@ -739,7 +739,7 @@ msgstr "En número de días."
 
 msgctxt "help:purchase.product_supplier.price,quantity:"
 msgid "Minimal quantity"
-msgstr "Cantidad mínima."
+msgstr "Cantidad mínima"
 
 msgctxt "model:ir.action,name:act_invoice_form"
 msgid "Invoices"
@@ -761,6 +761,10 @@ msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
 msgstr "Compras"
 
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr "Compras"
+
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr "Devolución"
@@ -775,11 +779,11 @@ msgstr "Compra"
 
 msgctxt "model:ir.action,name:wizard_invoice_handle_exception"
 msgid "Handle Invoice Exception"
-msgstr "Gestionar Excepción de Factura"
+msgstr "Excepció Manual de Factura"
 
 msgctxt "model:ir.action,name:wizard_shipment_handle_exception"
 msgid "Handle Shipment Exception"
-msgstr "Gestionar Excepción de Envío"
+msgstr "Excepción Manual de Envío"
 
 msgctxt "model:ir.action.act_window.domain,name:act_purchase_form_domain_all"
 msgid "All"
@@ -814,7 +818,7 @@ msgstr "Configuración"
 
 msgctxt "model:ir.ui.menu,name:menu_purchase"
 msgid "Purchase"
-msgstr "Compras"
+msgstr "Gestión de Compras"
 
 msgctxt "model:ir.ui.menu,name:menu_purchase_configuration"
 msgid "Purchase Configuration"
@@ -838,7 +842,7 @@ msgstr "Configuración de Compras"
 
 msgctxt "model:purchase.handle.invoice.exception.ask,name:"
 msgid "Handle Invoice Exception"
-msgstr "Gestionar Excepción de Factura"
+msgstr "Excepción Manual de Factura"
 
 msgctxt "model:purchase.handle.shipment.exception.ask,name:"
 msgid "Handle Shipment Exception"
@@ -894,7 +898,7 @@ msgstr "Administrador de Compras"
 
 msgctxt "odt:purchase.purchase:"
 msgid "Amount"
-msgstr "Cantidad"
+msgstr "Subtotal"
 
 msgctxt "odt:purchase.purchase:"
 msgid "Date:"
@@ -960,10 +964,9 @@ msgctxt "odt:purchase.purchase:"
 msgid "VAT:"
 msgstr "NIT:"
 
-#, fuzzy
 msgctxt "selection:account.invoice,purchase_exception_state:"
 msgid ""
-msgstr "Punto de Orden"
+msgstr ""
 
 msgctxt "selection:account.invoice,purchase_exception_state:"
 msgid "Ignored"
@@ -1039,7 +1042,7 @@ msgstr "Ninguno"
 
 msgctxt "selection:purchase.purchase,shipment_state:"
 msgid "Received"
-msgstr "Recibida"
+msgstr "Recibido"
 
 msgctxt "selection:purchase.purchase,shipment_state:"
 msgid "Waiting"
@@ -1055,7 +1058,7 @@ msgstr "Confirmada"
 
 msgctxt "selection:purchase.purchase,state:"
 msgid "Done"
-msgstr "Realizada"
+msgstr "Hecha"
 
 msgctxt "selection:purchase.purchase,state:"
 msgid "Draft"
@@ -1065,10 +1068,9 @@ msgctxt "selection:purchase.purchase,state:"
 msgid "Quotation"
 msgstr "Cotización"
 
-#, fuzzy
 msgctxt "selection:stock.move,purchase_exception_state:"
 msgid ""
-msgstr "Punto de Orden"
+msgstr ""
 
 msgctxt "selection:stock.move,purchase_exception_state:"
 msgid "Ignored"
@@ -1096,7 +1098,7 @@ msgstr "Seleccione facturas a recrear"
 
 msgctxt "view:purchase.handle.invoice.exception.ask:"
 msgid "Handle Invoice Exception"
-msgstr "Gestionar Excepción de Factura"
+msgstr "Excepción Manual de Factura"
 
 msgctxt "view:purchase.handle.shipment.exception.ask:"
 msgid "Choose move to recreate"
@@ -1104,7 +1106,7 @@ msgstr "Seleccione movimientos a recrear"
 
 msgctxt "view:purchase.handle.shipment.exception.ask:"
 msgid "Handle shipment Exception"
-msgstr "Gestionar Excepción de Envío"
+msgstr "Excepción Manual de Envío"
 
 msgctxt "view:purchase.line:"
 msgid "General"
@@ -1156,11 +1158,11 @@ msgstr "Borrador"
 
 msgctxt "view:purchase.purchase:"
 msgid "Handle Invoice Exception"
-msgstr "Gestionar Excepción de Factura"
+msgstr "Excepción Manual de Factura"
 
 msgctxt "view:purchase.purchase:"
 msgid "Handle Shipment Exception"
-msgstr "Gestionar Excepción de Envío"
+msgstr "Excepción Manual de Envío"
 
 msgctxt "view:purchase.purchase:"
 msgid "Invoices"
diff --git a/locale/es_ES.po b/locale/es_ES.po
index 7b4bc5d..0f42e29 100644
--- a/locale/es_ES.po
+++ b/locale/es_ES.po
@@ -51,7 +51,7 @@ msgstr "Falta la \"Cuenta a pagar\" en el tercer \"%s\"."
 
 msgctxt "error:purchase.purchase:"
 msgid "Purchase \"%s\" must be cancelled before deletion."
-msgstr "Debe cancelar la compra \"%s\" antes de borrar."
+msgstr "Debe cancelar la compra \"%s\" antes de borrarla."
 
 msgctxt "error:stock.shipment.in.return:"
 msgid "You cannot reset to draft a move generated by a purchase."
@@ -371,7 +371,7 @@ msgstr "Moneda"
 
 msgctxt "field:purchase.product_supplier,delivery_time:"
 msgid "Delivery Time"
-msgstr "Tiempo de envío"
+msgstr "Plazo de entrega"
 
 msgctxt "field:purchase.product_supplier,id:"
 msgid "ID"
@@ -555,11 +555,11 @@ msgstr "Referencia de proveedor"
 
 msgctxt "field:purchase.purchase,tax_amount:"
 msgid "Tax"
-msgstr "Impuesto"
+msgstr "Impuestos"
 
 msgctxt "field:purchase.purchase,tax_amount_cache:"
 msgid "Tax Cache"
-msgstr "Impuestos precalculado"
+msgstr "Impuestos precalculados"
 
 msgctxt "field:purchase.purchase,total_amount:"
 msgid "Total"
@@ -760,6 +760,10 @@ msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
 msgstr "Compras"
 
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr "Compras"
+
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr "Devolver"
diff --git a/locale/fr_FR.po b/locale/fr_FR.po
index c1791eb..4929bc8 100644
--- a/locale/fr_FR.po
+++ b/locale/fr_FR.po
@@ -10,17 +10,6 @@ msgctxt "error:account.invoice:"
 msgid "You cannot reset to draft an invoice generated by a purchase."
 msgstr "Vous ne pouvez pas réinitialiser une facture générée par un achat."
 
-msgctxt "error:account.invoice:"
-msgid "You cannot reset to draft an invoice generated by a purchase."
-msgstr "Vous ne pouvez pas réinitialiser une facture générée par un achat."
-
-msgctxt "error:product.template:"
-msgid ""
-"Purchase prices are based on the purchase uom, are you sure to change it?"
-msgstr ""
-"Les prix d'achat sont basé sur l'UDM d'achat, êtes-vous sûr de vouloir la "
-"modifier ?"
-
 msgctxt "error:product.template:"
 msgid ""
 "Purchase prices are based on the purchase uom, are you sure to change it?"
@@ -149,7 +138,7 @@ msgstr "ID"
 
 msgctxt "field:purchase.handle.shipment.exception.ask,recreate_moves:"
 msgid "Recreate Moves"
-msgstr "Recréer les mouvements"
+msgstr "Recréer des mouvements"
 
 msgctxt "field:purchase.line,amount:"
 msgid "Amount"
@@ -770,6 +759,10 @@ msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
 msgstr "Achats"
 
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr "Achats"
+
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr "Retours"
@@ -906,30 +899,14 @@ msgid "Amount"
 msgstr "Montant"
 
 msgctxt "odt:purchase.purchase:"
-msgid "Amount"
-msgstr "Montant"
-
-msgctxt "odt:purchase.purchase:"
 msgid "Date:"
-msgstr "Date:"
-
-msgctxt "odt:purchase.purchase:"
-msgid "Date:"
-msgstr "Date:"
+msgstr "Date :"
 
 msgctxt "odt:purchase.purchase:"
 msgid "Description"
 msgstr "Description"
 
 msgctxt "odt:purchase.purchase:"
-msgid "Description"
-msgstr "Description"
-
-msgctxt "odt:purchase.purchase:"
-msgid "Description:"
-msgstr "Description:"
-
-msgctxt "odt:purchase.purchase:"
 msgid "Description:"
 msgstr "Description:"
 
@@ -938,14 +915,6 @@ msgid "Draft Purchase Order"
 msgstr "Commande d'achat"
 
 msgctxt "odt:purchase.purchase:"
-msgid "Draft Purchase Order"
-msgstr "Commande d'achat"
-
-msgctxt "odt:purchase.purchase:"
-msgid "E-Mail:"
-msgstr "E-Mail:"
-
-msgctxt "odt:purchase.purchase:"
 msgid "E-Mail:"
 msgstr "E-Mail:"
 
@@ -954,22 +923,10 @@ msgid "Phone:"
 msgstr "Téléphone"
 
 msgctxt "odt:purchase.purchase:"
-msgid "Phone:"
-msgstr "Téléphone"
-
-msgctxt "odt:purchase.purchase:"
 msgid "Purchase Order N°:"
 msgstr "Commande d'achat n° :"
 
 msgctxt "odt:purchase.purchase:"
-msgid "Purchase Order N°:"
-msgstr "Commande d'achat n° :"
-
-msgctxt "odt:purchase.purchase:"
-msgid "Quantity"
-msgstr "Quantité"
-
-msgctxt "odt:purchase.purchase:"
 msgid "Quantity"
 msgstr "Quantité"
 
@@ -978,14 +935,6 @@ msgid "Request for Quotation N°:"
 msgstr "Demande pour le devis n°"
 
 msgctxt "odt:purchase.purchase:"
-msgid "Request for Quotation N°:"
-msgstr "Demande pour le devis n°"
-
-msgctxt "odt:purchase.purchase:"
-msgid "Taxes"
-msgstr "Taxes"
-
-msgctxt "odt:purchase.purchase:"
 msgid "Taxes"
 msgstr "Taxes"
 
@@ -994,14 +943,6 @@ msgid "Taxes:"
 msgstr "Taxes:"
 
 msgctxt "odt:purchase.purchase:"
-msgid "Taxes:"
-msgstr "Taxes:"
-
-msgctxt "odt:purchase.purchase:"
-msgid "Total (excl. taxes):"
-msgstr "Total (htva)"
-
-msgctxt "odt:purchase.purchase:"
 msgid "Total (excl. taxes):"
 msgstr "Total (htva)"
 
@@ -1010,28 +951,12 @@ msgid "Total:"
 msgstr "Total:"
 
 msgctxt "odt:purchase.purchase:"
-msgid "Total:"
-msgstr "Total:"
-
-msgctxt "odt:purchase.purchase:"
-msgid "Unit Price"
-msgstr "Prix unitaire"
-
-msgctxt "odt:purchase.purchase:"
 msgid "Unit Price"
 msgstr "Prix unitaire"
 
 msgctxt "odt:purchase.purchase:"
 msgid "VAT Number:"
-msgstr "Numéro TVA:"
-
-msgctxt "odt:purchase.purchase:"
-msgid "VAT Number:"
-msgstr "Numéro TVA:"
-
-msgctxt "odt:purchase.purchase:"
-msgid "VAT:"
-msgstr "TVA:"
+msgstr "Numéro TVA :"
 
 msgctxt "odt:purchase.purchase:"
 msgid "VAT:"
@@ -1042,14 +967,6 @@ msgid ""
 msgstr ""
 
 msgctxt "selection:account.invoice,purchase_exception_state:"
-msgid ""
-msgstr ""
-
-msgctxt "selection:account.invoice,purchase_exception_state:"
-msgid "Ignored"
-msgstr "Ignoré"
-
-msgctxt "selection:account.invoice,purchase_exception_state:"
 msgid "Ignored"
 msgstr "Ignoré"
 
@@ -1057,14 +974,6 @@ msgctxt "selection:account.invoice,purchase_exception_state:"
 msgid "Recreated"
 msgstr "Recréé"
 
-msgctxt "selection:account.invoice,purchase_exception_state:"
-msgid "Recreated"
-msgstr "Recréé"
-
-msgctxt "selection:purchase.configuration,purchase_invoice_method:"
-msgid "Based On Order"
-msgstr "Basé sur la commande"
-
 msgctxt "selection:purchase.configuration,purchase_invoice_method:"
 msgid "Based On Order"
 msgstr "Basé sur la commande"
@@ -1074,14 +983,6 @@ msgid "Based On Shipment"
 msgstr "Basé sur la livraison"
 
 msgctxt "selection:purchase.configuration,purchase_invoice_method:"
-msgid "Based On Shipment"
-msgstr "Basé sur la livraison"
-
-msgctxt "selection:purchase.configuration,purchase_invoice_method:"
-msgid "Manual"
-msgstr "Manuel"
-
-msgctxt "selection:purchase.configuration,purchase_invoice_method:"
 msgid "Manual"
 msgstr "Manuel"
 
@@ -1090,14 +991,6 @@ msgid "Comment"
 msgstr "Commentaire"
 
 msgctxt "selection:purchase.line,type:"
-msgid "Comment"
-msgstr "Commentaire"
-
-msgctxt "selection:purchase.line,type:"
-msgid "Line"
-msgstr "Ligne"
-
-msgctxt "selection:purchase.line,type:"
 msgid "Line"
 msgstr "Ligne"
 
@@ -1106,14 +999,6 @@ msgid "Subtotal"
 msgstr "Sous-total"
 
 msgctxt "selection:purchase.line,type:"
-msgid "Subtotal"
-msgstr "Sous-total"
-
-msgctxt "selection:purchase.line,type:"
-msgid "Title"
-msgstr "Titre"
-
-msgctxt "selection:purchase.line,type:"
 msgid "Title"
 msgstr "Titre"
 
@@ -1122,14 +1007,6 @@ msgid "Based On Order"
 msgstr "Basé sur la commande"
 
 msgctxt "selection:purchase.purchase,invoice_method:"
-msgid "Based On Order"
-msgstr "Basé sur la commande"
-
-msgctxt "selection:purchase.purchase,invoice_method:"
-msgid "Based On Shipment"
-msgstr "Basé sur la livraison"
-
-msgctxt "selection:purchase.purchase,invoice_method:"
 msgid "Based On Shipment"
 msgstr "Basé sur la livraison"
 
@@ -1137,23 +1014,11 @@ msgctxt "selection:purchase.purchase,invoice_method:"
 msgid "Manual"
 msgstr "Manuel"
 
-msgctxt "selection:purchase.purchase,invoice_method:"
-msgid "Manual"
-msgstr "Manuel"
-
 msgctxt "selection:purchase.purchase,invoice_state:"
 msgid "Exception"
 msgstr "Exception"
 
 msgctxt "selection:purchase.purchase,invoice_state:"
-msgid "Exception"
-msgstr "Exception"
-
-msgctxt "selection:purchase.purchase,invoice_state:"
-msgid "None"
-msgstr "Aucun"
-
-msgctxt "selection:purchase.purchase,invoice_state:"
 msgid "None"
 msgstr "Aucun"
 
@@ -1162,14 +1027,6 @@ msgid "Paid"
 msgstr "Payé"
 
 msgctxt "selection:purchase.purchase,invoice_state:"
-msgid "Paid"
-msgstr "Payé"
-
-msgctxt "selection:purchase.purchase,invoice_state:"
-msgid "Waiting"
-msgstr "En attente"
-
-msgctxt "selection:purchase.purchase,invoice_state:"
 msgid "Waiting"
 msgstr "En attente"
 
@@ -1178,14 +1035,6 @@ msgid "Exception"
 msgstr "Exception"
 
 msgctxt "selection:purchase.purchase,shipment_state:"
-msgid "Exception"
-msgstr "Exception"
-
-msgctxt "selection:purchase.purchase,shipment_state:"
-msgid "None"
-msgstr "Aucun"
-
-msgctxt "selection:purchase.purchase,shipment_state:"
 msgid "None"
 msgstr "Aucun"
 
@@ -1194,14 +1043,6 @@ msgid "Received"
 msgstr "Reçu"
 
 msgctxt "selection:purchase.purchase,shipment_state:"
-msgid "Received"
-msgstr "Reçu"
-
-msgctxt "selection:purchase.purchase,shipment_state:"
-msgid "Waiting"
-msgstr "En attente"
-
-msgctxt "selection:purchase.purchase,shipment_state:"
 msgid "Waiting"
 msgstr "En attente"
 
@@ -1210,22 +1051,10 @@ msgid "Canceled"
 msgstr "Annulé"
 
 msgctxt "selection:purchase.purchase,state:"
-msgid "Canceled"
-msgstr "Annulé"
-
-msgctxt "selection:purchase.purchase,state:"
 msgid "Confirmed"
 msgstr "Confirmé"
 
 msgctxt "selection:purchase.purchase,state:"
-msgid "Confirmed"
-msgstr "Confirmé"
-
-msgctxt "selection:purchase.purchase,state:"
-msgid "Done"
-msgstr "Fait"
-
-msgctxt "selection:purchase.purchase,state:"
 msgid "Done"
 msgstr "Fait"
 
@@ -1234,21 +1063,9 @@ msgid "Draft"
 msgstr "Brouillon"
 
 msgctxt "selection:purchase.purchase,state:"
-msgid "Draft"
-msgstr "Brouillon"
-
-msgctxt "selection:purchase.purchase,state:"
 msgid "Quotation"
 msgstr "Devis"
 
-msgctxt "selection:purchase.purchase,state:"
-msgid "Quotation"
-msgstr "Devis"
-
-msgctxt "selection:stock.move,purchase_exception_state:"
-msgid ""
-msgstr ""
-
 msgctxt "selection:stock.move,purchase_exception_state:"
 msgid ""
 msgstr ""
@@ -1258,14 +1075,6 @@ msgid "Ignored"
 msgstr "Ignoré"
 
 msgctxt "selection:stock.move,purchase_exception_state:"
-msgid "Ignored"
-msgstr "Ignoré"
-
-msgctxt "selection:stock.move,purchase_exception_state:"
-msgid "Recreated"
-msgstr "Recréé"
-
-msgctxt "selection:stock.move,purchase_exception_state:"
 msgid "Recreated"
 msgstr "Recréé"
 
@@ -1277,14 +1086,6 @@ msgctxt "view:product.template:"
 msgid "Suppliers"
 msgstr "Fournisseurs"
 
-msgctxt "view:product.template:"
-msgid "Suppliers"
-msgstr "Fournisseurs"
-
-msgctxt "view:purchase.configuration:"
-msgid "Purchase Configuration"
-msgstr "Configuration des achats"
-
 msgctxt "view:purchase.configuration:"
 msgid "Purchase Configuration"
 msgstr "Configuration des achats"
@@ -1294,14 +1095,6 @@ msgid "Choose invoices to recreate"
 msgstr "Choisir les factures à recréer"
 
 msgctxt "view:purchase.handle.invoice.exception.ask:"
-msgid "Choose invoices to recreate"
-msgstr "Choisir les factures à recréer"
-
-msgctxt "view:purchase.handle.invoice.exception.ask:"
-msgid "Handle Invoice Exception"
-msgstr "Gérer l'exception de facture"
-
-msgctxt "view:purchase.handle.invoice.exception.ask:"
 msgid "Handle Invoice Exception"
 msgstr "Gérer l'exception de facture"
 
@@ -1310,14 +1103,6 @@ msgid "Choose move to recreate"
 msgstr "Choisir le mouvement à recréer"
 
 msgctxt "view:purchase.handle.shipment.exception.ask:"
-msgid "Choose move to recreate"
-msgstr "Choisir le mouvement à recréer"
-
-msgctxt "view:purchase.handle.shipment.exception.ask:"
-msgid "Handle shipment Exception"
-msgstr "Gérer l'exception d'expédition"
-
-msgctxt "view:purchase.handle.shipment.exception.ask:"
 msgid "Handle shipment Exception"
 msgstr "Gérer l'exception d'expédition"
 
@@ -1326,10 +1111,6 @@ msgid "General"
 msgstr "Général"
 
 msgctxt "view:purchase.line:"
-msgid "General"
-msgstr "Général"
-
-msgctxt "view:purchase.line:"
 msgid "Lines"
 msgstr "Lignes"
 
@@ -1338,14 +1119,6 @@ msgid "Notes"
 msgstr "Notes"
 
 msgctxt "view:purchase.line:"
-msgid "Notes"
-msgstr "Notes"
-
-msgctxt "view:purchase.line:"
-msgid "Purchase Line"
-msgstr "Ligne d'achat"
-
-msgctxt "view:purchase.line:"
 msgid "Purchase Line"
 msgstr "Ligne d'achat"
 
@@ -1353,14 +1126,6 @@ msgctxt "view:purchase.line:"
 msgid "Purchase Lines"
 msgstr "Lignes d'achat"
 
-msgctxt "view:purchase.line:"
-msgid "Purchase Lines"
-msgstr "Lignes d'achat"
-
-msgctxt "view:purchase.product_supplier.price:"
-msgid "Product Supplier Price"
-msgstr "Prix du fournisseur du produit"
-
 msgctxt "view:purchase.product_supplier.price:"
 msgid "Product Supplier Price"
 msgstr "Prix du fournisseur du produit"
@@ -1369,14 +1134,6 @@ msgctxt "view:purchase.product_supplier.price:"
 msgid "Product Supplier Prices"
 msgstr "Prix du fournisseur du produit"
 
-msgctxt "view:purchase.product_supplier.price:"
-msgid "Product Supplier Prices"
-msgstr "Prix du fournisseur du produit"
-
-msgctxt "view:purchase.product_supplier:"
-msgid "Product Supplier"
-msgstr "Fournisseur du produit"
-
 msgctxt "view:purchase.product_supplier:"
 msgid "Product Supplier"
 msgstr "Fournisseur du produit"
@@ -1385,14 +1142,6 @@ msgctxt "view:purchase.product_supplier:"
 msgid "Product Suppliers"
 msgstr "Fournisseurs du produit"
 
-msgctxt "view:purchase.product_supplier:"
-msgid "Product Suppliers"
-msgstr "Fournisseurs du produit"
-
-msgctxt "view:purchase.purchase:"
-msgid "Cancel"
-msgstr "Annuler"
-
 msgctxt "view:purchase.purchase:"
 msgid "Cancel"
 msgstr "Annuler"
@@ -1402,22 +1151,10 @@ msgid "Confirm"
 msgstr "Confirmer"
 
 msgctxt "view:purchase.purchase:"
-msgid "Confirm"
-msgstr "Confirmer"
-
-msgctxt "view:purchase.purchase:"
 msgid "Draft"
 msgstr "Brouillon"
 
 msgctxt "view:purchase.purchase:"
-msgid "Draft"
-msgstr "Brouillon"
-
-msgctxt "view:purchase.purchase:"
-msgid "Handle Invoice Exception"
-msgstr "Gérer l'exception de facture"
-
-msgctxt "view:purchase.purchase:"
 msgid "Handle Invoice Exception"
 msgstr "Gérer l'exception de facture"
 
@@ -1426,14 +1163,6 @@ msgid "Handle Shipment Exception"
 msgstr "Gérer l'exception d'expédition"
 
 msgctxt "view:purchase.purchase:"
-msgid "Handle Shipment Exception"
-msgstr "Gérer l'exception d'expédition"
-
-msgctxt "view:purchase.purchase:"
-msgid "Invoices"
-msgstr "Factures"
-
-msgctxt "view:purchase.purchase:"
 msgid "Invoices"
 msgstr "Factures"
 
@@ -1442,14 +1171,6 @@ msgid "Other Info"
 msgstr "Autre information"
 
 msgctxt "view:purchase.purchase:"
-msgid "Other Info"
-msgstr "Autre information"
-
-msgctxt "view:purchase.purchase:"
-msgid "Purchase"
-msgstr "Achat"
-
-msgctxt "view:purchase.purchase:"
 msgid "Purchase"
 msgstr "Achat"
 
@@ -1458,10 +1179,6 @@ msgid "Purchases"
 msgstr "Achats"
 
 msgctxt "view:purchase.purchase:"
-msgid "Purchases"
-msgstr "Achats"
-
-msgctxt "view:purchase.purchase:"
 msgid "Quote"
 msgstr "Devis"
 
@@ -1469,10 +1186,6 @@ msgctxt "view:purchase.purchase:"
 msgid "Shipments"
 msgstr "Expéditions"
 
-msgctxt "view:purchase.purchase:"
-msgid "Shipments"
-msgstr "Expéditions"
-
 msgctxt "view:stock.move:"
 msgid "Moves"
 msgstr "Mouvements"
diff --git a/locale/nl_NL.po b/locale/nl_NL.po
index bf39673..4c9c7c2 100644
--- a/locale/nl_NL.po
+++ b/locale/nl_NL.po
@@ -827,6 +827,10 @@ msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
 msgstr ""
 
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr ""
+
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr ""
diff --git a/locale/ru_RU.po b/locale/ru_RU.po
index 703403d..5291128 100644
--- a/locale/ru_RU.po
+++ b/locale/ru_RU.po
@@ -756,6 +756,11 @@ msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
 msgstr "Покупки"
 
+#, fuzzy
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr "Покупки"
+
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
 msgstr "Возвраты"
diff --git a/locale/nl_NL.po b/locale/sl_SI.po
similarity index 75%
copy from locale/nl_NL.po
copy to locale/sl_SI.po
index bf39673..ea0b3f1 100644
--- a/locale/nl_NL.po
+++ b/locale/sl_SI.po
@@ -4,1345 +4,1213 @@ msgstr "Content-Type: text/plain; charset=utf-8\n"
 
 msgctxt "error:account.invoice:"
 msgid "You can not delete invoices that come from a purchase."
-msgstr ""
+msgstr "Računov, izhajajočih iz nabavnih nalogov, ni možno brisati."
 
 msgctxt "error:account.invoice:"
 msgid "You cannot reset to draft an invoice generated by a purchase."
 msgstr ""
+"Računa, ustvarjenega iz nabavnega naloga, ni možno prestaviti v stanje "
+"osnutka."
 
 msgctxt "error:product.template:"
 msgid ""
 "Purchase prices are based on the purchase uom, are you sure to change it?"
 msgstr ""
+"Nabavne cene so zasnovane na nabavni ME. Ali jo res želite spremeniti?"
 
 msgctxt "error:purchase.line:"
 msgid ""
 "Product \"%(product)s\" of purchase %(purchase)s misses an expense account."
 msgstr ""
+"Izdelku \"%(product)s\" na nabavnem nalogu %(purchase)s manjka odhodkovni "
+"konto."
 
 msgctxt "error:purchase.line:"
 msgid "Purchase \"%(purchase)s\" misses an \"account expense\" default property."
 msgstr ""
+"Nabavnemu nalogu \"%(purchase)s\" manjka privzeta lastnost odhodkovnega "
+"konta."
 
 msgctxt "error:purchase.line:"
 msgid "Purchase \"%(purchase)s\" misses the supplier location for line \"%(line)s\"."
 msgstr ""
+"Postavki \"%(line)s\" na nabavnem nalogu \"%(purchase)s\" manjka "
+"dobaviteljeva lokacija."
 
 msgctxt "error:purchase.purchase:"
 msgid "A warehouse must be defined for quotation of sale \"%s\"."
-msgstr ""
+msgstr "Za ponudbo \"%s\" mora biti določeno skladišče."
 
 msgctxt "error:purchase.purchase:"
 msgid "Invoice address must be defined for quotation of sale \"%s\"."
-msgstr ""
+msgstr "Za ponudbo \"%s\" mora biti določen plačnik."
 
 msgctxt "error:purchase.purchase:"
 msgid "Missing \"Account Payable\" on party \"%s\"."
-msgstr ""
+msgstr "Za stranko \"%s\" manjka terjatveni konto."
 
 msgctxt "error:purchase.purchase:"
 msgid "Purchase \"%s\" must be cancelled before deletion."
-msgstr ""
+msgstr "Pred brisanjem je potrebno nabavni nalog \"%s\" preklicati."
 
 msgctxt "error:stock.shipment.in.return:"
 msgid "You cannot reset to draft a move generated by a purchase."
 msgstr ""
+"Prometa, ustvarjenega iz nabavnega naloga, ni možno prestaviti v stanje "
+"osnutka."
 
 msgctxt "error:stock.shipment.in:"
 msgid ""
 "You cannot reset to draft move \"%s\" because it was generated by a "
 "purchase."
 msgstr ""
+"Prometa \"%s\", ustvarjenega iz nabavnega naloga, ni možno prestaviti v "
+"stanje osnutka."
 
-#, fuzzy
 msgctxt "field:account.invoice,purchase_exception_state:"
 msgid "Exception State"
-msgstr "Uitzonderingstoestand"
+msgstr "Pridržano"
 
 msgctxt "field:account.invoice,purchases:"
 msgid "Purchases"
-msgstr ""
+msgstr "Nabavni nalogi"
 
 msgctxt "field:product.template,product_suppliers:"
 msgid "Suppliers"
-msgstr ""
+msgstr "Dobavitelji"
 
 msgctxt "field:product.template,purchasable:"
 msgid "Purchasable"
-msgstr ""
+msgstr "Za nabavo"
 
 msgctxt "field:product.template,purchase_uom:"
 msgid "Purchase UOM"
-msgstr ""
+msgstr "Nabavna ME"
 
 msgctxt "field:purchase.configuration,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.configuration,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
 msgctxt "field:purchase.configuration,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.configuration,purchase_invoice_method:"
 msgid "Invoice Method"
-msgstr "Factuur afhandeling"
+msgstr "Način obračuna"
 
 msgctxt "field:purchase.configuration,purchase_sequence:"
 msgid "Purchase Reference Sequence"
-msgstr ""
+msgstr "Štetje nabavnih nalogov"
 
-#, fuzzy
 msgctxt "field:purchase.configuration,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
 msgctxt "field:purchase.configuration,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.configuration,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
-#, fuzzy
 msgctxt "field:purchase.handle.invoice.exception.ask,domain_invoices:"
 msgid "Domain Invoices"
-msgstr "Domein facturen"
+msgstr "Vključeni računi"
 
 msgctxt "field:purchase.handle.invoice.exception.ask,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.handle.invoice.exception.ask,recreate_invoices:"
 msgid "Recreate Invoices"
-msgstr "Facturen opnieuw aanmaken"
+msgstr "Poustvarjeni računi"
 
-#, fuzzy
 msgctxt "field:purchase.handle.shipment.exception.ask,domain_moves:"
 msgid "Domain Moves"
-msgstr "Domein boekingen"
+msgstr "Vključen promet"
 
 msgctxt "field:purchase.handle.shipment.exception.ask,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.handle.shipment.exception.ask,recreate_moves:"
 msgid "Recreate Moves"
-msgstr "Boekingen opnieuw aanmaken"
+msgstr "Poustvarjen promet"
 
-#, fuzzy
 msgctxt "field:purchase.line,amount:"
 msgid "Amount"
-msgstr "Bedrag"
+msgstr "Znesek"
 
 msgctxt "field:purchase.line,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.line,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
 msgctxt "field:purchase.line,delivery_date:"
 msgid "Delivery Date"
-msgstr ""
+msgstr "Dostavljeno"
 
-#, fuzzy
 msgctxt "field:purchase.line,description:"
 msgid "Description"
-msgstr "Specificatie"
+msgstr "Opis"
 
 msgctxt "field:purchase.line,from_location:"
 msgid "From Location"
-msgstr ""
+msgstr "Iz lokacije"
 
 msgctxt "field:purchase.line,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.line,invoice_lines:"
 msgid "Invoice Lines"
-msgstr "Factuurregels"
+msgstr "Postavke računa"
 
-#, fuzzy
 msgctxt "field:purchase.line,move_done:"
 msgid "Moves Done"
-msgstr "Boekingen klaar"
+msgstr "Zaključen promet"
 
-#, fuzzy
 msgctxt "field:purchase.line,move_exception:"
 msgid "Moves Exception"
-msgstr "Boekingen uitzondering"
+msgstr "Pridržani promet"
 
-#, fuzzy
 msgctxt "field:purchase.line,moves:"
 msgid "Moves"
-msgstr "Boekingen"
+msgstr "Promet"
 
-#, fuzzy
 msgctxt "field:purchase.line,moves_ignored:"
 msgid "Ignored Moves"
-msgstr "Genegeerde boekingen"
+msgstr "Prezrt promet"
 
-#, fuzzy
 msgctxt "field:purchase.line,moves_recreated:"
 msgid "Recreated Moves"
-msgstr "Opnieuw aangemaakte boekingen"
+msgstr "Poustvarjen promet"
 
-#, fuzzy
 msgctxt "field:purchase.line,note:"
 msgid "Note"
-msgstr "Aantekening"
+msgstr "Opomba"
 
-#, fuzzy
 msgctxt "field:purchase.line,product:"
 msgid "Product"
-msgstr "Producten"
+msgstr "Izdelek"
 
 msgctxt "field:purchase.line,product_uom_category:"
 msgid "Product Uom Category"
-msgstr ""
+msgstr "Katerogija EM izdelka"
 
 msgctxt "field:purchase.line,purchase:"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalog"
 
-#, fuzzy
 msgctxt "field:purchase.line,quantity:"
 msgid "Quantity"
-msgstr "Hoeveelheid"
+msgstr "Količina"
 
-#, fuzzy
 msgctxt "field:purchase.line,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
-#, fuzzy
 msgctxt "field:purchase.line,sequence:"
 msgid "Sequence"
-msgstr "Reeks"
+msgstr "Zap.št."
 
-#, fuzzy
 msgctxt "field:purchase.line,taxes:"
 msgid "Taxes"
-msgstr "Belastingen"
+msgstr "Davki"
 
 msgctxt "field:purchase.line,to_location:"
 msgid "To Location"
-msgstr ""
+msgstr "Na lokacijo"
 
-#, fuzzy
 msgctxt "field:purchase.line,type:"
 msgid "Type"
-msgstr "Type"
+msgstr "Vrsta"
 
-#, fuzzy
 msgctxt "field:purchase.line,unit:"
 msgid "Unit"
-msgstr "Eenheid"
+msgstr "enota"
 
-#, fuzzy
 msgctxt "field:purchase.line,unit_digits:"
 msgid "Unit Digits"
-msgstr "Decimalen eenheid"
+msgstr "Decimalke"
 
-#, fuzzy
 msgctxt "field:purchase.line,unit_price:"
 msgid "Unit Price"
-msgstr "Eenheidsprijs"
+msgstr "Cena"
 
 msgctxt "field:purchase.line,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.line,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
 msgctxt "field:purchase.line-account.tax,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.line-account.tax,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
 msgctxt "field:purchase.line-account.tax,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
 msgctxt "field:purchase.line-account.tax,line:"
 msgid "Purchase Line"
-msgstr ""
+msgstr "Nabavna postavka"
 
-#, fuzzy
 msgctxt "field:purchase.line-account.tax,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
-#, fuzzy
 msgctxt "field:purchase.line-account.tax,tax:"
 msgid "Tax"
-msgstr "Belasting"
+msgstr "Davek"
 
 msgctxt "field:purchase.line-account.tax,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.line-account.tax,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
 msgctxt "field:purchase.line-ignored-stock.move,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.line-ignored-stock.move,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
 msgctxt "field:purchase.line-ignored-stock.move,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.line-ignored-stock.move,move:"
 msgid "Move"
-msgstr "Boeking"
+msgstr "Promet"
 
 msgctxt "field:purchase.line-ignored-stock.move,purchase_line:"
 msgid "Purchase Line"
-msgstr ""
+msgstr "Nabavna postavka"
 
-#, fuzzy
 msgctxt "field:purchase.line-ignored-stock.move,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
 msgctxt "field:purchase.line-ignored-stock.move,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.line-ignored-stock.move,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
 msgctxt "field:purchase.line-recreated-stock.move,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.line-recreated-stock.move,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
 msgctxt "field:purchase.line-recreated-stock.move,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.line-recreated-stock.move,move:"
 msgid "Move"
-msgstr "Boeking"
+msgstr "Promet"
 
 msgctxt "field:purchase.line-recreated-stock.move,purchase_line:"
 msgid "Purchase Line"
-msgstr ""
+msgstr "Nabavna postavka"
 
-#, fuzzy
 msgctxt "field:purchase.line-recreated-stock.move,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
 msgctxt "field:purchase.line-recreated-stock.move,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.line-recreated-stock.move,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier,code:"
 msgid "Code"
-msgstr "Code"
+msgstr "Šifra"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier,company:"
 msgid "Company"
-msgstr "Bedrijf"
+msgstr "Podjetje"
 
 msgctxt "field:purchase.product_supplier,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.product_supplier,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier,currency:"
 msgid "Currency"
 msgstr "Valuta"
 
 msgctxt "field:purchase.product_supplier,delivery_time:"
 msgid "Delivery Time"
-msgstr ""
+msgstr "Dostavljeno"
 
 msgctxt "field:purchase.product_supplier,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier,name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Naziv"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier,party:"
 msgid "Supplier"
-msgstr "Leverancier"
+msgstr "Dobavitelj"
 
 msgctxt "field:purchase.product_supplier,prices:"
 msgid "Prices"
-msgstr ""
+msgstr "Cene"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier,product:"
 msgid "Product"
-msgstr "Producten"
+msgstr "Izdelek"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier,sequence:"
 msgid "Sequence"
-msgstr "Reeks"
+msgstr "Zap.št."
 
 msgctxt "field:purchase.product_supplier,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.product_supplier,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
 msgctxt "field:purchase.product_supplier.price,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.product_supplier.price,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
 msgctxt "field:purchase.product_supplier.price,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier.price,product_supplier:"
 msgid "Supplier"
-msgstr "Leverancier"
+msgstr "Dobavitelj"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier.price,quantity:"
 msgid "Quantity"
-msgstr "Hoeveelheid"
+msgstr "Količina"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier.price,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
-#, fuzzy
 msgctxt "field:purchase.product_supplier.price,unit_price:"
 msgid "Unit Price"
-msgstr "Eenheidsprijs"
+msgstr "Cena"
 
 msgctxt "field:purchase.product_supplier.price,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.product_supplier.price,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,comment:"
 msgid "Comment"
-msgstr "Opmerking"
+msgstr "Opomba"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,company:"
 msgid "Company"
-msgstr "Bedrijf"
+msgstr "Podjetje"
 
 msgctxt "field:purchase.purchase,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.purchase,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,currency:"
 msgid "Currency"
 msgstr "Valuta"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,currency_digits:"
 msgid "Currency Digits"
-msgstr "Valuta decimalen"
+msgstr "Decimalke"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,description:"
 msgid "Description"
-msgstr "Specificatie"
+msgstr "Opis"
 
 msgctxt "field:purchase.purchase,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,invoice_address:"
 msgid "Invoice Address"
-msgstr "Factuuradres"
+msgstr "Plačnik"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,invoice_method:"
 msgid "Invoice Method"
-msgstr "Factuur afhandeling"
+msgstr "Način obračuna"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,invoice_state:"
 msgid "Invoice State"
-msgstr "Factuur status"
+msgstr "Stanje računa"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,invoices:"
 msgid "Invoices"
-msgstr "Verkoopfacturen"
+msgstr "Računi"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,invoices_ignored:"
 msgid "Ignored Invoices"
-msgstr "Genegeerde facturen"
+msgstr "Prezrti računi"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,invoices_recreated:"
 msgid "Recreated Invoices"
-msgstr "Opnieuw aangemaakte facturen"
+msgstr "Poustvarjeni računi"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,lines:"
 msgid "Lines"
-msgstr "Regels"
+msgstr "Postavke"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,moves:"
 msgid "Moves"
-msgstr "Boekingen"
+msgstr "Promet"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,party:"
 msgid "Party"
-msgstr "Relaties"
+msgstr "Stranka"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,party_lang:"
 msgid "Party Language"
-msgstr "Taal relatie"
+msgstr "Jezik stranke"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,payment_term:"
 msgid "Payment Term"
-msgstr "Betalingstermijn"
+msgstr "Plačilni rok"
 
 msgctxt "field:purchase.purchase,purchase_date:"
 msgid "Purchase Date"
-msgstr ""
+msgstr "Nabavljeno"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,reference:"
 msgid "Reference"
-msgstr "Referentie"
+msgstr "Sklic"
 
 msgctxt "field:purchase.purchase,shipment_returns:"
 msgid "Shipment Returns"
-msgstr ""
+msgstr "Vrnjene prevzemnice"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,shipment_state:"
 msgid "Shipment State"
-msgstr "Levering status"
+msgstr "Stanje pošiljke"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,shipments:"
 msgid "Shipments"
-msgstr "Leveringen"
+msgstr "Pošiljke"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,state:"
 msgid "State"
-msgstr "Status"
+msgstr "Stanje"
 
 msgctxt "field:purchase.purchase,supplier_reference:"
 msgid "Supplier Reference"
-msgstr ""
+msgstr "Dobaviteljev sklic"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,tax_amount:"
 msgid "Tax"
-msgstr "Belasting"
+msgstr "Davek"
 
 msgctxt "field:purchase.purchase,tax_amount_cache:"
 msgid "Tax Cache"
-msgstr ""
+msgstr "Davek predpomnjen"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,total_amount:"
 msgid "Total"
-msgstr "Totaal"
+msgstr "Skupaj"
 
 msgctxt "field:purchase.purchase,total_amount_cache:"
 msgid "Total Cache"
-msgstr ""
+msgstr "Skupaj predpomnjeno"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,untaxed_amount:"
 msgid "Untaxed"
-msgstr "Onbelast"
+msgstr "Neobdavčeno"
 
 msgctxt "field:purchase.purchase,untaxed_amount_cache:"
 msgid "Untaxed Cache"
-msgstr ""
+msgstr "Neobdavčeno predpomnjeno"
 
-#, fuzzy
 msgctxt "field:purchase.purchase,warehouse:"
 msgid "Warehouse"
-msgstr "Magazijn"
+msgstr "Skladišče"
 
 msgctxt "field:purchase.purchase,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.purchase,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
 msgctxt "field:purchase.purchase-account.invoice,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.purchase-account.invoice,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
 msgctxt "field:purchase.purchase-account.invoice,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.purchase-account.invoice,invoice:"
 msgid "Invoice"
-msgstr "Verkoopfactuur"
+msgstr "Račun"
 
 msgctxt "field:purchase.purchase-account.invoice,purchase:"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalog"
 
-#, fuzzy
 msgctxt "field:purchase.purchase-account.invoice,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
 msgctxt "field:purchase.purchase-account.invoice,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.purchase-account.invoice,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
 msgctxt "field:purchase.purchase-ignored-account.invoice,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.purchase-ignored-account.invoice,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
 msgctxt "field:purchase.purchase-ignored-account.invoice,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.purchase-ignored-account.invoice,invoice:"
 msgid "Invoice"
-msgstr "Verkoopfactuur"
+msgstr "Račun"
 
 msgctxt "field:purchase.purchase-ignored-account.invoice,purchase:"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalog"
 
-#, fuzzy
 msgctxt "field:purchase.purchase-ignored-account.invoice,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
 msgctxt "field:purchase.purchase-ignored-account.invoice,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.purchase-ignored-account.invoice,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
 msgctxt "field:purchase.purchase-recreated-account.invoice,create_date:"
 msgid "Create Date"
-msgstr ""
+msgstr "Ustvarjeno"
 
 msgctxt "field:purchase.purchase-recreated-account.invoice,create_uid:"
 msgid "Create User"
-msgstr ""
+msgstr "Ustvaril"
 
 msgctxt "field:purchase.purchase-recreated-account.invoice,id:"
 msgid "ID"
-msgstr ""
+msgstr "ID"
 
-#, fuzzy
 msgctxt "field:purchase.purchase-recreated-account.invoice,invoice:"
 msgid "Invoice"
-msgstr "Verkoopfactuur"
+msgstr "Račun"
 
 msgctxt "field:purchase.purchase-recreated-account.invoice,purchase:"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalog"
 
-#, fuzzy
 msgctxt "field:purchase.purchase-recreated-account.invoice,rec_name:"
 msgid "Name"
-msgstr "Naam bijlage"
+msgstr "Ime"
 
 msgctxt "field:purchase.purchase-recreated-account.invoice,write_date:"
 msgid "Write Date"
-msgstr ""
+msgstr "Zapisano"
 
 msgctxt "field:purchase.purchase-recreated-account.invoice,write_uid:"
 msgid "Write User"
-msgstr ""
+msgstr "Zapisal"
 
 msgctxt "field:stock.move,purchase:"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalog"
 
 msgctxt "field:stock.move,purchase_currency:"
 msgid "Purchase Currency"
-msgstr ""
+msgstr "Nabavna valuta"
 
-#, fuzzy
 msgctxt "field:stock.move,purchase_exception_state:"
 msgid "Exception State"
-msgstr "Uitzonderingstoestand"
+msgstr "Pridržano"
 
 msgctxt "field:stock.move,purchase_quantity:"
 msgid "Purchase Quantity"
-msgstr ""
+msgstr "Nabavna količina"
 
 msgctxt "field:stock.move,purchase_unit:"
 msgid "Purchase Unit"
-msgstr ""
+msgstr "Nabavna enota"
 
 msgctxt "field:stock.move,purchase_unit_digits:"
 msgid "Purchase Unit Digits"
-msgstr ""
+msgstr "Nabavne decimalke"
 
 msgctxt "field:stock.move,purchase_unit_price:"
 msgid "Purchase Unit Price"
-msgstr ""
+msgstr "Nabavna cena"
 
 msgctxt "field:stock.move,purchase_visible:"
 msgid "Purchase Visible"
-msgstr ""
+msgstr "Nabavni nalog viden"
 
-#, fuzzy
 msgctxt "field:stock.move,supplier:"
 msgid "Supplier"
-msgstr "Leverancier"
+msgstr "Dobavitelj"
 
-#, fuzzy
 msgctxt "help:purchase.handle.invoice.exception.ask,recreate_invoices:"
 msgid ""
 "The selected invoices will be recreated. The other ones will be ignored."
-msgstr ""
-"De geselecteerde facturen worden opnieuw aangemaakt. De rest wordt "
-"genegeerd."
+msgstr "Izbrani računi bodo poustvarjeni, ostali bodo prezrti."
 
 msgctxt "help:purchase.handle.shipment.exception.ask,recreate_moves:"
 msgid "The selected moves will be recreated. The other ones will be ignored."
-msgstr ""
+msgstr "Izbran promet bo poustvarjen, ostali bo prezrt."
 
 msgctxt "help:purchase.product_supplier,delivery_time:"
 msgid "In number of days"
-msgstr ""
+msgstr "V dnevih"
 
 msgctxt "help:purchase.product_supplier.price,quantity:"
 msgid "Minimal quantity"
-msgstr ""
+msgstr "Minimalna količina"
 
-#, fuzzy
 msgctxt "model:ir.action,name:act_invoice_form"
 msgid "Invoices"
-msgstr "Verkoopfacturen"
+msgstr "Računi"
 
 msgctxt "model:ir.action,name:act_open_supplier"
 msgid "Parties associated to Purchases"
-msgstr ""
+msgstr "Stranke pri nabavi"
 
 msgctxt "model:ir.action,name:act_purchase_configuration_form"
 msgid "Purchase Configuration"
-msgstr ""
+msgstr "Nabavna konfiguracija"
 
 msgctxt "model:ir.action,name:act_purchase_form"
 msgid "Purchases"
-msgstr ""
+msgstr "Nabavni nalogi"
 
 msgctxt "model:ir.action,name:act_purchase_form2"
 msgid "Purchases"
-msgstr ""
+msgstr "Nabavni nalogi"
+
+msgctxt "model:ir.action,name:act_purchase_invoice_relate"
+msgid "Purchases"
+msgstr "Nabavni nalogi"
 
 msgctxt "model:ir.action,name:act_return_form"
 msgid "Returns"
-msgstr ""
+msgstr "Vrnjene prevzemnice"
 
-#, fuzzy
 msgctxt "model:ir.action,name:act_shipment_form"
 msgid "Shipments"
-msgstr "Leveringen"
+msgstr "Pošiljke"
 
 msgctxt "model:ir.action,name:report_purchase"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalogi"
 
-#, fuzzy
 msgctxt "model:ir.action,name:wizard_invoice_handle_exception"
 msgid "Handle Invoice Exception"
-msgstr "Factuuruitzondering afhandelen"
+msgstr "Obravnava pridržanih računov"
 
-#, fuzzy
 msgctxt "model:ir.action,name:wizard_shipment_handle_exception"
 msgid "Handle Shipment Exception"
-msgstr "Zendinguitzondering afhandelen"
+msgstr "Obravnava pridržanih prevzemnic"
 
 msgctxt "model:ir.action.act_window.domain,name:act_purchase_form_domain_all"
 msgid "All"
-msgstr ""
+msgstr "Vse"
 
-#, fuzzy
 msgctxt ""
 "model:ir.action.act_window.domain,name:act_purchase_form_domain_confirmed"
 msgid "Confirmed"
-msgstr "Bevestigd"
+msgstr "Potrjeno"
 
-#, fuzzy
 msgctxt ""
 "model:ir.action.act_window.domain,name:act_purchase_form_domain_draft"
 msgid "Draft"
-msgstr "Concept"
+msgstr "Osnutek"
 
-#, fuzzy
 msgctxt ""
 "model:ir.action.act_window.domain,name:act_purchase_form_domain_quotation"
 msgid "Quotation"
-msgstr "Offerte"
+msgstr "Ponudba"
 
 msgctxt "model:ir.sequence,name:sequence_purchase"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalog"
 
 msgctxt "model:ir.sequence.type,name:sequence_type_purchase"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalog"
 
-#, fuzzy
 msgctxt "model:ir.ui.menu,name:menu_configuration"
 msgid "Configuration"
-msgstr "Instellingen"
+msgstr "Nastavitve"
 
 msgctxt "model:ir.ui.menu,name:menu_purchase"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabava"
 
 msgctxt "model:ir.ui.menu,name:menu_purchase_configuration"
 msgid "Purchase Configuration"
-msgstr ""
+msgstr "Konfiguracija"
 
 msgctxt "model:ir.ui.menu,name:menu_purchase_form"
 msgid "Purchases"
-msgstr ""
+msgstr "Nabavni nalogi"
 
-#, fuzzy
 msgctxt "model:ir.ui.menu,name:menu_reporting"
 msgid "Reporting"
-msgstr "Rapportage"
+msgstr "Poročila"
 
 msgctxt "model:ir.ui.menu,name:menu_supplier"
 msgid "Parties associated to Purchases"
-msgstr ""
+msgstr "Stranke pri nabavi"
 
 msgctxt "model:purchase.configuration,name:"
 msgid "Purchase Configuration"
-msgstr ""
+msgstr "Nabavna konfiguracija"
 
-#, fuzzy
 msgctxt "model:purchase.handle.invoice.exception.ask,name:"
 msgid "Handle Invoice Exception"
-msgstr "Factuur uitzondering vragen"
+msgstr "Obravnava pridržanih računov"
 
-#, fuzzy
 msgctxt "model:purchase.handle.shipment.exception.ask,name:"
 msgid "Handle Shipment Exception"
-msgstr "Afleveren uitzondering vragen"
+msgstr "Obravnava pridržanih prevzemnic"
 
 msgctxt "model:purchase.line,name:"
 msgid "Purchase Line"
-msgstr ""
+msgstr "Nabavna postavka"
 
 msgctxt "model:purchase.line-account.tax,name:"
 msgid "Purchase Line - Tax"
-msgstr ""
+msgstr "Nabavna postavka - Davek"
 
 msgctxt "model:purchase.line-ignored-stock.move,name:"
 msgid "Purchase Line - Ignored Move"
-msgstr ""
+msgstr "Nabavna postavka - Prezrt promet"
 
 msgctxt "model:purchase.line-recreated-stock.move,name:"
 msgid "Purchase Line - Ignored Move"
-msgstr ""
+msgstr "Nabavna postavka - Poustvarjen promet"
 
 msgctxt "model:purchase.product_supplier,name:"
 msgid "Product Supplier"
-msgstr ""
+msgstr "Dobavitelj izdelkov"
 
 msgctxt "model:purchase.product_supplier.price,name:"
 msgid "Product Supplier Price"
-msgstr ""
+msgstr "Dobaviteljeva cena"
 
 msgctxt "model:purchase.purchase,name:"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalog"
 
 msgctxt "model:purchase.purchase-account.invoice,name:"
 msgid "Purchase - Invoice"
-msgstr ""
+msgstr "Nabavni nalog - Račun"
 
 msgctxt "model:purchase.purchase-ignored-account.invoice,name:"
 msgid "Purchase - Ignored Invoice"
-msgstr ""
+msgstr "Nabavni nalog - Prezrt račun"
 
 msgctxt "model:purchase.purchase-recreated-account.invoice,name:"
 msgid "Purchase - Recreated Invoice"
-msgstr ""
+msgstr "Nabavni nalog - Poustvarjeni račun"
 
 msgctxt "model:res.group,name:group_purchase"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabava"
 
 msgctxt "model:res.group,name:group_purchase_admin"
 msgid "Purchase Administrator"
-msgstr ""
+msgstr "Nabava - vodenje"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Amount"
-msgstr "Bedrag"
+msgstr "Znesek"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Date:"
 msgstr "Datum:"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Description"
-msgstr "Specificatie"
+msgstr "Opis"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Description:"
-msgstr "Betreft:"
+msgstr "Opis:"
 
 msgctxt "odt:purchase.purchase:"
 msgid "Draft Purchase Order"
-msgstr ""
+msgstr "Osnutek nabavnega naloga"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "E-Mail:"
-msgstr "E-mail:"
+msgstr "E-pošta:"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Phone:"
-msgstr "Telefoon:"
+msgstr "Telefon:"
 
 msgctxt "odt:purchase.purchase:"
 msgid "Purchase Order N°:"
-msgstr ""
+msgstr "Nabavni nalog št.:"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Quantity"
-msgstr "Hoeveelheid"
+msgstr "Količina"
 
 msgctxt "odt:purchase.purchase:"
 msgid "Request for Quotation N°:"
-msgstr ""
+msgstr "Zahtevek za ponudbo št.:"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Taxes"
-msgstr "Belastingen"
+msgstr "Davki"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Taxes:"
-msgstr "Belastingen:"
+msgstr "Davki:"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Total (excl. taxes):"
-msgstr "Totaal (excl. belasting):"
+msgstr "Skupaj (brez davkov):"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Total:"
-msgstr "Totaal:"
+msgstr "Skupaj:"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "Unit Price"
-msgstr "Eenheidsprijs"
+msgstr "Cena"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "VAT Number:"
-msgstr "BTW-nummer:"
+msgstr "DDV številka:"
 
-#, fuzzy
 msgctxt "odt:purchase.purchase:"
 msgid "VAT:"
-msgstr "BTW:"
+msgstr "DDV:"
 
 msgctxt "selection:account.invoice,purchase_exception_state:"
 msgid ""
 msgstr ""
 
-#, fuzzy
 msgctxt "selection:account.invoice,purchase_exception_state:"
 msgid "Ignored"
-msgstr "Genegeerd"
+msgstr "Prezrto"
 
-#, fuzzy
 msgctxt "selection:account.invoice,purchase_exception_state:"
 msgid "Recreated"
-msgstr "Opnieuw aangemaakt"
+msgstr "Poustvarjeno"
 
 msgctxt "selection:purchase.configuration,purchase_invoice_method:"
 msgid "Based On Order"
-msgstr ""
+msgstr "Na podlagi naloga"
 
 msgctxt "selection:purchase.configuration,purchase_invoice_method:"
 msgid "Based On Shipment"
-msgstr ""
+msgstr "Na podlagi prevzemnice"
 
-#, fuzzy
 msgctxt "selection:purchase.configuration,purchase_invoice_method:"
 msgid "Manual"
-msgstr "Handmatig"
+msgstr "Ročno"
 
-#, fuzzy
 msgctxt "selection:purchase.line,type:"
 msgid "Comment"
-msgstr "Opmerking"
+msgstr "Opomba"
 
-#, fuzzy
 msgctxt "selection:purchase.line,type:"
 msgid "Line"
-msgstr "Regel"
+msgstr "Postavka"
 
-#, fuzzy
 msgctxt "selection:purchase.line,type:"
 msgid "Subtotal"
-msgstr "Subtotaal"
+msgstr "Vmesna vsota"
 
-#, fuzzy
 msgctxt "selection:purchase.line,type:"
 msgid "Title"
-msgstr "Titel"
+msgstr "Napis"
 
 msgctxt "selection:purchase.purchase,invoice_method:"
 msgid "Based On Order"
-msgstr ""
+msgstr "Na podlagi naloga"
 
 msgctxt "selection:purchase.purchase,invoice_method:"
 msgid "Based On Shipment"
-msgstr ""
+msgstr "Na podlagi pošiljke"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,invoice_method:"
 msgid "Manual"
-msgstr "Handmatig"
+msgstr "Ročno"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,invoice_state:"
 msgid "Exception"
-msgstr "Uitzondering"
+msgstr "Pridržano"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,invoice_state:"
 msgid "None"
-msgstr "Geen"
+msgstr "Brez"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,invoice_state:"
 msgid "Paid"
-msgstr "Betaald"
+msgstr "Plačano"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,invoice_state:"
 msgid "Waiting"
-msgstr "In afwachting"
+msgstr "Čakajoče"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,shipment_state:"
 msgid "Exception"
-msgstr "Uitzondering"
+msgstr "Pridržano"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,shipment_state:"
 msgid "None"
-msgstr "Geen"
+msgstr "Brez"
 
 msgctxt "selection:purchase.purchase,shipment_state:"
 msgid "Received"
-msgstr ""
+msgstr "Prejeto"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,shipment_state:"
 msgid "Waiting"
-msgstr "In afwachting"
+msgstr "Čakajoče"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,state:"
 msgid "Canceled"
-msgstr "Geannuleerd"
+msgstr "Preklicano"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,state:"
 msgid "Confirmed"
-msgstr "Bevestigd"
+msgstr "Potrjeno"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,state:"
 msgid "Done"
-msgstr "Klaar"
+msgstr "Zaključeno"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,state:"
 msgid "Draft"
-msgstr "Concept"
+msgstr "Osnutek"
 
-#, fuzzy
 msgctxt "selection:purchase.purchase,state:"
 msgid "Quotation"
-msgstr "Offerte"
+msgstr "Ponudba"
 
 msgctxt "selection:stock.move,purchase_exception_state:"
 msgid ""
 msgstr ""
 
-#, fuzzy
 msgctxt "selection:stock.move,purchase_exception_state:"
 msgid "Ignored"
-msgstr "Genegeerd"
+msgstr "Prezrto"
 
-#, fuzzy
 msgctxt "selection:stock.move,purchase_exception_state:"
 msgid "Recreated"
-msgstr "Opnieuw aangemaakt"
+msgstr "Poustvarjeno"
 
-#, fuzzy
 msgctxt "view:product.product:"
 msgid "Products"
-msgstr "Producten"
+msgstr "Izdelki"
 
 msgctxt "view:product.template:"
 msgid "Suppliers"
-msgstr ""
+msgstr "Dobavitelji"
 
 msgctxt "view:purchase.configuration:"
 msgid "Purchase Configuration"
-msgstr ""
+msgstr "Nabavna konfiguracija"
 
-#, fuzzy
 msgctxt "view:purchase.handle.invoice.exception.ask:"
 msgid "Choose invoices to recreate"
-msgstr "Kies facturen om opnieuw aan te maken"
+msgstr "Izbor računov za poustvaritev"
 
-#, fuzzy
 msgctxt "view:purchase.handle.invoice.exception.ask:"
 msgid "Handle Invoice Exception"
-msgstr "Factuuruitzondering afhandelen"
+msgstr "Obravnava pridržanih računov"
 
-#, fuzzy
 msgctxt "view:purchase.handle.shipment.exception.ask:"
 msgid "Choose move to recreate"
-msgstr "Kies boeking om opnieuw aan te maken"
+msgstr "Izbor prometa za poustvaritev"
 
-#, fuzzy
 msgctxt "view:purchase.handle.shipment.exception.ask:"
 msgid "Handle shipment Exception"
-msgstr "Zendinguitzondering afhandelen"
+msgstr "Obravnava pridržanih prevzemnic"
 
-#, fuzzy
 msgctxt "view:purchase.line:"
 msgid "General"
-msgstr "Algemeen"
+msgstr "Splošno"
 
-#, fuzzy
 msgctxt "view:purchase.line:"
 msgid "Lines"
-msgstr "Regels"
+msgstr "Postavke"
 
-#, fuzzy
 msgctxt "view:purchase.line:"
 msgid "Notes"
-msgstr "Aantekeningen"
+msgstr "Opombe"
 
 msgctxt "view:purchase.line:"
 msgid "Purchase Line"
-msgstr ""
+msgstr "Nabavna postavka"
 
 msgctxt "view:purchase.line:"
 msgid "Purchase Lines"
-msgstr ""
+msgstr "Nabavne postavke"
 
 msgctxt "view:purchase.product_supplier.price:"
 msgid "Product Supplier Price"
-msgstr ""
+msgstr "Dobaviteljeva cena"
 
 msgctxt "view:purchase.product_supplier.price:"
 msgid "Product Supplier Prices"
-msgstr ""
+msgstr "Dobaviteljeve cene"
 
 msgctxt "view:purchase.product_supplier:"
 msgid "Product Supplier"
-msgstr ""
+msgstr "Dobavitelj izdelkov"
 
 msgctxt "view:purchase.product_supplier:"
 msgid "Product Suppliers"
-msgstr ""
+msgstr "Dobavitelji izdelkov"
 
-#, fuzzy
 msgctxt "view:purchase.purchase:"
 msgid "Cancel"
-msgstr "Annuleren"
+msgstr "Prekliči"
 
-#, fuzzy
 msgctxt "view:purchase.purchase:"
 msgid "Confirm"
-msgstr "Bevestig"
+msgstr "Potrditev"
 
-#, fuzzy
 msgctxt "view:purchase.purchase:"
 msgid "Draft"
-msgstr "Concept"
+msgstr "Osnutek"
 
-#, fuzzy
 msgctxt "view:purchase.purchase:"
 msgid "Handle Invoice Exception"
-msgstr "Factuuruitzondering afhandelen"
+msgstr "Obravnava pridržanih računov"
 
-#, fuzzy
 msgctxt "view:purchase.purchase:"
 msgid "Handle Shipment Exception"
-msgstr "Zendinguitzondering afhandelen"
+msgstr "Obravnava pridržanih prevzemnic"
 
-#, fuzzy
 msgctxt "view:purchase.purchase:"
 msgid "Invoices"
-msgstr "Verkoopfacturen"
+msgstr "Računi"
 
-#, fuzzy
 msgctxt "view:purchase.purchase:"
 msgid "Other Info"
-msgstr "Aanvullende informatie"
+msgstr "Drugo"
 
 msgctxt "view:purchase.purchase:"
 msgid "Purchase"
-msgstr ""
+msgstr "Nabavni nalog"
 
 msgctxt "view:purchase.purchase:"
 msgid "Purchases"
-msgstr ""
+msgstr "Nabavni nalogi"
 
 msgctxt "view:purchase.purchase:"
 msgid "Quote"
-msgstr ""
+msgstr "Ponudba"
 
-#, fuzzy
 msgctxt "view:purchase.purchase:"
 msgid "Shipments"
-msgstr "Leveringen"
+msgstr "Pošiljke"
 
-#, fuzzy
 msgctxt "view:stock.move:"
 msgid "Moves"
-msgstr "Boekingen"
+msgstr "Promet"
 
-#, fuzzy
 msgctxt "wizard_button:purchase.handle.invoice.exception,ask,end:"
 msgid "Cancel"
-msgstr "Annuleren"
+msgstr "Prekliči"
 
-#, fuzzy
 msgctxt "wizard_button:purchase.handle.invoice.exception,ask,handle:"
 msgid "Ok"
-msgstr "Oké"
+msgstr "V redu"
 
-#, fuzzy
 msgctxt "wizard_button:purchase.handle.shipment.exception,ask,end:"
 msgid "Cancel"
-msgstr "Annuleren"
+msgstr "Prekliči"
 
-#, fuzzy
 msgctxt "wizard_button:purchase.handle.shipment.exception,ask,handle:"
 msgid "Ok"
-msgstr "Oké"
+msgstr "V redu"
 
-#, fuzzy
 msgctxt "wizard_button:stock.product_quantities_warehouse,start,end:"
 msgid "Cancel"
-msgstr "Annuleren"
+msgstr "Prekliči"
 
-#, fuzzy
 msgctxt "wizard_button:stock.product_quantities_warehouse,start,open_:"
 msgid "Open"
-msgstr "Open"
+msgstr "Odpri"
diff --git a/product.py b/product.py
new file mode 100644
index 0000000..d4164ba
--- /dev/null
+++ b/product.py
@@ -0,0 +1,276 @@
+#This file is part of Tryton.  The COPYRIGHT file at the top level of
+#this repository contains the full copyright notices and license terms.
+import datetime
+from sql import Literal
+from sql.aggregate import Count
+
+from trytond.model import ModelView, ModelSQL, fields
+from trytond.pyson import Eval, If
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
+from trytond import backend
+
+__all__ = ['Template', 'Product', 'ProductSupplier', 'ProductSupplierPrice']
+__metaclass__ = PoolMeta
+
+
+class Template:
+    __name__ = "product.template"
+    purchasable = fields.Boolean('Purchasable', states={
+            'readonly': ~Eval('active', True),
+            }, depends=['active'])
+    product_suppliers = fields.One2Many('purchase.product_supplier',
+        'product', 'Suppliers', states={
+            'readonly': ~Eval('active', True),
+            'invisible': (~Eval('purchasable', False)
+                | ~Eval('context', {}).get('company')),
+            }, depends=['active', 'purchasable'])
+    purchase_uom = fields.Many2One('product.uom', 'Purchase UOM', states={
+            'readonly': ~Eval('active'),
+            'invisible': ~Eval('purchasable'),
+            'required': Eval('purchasable', False),
+            },
+        domain=[('category', '=', Eval('default_uom_category'))],
+        on_change_with=['default_uom', 'purchase_uom', 'purchasable'],
+        depends=['active', 'purchasable', 'default_uom_category'])
+
+    @classmethod
+    def __setup__(cls):
+        super(Template, cls).__setup__()
+        cls._error_messages.update({
+                'change_purchase_uom': ('Purchase prices are based '
+                    'on the purchase uom, are you sure to change it?'),
+                })
+        required = ~Eval('account_category') & Eval('purchasable', False)
+        if not cls.account_expense.states.get('required'):
+            cls.account_expense.states['required'] = required
+        else:
+            cls.account_expense.states['required'] = (
+                cls.account_expense.states['required'] | required)
+        if 'account_category' not in cls.account_expense.depends:
+            cls.account_expense.depends.append('account_category')
+        if 'purchasable' not in cls.account_expense.depends:
+            cls.account_expense.depends.append('purchasable')
+
+    def on_change_with_purchase_uom(self):
+        if self.default_uom:
+            if self.purchase_uom:
+                if self.default_uom.category == self.purchase_uom.category:
+                    return self.purchase_uom.id
+                else:
+                    return self.default_uom.id
+            else:
+                return self.default_uom.id
+
+    @classmethod
+    def write(cls, templates, vals):
+        if vals.get("purchase_uom"):
+            for template in templates:
+                if not template.purchase_uom:
+                    continue
+                if template.purchase_uom.id == vals["purchase_uom"]:
+                    continue
+                for product in template.products:
+                    if not product.product_suppliers:
+                        continue
+                    cls.raise_user_warning(
+                            '%s at product_template' % template.id,
+                            'change_purchase_uom')
+        super(Template, cls).write(templates, vals)
+
+
+class Product:
+    __name__ = 'product.product'
+
+    @classmethod
+    def get_purchase_price(cls, products, quantity=0):
+        '''
+        Return purchase price for product ids.
+        The context that can have as keys:
+            uom: the unit of measure
+            supplier: the supplier party id
+            currency: the currency id for the returned price
+        '''
+        pool = Pool()
+        Uom = pool.get('product.uom')
+        User = pool.get('res.user')
+        Currency = pool.get('currency.currency')
+        Date = pool.get('ir.date')
+
+        today = Date.today()
+        res = {}
+
+        uom = None
+        if Transaction().context.get('uom'):
+            uom = Uom(Transaction().context['uom'])
+
+        currency = None
+        if Transaction().context.get('currency'):
+            currency = Currency(Transaction().context['currency'])
+
+        user = User(Transaction().user)
+
+        for product in products:
+            res[product.id] = product.cost_price
+            default_uom = product.default_uom
+            default_currency = (user.company.currency if user.company
+                else None)
+            if not uom:
+                uom = default_uom
+            if (Transaction().context.get('supplier')
+                    and product.product_suppliers):
+                supplier_id = Transaction().context['supplier']
+                for product_supplier in product.product_suppliers:
+                    if product_supplier.party.id == supplier_id:
+                        for price in product_supplier.prices:
+                            if Uom.compute_qty(product.purchase_uom,
+                                    price.quantity, uom) <= quantity:
+                                res[product.id] = price.unit_price
+                                default_uom = product.purchase_uom
+                                default_currency = product_supplier.currency
+                        break
+            res[product.id] = Uom.compute_price(default_uom, res[product.id],
+                uom)
+            if currency and default_currency:
+                date = Transaction().context.get('purchase_date') or today
+                with Transaction().set_context(date=date):
+                    res[product.id] = Currency.compute(default_currency,
+                        res[product.id], currency, round=False)
+        return res
+
+
+class ProductSupplier(ModelSQL, ModelView):
+    'Product Supplier'
+    __name__ = 'purchase.product_supplier'
+    product = fields.Many2One('product.template', 'Product', required=True,
+            ondelete='CASCADE', select=True)
+    party = fields.Many2One('party.party', 'Supplier', required=True,
+            ondelete='CASCADE', select=True, on_change=['party'])
+    name = fields.Char('Name', size=None, translate=True, select=True)
+    code = fields.Char('Code', size=None, select=True)
+    sequence = fields.Integer('Sequence')
+    prices = fields.One2Many('purchase.product_supplier.price',
+            'product_supplier', 'Prices')
+    company = fields.Many2One('company.company', 'Company', required=True,
+        ondelete='CASCADE', select=True,
+        domain=[
+            ('id', If(Eval('context', {}).contains('company'), '=', '!='),
+                Eval('context', {}).get('company', -1)),
+            ])
+    delivery_time = fields.Integer('Delivery Time', help="In number of days")
+    currency = fields.Many2One('currency.currency', 'Currency', required=True,
+        ondelete='RESTRICT')
+
+    @classmethod
+    def __setup__(cls):
+        super(ProductSupplier, cls).__setup__()
+        cls._order.insert(0, ('sequence', 'ASC'))
+
+    @classmethod
+    def __register__(cls, module_name):
+        TableHandler = backend.get('TableHandler')
+        cursor = Transaction().cursor
+        table = TableHandler(cursor, cls, module_name)
+        sql_table = cls.__table__()
+
+        # Migration from 2.2 new field currency
+        created_currency = table.column_exist('currency')
+
+        super(ProductSupplier, cls).__register__(module_name)
+
+        # Migration from 2.2 fill currency
+        if not created_currency:
+            Company = Pool().get('company.company')
+            company = Company.__table__()
+            limit = cursor.IN_MAX
+            cursor.execute(*sql_table.select(Count(sql_table.id)))
+            product_supplier_count, = cursor.fetchone()
+            for offset in range(0, product_supplier_count, limit):
+                cursor.execute(*sql_table.join(company,
+                        condition=sql_table.company == company.id
+                        ).select(sql_table.id, company.currency,
+                        order_by=sql_table.id,
+                        limit=limit, offset=offset))
+                for product_supplier_id, currency_id in cursor.fetchall():
+                    cursor.execute(*sql_table.update(
+                            columns=[sql_table.currency],
+                            values=[currency_id],
+                            where=sql_table.id == product_supplier_id))
+
+        # Migration from 2.4: drop required on sequence
+        table.not_null_action('sequence', action='remove')
+
+        # Migration from 2.6: drop required on delivery_time
+        table.not_null_action('delivery_time', action='remove')
+
+    @staticmethod
+    def order_sequence(tables):
+        table, _ = tables[None]
+        return [table.sequence == None, table.sequence]
+
+    @staticmethod
+    def default_company():
+        return Transaction().context.get('company')
+
+    @staticmethod
+    def default_currency():
+        Company = Pool().get('company.company')
+        if Transaction().context.get('company'):
+            company = Company(Transaction().context['company'])
+            return company.currency.id
+
+    def on_change_party(self):
+        cursor = Transaction().cursor
+        changes = {
+            'currency': self.default_currency(),
+            }
+        if self.party:
+            table = self.__table__()
+            cursor.execute(*table.select(table.currency,
+                    where=table.party == self.party.id,
+                    group_by=table.currency,
+                    order_by=Count(Literal(1)).desc))
+            row = cursor.fetchone()
+            if row:
+                changes['currency'], = row
+        return changes
+
+    def compute_supply_date(self, date=None):
+        '''
+        Compute the supply date for the Product Supplier at the given date
+        '''
+        Date = Pool().get('ir.date')
+
+        if not date:
+            date = Date.today()
+        if self.delivery_time is None:
+            return datetime.date.max
+        return date + datetime.timedelta(self.delivery_time)
+
+    def compute_purchase_date(self, date):
+        '''
+        Compute the purchase date for the Product Supplier at the given date
+        '''
+        Date = Pool().get('ir.date')
+
+        if self.delivery_time is None:
+            return Date.today()
+        return date - datetime.timedelta(self.delivery_time)
+
+
+class ProductSupplierPrice(ModelSQL, ModelView):
+    'Product Supplier Price'
+    __name__ = 'purchase.product_supplier.price'
+    product_supplier = fields.Many2One('purchase.product_supplier',
+            'Supplier', required=True, ondelete='CASCADE')
+    quantity = fields.Float('Quantity', required=True, help='Minimal quantity')
+    unit_price = fields.Numeric('Unit Price', required=True, digits=(16, 4))
+
+    @classmethod
+    def __setup__(cls):
+        super(ProductSupplierPrice, cls).__setup__()
+        cls._order.insert(0, ('quantity', 'ASC'))
+
+    @staticmethod
+    def default_quantity():
+        return 0.0
diff --git a/purchase.odt b/purchase.odt
index 7c6784e..95c53f8 100644
Binary files a/purchase.odt and b/purchase.odt differ
diff --git a/purchase.py b/purchase.py
index 4e30c24..1abdd58 100644
--- a/purchase.py
+++ b/purchase.py
@@ -3,29 +3,31 @@
 import datetime
 from itertools import chain
 from decimal import Decimal
+from sql import Table, Literal
+from sql.functions import Overlay, Position
+from sql.aggregate import Count
+
 from trytond.model import Workflow, ModelView, ModelSQL, fields
 from trytond.modules.company import CompanyReport
 from trytond.wizard import Wizard, StateAction, StateView, StateTransition, \
     Button
-from trytond.backend import TableHandler
+from trytond import backend
 from trytond.pyson import Eval, Bool, If, PYSONEncoder, Id
 from trytond.transaction import Transaction
 from trytond.pool import Pool, PoolMeta
 
 __all__ = ['Purchase', 'PurchaseInvoice', 'PurchaseIgnoredInvoice',
     'PurchaseRecreadtedInvoice', 'PurchaseLine', 'PurchaseLineTax',
-    'PurchaseLineIgnoredMove',
-    'PurchaseLineRecreatedMove', 'PurchaseReport', 'Template', 'Product',
-    'ProductSupplier', 'ProductSupplierPrice', 'ShipmentIn',
-    'ShipmentInReturn', 'Move', 'OpenSupplier', 'HandleShipmentExceptionAsk',
-    'HandleShipmentException', 'HandleInvoiceExceptionAsk',
-    'HandleInvoiceException']
+    'PurchaseLineIgnoredMove', 'PurchaseLineRecreatedMove', 'PurchaseReport',
+    'OpenSupplier', 'HandleShipmentExceptionAsk', 'HandleShipmentException',
+    'HandleInvoiceExceptionAsk', 'HandleInvoiceException']
 __metaclass__ = PoolMeta
 
 _STATES = {
     'readonly': Eval('state') != 'draft',
     }
 _DEPENDS = ['state']
+_ZERO = Decimal(0)
 
 
 class Purchase(Workflow, ModelSQL, ModelView):
@@ -38,7 +40,7 @@ class Purchase(Workflow, ModelSQL, ModelView):
             },
         domain=[
             ('id', If(Eval('context', {}).contains('company'), '=', '!='),
-                Eval('context', {}).get('company', 0)),
+                Eval('context', {}).get('company', -1)),
             ],
         depends=['state'], select=True)
     reference = fields.Char('Reference', size=None, readonly=True, select=True)
@@ -85,19 +87,19 @@ class Purchase(Workflow, ModelSQL, ModelView):
     comment = fields.Text('Comment')
     untaxed_amount = fields.Function(fields.Numeric('Untaxed',
             digits=(16, Eval('currency_digits', 2)),
-            depends=['currency_digits']), 'get_untaxed_amount')
+            depends=['currency_digits']), 'get_amount')
     untaxed_amount_cache = fields.Numeric('Untaxed Cache',
         digits=(16, Eval('currency_digits', 2)),
         depends=['currency_digits'])
     tax_amount = fields.Function(fields.Numeric('Tax',
             digits=(16, Eval('currency_digits', 2)),
-            depends=['currency_digits']), 'get_tax_amount')
+            depends=['currency_digits']), 'get_amount')
     tax_amount_cache = fields.Numeric('Tax Cache',
         digits=(16, Eval('currency_digits', 2)),
         depends=['currency_digits'])
     total_amount = fields.Function(fields.Numeric('Total',
             digits=(16, Eval('currency_digits', 2)),
-            depends=['currency_digits']), 'get_total_amount')
+            depends=['currency_digits']), 'get_amount')
     total_amount_cache = fields.Numeric('Total Cache',
         digits=(16, Eval('currency_digits', 2)),
         depends=['currency_digits'])
@@ -193,18 +195,34 @@ class Purchase(Workflow, ModelSQL, ModelView):
 
     @classmethod
     def __register__(cls, module_name):
+        TableHandler = backend.get('TableHandler')
         cursor = Transaction().cursor
+        model_data = Table('ir_model_data')
+        model_field = Table('ir_model_field')
+        sql_table = cls.__table__()
+
         # Migration from 1.2: packing renamed into shipment
-        cursor.execute("UPDATE ir_model_data "
-            "SET fs_id = REPLACE(fs_id, 'packing', 'shipment') "
-            "WHERE fs_id like '%%packing%%' AND module = %s",
-            (module_name,))
-        cursor.execute("UPDATE ir_model_field "
-            "SET relation = REPLACE(relation, 'packing', 'shipment'), "
-                "name = REPLACE(name, 'packing', 'shipment') "
-            "WHERE (relation like '%%packing%%' "
-                "OR name like '%%packing%%') AND module = %s",
-            (module_name,))
+        cursor.execute(*model_data.update(
+                columns=[model_data.fs_id],
+                values=[Overlay(model_data.fs_id, 'shipment',
+                        Position('packing', model_data.fs_id),
+                        len('packing'))],
+                where=model_data.fs_id.like('%packing%')
+                & (model_data.module == module_name)))
+        cursor.execute(*model_field.update(
+                columns=[model_field.relation],
+                values=[Overlay(model_field.relation, 'shipment',
+                        Position('packing', model_field.relation),
+                        len('packing'))],
+                where=model_field.relation.like('%packing%')
+                & (model_field.module == module_name)))
+        cursor.execute(*model_field.update(
+                columns=[model_field.name],
+                values=[Overlay(model_field.name, 'shipment',
+                        Position('packing', model_field.name),
+                        len('packing'))],
+                where=model_field.name.like('%packing%')
+                & (model_field.module == module_name)))
         table = TableHandler(cursor, cls, module_name)
         table.column_rename('packing_state', 'shipment_state')
 
@@ -212,9 +230,10 @@ class Purchase(Workflow, ModelSQL, ModelView):
 
         # Migration from 1.2: rename packing to shipment in
         # invoice_method values
-        cursor.execute("UPDATE " + cls._table + " "
-            "SET invoice_method = 'shipment' "
-            "WHERE invoice_method = 'packing'")
+        cursor.execute(*sql_table.update(
+                columns=[sql_table.invoice_method],
+                values=['shipment'],
+                where=sql_table.invoice_method == 'packing'))
 
         table = TableHandler(cursor, cls, module_name)
         # Migration from 2.2: warehouse is no more required
@@ -285,6 +304,7 @@ class Purchase(Workflow, ModelSQL, ModelView):
         PaymentTerm = pool.get('account.invoice.payment_term')
         Currency = pool.get('currency.currency')
         cursor = Transaction().cursor
+        table = self.__table__()
         changes = {
             'invoice_address': None,
             'payment_term': None,
@@ -298,13 +318,13 @@ class Purchase(Workflow, ModelSQL, ModelView):
             if self.party.supplier_payment_term:
                 payment_term = self.party.supplier_payment_term
 
-            subquery = cursor.limit_clause('SELECT currency '
-                'FROM "' + self._table + '" '
-                'WHERE party = %s '
-                'ORDER BY id DESC', 10)
-            cursor.execute('SELECT currency FROM (' + subquery + ') AS p '
-                'GROUP BY currency '
-                'ORDER BY COUNT(1) DESC', (self.party.id,))
+            subquery = table.select(table.currency,
+                where=table.party == self.party.id,
+                order_by=table.id,
+                limit=10)
+            cursor.execute(*subquery.select(subquery.currency,
+                    group_by=subquery.currency,
+                    order_by=Count(Literal(1)).desc))
             row = cursor.fetchone()
             if row:
                 currency_id, = row
@@ -387,25 +407,11 @@ class Purchase(Workflow, ModelSQL, ModelView):
                 changes['total_amount'])
         return changes
 
-    def get_untaxed_amount(self, name):
-        '''
-        Return the untaxed amount for each purchases
-        '''
-        if (self.state in self._states_cached
-                and self.untaxed_amount_cache is not None):
-            return self.untaxed_amount_cache
-        amount = sum((l.amount for l in self.lines
-                if l.type == 'line'), Decimal(0))
-        return self.currency.round(amount)
-
-    def get_tax_amount(self, name):
+    def get_tax_amount(self):
         pool = Pool()
         Tax = pool.get('account.tax')
         Invoice = pool.get('account.invoice')
 
-        if (self.state in self._states_cached
-                and self.tax_amount_cache is not None):
-            return self.tax_amount_cache
         context = self.get_tax_context()
         taxes = {}
         for line in self.lines:
@@ -421,15 +427,39 @@ class Purchase(Workflow, ModelSQL, ModelView):
                     taxes[key] = val['amount']
                 else:
                     taxes[key] += val['amount']
-        amount = sum((self.currency.round(tax) for tax in taxes.itervalues()),
-            Decimal(0))
-        return self.currency.round(amount)
+        return sum((self.currency.round(tax) for tax in taxes.values()), _ZERO)
+
+    @classmethod
+    def get_amount(cls, purchases, names):
+        untaxed_amount = {}
+        tax_amount = {}
+        total_amount = {}
 
-    def get_total_amount(self, name):
-        if (self.state in self._states_cached
-                and self.total_amount_cache is not None):
-            return self.total_amount_cache
-        return self.currency.round(self.untaxed_amount + self.tax_amount)
+        for purchase in purchases:
+            if (purchase.state in cls._states_cached
+                    and purchase.untaxed_amount_cache is not None
+                    and purchase.tax_amount_cache is not None
+                    and purchase.total_amount_cache is not None):
+                untaxed_amount[purchase.id] = purchase.untaxed_amount_cache
+                tax_amount[purchase.id] = purchase.tax_amount_cache
+                total_amount[purchase.id] = purchase.total_amount_cache
+            else:
+                untaxed_amount[purchase.id] = sum(
+                    (line.amount for line in purchase.lines
+                        if line.type == 'line'), _ZERO)
+                tax_amount[purchase.id] = purchase.get_tax_amount()
+                total_amount[purchase.id] = (
+                    untaxed_amount[purchase.id] + tax_amount[purchase.id])
+
+        result = {
+            'untaxed_amount': untaxed_amount,
+            'tax_amount': tax_amount,
+            'total_amount': total_amount,
+            }
+        for key in result.keys():
+            if key not in names:
+                del result[key]
+        return result
 
     def get_invoice_state(self):
         '''
@@ -604,7 +634,6 @@ class Purchase(Workflow, ModelSQL, ModelView):
             return Invoice(
                 company=self.company,
                 type=invoice_type,
-                reference=self.reference,
                 journal=journal,
                 party=self.party,
                 invoice_address=self.invoice_address,
@@ -661,7 +690,6 @@ class Purchase(Workflow, ModelSQL, ModelView):
         with Transaction().set_user(0, set_context=True):
             return ShipmentInReturn(
                 company=self.company,
-                reference=self.reference,
                 from_location=self.warehouse.storage_location,
                 to_location=self.party.supplier_location,
                 )
@@ -788,9 +816,7 @@ class PurchaseLine(ModelSQL, ModelView):
     _rec_name = 'description'
     purchase = fields.Many2One('purchase.purchase', 'Purchase',
             ondelete='CASCADE', select=True, required=True)
-    sequence = fields.Integer('Sequence',
-        order_field='(%(table)s.sequence IS NULL) %(order)s, '
-        '%(table)s.sequence %(order)s')
+    sequence = fields.Integer('Sequence')
     type = fields.Selection([
         ('line', 'Line'),
         ('subtotal', 'Subtotal'),
@@ -838,7 +864,6 @@ class PurchaseLine(ModelSQL, ModelView):
                 []),
             'stock_date_end': Eval('_parent_purchase', {}).get(
                 'purchase_date'),
-            'purchasable': True,
             'stock_skip_warehouse': True,
             }, depends=['type'])
     product_uom_category = fields.Function(
@@ -900,30 +925,38 @@ class PurchaseLine(ModelSQL, ModelView):
         super(PurchaseLine, cls).__setup__()
         cls._order.insert(0, ('sequence', 'ASC'))
         cls._error_messages.update({
-                'supplier_location_required': ('Purchase "%(purchase)s" misses '
-                    'the supplier location for line "%(line)s".'),
-                'missing_account_expense': ('Product "%(product)s" of purchase '
-                    '%(purchase)s misses an expense account.'),
+                'supplier_location_required': ('Purchase "%(purchase)s" '
+                    'misses the supplier location for line "%(line)s".'),
+                'missing_account_expense': ('Product "%(product)s" of '
+                    'purchase %(purchase)s misses an expense account.'),
                 'missing_account_expense_property': ('Purchase "%(purchase)s" '
                     'misses an "account expense" default property.'),
                 })
 
     @classmethod
     def __register__(cls, module_name):
-        super(PurchaseLine, cls).__register__(module_name)
+        TableHandler = backend.get('TableHandler')
         cursor = Transaction().cursor
+        sql_table = cls.__table__()
+        super(PurchaseLine, cls).__register__(module_name)
         table = TableHandler(cursor, cls, module_name)
 
         # Migration from 1.0 comment change into note
         if table.column_exist('comment'):
-            cursor.execute('UPDATE "' + cls._table + '" '
-                'SET note = comment')
+            cursor.execute(*sql_table.update(
+                    columns=[sql_table.note],
+                    values=[sql_table.comment]))
             table.drop_column('comment', exception=True)
 
         # Migration from 2.4: drop required on sequence
         table.not_null_action('sequence', action='remove')
 
     @staticmethod
+    def order_sequence(tables):
+        table, _ = tables[None]
+        return [table.sequence == None, table.sequence]
+
+    @staticmethod
     def default_type():
         return 'line'
 
@@ -1006,7 +1039,7 @@ class PurchaseLine(ModelSQL, ModelView):
 
         with Transaction().set_context(self._get_context_purchase_price()):
             res['unit_price'] = Product.get_purchase_price([self.product],
-                self.quantity or 0)[self.product.id]
+                abs(self.quantity or 0))[self.product.id]
             if res['unit_price']:
                 res['unit_price'] = res['unit_price'].quantize(
                     Decimal(1) / 10 ** self.__class__.unit_price.digits[1])
@@ -1046,7 +1079,7 @@ class PurchaseLine(ModelSQL, ModelView):
 
         with Transaction().set_context(self._get_context_purchase_price()):
             res['unit_price'] = Product.get_purchase_price([self.product],
-                self.quantity or 0)[self.product.id]
+                abs(self.quantity or 0))[self.product.id]
             if res['unit_price']:
                 res['unit_price'] = res['unit_price'].quantize(
                     Decimal(1) / 10 ** self.__class__.unit_price.digits[1])
@@ -1166,6 +1199,7 @@ class PurchaseLine(ModelSQL, ModelView):
         invoice_line.product = self.product
         invoice_line.unit_price = self.unit_price
         invoice_line.taxes = self.taxes
+        invoice_line.invoice_type = invoice_type
         if self.product:
             invoice_line.account = self.product.account_expense_used
             if not invoice_line.account:
@@ -1282,531 +1316,6 @@ class PurchaseReport(CompanyReport):
     __name__ = 'purchase.purchase'
 
 
-class Template:
-    __name__ = "product.template"
-    purchasable = fields.Boolean('Purchasable', states={
-            'readonly': ~Eval('active', True),
-            }, depends=['active'])
-    product_suppliers = fields.One2Many('purchase.product_supplier',
-        'product', 'Suppliers', states={
-            'readonly': ~Eval('active', True),
-            'invisible': (~Eval('purchasable', False)
-                | ~Eval('context', {}).get('company', 0)),
-            }, depends=['active', 'purchasable'])
-    purchase_uom = fields.Many2One('product.uom', 'Purchase UOM', states={
-            'readonly': ~Eval('active'),
-            'invisible': ~Eval('purchasable'),
-            'required': Eval('purchasable', False),
-            },
-        domain=[('category', '=', Eval('default_uom_category'))],
-        on_change_with=['default_uom', 'purchase_uom', 'purchasable'],
-        depends=['active', 'purchasable', 'default_uom_category'])
-
-    @classmethod
-    def __setup__(cls):
-        super(Template, cls).__setup__()
-        cls._error_messages.update({
-                'change_purchase_uom': ('Purchase prices are based '
-                    'on the purchase uom, are you sure to change it?'),
-                })
-        required = ~Eval('account_category') & Eval('purchasable', False)
-        if not cls.account_expense.states.get('required'):
-            cls.account_expense.states['required'] = required
-        else:
-            cls.account_expense.states['required'] = (
-                cls.account_expense.states['required'] | required)
-        if 'account_category' not in cls.account_expense.depends:
-            cls.account_expense.depends.append('account_category')
-        if 'purchasable' not in cls.account_expense.depends:
-            cls.account_expense.depends.append('purchasable')
-
-    @staticmethod
-    def default_purchasable():
-        return Transaction().context.get('purchasable') or False
-
-    def on_change_with_purchase_uom(self):
-        if self.default_uom:
-            if self.purchase_uom:
-                if self.default_uom.category == self.purchase_uom.category:
-                    return self.purchase_uom.id
-                else:
-                    return self.default_uom.id
-            else:
-                return self.default_uom.id
-
-    @classmethod
-    def write(cls, templates, vals):
-        if vals.get("purchase_uom"):
-            for template in templates:
-                if not template.purchase_uom:
-                    continue
-                if template.purchase_uom.id == vals["purchase_uom"]:
-                    continue
-                for product in template.products:
-                    if not product.product_suppliers:
-                        continue
-                    cls.raise_user_warning(
-                            '%s at product_template' % template.id,
-                            'change_purchase_uom')
-        super(Template, cls).write(templates, vals)
-
-
-class Product:
-    __name__ = 'product.product'
-
-    @classmethod
-    def get_purchase_price(cls, products, quantity=0):
-        '''
-        Return purchase price for product ids.
-        The context that can have as keys:
-            uom: the unit of measure
-            supplier: the supplier party id
-            currency: the currency id for the returned price
-        '''
-        pool = Pool()
-        Uom = pool.get('product.uom')
-        User = pool.get('res.user')
-        Currency = pool.get('currency.currency')
-        Date = pool.get('ir.date')
-
-        today = Date.today()
-        res = {}
-
-        uom = None
-        if Transaction().context.get('uom'):
-            uom = Uom(Transaction().context['uom'])
-
-        currency = None
-        if Transaction().context.get('currency'):
-            currency = Currency(Transaction().context['currency'])
-
-        user = User(Transaction().user)
-
-        for product in products:
-            res[product.id] = product.cost_price
-            default_uom = product.default_uom
-            default_currency = (user.company.currency if user.company
-                else None)
-            if not uom:
-                uom = default_uom
-            if (Transaction().context.get('supplier')
-                    and product.product_suppliers):
-                supplier_id = Transaction().context['supplier']
-                for product_supplier in product.product_suppliers:
-                    if product_supplier.party.id == supplier_id:
-                        for price in product_supplier.prices:
-                            if Uom.compute_qty(product.purchase_uom,
-                                    price.quantity, uom) <= quantity:
-                                res[product.id] = price.unit_price
-                                default_uom = product.purchase_uom
-                                default_currency = product_supplier.currency
-                        break
-            res[product.id] = Uom.compute_price(default_uom, res[product.id],
-                uom)
-            if currency and default_currency:
-                date = Transaction().context.get('purchase_date') or today
-                with Transaction().set_context(date=date):
-                    res[product.id] = Currency.compute(default_currency,
-                        res[product.id], currency, round=False)
-        return res
-
-
-class ProductSupplier(ModelSQL, ModelView):
-    'Product Supplier'
-    __name__ = 'purchase.product_supplier'
-    product = fields.Many2One('product.template', 'Product', required=True,
-            ondelete='CASCADE', select=True)
-    party = fields.Many2One('party.party', 'Supplier', required=True,
-            ondelete='CASCADE', select=True, on_change=['party'])
-    name = fields.Char('Name', size=None, translate=True, select=True)
-    code = fields.Char('Code', size=None, select=True)
-    sequence = fields.Integer('Sequence',
-        order_field='(%(table)s.sequence IS NULL) %(order)s, '
-        '%(table)s.sequence %(order)s')
-    prices = fields.One2Many('purchase.product_supplier.price',
-            'product_supplier', 'Prices')
-    company = fields.Many2One('company.company', 'Company', required=True,
-        ondelete='CASCADE', select=True,
-        domain=[
-            ('id', If(Eval('context', {}).contains('company'), '=', '!='),
-                Eval('context', {}).get('company', 0)),
-            ])
-    delivery_time = fields.Integer('Delivery Time', help="In number of days")
-    currency = fields.Many2One('currency.currency', 'Currency', required=True,
-        ondelete='RESTRICT')
-
-    @classmethod
-    def __setup__(cls):
-        super(ProductSupplier, cls).__setup__()
-        cls._order.insert(0, ('sequence', 'ASC'))
-
-    @classmethod
-    def __register__(cls, module_name):
-        cursor = Transaction().cursor
-        table = TableHandler(cursor, cls, module_name)
-
-        # Migration from 2.2 new field currency
-        created_currency = table.column_exist('currency')
-
-        super(ProductSupplier, cls).__register__(module_name)
-
-        # Migration from 2.2 fill currency
-        if not created_currency:
-            Company = Pool().get('company.company')
-            limit = cursor.IN_MAX
-            cursor.execute('SELECT count(id) FROM "' + cls._table + '"')
-            product_supplier_count, = cursor.fetchone()
-            for offset in range(0, product_supplier_count, limit):
-                cursor.execute(cursor.limit_clause(
-                        'SELECT p.id, c.currency '
-                        'FROM "' + cls._table + '" AS p '
-                        'INNER JOIN "' + Company._table + '" AS c '
-                            'ON p.company = c.id '
-                        'ORDER BY p.id',
-                        limit, offset))
-                for product_supplier_id, currency_id in cursor.fetchall():
-                    cursor.execute('UPDATE "' + cls._table + '" '
-                        'SET currency = %s '
-                        'WHERE id = %s', (currency_id, product_supplier_id))
-
-        # Migration from 2.4: drop required on sequence
-        table.not_null_action('sequence', action='remove')
-
-        # Migration from 2.6: drop required on delivery_time
-        table.not_null_action('delivery_time', action='remove')
-
-    @staticmethod
-    def default_company():
-        return Transaction().context.get('company')
-
-    @staticmethod
-    def default_currency():
-        Company = Pool().get('company.company')
-        if Transaction().context.get('company'):
-            company = Company(Transaction().context['company'])
-            return company.currency.id
-
-    def on_change_party(self):
-        cursor = Transaction().cursor
-        changes = {
-            'currency': self.default_currency(),
-            }
-        if self.party:
-            cursor.execute('SELECT currency FROM "' + self._table + '" '
-                'WHERE party = %s '
-                'GROUP BY currency '
-                'ORDER BY COUNT(1) DESC', (self.party.id,))
-            row = cursor.fetchone()
-            if row:
-                changes['currency'], = row
-        return changes
-
-    def compute_supply_date(self, date=None):
-        '''
-        Compute the supply date for the Product Supplier at the given date
-        '''
-        Date = Pool().get('ir.date')
-
-        if not date:
-            date = Date.today()
-        if self.delivery_time is None:
-            return datetime.date.max
-        return date + datetime.timedelta(self.delivery_time)
-
-    def compute_purchase_date(self, date):
-        '''
-        Compute the purchase date for the Product Supplier at the given date
-        '''
-        Date = Pool().get('ir.date')
-
-        if self.delivery_time is None:
-            return Date.today()
-        return date - datetime.timedelta(self.delivery_time)
-
-
-class ProductSupplierPrice(ModelSQL, ModelView):
-    'Product Supplier Price'
-    __name__ = 'purchase.product_supplier.price'
-    product_supplier = fields.Many2One('purchase.product_supplier',
-            'Supplier', required=True, ondelete='CASCADE')
-    quantity = fields.Float('Quantity', required=True, help='Minimal quantity')
-    unit_price = fields.Numeric('Unit Price', required=True, digits=(16, 4))
-
-    @classmethod
-    def __setup__(cls):
-        super(ProductSupplierPrice, cls).__setup__()
-        cls._order.insert(0, ('quantity', 'ASC'))
-
-    @staticmethod
-    def default_quantity():
-        return 0.0
-
-
-class ShipmentIn:
-    __name__ = 'stock.shipment.in'
-
-    @classmethod
-    def __setup__(cls):
-        super(ShipmentIn, cls).__setup__()
-        add_remove = [
-            ('supplier', '=', Eval('supplier')),
-            ]
-        if not cls.incoming_moves.add_remove:
-            cls.incoming_moves.add_remove = add_remove
-        else:
-            cls.incoming_moves.add_remove = [
-                add_remove,
-                cls.incoming_moves.add_remove,
-                ]
-        if 'supplier' not in cls.incoming_moves.depends:
-            cls.incoming_moves.depends.append('supplier')
-
-        cls._error_messages.update({
-                'reset_move': ('You cannot reset to draft move "%s" because '
-                    'it was generated by a purchase.'),
-                })
-
-    @classmethod
-    def write(cls, shipments, vals):
-        pool = Pool()
-        Purchase = pool.get('purchase.purchase')
-        PurchaseLine = pool.get('purchase.line')
-
-        super(ShipmentIn, cls).write(shipments, vals)
-
-        if 'state' in vals and vals['state'] in ('received', 'cancel'):
-            purchases = []
-            move_ids = []
-            for shipment in shipments:
-                move_ids.extend([x.id for x in shipment.incoming_moves])
-
-            purchase_lines = PurchaseLine.search([
-                    ('moves', 'in', move_ids),
-                    ])
-            if purchase_lines:
-                for purchase_line in purchase_lines:
-                    if purchase_line.purchase not in purchases:
-                        purchases.append(purchase_line.purchase)
-
-            with Transaction().set_user(0, set_context=True):
-                purchases = Purchase.browse([p.id for p in purchases])
-                Purchase.process(purchases)
-
-    @classmethod
-    @ModelView.button
-    @Workflow.transition('draft')
-    def draft(cls, shipments):
-        PurchaseLine = Pool().get('purchase.line')
-        for shipment in shipments:
-            for move in shipment.incoming_moves:
-                if (move.state == 'cancel'
-                        and isinstance(move.origin, PurchaseLine)):
-                    cls.raise_user_error('reset_move', (move.rec_name,))
-
-        return super(ShipmentIn, cls).draft(shipments)
-
-
-class ShipmentInReturn:
-    __name__ = 'stock.shipment.in.return'
-
-    @classmethod
-    def __setup__(cls):
-        super(ShipmentInReturn, cls).__setup__()
-        cls._error_messages.update({
-                'reset_move': ('You cannot reset to draft a move generated '
-                    'by a purchase.'),
-                })
-
-    @classmethod
-    def write(cls, shipments, vals):
-        pool = Pool()
-        Purchase = pool.get('purchase.purchase')
-        PurchaseLine = pool.get('purchase.line')
-
-        super(ShipmentInReturn, cls).write(shipments, vals)
-
-        if 'state' in vals and vals['state'] == 'done':
-            move_ids = []
-            for shipment in shipments:
-                move_ids.extend([x.id for x in shipment.moves])
-
-            purchase_lines = PurchaseLine.search([
-                    ('moves', 'in', move_ids),
-                    ])
-            purchases = set()
-            if purchase_lines:
-                for purchase_line in purchase_lines:
-                    purchases.add(purchase_line.purchase)
-
-            with Transaction().set_user(0, set_context=True):
-                purchases = Purchase.browse([p.id for p in purchases])
-                Purchase.process(purchases)
-
-    @classmethod
-    @ModelView.button
-    @Workflow.transition('draft')
-    def draft(cls, shipments):
-        PurchaseLine = Pool().get('purchase.line')
-        for shipment in shipments:
-            for move in shipment.moves:
-                if (move.state == 'cancel'
-                        and isinstance(move.origin, PurchaseLine)):
-                    cls.raise_user_error('reset_move')
-
-        return super(ShipmentInReturn, cls).draft(shipments)
-
-
-class Move(ModelSQL, ModelView):
-    __name__ = 'stock.move'
-    purchase = fields.Function(fields.Many2One('purchase.purchase', 'Purchase',
-            states={
-                'invisible': ~Eval('purchase_visible', False),
-                },
-            depends=['purchase_visible']), 'get_purchase',
-        searcher='search_purchase')
-    purchase_quantity = fields.Function(fields.Float('Purchase Quantity',
-            digits=(16, Eval('unit_digits', 2)),
-            states={
-                'invisible': ~Eval('purchase_visible', False),
-                },
-            depends=['purchase_visible', 'unit_digits']),
-        'get_purchase_fields')
-    purchase_unit = fields.Function(fields.Many2One('product.uom',
-            'Purchase Unit', states={
-                'invisible': ~Eval('purchase_visible', False),
-                }, depends=['purchase_visible']), 'get_purchase_fields')
-    purchase_unit_digits = fields.Function(fields.Integer(
-        'Purchase Unit Digits'), 'get_purchase_fields')
-    purchase_unit_price = fields.Function(fields.Numeric('Purchase Unit Price',
-            digits=(16, 4), states={
-                'invisible': ~Eval('purchase_visible', False),
-                }, depends=['purchase_visible']), 'get_purchase_fields')
-    purchase_currency = fields.Function(fields.Many2One('currency.currency',
-            'Purchase Currency', states={
-                'invisible': ~Eval('purchase_visible', False),
-                }, depends=['purchase_visible']), 'get_purchase_fields')
-    purchase_visible = fields.Function(fields.Boolean('Purchase Visible',
-        on_change_with=['from_location']), 'on_change_with_purchase_visible')
-    supplier = fields.Function(fields.Many2One('party.party', 'Supplier'),
-        'get_supplier', searcher='search_supplier')
-    purchase_exception_state = fields.Function(fields.Selection([
-        ('', ''),
-        ('ignored', 'Ignored'),
-        ('recreated', 'Recreated'),
-        ], 'Exception State'), 'get_purchase_exception_state')
-
-    @classmethod
-    def __register__(cls, module_name):
-        cursor = Transaction().cursor
-
-        super(Move, cls).__register__(module_name)
-
-        table = TableHandler(cursor, cls, module_name)
-
-        # Migration from 2.6: remove purchase_line
-        if table.column_exist('purchase_line'):
-            cursor.execute('UPDATE "' + cls._table + '" '
-                'SET origin = \'purchase.line,\' || purchase_line '
-                'WHERE purchase_line IS NOT NULL')
-            table.drop_column('purchase_line')
-
-    @classmethod
-    def _get_origin(cls):
-        models = super(Move, cls)._get_origin()
-        models.append('purchase.line')
-        return models
-
-    def get_purchase(self, name):
-        PurchaseLine = Pool().get('purchase.line')
-        if isinstance(self.origin, PurchaseLine):
-            return self.origin.purchase.id
-
-    @classmethod
-    def search_purchase(cls, name, clause):
-        return [('origin.' + name,) + tuple(clause[1:]) + ('purchase.line',)]
-
-    def get_purchase_exception_state(self, name):
-        PurchaseLine = Pool().get('purchase.line')
-        if not isinstance(self.origin, PurchaseLine):
-            return ''
-        if self in self.origin.moves_recreated:
-            return 'recreated'
-        if self in self.origin.moves_ignored:
-            return 'ignored'
-
-    def get_purchase_fields(self, name):
-        PurchaseLine = Pool().get('purchase.line')
-        if isinstance(self.origin, PurchaseLine):
-            if name[9:] == 'currency':
-                return self.origin.purchase.currency.id
-            elif name[9:] in ('quantity', 'unit_digits', 'unit_price'):
-                return getattr(self.origin, name[9:])
-            else:
-                return getattr(self.origin, name[9:]).id
-        else:
-            if name[9:] == 'quantity':
-                return 0.0
-            elif name[9:] == 'unit_digits':
-                return 2
-
-    def on_change_with_purchase_visible(self, name=None):
-        if self.from_location:
-            if self.from_location.type == 'supplier':
-                return True
-        return False
-
-    def get_supplier(self, name):
-        PurchaseLine = Pool().get('purchase.line')
-        if isinstance(self.origin, PurchaseLine):
-            return self.origin.purchase.party.id
-
-    @classmethod
-    def search_supplier(cls, name, clause):
-        return [('origin.purchase.party',) + tuple(clause[1:]) +
-            ('purchase.line',)]
-
-    @classmethod
-    def write(cls, moves, vals):
-        pool = Pool()
-        Purchase = pool.get('purchase.purchase')
-        PurchaseLine = pool.get('purchase.line')
-
-        super(Move, cls).write(moves, vals)
-        if 'state' in vals and vals['state'] in ('cancel',):
-            purchases = set()
-            purchase_lines = PurchaseLine.search([
-                    ('moves', 'in', [m.id for m in moves]),
-                    ])
-            if purchase_lines:
-                for purchase_line in purchase_lines:
-                    purchases.add(purchase_line.purchase)
-            if purchases:
-                with Transaction().set_user(0, set_context=True):
-                    purchases = Purchase.browse([p.id for p in purchases])
-                    Purchase.process(purchases)
-
-    @classmethod
-    def delete(cls, moves):
-        pool = Pool()
-        Purchase = pool.get('purchase.purchase')
-        PurchaseLine = pool.get('purchase.line')
-
-        purchases = set()
-        purchase_lines = PurchaseLine.search([
-                ('moves', 'in', [m.id for m in moves]),
-                ])
-
-        super(Move, cls).delete(moves)
-
-        if purchase_lines:
-            for purchase_line in purchase_lines:
-                purchases.add(purchase_line.purchase)
-            if purchases:
-                with Transaction().set_user(0, set_context=True):
-                    purchases = Purchase.browse([p.id for p in purchases])
-                    Purchase.process(purchases)
-
-
 class OpenSupplier(Wizard):
     'Open Suppliers'
     __name__ = 'purchase.open_supplier'
@@ -1817,9 +1326,12 @@ class OpenSupplier(Wizard):
         pool = Pool()
         ModelData = pool.get('ir.model.data')
         Wizard = pool.get('ir.action.wizard')
+        Purchase = pool.get('purchase.purchase')
         cursor = Transaction().cursor
+        purchase = Purchase.__table__()
 
-        cursor.execute("SELECT DISTINCT(party) FROM purchase_purchase")
+        cursor.execute(*purchase.select(purchase.party,
+                group_by=purchase.party))
         supplier_ids = [line[0] for line in cursor.fetchall()]
         action['pyson_domain'] = PYSONEncoder().encode(
             [('id', 'in', supplier_ids)])
@@ -1848,11 +1360,15 @@ class HandleShipmentExceptionAsk(ModelView):
     @classmethod
     def __register__(cls, module_name):
         cursor = Transaction().cursor
+        model = Table('ir_model')
         # Migration from 1.2: packing renamed into shipment
-        cursor.execute("UPDATE ir_model "
-            "SET model = REPLACE(model, 'packing', 'shipment') "
-            "WHERE model like '%%packing%%' AND module = %s",
-            (module_name,))
+        cursor.execute(*model.update(
+                columns=[model.model],
+                values=[Overlay(model.model, 'shipment',
+                        Position('packing', model.model),
+                        len('packing'))],
+                where=model.model.like('%packing%')
+                & (model.module == module_name)))
         super(HandleShipmentExceptionAsk, cls).__register__(module_name)
 
 
diff --git a/purchase.xml b/purchase.xml
index 2e2d6b4..a0427d8 100644
--- a/purchase.xml
+++ b/purchase.xml
@@ -163,6 +163,30 @@ this repository contains the full copyright notices and license terms. -->
             <field name="group" ref="group_purchase"/>
         </record>
 
+        <record model="ir.action.act_window" id="act_purchase_invoice_relate">
+            <field name="name">Purchases</field>
+            <field name="res_model">purchase.purchase</field>
+            <field name="domain">[('invoices', 'in', [Eval('id')])]</field>
+        </record>
+        <record model="ir.action.act_window.view"
+            id="act_purchase_invoice_relate_view1">
+            <field name="sequence" eval="10"/>
+            <field name="view" ref="purchase_view_tree"/>
+            <field name="act_window" ref="act_purchase_invoice_relate"/>
+        </record>
+        <record model="ir.action.act_window.view"
+            id="act_purchase_invoice_relate_view2">
+            <field name="sequence" eval="20"/>
+            <field name="view" ref="purchase_view_form"/>
+            <field name="act_window" ref="act_purchase_invoice_relate"/>
+        </record>
+        <record model="ir.action.keyword"
+            id="act_purchase_invoice_relate_keyword">
+            <field name="keyword">form_relate</field>
+            <field name="model">account.invoice,-1</field>
+            <field name="action" ref="act_purchase_invoice_relate"/>
+        </record>
+
         <menuitem name="Reporting" parent="menu_purchase"
             id="menu_reporting" sequence="100" active="0"/>
 
diff --git a/setup.py b/setup.py
index b231cb4..4ecd41d 100644
--- a/setup.py
+++ b/setup.py
@@ -21,7 +21,7 @@ major_version, minor_version, _ = info.get('version', '0.0.1').split('.', 2)
 major_version = int(major_version)
 minor_version = int(minor_version)
 
-requires = []
+requires = ['python-sql']
 for dep in info.get('depends', []):
     if not re.match(r'(ir|res|webdav)(\W|$)', dep):
         requires.append('trytond_%s >= %s.%s, < %s.%s' %
@@ -45,7 +45,8 @@ setup(name='trytond_purchase',
         ],
     package_data={
         'trytond.modules.purchase': (info.get('xml', [])
-            + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'purchase.odt']),
+            + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'tests/*.rst',
+                'purchase.odt']),
         },
     classifiers=[
         'Development Status :: 5 - Production/Stable',
@@ -63,6 +64,7 @@ setup(name='trytond_purchase',
         'Natural Language :: French',
         'Natural Language :: German',
         'Natural Language :: Russian',
+        'Natural Language :: Slovenian',
         'Natural Language :: Spanish',
         'Operating System :: OS Independent',
         'Programming Language :: Python :: 2.6',
diff --git a/stock.py b/stock.py
index 18ccf22..b01801a 100644
--- a/stock.py
+++ b/stock.py
@@ -1,13 +1,294 @@
 #This file is part of Tryton.  The COPYRIGHT file at the top level of
 #this repository contains the full copyright notices and license terms.
 import datetime
+from sql.operators import Concat
 
+from trytond.model import Workflow, ModelView, fields
+from trytond.pyson import Eval
 from trytond.wizard import Wizard
-from trytond.pool import Pool
+from trytond.pool import Pool, PoolMeta
 from trytond.transaction import Transaction
 from trytond.pyson import PYSONDecoder, PYSONEncoder
+from trytond import backend
 
-__all__ = ['OpenProductQuantitiesByWarehouse']
+__all__ = ['ShipmentIn', 'ShipmentInReturn', 'Move',
+    'OpenProductQuantitiesByWarehouse']
+__metaclass__ = PoolMeta
+
+
+class ShipmentIn:
+    __name__ = 'stock.shipment.in'
+
+    @classmethod
+    def __setup__(cls):
+        super(ShipmentIn, cls).__setup__()
+        add_remove = [
+            ('supplier', '=', Eval('supplier')),
+            ]
+        if not cls.incoming_moves.add_remove:
+            cls.incoming_moves.add_remove = add_remove
+        else:
+            cls.incoming_moves.add_remove = [
+                add_remove,
+                cls.incoming_moves.add_remove,
+                ]
+        if 'supplier' not in cls.incoming_moves.depends:
+            cls.incoming_moves.depends.append('supplier')
+
+        cls._error_messages.update({
+                'reset_move': ('You cannot reset to draft move "%s" because '
+                    'it was generated by a purchase.'),
+                })
+
+    @classmethod
+    def write(cls, shipments, vals):
+        pool = Pool()
+        Purchase = pool.get('purchase.purchase')
+        PurchaseLine = pool.get('purchase.line')
+
+        super(ShipmentIn, cls).write(shipments, vals)
+
+        if 'state' in vals and vals['state'] in ('received', 'cancel'):
+            purchases = []
+            move_ids = []
+            for shipment in shipments:
+                move_ids.extend([x.id for x in shipment.incoming_moves])
+
+            purchase_lines = PurchaseLine.search([
+                    ('moves', 'in', move_ids),
+                    ])
+            if purchase_lines:
+                for purchase_line in purchase_lines:
+                    if purchase_line.purchase not in purchases:
+                        purchases.append(purchase_line.purchase)
+
+            with Transaction().set_user(0, set_context=True):
+                purchases = Purchase.browse([p.id for p in purchases])
+                Purchase.process(purchases)
+
+    @classmethod
+    @ModelView.button
+    @Workflow.transition('draft')
+    def draft(cls, shipments):
+        PurchaseLine = Pool().get('purchase.line')
+        for shipment in shipments:
+            for move in shipment.incoming_moves:
+                if (move.state == 'cancel'
+                        and isinstance(move.origin, PurchaseLine)):
+                    cls.raise_user_error('reset_move', (move.rec_name,))
+
+        return super(ShipmentIn, cls).draft(shipments)
+
+
+class ShipmentInReturn:
+    __name__ = 'stock.shipment.in.return'
+
+    @classmethod
+    def __setup__(cls):
+        super(ShipmentInReturn, cls).__setup__()
+        cls._error_messages.update({
+                'reset_move': ('You cannot reset to draft a move generated '
+                    'by a purchase.'),
+                })
+
+    @classmethod
+    def write(cls, shipments, vals):
+        pool = Pool()
+        Purchase = pool.get('purchase.purchase')
+        PurchaseLine = pool.get('purchase.line')
+
+        super(ShipmentInReturn, cls).write(shipments, vals)
+
+        if 'state' in vals and vals['state'] == 'done':
+            move_ids = []
+            for shipment in shipments:
+                move_ids.extend([x.id for x in shipment.moves])
+
+            purchase_lines = PurchaseLine.search([
+                    ('moves', 'in', move_ids),
+                    ])
+            purchases = set()
+            if purchase_lines:
+                for purchase_line in purchase_lines:
+                    purchases.add(purchase_line.purchase)
+
+            with Transaction().set_user(0, set_context=True):
+                purchases = Purchase.browse([p.id for p in purchases])
+                Purchase.process(purchases)
+
+    @classmethod
+    @ModelView.button
+    @Workflow.transition('draft')
+    def draft(cls, shipments):
+        PurchaseLine = Pool().get('purchase.line')
+        for shipment in shipments:
+            for move in shipment.moves:
+                if (move.state == 'cancel'
+                        and isinstance(move.origin, PurchaseLine)):
+                    cls.raise_user_error('reset_move')
+
+        return super(ShipmentInReturn, cls).draft(shipments)
+
+
+class Move:
+    __name__ = 'stock.move'
+    purchase = fields.Function(fields.Many2One('purchase.purchase', 'Purchase',
+            states={
+                'invisible': ~Eval('purchase_visible', False),
+                },
+            depends=['purchase_visible']), 'get_purchase',
+        searcher='search_purchase')
+    purchase_quantity = fields.Function(fields.Float('Purchase Quantity',
+            digits=(16, Eval('unit_digits', 2)),
+            states={
+                'invisible': ~Eval('purchase_visible', False),
+                },
+            depends=['purchase_visible', 'unit_digits']),
+        'get_purchase_fields')
+    purchase_unit = fields.Function(fields.Many2One('product.uom',
+            'Purchase Unit', states={
+                'invisible': ~Eval('purchase_visible', False),
+                }, depends=['purchase_visible']), 'get_purchase_fields')
+    purchase_unit_digits = fields.Function(fields.Integer(
+        'Purchase Unit Digits'), 'get_purchase_fields')
+    purchase_unit_price = fields.Function(fields.Numeric('Purchase Unit Price',
+            digits=(16, 4), states={
+                'invisible': ~Eval('purchase_visible', False),
+                }, depends=['purchase_visible']), 'get_purchase_fields')
+    purchase_currency = fields.Function(fields.Many2One('currency.currency',
+            'Purchase Currency', states={
+                'invisible': ~Eval('purchase_visible', False),
+                }, depends=['purchase_visible']), 'get_purchase_fields')
+    purchase_visible = fields.Function(fields.Boolean('Purchase Visible',
+        on_change_with=['from_location']), 'on_change_with_purchase_visible')
+    supplier = fields.Function(fields.Many2One('party.party', 'Supplier'),
+        'get_supplier', searcher='search_supplier')
+    purchase_exception_state = fields.Function(fields.Selection([
+        ('', ''),
+        ('ignored', 'Ignored'),
+        ('recreated', 'Recreated'),
+        ], 'Exception State'), 'get_purchase_exception_state')
+
+    @classmethod
+    def __register__(cls, module_name):
+        TableHandler = backend.get('TableHandler')
+        cursor = Transaction().cursor
+        sql_table = cls.__table__()
+
+        super(Move, cls).__register__(module_name)
+
+        table = TableHandler(cursor, cls, module_name)
+
+        # Migration from 2.6: remove purchase_line
+        if table.column_exist('purchase_line'):
+            cursor.execute(*sql_table.update(
+                    columns=[sql_table.origin],
+                    values=[Concat('purchase.line,', sql_table.purchase_line)],
+                    where=sql_table.purchase_line != None))
+            table.drop_column('purchase_line')
+
+    @classmethod
+    def _get_origin(cls):
+        models = super(Move, cls)._get_origin()
+        models.append('purchase.line')
+        return models
+
+    def get_purchase(self, name):
+        PurchaseLine = Pool().get('purchase.line')
+        if isinstance(self.origin, PurchaseLine):
+            return self.origin.purchase.id
+
+    @classmethod
+    def search_purchase(cls, name, clause):
+        return [('origin.' + name,) + tuple(clause[1:]) + ('purchase.line',)]
+
+    def get_purchase_exception_state(self, name):
+        PurchaseLine = Pool().get('purchase.line')
+        if not isinstance(self.origin, PurchaseLine):
+            return ''
+        if self in self.origin.moves_recreated:
+            return 'recreated'
+        if self in self.origin.moves_ignored:
+            return 'ignored'
+
+    def get_purchase_fields(self, name):
+        PurchaseLine = Pool().get('purchase.line')
+        if isinstance(self.origin, PurchaseLine):
+            if name[9:] == 'currency':
+                return self.origin.purchase.currency.id
+            elif name[9:] in ('quantity', 'unit_digits', 'unit_price'):
+                return getattr(self.origin, name[9:])
+            else:
+                return getattr(self.origin, name[9:]).id
+        else:
+            if name[9:] == 'quantity':
+                return 0.0
+            elif name[9:] == 'unit_digits':
+                return 2
+
+    def on_change_with_purchase_visible(self, name=None):
+        if self.from_location:
+            if self.from_location.type == 'supplier':
+                return True
+        return False
+
+    def get_supplier(self, name):
+        PurchaseLine = Pool().get('purchase.line')
+        if isinstance(self.origin, PurchaseLine):
+            return self.origin.purchase.party.id
+
+    @property
+    def origin_name(self):
+        pool = Pool()
+        PurchaseLine = pool.get('purchase.line')
+        name = super(Move, self).origin_name
+        if isinstance(self.origin, PurchaseLine):
+            name = self.origin.purchase.rec_name
+        return name
+
+    @classmethod
+    def search_supplier(cls, name, clause):
+        return [('origin.purchase.party',) + tuple(clause[1:]) +
+            ('purchase.line',)]
+
+    @classmethod
+    @ModelView.button
+    @Workflow.transition('cancel')
+    def cancel(cls, moves):
+        pool = Pool()
+        Purchase = pool.get('purchase.purchase')
+        PurchaseLine = pool.get('purchase.line')
+
+        super(Move, cls).cancel(moves)
+        purchase_lines = PurchaseLine.search([
+                ('moves', 'in', [m.id for m in moves]),
+                ])
+        if purchase_lines:
+            purchase_ids = list(set(l.purchase.id for l in purchase_lines))
+            with Transaction().set_user(0, set_context=True):
+                purchases = Purchase.browse(purchase_ids)
+                Purchase.process(purchases)
+
+    @classmethod
+    def delete(cls, moves):
+        pool = Pool()
+        Purchase = pool.get('purchase.purchase')
+        PurchaseLine = pool.get('purchase.line')
+
+        purchases = set()
+        purchase_lines = PurchaseLine.search([
+                ('moves', 'in', [m.id for m in moves]),
+                ])
+
+        super(Move, cls).delete(moves)
+
+        if purchase_lines:
+            for purchase_line in purchase_lines:
+                purchases.add(purchase_line.purchase)
+            if purchases:
+                with Transaction().set_user(0, set_context=True):
+                    purchases = Purchase.browse([p.id for p in purchases])
+                    Purchase.process(purchases)
 
 
 class OpenProductQuantitiesByWarehouse(Wizard):
diff --git a/tests/__init__.py b/tests/__init__.py
index fdda836..f648605 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -2,3 +2,5 @@
 #this repository contains the full copyright notices and license terms.
 
 from .test_purchase import suite
+
+__all__ = ['suite']
diff --git a/tests/scenario_purchase.rst b/tests/scenario_purchase.rst
new file mode 100644
index 0000000..51472dc
--- /dev/null
+++ b/tests/scenario_purchase.rst
@@ -0,0 +1,509 @@
+=================
+Purchase Scenario
+=================
+
+Imports::
+
+    >>> import datetime
+    >>> from dateutil.relativedelta import relativedelta
+    >>> from decimal import Decimal
+    >>> from operator import attrgetter
+    >>> from proteus import config, Model, Wizard
+    >>> today = datetime.date.today()
+
+Create database::
+
+    >>> config = config.set_trytond()
+    >>> config.pool.test = True
+
+Install purchase::
+
+    >>> Module = Model.get('ir.module.module')
+    >>> purchase_module, = Module.find([('name', '=', 'purchase')])
+    >>> Module.install([purchase_module.id], config.context)
+    >>> Wizard('ir.module.module.install_upgrade').execute('upgrade')
+
+Create company::
+
+    >>> Currency = Model.get('currency.currency')
+    >>> CurrencyRate = Model.get('currency.currency.rate')
+    >>> currencies = Currency.find([('code', '=', 'EUR')])
+    >>> if not currencies:
+    ...     currency = Currency(name='Euro', symbol=u'€', code='EUR',
+    ...         rounding=Decimal('0.01'), mon_grouping='[3, 3, 0]',
+    ...         mon_decimal_point=',')
+    ...     currency.save()
+    ...     CurrencyRate(date=today + relativedelta(month=1, day=1),
+    ...         rate=Decimal('1.0'), currency=currency).save()
+    ... else:
+    ...     currency, = currencies
+    >>> Company = Model.get('company.company')
+    >>> Party = Model.get('party.party')
+    >>> company_config = Wizard('company.company.config')
+    >>> company_config.execute('company')
+    >>> company = company_config.form
+    >>> party = Party(name='B2CK')
+    >>> party.save()
+    >>> company.party = party
+    >>> company.currency = currency
+    >>> company_config.execute('add')
+    >>> company, = Company.find([])
+
+Reload the context::
+
+    >>> User = Model.get('res.user')
+    >>> Group = Model.get('res.group')
+    >>> config._context = User.get_preferences(True, config.context)
+
+Create purchase user::
+
+    >>> purchase_user = User()
+    >>> purchase_user.name = 'Purchase'
+    >>> purchase_user.login = 'purchase'
+    >>> purchase_user.main_company = company
+    >>> purchase_group, = Group.find([('name', '=', 'Purchase')])
+    >>> purchase_user.groups.append(purchase_group)
+    >>> purchase_user.save()
+
+Create stock user::
+
+    >>> stock_user = User()
+    >>> stock_user.name = 'Stock'
+    >>> stock_user.login = 'stock'
+    >>> stock_user.main_company = company
+    >>> stock_group, = Group.find([('name', '=', 'Stock')])
+    >>> stock_user.groups.append(stock_group)
+    >>> stock_user.save()
+
+Create account user::
+
+    >>> account_user = User()
+    >>> account_user.name = 'Account'
+    >>> account_user.login = 'account'
+    >>> account_user.main_company = company
+    >>> account_group, = Group.find([('name', '=', 'Account')])
+    >>> account_user.groups.append(account_group)
+    >>> account_user.save()
+
+Create fiscal year::
+
+    >>> FiscalYear = Model.get('account.fiscalyear')
+    >>> Sequence = Model.get('ir.sequence')
+    >>> SequenceStrict = Model.get('ir.sequence.strict')
+    >>> fiscalyear = FiscalYear(name=str(today.year))
+    >>> fiscalyear.start_date = today + relativedelta(month=1, day=1)
+    >>> fiscalyear.end_date = today + relativedelta(month=12, day=31)
+    >>> fiscalyear.company = company
+    >>> post_move_seq = Sequence(name=str(today.year), code='account.move',
+    ...     company=company)
+    >>> post_move_seq.save()
+    >>> fiscalyear.post_move_sequence = post_move_seq
+    >>> invoice_seq = SequenceStrict(name=str(today.year),
+    ...     code='account.invoice', company=company)
+    >>> invoice_seq.save()
+    >>> fiscalyear.out_invoice_sequence = invoice_seq
+    >>> fiscalyear.in_invoice_sequence = invoice_seq
+    >>> fiscalyear.out_credit_note_sequence = invoice_seq
+    >>> fiscalyear.in_credit_note_sequence = invoice_seq
+    >>> fiscalyear.save()
+    >>> FiscalYear.create_period([fiscalyear.id], config.context)
+
+Create chart of accounts::
+
+    >>> AccountTemplate = Model.get('account.account.template')
+    >>> Account = Model.get('account.account')
+    >>> account_template, = AccountTemplate.find([('parent', '=', None)])
+    >>> create_chart = Wizard('account.create_chart')
+    >>> create_chart.execute('account')
+    >>> create_chart.form.account_template = account_template
+    >>> create_chart.form.company = company
+    >>> create_chart.execute('create_account')
+    >>> receivable, = Account.find([
+    ...         ('kind', '=', 'receivable'),
+    ...         ('company', '=', company.id),
+    ...         ])
+    >>> payable, = Account.find([
+    ...         ('kind', '=', 'payable'),
+    ...         ('company', '=', company.id),
+    ...         ])
+    >>> revenue, = Account.find([
+    ...         ('kind', '=', 'revenue'),
+    ...         ('company', '=', company.id),
+    ...         ])
+    >>> expense, = Account.find([
+    ...         ('kind', '=', 'expense'),
+    ...         ('company', '=', company.id),
+    ...         ])
+    >>> create_chart.form.account_receivable = receivable
+    >>> create_chart.form.account_payable = payable
+    >>> create_chart.execute('create_properties')
+
+Create parties::
+
+    >>> Party = Model.get('party.party')
+    >>> supplier = Party(name='Supplier')
+    >>> supplier.save()
+    >>> customer = Party(name='Customer')
+    >>> customer.save()
+
+Create product::
+
+    >>> ProductUom = Model.get('product.uom')
+    >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+    >>> ProductTemplate = Model.get('product.template')
+    >>> Product = Model.get('product.product')
+    >>> product = Product()
+    >>> template = ProductTemplate()
+    >>> template.name = 'product'
+    >>> template.default_uom = unit
+    >>> template.type = 'goods'
+    >>> template.purchasable = True
+    >>> template.salable = True
+    >>> template.list_price = Decimal('10')
+    >>> template.cost_price = Decimal('5')
+    >>> template.cost_price_method = 'fixed'
+    >>> template.account_expense = expense
+    >>> template.account_revenue = revenue
+    >>> template.save()
+    >>> product.template = template
+    >>> product.save()
+
+Create payment term::
+
+    >>> PaymentTerm = Model.get('account.invoice.payment_term')
+    >>> PaymentTermLine = Model.get('account.invoice.payment_term.line')
+    >>> payment_term = PaymentTerm(name='Direct')
+    >>> payment_term_line = PaymentTermLine(type='remainder', days=0)
+    >>> payment_term.lines.append(payment_term_line)
+    >>> payment_term.save()
+
+Create an Inventory::
+
+    >>> config.user = stock_user.id
+    >>> Inventory = Model.get('stock.inventory')
+    >>> InventoryLine = Model.get('stock.inventory.line')
+    >>> Location = Model.get('stock.location')
+    >>> storage, = Location.find([
+    ...         ('code', '=', 'STO'),
+    ...         ])
+    >>> inventory = Inventory()
+    >>> inventory.location = storage
+    >>> inventory.save()
+    >>> inventory_line = InventoryLine(product=product, inventory=inventory)
+    >>> inventory_line.quantity = 100.0
+    >>> inventory_line.expected_quantity = 0.0
+    >>> inventory.save()
+    >>> inventory_line.save()
+    >>> Inventory.confirm([inventory.id], config.context)
+    >>> inventory.state
+    u'done'
+
+Purchase 5 products::
+
+    >>> config.user = purchase_user.id
+    >>> Purchase = Model.get('purchase.purchase')
+    >>> PurchaseLine = Model.get('purchase.line')
+    >>> purchase = Purchase()
+    >>> purchase.party = supplier
+    >>> purchase.payment_term = payment_term
+    >>> purchase.invoice_method = 'order'
+    >>> purchase_line = PurchaseLine()
+    >>> purchase.lines.append(purchase_line)
+    >>> purchase_line.product = product
+    >>> purchase_line.quantity = 2.0
+    >>> purchase_line = PurchaseLine()
+    >>> purchase.lines.append(purchase_line)
+    >>> purchase_line.type = 'comment'
+    >>> purchase_line.description = 'Comment'
+    >>> purchase_line = PurchaseLine()
+    >>> purchase.lines.append(purchase_line)
+    >>> purchase_line.product = product
+    >>> purchase_line.quantity = 3.0
+    >>> purchase.save()
+    >>> Purchase.quote([purchase.id], config.context)
+    >>> Purchase.confirm([purchase.id], config.context)
+    >>> purchase.state
+    u'confirmed'
+    >>> purchase.reload()
+    >>> len(purchase.moves), len(purchase.shipment_returns), len(purchase.invoices)
+    (2, 0, 1)
+    >>> invoice, = purchase.invoices
+    >>> invoice.origins == purchase.rec_name
+    True
+
+Post invoice and check no new invoices::
+
+    >>> config.user = account_user.id
+    >>> Invoice = Model.get('account.invoice')
+    >>> purchase.invoices[0].invoice_date = today
+    >>> purchase.invoices[0].save()
+    >>> Invoice.post([i.id for i in purchase.invoices], config.context)
+    >>> config.user = purchase_user.id
+    >>> purchase.reload()
+    >>> len(purchase.moves), len(purchase.shipment_returns), len(purchase.invoices)
+    (2, 0, 1)
+
+Purchase 5 products with an invoice method 'on shipment'::
+
+    >>> config.user = purchase_user.id
+    >>> purchase = Purchase()
+    >>> purchase.party = supplier
+    >>> purchase.payment_term = payment_term
+    >>> purchase.invoice_method = 'shipment'
+    >>> purchase_line = PurchaseLine()
+    >>> purchase.lines.append(purchase_line)
+    >>> purchase_line.product = product
+    >>> purchase_line.quantity = 2.0
+    >>> purchase_line = PurchaseLine()
+    >>> purchase.lines.append(purchase_line)
+    >>> purchase_line.type = 'comment'
+    >>> purchase_line.description = 'Comment'
+    >>> purchase_line = PurchaseLine()
+    >>> purchase.lines.append(purchase_line)
+    >>> purchase_line.product = product
+    >>> purchase_line.quantity = 3.0
+    >>> purchase.save()
+    >>> Purchase.quote([purchase.id], config.context)
+    >>> Purchase.confirm([purchase.id], config.context)
+    >>> purchase.state
+    u'confirmed'
+    >>> purchase.reload()
+    >>> len(purchase.moves), len(purchase.shipment_returns), len(purchase.invoices)
+    (2, 0, 0)
+
+Validate Shipments::
+
+    >>> config.user = stock_user.id
+    >>> Move = Model.get('stock.move')
+    >>> ShipmentIn = Model.get('stock.shipment.in')
+    >>> shipment = ShipmentIn()
+    >>> shipment.supplier = supplier
+    >>> for move in purchase.moves:
+    ...     incoming_move = Move(id=move.id)
+    ...     shipment.incoming_moves.append(incoming_move)
+    >>> shipment.save()
+    >>> shipment.origins == purchase.rec_name
+    True
+    >>> ShipmentIn.receive([shipment.id], config.context)
+    >>> ShipmentIn.done([shipment.id], config.context)
+    >>> purchase.reload()
+    >>> len(purchase.shipments), len(purchase.shipment_returns)
+    (1, 0)
+
+Open supplier invoice::
+
+    >>> Invoice = Model.get('account.invoice')
+    >>> invoice, = purchase.invoices
+    >>> config.user = account_user.id
+    >>> invoice.type
+    u'in_invoice'
+    >>> len(invoice.lines)
+    2
+    >>> for line in invoice.lines:
+    ...     line.quantity = 1
+    ...     line.save()
+    >>> invoice.invoice_date = today
+    >>> invoice.save()
+    >>> Invoice.post([invoice.id], config.context)
+
+Check second invoices::
+
+    >>> config.user = purchase_user.id
+    >>> purchase.reload()
+    >>> len(purchase.invoices)
+    2
+    >>> sum(l.quantity for i in purchase.invoices for l in i.lines)
+    5.0
+
+Create a Return::
+
+    >>> config.user = purchase_user.id
+    >>> return_ = Purchase()
+    >>> return_.party = supplier
+    >>> return_.payment_term = payment_term
+    >>> return_.invoice_method = 'shipment'
+    >>> return_line = PurchaseLine()
+    >>> return_.lines.append(return_line)
+    >>> return_line.product = product
+    >>> return_line.quantity = -4.
+    >>> return_line = PurchaseLine()
+    >>> return_.lines.append(return_line)
+    >>> return_line.type = 'comment'
+    >>> return_line.description = 'Comment'
+    >>> return_.save()
+    >>> Purchase.quote([return_.id], config.context)
+    >>> Purchase.confirm([return_.id], config.context)
+    >>> return_.state
+    u'confirmed'
+    >>> return_.reload()
+    >>> (len(return_.shipments), len(return_.shipment_returns),
+    ...     len(return_.invoices))
+    (0, 1, 0)
+
+Check Return Shipments::
+
+    >>> config.user = stock_user.id
+    >>> ShipmentReturn = Model.get('stock.shipment.in.return')
+    >>> ship_return, = return_.shipment_returns
+    >>> ship_return.state
+    u'waiting'
+    >>> move_return, = ship_return.moves
+    >>> move_return.product.rec_name
+    u'product'
+    >>> move_return.quantity
+    4.0
+    >>> ShipmentReturn.assign_try([ship_return.id], config.context)
+    True
+    >>> ShipmentReturn.done([ship_return.id], config.context)
+    >>> ship_return.reload()
+    >>> ship_return.state
+    u'done'
+    >>> return_.reload()
+
+Open supplier credit note::
+
+    >>> credit_note, = return_.invoices
+    >>> config.user = account_user.id
+    >>> credit_note.type
+    u'in_credit_note'
+    >>> len(credit_note.lines)
+    1
+    >>> sum(l.quantity for l in credit_note.lines)
+    4.0
+    >>> credit_note.invoice_date = today
+    >>> credit_note.save()
+    >>> Invoice.post([credit_note.id], config.context)
+
+Mixing return and purchase::
+
+    >>> config.user = purchase_user.id
+    >>> mix = Purchase()
+    >>> mix.party = supplier
+    >>> mix.payment_term = payment_term
+    >>> mix.invoice_method = 'order'
+    >>> mixline = PurchaseLine()
+    >>> mix.lines.append(mixline)
+    >>> mixline.product = product
+    >>> mixline.quantity = 7.
+    >>> mixline_comment = PurchaseLine()
+    >>> mix.lines.append(mixline_comment)
+    >>> mixline_comment.type = 'comment'
+    >>> mixline_comment.description = 'Comment'
+    >>> mixline2 = PurchaseLine()
+    >>> mix.lines.append(mixline2)
+    >>> mixline2.product = product
+    >>> mixline2.quantity = -2.
+    >>> mix.save()
+    >>> Purchase.quote([mix.id], config.context)
+    >>> Purchase.confirm([mix.id], config.context)
+    >>> mix.state
+    u'confirmed'
+    >>> mix.reload()
+    >>> len(mix.moves), len(mix.shipment_returns), len(mix.invoices)
+    (2, 1, 2)
+
+Checking Shipments::
+
+    >>> mix_returns, = mix.shipment_returns
+    >>> config.user = stock_user.id
+    >>> mix_shipments = ShipmentIn()
+    >>> mix_shipments.supplier = supplier
+    >>> for move in mix.moves:
+    ...     if move.id in [m.id for m in mix_returns.moves]:
+    ...         continue
+    ...     incoming_move = Move(id=move.id)
+    ...     mix_shipments.incoming_moves.append(incoming_move)
+    >>> mix_shipments.save()
+    >>> ShipmentIn.receive([mix_shipments.id], config.context)
+    >>> ShipmentIn.done([mix_shipments.id], config.context)
+    >>> mix.reload()
+    >>> len(mix.shipments)
+    1
+
+    >>> ShipmentReturn.wait([mix_returns.id], config.context)
+    >>> ShipmentReturn.assign_try([mix_returns.id], config.context)
+    True
+    >>> ShipmentReturn.done([mix_returns.id], config.context)
+    >>> move_return, = mix_returns.moves
+    >>> move_return.product.rec_name
+    u'product'
+    >>> move_return.quantity
+    2.0
+
+Checking the invoice::
+
+    >>> config.user = purchase_user.id
+    >>> mix.reload()
+    >>> mix_invoice, mix_credit_note = sorted(mix.invoices,
+    ...     key=attrgetter('type'), reverse=True)
+    >>> config.user = account_user.id
+    >>> mix_invoice.type, mix_credit_note.type
+    (u'in_invoice', u'in_credit_note')
+    >>> len(mix_invoice.lines), len(mix_credit_note.lines)
+    (1, 1)
+    >>> sum(l.quantity for l in mix_invoice.lines)
+    7.0
+    >>> sum(l.quantity for l in mix_credit_note.lines)
+    2.0
+    >>> mix_invoice.invoice_date = today
+    >>> mix_invoice.save()
+    >>> Invoice.post([mix_invoice.id], config.context)
+    >>> mix_credit_note.invoice_date = today
+    >>> mix_credit_note.save()
+    >>> Invoice.post([mix_credit_note.id], config.context)
+
+Mixing stuff with an invoice method 'on shipment'::
+
+    >>> config.user = purchase_user.id
+    >>> mix = Purchase()
+    >>> mix.party = supplier
+    >>> mix.payment_term = payment_term
+    >>> mix.invoice_method = 'shipment'
+    >>> mixline = PurchaseLine()
+    >>> mix.lines.append(mixline)
+    >>> mixline.product = product
+    >>> mixline.quantity = 6.
+    >>> mixline_comment = PurchaseLine()
+    >>> mix.lines.append(mixline_comment)
+    >>> mixline_comment.type = 'comment'
+    >>> mixline_comment.description = 'Comment'
+    >>> mixline2 = PurchaseLine()
+    >>> mix.lines.append(mixline2)
+    >>> mixline2.product = product
+    >>> mixline2.quantity = -3.
+    >>> mix.save()
+    >>> Purchase.quote([mix.id], config.context)
+    >>> Purchase.confirm([mix.id], config.context)
+    >>> mix.state
+    u'confirmed'
+    >>> mix.reload()
+    >>> len(mix.moves), len(mix.shipment_returns), len(mix.invoices)
+    (2, 1, 0)
+
+Checking Shipments::
+
+    >>> config.user = stock_user.id
+    >>> mix_returns, = mix.shipment_returns
+    >>> mix_shipments = ShipmentIn()
+    >>> mix_shipments.supplier = supplier
+    >>> for move in mix.moves:
+    ...     if move.id in [m.id for m in mix_returns.moves]:
+    ...         continue
+    ...     incoming_move = Move(id=move.id)
+    ...     mix_shipments.incoming_moves.append(incoming_move)
+    >>> mix_shipments.save()
+    >>> ShipmentIn.receive([mix_shipments.id], config.context)
+    >>> ShipmentIn.done([mix_shipments.id], config.context)
+    >>> mix.reload()
+    >>> len(mix.shipments)
+    1
+
+    >>> ShipmentReturn.wait([mix_returns.id], config.context)
+    >>> ShipmentReturn.assign_try([mix_returns.id], config.context)
+    True
+    >>> ShipmentReturn.done([mix_returns.id], config.context)
+    >>> move_return, = mix_returns.moves
+    >>> move_return.product.rec_name
+    u'product'
+    >>> move_return.quantity
+    3.0
diff --git a/tryton.cfg b/tryton.cfg
index 2e500f3..d730807 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -1,5 +1,5 @@
 [tryton]
-version=2.8.1
+version=3.0.0
 depends:
     account
     account_invoice
diff --git a/trytond_purchase.egg-info/PKG-INFO b/trytond_purchase.egg-info/PKG-INFO
index 9cd4956..9b4ba9e 100644
--- a/trytond_purchase.egg-info/PKG-INFO
+++ b/trytond_purchase.egg-info/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: trytond-purchase
-Version: 2.8.1
+Version: 3.0.0
 Summary: Tryton module for purchase
 Home-page: http://www.tryton.org/
 Author: Tryton
 Author-email: UNKNOWN
 License: GPL-3
-Download-URL: http://downloads.tryton.org/2.8/
+Download-URL: http://downloads.tryton.org/3.0/
 Description: trytond_purchase
         ================
         
@@ -59,6 +59,7 @@ Classifier: Natural Language :: English
 Classifier: Natural Language :: French
 Classifier: Natural Language :: German
 Classifier: Natural Language :: Russian
+Classifier: Natural Language :: Slovenian
 Classifier: Natural Language :: Spanish
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python :: 2.6
diff --git a/trytond_purchase.egg-info/SOURCES.txt b/trytond_purchase.egg-info/SOURCES.txt
index 8e0a17a..67ef9c3 100644
--- a/trytond_purchase.egg-info/SOURCES.txt
+++ b/trytond_purchase.egg-info/SOURCES.txt
@@ -16,6 +16,7 @@ tryton.cfg
 ./__init__.py
 ./configuration.py
 ./invoice.py
+./product.py
 ./purchase.py
 ./stock.py
 ./tests/__init__.py
@@ -31,6 +32,8 @@ locale/es_ES.po
 locale/fr_FR.po
 locale/nl_NL.po
 locale/ru_RU.po
+locale/sl_SI.po
+tests/scenario_purchase.rst
 trytond_purchase.egg-info/PKG-INFO
 trytond_purchase.egg-info/SOURCES.txt
 trytond_purchase.egg-info/dependency_links.txt
diff --git a/trytond_purchase.egg-info/requires.txt b/trytond_purchase.egg-info/requires.txt
index 54d6265..bc38aef 100644
--- a/trytond_purchase.egg-info/requires.txt
+++ b/trytond_purchase.egg-info/requires.txt
@@ -1,9 +1,10 @@
-trytond_account >= 2.8, < 2.9
-trytond_account_invoice >= 2.8, < 2.9
-trytond_account_product >= 2.8, < 2.9
-trytond_company >= 2.8, < 2.9
-trytond_currency >= 2.8, < 2.9
-trytond_party >= 2.8, < 2.9
-trytond_product >= 2.8, < 2.9
-trytond_stock >= 2.8, < 2.9
-trytond >= 2.8, < 2.9
\ No newline at end of file
+python-sql
+trytond_account >= 3.0, < 3.1
+trytond_account_invoice >= 3.0, < 3.1
+trytond_account_product >= 3.0, < 3.1
+trytond_company >= 3.0, < 3.1
+trytond_currency >= 3.0, < 3.1
+trytond_party >= 3.0, < 3.1
+trytond_product >= 3.0, < 3.1
+trytond_stock >= 3.0, < 3.1
+trytond >= 3.0, < 3.1
\ No newline at end of file
diff --git a/view/purchase_tree.xml b/view/purchase_tree.xml
index 7778ed4..4f16d6c 100644
--- a/view/purchase_tree.xml
+++ b/view/purchase_tree.xml
@@ -15,5 +15,4 @@ this repository contains the full copyright notices and license terms. -->
     <field name="shipment_state"/>
     <field name="description"/>
     <field name="currency_digits" tree_invisible="1"/>
-    <field name="create_date" tree_invisible="1"/>
 </tree>
-- 
tryton-modules-purchase



More information about the tryton-debian-vcs mailing list