first commit

This commit is contained in:
root
2026-03-14 09:42:12 +00:00
commit 0adbd20c2c
10991 changed files with 1646955 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

View File

@@ -0,0 +1,19 @@
# 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 trytond.pool import Pool, PoolMeta
from trytond.tools import cached_property
class InvoiceLine(metaclass=PoolMeta):
__name__ = 'account.invoice.line'
@cached_property
def product_name(self):
pool = Pool()
SaleLine = pool.get('sale.line')
name = super().product_name
if (isinstance(self.origin, SaleLine)
and self.origin.product_customer):
name = self.origin.product_customer.rec_name
return name

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr "Clients"
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr "Clients"
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr "Producte del client"
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr "Producte del client"
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr "Producte del client"
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr "Codi"
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr "Client"
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr "Variant"
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr "Producte"
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr "Clients"
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr "Clients"
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr "Producte del client"

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr "Kunden"
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr "Kunden"
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr "Kundenartikel"
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr "Kundenartikel"
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr "Kundenartikel"
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr "Code"
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr "Name"
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr "Kunde"
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr "Variante"
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr "Artikel"
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr "Kunden"
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr "Kunden"
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr "Verkauf Artikel Kunde"

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr "Clientes"
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr "Clientes"
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr "Producto del cliente"
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr "Producto del cliente"
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr "Producto del cliente"
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr "Código"
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr "Cliente"
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr "Variante"
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr "Producto"
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr "Clientes"
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr "Clientes"
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr "Producto del cliente"

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,60 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr "Kliendid"
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr "Kliendid"
#, fuzzy
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr "Kliendi toode"
#, fuzzy
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr "Kliendi toode"
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr "Kliendi toode"
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr "Kood"
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr "Nimi"
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr "Klient"
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr "Variant"
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr "Toode"
#, fuzzy
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr "Kliendid"
#, fuzzy
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr "Kliendid"
#, fuzzy
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr "Toote klient"

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr "Clients"
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr "Clients"
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr "Produit Client"
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr "Produit Client"
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr "Produit Client"
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr "Code"
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr "Client"
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr "Variante"
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr "Produit"
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr "Clients"
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr "Clients"
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr "Produit en vente Client"

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,58 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr "Pelanggan"
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr "Produk Pelanggan"
#, fuzzy
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr "Produk Pelanggan"
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr "Produk Pelanggan"
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr "Kode"
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr "Nama"
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr "Pelanggan"
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr "Produk"
#, fuzzy
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr "Pelanggan"
#, fuzzy
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr "Pelanggan"
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,57 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr "Clienti"
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr "Clienti"
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr "Prodotto del cliente"
#, fuzzy
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr "Prodotto del cliente"
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr "Prodotto del cliente"
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr "Codice"
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr "Nome"
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr "Cliente"
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr "Variante"
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr "Prodotto"
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr "Clienti"
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr "Clienti"
#, fuzzy
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr "Cliente del prodotto"

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr "Klanten"
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr "Klanten"
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr "Klant product"
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr "Product van de klant"
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr "Klant product"
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr "Code"
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr "Naam"
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr "Klant"
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr "Variant"
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr "Product"
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr "Klanten"
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr "Klanten"
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr "Verkoop product klant"

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,56 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr "Clienți"
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr "Clienți"
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr "Produsul Clientului"
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr "Produsul Clientului"
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr "Produsul Clientului"
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr "Cod"
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr "Denumire"
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr "Client"
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr "Varianta"
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr "Produs"
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr "Clienți"
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr "Clienți"
#, fuzzy
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr "Produs Client"

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,55 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.product,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:product.template,product_customers:"
msgid "Customers"
msgstr ""
msgctxt "field:sale.amendment.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.blanket_agreement.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.line,product_customer:"
msgid "Customer's Product"
msgstr ""
msgctxt "field:sale.product_customer,code:"
msgid "Code"
msgstr ""
msgctxt "field:sale.product_customer,name:"
msgid "Name"
msgstr ""
msgctxt "field:sale.product_customer,party:"
msgid "Customer"
msgstr ""
msgctxt "field:sale.product_customer,product:"
msgid "Variant"
msgstr ""
msgctxt "field:sale.product_customer,template:"
msgid "Product"
msgstr ""
msgctxt "model:ir.action,name:act_product_customer_form"
msgid "Customers"
msgstr ""
msgctxt "model:ir.ui.menu,name:menu_product_customer"
msgid "Customers"
msgstr ""
msgctxt "model:sale.product_customer,string:"
msgid "Sale Product Customer"
msgstr ""

View File

@@ -0,0 +1,172 @@
# 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 trytond.model import (
MatchMixin, ModelSQL, ModelView, fields, sequence_ordered)
from trytond.modules.product import ProductDeactivatableMixin
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, If
from trytond.tools import is_full_text, lstrip_wildcard
class ProductCustomer(
sequence_ordered(), ProductDeactivatableMixin, MatchMixin,
ModelSQL, ModelView):
__name__ = 'sale.product_customer'
template = fields.Many2One(
'product.template', "Product",
required=True, ondelete='CASCADE',
domain=[
If(Bool(Eval('product')),
('products', '=', Eval('product')),
()),
],
states={
'readonly': Eval('id', -1) >= 0,
})
product = fields.Many2One(
'product.product', "Variant",
domain=[
If(Bool(Eval('template')),
('template', '=', Eval('template')),
()),
],
states={
'readonly': Eval('id', -1) >= 0,
})
party = fields.Many2One(
'party.party', "Customer", required=True, ondelete='CASCADE',
states={
'readonly': Eval('id', -1) >= 0,
})
name = fields.Char("Name", translate=True)
code = fields.Char("Code")
@fields.depends(
'product', '_parent_product.template')
def on_change_product(self):
if self.product:
self.template = self.product.template
def get_rec_name(self, name):
if not self.name and not self.code:
if self.product:
name = self.product.rec_name
else:
name = self.template.rec_name
else:
if self.name:
name = self.name
elif self.product:
name = self.product.name
else:
name = self.template.name
if self.code:
name = '[' + self.code + '] ' + name
return name
@classmethod
def search_rec_name(cls, name, clause):
_, operator, operand, *extra = clause
if operator.startswith('!') or operator.startswith('not '):
bool_op = 'AND'
else:
bool_op = 'OR'
code_value = operand
if operator.endswith('like') and is_full_text(operand):
code_value = lstrip_wildcard(operand)
return [bool_op,
('template', operator, operand, *extra),
('product', operator, operand, *extra),
('party', operator, operand, *extra),
('code', operator, code_value, *extra),
('name', operator, operand, *extra),
]
class Template(metaclass=PoolMeta):
__name__ = 'product.template'
product_customers = fields.One2Many(
'sale.product_customer', 'template', "Customers",
states={
'invisible': ~Eval('salable', False),
})
def product_customer_used(self, **pattern):
for product_customer in self.product_customers:
if product_customer.match(pattern):
yield product_customer
@classmethod
def copy(cls, templates, default=None):
pool = Pool()
ProductCustomer = pool.get('sale.product_customer')
if default is None:
default = {}
else:
default = default.copy()
copy_customers = 'product_customers' not in default
default.setdefault('product_customers', None)
new_templates = super().copy(templates, default)
if copy_customers:
old2new = {}
to_copy = []
for template, new_template in zip(templates, new_templates):
to_copy.extend(
pc for pc in template.product_customers if not pc.product)
old2new[template.id] = new_template.id
if to_copy:
ProductCustomer.copy(to_copy, {
'template': lambda d: old2new[d['template']],
})
return new_templates
class Product(metaclass=PoolMeta):
__name__ = 'product.product'
product_customers = fields.One2Many(
'sale.product_customer', 'product', "Customers",
domain=[
('template', '=', Eval('template', -1)),
],
states={
'invisible': ~Eval('salable', False),
})
def product_customer_used(self, **pattern):
for product_customer in self.product_customers:
if product_customer.match(pattern):
yield product_customer
pattern['product'] = None
yield from self.template.product_customer_used(**pattern)
@classmethod
def copy(cls, products, default=None):
pool = Pool()
ProductCustomer = pool.get('sale.product_customer')
if default is None:
default = {}
else:
default = default.copy()
copy_customers = 'product_customers' not in default
if 'template' in default:
default.setdefault('product_customers', None)
new_products = super().copy(products, default)
if 'template' in default and copy_customers:
template2new = {}
product2new = {}
to_copy = []
for product, new_product in zip(products, new_products):
if product.product_customers:
to_copy.extend(product.product_customers)
template2new[product.template.id] = new_product.template.id
product2new[product.id] = new_product.id
if to_copy:
ProductCustomer.copy(to_copy, {
'product': lambda d: product2new[d['product']],
'template': lambda d: template2new[d['template']],
})
return new_products

View File

@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.ui.view" id="template_view_form">
<field name="model">product.template</field>
<field name="inherit" ref="product.template_view_form"/>
<field name="name">template_form</field>
</record>
</data>
</tryton>

View File

@@ -0,0 +1,228 @@
# 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 trytond.model import fields
from trytond.pool import PoolMeta
from trytond.pyson import Bool, Eval, If
from trytond.tools import cached_property
class Line(metaclass=PoolMeta):
__name__ = 'sale.line'
product_customer = fields.Many2One(
'sale.product_customer', "Customer's Product",
ondelete='RESTRICT',
domain=[
If(Bool(Eval('product')),
['OR',
[
('template.products', '=', Eval('product', -1)),
('product', '=', None),
],
('product', '=', Eval('product', -1)),
],
[]),
('party', '=', Eval('customer', -1)),
],
states={
'invisible': Eval('type') != 'line',
'readonly': Eval('sale_state') != 'draft',
},
depends={'sale'})
@fields.depends('sale', '_parent_sale.party')
def _get_product_customer_pattern(self):
return {
'party': (
self.sale.party.id if self.sale and self.sale.party else -1),
}
@fields.depends('product', 'product_customer',
methods=['_get_product_customer_pattern'])
def on_change_product(self):
super().on_change_product()
if not self.product:
return
product_customers = list(self.product.product_customer_used(
**self._get_product_customer_pattern()))
if len(product_customers) == 1:
self.product_customer, = product_customers
elif (self.product_customer
and self.product_customer not in product_customers):
self.product_customer = None
@fields.depends('product', 'product_customer',
methods=['on_change_product'])
def on_change_product_customer(self):
if self.product_customer:
if self.product_customer.product:
self.product = self.product_customer.product
elif not self.product:
if len(self.product_customer.template.products) == 1:
self.product, = self.product_customer.template.products
self.on_change_product()
@cached_property
def product_name(self):
name = super().product_name
if self.product_customer:
name = self.product_customer.rec_name
return name
class AmendmentLine(metaclass=PoolMeta):
__name__ = 'sale.amendment.line'
product_customer = fields.Many2One(
'sale.product_customer', "Customer's Product",
domain=[
['OR',
[
('template.products', '=', Eval('product', -1)),
('product', '=', None),
],
('product', '=', Eval('product', -1)),
],
('party', '=', Eval('party', -1)),
],
states={
'invisible': Eval('action') != 'line',
})
@fields.depends('line')
def on_change_line(self):
super().on_change_line()
if self.line:
self.product_customer = self.line.product_customer
@fields.depends('product', 'product_customer', 'line')
def on_change_product(self):
try:
super().on_change_product()
except AttributeError:
pass
if not self.product or not self.line:
return
product_customers = list(self.product.product_customer_used(
**self.line._get_product_customer_pattern()))
if len(product_customers) == 1:
self.product_customer, = product_customers
elif (self.product_customer
and self.product_customer not in product_customers):
self.product_customer = None
@fields.depends('product', 'product_customer',
methods=['on_change_product'])
def on_change_product_customer(self):
if self.product_customer:
if self.product_customer.product:
self.product = self.product_customer.product
elif not self.product:
if len(self.product_customer.template.products) == 1:
self.product, = self.product_customer.template.products
self.on_change_product()
def _apply_line(self, sale, sale_line):
super()._apply_line(sale, sale_line)
sale_line.product_customer = self.product_customer
class LineBlanketAgreement(metaclass=PoolMeta):
__name__ = 'sale.line'
@classmethod
def _domain_blanket_agreemnt_line_product(cls):
return [
super()._domain_blanket_agreemnt_line_product(),
If(Eval('product_customer'),
['OR',
('product_customer', '=', Eval('product_customer')),
('product_customer', '=', None),
],
[]),
]
@fields.depends(
'blanket_agreement_line', 'product_customer',
'_parent_blanket_agreement_line.product_customer')
def on_change_blanket_agreement_line(self):
if self.blanket_agreement_line:
line = self.blanket_agreement_line
if not self.product_customer:
self.product_customer = line.product_customer
super().on_change_blanket_agreement_line()
@fields.depends(
'product_customer', '_parent_blanket_agreement_line.product_customer')
def is_valid_product_for_blanket_agreement(self):
return (super().is_valid_product_for_blanket_agreement()
and (
(self.product_customer
== self.blanket_agreement_line.product_customer)
or not self.product_customer))
class BlanketAgreementLine(metaclass=PoolMeta):
__name__ = 'sale.blanket_agreement.line'
product_customer = fields.Many2One(
'sale.product_customer', "Customer's Product", ondelete='RESTRICT',
domain=[
If(Bool(Eval('product')),
['OR',
[
('template.products', '=', Eval('product')),
('product', '=', None),
],
('product', '=', Eval('product')),
],
[]),
('party', '=', Eval('_parent_blanket_agreement', {}).get(
'customer', -1)),
],
states={
'readonly': Eval('agreement_state') != 'draft'
})
@fields.depends('blanket_agreement', '_parent_blanket_agreement.customer')
def _get_product_customer_pattern(self):
return {
'party': (
self.blanket_agreement.customer.id
if self.blanket_agreement and self.blanket_agreement.customer
else -1),
}
@fields.depends('product', 'product_customer')
def on_change_product(self):
try:
super().on_change_product()
except AttributeError:
pass
if not self.product:
return
product_customers = list(self.product.product_customer_used(
**self._get_product_customer_pattern()))
if len(product_customers) == 1:
self.product_customer, = product_customers
elif (self.product_customer
and self.product_customer not in product_customers):
self.product_customer = None
@fields.depends('product', 'product_customer',
methods=['on_change_product'])
def on_change_product_customer(self):
if self.product_customer:
if self.product_customer.product:
self.product = self.product_customer.product
elif not self.product:
if len(self.product_customer.template.products) == 1:
self.product, = self.product_customer.template.products
self.on_change_product()
def get_sale_line(self, sale):
sale_line = super().get_sale_line(sale)
if self.product_customer:
sale_line.product_customer = self.product_customer
return sale_line

View File

@@ -0,0 +1,101 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.ui.view" id="sale_line_view_form">
<field name="model">sale.line</field>
<field name="inherit" ref="sale.sale_line_view_form"/>
<field name="name">sale_line_form</field>
</record>
<record model="ir.ui.view" id="sale_line_view_tree">
<field name="model">sale.line</field>
<field name="inherit" ref="sale.sale_line_view_tree"/>
<field name="name">sale_line_tree</field>
</record>
<record model="ir.ui.view" id="sale_line_view_tree_sequence">
<field name="model">sale.line</field>
<field name="inherit" ref="sale.sale_line_view_tree_sequence"/>
<field name="name">sale_line_tree_sequence</field>
</record>
<record model="ir.ui.view" id="product_customer_view_form">
<field name="model">sale.product_customer</field>
<field name="type">form</field>
<field name="name">product_customer_form</field>
</record>
<record model="ir.ui.view" id="product_customer_view_tree">
<field name="model">sale.product_customer</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">product_customer_tree</field>
</record>
<record model="ir.ui.view" id="product_customer_view_tree_sequence">
<field name="model">sale.product_customer</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="name">product_customer_tree_sequence</field>
</record>
<record model="ir.action.act_window" id="act_product_customer_form">
<field name="name">Customers</field>
<field name="res_model">sale.product_customer</field>
</record>
<record model="ir.action.act_window.view"
id="act_product_customer_list_view">
<field name="sequence" eval="10"/>
<field name="view" ref="product_customer_view_tree"/>
<field name="act_window" ref="act_product_customer_form"/>
</record>
<record model="ir.action.act_window.view"
id="act_product_customer_form_view">
<field name="sequence" eval="20"/>
<field name="view" ref="product_customer_view_form"/>
<field name="act_window" ref="act_product_customer_form"/>
</record>
<menuitem
parent="product.menu_template"
action="act_product_customer_form"
sequence="20"
id="menu_product_customer"/>
<record model="ir.model.access" id="access_product_customer">
<field name="model">sale.product_customer</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_product_customer_sale">
<field name="model">sale.product_customer</field>
<field name="group" ref="sale.group_sale"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
</data>
<data depends="sale_amendment">
<record model="ir.ui.view" id="sale_amendment_line_view_form">
<field name="model">sale.amendment.line</field>
<field name="inherit" ref="sale_amendment.sale_amendment_line_view_form"/>
<field name="name">sale_amendment_line_form</field>
</record>
</data>
<data depends="sale_blanket_agreement">
<record model="ir.ui.view" id="sale_blanket_agreement_line_view_form">
<field name="model">sale.blanket_agreement.line</field>
<field name="inherit" ref="sale_blanket_agreement.sale_blanket_agreement_line_view_form"/>
<field name="name">sale_blanket_agreement_line_form</field>
</record>
<record model="ir.ui.view" id="sale_blanket_agreement_line_view_list">
<field name="model">sale.blanket_agreement.line</field>
<field name="inherit" ref="sale_blanket_agreement.sale_blanket_agreement_line_view_list"/>
<field name="name">sale_blanket_agreement_line_list</field>
</record>
</data>
</tryton>

View File

@@ -0,0 +1,19 @@
# 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 trytond.pool import Pool, PoolMeta
from trytond.tools import cached_property
class Move(metaclass=PoolMeta):
__name__ = 'stock.move'
@cached_property
def product_name(self):
pool = Pool()
SaleLine = pool.get('sale.line')
name = super().product_name
if (isinstance(self.origin, SaleLine)
and self.origin.product_customer):
name = self.origin.product_customer.rec_name
return name

View File

@@ -0,0 +1,2 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

View File

@@ -0,0 +1,52 @@
===================================
Sale Copy Product Customer Scenario
===================================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('sale_product_customer', create_company)
Create party::
>>> Party = Model.get('party.party')
>>> customer = Party(name='customer')
>>> customer.save()
Create a product with customers::
>>> ProductUom = Model.get('product.uom')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> ProductTemplate = Model.get('product.template')
>>> template = ProductTemplate()
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.salable = True
>>> template.list_price = Decimal('10')
>>> template.cost_price_method = 'fixed'
>>> product_customer = template.product_customers.new()
>>> product_customer.party = customer
>>> template.save()
>>> product, = template.products
>>> product_customer = product.product_customers.new()
>>> product_customer.party = customer
>>> assertEqual(product_customer.template, template)
>>> product.save()
Customer is copied when copying the template::
>>> template_copy, = template.duplicate()
>>> product_copy, = template_copy.products
>>> len(template_copy.product_customers)
2
>>> len(product_copy.product_customers)
1

View File

@@ -0,0 +1,68 @@
==============================
Sale Product Customer Scenario
==============================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('sale_product_customer', create_company)
Create parties::
>>> Party = Model.get('party.party')
>>> customer = Party(name='Customer')
>>> customer.save()
Create product::
>>> ProductUom = Model.get('product.uom')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> ProductTemplate = Model.get('product.template')
>>> template = ProductTemplate()
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.salable = True
>>> template.list_price = Decimal('10')
>>> template.save()
>>> product, = template.products
>>> product_customer = product.product_customers.new()
>>> product_customer.party = customer
>>> product_customer.code = 'CUST'
>>> product.save()
Create sale::
>>> Sale = Model.get('sale.sale')
>>> sale = Sale()
>>> sale.party = customer
>>> line = sale.lines.new()
Check filling product customer::
>>> line.product = product
>>> line.product_customer.code
'CUST'
Add product customer to the template::
>>> product_customer2 = template.product_customers.new()
>>> product_customer2.party = customer
>>> product_customer2.code = 'TEMPCUST'
>>> template.save()
Count product linked to customer::
>>> ProductCustomer = Model.get('sale.product_customer')
>>> products = ProductCustomer.find(
... [('party', '=', customer.id)])
>>> len(products)
2

View File

@@ -0,0 +1,13 @@
# 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 trytond.tests.test_tryton import ModuleTestCase
class SaleProductCustomerTestCase(ModuleTestCase):
'Test Sale Product Customer module'
module = 'sale_product_customer'
extras = ['sale_amendment', 'sale_blanket_agreement']
del ModuleTestCase

View File

@@ -0,0 +1,8 @@
# 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 trytond.tests.test_tryton import load_doc_tests
def load_tests(*args, **kwargs):
return load_doc_tests(__name__, __file__, *args, **kwargs)

View File

@@ -0,0 +1,32 @@
[tryton]
version=7.8.0
depends:
account_invoice
ir
product
sale
stock
extras_depend:
sale_amendment
sale_blanket_agreement
xml:
product.xml
sale.xml
[register]
model:
product.Template
product.Product
product.ProductCustomer
sale.Line
account.InvoiceLine
stock.Move
[register sale_amendment]
model:
sale.AmendmentLine
[register sale_blanket_agreement]
model:
sale.LineBlanketAgreement
sale.BlanketAgreementLine

View File

@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<form>
<label name="template"/>
<field name="template" colspan="3"/>
<label name="product"/>
<field name="product" colspan="3"/>
<label name="party"/>
<field name="party"/>
<group id="sequence-active" col="-1" colspan="2">
<label name="sequence"/>
<field name="sequence"/>
<label name="active"/>
<field name="active"/>
</group>
<label name="name"/>
<field name="name"/>
<label name="code"/>
<field name="code"/>
</form>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree>
<field name="template" expand="1"/>
<field name="product" expand="1"/>
<field name="party" expand="2"/>
<field name="name" expand="1"/>
<field name="code"/>
</tree>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree sequence="sequence">
<field name="template" expand="1"/>
<field name="product" expand="1"/>
<field name="party" expand="2"/>
<field name="name" expand="1"/>
<field name="code"/>
</tree>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form/field[@name='product']" position="after">
<label name="product_customer"/>
<field name="product_customer"/>
</xpath>
</data>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="//field[@name='product']" position="after">
<label name="product_customer"/>
<field name="product_customer"/>
</xpath>
</data>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="//field[@name='product']" position="after">
<field name="product_customer" expand="1" optional="1"/>
</xpath>
</data>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form/notebook/page[@id='general']/field[@name='product']" position="after">
<label name="product_customer"/>
<field name="product_customer"/>
</xpath>
</data>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/tree/field[@name='product']" position="after">
<field name="product_customer" optional="1"/>
</xpath>
</data>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/tree/field[@name='product']" position="after">
<field name="product_customer" optional="1"/>
</xpath>
</data>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form/notebook/page[@id='customers']/group[@id='customers_links']" position="before">
<field name="product_customers" colspan="4" view_ids="sale_product_customer.product_customer_view_tree_sequence"/>
</xpath>
</data>