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,47 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "FIFO количество"
#, fuzzy
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "FIFO количество"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
#, fuzzy
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,50 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "Quantitat FIFO"
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "Quantitat FIFO disponible"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr "Quantitat utilizada pel FIFO."
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr "Quantitat disponible per FIFO"
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"No podeu cancelar el moviment \"%(move)s\" perquè es fa servir en el càlcul "
"del cost FIFO."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"No podeu eliminar el moviment \"%(move)s\" perquè es fa servir en el càlcul "
"del cost FIFO."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
"La quantitat FIFo del moviment no pot ser més gran que la seva quantitat."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,50 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "Menge FIFO"
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "Menge FIFO verfügbar"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr "Menge bei FIFO verwendet."
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr "Menge für FIFO verfügbar"
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Die Warenbewegung \"%(move)s\" kann nicht gelöscht werden, weil sie für die "
"Kalkulation des FIFO Kostenpreis benutzt wird."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Die Warenbewegung \"%(move)s\" kann nicht gelöscht werden, weil sie für die "
"Kalkulation des FIFO Kostenpreis benutzt wird."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
"Die Anzahl FIFO auf der Warenbewegung darf nicht größer als die Anzahl sein."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,49 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "Cantidad FIFO"
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "Cantidad FIFO disponible"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr "Cantidad utilizada para el FIFO."
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr "Cantidad disponible para FIFO"
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"No puede cancelar el movimiento \"%(move)s\" porque se utiliza en el cálculo"
" de precio coste FIFO."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"No puede eliminar el movimiento \"%(move)s\" porque se utiliza en el cálculo"
" de precio coste FIFO."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr "La cantidad FIFO en el movimiento no puede ser mayor que su cantidad."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,50 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "FIFO kogus"
#, fuzzy
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "FIFO kogus"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, fuzzy, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Ei saa kustutada rida \"%(move)s\", mida kasutatakse FIFO hinna "
"arvestamisel."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Ei saa kustutada rida \"%(move)s\", mida kasutatakse FIFO hinna "
"arvestamisel."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr "FIFO kogus real ei või olla suurem kogusest."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,50 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "مقدار FIFO"
#, fuzzy
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "مقدار FIFO"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, fuzzy, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"شما نمیتوانید جابجایی : \"%(move)s\" را حذف کنید چرا که برای محاسبه قیمت "
"هزینه FIFO استفاده می شود."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"شما نمیتوانید جابجایی : \"%(move)s\" را حذف کنید چرا که برای محاسبه قیمت "
"هزینه FIFO استفاده می شود."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr "مقدار FIFO در جابجایی نمی تواند بیشتر از مقدار آن باشد."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,50 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "Quantité PEPS"
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "Quantité PEPS disponible"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr "Quantité utilisée par PEPS."
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr "Quantité disponible pour PEPS"
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Vous ne pouvez pas annuler le mouvement « %(move)s » parce qu'il est utilisé"
" pour le calcul PEPS du prix de revient."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Vous ne pouvez pas supprimer le mouvement « %(move)s » parce qu'il est "
"utilisé pour le calcul PEPS du prix de revient."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
"La quantité PEPS du mouvement ne peut pas être plus grande que sa quantité."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "PEPS"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "PEPS"

View File

@@ -0,0 +1,49 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "FIFO mennyiség"
#, fuzzy
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "FIFO mennyiség"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, fuzzy, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"\"%s\" könyvelési rész nem törölhető, mivel a FIFO ár kalkulációjához "
"használandó."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
#, fuzzy
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,51 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "Quantità FIFO"
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "Quantità FIFO disponibile"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr "Quantità utilizzata dalla FIFO."
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr "Quantità disponibile per la FIFO"
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Non è possibile eliminare il movimento \"%(move)s\" perché viene utilizzato "
"per il calcolo del prezzo di costo FIFO."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Non è possibile eliminare il movimento contabile \"%(move)s\" perché viene "
"utilizzato per il calcolo del prezzo di costo FIFO."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
"La quantità FIFO nel movimento contabile non può essere maggiore della sua "
"quantità."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,50 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "FIFO-hoeveelheid"
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "FIFO Beschikbare hoeveelheid"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr "Hoeveelheid gebruikt door FIFO."
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr "Beschikbare hoeveelheid voor FIFO"
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"U kunt de voorraad boeking \"%(move)s\" niet annuleren omdat deze wordt "
"gebruikt voor de FIFO kostprijsberekening."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"U kunt de beweging \"%(move)s\" niet verwijderen omdat deze wordt gebruikt "
"voor de FIFO-kostprijsberekening."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
"De FIFO hoeveelheid van de beweging kan niet groter zijn dan de hoeveelheid."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,49 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "Ilość FIFO"
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "Dostępna ilość wg FIFO"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr "Ilość wykorzystana w FIFO."
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr "Ilość dostępna dla FIFO"
#, fuzzy, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Nie można usunąć przesunięcia„% (move) s”, ponieważ jest używane do "
"obliczania kosztu własnego wg FIFO."
#, fuzzy, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Nie można usunąć przesunięcia„% (move) s”, ponieważ jest używane do "
"obliczania kosztu własnego wg FIFO."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr "Przesuwana ilość wg FIFO nie może być większa niż jej ilość."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,50 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "Quantidade PEPS"
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "Quantidade PEPS Disponível"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr "Quantidade usada por PEPS."
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr "Quantidade disponível para PEPS"
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Você não pode apagar a movimentação \"%(move)s\" porque é utilizado para o "
"cálculo do preço de custo FIFO."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Não é possível deletar \"%(move)s\" porque está sendo usado para cáculo de "
"preço PEPS."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
"A quantidade PEPS do movimento não pode ser maior que a quantidade total."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "PEPS"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "PEPS"

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,49 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "FIFO količina"
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "Razpoložljiva FIFO količina"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr "Količina, ki jo uporablja FIFO."
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr "Razpoložljiva količina za FIFO"
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Postavke »%(move)s« ne morete preklicati, ker se uporablja za izračun "
"stroškov FIFO."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
"Postavke »%(move)s« ne morete izbrisati, ker se uporablja za izračun "
"stroškov FIFO."
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr "Količina FIFO na postavki ne more biti večja od njene količine."
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,47 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr "FIFO Miktarı"
#, fuzzy
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr "FIFO Miktarı"
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, fuzzy, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr "FIFO maliyet değeri için kullanılan \"%s\" hareketi silinemez."
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
#, fuzzy
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr "FIFO"

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,45 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:stock.move,fifo_quantity:"
msgid "FIFO Quantity"
msgstr ""
msgctxt "field:stock.move,fifo_quantity_available:"
msgid "FIFO Quantity Available"
msgstr ""
msgctxt "help:stock.move,fifo_quantity:"
msgid "Quantity used by FIFO."
msgstr ""
msgctxt "help:stock.move,fifo_quantity_available:"
msgid "Quantity available for FIFO"
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_cancel_fifo"
msgid ""
"You cannot cancel move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
#, python-format
msgctxt "model:ir.message,text:msg_move_delete_fifo"
msgid ""
"You cannot delete move \"%(move)s\" because it is used for FIFO cost price "
"calculation."
msgstr ""
msgctxt "model:ir.message,text:msg_move_fifo_quantity_greater"
msgid "The FIFO quantity on move cannot be greater than its quantity."
msgstr ""
msgctxt "selection:product.product,cost_price_method:"
msgid "FIFO"
msgstr ""
msgctxt "selection:product.template,cost_price_method:"
msgid "FIFO"
msgstr ""

View File

@@ -0,0 +1,16 @@
<?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 grouped="1">
<record model="ir.message" id="msg_move_cancel_fifo">
<field name="text">You cannot cancel move "%(move)s" because it is used for FIFO cost price calculation.</field>
</record>
<record model="ir.message" id="msg_move_delete_fifo">
<field name="text">You cannot delete move "%(move)s" because it is used for FIFO cost price calculation.</field>
</record>
<record model="ir.message" id="msg_move_fifo_quantity_greater">
<field name="text">The FIFO quantity on move cannot be greater than its quantity.</field>
</record>
</data>
</tryton>

View File

@@ -0,0 +1,175 @@
# 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 decimal import Decimal
from sql import Literal, operators
from trytond.i18n import gettext
from trytond.model import Check, ModelView, Workflow, fields
from trytond.model.exceptions import AccessError
from trytond.modules.product import round_price
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from trytond.transaction import Transaction
class Move(metaclass=PoolMeta):
__name__ = 'stock.move'
fifo_quantity = fields.Float(
"FIFO Quantity", required=True,
domain=[
('fifo_quantity', '<=', Eval('quantity', 0)),
],
help="Quantity used by FIFO.")
fifo_quantity_available = fields.Function(fields.Float(
"FIFO Quantity Available",
help="Quantity available for FIFO"),
'get_fifo_quantity_available')
@classmethod
def __setup__(cls):
super().__setup__()
cls._allow_modify_closed_period.add('fifo_quantity')
t = cls.__table__()
cls._sql_constraints += [
('check_fifo_quantity',
Check(t, t.quantity >= t.fifo_quantity),
'product_cost_fifo.msg_move_fifo_quantity_greater'),
]
@classmethod
def __register__(cls, module):
table_h = cls.__table_handler__(module)
super().__register__(module)
# Migration from 6.6: rename check_fifo_quantity_out to
# check_fifo_quantity
table_h.drop_constraint('check_fifo_quantity_out')
@staticmethod
def default_fifo_quantity():
return 0.0
def get_fifo_quantity_available(self, name):
return self.quantity - (self.fifo_quantity or 0)
@classmethod
def domain_fifo_quantity_available(cls, domain, tables):
table, _ = tables[None]
name, operator, value = domain
field = cls.fifo_quantity_available._field
Operator = fields.SQL_OPERATORS[operator]
column = (
cls.quantity.sql_column(table)
- cls.fifo_quantity.sql_column(table))
expression = Operator(column, field._domain_value(operator, value))
if isinstance(expression, operators.In) and not expression.right:
expression = Literal(False)
elif isinstance(expression, operators.NotIn) and not expression.right:
expression = Literal(True)
expression = field._domain_add_null(
column, operator, value, expression)
return expression
def _update_fifo_out_product_cost_price(self):
'''
Update the product cost price of the given product on the move. Update
fifo_quantity on the concerned incoming moves. Return the
cost price for outputing the given product and quantity.
'''
pool = Pool()
Uom = pool.get('product.uom')
total_qty = Uom.compute_qty(
self.unit, self.quantity, self.product.default_uom, round=False)
with Transaction().set_context(company=self.company.id):
fifo_moves = self.product.get_fifo_move(total_qty)
cost_price = Decimal(0)
consumed_qty = 0.0
to_save = []
for move, move_qty in fifo_moves:
consumed_qty += move_qty
cost_price += move.get_cost_price() * Decimal(str(move_qty))
move_qty = Uom.compute_qty(
self.product.default_uom, move_qty, move.unit, round=False)
move.fifo_quantity = (move.fifo_quantity or 0.0) + move_qty
# Due to float, the fifo quantity result can exceed the quantity.
assert move.quantity >= move.fifo_quantity - move.unit.rounding
move.fifo_quantity = min(move.fifo_quantity, move.quantity)
to_save.append(move)
if consumed_qty:
cost_price = cost_price / Decimal(str(consumed_qty))
else:
cost_price = self.product.get_multivalue(
'cost_price', **self._cost_price_pattern)
# Compute average cost price
average_cost_price = self._compute_product_cost_price(
'out', product_cost_price=cost_price)
if cost_price:
cost_price = round_price(cost_price)
else:
cost_price = average_cost_price
return cost_price, average_cost_price, to_save
def _do(self):
cost_price, to_save = super()._do()
cost_price_method = self.product.get_multivalue(
'cost_price_method', **self._cost_price_pattern)
if (self.from_location.type != 'storage'
and self.to_location.type == 'storage'
and cost_price_method == 'fifo'):
cost_price = self._compute_product_cost_price('in')
elif (self.to_location.type == 'supplier'
and self.from_location.type == 'storage'
and cost_price_method == 'fifo'):
cost_price = self._compute_product_cost_price('out')
elif (self.from_location.type == 'storage'
and self.to_location.type != 'storage'
and cost_price_method == 'fifo'):
fifo_cost_price, cost_price, moves = (
self._update_fifo_out_product_cost_price())
if self.cost_price_required:
if self.cost_price is None:
self.cost_price = fifo_cost_price
if self.product_cost_price is None:
self.product_cost_price = cost_price
to_save.extend(moves)
return cost_price, to_save
@classmethod
@ModelView.button
@Workflow.transition('cancelled')
def cancel(cls, moves):
for move in moves:
if move.fifo_quantity:
raise AccessError(
gettext('product_cost_fifo.msg_move_cancel_fifo',
move=move.rec_name))
super().cancel(moves)
@classmethod
def check_modification(cls, mode, moves, values=None, external=False):
super().check_modification(
mode, moves, values=values, external=external)
if mode == 'delete':
for move in moves:
if move.fifo_quantity:
raise AccessError(gettext(
'product_cost_fifo.msg_move_delete_fifo',
move=move.rec_name))
@classmethod
def copy(cls, moves, default=None):
if default is None:
default = {}
else:
default = default.copy()
default.setdefault('fifo_quantity', cls.default_fifo_quantity())
return super().copy(moves, default=default)

View File

@@ -0,0 +1,258 @@
# 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 decimal import Decimal
import trytond.config as config
from trytond.modules.product import round_price
from trytond.pool import Pool, PoolMeta
class Template(metaclass=PoolMeta):
__name__ = 'product.template'
@classmethod
def __setup__(cls):
super().__setup__()
new_sel = ('fifo', 'FIFO')
if new_sel not in cls.cost_price_method.selection:
cls.cost_price_method._field.selection.append(new_sel)
class Product(metaclass=PoolMeta):
__name__ = 'product.product'
def _get_available_fifo_moves(self, date=None, offset=0, limit=None):
pool = Pool()
Move = pool.get('stock.move')
domain = [
('product', '=', self.id),
self._domain_moves_cost(),
('from_location.type', '!=', 'storage'),
('to_location.type', '=', 'storage'),
]
if not date:
domain.append(('fifo_quantity_available', '>', 0))
else:
domain.append(('effective_date', '<=', date))
return Move.search(
domain,
offset=offset, limit=limit,
order=[('effective_date', 'DESC'), ('id', 'DESC')])
def get_fifo_move(self, quantity=0.0, date=None):
'''
Return a list of (move, qty) where move is the move to be
consumed and qty is the quantity (in the product default uom)
to be consumed on this move. The list contains the "first in"
moves for the given quantity.
'''
pool = Pool()
Uom = pool.get('product.uom')
avail_qty = self._get_storage_quantity(date=date)
if date:
# On recomputation, we must pretend
# outgoing moves are not yet done.
avail_qty += quantity
fifo_moves = []
size = config.getint('cache', 'record')
def moves():
offset, limit = 0, size
while True:
moves = self._get_available_fifo_moves(
date=date, offset=offset, limit=limit)
if not moves:
break
for move in moves:
yield move
offset += size
for move in moves():
qty = move.fifo_quantity_available if not date else move.quantity
qty = Uom.compute_qty(
move.unit, qty, self.default_uom, round=False)
avail_qty -= qty
if avail_qty <= quantity:
if avail_qty > 0.0:
fifo_moves.append(
(move, min(qty, quantity - avail_qty)))
else:
fifo_moves.append(
(move, min(quantity, qty + avail_qty)))
break
fifo_moves.reverse()
return fifo_moves
def recompute_cost_price_fifo(self, start=None):
pool = Pool()
Move = pool.get('stock.move')
Uom = pool.get('product.uom')
Revision = pool.get('product.cost_price.revision')
domain = [
('product', '=', self.id),
self._domain_moves_cost(),
['OR',
self._domain_in_moves_cost(),
self._domain_out_moves_cost(),
]
]
if start:
domain.append(('effective_date', '>=', start))
moves = Move.search(
domain, order=[('effective_date', 'ASC'), ('id', 'ASC')])
_in_moves = Move.search([
('product', '=', self.id),
self._domain_moves_cost(),
self._domain_in_moves_cost(),
], order=[])
_in_moves = set(m.id for m in _in_moves)
revisions = Revision.get_for_product(self)
cost_price = Decimal(0)
quantity = 0
if start:
domain.remove(('effective_date', '>=', start))
domain.append(('effective_date', '<', start))
domain.append(self._domain_in_moves_cost())
prev_moves = Move.search(
domain,
order=[('effective_date', 'DESC'), ('id', 'DESC')],
limit=1)
if prev_moves:
move, = prev_moves
cost_price = move.cost_price
quantity = self._get_storage_quantity(
date=start - dt.timedelta(days=1))
quantity = Decimal(str(quantity))
def in_move(move):
return move.id in _in_moves
def out_move(move):
return not in_move(move)
def production_move(move):
return (
move.from_location.type == 'production'
or move.to_location.type == 'production')
def compute_fifo_cost_price(quantity, date):
fifo_moves = self.get_fifo_move(float(quantity), date=date)
cost_price = Decimal(0)
consumed_qty = 0
for move, move_qty in fifo_moves:
consumed_qty += move_qty
cost_price += move.get_cost_price() * Decimal(str(move_qty))
if consumed_qty:
return round_price(cost_price / Decimal(str(consumed_qty)))
# For each day, process the incoming moves first
# in order to keep quantity positive where possible
# We do not re-browse because we expect only small changes
moves = sorted(moves, key=lambda m: (
m.effective_date,
out_move(m) or (in_move(m) and production_move(m)),
m.id))
current_moves = []
current_out_qty = 0
current_cost_price = cost_price
qty_production = 0
for move in moves:
if (current_moves
and current_moves[-1].effective_date
!= move.effective_date):
Move.write([
m for m in filter(in_move, current_moves)
if m.cost_price != current_cost_price],
dict(cost_price=current_cost_price))
out_moves = list(filter(out_move, current_moves))
if out_moves:
fifo_cost_price = compute_fifo_cost_price(
current_out_qty, current_moves[-1].effective_date)
if fifo_cost_price is None:
fifo_cost_price = current_cost_price
if quantity > 0 and quantity + current_out_qty >= 0:
cost_price = (
((current_cost_price * (
quantity + current_out_qty))
- (fifo_cost_price * current_out_qty))
/ quantity)
else:
cost_price = current_cost_price
current_cost_price = round_price(cost_price)
Move.write([
m for m in out_moves
if m.cost_price != fifo_cost_price
or m.product_cost_price != current_cost_price],
dict(
cost_price=fifo_cost_price,
product_cost_price=current_cost_price))
current_moves.clear()
current_out_qty = 0
qty_production = 0
current_moves.append(move)
cost_price = Revision.apply_up_to(
revisions, cost_price, move.effective_date)
qty = Uom.compute_qty(move.unit, move.quantity, self.default_uom)
qty = Decimal(str(qty))
if out_move(move):
qty *= -1
if in_move(move):
in_qty = qty
if production_move(move) and qty_production < 0:
# Exclude quantity coming back from production
in_qty -= min(abs(qty_production), in_qty)
unit_price = move.get_cost_price(product_cost_price=cost_price)
if quantity + in_qty > 0 and quantity >= 0:
cost_price = (
(cost_price * quantity) + (unit_price * in_qty)
) / (quantity + in_qty)
elif in_qty > 0:
cost_price = unit_price
current_cost_price = round_price(cost_price)
elif out_move(move):
current_out_qty += -qty
quantity += qty
if production_move(move):
qty_production += qty
Move.write([
m for m in filter(in_move, current_moves)
if m.cost_price != current_cost_price],
dict(cost_price=current_cost_price))
out_moves = list(filter(out_move, current_moves))
if out_moves:
fifo_cost_price = compute_fifo_cost_price(
current_out_qty, current_moves[-1].effective_date)
if fifo_cost_price is None:
fifo_cost_price = current_cost_price
if quantity > 0:
cost_price = (
((cost_price * (quantity + current_out_qty))
- (fifo_cost_price * current_out_qty))
/ quantity)
else:
cost_price = current_cost_price
current_cost_price = round_price(cost_price)
Move.write([
m for m in out_moves
if m.cost_price != fifo_cost_price
or m.product_cost_price != current_cost_price],
dict(
cost_price=fifo_cost_price,
product_cost_price=current_cost_price))
for revision in revisions:
cost_price = revision.get_cost_price(cost_price)
return cost_price

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,154 @@
=====================
Stock FIFO Cost Price
=====================
Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.company.tests.tools import create_company, get_company
>>> from trytond.tests.tools import activate_modules
>>> today = dt.date.today()
Activate modules::
>>> config = activate_modules('product_cost_fifo', create_company)
Get company::
>>> company = get_company()
Create product::
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'Product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.list_price = Decimal('300')
>>> template.cost_price_method = 'fifo'
>>> product, = template.products
>>> product.cost_price = Decimal('80')
>>> template.save()
>>> product, = template.products
Get stock locations::
>>> Location = Model.get('stock.location')
>>> supplier_loc, = Location.find([('code', '=', 'SUP')])
>>> customer_loc, = Location.find([('code', '=', 'CUS')])
>>> storage_loc, = Location.find([('code', '=', 'STO')])
>>> production_loc = Location(name="Production", type='production')
>>> production_loc.save()
Make 4 units of the product available @ 10 ::
>>> StockMove = Model.get('stock.move')
>>> incoming_move = StockMove()
>>> incoming_move.product = product
>>> incoming_move.unit = unit
>>> incoming_move.quantity = 4
>>> incoming_move.from_location = supplier_loc
>>> incoming_move.to_location = storage_loc
>>> incoming_move.planned_date = today
>>> incoming_move.company = company
>>> incoming_move.unit_price = Decimal('10')
>>> incoming_move.currency = company.currency
>>> incoming_move.click('do')
Check Cost Price is 10::
>>> product.reload()
>>> product.cost_price
Decimal('10.0000')
Add 2 more units @ 25 from production::
>>> incoming_move = StockMove()
>>> incoming_move.product = product
>>> incoming_move.unit = unit
>>> incoming_move.quantity = 2
>>> incoming_move.from_location = production_loc
>>> incoming_move.to_location = storage_loc
>>> incoming_move.planned_date = today
>>> incoming_move.company = company
>>> incoming_move.unit_price = Decimal('25')
>>> incoming_move.currency = company.currency
>>> incoming_move.click('do')
Check Cost Price FIFO is 15::
>>> product.reload()
>>> product.cost_price
Decimal('15.0000')
Sell 3 units @ 50::
>>> outgoing_move = StockMove()
>>> outgoing_move.product = product
>>> outgoing_move.unit = unit
>>> outgoing_move.quantity = 3
>>> outgoing_move.from_location = storage_loc
>>> outgoing_move.to_location = customer_loc
>>> outgoing_move.planned_date = today
>>> outgoing_move.company = company
>>> outgoing_move.unit_price = Decimal('50')
>>> outgoing_move.currency = company.currency
>>> outgoing_move.click('do')
Check Cost Price FIFO is 20 and cost is 10::
>>> product.reload()
>>> product.cost_price
Decimal('20.0000')
>>> outgoing_move.cost_price
Decimal('10.0000')
>>> outgoing_move.product_cost_price
Decimal('20.0000')
Sell twice 1 more units @ 50::
>>> outgoing_moves = []
>>> outgoing_move = StockMove()
>>> outgoing_move.product = product
>>> outgoing_move.unit = unit
>>> outgoing_move.quantity = 1
>>> outgoing_move.from_location = storage_loc
>>> outgoing_move.to_location = customer_loc
>>> outgoing_move.planned_date = today
>>> outgoing_move.company = company
>>> outgoing_move.unit_price = Decimal('50')
>>> outgoing_move.currency = company.currency
>>> outgoing_move.save()
>>> outgoing_moves.append(outgoing_move)
>>> outgoing_move = StockMove()
>>> outgoing_move.product = product
>>> outgoing_move.unit = unit
>>> outgoing_move.quantity = 1
>>> outgoing_move.from_location = storage_loc
>>> outgoing_move.to_location = customer_loc
>>> outgoing_move.planned_date = today
>>> outgoing_move.company = company
>>> outgoing_move.unit_price = Decimal('50')
>>> outgoing_move.currency = company.currency
>>> outgoing_move.save()
>>> outgoing_moves.append(outgoing_move)
>>> StockMove.click(outgoing_moves, 'do')
Check Cost Price FIFO is 25 and costs are 10 and 25::
>>> product.reload()
>>> product.cost_price
Decimal('25.0000')
>>> [m.cost_price for m in outgoing_moves]
[Decimal('10.0000'), Decimal('25.0000')]
>>> [m.product_cost_price for m in outgoing_moves]
[Decimal('25.0000'), Decimal('25.0000')]

View File

@@ -0,0 +1,100 @@
===================================
Stock FIFO Cost Price with no Input
===================================
Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.company.tests.tools import create_company, get_company
>>> from trytond.tests.tools import activate_modules
>>> today = dt.date.today()
Activate modules::
>>> config = activate_modules('product_cost_fifo', create_company)
Get company::
>>> company = get_company()
Create product::
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'Product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.list_price = Decimal('300')
>>> template.cost_price_method = 'fifo'
>>> product, = template.products
>>> product.cost_price = Decimal('80')
>>> template.save()
>>> product, = template.products
Get stock locations::
>>> Location = Model.get('stock.location')
>>> supplier_loc, = Location.find([('code', '=', 'SUP')])
>>> customer_loc, = Location.find([('code', '=', 'CUS')])
>>> storage_loc, = Location.find([('code', '=', 'STO')])
Make 2 units of the product not available @ 60 and 80 ::
>>> StockMove = Model.get('stock.move')
>>> incoming_move = StockMove()
>>> incoming_move.product = product
>>> incoming_move.unit = unit
>>> incoming_move.quantity = 1
>>> incoming_move.from_location = supplier_loc
>>> incoming_move.to_location = storage_loc
>>> incoming_move.planned_date = today
>>> incoming_move.company = company
>>> incoming_move.unit_price = Decimal('60')
>>> incoming_move.currency = company.currency
>>> incoming_move.fifo_quantity = 1
>>> incoming_move.click('do')
>>> incoming_move = StockMove()
>>> incoming_move.product = product
>>> incoming_move.unit = unit
>>> incoming_move.quantity = 1
>>> incoming_move.from_location = supplier_loc
>>> incoming_move.to_location = storage_loc
>>> incoming_move.planned_date = today
>>> incoming_move.company = company
>>> incoming_move.unit_price = Decimal('80')
>>> incoming_move.currency = company.currency
>>> incoming_move.fifo_quantity = 1
>>> incoming_move.click('do')
Sell 1 unit @ 200::
>>> StockMove = Model.get('stock.move')
>>> outgoing_move = StockMove()
>>> outgoing_move.product = product
>>> outgoing_move.unit = unit
>>> outgoing_move.quantity = 1
>>> outgoing_move.from_location = storage_loc
>>> outgoing_move.to_location = customer_loc
>>> outgoing_move.planned_date = today
>>> outgoing_move.company = company
>>> outgoing_move.unit_price = Decimal('200')
>>> outgoing_move.currency = company.currency
>>> outgoing_move.click('do')
Check Cost Price FIFO is the current cost price::
>>> product.reload()
>>> product.cost_price
Decimal('70.0000')
>>> outgoing_move.cost_price
Decimal('70.0000')
>>> outgoing_move.product_cost_price
Decimal('70.0000')

View File

@@ -0,0 +1,142 @@
======================================
Product Cost FIFO Recompute Cost Price
======================================
Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.company.tests.tools import create_company, get_company
>>> from trytond.tests.tools import activate_modules
>>> today = dt.date.today()
Activate modules::
>>> config = activate_modules('product_cost_fifo', create_company)
Get company::
>>> company = get_company()
Create product::
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'Product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.list_price = Decimal('300')
>>> template.cost_price_method = 'fifo'
>>> product, = template.products
>>> product.cost_price = Decimal('80')
>>> template.save()
>>> product, = template.products
Get stock locations::
>>> Location = Model.get('stock.location')
>>> supplier_loc, = Location.find([('code', '=', 'SUP')])
>>> storage_loc, = Location.find([('code', '=', 'STO')])
>>> customer_loc, = Location.find([('code', '=', 'CUS')])
>>> lost_found, = Location.find([('name', '=', "Lost and Found")])
Create some moves::
>>> StockMove = Model.get('stock.move')
>>> StockMove(
... product=product,
... quantity=1,
... from_location=supplier_loc,
... to_location=storage_loc,
... unit_price=Decimal('100'),
... currency=company.currency,
... effective_date=today - dt.timedelta(days=2)).click('do')
>>> StockMove(
... product=product,
... quantity=2,
... from_location=supplier_loc,
... to_location=storage_loc,
... unit_price=Decimal('120'),
... currency=company.currency,
... effective_date=today - dt.timedelta(days=1)).click('do')
>>> StockMove(
... product=product,
... quantity=1,
... from_location=lost_found,
... to_location=storage_loc,
... effective_date=today - dt.timedelta(days=1)).click('do')
>>> StockMove(
... product=product,
... quantity=2,
... from_location=storage_loc,
... to_location=customer_loc,
... unit_price=Decimal('300'),
... currency=company.currency,
... effective_date=today - dt.timedelta(days=1)).click('do')
>>> StockMove(
... product=product,
... quantity=3,
... from_location=supplier_loc,
... to_location=storage_loc,
... unit_price=Decimal('100'),
... currency=company.currency,
... effective_date=today).click('do')
>>> StockMove(
... product=product,
... quantity=2,
... from_location=storage_loc,
... to_location=customer_loc,
... unit_price=Decimal('300'),
... currency=company.currency,
... effective_date=today).click('do')
>>> StockMove(
... product=product,
... quantity=1,
... from_location=storage_loc,
... to_location=lost_found,
... effective_date=today).click('do')
>>> [m.cost_price for m in StockMove.find([])]
[Decimal('100.0000'), Decimal('116.6666'), Decimal('106.6666'), Decimal('110.0000'), Decimal('113.3333'), Decimal('113.3333'), Decimal('100.0000')]
>>> [m.product_cost_price for m in StockMove.find([])]
[Decimal('99.9998'), Decimal('99.9999'), None, Decimal('116.6666'), None, None, None]
>>> product.reload()
>>> product.cost_price
Decimal('99.9998')
Recompute cost price::
>>> recompute = Wizard('product.recompute_cost_price', [product])
>>> recompute.execute('recompute')
>>> [m.cost_price for m in StockMove.find([])]
[Decimal('111.1111'), Decimal('111.1111'), Decimal('106.6666'), Decimal('110.0000'), Decimal('113.3333'), Decimal('113.3333'), Decimal('100.0000')]
>>> [m.product_cost_price for m in StockMove.find([])]
[Decimal('100.0000'), Decimal('100.0000'), None, Decimal('116.6666'), None, None, None]
>>> product.reload()
>>> product.cost_price
Decimal('100.0000')
Recompute cost price from a date::
>>> recompute = Wizard('product.recompute_cost_price', [product])
>>> recompute.form.from_ = today - dt.timedelta(days=1)
>>> recompute.execute('recompute')
>>> [m.cost_price for m in StockMove.find([])]
[Decimal('111.1111'), Decimal('111.1111'), Decimal('106.6666'), Decimal('110.0000'), Decimal('113.3333'), Decimal('113.3333'), Decimal('100.0000')]
>>> product.reload()
>>> product.cost_price
Decimal('100.0000')

View File

@@ -0,0 +1,112 @@
=================================================
Product Cost FIFO Recompute Cost Price Production
=================================================
Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.company.tests.tools import create_company, get_company
>>> from trytond.tests.tools import activate_modules
>>> today = dt.date.today()
>>> yesterday = today - dt.timedelta(days=1)
Activate modules::
>>> config = activate_modules('product_cost_fifo', create_company)
>>> Location = Model.get('stock.location')
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> StockMove = Model.get('stock.move')
Get company::
>>> company = get_company()
Create product::
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'Product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.list_price = Decimal('50.0000')
>>> template.cost_price_method = 'fifo'
>>> product, = template.products
>>> product.cost_price = Decimal('40.0000')
>>> template.save()
>>> product, = template.products
Get stock locations::
>>> supplier_loc, = Location.find([('code', '=', 'SUP')])
>>> storage_loc, = Location.find([('code', '=', 'STO')])
>>> production_loc = Location(name="Production", type='production')
>>> production_loc.save()
Consume product for production and reverse some::
>>> StockMove(
... product=product,
... quantity=10,
... from_location=storage_loc,
... to_location=production_loc,
... effective_date=today).click('do')
>>> StockMove(
... product=product,
... quantity=2,
... from_location=production_loc,
... to_location=storage_loc,
... unit_price=Decimal('40.0000'),
... currency=company.currency,
... effective_date=today).click('do')
>>> [m.cost_price for m in StockMove.find([])]
[Decimal('40.0000'), Decimal('40.0000')]
>>> [m.product_cost_price for m in StockMove.find([])]
[None, Decimal('40.0000')]
Recompute cost price::
>>> recompute = Wizard('product.recompute_cost_price', [product])
>>> recompute.execute('recompute')
>>> [m.cost_price for m in StockMove.find([])]
[Decimal('0.0000'), Decimal('40.0000')]
>>> [m.product_cost_price for m in StockMove.find([])]
[None, Decimal('0.0000')]
>>> product.reload()
>>> product.cost_price
Decimal('0.0000')
Receive product yesterday at new cost::
>>> StockMove(
... product=product,
... quantity=16,
... from_location=supplier_loc,
... to_location=storage_loc,
... unit_price=Decimal('20.0000'),
... currency=company.currency,
... effective_date=yesterday).click('do')
Recompute cost price::
>>> recompute = Wizard('product.recompute_cost_price', [product])
>>> recompute.execute('recompute')
>>> [m.cost_price for m in StockMove.find([])]
[Decimal('20.0000'), Decimal('20.0000'), Decimal('20.0000')]
>>> [m.product_cost_price for m in StockMove.find([])]
[None, None, Decimal('20.0000')]
>>> product.reload()
>>> product.cost_price
Decimal('20.0000')

View File

@@ -0,0 +1,149 @@
=========================
Stock FIFO Cost Price UoM
=========================
Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.company.tests.tools import create_company, get_company
>>> from trytond.tests.tools import activate_modules
>>> today = dt.date.today()
Activate modules::
>>> config = activate_modules('product_cost_fifo', create_company)
Get company::
>>> company = get_company()
Create product::
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> kg, = ProductUom.find([('name', '=', 'Kilogram')])
>>> g, = ProductUom.find([('name', '=', 'Gram')])
>>> template = ProductTemplate()
>>> template.name = 'Product'
>>> template.default_uom = kg
>>> template.type = 'goods'
>>> template.list_price = Decimal('300')
>>> template.cost_price_method = 'fifo'
>>> product, = template.products
>>> product.cost_price = Decimal('80')
>>> template.save()
>>> product, = template.products
Get stock locations::
>>> Location = Model.get('stock.location')
>>> supplier_loc, = Location.find([('code', '=', 'SUP')])
>>> customer_loc, = Location.find([('code', '=', 'CUS')])
>>> storage_loc, = Location.find([('code', '=', 'STO')])
Make 4 kg of the product available @ 10 ::
>>> StockMove = Model.get('stock.move')
>>> incoming_move = StockMove()
>>> incoming_move.product = product
>>> incoming_move.unit = kg
>>> incoming_move.quantity = 4
>>> incoming_move.from_location = supplier_loc
>>> incoming_move.to_location = storage_loc
>>> incoming_move.planned_date = today
>>> incoming_move.company = company
>>> incoming_move.unit_price = Decimal('10')
>>> incoming_move.currency = company.currency
>>> incoming_move.click('do')
Check Cost Price is 10::
>>> product.reload()
>>> product.cost_price
Decimal('10.0000')
Add 2000 more g @ 0.025::
>>> incoming_move = StockMove()
>>> incoming_move.product = product
>>> incoming_move.unit = g
>>> incoming_move.quantity = 2000
>>> incoming_move.from_location = supplier_loc
>>> incoming_move.to_location = storage_loc
>>> incoming_move.planned_date = today
>>> incoming_move.company = company
>>> incoming_move.unit_price = Decimal('0.025')
>>> incoming_move.currency = company.currency
>>> incoming_move.click('do')
Check Cost Price FIFO is 15::
>>> product.reload()
>>> product.cost_price
Decimal('15.0000')
Sell 3 kg @ 50::
>>> outgoing_move = StockMove()
>>> outgoing_move.product = product
>>> outgoing_move.unit = kg
>>> outgoing_move.quantity = 3
>>> outgoing_move.from_location = storage_loc
>>> outgoing_move.to_location = customer_loc
>>> outgoing_move.planned_date = today
>>> outgoing_move.company = company
>>> outgoing_move.unit_price = Decimal('50')
>>> outgoing_move.currency = company.currency
>>> outgoing_move.click('do')
Check Cost Price FIFO is 20 and cost is 10::
>>> product.reload()
>>> product.cost_price
Decimal('20.0000')
>>> outgoing_move.cost_price
Decimal('10.0000')
Sell twice 1 more kg @ 50::
>>> outgoing_moves = []
>>> outgoing_move = StockMove()
>>> outgoing_move.product = product
>>> outgoing_move.unit = kg
>>> outgoing_move.quantity = 1
>>> outgoing_move.from_location = storage_loc
>>> outgoing_move.to_location = customer_loc
>>> outgoing_move.planned_date = today
>>> outgoing_move.company = company
>>> outgoing_move.unit_price = Decimal('50')
>>> outgoing_move.currency = company.currency
>>> outgoing_move.save()
>>> outgoing_moves.append(outgoing_move)
>>> outgoing_move = StockMove()
>>> outgoing_move.product = product
>>> outgoing_move.unit = g
>>> outgoing_move.quantity = 1000
>>> outgoing_move.from_location = storage_loc
>>> outgoing_move.to_location = customer_loc
>>> outgoing_move.planned_date = today
>>> outgoing_move.company = company
>>> outgoing_move.unit_price = Decimal('0.05')
>>> outgoing_move.currency = company.currency
>>> outgoing_move.save()
>>> outgoing_moves.append(outgoing_move)
>>> StockMove.click(outgoing_moves, 'do')
Check Cost Price FIFO is 25 and costs are 10 and 25::
>>> product.reload()
>>> product.cost_price
Decimal('25.0000')
>>> [m.cost_price for m in outgoing_moves]
[Decimal('10.0000'), Decimal('25.0000')]

View File

@@ -0,0 +1,12 @@
# 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 ProductCostFIFOTestCase(ModuleTestCase):
'Test ProductCostFIFO module'
module = 'product_cost_fifo'
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,14 @@
[tryton]
version=7.8.0
depends:
ir
product
stock
xml:
message.xml
[register]
model:
product.Template
product.Product
move.Move