diff --git a/account_reconciliation_widget_partial/README.rst b/account_reconciliation_widget_partial/README.rst new file mode 100644 index 00000000..fb78bde9 --- /dev/null +++ b/account_reconciliation_widget_partial/README.rst @@ -0,0 +1,85 @@ +========================= +Account Reconcile Partial +========================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--reconcile-lightgray.png?logo=github + :target: https://github.com/OCA/account-reconcile/tree/11.0/account_reconcile_partial + :alt: OCA/account-reconcile +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-reconcile-11-0/account-reconcile-11-0-account_reconcile_partial + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/98/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This addons allow to change the amount of a reconciliation line in order to +partially reconcile it. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +On reconciliations, an edit button is created. +Once pressed, you can modify the amount. +By default, it will propose the difference between the original amount and the +current balance if allowed. + +.. figure:: https://raw.githubusercontent.com/account_reconcile_partial/static/description/reconciliation_partial.png + :alt: Partial reconciliation + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Creu Blanca + +Contributors +~~~~~~~~~~~~ + +* Enric Tobella + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/account-reconcile `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_reconciliation_widget_partial/__init__.py b/account_reconciliation_widget_partial/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/account_reconciliation_widget_partial/__manifest__.py b/account_reconciliation_widget_partial/__manifest__.py new file mode 100644 index 00000000..640ba1ea --- /dev/null +++ b/account_reconciliation_widget_partial/__manifest__.py @@ -0,0 +1,21 @@ +# Copyright 2019 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Account Reconciliation Widget Partial', + 'summary': """ + Allow to modifiy the reconcile amount for partial payments""", + 'version': '11.0.1.0.0', + 'license': 'AGPL-3', + 'author': 'Creu Blanca,Odoo Community Association (OCA)', + 'website': 'https://github.com/OCA/account-reconcile', + 'depends': [ + 'account', + ], + 'data': [ + 'views/assets.xml', + ], + 'qweb': [ + 'static/src/xml/account_reconciliation.xml', + ], +} diff --git a/account_reconciliation_widget_partial/readme/CONTRIBUTORS.rst b/account_reconciliation_widget_partial/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..93ec993e --- /dev/null +++ b/account_reconciliation_widget_partial/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Enric Tobella diff --git a/account_reconciliation_widget_partial/readme/DESCRIPTION.rst b/account_reconciliation_widget_partial/readme/DESCRIPTION.rst new file mode 100644 index 00000000..1c2580d1 --- /dev/null +++ b/account_reconciliation_widget_partial/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This addons allow to change the amount of a reconciliation line in order to +partially reconcile it. diff --git a/account_reconciliation_widget_partial/readme/USAGE.rst b/account_reconciliation_widget_partial/readme/USAGE.rst new file mode 100644 index 00000000..4fcf4f70 --- /dev/null +++ b/account_reconciliation_widget_partial/readme/USAGE.rst @@ -0,0 +1,7 @@ +On reconciliations, an edit button is created. +Once pressed, you can modify the amount. +By default, it will propose the difference between the original amount and the +current balance if allowed. + +.. figure:: /account_reconcile_partial/static/description/reconciliation_partial.png + :alt: Partial reconciliation diff --git a/account_reconciliation_widget_partial/static/description/icon.png b/account_reconciliation_widget_partial/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/account_reconciliation_widget_partial/static/description/icon.png differ diff --git a/account_reconciliation_widget_partial/static/description/index.html b/account_reconciliation_widget_partial/static/description/index.html new file mode 100644 index 00000000..e533b4e2 --- /dev/null +++ b/account_reconciliation_widget_partial/static/description/index.html @@ -0,0 +1,431 @@ + + + + + + +Account Reconcile Partial + + + +
+

Account Reconcile Partial

+ + +

Beta License: AGPL-3 OCA/account-reconcile Translate me on Weblate Try me on Runbot

+

This addons allow to change the amount of a reconciliation line in order to +partially reconcile it.

+

Table of contents

+ +
+

Usage

+

On reconciliations, an edit button is created. +Once pressed, you can modify the amount. +By default, it will propose the difference between the original amount and the +current balance if allowed.

+
+Partial reconciliation +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Creu Blanca
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/account-reconcile project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/account_reconciliation_widget_partial/static/description/reconciliation_partial.png b/account_reconciliation_widget_partial/static/description/reconciliation_partial.png new file mode 100644 index 00000000..d5cb9b2e Binary files /dev/null and b/account_reconciliation_widget_partial/static/description/reconciliation_partial.png differ diff --git a/account_reconciliation_widget_partial/static/src/js/reconciliation_action.js b/account_reconciliation_widget_partial/static/src/js/reconciliation_action.js new file mode 100644 index 00000000..3e80989f --- /dev/null +++ b/account_reconciliation_widget_partial/static/src/js/reconciliation_action.js @@ -0,0 +1,18 @@ +odoo.define("account_reconcile_partial.ReconciliationClientAction", function (require) { + + var action = require('account.ReconciliationClientAction'); + + action.StatementAction.include({ + custom_events: _.extend({}, action.StatementAction.prototype.custom_events, { + get_partial_amount: '_onActionPartialAmount', + partial_reconcile: '_onAction', + }), + _onActionPartialAmount: function(event) { + var self = this; + var handle = event.target.handle; + var line = this.model.getLine(handle); + var amount = this.model.getPartialReconcileAmount(handle, event.data); + self._getWidget(handle).updatePartialAmount(event.data.data, amount); + }, + }); +}); diff --git a/account_reconciliation_widget_partial/static/src/js/reconciliation_model.js b/account_reconciliation_widget_partial/static/src/js/reconciliation_model.js new file mode 100644 index 00000000..e2ff0697 --- /dev/null +++ b/account_reconciliation_widget_partial/static/src/js/reconciliation_model.js @@ -0,0 +1,117 @@ +odoo.define("account_reconcile_partial.ReconciliationModel", function (require) { + + var model = require('account.ReconciliationModel'); + var field_utils = require('web.field_utils'); + var utils = require('web.utils'); + var session = require('web.session'); + + model.StatementModel.include({ + getPartialReconcileAmount: function(handle, data) { + var line = this.getLine(handle); + var prop = _.find(line.reconciliation_proposition, {'id': data.data}); + if (prop) { + var amount = prop.partial_amount || prop.amount; + // Check if we can get a partial amount + // that would directly set balance to zero + var partial = Math.abs(line.balance.amount + amount); + if (partial <= Math.abs(prop.amount)) { + return partial; + } + return Math.abs(amount); + } + }, + partialReconcile: function(handle, data) { + var line = this.getLine(handle); + var prop = _.find( + line.reconciliation_proposition, {'id' : data.mvLineId}); + if (prop) { + var amount = data.amount; + try { + amount = field_utils.parse.float(data.amount); + } + catch (err) { + amount = NaN; + } + if ( + amount >= Math.abs(prop.amount) + || amount <= 0 || isNaN(amount) + ) { + delete prop.partial_amount_str; + delete prop.partial_amount; + if (isNaN(amount) || amount < 0) { + this.do_warn(_.str.sprintf(_t( + 'The amount %s is not a valid partial amount' + ), data.amount)); + } + return this._computeLine(line); + } + else { + var format_options = { currency_id: line.st_line.currency_id }; + prop.partial_reconcile = true; + prop.partial_amount = (prop.amount > 0 ? 1 : -1)*amount; + prop.write_off_amount = prop.partial_amount; + prop.partial_amount_str = field_utils.format.monetary( + Math.abs(prop.partial_amount), {}, format_options); + } + } + return this._computeLine(line); + }, + _computeLine: function (line) { + // Fixing the computation of the balance in order to use + // amount_reconcile if it will be partially reconciled + var self = this; + var formatOptions = { + currency_id: line.st_line.currency_id, + }; + return this._super.apply(this, arguments).then(function () { + + var amount_currency = 0; + var total = line.st_line.amount || 0; + var isOtherCurrencyId = _.uniq(_.pluck(_.reject( + line.reconciliation_proposition, 'invalid'), 'currency_id')); + isOtherCurrencyId = ( + isOtherCurrencyId.length === 1 + && !total + && isOtherCurrencyId[0] !== formatOptions.currency_id + ? isOtherCurrencyId[0] : false); + + _.each(line.reconciliation_proposition, function (prop) { + if (!prop.invalid) { + if (prop.partial_reconcile) + total -= prop.partial_amount || prop.amount; + else + total -= prop.amount; + if (isOtherCurrencyId) { + amount_currency -= ( + prop.amount < 0 ? -1 : 1 + ) * Math.abs(prop.amount_currency); + } + } + }); + var company_currency = session.get_currency( + line.st_line.currency_id); + var company_precision = ( + company_currency && company_currency.digits[1] || 2); + total = utils.round_decimals(total, company_precision) || 0; + if(isOtherCurrencyId){ + var other_currency = session.get_currency(isOtherCurrencyId); + var other_precision = other_currency && other_currency.digits[1] || 2; + amount_currency = utils.round_decimals(amount_currency, other_precision); + } + line.balance = { + amount: total, + amount_str: field_utils.format.monetary(Math.abs(total), {}, formatOptions), + currency_id: isOtherCurrencyId, + amount_currency: isOtherCurrencyId ? amount_currency : total, + amount_currency_str: isOtherCurrencyId ? field_utils.format.monetary( + Math.abs(amount_currency), {}, { + currency_id: isOtherCurrencyId + }) : false, + account_code: self.accounts[line.st_line.open_balance_account_id], + }; + line.balance.show_balance = line.balance.amount_currency != 0; + line.balance.type = line.balance.amount_currency ? (line.st_line.partner_id ? 0 : -1) : 1; + }); + }, + }); +}); diff --git a/account_reconciliation_widget_partial/static/src/js/reconciliation_renderer.js b/account_reconciliation_widget_partial/static/src/js/reconciliation_renderer.js new file mode 100644 index 00000000..ba2871bd --- /dev/null +++ b/account_reconciliation_widget_partial/static/src/js/reconciliation_renderer.js @@ -0,0 +1,54 @@ +odoo.define('account_reconcile_partial.ReconciliationRenderer', function (require) { + "use strict"; + + var renderer = require('account.ReconciliationRenderer') + + renderer.LineRenderer.include({ + events: _.extend({}, renderer.LineRenderer.prototype.events, { + 'click .accounting_view .line_info_edit.fa-pencil': '_onInfoEdit', + }), + _onInfoEdit: function(e){ + e.stopPropagation(); + var $line = $(event.target); + this.trigger_up( + 'get_partial_amount', + {'data': $line.closest('.mv_line').data('line-id')} + ); + }, + updatePartialAmount: function(line_id, amount) { + var $line = this.$('.mv_line[data-line-id='+line_id+']'); + $line.find('.line_info_edit').addClass('o_hidden'); + $line.find('.edit_amount_input').removeClass('o_hidden'); + $line.find('.edit_amount_input').focus(); + $line.find('.edit_amount_input').val(amount.toFixed(2)); + $line.find('.edit_amount_input').select(); + $line.find('.line_amount').addClass('o_hidden'); + }, + _editAmount: function (event) { + event.stopPropagation(); + var $line = $(event.target); + var moveLineId = $line.closest('.mv_line').data('line-id'); + this.trigger_up( + 'partial_reconcile', + {'data': {mvLineId: moveLineId, 'amount': $line.val()}} + ); + }, + _onInputKeyup: function (event) { + if(event.keyCode === 13) { + if ($(event.target).hasClass('edit_amount_input')) { + $(event.target).blur(); + return; + } + } + if ($(event.target).hasClass('edit_amount_input')) { + if (event.type === 'keyup') { + return; + } + else { + return this._editAmount(event); + } + } + return this._super.apply(this, arguments); + }, + }); +}); diff --git a/account_reconciliation_widget_partial/static/src/less/account_reconciliation.less b/account_reconciliation_widget_partial/static/src/less/account_reconciliation.less new file mode 100644 index 00000000..e4da458c --- /dev/null +++ b/account_reconciliation_widget_partial/static/src/less/account_reconciliation.less @@ -0,0 +1,25 @@ +.o_reconciliation { + .o_reconciliation_line{ + .line_info_edit { + text-align: right; + width: 15px; + color: #ccc; + background: #fff; + border: 0; + } + .do_partial_reconcile_true { + display: none!important; + } + .do_partial_reconcile_false { + display: none!important; + } + .strike_amount { + text-decoration: line-through; + } + } + .o_reconciliation_line .match{ + .line_info_edit { + display: none!important; + } + } +} diff --git a/account_reconciliation_widget_partial/static/src/xml/account_reconciliation.xml b/account_reconciliation_widget_partial/static/src/xml/account_reconciliation.xml new file mode 100644 index 00000000..aa956063 --- /dev/null +++ b/account_reconciliation_widget_partial/static/src/xml/account_reconciliation.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + +
+ + + state.balance.amount_currency + + + +
diff --git a/account_reconciliation_widget_partial/views/assets.xml b/account_reconciliation_widget_partial/views/assets.xml new file mode 100644 index 00000000..6ea4dda8 --- /dev/null +++ b/account_reconciliation_widget_partial/views/assets.xml @@ -0,0 +1,11 @@ + + +