From 9de43b804b94270bd7cdfcc3c7c0d16068df02b6 Mon Sep 17 00:00:00 2001 From: houssine Date: Wed, 23 Jan 2019 10:32:55 +0100 Subject: [PATCH] [ADD] Dividend Engine this module allow to calculate the amount to give to the cooperator based on the purcentage to attribute --- easy_my_coop_dividend/__init__.py | 2 + easy_my_coop_dividend/__openerp__.py | 51 +++++ easy_my_coop_dividend/models/__init__.py | 2 + easy_my_coop_dividend/models/dividend.py | 200 ++++++++++++++++++ .../security/ir.model.access.csv | 1 + .../views/dividend_views.xml | 164 ++++++++++++++ 6 files changed, 420 insertions(+) create mode 100644 easy_my_coop_dividend/__init__.py create mode 100644 easy_my_coop_dividend/__openerp__.py create mode 100644 easy_my_coop_dividend/models/__init__.py create mode 100644 easy_my_coop_dividend/models/dividend.py create mode 100644 easy_my_coop_dividend/security/ir.model.access.csv create mode 100644 easy_my_coop_dividend/views/dividend_views.xml diff --git a/easy_my_coop_dividend/__init__.py b/easy_my_coop_dividend/__init__.py new file mode 100644 index 0000000..c204cef --- /dev/null +++ b/easy_my_coop_dividend/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf8 -*- +from . import models diff --git a/easy_my_coop_dividend/__openerp__.py b/easy_my_coop_dividend/__openerp__.py new file mode 100644 index 0000000..95e0306 --- /dev/null +++ b/easy_my_coop_dividend/__openerp__.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2013-2018 Open Architects Consulting SPRL. +# Copyright (C) 2013-2018 Coop IT Easy SCRLfs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +############################################################################## + + +{ + 'name': 'Easy My Coop Dividend Engine', + + 'summary': """ + Manage the dividend calculation for a fiscal year. + """, + 'description': """ + This module allows to calculate the dividend to give to a cooperator base + on the amount of his shares, the percentage allocated and for how long the + shares have been owned on prorata temporis calculation. + """, + + 'author': 'Houssine BAKKALI, ', + 'license': 'AGPL-3', + 'version': '9.0.1.0', + 'website': "www.coopiteasy.be", + + 'category': 'Cooperative Management', + + 'depends': [ + 'base', + 'web', + 'mail', + ], + + 'data': [ + 'security/ir.model.access.csv', + 'views/dividend_views.xml', + ] +} diff --git a/easy_my_coop_dividend/models/__init__.py b/easy_my_coop_dividend/models/__init__.py new file mode 100644 index 0000000..63d8540 --- /dev/null +++ b/easy_my_coop_dividend/models/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf8 -*- +from . import dividend diff --git a/easy_my_coop_dividend/models/dividend.py b/easy_my_coop_dividend/models/dividend.py new file mode 100644 index 0000000..6db099c --- /dev/null +++ b/easy_my_coop_dividend/models/dividend.py @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2013-2018 Open Architects Consulting SPRL. +# Copyright (C) 2013-2018 Coop IT Easy SCRLfs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from __future__ import division +from datetime import datetime +import openerp.addons.decimal_precision as dp + +from openerp import fields, models, api + + +class dividend_year(models.Model): + _name = 'dividend.year' + + @api.multi + def _compute_dividend_info(self): + res = {} + for dividend in self: + res[dividend.id] = {'grand_total_dividend': 0.0, + 'grand_total_taxes': 0.0} + for line in dividend.dividend_ids: + res[dividend.id]['grand_total_dividend'] += line.dividend_amount + res[dividend.id]['grand_total_taxes'] += line.dividend_taxes + return res + + name = fields.Char(string='Code') + date_from = fields.Date(string='Date from') + date_to = fields.Date(string='Date to') +# fiscal_year_id = fields.Many2one('account.fiscalyear', +# string='Fiscal year') + percentage = fields.Float(string='Percentage') + withholding_tax = fields.Float(string='Withholding tax') + detailed_dividend_ids = fields.One2many('detailed.dividend.line', + 'dividend_year_id', + string='Dividend lines') + dividend_ids = fields.One2many('dividend.line', + 'dividend_year_id', + string='Dividend lines') + grand_total_dividend = fields.Float( + compute=_compute_dividend_info, + string='Grand total dividend', + digits_compute=dp.get_precision('Account')) + grand_total_taxes = fields.Float( + compute=_compute_dividend_info, + string='Grand total taxes', + digits_compute=dp.get_precision('Account')) + + @api.multi + def compute_dividend(self): + self.ensure_one() + det_div_line_obj = self.env['detailed.dividend.line'] + div_line_obj = self.env['dividend.line'] + res_partner_obj = self.env['res.partner'] + + # delete lines if any + detailed_dividend_ids = det_div_line_obj.search([('dividend_year_id', '=', self.id)]) + detailed_dividend_ids.unlink() + dividend_ids = div_line_obj.search([('dividend_year_id', '=', self.id)]) + dividend_ids.unlink() + + partner_ids = res_partner_obj.search([ + ('cooperator', '=', True), + ('member', '=', True)], + order='cooperator_register_number') + number_of_days = (datetime.strptime(self.date_to, '%Y-%m-%d') + - datetime.strptime(self.date_from, '%Y-%m-%d') + ).days + 1 + print number_of_days + + for partner in partner_ids: + total_amount_dividend = 0.0 + for line in partner.share_ids: + vals = {} + vals2 = {} + line_id = False + if line.effective_date >= self.date_from \ + and line.effective_date <= self.date_to: + date_res = (datetime.strptime(self.date_to, '%Y-%m-%d') + - datetime.strptime(line.effective_date, '%Y-%m-%d')).days + coeff = (date_res / number_of_days) * self.percentage + dividend_amount = line.total_amount_line * coeff + + vals['days'] = date_res + vals['dividend_year_id'] = self.id + vals['coop_number'] = line.partner_id.cooperator_register_number + vals['partner_id'] = partner.id + vals['share_line_id'] = line.id + vals['coeff'] = coeff + vals['dividend_amount'] = dividend_amount + total_amount_dividend += dividend_amount + + line_id = det_div_line_obj.create(vals) + elif line.effective_date < self.date_from: + dividend_amount = line.total_amount_line * self.percentage + vals['days'] = number_of_days + vals['dividend_year_id'] = self.id + vals['coop_number'] = line.partner_id.cooperator_register_number + vals['partner_id'] = partner.id + vals['share_line_id'] = line.id + vals['coeff'] = self.percentage + vals['dividend_amount'] = dividend_amount + total_amount_dividend += dividend_amount + + line_id = det_div_line_obj.create(vals) + if line_id: + vals2['coop_number'] = line.partner_id.cooperator_register_number + vals2['dividend_year_id'] = self.id + vals2['partner_id'] = line.partner_id.id + + vals2['dividend_amount_net'] = total_amount_dividend + vals2['dividend_amount'] = total_amount_dividend + + # TODO set as a parameter on dividend year object + if total_amount_dividend <= 190.00: + vals2['dividend_taxes'] = 0.0 + else: + div_tax = (total_amount_dividend - 190) * self.withholding_tax + vals2['dividend_taxes'] = div_tax + vals2['dividend_amount_net'] = total_amount_dividend - div_tax + + div_line_obj.create(vals2) + return True + + +class DetailedDividendLine(models.Model): + _name = 'detailed.dividend.line' + + @api.multi + def _compute_total_line(self): + res = {} + for line in self: + res[line.id] = line.share_unit_price * line.share_number + return res + + dividend_year_id = fields.Many2one('dividend.year', + string='Dividend year') + coop_number = fields.Integer(string='Cooperator Number') + days = fields.Integer(string='Days') + partner_id = fields.Many2one('res.partner', + string='Cooperator', + readonly=True) + share_line_id = fields.Many2one('share.line', + string='Share line', + readonly=True) + share_number = fields.Integer(related='share_line_id.share_number', + string='Number of Share') + share_unit_price = fields.Float(related='share_line_id.share_unit_price', + string='Share unit price') + effective_date = fields.Date(related='share_line_id.effective_date', + string='Effective date') + total_amount_line = fields.Float(compute=_compute_total_line, + string="Total value of share", + readonly=True) + coeff = fields.Float(string='Coefficient to apply', + digits=(2, 4)) + dividend_amount = fields.Float(string='Gross Dividend') + dividend_amount_net = fields.Float(string='Dividend net') + dividend_taxes = fields.Float(string='Taxes') + + +class dividend_line(models.Model): + _name = 'dividend.line' + + @api.multi + def _get_account_number(self): + res = {} + for line in self: + bank_accounts = self.env['res.partner.bank'].search( + [('partner_id', '=', line.partner_id.id)]) + res[line.id] = bank_accounts[0].acc_number + + return res + + coop_number = fields.Integer(string='Coop Number') + dividend_year_id = fields.Many2one('dividend.year', + string='Dividend year') + partner_id = fields.Many2one('res.partner', + string='Cooperator', + readonly=True) + account_number = fields.Char(compute=_get_account_number, + string='Account Number') + dividend_amount = fields.Float(string='Gross Dividend') + dividend_amount_net = fields.Float(string='Dividend net') + dividend_taxes = fields.Float(string='Taxes') diff --git a/easy_my_coop_dividend/security/ir.model.access.csv b/easy_my_coop_dividend/security/ir.model.access.csv new file mode 100644 index 0000000..4a08a4a --- /dev/null +++ b/easy_my_coop_dividend/security/ir.model.access.csv @@ -0,0 +1 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink diff --git a/easy_my_coop_dividend/views/dividend_views.xml b/easy_my_coop_dividend/views/dividend_views.xml new file mode 100644 index 0000000..77a1a2e --- /dev/null +++ b/easy_my_coop_dividend/views/dividend_views.xml @@ -0,0 +1,164 @@ + + + + + + dividend.year.form + dividend.year + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + dividend.year.tree + dividend.year + + + + + + + + + + Dividend year + dividend.year + form + + + + + + + detailed.dividend.line.select + detailed.dividend.line + + + + + + + + + + + + + detailed.dividend.line.tree + detailed.dividend.line + + + + + + + + + + + + + + + + + + Detailed dividend lines + detailed.dividend.line + form + + + + + + + dividend.line.select + dividend.line + + + + + + + + + + + + + + + + dividend.line.tree + dividend.line + + + + + + + + + + + + + + + Dividend lines + dividend.line + form + + + + +
+
\ No newline at end of file