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,46 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Разход"
#, fuzzy
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Цифри за валута"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Каталожна цена"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Продукт"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Приход"
#, fuzzy
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Дейност"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
#, fuzzy
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Покупки"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Cost"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Moneda"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Preu de venda"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Producte"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Línies de compra"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Ingressos"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Projecte/Tasca"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr "Afegiu al cost del Projecte/Tasca."
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Compres"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Projecte"

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr ""
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr ""
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr ""
msgctxt "field:project.work,product:"
msgid "Product"
msgstr ""
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr ""
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr ""
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Kosten"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Währung"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Listenpreis"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Artikel"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Einkaufspositionen"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Veranschlagter Ertrag"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Projektaufgabe"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr "Zu den Kosten des Arbeitsaufwands hinzufügen."
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Einkäufe"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Projekt"

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Coste"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Moneda"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Precio de venta"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Producto"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Líneas de compra"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Ingresos"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Proyecto/Tarea"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr "Añade al coste del Proyecto/Tarea."
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Compras"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Proyecto"

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Costo"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr ""
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr ""
msgctxt "field:project.work,product:"
msgid "Product"
msgstr ""
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr ""
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Esfuerzo de trabajo"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr ""
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,44 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Kulu"
#, fuzzy
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Valuuta numbriline arv"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Müügihind"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Toode"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Ostu read"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Müügitulu"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Pingutus"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr "Lisa pingutuse kulule."
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Ostud"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Projekt"

View File

@@ -0,0 +1,44 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "هزینه"
#, fuzzy
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "رقم های واحد پول"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "لیست قیمت"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "محصول"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "خطوط خرید"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "درآمد"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "تلاش کار"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr "اضافه کردن هزینه تلاش کار."
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "خریدها"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "پروژه"

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr ""
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr ""
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr ""
msgctxt "field:project.work,product:"
msgid "Product"
msgstr ""
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr ""
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr ""
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Coût"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Devise"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Prix listé"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Produit"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Lignes d'achat"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Revenu"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Effort de travail"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr "Ajouter au coût de l'effort de travail."
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Achats"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Projet"

View File

@@ -0,0 +1,46 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
#, fuzzy
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Költség"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr ""
#, fuzzy
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Árlista szerinti ár"
#, fuzzy
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Termék"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr ""
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr ""
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Biaya"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Mata Uang"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr ""
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Produk"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Pendapatan"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr ""
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Costo"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Valuta"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Listino prezzi"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Prodotto"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Linee di acquisto"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Ricavi"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Acquisti"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Progetto"

View File

@@ -0,0 +1,44 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "ລາຄາ"
#, fuzzy
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "ເລກເສດສະກຸນເງິນ"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "ລາຍການລາຄາ"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "ຜະລິດຕະພັນ"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "ລາຍການສັ່ງຊື້"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "ລາຍຮັບ"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "ວຽກສູ້ຊົນ"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "ການຈັດຊື້"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "ໂຄງການ"

View File

@@ -0,0 +1,44 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr ""
#, fuzzy
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Valiutos skaitmenų skaičius"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr ""
msgctxt "field:project.work,product:"
msgid "Product"
msgstr ""
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr ""
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr ""
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Kosten"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Valuta"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Catalogusprijs"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Product"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "aankooplijnen"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Opbrengst/omzet"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Arbeidsinspanning"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr "Voeg toe aan de kosten van de werkinspanning."
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Aankopen"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Project"

View File

@@ -0,0 +1,44 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Koszt"
#, fuzzy
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Cyfry waluty"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Cena sprzedaży"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Produkt"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Wiersze zakupu"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Przychód"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Zakupy"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Projekt"

View File

@@ -0,0 +1,44 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Custo"
#, fuzzy
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Dígitos da Moeda"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Preço de Lista"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Produto"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Linhas de compra"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Receita"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Esforço de trabalho"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr "Adiciona ao custo do trabalho."
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Compras"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Projeto"

View File

@@ -0,0 +1,46 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Cost"
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Monedă"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Lista de preturi"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Produs"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Rânduri de Achiziție"
#, fuzzy
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Venit"
#, fuzzy
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Efort de muncă"
#, fuzzy
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr "Adaugă la costul efortului de muncă."
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Achiziții"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Proiect"

View File

@@ -0,0 +1,46 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Стоимость"
#, fuzzy
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Кол-во цифр валюты"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Цена"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Продукт"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Доходы"
#, fuzzy
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Рабочие затраты"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
#, fuzzy
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Покупки"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,44 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr "Strošek"
#, fuzzy
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr "Decimalke"
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr "Prodajna cena"
msgctxt "field:project.work,product:"
msgid "Product"
msgstr "Izdelek"
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr "Nabavne postavke"
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr "Prihodki"
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr "Ocena naloge"
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr "Nabavni nalogi"
msgctxt "view:purchase.line:"
msgid "Project"
msgstr "Projekt"

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr ""
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr ""
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr ""
msgctxt "field:project.work,product:"
msgid "Product"
msgstr ""
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr ""
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr ""
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr ""
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr ""
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr ""
msgctxt "field:project.work,product:"
msgid "Product"
msgstr ""
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr ""
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr ""
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,43 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:project.work,cost:"
msgid "Cost"
msgstr ""
msgctxt "field:project.work,currency:"
msgid "Currency"
msgstr ""
msgctxt "field:project.work,list_price:"
msgid "List Price"
msgstr ""
msgctxt "field:project.work,product:"
msgid "Product"
msgstr ""
msgctxt "field:project.work,purchase_lines:"
msgid "Purchase Lines"
msgstr ""
msgctxt "field:project.work,revenue:"
msgid "Revenue"
msgstr ""
msgctxt "field:purchase.line,work:"
msgid "Work Effort"
msgstr ""
msgctxt "help:purchase.line,work:"
msgid "Add to the cost of the work effort."
msgstr ""
msgctxt "view:project.work:"
msgid "Purchases"
msgstr ""
msgctxt "view:purchase.line:"
msgid "Project"
msgstr ""

View File

@@ -0,0 +1,20 @@
# 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 Eval
class Line(metaclass=PoolMeta):
__name__ = 'purchase.line'
work = fields.Many2One(
'project.work', "Work Effort",
domain=[
('company', '=', Eval('_parent_purchase', {}).get('company', -1)),
],
states={
'invisible': Eval('type') != 'line',
},
depends={'purchase'},
help="Add to the cost of the work effort.")

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 depends="purchase">
<record model="ir.ui.view" id="purchase_line_view_form">
<field name="model">purchase.line</field>
<field name="inherit" ref="purchase.purchase_line_view_form"/>
<field name="name">purchase_line_form</field>
</record>
</data>
</tryton>

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,133 @@
========================
Project Revenue Scenario
========================
Imports::
>>> import datetime
>>> 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('project_revenue', create_company)
Create customer::
>>> Party = Model.get('party.party')
>>> customer = Party(name='Customer')
>>> customer.save()
Create employee::
>>> Employee = Model.get('company.employee')
>>> employee = Employee()
>>> party = Party(name='Employee')
>>> party.save()
>>> employee.party = party
>>> _ = employee.cost_prices.new(cost_price=Decimal('10.00'))
>>> employee.save()
>>> employee.cost_price
Decimal('10.00')
Create product::
>>> ProductUom = Model.get('product.uom')
>>> hour, = ProductUom.find([('name', '=', 'Hour')])
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> ProductTemplate = Model.get('product.template')
>>> template = ProductTemplate()
>>> template.name = 'Service'
>>> template.default_uom = hour
>>> template.type = 'service'
>>> template.list_price = Decimal('20')
>>> template.save()
>>> product, = template.products
>>> template = ProductTemplate()
>>> template.name = 'Service'
>>> template.default_uom = unit
>>> template.type = 'service'
>>> template.list_price = Decimal('80')
>>> template.save()
>>> package, = template.products
Create a Project::
>>> Project = Model.get('project.work')
>>> project = Project()
>>> project.name = 'Test effort'
>>> project.type = 'project'
>>> project.party = customer
>>> project.timesheet_available = True
>>> project.product = product
>>> project.list_price
Decimal('20.0000')
>>> project.effort_duration = datetime.timedelta(hours=1)
>>> task = project.children.new()
>>> task.name = 'Task 1'
>>> task.type = 'task'
>>> task.timesheet_available = True
>>> task.product = product
>>> task.list_price
Decimal('20.0000')
>>> task.effort_duration = datetime.timedelta(hours=5)
>>> task_no_effort = project.children.new()
>>> task_no_effort.name = "Task 2"
>>> task_no_effort.type = 'task'
>>> task_no_effort.effort_duration = None
>>> task_no_effort.product = package
>>> task_no_effort.list_price
Decimal('80.0000')
>>> project.save()
>>> task, task_no_effort = project.children
Check project revenue and cost::
>>> project.revenue
Decimal('200.00')
>>> task.revenue
Decimal('100.00')
>>> task_no_effort.revenue
Decimal('80.00')
>>> project.cost
Decimal('0.00')
>>> task.cost
Decimal('0.00')
>>> task_no_effort.cost
Decimal('0.00')
Create timesheets::
>>> TimesheetLine = Model.get('timesheet.line')
>>> line = TimesheetLine()
>>> line.employee = employee
>>> line.duration = datetime.timedelta(hours=3)
>>> line.work, = task.timesheet_works
>>> line.save()
>>> line = TimesheetLine()
>>> line.employee = employee
>>> line.duration = datetime.timedelta(hours=2)
>>> line.work, = project.timesheet_works
>>> line.save()
Cost should take in account timesheet lines::
>>> project.reload()
>>> task, task_no_effort = project.children
>>> project.revenue
Decimal('200.00')
>>> task.revenue
Decimal('100.00')
>>> task_no_effort.revenue
Decimal('80.00')
>>> project.cost
Decimal('50.00')
>>> task.cost
Decimal('30.00')
>>> task_no_effort.cost
Decimal('0.00')

View File

@@ -0,0 +1,14 @@
# 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.modules.company.tests import CompanyTestMixin
from trytond.tests.test_tryton import ModuleTestCase
class ProjectRevenueTestCase(CompanyTestMixin, ModuleTestCase):
'Test ProjectRevenue module'
module = 'project_revenue'
extras = ['purchase']
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,22 @@
[tryton]
version=7.8.0
depends:
ir
project
timesheet
timesheet_cost
company
product
extras_depend:
purchase
xml:
work.xml
purchase.xml
[register]
model:
work.Work
[register purchase]
model:
purchase.Line

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. -->
<data>
<xpath
expr="/form/notebook/page[@id='general']" position="after">
<page string="Project" name="work">
<label name="work"/>
<field name="work"/>
</page>
</xpath>
</data>

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. -->
<data>
<xpath expr="/form/notebook/page[@id='general']/label[@name='timesheet_duration']"
position="before">
<label name="product"/>
<field name="product"/>
<label name="list_price"/>
<field name="list_price"/>
<newline/>
</xpath>
<xpath expr="/form/notebook/page[@id='general']/field[@name='total_effort']"
position="after">
<newline/>
<label name="cost"/>
<field name="cost"/>
<label name="revenue"/>
<field name="revenue"/>
</xpath>
</data>

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. -->
<data>
<xpath expr="/form/notebook" position="inside">
<page string="Purchases" id="purchase">
<field name="purchase_lines" colspan="4" widget="many2many"/>
</page>
</xpath>
</data>

View File

@@ -0,0 +1,11 @@
<?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='total_effort']" position="after">
<field name="product" optional="1"/>
<field name="list_price" optional="1"/>
<field name="revenue" optional="0"/>
<field name="cost" optional="0"/>
</xpath>
</data>

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. -->
<data>
<xpath expr="/tree/field[@name='total_effort']" position="after">
<field name="product" optional="1"/>
<field name="list_price" optional="1"/>
<field name="cost" optional="0"/>
</xpath>
</data>

View File

@@ -0,0 +1,11 @@
<?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='total_effort']" position="after">
<field name="product" optional="1"/>
<field name="list_price" optional="1"/>
<field name="revenue" optional="0"/>
<field name="cost" optional="0"/>
</xpath>
</data>

View File

@@ -0,0 +1,227 @@
# 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 as dt
from collections import defaultdict
from decimal import Decimal
from sql.aggregate import Sum
from sql.operators import Concat
from trytond.model import fields
from trytond.modules.currency.fields import Monetary
from trytond.modules.product import price_digits, round_price
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from trytond.tools import grouped_slice, reduce_ids
from trytond.transaction import Transaction
class Work(metaclass=PoolMeta):
__name__ = 'project.work'
product = fields.Many2One('product.product', 'Product',
domain=[
('type', '=', 'service'),
],
context={
'company': Eval('company', -1),
},
depends={'company'})
list_price = Monetary(
"List Price", currency='currency', digits=price_digits)
revenue = fields.Function(Monetary(
"Revenue", currency='currency', digits='currency'),
'get_total')
cost = fields.Function(Monetary(
"Cost", currency='currency', digits='currency'),
'get_total')
currency = fields.Function(fields.Many2One('currency.currency',
'Currency'), 'on_change_with_currency')
@classmethod
def __setup__(cls):
pool = Pool()
super().__setup__()
try:
pool.get('purchase.line')
except KeyError:
pass
else:
# Add purchase lines if purchase is activated
cls.purchase_lines = fields.One2Many('purchase.line', 'work',
'Purchase Lines', domain=[
('purchase.company', '=', Eval('company', -1)),
('type', '=', 'line'),
])
@classmethod
def get_total(cls, works, names):
result = super().get_total(works, names)
currencies = []
for name in names:
field = getattr(cls, name)
if getattr(field, 'digits', None) == 'currency':
currencies.append(name)
if currencies:
for work in works:
for name in currencies:
result[name][work.id] = work.company.currency.round(
result[name][work.id])
return result
@classmethod
def _get_cost(cls, works):
costs = defaultdict(Decimal)
for work_id, cost in cls._timesheet_cost(works):
costs[work_id] += cost
for work_id, cost in cls._purchase_cost(works):
costs[work_id] += cost
return costs
@classmethod
def _timesheet_cost(cls, works):
pool = Pool()
Line = pool.get('timesheet.line')
Work = pool.get('timesheet.work')
transaction = Transaction()
cursor = transaction.connection.cursor()
table = cls.__table__()
work = Work.__table__()
line = Line.__table__()
work_ids = [w.id for w in works]
for sub_ids in grouped_slice(work_ids):
red_sql = reduce_ids(table.id, sub_ids)
cursor.execute(*table.join(work,
condition=(
Concat(cls.__name__ + ',', table.id) == work.origin)
).join(line, condition=line.work == work.id
).select(table.id, Sum(line.cost_price * line.duration),
where=red_sql,
group_by=[table.id]))
for work_id, cost in cursor:
# SQLite stores timedelta as float
if isinstance(cost, dt.timedelta):
cost = cost.total_seconds()
# Convert from seconds
cost /= 60 * 60
yield work_id, Decimal(str(cost))
@classmethod
def _purchase_cost(cls, works):
'Compute direct purchase cost'
if not hasattr(cls, 'purchase_lines'):
return
pool = Pool()
Currency = pool.get('currency.currency')
PurchaseLine = pool.get('purchase.line')
InvoiceLine = pool.get('account.invoice.line')
Invoice = pool.get('account.invoice')
Company = pool.get('company.company')
cursor = Transaction().connection.cursor()
table = cls.__table__()
purchase_line = PurchaseLine.__table__()
invoice_line = InvoiceLine.__table__()
invoice = Invoice.__table__()
company = Company.__table__()
work_ids = [w.id for w in works]
work2currency = {}
iline2work = {}
for sub_ids in grouped_slice(work_ids):
where = reduce_ids(table.id, sub_ids)
cursor.execute(*table.join(purchase_line,
condition=purchase_line.work == table.id
).join(invoice_line,
condition=invoice_line.origin == Concat(
'purchase.line,', purchase_line.id)
).join(invoice,
condition=invoice_line.invoice == invoice.id
).select(invoice_line.id, table.id,
where=where & ~invoice.state.in_(['draft', 'cancelled'])))
iline2work.update(cursor)
cursor.execute(*table.join(company,
condition=table.company == company.id
).select(table.id, company.currency,
where=where))
work2currency.update(cursor)
currencies = Currency.browse(set(work2currency.values()))
id2currency = {c.id: c for c in currencies}
invoice_lines = InvoiceLine.browse(list(iline2work.keys()))
for invoice_line in invoice_lines:
invoice = invoice_line.invoice
work_id = iline2work[invoice_line.id]
currency_id = work2currency[work_id]
currency = id2currency[currency_id]
if currency != invoice.currency:
with Transaction().set_context(date=invoice.currency_date):
amount = Currency.compute(invoice.currency,
invoice_line.amount, currency)
else:
amount = invoice_line.amount
yield work_id, amount
@classmethod
def _get_revenue(cls, works):
revenues = defaultdict(Decimal)
for work in works:
if not work.list_price:
continue
if work.price_list_hour:
revenue = work.list_price * Decimal(str(work.effort_hours))
else:
revenue = work.list_price
revenues[work.id] = revenue
return revenues
@fields.depends('company')
def on_change_with_currency(self, name=None):
return self.company.currency if self.company else None
@fields.depends('product')
def on_change_product(self):
pool = Pool()
ModelData = pool.get('ir.model.data')
Uom = pool.get('product.uom')
if not self.product:
return
list_price = self.product.list_price_used
if list_price is not None:
if self.price_list_hour:
hour_uom = Uom(ModelData.get_id('product', 'uom_hour'))
list_price = Uom.compute_price(
self.product.default_uom, list_price, hour_uom)
list_price = round_price(list_price)
self.list_price = list_price
@property
def price_list_hour(self):
pool = Pool()
ModelData = pool.get('ir.model.data')
Category = pool.get('product.uom.category')
if not self.product:
return
time = Category(ModelData.get_id('product', 'uom_cat_time'))
return self.product.default_uom_category == time
@classmethod
def copy(cls, records, default=None):
if default is None:
default = {}
else:
default = default.copy()
if hasattr(cls, 'purchase_lines'):
# Do not copy purchase lines if purchase is activated
default.setdefault('purchase_lines', None)
return super().copy(records, default=default)

View File

@@ -0,0 +1,41 @@
<?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="work_view_form">
<field name="model">project.work</field>
<field name="inherit" ref="project.work_view_form"/>
<field name="name">work_form</field>
</record>
<record model="ir.ui.view" id="work_view_tree">
<field name="model">project.work</field>
<field name="inherit" ref="project.work_view_tree"/>
<field name="name">work_tree</field>
</record>
<record model="ir.ui.view" id="work_view_list">
<field name="model">project.work</field>
<field name="inherit" ref="project.work_view_list"/>
<field name="name">work_list</field>
</record>
<record model="ir.ui.view" id="work_view_list_children">
<field name="model">project.work</field>
<field name="inherit" ref="project.work_view_list_children"/>
<field name="name">work_list_children</field>
</record>
</data>
<data depends="purchase">
<record model="ir.ui.view" id="work_view_form_purchase">
<field name="model">project.work</field>
<field name="inherit" ref="project.work_view_form"/>
<field name="name">work_form_purchase</field>
</record>
</data>
</tryton>