Skip to content
Extraits de code Groupes Projets
Valider 497edfdd rédigé par Benjamin - Le Filament's avatar Benjamin - Le Filament
Parcourir les fichiers

[add] report contribution for partner

parent bbccaf91
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!212.0 dev
# -*- coding: utf-8 -*- # © 2022 Le Filament (<http://www.le-filament.com>)
# Part of Odoo. See LICENSE file for full copyright and licensing details. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models from . import models
from . import report
from . import wizard from . import wizard
from odoo import api, SUPERUSER_ID from odoo import api, SUPERUSER_ID
......
# © 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", "name": "CG SCOP - Cotisations",
"summary": "CG SCOP - Cotisations", "summary": "CG SCOP - Cotisations",
...@@ -24,6 +26,7 @@ ...@@ -24,6 +26,7 @@
"views/res_config_settings.xml", "views/res_config_settings.xml",
"views/res_partner.xml", "views/res_partner.xml",
"views/scop_cotisation_task.xml", "views/scop_cotisation_task.xml",
"report/scop_contribution_report.xml",
], ],
"qweb": [ "qweb": [
"static/src/xml/*.xml", "static/src/xml/*.xml",
......
...@@ -6,6 +6,7 @@ from . import account_payment_order ...@@ -6,6 +6,7 @@ from . import account_payment_order
from . import chart_template from . import chart_template
from . import res_company from . import res_company
from . import res_config_settings from . import res_config_settings
from . import res_partner
from . import scop_contribution from . import scop_contribution
from . import scop_cotisation from . import scop_cotisation
from . import scop_cotisation_task from . import scop_cotisation_task
# © 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',
)
# © 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
# © 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
<?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>
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 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 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 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
...@@ -9,9 +9,24 @@ ...@@ -9,9 +9,24 @@
<field name="model">res.partner</field> <field name="model">res.partner</field>
<field name="inherit_id" ref="cgscop_partner.scop_contact_view_form"/> <field name="inherit_id" ref="cgscop_partner.scop_contact_view_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='contribution_ids']/tree/field[@name='spreading']" position="before"> <xpath expr="//page[@name='scop_membership']" position="after">
<field name="is_exempt" style="text-align: center;"/> <page name='scop_contribution' string="Cotisations" attrs="{'invisible': ['|', ('is_cooperative', '!=', True), ('project_status', '!=', '6_suivi')]}">
<button name="view_refund" type="object" icon="fa-eye" attrs="{'invisible': [('is_exempt', '=', False)]}" style="pointer-events: visible;"/> <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> </xpath>
</field> </field>
</record> </record>
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter