diff --git a/modules/account/move.py b/modules/account/move.py
index 16fb786..c123e62 100755
--- a/modules/account/move.py
+++ b/modules/account/move.py
@@ -1013,7 +1013,9 @@ class Line(DescriptionOriginMixin, MoveLineMixin, ModelSQL, ModelView):
journal = fields.Function(fields.Many2One('account.journal',"Journal"),'get_journal')
- rate = fields.Function(fields.Numeric("Rate",digits=(1,6)),'get_rate')
+ rate = fields.Numeric("Rate", digits=(10, 6), states={
+ 'readonly': _states['readonly'],
+ })
del _states
@@ -1119,44 +1121,58 @@ class Line(DescriptionOriginMixin, MoveLineMixin, ModelSQL, ModelView):
def get_rate(self,name=None):
if self.amount_second_currency:
return round((self.credit if self.credit else self.debit) / abs(self.amount_second_currency),6)
-
- @fields.depends(
- 'debit', 'credit',
- 'date','second_currency','amount_second_currency')
- def on_change_amount_second_currency(self):
- Currency = Pool().get('currency.currency')
- Date = Pool().get('ir.date')
- if self.second_currency != None and self.amount_second_currency != None and (not self.credit and not self.debit):
- tdate = Date.today()
- if self.date:
- tdate = self.date
- rate = Currency._get_rate([self.second_currency],tdate)
- if rate:
- rate = rate[self.second_currency.id]
- if self.amount_second_currency > 0:
- self.debit = round(rate * self.amount_second_currency,2)
- elif self.amount_second_currency > 0:
- self.credit = round(rate * abs(self.amount_second_currency),2)
- self.rate = self.get_rate()
@fields.depends(
'debit', 'credit',
- 'date','second_currency','amount_second_currency')
+ 'date','second_currency','amount_second_currency', 'rate',
+ 'origin', 'move_origin', 'move', '_parent_move.origin')
def on_change_second_currency(self):
+ if self._manual_rate_mode():
+ self.rate = self._get_second_currency_rate()
+ self._compute_amount_from_second_currency()
+
+ @fields.depends(
+ 'debit', 'credit',
+ 'date','second_currency','amount_second_currency', 'rate',
+ 'origin', 'move_origin', 'move', '_parent_move.origin')
+ def on_change_rate(self):
+ if self._manual_rate_mode() and not self.debit and not self.credit:
+ self._compute_amount_from_second_currency()
+
+ def _manual_rate_mode(self):
+ if getattr(self, 'origin', None) or getattr(self, 'move_origin', None):
+ return False
+ move = getattr(self, 'move', None)
+ if move and getattr(move, 'origin', None):
+ return False
+ return True
+
+ def _get_second_currency_rate(self):
Currency = Pool().get('currency.currency')
Date = Pool().get('ir.date')
- if self.second_currency != None and self.amount_second_currency != None and (not self.credit and not self.debit):
- tdate = Date.today()
- if self.date:
- tdate = self.date
- rate = Currency._get_rate([self.second_currency],tdate)
- if rate:
- rate = rate[self.second_currency.id]
+ if self.second_currency is None:
+ return None
+ tdate = Date.today()
+ if self.date:
+ tdate = self.date
+ rates = Currency._get_rate([self.second_currency], tdate)
+ return rates.get(self.second_currency.id) if rates else None
+
+ def _compute_amount_from_second_currency(self):
+ if self.second_currency is not None and self.amount_second_currency is not None:
+ if not self.rate:
+ self.rate = self._get_second_currency_rate()
+ if self.rate:
+ amount = round(self.rate * abs(self.amount_second_currency), 2)
if self.amount_second_currency > 0:
- self.debit = round(rate * self.amount_second_currency,2)
- elif self.amount_second_currency > 0:
- self.credit = round(rate * abs(self.amount_second_currency),2)
- self.rate = self.get_rate()
+ self.debit = amount
+ self.credit = Decimal(0)
+ elif self.amount_second_currency < 0:
+ self.debit = Decimal(0)
+ self.credit = amount
+ else:
+ self.debit = Decimal(0)
+ self.credit = Decimal(0)
@fields.depends(
'move', 'debit', 'credit',
@@ -1223,15 +1239,25 @@ class Line(DescriptionOriginMixin, MoveLineMixin, ModelSQL, ModelView):
if self.debit:
self.credit = Decimal(0)
self._amount_second_currency_sign()
+ self.rate = self.get_rate()
@fields.depends('debit', 'credit', 'amount_second_currency')
def on_change_credit(self):
if self.credit:
self.debit = Decimal(0)
self._amount_second_currency_sign()
+ self.rate = self.get_rate()
- @fields.depends('amount_second_currency', 'debit', 'credit')
+ @fields.depends(
+ 'amount_second_currency', 'debit', 'credit', 'date', 'second_currency',
+ 'rate', 'origin', 'move_origin', 'move', '_parent_move.origin')
def on_change_amount_second_currency(self):
+ if self._manual_rate_mode():
+ if not self.rate:
+ self.rate = self._get_second_currency_rate()
+ self._compute_amount_from_second_currency()
+ elif not self.rate:
+ self.rate = self.get_rate()
self._amount_second_currency_sign()
def _amount_second_currency_sign(self):
diff --git a/modules/account/tests/test_module.py b/modules/account/tests/test_module.py
index 0373751..15e0d4b 100755
--- a/modules/account/tests/test_module.py
+++ b/modules/account/tests/test_module.py
@@ -12,7 +12,7 @@ from trytond.modules.account.exceptions import (
from trytond.modules.account.tax import TaxableMixin
from trytond.modules.company.tests import (
CompanyTestMixin, PartyCompanyCheckEraseMixin, create_company, set_company)
-from trytond.modules.currency.tests import create_currency
+from trytond.modules.currency.tests import add_currency_rate, create_currency
from trytond.pool import Pool
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
from trytond.transaction import Transaction, inactive_records
@@ -576,6 +576,54 @@ class AccountTestCase(
self.assertEqual(
cash_cur.amount_second_currency, Decimal(50))
+ @with_transaction()
+ def test_move_line_second_currency_amount_on_change(self):
+ 'Test account move line computes amount from second currency'
+ pool = Pool()
+ Account = pool.get('account.account')
+ Line = pool.get('account.move.line')
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+ second_currency = create_currency('sec')
+ add_currency_rate(second_currency, Decimal('0.939506'))
+
+ expense, = Account.search([
+ ('type.expense', '=', True),
+ ])
+
+ line = Line(
+ account=expense,
+ second_currency=second_currency,
+ amount_second_currency=Decimal('100.00'))
+ line.on_change_amount_second_currency()
+
+ self.assertEqual(line.debit, Decimal('93.95'))
+ self.assertEqual(line.credit, Decimal(0))
+ self.assertEqual(line.rate, Decimal('0.939506'))
+ self.assertEqual(line.get_rate(), Decimal('0.939500'))
+
+ line = Line(
+ account=expense,
+ credit=Decimal('7.61'),
+ second_currency=second_currency,
+ amount_second_currency=Decimal('-108.10'))
+ line.on_change_amount_second_currency()
+
+ self.assertEqual(line.debit, Decimal(0))
+ self.assertEqual(line.credit, Decimal('101.56'))
+ self.assertEqual(line.rate, Decimal('0.939506'))
+ self.assertEqual(line.get_rate(), Decimal('0.939500'))
+
+ line.debit = line.credit = Decimal(0)
+ line.rate = Decimal('1.100000')
+ line.on_change_rate()
+
+ self.assertEqual(line.debit, Decimal(0))
+ self.assertEqual(line.credit, Decimal('118.91'))
+ self.assertEqual(line.rate, Decimal('1.100000'))
+
@with_transaction()
def test_account_type_amount(self):
"Test account type amount"
diff --git a/modules/account/view/move_line_form_move.xml b/modules/account/view/move_line_form_move.xml
index 77fff6b..5fa381f 100755
--- a/modules/account/view/move_line_form_move.xml
+++ b/modules/account/view/move_line_form_move.xml
@@ -26,6 +26,8 @@ this repository contains the full copyright notices and license terms. -->
+
+
diff --git a/modules/account_invoice/invoice.py b/modules/account_invoice/invoice.py
index 774b3b0..9eac40e 100755
--- a/modules/account_invoice/invoice.py
+++ b/modules/account_invoice/invoice.py
@@ -515,7 +515,9 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin):
~((table.state == 'cancelled') & (table.number == Null)),
CharLength(table.number), table.number]
- @fields.depends('selection_rate','rate_date')
+ @fields.depends(
+ 'selection_rate', 'rate_date', 'currency', 'company', 'invoice_date',
+ 'lines', 'lines.lot', 'lines.amount')
def on_change_with_rate(self, name=None):
return self.get_selected_rate()
@@ -528,8 +530,8 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin):
def get_selected_rate(self,name=None):
Currency = Pool().get('currency.currency')
Date = Pool().get('ir.date')
- company = self.company
- currency = self.currency
+ company = getattr(self, 'company', None)
+ currency = getattr(self, 'currency', None)
if not currency or not company:
return None