forked from Vauxoo/addons-vauxoo
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #344 from Vauxoo/17.0
Syncing from upstream Vauxoo/addons-vauxoo (17.0)
- Loading branch information
Showing
11 changed files
with
341 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
Customized Rate Date in Stock | ||
============================= | ||
|
||
This module allows to set a customized date on transfers to be used when | ||
computing product unit prices, instead of the date when the transfer is | ||
validated, in case exchange rates are involved. | ||
|
||
The use for the above is that created journal entries take the newly | ||
computed unit price, which makes the inventory to be valuated using the | ||
specified rate. | ||
|
||
Contributors | ||
------------ | ||
|
||
* Luis González <[email protected]> | ||
|
||
|
||
Maintainer | ||
========== | ||
|
||
.. image:: https://www.vauxoo.com/logo.png | ||
:alt: Vauxoo | ||
:target: https://vauxoo.com | ||
|
||
This module is maintained by Vauxoo. | ||
|
||
a latinamerican company that provides training, coaching, | ||
development and implementation of enterprise management | ||
systems and bases its entire operation strategy in the use | ||
of Open Source Software and its main product is Odoo. | ||
|
||
To contribute to this module, please visit http://www.vauxoo.com. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "Customized Rate Date in Stock", | ||
"version": "17.0.1.0.0", | ||
"author": "Vauxoo", | ||
"category": "stock", | ||
"website": "http://www.vauxoo.com/", | ||
"license": "LGPL-3", | ||
"depends": [ | ||
"purchase_stock", | ||
], | ||
"data": [ | ||
"views/stock_picking_views.xml", | ||
], | ||
"demo": [], | ||
"installable": True, | ||
"auto_install": False, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Translation of Odoo Server. | ||
# This file contains the translation of the following modules: | ||
# * stock_custom_exchange_rate_date | ||
# | ||
msgid "" | ||
msgstr "" | ||
"Project-Id-Version: Odoo Server 17.0+e\n" | ||
"Report-Msgid-Bugs-To: \n" | ||
"POT-Creation-Date: 2023-05-19 23:36+0000\n" | ||
"PO-Revision-Date: 2023-05-19 23:36+0000\n" | ||
"Last-Translator: \n" | ||
"Language-Team: \n" | ||
"MIME-Version: 1.0\n" | ||
"Content-Type: text/plain; charset=UTF-8\n" | ||
"Content-Transfer-Encoding: \n" | ||
"Plural-Forms: \n" | ||
|
||
#. module: stock_custom_exchange_rate_date | ||
#: model:ir.model.fields,field_description:stock_custom_exchange_rate_date.field_stock_picking__exchange_rate_date | ||
msgid "Exchange Rate Date" | ||
msgstr "Fecha de tasa de cambio" | ||
|
||
#. module: stock_custom_exchange_rate_date | ||
#: model:ir.model.fields,help:stock_custom_exchange_rate_date.field_stock_picking__exchange_rate_date | ||
msgid "" | ||
"If set, specifies a customized date that will be used when computing product" | ||
" unit prices, instead of the date when the transfer is validated, in case " | ||
"exchange rates are involved." | ||
msgstr "" | ||
"Si se establece, especifica una fecha personalizada que se utilizará al " | ||
"calcular precios unitarios de productos, en lugar de la fecha en que se " | ||
"valide la transferencia, en caso que haya tasas de cambio involucradas." | ||
|
||
#. module: stock_custom_exchange_rate_date | ||
#: model:ir.model,name:stock_custom_exchange_rate_date.model_stock_move | ||
msgid "Stock Move" | ||
msgstr "Movimiento de existencias" | ||
|
||
#. module: stock_custom_exchange_rate_date | ||
#: model:ir.model,name:stock_custom_exchange_rate_date.model_stock_picking | ||
msgid "Transfer" | ||
msgstr "Transferencia" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import stock_move | ||
from . import stock_picking |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from odoo import models | ||
|
||
|
||
class StockMove(models.Model): | ||
_inherit = "stock.move" | ||
|
||
def _get_price_unit(self): | ||
"""Take into account custom rate date, if provided""" | ||
line = self.purchase_line_id | ||
if ( | ||
not self.picking_id.exchange_rate_date | ||
or self.product_id != line.product_id | ||
or line.currency_id == line.company_id.currency_id | ||
or self._should_ignore_pol_price() | ||
): | ||
return super()._get_price_unit() | ||
price_unit = line._get_gross_price_unit() | ||
price_unit = line.currency_id._convert( | ||
price_unit, line.company_id.currency_id, line.company_id, self.picking_id.exchange_rate_date, round=False | ||
) | ||
return price_unit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from odoo import fields, models | ||
|
||
|
||
class StockPicking(models.Model): | ||
_inherit = "stock.picking" | ||
|
||
exchange_rate_date = fields.Date( | ||
copy=False, | ||
help="If set, specifies a customized date that will be used when " | ||
"computing product unit prices, instead of the date when the transfer " | ||
"is validated, in case exchange rates are involved.", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import test_stock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
from datetime import timedelta | ||
|
||
from odoo import fields | ||
from odoo.tests import Form, TransactionCase, tagged | ||
|
||
|
||
@tagged("post_install", "-at_install") | ||
class TestStock(TransactionCase): | ||
@classmethod | ||
def setUpClass(cls): | ||
super().setUpClass() | ||
cls.vendor = cls.env.ref("base.res_partner_1") | ||
cls.usd = cls.env.ref("base.USD") | ||
cls.eur = cls.env.ref("base.EUR") | ||
cls.eur.active = True | ||
cls.today = fields.Date.context_today(cls.env.user) | ||
cls.yesterday = cls.today - timedelta(days=1) | ||
account = cls.env["account.account"].create( | ||
{ | ||
"name": "Receivable", | ||
"code": "RCV00", | ||
"account_type": "asset_receivable", | ||
"reconcile": True, | ||
} | ||
) | ||
account_expense = cls.env["account.account"].create( | ||
{ | ||
"name": "Expense", | ||
"code": "EXP00", | ||
"account_type": "expense", | ||
"reconcile": True, | ||
} | ||
) | ||
account_income = cls.env["account.account"].create( | ||
{ | ||
"name": "Income", | ||
"code": "INC00", | ||
"account_type": "income", | ||
"reconcile": True, | ||
} | ||
) | ||
account_output = cls.env["account.account"].create( | ||
{ | ||
"name": "Output", | ||
"code": "OUT00", | ||
"account_type": "expense", | ||
"reconcile": True, | ||
} | ||
) | ||
account_valuation = cls.env["account.account"].create( | ||
{ | ||
"name": "Valuation", | ||
"code": "STV00", | ||
"account_type": "expense", | ||
"reconcile": True, | ||
} | ||
) | ||
stock_journal = cls.env["account.journal"].create( | ||
{ | ||
"name": "Stock journal", | ||
"type": "sale", | ||
"code": "STK00", | ||
} | ||
) | ||
|
||
# Creating a new product to ensure valuation is clean | ||
cls.stock_account_product_categ = cls.env["product.category"].create( | ||
{ | ||
"name": "Test category", | ||
"property_valuation": "real_time", | ||
"property_cost_method": "fifo", | ||
"property_account_income_categ_id": account_income.id, | ||
"property_account_expense_categ_id": account_expense.id, | ||
"property_stock_account_input_categ_id": account.id, | ||
"property_stock_account_output_categ_id": account_output.id, | ||
"property_stock_valuation_account_id": account_valuation.id, | ||
"property_stock_journal": stock_journal.id, | ||
} | ||
) | ||
cls.product = cls.env["product.product"].create( | ||
{ | ||
"name": "Product fifo", | ||
"type": "product", | ||
"default_code": "PR-FIFO", | ||
"categ_id": cls.stock_account_product_categ.id, | ||
} | ||
) | ||
|
||
def create_purchase_order(self, partner=None, **line_kwargs): | ||
if partner is None: | ||
partner = self.vendor | ||
purchase_order = Form(self.env["purchase.order"]) | ||
purchase_order.partner_id = partner | ||
purchase_order.currency_id = self.eur | ||
purchase_order = purchase_order.save() | ||
self.create_po_line(purchase_order, **line_kwargs) | ||
return purchase_order | ||
|
||
def create_po_line(self, purchase_order, product=None, quantity=1, price=100): | ||
if product is None: | ||
product = self.product | ||
with Form(purchase_order) as po: | ||
with po.order_line.new() as line: | ||
line.product_id = product | ||
line.product_qty = quantity | ||
line.price_unit = price | ||
|
||
def set_currency_rates(self, rate_date, usd_rate, eur_rate): | ||
# Remove existing rates, if any | ||
rate_model = self.env["res.currency.rate"] | ||
current_rates = rate_model.search( | ||
[ | ||
("name", "=", rate_date), | ||
("currency_id", "in", [self.usd.id, self.eur.id]), | ||
] | ||
) | ||
current_rates.unlink() | ||
|
||
# Create new rates | ||
rate_model.create( | ||
{ | ||
"currency_id": self.usd.id, | ||
"rate": usd_rate, | ||
"name": rate_date, | ||
} | ||
) | ||
rate_model.create({"currency_id": self.eur.id, "rate": eur_rate, "name": rate_date}) | ||
|
||
def test_01_date_rate_set(self): | ||
"""Set a custom rate date on a transfer, valuation should be computed using that date""" | ||
# Purchase product | ||
self.set_currency_rates(rate_date=self.today, usd_rate=1, eur_rate=1.25) | ||
self.set_currency_rates(rate_date=self.yesterday, usd_rate=1, eur_rate=2) | ||
po = self.create_purchase_order() | ||
po.button_confirm() | ||
self.assertEqual(po.state, "purchase") | ||
|
||
# Set custom rate date on the receipt transfer and confirm | ||
picking_po = po.picking_ids | ||
picking_po.exchange_rate_date = self.yesterday | ||
picking_po.move_line_ids.write({"quantity": 1.0}) | ||
picking_po.button_validate() | ||
self.assertEqual(picking_po.state, "done") | ||
|
||
# Check valuation according to stock moves | ||
# Yesterday's rate was 1 USD = 2 EUR, so 100 EUR should be valued as 50 USD | ||
val_layer = self.env["stock.valuation.layer"].search([("stock_move_id", "in", picking_po.move_ids.ids)]) | ||
self.assertRecordValues( | ||
val_layer, | ||
[ | ||
{ | ||
"remaining_qty": 1.0, | ||
"remaining_value": 50.0, | ||
"value": 50.0, | ||
} | ||
], | ||
) | ||
|
||
def test_02_date_rate_not_set(self): | ||
"""Don't set a custom date rate, valuation should be computed using today""" | ||
# Purchase product | ||
self.set_currency_rates(rate_date=self.today, usd_rate=1, eur_rate=1.25) | ||
self.set_currency_rates(rate_date=self.yesterday, usd_rate=1, eur_rate=2) | ||
po = self.create_purchase_order() | ||
po.button_confirm() | ||
self.assertEqual(po.state, "purchase") | ||
|
||
# Confirm receipt transfer | ||
picking_po = po.picking_ids | ||
picking_po.move_line_ids.write({"quantity": 1.0}) | ||
picking_po.button_validate() | ||
self.assertEqual(picking_po.state, "done") | ||
|
||
# Check valuation according to stock moves | ||
# Today"s rate is 1 USD = 1.25 EUR, so 100 EUR should be valued as 80 USD | ||
val_layer = self.env["stock.valuation.layer"].search([("stock_move_id", "in", picking_po.move_ids.ids)]) | ||
self.assertRecordValues( | ||
val_layer, | ||
[ | ||
{ | ||
"remaining_qty": 1.0, | ||
"remaining_value": 80.0, | ||
"value": 80.0, | ||
} | ||
], | ||
) |
20 changes: 20 additions & 0 deletions
20
stock_custom_exchange_rate_date/views/stock_picking_views.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<odoo> | ||
|
||
<record id="view_picking_form" model="ir.ui.view"> | ||
<field name="name">stock.picking.form.inherit.custom.rate.date</field> | ||
<field name="model">stock.picking</field> | ||
<field name="inherit_id" ref="stock.view_picking_form" /> | ||
<field name="arch" type="xml"> | ||
<xpath expr="//label[@for='scheduled_date']" position="before"> | ||
<field name="purchase_id" invisible="True" /> | ||
<field | ||
name="exchange_rate_date" | ||
invisible="not purchase_id or picking_type_code != 'incoming'" | ||
readonly="state in ['cancel', 'done']" | ||
/> | ||
</xpath> | ||
</field> | ||
</record> | ||
|
||
</odoo> |