diff --git a/exchange_currency_rate/__manifest__.py b/exchange_currency_rate/__manifest__.py index 0159c0ee7..4f70a2979 100644 --- a/exchange_currency_rate/__manifest__.py +++ b/exchange_currency_rate/__manifest__.py @@ -21,7 +21,7 @@ ################################################################################ { 'name': "Manual Currency Exchange Rate", - 'version': '18.0.1.0.0', + 'version': '18.0.1.1.0', 'category': 'Accounting', 'summary': """By using this module ,we can change the currency rate manually in sale ,purchase and invoice. """, @@ -40,7 +40,7 @@ 'views/purchase_order_views.xml', 'views/sale_order_views.xml' ], - 'images': ['static/description/banner.gif'], + 'images': ['static/description/banner.png'], 'license': 'AGPL-3', 'installable': True, 'auto_install': False, diff --git a/exchange_currency_rate/doc/RELEASE_NOTES.md b/exchange_currency_rate/doc/RELEASE_NOTES.md index 464602921..c4f4bf11d 100644 --- a/exchange_currency_rate/doc/RELEASE_NOTES.md +++ b/exchange_currency_rate/doc/RELEASE_NOTES.md @@ -1,7 +1,7 @@ ## Module -#### 26.06.2024 -#### Version 18.0.1.0.0 +#### 03.03.2025 +#### Version 18.0.1.1.0 #### ADD - Initial commit for Manual Currency Exchange Rate diff --git a/exchange_currency_rate/models/account_move.py b/exchange_currency_rate/models/account_move.py index 9dbbe2362..5e6d0f776 100644 --- a/exchange_currency_rate/models/account_move.py +++ b/exchange_currency_rate/models/account_move.py @@ -29,23 +29,91 @@ class AccountMove(models.Model): the exchange rate through the 'rate' field.""" _inherit = 'account.move' - is_exchange = fields.Boolean(string='Apply Manual Exchange', - help='Check this box if you want to manually ' - 'apply an exchange rate for this ' - 'transaction.') - rate = fields.Float(string='Rate', help='specify the rate', - compute='_compute_rate', readonly=False, store=True, - default=1) - - @api.depends('invoice_line_ids.product_id') + is_exchange = fields.Boolean(string="Apply Manual Exchange", compute="_compute_is_exchange", + inverse="_inverse_is_exchange", + store=True, help='Check this box if you want to manually ' + 'apply an exchange rate for this ' + 'transaction.') + + rate = fields.Float(string="Exchange Rate", compute="_compute_rate", inverse="_inverse_rate", store=True, + help='specify the rate') + + sale_order_id = fields.Many2one('sale.order', string="Sale Order", compute="_compute_sale_order", + store=True,help="Linking corresponding Sale Order") + purchase_order_id = fields.Many2one('purchase.order', string="Purchase Order", + compute="_compute_purchase_order", store=True,help="Linking Purchase Order") + + @api.constrains('company_currency_id', 'currency_id') + def _onchange_different_currency(self): + """ When the Currency is changed back to company currency, the boolean field is disabled """ + if self.company_currency_id == self.currency_id: + if self.is_exchange: + self.is_exchange = False + + @api.depends('line_ids.sale_line_ids.order_id') + def _compute_sale_order(self): + """ Compute Function to Update the Corresponding Sale Order """ + for move in self: + sale_orders = move.line_ids.mapped('sale_line_ids.order_id') + move.sale_order_id = sale_orders and sale_orders[0] or False + + @api.depends('line_ids.purchase_line_id.order_id') + def _compute_purchase_order(self): + """ Compute Function to Update the Corresponding Purchase Order """ + for move in self: + purchase_orders = move.line_ids.mapped('purchase_line_id.order_id') + move.purchase_order_id = purchase_orders and purchase_orders[0] or False + + @api.depends('currency_id', 'company_currency_id', 'company_id', 'invoice_date', 'rate', 'is_exchange') + def _compute_invoice_currency_rate(self): + """Overriding the Default Compute function to include the Manual Rate Also.""" + for move in self: + if move.is_invoice(include_receipts=True): + if move.currency_id: + if move.is_exchange: + rate = move.rate if move.rate else 1 + move.invoice_currency_rate = rate + continue + move.invoice_currency_rate = self.env['res.currency']._get_conversion_rate( + from_currency=move.company_currency_id, + to_currency=move.currency_id, + company=move.company_id, + date=move._get_invoice_currency_rate_date(), + ) + else: + move.invoice_currency_rate = 1 + + @api.depends('sale_order_id.is_exchange', 'purchase_order_id.is_exchange') + def _compute_is_exchange(self): + """ Compute Function to Update the Exchange Boolean based on Sale Order and Purchase Order""" + for move in self: + if move.sale_order_id: + move.is_exchange = move.sale_order_id.is_exchange + elif move.purchase_order_id: + move.is_exchange = move.purchase_order_id.is_exchange + else: + move.is_exchange = False + + def _inverse_is_exchange(self): + """ Allow manual editing of is_exchange in account.move """ + pass + + @api.depends('sale_order_id.rate', 'purchase_order_id.rate') def _compute_rate(self): - """Changing the unit price of product by changing the rate.""" - for rec in self: - if rec.move_type == 'out_invoice': - if len(rec.invoice_line_ids) >= 1 and rec.is_exchange: - rec.invoice_line_ids[-1].price_unit = rec.invoice_line_ids[ - -1].product_id.list_price * rec.rate - elif rec.move_type == 'in_invoice': - if len(rec.invoice_line_ids) >= 1 and rec.is_exchange: - rec.invoice_line_ids[-1].price_unit = rec.invoice_line_ids[ - -1].product_id.standard_price * rec.rate + """ Compute The rate based on sale order and purchase order""" + for move in self: + if move.sale_order_id: + move.rate = move.sale_order_id.rate + elif move.purchase_order_id: + move.rate = move.purchase_order_id.rate + else: + move.rate = move.env['res.currency']._get_conversion_rate( + from_currency=move.company_currency_id, + to_currency=move.currency_id, + company=move.company_id, + date=self.date, + ) + + def _inverse_rate(self): + """ Allow manual editing of rate in account.move """ + pass diff --git a/exchange_currency_rate/models/purchase_order.py b/exchange_currency_rate/models/purchase_order.py index 2b86f2bd2..9841f8f1d 100644 --- a/exchange_currency_rate/models/purchase_order.py +++ b/exchange_currency_rate/models/purchase_order.py @@ -21,7 +21,6 @@ ################################################################################ from odoo import api, fields, models - class PurchaseOrder(models.Model): """This class extends the base 'purchase.order' model to introduce a new field, 'is_exchange',which allows users to manually apply an exchange @@ -29,17 +28,25 @@ class PurchaseOrder(models.Model): the exchange rate through the 'rate' field.""" _inherit = 'purchase.order' - is_exchange = fields.Boolean(string='Apply Manual Currency', - help='Check this box if you want to manually' - 'apply an exchange rate for this ' - 'transaction.') - rate = fields.Float(string='Rate', help='specify the rate', compute='_compute_rate', readonly=False, store=True, - default=1) + company_currency_id = fields.Many2one( + string='Company Currency', + related='company_id.currency_id', readonly=True, help="To store the Company Currency") + is_exchange = fields.Boolean(string='Apply Manual Currency', help='allows users to manually apply an exchange rate') + rate = fields.Float(string='Rate', help='specify the rate', default=1) + + @api.constrains('company_currency_id', 'currency_id') + def _onchange_different_currency(self): + """ When the Currency is changed back to company currency, the boolean field is disabled """ + if self.company_currency_id == self.currency_id: + if self.is_exchange: + self.is_exchange = False - @api.depends('order_line.product_id') - def _compute_rate(self): - """Changing the unit price of product by changing the rate.""" - for rec in self: - if len(rec.order_line) >= 1 and rec.is_exchange: - rec.order_line[-1].price_unit = rec.order_line[ - -1].product_id.standard_price * rec.rate + @api.onchange('is_exchange') + def _onchange_is_exchange(self): + """ Update Rate when is_exchange is Enabled.""" + if self.is_exchange: + self.rate = self.env['res.currency']._get_conversion_rate( + from_currency=self.company_currency_id, + to_currency=self.currency_id, + company=self.company_id, + date=self.date_order) diff --git a/exchange_currency_rate/models/sale_order.py b/exchange_currency_rate/models/sale_order.py index cad022f68..44491c826 100644 --- a/exchange_currency_rate/models/sale_order.py +++ b/exchange_currency_rate/models/sale_order.py @@ -21,7 +21,6 @@ ################################################################################ from odoo import api, fields, models - class SaleOrder(models.Model): """This class extends the base 'sale.order' model to introduce a new field, 'is_exchange',which allows users to manually apply an exchange @@ -29,17 +28,30 @@ class SaleOrder(models.Model): exchange rate through the 'rate' field.""" _inherit = 'sale.order' + company_currency_id = fields.Many2one( + string='Company Currency', + related='company_id.currency_id', readonly=True,help='Store the Company Currency' + ) + is_exchange = fields.Boolean(string='Apply Manual Currency', help='Enable the boolean field to display ' 'rate field') - rate = fields.Float(string='Rate', help='specify the currency rate', - compute='_compute_rate', readonly=False, store=True, - default=1) + rate = fields.Float(string='Rate', help='specify the currency rate',default=1) + + @api.constrains('company_currency_id', 'currency_id') + def _onchange_different_currency(self): + """ When the Currency is changed back to company currency, the boolean field is disabled """ + if self.company_currency_id == self.currency_id: + if self.is_exchange: + self.is_exchange = False - @api.depends('order_line.product_id') - def _compute_rate(self): - """Changing the unit price of product by changing the rate.""" - for rec in self: - if len(rec.order_line) >= 1 and rec.is_exchange: - rec.order_line[-1].price_unit = rec.order_line[ - -1].product_id.list_price * rec.rate + @api.onchange('is_exchange') + def _onchange_is_exchange(self): + """ Update Rate when is_exchange is Enabled.""" + if self.is_exchange: + self.rate = self.env['res.currency']._get_conversion_rate( + from_currency=self.company_currency_id, + to_currency=self.currency_id, + company=self.company_id, + date=self.date_order, + ) diff --git a/exchange_currency_rate/static/description/assets/icons/hero.gif b/exchange_currency_rate/static/description/assets/icons/hero.gif index edd337525..7c9b52ad9 100644 Binary files a/exchange_currency_rate/static/description/assets/icons/hero.gif and b/exchange_currency_rate/static/description/assets/icons/hero.gif differ diff --git a/exchange_currency_rate/static/description/assets/screenshots/1.png b/exchange_currency_rate/static/description/assets/screenshots/1.png index 6446be511..32af42d59 100644 Binary files a/exchange_currency_rate/static/description/assets/screenshots/1.png and b/exchange_currency_rate/static/description/assets/screenshots/1.png differ diff --git a/exchange_currency_rate/static/description/assets/screenshots/2.png b/exchange_currency_rate/static/description/assets/screenshots/2.png index 0962c3b63..339b6700b 100644 Binary files a/exchange_currency_rate/static/description/assets/screenshots/2.png and b/exchange_currency_rate/static/description/assets/screenshots/2.png differ diff --git a/exchange_currency_rate/static/description/assets/screenshots/3.png b/exchange_currency_rate/static/description/assets/screenshots/3.png index 38908c538..00e94be80 100644 Binary files a/exchange_currency_rate/static/description/assets/screenshots/3.png and b/exchange_currency_rate/static/description/assets/screenshots/3.png differ diff --git a/exchange_currency_rate/static/description/assets/screenshots/4.png b/exchange_currency_rate/static/description/assets/screenshots/4.png deleted file mode 100644 index ac09f48dd..000000000 Binary files a/exchange_currency_rate/static/description/assets/screenshots/4.png and /dev/null differ diff --git a/exchange_currency_rate/static/description/assets/screenshots/5.png b/exchange_currency_rate/static/description/assets/screenshots/5.png index 75dee1edf..9d51a21d4 100644 Binary files a/exchange_currency_rate/static/description/assets/screenshots/5.png and b/exchange_currency_rate/static/description/assets/screenshots/5.png differ diff --git a/exchange_currency_rate/static/description/assets/screenshots/6.png b/exchange_currency_rate/static/description/assets/screenshots/6.png index a65a7ac1b..eb9e8f546 100644 Binary files a/exchange_currency_rate/static/description/assets/screenshots/6.png and b/exchange_currency_rate/static/description/assets/screenshots/6.png differ diff --git a/exchange_currency_rate/static/description/assets/screenshots/7.png b/exchange_currency_rate/static/description/assets/screenshots/7.png index 81920afbc..5194fae16 100644 Binary files a/exchange_currency_rate/static/description/assets/screenshots/7.png and b/exchange_currency_rate/static/description/assets/screenshots/7.png differ diff --git a/exchange_currency_rate/static/description/assets/screenshots/8.png b/exchange_currency_rate/static/description/assets/screenshots/8.png deleted file mode 100644 index d99fd1e43..000000000 Binary files a/exchange_currency_rate/static/description/assets/screenshots/8.png and /dev/null differ diff --git a/exchange_currency_rate/static/description/banner.png b/exchange_currency_rate/static/description/banner.png new file mode 100644 index 000000000..5b5797908 Binary files /dev/null and b/exchange_currency_rate/static/description/banner.png differ diff --git a/exchange_currency_rate/static/description/index.html b/exchange_currency_rate/static/description/index.html index 52d075e2b..0d9716006 100644 --- a/exchange_currency_rate/static/description/index.html +++ b/exchange_currency_rate/static/description/index.html @@ -395,37 +395,6 @@ In the

-Here you can find different prices for the - - same product -

- -
-

- Above mentioned one is the actual sales price of the product. Below is - the changing price as manual currency exchange rates are provided. -

-
-
-
- -
-
- - - -
-
-
-
-

- In the Purchase Order @@ -442,38 +411,7 @@ In the style="background-color:#fff; border-radius:10px"> -

-
-
-
- -
-
-
-
-

- -Here you can find different prices for the - - same product -

-
-
-

- Above mentioned one is the actual purchase cost of the product. Below is - the changing price as manual currency exchange rates are provided. -

-
-
-
-
@@ -495,8 +433,10 @@ In the

- there is a check-box to select for manual currency exchange rate. Apply - rates that you want to be exchanged. + There is a check-box to select for manual currency exchange rate, this + will be automatically updated from the Sale Order. + Here the rates can be updated again or manual exchange rate can be + disabled.

@@ -504,7 +444,7 @@ In the style="background-color:#fff; border-radius:10px">
@@ -519,15 +459,15 @@ In the

-Here you can find different prices for the + Converted Price + - same product +

- Above mentioned one is the actual sales price of the product. Below is - the changing price as manual currency exchange rates are provided. + Here you can find converted prices for the Products in the Journal Items based on the newly applied Manual Rate.

@@ -535,7 +475,7 @@ Here you can find different prices for the style="background-color:#fff; border-radius:10px">
@@ -558,8 +498,10 @@ In the

- there is a check-box to select for manual currency exchange rate. Apply - rates that you want to be exchanged. + There is a check-box to select for manual currency exchange rate, this + will be automatically updated from the Purchase Order. + Here the rates can be updated again or manual exchange rate can be + disabled.

@@ -567,7 +509,7 @@ In the style="background-color:#fff; border-radius:10px">
@@ -582,15 +524,16 @@ In the

-Here you can find different prices for the +Converted Price - same product +

- Above mentioned one is the actual purchase cost of the product. Below is - the changing price as manual currency exchange rates are provided. + Here you can find converted prices for the Products in the Journal Items + based on the newly applied Manual Rate. +

@@ -598,7 +541,7 @@ Here you can find different prices for the style="background-color:#fff; border-radius:10px">
@@ -667,7 +610,8 @@ Here you can find different prices for the style="cursor: pointer; background-color:#f8f8f8; border:none; border-top-right-radius:10px; border-top-left-radius:10px; padding: 12px 24px;"> - Can I manually set exchange rates for each sale and purchase? + Can I manually set exchange rates for each sale and + purchase?

- Yes, the module allows you to manually set specific exchange rates for each transaction individually. + Yes, the module allows you to manually set specific exchange + rates for each transaction individually.

@@ -694,7 +639,8 @@ Here you can find different prices for the style="cursor: pointer; background-color:#f8f8f8; border:1px solid #f8f8f8; border-top-right-radius:10px; border-top-left-radius:10px; padding: 12px 24px">
- How can I update the exchange rate for a sale or purchase order? + How can I update the exchange rate for a sale or purchase + order?

- You can update the exchange rate directly from the sale or purchase order form under the currency section. + You can update the exchange rate directly from the sale or + purchase order form under the currency section.

@@ -721,7 +668,8 @@ Here you can find different prices for the style="cursor: pointer; background-color:#f8f8f8; border:1px solid #f8f8f8; border-top-right-radius:10px; border-top-left-radius:10px; padding: 12px 24px">
- Will the manual exchange rate override the system’s automatic rates? + Will the manual exchange rate override the system’s + automatic rates?

- Yes, when you apply a manual exchange rate, it will override any automatically retrieved rates for that transaction. + Yes, when you apply a manual exchange rate, it will override + any automatically retrieved rates for that transaction.

@@ -748,7 +697,8 @@ Here you can find different prices for the style="cursor: pointer; background-color:#f8f8f8; border:1px solid #f8f8f8; border-top-right-radius:10px; border-top-left-radius:10px; padding: 12px 24px">
- Can I view or edit exchange rates after confirming the order? + Can I view or edit exchange rates after confirming the + order?

- Yes, you can view and adjust the applied exchange rate even after the order has been confirmed, as long as the transaction is still editable. + Yes, you can view and adjust the applied exchange rate even + after the order has been confirmed, as long as the + transaction is still editable.

@@ -1078,7 +1030,7 @@ Here you can find different prices for the style="background-color:#FCD12C; border-radius:50%; height:56px; width:56px"> + height="28px" width="28px"/> - - + + + + - \ No newline at end of file + diff --git a/exchange_currency_rate/views/purchase_order_views.xml b/exchange_currency_rate/views/purchase_order_views.xml index 621f708ca..f46b7e15f 100644 --- a/exchange_currency_rate/views/purchase_order_views.xml +++ b/exchange_currency_rate/views/purchase_order_views.xml @@ -7,10 +7,13 @@ - - + + + - \ No newline at end of file + diff --git a/exchange_currency_rate/views/sale_order_views.xml b/exchange_currency_rate/views/sale_order_views.xml index 20b7b54b9..227068f8b 100644 --- a/exchange_currency_rate/views/sale_order_views.xml +++ b/exchange_currency_rate/views/sale_order_views.xml @@ -6,11 +6,13 @@ sale.order - - - - + + + + +