diff --git a/__init__.py b/__init__.py index 128fa3f8ff8d7de77d5d026b933d37c8d3b76db1..a453b4b3a3656a314b8ca36c4d0b0f54f491c85e 100755 --- a/__init__.py +++ b/__init__.py @@ -1,7 +1,8 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. +# © 2022 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import models +from . import report from . import wizard from odoo import api, SUPERUSER_ID diff --git a/__manifest__.py b/__manifest__.py index 3def71d28e7fc0fa430df7cba1f888815665c0e5..323070940c3d915ecb1cbe547b2bafea7c600e29 100755 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,3 +1,5 @@ +# © 2022 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "CG SCOP - Cotisations", "summary": "CG SCOP - Cotisations", @@ -19,12 +21,12 @@ "security/ir.model.access.csv", "views/account_invoice.xml", "views/account_move.xml", - "views/account_payment_term.xml", "views/account_payment_order.xml", "views/account_payment_line.xml", "views/res_config_settings.xml", "views/res_partner.xml", "views/scop_cotisation_task.xml", + "report/scop_contribution_report.xml", ], "qweb": [ "static/src/xml/*.xml", diff --git a/models/__init__.py b/models/__init__.py index 796e1a90e000ad97359e122f24ed12b32c2a0aa0..419d51378ff1cf86ca82d88e686bdf688a159866 100755 --- a/models/__init__.py +++ b/models/__init__.py @@ -3,10 +3,10 @@ from . import account_invoice from . import account_payment_order -from . import account_payment_term from . import chart_template from . import res_company from . import res_config_settings +from . import res_partner from . import scop_contribution from . import scop_cotisation from . import scop_cotisation_task diff --git a/models/account_invoice.py b/models/account_invoice.py index f9cf02df769014f42e6d46efa98d1c4e5caad861..16c9033bad0656caeb6ce5001b49d05ac5defe78 100755 --- a/models/account_invoice.py +++ b/models/account_invoice.py @@ -4,8 +4,7 @@ from datetime import datetime import json -from odoo import models, fields, api, _ -from odoo.exceptions import UserError +from odoo import models, fields, api class ScopAccountInvoice(models.Model): @@ -49,14 +48,6 @@ class ScopAccountInvoice(models.Model): contribution_id = fields.Many2one( comodel_name='scop.contribution', string='Ligne de cotisation') - nb_quarter = fields.Selection( - string='Nombre de trimestres de cotisation', - selection=[(1, '1'), - (2, '2'), - (3, '3'), - (4, '4')], - default=4, - required=True) is_sdd = fields.Boolean( 'Au prélèvement', compute='compute_is_sdd', @@ -84,123 +75,6 @@ class ScopAccountInvoice(models.Model): # ------------------------------------------------------ # Override Parent # ------------------------------------------------------ - @api.multi - def action_invoice_open(self): - """ - Création d'une ligne dans scop.contribution - quand une facture cotisation devient valide - """ - results = super(ScopAccountInvoice, self).action_invoice_open() - for inv in self: - if inv.is_contribution: - inv.set_scop_contribution() - return results - - @api.multi - def action_move_create(self): - """ - Complete override parent - Pass invoice in payment_term.compute function to generate payment - schedule - :return: True - """ - account_move = self.env['account.move'] - - for inv in self: - if not inv.journal_id.sequence_id: - raise UserError(_('Please define sequence on the journal related to this invoice.')) - if not inv.invoice_line_ids.filtered(lambda line: line.account_id): - raise UserError(_('Please add at least one invoice line.')) - if inv.move_id: - continue - - if not inv.date_invoice: - inv.write({'date_invoice': fields.Date.context_today(self)}) - if not inv.date_due: - inv.write({'date_due': inv.date_invoice}) - company_currency = inv.company_id.currency_id - - # create move lines - # (one per invoice line + eventual taxes and analytic lines) - iml = inv.invoice_line_move_line_get() - iml += inv.tax_line_move_line_get() - - diff_currency = inv.currency_id != company_currency - # create one move line for the total and possibly adjust - # the other lines amount - total, total_currency, iml = inv.compute_invoice_totals( - company_currency, iml) - - name = inv.name or '' - if inv.payment_term_id: - totlines = inv.payment_term_id.with_context( - currency_id=company_currency.id).compute(total, inv.date_invoice, inv)[0] - res_amount_currency = total_currency - for i, t in enumerate(totlines): - if inv.currency_id != company_currency: - amount_currency = company_currency._convert( - t[1], - inv.currency_id, - inv.company_id, - inv._get_currency_rate_date() or fields.Date.today()) - else: - amount_currency = False - - # last line: add the diff - res_amount_currency -= amount_currency or 0 - if i + 1 == len(totlines): - amount_currency += res_amount_currency - - iml.append({ - 'type': 'dest', - 'name': name, - 'price': t[1], - 'account_id': inv.account_id.id, - 'date_maturity': t[0], - 'amount_currency': diff_currency and amount_currency, - 'currency_id': diff_currency and inv.currency_id.id, - 'invoice_id': inv.id - }) - else: - iml.append({ - 'type': 'dest', - 'name': name, - 'price': total, - 'account_id': inv.account_id.id, - 'date_maturity': inv.date_due, - 'amount_currency': diff_currency and total_currency, - 'currency_id': diff_currency and inv.currency_id.id, - 'invoice_id': inv.id - }) - part = self.env['res.partner']._find_accounting_partner( - inv.partner_id) - line = [(0, 0, self.line_get_convert(l, part.id)) for l in iml] - line = inv.group_lines(iml, line) - - line = inv.finalize_invoice_move_lines(line) - - date = inv.date or inv.date_invoice - move_vals = { - 'ref': inv.reference, - 'line_ids': line, - 'journal_id': inv.journal_id.id, - 'date': date, - 'narration': inv.comment, - } - move = account_move.create(move_vals) - # Pass invoice in method post: used if you want to get the same - # account move reference when creating the same invoice - # after a cancelled one: - move.post(invoice = inv) - # make the invoice point to that move - vals = { - 'move_id': move.id, - 'date': date, - 'move_name': move.name, - } - inv.write(vals) - return True - @api.one def _get_outstanding_info_JSON(self): super(ScopAccountInvoice, self)._get_outstanding_info_JSON() @@ -233,48 +107,3 @@ class ScopAccountInvoice(models.Model): 'invoice': line.invoice_id.number }) self.outstanding_credits_debits_widget = json.dumps(info) - - # ------------------------------------------------------ - # Common Function - # ------------------------------------------------------ - @api.multi - def set_scop_contribution(self): - """ - Création d'une ligne dans scop.contribution - """ - self.ensure_one() - if self.is_contribution: - year = self.year - # Get existing contribution for this year - contrib_id = self.env['scop.contribution'].search([ - ('partner_id', '=', self.partner_id.id), - ('year', '=', year), - ('type_id', '=', self.type_contribution_id.id) - ]) - - # Create scop.contribution line if not exists - # for year, partner and type - if not contrib_id: - contrib_line = self.env['scop.contribution'].create({ - 'partner_id': self.partner_id.id, - 'type_id': self.type_contribution_id.id, - 'year': self.year, - 'calculation_date': fields.Datetime.now(), - 'amount_calculated': self.amount_total, - 'amount_called': self.amount_total, - 'spreading': self.nb_quarter, - 'invoice_id': self.id, - }) - else: - contrib_line = self.set_scop_contribution_hook(contrib_id) - self.contribution_id = contrib_line.id - return contrib_line - return False - - def set_scop_contribution_hook(self, contrib_id): - """ - Function that can be inherited if a contrib line already exists - :param contrib_id: scop.contribution line - :return: scop.contribution - """ - return contrib_id diff --git a/models/account_payment_term.py b/models/account_payment_term.py deleted file mode 100644 index 7f21e6098a9bd9624d87b70005dc8bcf71900a88..0000000000000000000000000000000000000000 --- a/models/account_payment_term.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2020 Le Filament -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from odoo import fields, models, api - - -class AccountPaymentTerm(models.Model): - _inherit = 'account.payment.term' - - is_contribution = fields.Boolean('Conditions de paiement des cotisations') - - def compute(self, value, date_ref=False, invoice=False): - """ - Override la fonction compute du modèle account.payment.term - La fonction initiale checke les conditions de paiement et crée - les lignes de paiement associées - - L'héritage permet de créer un échéancier en fonction de celui - défini sur la base de cotisations - """ - date_ref = date_ref or fields.Date.today() - amount = value - sign = value < 0 and -1 or 1 - if self.env.context.get('currency_id'): - currency = self.env['res.currency'].browse( - self.env.context['currency_id']) - else: - currency = self.env.user.company_id.currency_id - - # si base de cotisation - if self.is_contribution and invoice and (invoice.cotisation_cg_id or invoice.cotisation_aura_id): - result = [] - if invoice.cotisation_cg_id: - base_contrib_field = 'cotisation_cg_id' - elif invoice.cotisation_aura_id: - base_contrib_field = 'cotisation_aura_id' - trimesters = { - 4: invoice[base_contrib_field].trimester_1, - 3: invoice[base_contrib_field].trimester_2, - 2: invoice[base_contrib_field].trimester_3, - 1: invoice[base_contrib_field].trimester_4, - } - for i in range(invoice.nb_quarter, 0, -1): - # Gestion de l'arrondi de la division - if i == 1: - amt = currency.round(amount) - else: - amt = currency.round(value / invoice.nb_quarter) - result.append((fields.Date.to_string(trimesters.get(i)), amt)) - amount -= amt - return [result] - else: - return super(AccountPaymentTerm, self).compute(value, date_ref) diff --git a/models/res_company.py b/models/res_company.py index f3466180e9f570be6977378f3d5db8be9859241c..96f63c04070421d104eb92937429a0cc301f530b 100644 --- a/models/res_company.py +++ b/models/res_company.py @@ -14,12 +14,6 @@ class ScopCotisationCompany(models.Model): domain="[('type', '=', 'sale')]" ) - contribution_default_payment_term_id = fields.Many2one( - comodel_name='account.payment.term', - string="Conditions de paiement par défaut pour les cotisations", - domain=[('is_contribution', '=', True)], - ) - tag_cotiz_id = fields.Many2one( comodel_name='res.partner.category', string='Etiquette de cotisation', diff --git a/models/res_config_settings.py b/models/res_config_settings.py index 714396c9f305f40bc63cea3d1a355e7b04d36ce1..61cb183a9fce0277fbeb904b72d40f3c27c40e23 100644 --- a/models/res_config_settings.py +++ b/models/res_config_settings.py @@ -1,7 +1,7 @@ # © 2020 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import fields, models, api +from odoo import fields, models class CotisationsConfigSettings(models.TransientModel): @@ -18,14 +18,6 @@ class CotisationsConfigSettings(models.TransientModel): string='Journal des cotisations', domain="[('type', '=', 'sale')]") - contribution_default_payment_term_id = fields.Many2one( - comodel_name='account.payment.term', - related="company_id.contribution_default_payment_term_id", - readonly=False, - string="Conditions de paiement par défaut pour les cotisations", - domain=[('is_contribution', '=', True)], - ) - tag_cotiz_id = fields.Many2one( comodel_name='res.partner.category', related="company_id.tag_cotiz_id", diff --git a/models/res_partner.py b/models/res_partner.py new file mode 100644 index 0000000000000000000000000000000000000000..67c5ab6ec7046cba252932d4083ecd6b1bdffd43 --- /dev/null +++ b/models/res_partner.py @@ -0,0 +1,14 @@ +# © 2020 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + contribution_report_ids = fields.One2many( + comodel_name='scop.contribution.report', + inverse_name='partner_id', + string='Cotisations', + ) diff --git a/models/scop_cotisation.py b/models/scop_cotisation.py index 31343230b3636b3cb0ca7bf877fff54d8317d9d7..37f9bb00da983f93fb9a2ce72b6f89ca573a26f5 100644 --- a/models/scop_cotisation.py +++ b/models/scop_cotisation.py @@ -10,19 +10,6 @@ class ScopCotisation(models.AbstractModel): _name = "scop.cotisation" _description = "Base des cotisations" - @api.model - def default_get(self, fields): - """ - Attribue la valeur des conditions de paiments par - défault à la base de cotisation - :param fields: - :return: - """ - res = super(ScopCotisation, self).default_get(fields) - res['payment_term_id'] = self.env.user.company_id.\ - contribution_default_payment_term_id.id - return res - year = fields.Selection( [(year, str(year)) for year in range( fields.Datetime.now().year - 1, fields.Datetime.now().year + 2)], @@ -37,12 +24,6 @@ class ScopCotisation(models.AbstractModel): company_currency_id = fields.Many2one( comodel_name='res.currency', related='company_id.currency_id', string="Company Currency", readonly=True) - payment_term_id = fields.Many2one( - comodel_name='account.payment.term', - string="Conditions de paiement", - domain=[('is_contribution', '=', True)], - required=True, - ) date_cotisation = fields.Date( string="Date calcul cotisation", help="Date de calcul qui apparaitra sur le bordereau de cotisation" @@ -84,81 +65,6 @@ class ScopCotisation(models.AbstractModel): # ------------------------------------------------------ # Global functions # ------------------------------------------------------ - def create_contribution( - self, product, partner, type_contribution, liasse=None, amount=0, - date=False, journal_id=False, account_id=False, - type_invoice='out_invoice', is_regul=False, bordereau=False): - """ - Create invoice from Contribution Base - :param product: product_id - :param partner: partner_id - :param type_contribution: type_contribution (CG, UR, Fédé) - :param liasse: liasse_fiscale_id (reference) - :param amount: contribution amount (float) - :param date: date invoice - :param journal_id: journal - :param account_id: customer_account_id - :param type_invoice: invoice or refund - :param is_regul: used for CG Scop regul - :return: invoice - """ - Invoice = self.env['account.invoice'] - InvoiceLine = self.env['account.invoice.line'] - - domain = [ - ('partner_id', '=', partner.id), - ('year', '=', self.year), - ('type_contribution_id', '=', type_contribution), - ] - if bordereau: - domain.append(('bordereau_id', '=', bordereau.id)) - - exisiting_invoice = Invoice.search(domain) - - if not exisiting_invoice or is_regul: - date_invoice = date if date else self.date_cotisation - journal_id = self.company_id.contribution_journal_id \ - if not journal_id else journal_id - account_id = partner.property_account_receivable_id \ - if not account_id else account_id - member_invoice = Invoice.create({ - 'partner_id': partner.id, - 'liasse_fiscale_id': liasse.id, - 'type': type_invoice, - 'year': self.year, - 'is_contribution': True, - 'type_contribution_id': type_contribution, - 'journal_id': journal_id.id, - 'state': 'draft', - 'account_id': account_id.id, - 'payment_term_id': self.payment_term_id.id, - 'payment_mode_id': partner.customer_payment_mode_id.id, - 'date_invoice': date_invoice, - }) - else: - member_invoice = exisiting_invoice - - # Création de la ligne CG Scop - exisiting_invoice_line_ids = InvoiceLine.search([ - ('invoice_id', '=', member_invoice.id), - ('product_id', '=', product.id) - ]) - if not exisiting_invoice_line_ids or is_regul: - InvoiceLine.create({ - 'invoice_id': member_invoice.id, - 'product_id': product.id, - 'account_id': product.property_account_income_id.id, - 'invoice_line_tax_ids': [(6, 0, product.taxes_id.ids)], - 'name': product.name, - 'price_unit': amount - }) - else: - exisiting_invoice_line_ids[0].write({ - 'price_unit': amount - }) - - return member_invoice - @api.multi def get_members(self): self.ensure_one() diff --git a/report/__init__.py b/report/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..530b04980c303e369063f0beec2f53cace402497 --- /dev/null +++ b/report/__init__.py @@ -0,0 +1,4 @@ +# © 2020 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import scop_contribution_report diff --git a/report/scop_contribution_report.py b/report/scop_contribution_report.py new file mode 100644 index 0000000000000000000000000000000000000000..23dedb4d5f8fcd3980afcb2b526b9600b172309c --- /dev/null +++ b/report/scop_contribution_report.py @@ -0,0 +1,199 @@ +# © 2022 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import tools +from odoo import models, fields, api + + +class ScopContributionReport(models.Model): + _name = "scop.contribution.report" + _description = "Vue cotisations" + _auto = False + _order = 'year desc, partner_id' + + name = fields.Char(compute='_compute_name') + year = fields.Char('Année de cotisation') + type_contribution_id = fields.Many2one( + comodel_name="scop.contribution.type", + string="Type de cotisation", + readonly=True) + partner_id = fields.Many2one('res.partner', string='Partner', readonly=True) + amount_called = fields.Float('Montant Appelé') + amount_paid = fields.Float('Montant Payé') + amount_due = fields.Float('Montant Restant') + is_loss = fields.Boolean('Exonération/Perte') + payments = fields.Html('Paiements', compute="_compute_payments") + + _depends = { + 'account.invoice': [ + 'year', 'type_contribution_id', 'partner_id', + 'amount_total_signed', 'residual_company_signed', + 'state', 'type', 'is_contribution', 'refund_invoice_id' + ], + } + + # ------------------------------------------------------ + # Sub Query + # ------------------------------------------------------ + def _select_invoice(self): + select_str = """ + SELECT + CAST(i.year AS VARCHAR), + i.type_contribution_id, + i.partner_id, + SUM(i.amount_total_signed) AS amount_called, + SUM(i.amount_total_signed - i.residual_company_signed) AS amount_paid, + SUM(i.residual_company_signed) AS amount_due, + (CASE WHEN max(refund.id) IS NOT NULL THEN true ELSE FALSE END) AS is_loss + """ + return select_str + + def _from_invoice(self): + from_str = """ + FROM + account_invoice i + LEFT JOIN + account_invoice refund ON refund.refund_invoice_id = i.id + """ + return from_str + + def _where_invoice(self): + where_str = """ + WHERE + i.type = 'out_invoice' AND + i.state in ('open', 'paid') AND + i.is_contribution = true + """ + return where_str + + def _groupby_invoice(self): + groupby_str = """ + GROUP BY + i.year, + i.type_contribution_id, + i.partner_id + """ + return groupby_str + + def _query_invoice(self): + query = "(%s %s %s %s)" % ( + self._select_invoice(), self._from_invoice(), + self._where_invoice(), self._groupby_invoice()) + return query + + def _subquery(self): + return self._query_invoice() + + # ------------------------------------------------------ + # Main Query + # ------------------------------------------------------ + def _select(self): + select_str = """ + SELECT + ROW_NUMBER() OVER(ORDER BY c.year, c.partner_id) AS id, + c.year, + c.type_contribution_id, + c.partner_id, + SUM(c.amount_called) AS amount_called, + SUM(c.amount_paid) AS amount_paid, + SUM(c.amount_due) AS amount_due, + BOOL_OR(c.is_loss) AS is_loss + FROM ( + """ + return select_str + + def _query_groupby(self): + return """ + GROUP BY + c.year, + c.type_contribution_id, + c.partner_id + """ + + def _query_order(self): + return "ORDER BY c.year DESC" + + def _query(self): + query = ( + self._select() + self._subquery() + ') c ' + + self._query_groupby() + self._query_order() + ) + return query + + @api.model_cr + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute("""CREATE or REPLACE VIEW %s as ( + %s + )""" % ( + self._table, self._query())) + + # ------------------------------------------------------ + # Computed fields + # ------------------------------------------------------ + @api.multi + def _compute_name(self): + for contribution in self: + contribution.name = (contribution.year + ' - ' + + contribution.type_contribution_id.name + + ' - ' + contribution.partner_id.name) + + @api.multi + def _compute_payments(self): + for contribution in self: + contribution.payments = contribution._get_payment() + + # ------------------------------------------------------ + # Business functions + # ------------------------------------------------------ + def _get_payment(self): + self.ensure_one() + invoice_ids = self.env['account.invoice'].search([ + ('year', '=', int(self.year)), + ('partner_id', '=', self.partner_id.id), + ('type_contribution_id', '=', self.type_contribution_id.id), + ('type', '=', 'out_invoice') + ]) + payment_ids = invoice_ids.mapped('payment_move_line_ids') + if payment_ids: + payments = payment_ids.mapped(lambda p: { + 'date': p.date, + 'name': p.name, + 'ref': p.ref, + 'credit': p.credit, + }) + payments_html = self._get_html_table(payments) + else: + payments_html = "<p>Il n'y a pas de paiements associés à cette cotisation</p>" + return payments_html + + def _get_html_table(self, payments): + """ + :param payments: list of dict {date, name, ref, amount} + @return: HTML table with payments + """ + start_html = """ + <table class='table table-sm table-striped table-hover table-bordered'> + <thead><tr> + <th>Date</th> + <th>Libellé</th> + <th>Référence</th> + <th>Montant</th> + </tr></thead> + <tbody> + """ + content_html = "" + for payment in payments: + content_html += """ + <tr> + <td>%s</td> + <td>%s</td> + <td>%s</td> + <td class='text-right'>%.2f €</td> + </tr> + """ % (payment.get('date', '').strftime('%d/%m/%Y'), + payment.get('name', ''), payment.get('ref', ''), + payment.get('credit', 0.0),) + + end_html = "</tbody></table>" + return start_html + content_html + end_html diff --git a/report/scop_contribution_report.xml b/report/scop_contribution_report.xml new file mode 100644 index 0000000000000000000000000000000000000000..6b7fbd72581220dcf5dd99fc7dbb5dce9d511d09 --- /dev/null +++ b/report/scop_contribution_report.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <data> + <!-- SEARCH VIEW --> + <record model="ir.ui.view" id="scop_contribution_report_search"> + <field name="name">scop.contribution.report.search</field> + <field name="model">scop.contribution.report</field> + <field name="arch" type="xml"> + <search string="Cotisations"> + <field name='partner_id'/> + <field name="year"/> + <field name="type_contribution_id"/> + <filter name="filter_paid" string="À régler" domain="[('amount_due', '!=', 0)]"/> + <filter name="filter_paid" string="Réglé" domain="[('amount_due', '=', 0)]"/> + <separator></separator> + <filter name="filter_cg" string="Cotisations CG" domain="[('type_contribution_id', '=', 1)]"/> + <filter name="filter_ur" string="Cotisations UR" domain="[('type_contribution_id', '=', 3)]"/> + <filter name="filter_fede" string="Cotisations Fédé" domain="[('type_contribution_id', '=', 2)]"/> + <group expand="0" string="Group By"> + <filter name="group_by_type_contribution_id" string="Type de cotisation" context="{'group_by':'type_contribution_id'}"/> + <filter name="group_by_year" string="Année" context="{'group_by':'year'}"/> + </group> + </search> + </field> + </record> + + <!-- TREE VIEW --> + <record model="ir.ui.view" id="scop_contribution_report_tree"> + <field name="name">scop.contribution.report.tree</field> + <field name="model">scop.contribution.report</field> + <field name="arch" type="xml"> + <tree string="Cotisations"> + <field name="year"/> + <field name="type_contribution_id"/> + <field name='partner_id'/> + <field name='amount_called'/> + <field name='amount_paid'/> + <field name='amount_due'/> + </tree> + </field> + </record> + + <!-- FORM VIEW --> + <record model="ir.ui.view" id="scop_contribution_report_form"> + <field name="name">scop.contribution.report.form</field> + <field name="model">scop.contribution.report</field> + <field name="arch" type="xml"> + <form string="Cotisations"> + <sheet> + <h2><field name="name"/></h2> + <separator></separator> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th>Montant Appelé</th> + <th>Montant payé</th> + <th>Montant restant</th> + </tr> + </thead> + <tbody> + <tr> + <td><field name='amount_called'/> €</td> + <td><field name='amount_paid'/> €</td> + <td><field name='amount_due'/> €</td> + </tr> + </tbody> + </table> + <separator></separator> + <h4>Détail des Paiements</h4> + <field name='payments' widget="html"/> + </sheet> + </form> + </field> + </record> + + <!-- PIVOT VIEW --> + <record model="ir.ui.view" id="scop_contribution_report_pivot"> + <field name="name">scop.contribution.report.pivot</field> + <field name="model">scop.contribution.report</field> + <field name="arch" type="xml"> + <pivot string="Cotisations"> + <field name="year" type="row"/> + <field name="type_contribution_id" type="row"/> + <field name='amount_called' type="measure"/> + <field name='amount_paid' type="measure"/> + <field name='amount_due' type="measure"/> + </pivot> + </field> + </record> + + <!-- GRAPH VIEW --> + <record model="ir.ui.view" id="scop_contribution_report_graph"> + <field name="name">scop.contribution.report.graph</field> + <field name="model">scop.contribution.report</field> + <field name="arch" type="xml"> + <graph string="Cotisations"> + <field name="year"/> + <field name='amount_called' type="measure"/> + <field name='amount_paid' type="measure"/> + <field name='amount_due' type="measure"/> + </graph> + </field> + </record> + + <!-- ACTION --> + <record id="scop_contribution_report_action" model="ir.actions.act_window"> + <field name="name">Vue cotisations</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">scop.contribution.report</field> + <field name="view_mode">tree,pivot,graph,form</field> + </record> + + <!-- Menu --> + <menuitem + id="scop_contribution_report_menu" + name="Cotisations" + parent="account.account_reports_management_menu" + action="scop_contribution_report_action" + sequence="80" + /> + </data> +</odoo> diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index e20c8308a728efd5f82e307bdc0f250490c415a3..731427df84b1438d79b90c8dc5c23e0953a861b1 100755 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -1,3 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_scop_cotisation_task,access_scop_cotisation_task,model_scop_cotisation_task,account.group_account_manager,1,1,1,0 admin_access_scop_cotisation_task,admin_access_scop_cotisation_task,model_scop_cotisation_task,cgscop_partner.group_cg_administrator,1,1,1,1 +access_scop_contribution_report_user,access_scop_contribution_report_user,model_scop_contribution_report,base.group_user,1,0,0,0 \ No newline at end of file diff --git a/views/account_invoice.xml b/views/account_invoice.xml index d1b466ad9bf0350801ac27bac1c123abdb1d7dc9..4241a5bd8551419939c6972a7895c38c82a5c665 100644 --- a/views/account_invoice.xml +++ b/views/account_invoice.xml @@ -34,6 +34,17 @@ <attribute name="invisible">True</attribute> </xpath> + + <xpath expr="//field[@name='beneficiary_id']" position="attributes"> + <attribute name="invisible">True</attribute> + </xpath> + <xpath expr="//field[@name='lf_note_ref_facture']" position="attributes"> + <attribute name="invisible">True</attribute> + </xpath> + <xpath expr="//field[@name='team_id']" position="attributes"> + <attribute name="invisible">True</attribute> + </xpath> + <xpath expr="//sheet/h1/div/label[1]" position="attributes"> <attribute name="string">Cotisation en brouillon</attribute> </xpath> @@ -52,6 +63,9 @@ <xpath expr="//field[@name='partner_id']" position="attributes"> <attribute name="string">Adhérent</attribute> </xpath> + <xpath expr="//field[@name='partner_id']" position="after"> + <field name="type_contribution_id"/> + </xpath> <xpath expr="//field[@name='date_invoice']" position="attributes"> <attribute name="string">Date de cotisation</attribute> </xpath> @@ -67,6 +81,7 @@ <xpath expr="//field[@name='state']" position="after"> <field name="is_sdd" invisible="1"/> </xpath> + </field> </record> diff --git a/views/account_payment_term.xml b/views/account_payment_term.xml deleted file mode 100644 index 926975d35503140dc179961186dbd57f571e5261..0000000000000000000000000000000000000000 --- a/views/account_payment_term.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<odoo> - <!-- Copyright 2020 Le Filament - License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> - <data> - - <record id="view_payment_term_form_inherited" model="ir.ui.view"> - <field name="name">account.payment.term.form</field> - <field name="model">account.payment.term</field> - <field name="inherit_id" ref="account.view_payment_term_form"/> - <field name="arch" type="xml"> - <xpath expr="//group" position="after"> - <group name="schedule"> - <field name="is_contribution" widget="boolean_toggle"/> - </group> - </xpath> - </field> - </record> - - </data> -</odoo> \ No newline at end of file diff --git a/views/res_config_settings.xml b/views/res_config_settings.xml index 3cd000f26b42bf369c2f52e148ec125fe2dd6de2..f97b36ad4962d78d1d9b9c34cb8c4f2cad56bcc7 100644 --- a/views/res_config_settings.xml +++ b/views/res_config_settings.xml @@ -29,13 +29,6 @@ </div> <field name="contribution_journal_id" options="{'no_open': True, 'no_create': True}"/> </div> - <div class="o_setting_right_pane"> - <label for="contribution_default_payment_term_id"/> - <div class="text-muted"> - Conditions de paiement par défault - </div> - <field name="contribution_default_payment_term_id" options="{'no_open': True, 'no_create': True}"/> - </div> <div class="o_setting_left_pane"/> <div class="o_setting_right_pane"> <label for="tag_cotiz_id"/> diff --git a/views/res_partner.xml b/views/res_partner.xml index 3a9946327458e17d45390276491290a35f8cc686..b0a5c4532275eb22b82859dcb5002806ca057788 100644 --- a/views/res_partner.xml +++ b/views/res_partner.xml @@ -9,9 +9,24 @@ <field name="model">res.partner</field> <field name="inherit_id" ref="cgscop_partner.scop_contact_view_form"/> <field name="arch" type="xml"> - <xpath expr="//field[@name='contribution_ids']/tree/field[@name='spreading']" position="before"> - <field name="is_exempt" style="text-align: center;"/> - <button name="view_refund" type="object" icon="fa-eye" attrs="{'invisible': [('is_exempt', '=', False)]}" style="pointer-events: visible;"/> + <xpath expr="//page[@name='scop_membership']" position="after"> + <page name='scop_contribution' string="Cotisations" attrs="{'invisible': ['|', ('is_cooperative', '!=', True), ('project_status', '!=', '6_suivi')]}"> + <notebook> + <page name="contribution" string="Appels de Cotisations"> + <field name="contribution_report_ids" mode="tree,form"> + <tree create="false" edit="false" delete="false" default_order="year desc"> + <field name="year"/> + <field name="type_contribution_id"/> + <field name='partner_id'/> + <field name='amount_called'/> + <field name='amount_paid'/> + <field name='amount_due'/> + <field name='is_loss' style="text-align: center;"/> + </tree> + </field> + </page> + </notebook> + </page> </xpath> </field> </record>