Compare commits
No commits in common. 'old16.0' and '16-gn-fec' have entirely different histories.
@ -1,2 +1,2 @@
|
|||||||
*__pycache__
|
__pycache__/
|
||||||
*~lock*
|
*.py[cod]
|
@ -1,5 +0,0 @@
|
|||||||
# GN-ODOO
|
|
||||||
|
|
||||||
|
|
||||||
Addons for Odoo 16.
|
|
||||||
Starting with association loi 1901 chart of accounts.
|
|
@ -1,4 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
||||||
|
|
||||||
#from . import models
|
|
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "France - Contrats",
|
|
||||||
"version": "16.0.0.0.1",
|
|
||||||
"category": "Payroll",
|
|
||||||
"summary": "Templates for French contracts and agreements",
|
|
||||||
"author": "Le Garage Numérique",
|
|
||||||
"maintainers": ["makayabou"],
|
|
||||||
"website": "https://odoo.legaragenumerique.fr",
|
|
||||||
"depends": [
|
|
||||||
"agreement",
|
|
||||||
"agreement_legal",
|
|
||||||
"partner_company_type"
|
|
||||||
],
|
|
||||||
"data": [
|
|
||||||
"views/gn_agreement_bipartisan_agreement.xml",
|
|
||||||
"views/gn_agreement_external_layout_striped_footer.xml",
|
|
||||||
"data/gn_agreement_document_layout.xml",
|
|
||||||
"data/gn_agreement_types.xml",
|
|
||||||
"data/gn_agreement_convention_cadre_template.xml",
|
|
||||||
"data/gn_agreement_convention_avenant_template.xml",
|
|
||||||
],
|
|
||||||
"license": "LGPL-3",
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<data>
|
|
||||||
<record id="gn_agreement.layout_convention_partenariat_avenant" model="agreement">
|
|
||||||
<field name="is_template">true</field>
|
|
||||||
<field name="name">Modèle d'avenant lié à une convention-cadre de partenariat</field>
|
|
||||||
<field name="agreement_type_id" ref="gn_agreement.agreement_type_convention_partenariat"/>
|
|
||||||
<field name="agreement_subtype_id" ref="gn_agreement.agreement_subtype_convention_partenariat_avenant"/>
|
|
||||||
<field name="description">Avenant à la convention-cadre {{object.parent_agreement_id.code or ''}}</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_agreement.recital_ref_cadre" model="agreement.recital">
|
|
||||||
<field name="name">référence à la convention-cadre</field>
|
|
||||||
<field name="sequence">10</field>
|
|
||||||
<field name="content"><![CDATA[
|
|
||||||
Les entités {{ object.agreement_id.company_id.name }} et {{ object.agreement_id.partner_id.name }} sont liées par des engagements mutuels,<br/>
|
|
||||||
établis dans la convention-cadre {{ object.agreement_id.parent_agreement_id.code }} portant sur le dispositif {{ object.agreement_id.parent_agreement_id.name }}]]>
|
|
||||||
</field>
|
|
||||||
<field name="agreement_id" ref="gn_agreement.layout_convention_partenariat_avenant"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_agreement.convention_partenariat_avenant_section_art1" model="agreement.section">
|
|
||||||
<field name="name">Article 1 - Objet du présent avenant</field>
|
|
||||||
<field name="sequence">1</field>
|
|
||||||
<field name="title">Article 1 - Objet du présent avenant</field>
|
|
||||||
<field name="content"><![CDATA[Le présent avenant a pour objet de définir la participation de {{ object.agreement_id.company_id.name }} au projet {{ object.agreement_id.parent_agreement_id.description or ''}}.]]></field>
|
|
||||||
<field name="agreement_id" ref="gn_agreement.layout_convention_partenariat_avenant"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_agreement.convention_partenariat_avenant_section_art2" model="agreement.section">
|
|
||||||
<field name="name">Article 2 - Actions à mettre en oeuvre</field>
|
|
||||||
<field name="sequence">2</field>
|
|
||||||
<field name="title">Article 2 - Actions à mettre en oeuvre</field>
|
|
||||||
<field name="content"><![CDATA[{{ object.agreement_id.company_id.name}} s'engage à mettre en oeuvre les actions suivantes, dans le cadre défini par le dispositif {{ object.agreement_id.parent_agreement_id.name }}, entre le {{ object.agreement_id.start_date }} et le {{object.agreement_id.to_review_date}}:]]></field>
|
|
||||||
<field name="agreement_id" ref="gn_agreement.layout_convention_partenariat_avenant"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_agreement.convention_partenariat_avenant_section_art3" model="agreement.section">
|
|
||||||
<field name="name">Article 3 - Dispositions financières</field>
|
|
||||||
<field name="sequence">3</field>
|
|
||||||
<field name="title">Article 3 - Dispositions financières</field>
|
|
||||||
<field name="content"><![CDATA[
|
|
||||||
{{ object.agreement_id.partner_id.name }} établit ses factures qu'elle adresse à {{ object.agreement_id.company_id.name }}.<br/><br/>
|
|
||||||
|
|
||||||
{{ object.agreement_id.company_id.name }} s'engage à régler la facture émise, par chèque ou virement bancaire, dès réception et au plus tard avant la fin de la convention-cadre, soit le {{ object.agreement_id.end_date }}.]]></field>
|
|
||||||
<field name="agreement_id" ref="gn_agreement.layout_convention_partenariat_avenant"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_agreement.convention_partenariat_avenant_section_art4" model="agreement.section">
|
|
||||||
<field name="name">Article 4 - Date d'effet</field>
|
|
||||||
<field name="sequence">4</field>
|
|
||||||
<field name="title">Article 4 - Date d'effet</field>
|
|
||||||
<field name="content"><![CDATA[
|
|
||||||
Le présent avenant prend effet au {{ object.agreement_id.start_date }}.]]></field>
|
|
||||||
<field name="agreement_id" ref="gn_agreement.layout_convention_partenariat_avenant"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_agreement.convention_partenariat_avenant_section_art5" model="agreement.section">
|
|
||||||
<field name="name">Article 5 - Dispositions de la convention-cadre</field>
|
|
||||||
<field name="sequence">5</field>
|
|
||||||
<field name="title">Article 5 - Dispositions de la convention-cadre</field>
|
|
||||||
<field name="content"><![CDATA[
|
|
||||||
L'ensemble des dispositions de la convention-cadre {{ object.agreement_id.parent_agreement_id.code }}, non-contraire aux présentes, demeurent inchangées.]]></field>
|
|
||||||
<field name="agreement_id" ref="gn_agreement.layout_convention_partenariat_avenant"/>
|
|
||||||
</record>
|
|
||||||
</data>
|
|
||||||
</odoo>
|
|
@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<data>
|
|
||||||
<record id="gn_agreement.report_layout" model="report.layout">
|
|
||||||
<field name="name">GN</field>
|
|
||||||
<field name="sequence">6</field>
|
|
||||||
<field name="view_id" ref="gn_agreement.external_layout_striped_footer"/>
|
|
||||||
</record>
|
|
||||||
</data>
|
|
||||||
</odoo>
|
|
@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<data>
|
|
||||||
<record id="gn_agreement.agreement_type_convention_partenariat" model="agreement.type">
|
|
||||||
<field name="name">Convention de partenariat</field>
|
|
||||||
<field name="domain">sale</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_agreement.agreement_subtype_convention_partenariat_cadre" model="agreement.subtype">
|
|
||||||
<field name="name">Convention-Cadre</field>
|
|
||||||
<field name="agreement_type_id" ref="gn_agreement.agreement_type_convention_partenariat"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_agreement.agreement_subtype_convention_partenariat_avenant" model="agreement.subtype">
|
|
||||||
<field name="name">Avenant</field>
|
|
||||||
<field name="agreement_type_id" ref="gn_agreement.agreement_type_convention_partenariat"/>
|
|
||||||
</record>
|
|
||||||
</data>
|
|
||||||
</odoo>
|
|
@ -1,156 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<template id="gn_agreement.report_agreement_document" inherit_id="agreement_legal.report_agreement_document">
|
|
||||||
<xpath expr="//div[contains(@class, 'page') and .//table]" position="replace">
|
|
||||||
<div class="page">
|
|
||||||
<h1 style="font-size: 1.5rem; text-align: center; font-weight: bold"><span t-field="doc.code"/> : <t t-if="doc.template_id"><span t-field="doc.template_id.description"/></t><t t-else=""><span t-field="doc.name"/></t>
|
|
||||||
<t t-if="doc.parent_agreement_id"><span t-field="doc.parent_agreement_id.code"/></t></h1>
|
|
||||||
<t t-if="doc.parent_agreement_id">
|
|
||||||
<h1 style="font-size: 1.5rem; text-align: center; font-weight: bold"><span t-field="doc.parent_agreement_id.name"/></h1>
|
|
||||||
</t>
|
|
||||||
|
|
||||||
<div style="font-size: 1.5rem; text-align: center;" name="description">
|
|
||||||
|
|
||||||
<span t-field="doc.name"/>
|
|
||||||
</div>
|
|
||||||
<!--<h2>Parties</h2>-->
|
|
||||||
<div name="parties">
|
|
||||||
<t t-if="doc.use_parties_content">
|
|
||||||
<p t-field="doc.dynamic_parties"/>
|
|
||||||
</t>
|
|
||||||
|
|
||||||
<t t-else="">
|
|
||||||
<div class="my-3">
|
|
||||||
<h6 style="font-weight: bold">Entre</h6>
|
|
||||||
<div name="company_address">
|
|
||||||
<t t-set="a" t-value="doc.company_id.partner_id"/>
|
|
||||||
<div>
|
|
||||||
<p class="mb-0">
|
|
||||||
<span style="font-weight: bold;" t-field="a.name"/>,
|
|
||||||
<span t-field="a.partner_company_type_id"/>,
|
|
||||||
dont les activités sont situées au
|
|
||||||
<span t-field="a.street"/>,
|
|
||||||
<span t-field="a.zip"/>
|
|
||||||
<span t-field="a.city"/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div name="company_contact">
|
|
||||||
Representée par <span style="font-weight: bold" t-field="doc.company_contact_id.name"/>, en qualité de <span t-field="doc.company_contact_id.function"/>.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="my-3">
|
|
||||||
<h6 style="font-weight: bold">Et</h6>
|
|
||||||
<div name="partner_address">
|
|
||||||
<t t-set="a" t-value="doc.partner_id"/>
|
|
||||||
<div>
|
|
||||||
<p class="mb-0">
|
|
||||||
<span style="font-weight: bold;" t-field="a.name"/>,
|
|
||||||
<span t-field="a.partner_company_type_id"/>, dont les activités sont situées au
|
|
||||||
<span t-field="a.street"/>,
|
|
||||||
<span t-field="a.zip"/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div name="company_contact">
|
|
||||||
Representée par <span style="font-weight: bold" t-field="doc.partner_contact_id.name"/>, en qualité de <span t-field="doc.partner_contact_id.function"/>.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style="text-align:right;" name="company_contact_denomination">
|
|
||||||
Ci-après dénommés <span style="font-weight: bold">"Les partenaires"</span> ou <span style="font-weight: bold">"Les parties"</span>
|
|
||||||
</div>
|
|
||||||
</t>
|
|
||||||
<!--
|
|
||||||
<t t-else="">
|
|
||||||
<h3>Company Information</h3>
|
|
||||||
<div name="company_address">
|
|
||||||
<address t-field="doc.company_id.partner_id" t-options="{"widget": "contact", "fields": ["address", "name"], "no_marker": True}"/>
|
|
||||||
</div>
|
|
||||||
<div name="company_contact">
|
|
||||||
Represented by <span t-field="doc.company_contact_id.name"/>.
|
|
||||||
</div>
|
|
||||||
<h3>Partner Information</h3>
|
|
||||||
<div name="partner_address">
|
|
||||||
<address t-field="doc.partner_id" t-options="{"widget": "contact", "fields": ["address", "name"], "no_marker": True}"/>
|
|
||||||
</div>
|
|
||||||
<div name="partner_contact">
|
|
||||||
Represented by <span t-field="doc.partner_contact_id.name"/>.
|
|
||||||
</div>
|
|
||||||
</t>
|
|
||||||
-->
|
|
||||||
</div>
|
|
||||||
<!--<h2>Agreement</h2>-->
|
|
||||||
<h3 style="font-size: 1.2rem;">Préambule</h3>
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<t t-foreach="doc.recital_ids" t-as="r">
|
|
||||||
<t t-if="r.title">
|
|
||||||
<h3 style="font-size: 1rem;" t-field="r.title"/>
|
|
||||||
</t>
|
|
||||||
<p t-field="r.dynamic_content"/>
|
|
||||||
</t>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<p>C'est dans ce contexte que les parties se sont rapprochées afin de convenir de ce qui suit: </p>
|
|
||||||
<t t-foreach="doc.sections_ids" t-as="s">
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<tbody class="section_tbody">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
<t t-if="s.title">
|
|
||||||
<h3 style="font-size: 1.2rem;" t-field="s.title"/>
|
|
||||||
</t>
|
|
||||||
<p t-field="s.dynamic_content"/>
|
|
||||||
<ol>
|
|
||||||
<li t-foreach="s.clauses_ids" t-as="c">
|
|
||||||
<t t-if="c.title">
|
|
||||||
<h4 style="font-size: 1rem;" t-field="c.title"/>
|
|
||||||
</t>
|
|
||||||
<p t-field="c.dynamic_content"/>
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</t>
|
|
||||||
<t t-if="special_term">
|
|
||||||
<h2>Special Terms</h2>
|
|
||||||
<div name="special_term">
|
|
||||||
<p t-field="doc.dynamic_special_terms"/>
|
|
||||||
</div>
|
|
||||||
</t>
|
|
||||||
<!--<h2>Signatures</h2>-->
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<theader>
|
|
||||||
<tr>
|
|
||||||
<th>Signatures</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</theader>
|
|
||||||
<tbody class="section_tbody">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<p style="font-weight: bold;">Pour <span t-field="doc.company_id.partner_id"/></p>
|
|
||||||
<p><span t-field="doc.company_contact_id.name"/>, <span t-field="doc.company_contact_id.function"/></p>
|
|
||||||
<p>le <span t-field="doc.company_signed_date"/><br/><br/><br/><br/><br/><br/><br/></p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<p style="font-weight: bold;">Pour <span t-field="doc.partner_id"/>,</p>
|
|
||||||
<p><span t-field="doc.partner_contact_id.name"/>, <span t-field="doc.partner_contact_id.function"/></p>
|
|
||||||
<p>le <span t-field="doc.partner_signed_date"/><br/><br/><br/><br/><br/><br/><br/> </p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
</odoo>
|
|
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<template id="gn_agreement.external_layout_striped_footer" inherit_id="web.external_layout_striped">
|
|
||||||
<xpath expr="//div[contains(@class, 'text-muted') and span[contains(@class, 'page')] and span[contains(@class, 'topage')]]" position="replace">
|
|
||||||
<div t-if="report_type == 'pdf'" class="text-muted">
|
|
||||||
Page <span class="page"/> sur <span class="topage"/> -
|
|
||||||
<t t-if="doc and doc._name == 'agreement'"><span t-field="doc.code"/><span> : </span><t t-if="doc.template_id"><span t-field="doc.template_id.description"/></t> <t t-if="doc.parent_agreement_id"><span t-field="doc.parent_agreement_id.code"/></t><t t-else=""><span t-field="doc.name"/> </t></t><span t-if="display_name_in_footer" t-field="o.name"/>
|
|
||||||
</div>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
</odoo>
|
|
@ -0,0 +1,74 @@
|
|||||||
|
# GN-CASH
|
||||||
|
|
||||||
|
This modules revivals cash statements from Odoo 15.
|
||||||
|
|
||||||
|
It adds a wizard for cashbox counting after balance_start an balance_end_real fields of bank.statement form view.
|
||||||
|
|
||||||
|
It is based on modules:
|
||||||
|
- [account_statement_base from OCA](https://github.com/OCA/account-reconcile)
|
||||||
|
- [account_statement_import_sheet_file](https://github.com/OCA/bank-statement-import)
|
||||||
|
- [account_cash_deposit](https://github.com/OCA/account-financial-tools)
|
||||||
|
|
||||||
|
|
||||||
|
## How do we work with it:
|
||||||
|
|
||||||
|
1. Each day, users create operations like receive donation, pay expenses, etc. The counterpart is their own property_account_payable_id (467 or 425)
|
||||||
|
2. When the accountant gives/receive money to/from user, the accountant registers the cash-out/deposit to/from user (i.e. user's property_account_payable_id vs cash_account_id)
|
||||||
|
3. The accountant can then:
|
||||||
|
1. Generates a cash statement
|
||||||
|
2. Verify cashbox and generate loss/profit move
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Define cash statement import sheet template
|
||||||
|
- Import Cash statements
|
||||||
|
- Counting cashbox start and end for cash statements
|
||||||
|
- Create cash deposit / orders with currency lines
|
||||||
|
- Define a partner or a bank destination account for deposit / orders
|
||||||
|
- Generate Cash statement from payments, deposits and orphan statement lines
|
||||||
|
- Generate loss/profit move and statement line in case of miscount
|
||||||
|
|
||||||
|
## Whats Needs to Be Done:
|
||||||
|
|
||||||
|
- [x] add validate cashbox and entry lines creation | 16.0.0.0.1
|
||||||
|
- [x] loss/profit validation | 16.0.0.0.2
|
||||||
|
- [x] use predefined cash units | 16.0.0.0.3
|
||||||
|
- [x] sequencing on statement gen | 16.0.0.0.4
|
||||||
|
- [x] add button on payment to access statement if is_matched |16.0.0.0.5
|
||||||
|
- [x] add orphan statement lines in the next gen statement | 16.0.0.0.6
|
||||||
|
- [x] add partner in deposit and move | 16.0.0.0.7
|
||||||
|
- [x] use suspense account | 16.0.0.0.7
|
||||||
|
- [x] add button in dashboard to create a deposit / order | 16.0.0.0.8
|
||||||
|
- [x] add some defaults (date, default_lines) at deposit creation | 16.0.0.0.8
|
||||||
|
- [x] add wizard for cash order / deposit creation | 16.0.0.0.9
|
||||||
|
- [x] add nav buttons in wizard | 16.0.0.0.10
|
||||||
|
- [x] compute total in wizard | 16.0.0.0.11
|
||||||
|
- [x] bug: comparison values in on_change deposit.wizard | 16.0.0.0.12
|
||||||
|
- [x] remove use of on_change for deposit creation (creation done in action_confirm) | 16.0.0.0.12
|
||||||
|
- [x] add confirmations buttons in wizard | 16.0.0.0.12
|
||||||
|
- [x] return form view after deposit creation | 16.0.0.0.12
|
||||||
|
- [x] custom deposit form view | 16.0.0.0.12
|
||||||
|
- [x] add default cash units for cash order | 16.0.0.0.13
|
||||||
|
- [x] debug confirmation buttons and line_ids transmission | 16.0.0.0.14
|
||||||
|
- [x] verbose message for missing fields (could be highlighted?) | 16.0.0.0.15
|
||||||
|
- [x] forbid coin_amount to be defined in order/deposit from/to bank | 16.0.0.16
|
||||||
|
- [x] add a button to put directly the cash order from bank to cash | 16.0.0.17
|
||||||
|
- [x] add cash deposits / cash outs to statement | 16.0.0.18
|
||||||
|
- [x] check all reconciled before closing loss/profit | 16.0.0.19
|
||||||
|
- [] What to do when statement line generated has no label
|
||||||
|
- [] better handling of line_ids creation in deposit wizard
|
||||||
|
- [] report cashbox to next statement
|
||||||
|
- [] compute cashbox from cash entries
|
||||||
|
- [] upgrade _get_journal_dashboard_outstanding_payments for deposits being also counted for journal kanban card in accounting dashboard
|
||||||
|
|
||||||
|
## Security ToDo
|
||||||
|
|
||||||
|
- checks if all existing statements are valid before create one
|
||||||
|
- constrain coin_amount at model/db level
|
||||||
|
- check what happens when several currencies are defined on company's journals
|
||||||
|
|
||||||
|
## Bug
|
||||||
|
- [] need to validate 2 times for profit/loss line creation in cash statement
|
||||||
|
|
||||||
|
## Optimization
|
||||||
|
- work on README
|
@ -1,3 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
from . import wizards
|
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
'name': "Gn Cash",
|
||||||
|
'version': '16.0.0.0.18',
|
||||||
|
'author': 'Garage Numérique',
|
||||||
|
'category': 'Accounting',
|
||||||
|
'description': """
|
||||||
|
This module revivals cash statements from odoo 15.
|
||||||
|
""",
|
||||||
|
'depends': ['account_reconcile_oca', 'account_statement_import_sheet_file', 'account_cash_deposit'],
|
||||||
|
'data': [
|
||||||
|
'data/cash_statement_validate.xml',
|
||||||
|
'views/delete_views.xml',
|
||||||
|
'views/account_cash_statement_cashbox_views.xml',
|
||||||
|
'views/account_journal_ConfigForm_view.xml',
|
||||||
|
'views/account_cash_statement_views.xml',
|
||||||
|
'wizards/account_cash_deposit_bystep.xml',
|
||||||
|
'views/account_cash_deposit_views.xml',
|
||||||
|
'views/account_journal_dashboard_view.xml',
|
||||||
|
'views/account_payment_views.xml',
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
],
|
||||||
|
'translate': True,
|
||||||
|
'installable': True,
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="gn_cash.action_validate_cash_statement" model="ir.actions.server">
|
||||||
|
<field name="name">Validate Cash Statement</field>
|
||||||
|
<field name="model_id" ref="model_account_bank_statement"/>
|
||||||
|
<field name="state">code</field>
|
||||||
|
<field name="code">
|
||||||
|
<![CDATA[
|
||||||
|
statement_id = env.context.get('statement_id')
|
||||||
|
action = env['account.bank.statement'].browse(statement_id)._create_closing_difference_line_values()
|
||||||
|
]]>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import cash_statement, account_journal_dashboard, account_cash_deposit, account_payment
|
@ -0,0 +1,276 @@
|
|||||||
|
from odoo import models, api, _, fields
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class AccountCashDeposit(models.Model):
|
||||||
|
_inherit = 'account.cash.deposit'
|
||||||
|
|
||||||
|
partner_id = fields.Many2one(
|
||||||
|
comodel_name='res.partner',
|
||||||
|
domain=[
|
||||||
|
('is_company','=', False),
|
||||||
|
'|',
|
||||||
|
('parent_id', '=', False),
|
||||||
|
('parent_id.is_company', '=', True)
|
||||||
|
],
|
||||||
|
string='Partner',
|
||||||
|
store=True, readonly=False,
|
||||||
|
ondelete='restrict',
|
||||||
|
)
|
||||||
|
|
||||||
|
cash_journal_id = fields.Many2one(
|
||||||
|
"account.journal",
|
||||||
|
string="Cash or Bank Journal",
|
||||||
|
required=True,
|
||||||
|
domain=['|',
|
||||||
|
('type', '=', 'cash'),
|
||||||
|
'&',
|
||||||
|
('type', '=', 'bank'),
|
||||||
|
('bank_journal_id', '!=', False)
|
||||||
|
],
|
||||||
|
check_company=True,
|
||||||
|
readonly=True,
|
||||||
|
states={"draft": [("readonly", "=", False)]},
|
||||||
|
tracking=True,
|
||||||
|
)
|
||||||
|
cash_journal_type = fields.Selection(related='cash_journal_id.type', string="Origin Journal Type")
|
||||||
|
|
||||||
|
bank_journal_id = fields.Many2one(
|
||||||
|
"account.journal",
|
||||||
|
string="Counterpart Journal",
|
||||||
|
required=False,
|
||||||
|
domain=['|', ('type', '=', 'cash'), '&', ('type', '=', 'bank'),
|
||||||
|
('bank_journal_id', '!=', False)],
|
||||||
|
check_company=True,
|
||||||
|
readonly=True,
|
||||||
|
states={"draft": [("readonly", "=", False)]},
|
||||||
|
tracking=True,
|
||||||
|
)
|
||||||
|
counterpart_journal_type = fields.Selection(related='bank_journal_id.type', string="Counterpart Journal Type")
|
||||||
|
|
||||||
|
|
||||||
|
operation_type = fields.Selection(
|
||||||
|
[
|
||||||
|
("deposit", "Cash Deposit"),
|
||||||
|
("order", "Cash Order"),
|
||||||
|
],
|
||||||
|
required=True,
|
||||||
|
readonly=True,
|
||||||
|
states={"draft": [("readonly", "=", False)]},
|
||||||
|
)
|
||||||
|
|
||||||
|
'''
|
||||||
|
Reconciliation
|
||||||
|
'''
|
||||||
|
is_matched = fields.Boolean(string="Is Matched With a Bank Statement", store=True,
|
||||||
|
compute='_compute_reconciliation')
|
||||||
|
is_reconcile = fields.Boolean(
|
||||||
|
compute="_compute_reconciliation", store=True, string="Reconciled"
|
||||||
|
)
|
||||||
|
reconciled_statement_line_ids = fields.Many2many(
|
||||||
|
comodel_name='account.bank.statement.line',
|
||||||
|
string="Reconciled Statement Lines",
|
||||||
|
compute='_compute_reconciliation',
|
||||||
|
help="Statements lines matched to this deposit",
|
||||||
|
)
|
||||||
|
reconciled_statement_lines_count = fields.Integer(
|
||||||
|
string="# Reconciled Statement Lines",
|
||||||
|
compute="_compute_reconciliation",
|
||||||
|
)
|
||||||
|
reconciled_statement_ids = fields.Many2many(
|
||||||
|
comodel_name='account.bank.statement',
|
||||||
|
string="Reconciled Statements",
|
||||||
|
compute='_compute_reconciliation',
|
||||||
|
help="Statements matched to this payment",
|
||||||
|
)
|
||||||
|
reconciled_statements_count = fields.Integer(
|
||||||
|
string="# Reconciled Statement",
|
||||||
|
compute="_compute_reconciliation",
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends("move_id.line_ids.reconciled", "company_id")
|
||||||
|
def _compute_reconciliation(self):
|
||||||
|
for deposit in self:
|
||||||
|
match_counterpart = False
|
||||||
|
match_statement = False
|
||||||
|
reconciled_lines = self.env['account.move.line']
|
||||||
|
if deposit.move_id:
|
||||||
|
for line in deposit.move_id.line_ids:
|
||||||
|
if line.reconciled:
|
||||||
|
if line.account_id.id == deposit.move_id.journal_id.order_credit_account_id.id \
|
||||||
|
or deposit.move_id.journal_id.deposit_debit_account_id.id:
|
||||||
|
match_statement = True
|
||||||
|
elif line.account_id.id == deposit.partner_id.property_account_payable_id.id:
|
||||||
|
match_counterpart = True
|
||||||
|
elif line.account_id.id != self.company_id.transfer_account_id.id:
|
||||||
|
raise UserError("A line from the deposit %s is incorrect" % deposit.name)
|
||||||
|
|
||||||
|
if match_statement == True:
|
||||||
|
for partial in line.matched_credit_ids | line.matched_debit_ids:
|
||||||
|
reconciled_lines |= partial.debit_move_id | partial.credit_move_id
|
||||||
|
|
||||||
|
deposit.reconciled_statement_line_ids = [(6, 0, reconciled_lines.mapped('statement_line_id').ids)]
|
||||||
|
deposit.reconciled_statement_lines_count = len(deposit.reconciled_statement_line_ids)
|
||||||
|
deposit.is_matched = match_statement
|
||||||
|
deposit.is_reconcile = match_counterpart
|
||||||
|
statement_ids = {line.statement_id.id for line in reconciled_lines}
|
||||||
|
deposit.reconciled_statement_ids = [(6, 0, list(statement_ids))]
|
||||||
|
deposit.reconciled_statements_count = len(statement_ids)
|
||||||
|
|
||||||
|
def button_open_statement_lines(self):
|
||||||
|
''' Redirect the user to the statement line(s) reconciled to this payment.
|
||||||
|
:return: An action
|
||||||
|
'''
|
||||||
|
self.ensure_one()
|
||||||
|
|
||||||
|
action = {
|
||||||
|
'name': _("Matched Transactions"),
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'account.bank.statement.line',
|
||||||
|
'context': {'create': False},
|
||||||
|
}
|
||||||
|
if len(self.reconciled_statement_line_ids) == 1:
|
||||||
|
action.update({
|
||||||
|
'view_mode': 'form',
|
||||||
|
'res_id': self.reconciled_statement_line_ids.id,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
action.update({
|
||||||
|
'view_mode': 'list,form',
|
||||||
|
'domain': [('id', 'in', self.reconciled_statement_line_ids.ids)],
|
||||||
|
})
|
||||||
|
return action
|
||||||
|
|
||||||
|
def button_open_statements(self):
|
||||||
|
self.ensure_one()
|
||||||
|
action = {
|
||||||
|
'name': _("Statements"),
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'account.bank.statement',
|
||||||
|
'context': {'create': False, 'journal_type': 'cash'},
|
||||||
|
}
|
||||||
|
if len(self.reconciled_statement_ids) == 1:
|
||||||
|
action.update({
|
||||||
|
'views': [[self.env.ref('gn_cash.view_cash_statement_form').id, "form"]],
|
||||||
|
'res_id': self.reconciled_statement_ids.id,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
action.update({
|
||||||
|
'views': [[False, "list"], [self.env.ref('gn_cash.view_cash_statement_form').id, "form"]],
|
||||||
|
'domain': [('id', 'in', self.reconciled_statement_ids.ids)],
|
||||||
|
})
|
||||||
|
return action
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
End of fields and methods related to statements
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
def _prepare_account_move(self, vals):
|
||||||
|
move_vals = super()._prepare_account_move(vals)
|
||||||
|
if move_vals['line_ids']:
|
||||||
|
'''
|
||||||
|
Inverse debit / credit and use suspense_account_id for further reconciliation with statement
|
||||||
|
'''
|
||||||
|
journal = self.env['account.journal'].browse(move_vals['journal_id'])
|
||||||
|
debit_account_id = journal.deposit_debit_account_id.id
|
||||||
|
credit_account_id = journal.order_credit_account_id.id
|
||||||
|
|
||||||
|
if not (debit_account_id or credit_account_id):
|
||||||
|
raise UserError("Default debit and credit account must be defined in journal settings")
|
||||||
|
|
||||||
|
for line_tuple in move_vals["line_ids"]:
|
||||||
|
if line_tuple[2]['account_id'] == self.company_id.transfer_account_id.id:
|
||||||
|
if line_tuple[2]['amount_currency'] > 0:
|
||||||
|
line_tuple[2]['account_id'] = debit_account_id
|
||||||
|
else:
|
||||||
|
line_tuple[2]['account_id'] = credit_account_id
|
||||||
|
if self.partner_id:
|
||||||
|
line_tuple[2]['partner_id'] = self.partner_id.id
|
||||||
|
else:
|
||||||
|
if self.partner_id:
|
||||||
|
line_tuple[2]['account_id'] = self.partner_id.property_account_payable_id.id
|
||||||
|
line_tuple[2]['partner_id'] = self.partner_id.id
|
||||||
|
else:
|
||||||
|
line_tuple[2]['account_id'] = self.company_id.transfer_account_id.id
|
||||||
|
|
||||||
|
return move_vals
|
||||||
|
|
||||||
|
def confirm_order_and_receive(self):
|
||||||
|
self.confirm_order()
|
||||||
|
action = self.env['ir.actions.act_window']._for_xml_id('account_cash_deposit.account_cash_order_reception_action')
|
||||||
|
action['context'] = {'default_order_id': self.id}
|
||||||
|
return action
|
||||||
|
|
||||||
|
def create_counterpart_deposit(self):
|
||||||
|
if self.state != 'done':
|
||||||
|
raise UserError("La contrepartie ne peut être créée tant que cet enregistrement n'est pas validé")
|
||||||
|
if self.partner_id:
|
||||||
|
raise UserError("La contrepartie ne concerne que les transferts de banque à espèces")
|
||||||
|
if not self.partner_id and self.bank_journal_id.id == self.cash_journal_id.id:
|
||||||
|
raise UserError("Le journal de destination ne peut pas être le même que le journal d'origine")
|
||||||
|
lines = [{
|
||||||
|
'qty': line['qty'],
|
||||||
|
'cash_unit_id': line['cash_unit_id'].id,
|
||||||
|
} for line in self.line_ids]
|
||||||
|
counterpart_vals = {
|
||||||
|
'operation_type': 'order' if self.operation_type == 'deposit' else 'deposit',
|
||||||
|
'date': self.date,
|
||||||
|
'cash_journal_id': self.bank_journal_id.id,
|
||||||
|
'bank_journal_id': self.cash_journal_id.id,
|
||||||
|
'currency_id': self.currency_id.id,
|
||||||
|
'company_id': self.company_id.id,
|
||||||
|
'coin_amount': self.coin_amount,
|
||||||
|
'line_ids': [(0, 0, line) for line in lines],
|
||||||
|
}
|
||||||
|
counterpart_deposit = self.env['account.cash.deposit'].create(counterpart_vals)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'type': "ir.actions.act_window",
|
||||||
|
'res_model': 'account.cash.deposit',
|
||||||
|
'res_id': counterpart_deposit.id,
|
||||||
|
'view_mode': 'form',
|
||||||
|
'view_id': self.env.ref('gn_cash.view_cash_deposit_form').id,
|
||||||
|
'target': 'new',
|
||||||
|
'context': {'is_counterpart_of': self.move_id.id}
|
||||||
|
}
|
||||||
|
|
||||||
|
def validate(self, force_date=None):
|
||||||
|
super().validate(force_date=force_date)
|
||||||
|
counterpart_move = self.move_id
|
||||||
|
origin_move = self.env['account.move'].browse(self.env.context.get('is_counterpart_of')) if self.env.context.get('is_counterpart_of') else False
|
||||||
|
if origin_move:
|
||||||
|
lines_to_reconcile = [line for line in (counterpart_move.line_ids + origin_move.line_ids) if line.account_id.id == self.company_id.transfer_account_id.id]
|
||||||
|
if len(lines_to_reconcile) == 2:
|
||||||
|
(lines_to_reconcile[0] + lines_to_reconcile[1]).reconcile()
|
||||||
|
elif not self.partner_id:
|
||||||
|
return {
|
||||||
|
'type': "ir.actions.act_window",
|
||||||
|
'res_model': 'account.cash.deposit',
|
||||||
|
'res_id': self.id,
|
||||||
|
'view_mode': 'form',
|
||||||
|
'view_id': self.env.ref('gn_cash.view_cash_deposit_form').id,
|
||||||
|
'target': 'new',
|
||||||
|
'context': {'is_counterpart_of': False}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AccountCashOrderReception(models.TransientModel):
|
||||||
|
_inherit = "account.cash.order.reception"
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
super().run()
|
||||||
|
context = dict(self.env.context)
|
||||||
|
if not self.order_id.partner_id and not self.order_id.is_reconcile:
|
||||||
|
return {
|
||||||
|
'type': "ir.actions.act_window",
|
||||||
|
'res_model': 'account.cash.deposit',
|
||||||
|
'res_id': self.order_id.id,
|
||||||
|
'view_mode': 'form',
|
||||||
|
'view_id': self.env.ref('gn_cash.view_cash_deposit_form').id,
|
||||||
|
'target': 'new',
|
||||||
|
'context': context
|
||||||
|
}
|
@ -0,0 +1,163 @@
|
|||||||
|
from odoo import models, api, _, fields
|
||||||
|
import itertools
|
||||||
|
from datetime import datetime
|
||||||
|
from odoo.exceptions import ValidationError, UserError
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class AccountJournal(models.Model):
|
||||||
|
_inherit = "account.journal"
|
||||||
|
|
||||||
|
deposit_debit_account_id = fields.Many2one(
|
||||||
|
comodel_name='account.account', check_company=True,
|
||||||
|
string='Default account for cash deposit',
|
||||||
|
domain="[('deprecated', '=', False), ('company_id', '=', company_id), \
|
||||||
|
('account_type', '=', 'asset_current'), ('reconcile', '=', True)]")
|
||||||
|
|
||||||
|
order_credit_account_id = fields.Many2one(
|
||||||
|
comodel_name='account.account', check_company=True,
|
||||||
|
string='Default account for cash order',
|
||||||
|
domain="[('deprecated', '=', False), ('company_id', '=', company_id), \
|
||||||
|
('account_type', '=', 'asset_current'), ('reconcile', '=', True)]")
|
||||||
|
|
||||||
|
def cash_in_or_out(self):
|
||||||
|
for journal in self:
|
||||||
|
journal.ensure_one()
|
||||||
|
|
||||||
|
# Call form view
|
||||||
|
action = self.env['ir.actions.act_window']._for_xml_id('gn_cash.account_cash_inorout_action_wizard')
|
||||||
|
ctx = dict(self.env.context)
|
||||||
|
|
||||||
|
ctx.update({
|
||||||
|
'default_company_id': self.env.company.id,
|
||||||
|
'default_currency_id': journal.currency_id.id or journal.company_currency_id.id,
|
||||||
|
'default_operating_journal_id': journal.id,
|
||||||
|
'default_step': 'type',
|
||||||
|
})
|
||||||
|
action['context'] = ctx
|
||||||
|
return action
|
||||||
|
|
||||||
|
|
||||||
|
def generate_statement_line_from_payment(self, payment_id):
|
||||||
|
payment = self.env['account.payment'].browse(payment_id)
|
||||||
|
stmt_line_values = {
|
||||||
|
'date': payment.date,
|
||||||
|
'move_type': payment.move_type,
|
||||||
|
'journal_id': self.id,
|
||||||
|
'payment_ref': payment.ref,
|
||||||
|
'partner_id': payment.partner_id.id,
|
||||||
|
'amount': payment.amount if payment.payment_type == 'inbound' else -payment.amount
|
||||||
|
}
|
||||||
|
return stmt_line_values
|
||||||
|
|
||||||
|
def generate_statement_line_from_deposit(self, deposit_id):
|
||||||
|
deposit = self.env['account.cash.deposit'].browse(deposit_id)
|
||||||
|
stmt_line_values = {
|
||||||
|
'date': deposit.date,
|
||||||
|
'move_type': deposit.move_id.move_type,
|
||||||
|
'journal_id': deposit.move_id.journal_id.id,
|
||||||
|
'payment_ref': deposit.name,
|
||||||
|
'partner_id': deposit.partner_id.id,
|
||||||
|
'amount': deposit.total_amount * (deposit.operation_type == 'deposit' and 1 or -1)
|
||||||
|
}
|
||||||
|
return stmt_line_values
|
||||||
|
|
||||||
|
def create_cash_statement(self):
|
||||||
|
self.ensure_one()
|
||||||
|
context = dict(self.env.context or {})
|
||||||
|
|
||||||
|
if context.get('journal_type', False) == 'cash':
|
||||||
|
'''
|
||||||
|
Search for payments
|
||||||
|
'''
|
||||||
|
payment_lines = []
|
||||||
|
payment_values = self.env['account.payment'].search([
|
||||||
|
('journal_id', '=', self.id),
|
||||||
|
('is_matched', '=', False),
|
||||||
|
('date', '<=', fields.Date.context_today(self)),
|
||||||
|
('state', '=', 'posted'),
|
||||||
|
]).sorted(key=lambda r: (r.date, r.id)).read(['date', 'id', 'amount', 'ref', 'partner_id', 'payment_type'])
|
||||||
|
|
||||||
|
payment_ids = [pay['id'] for pay in payment_values]
|
||||||
|
for payment_id in payment_ids:
|
||||||
|
stmt_line_values = self.generate_statement_line_from_payment(payment_id)
|
||||||
|
stmt_line = self.env['account.bank.statement.line'].create(stmt_line_values)
|
||||||
|
payment_lines.extend(stmt_line.read(['date', 'id']))
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
Search for cash orders / cash deposits
|
||||||
|
'''
|
||||||
|
deposit_lines = []
|
||||||
|
deposit_values = self.env['account.cash.deposit'].search([
|
||||||
|
('cash_journal_id', '=', self.id),
|
||||||
|
('is_matched', '=', False),
|
||||||
|
('date', '<=', fields.Date.context_today(self)),
|
||||||
|
('state', '=', 'done'),
|
||||||
|
]).sorted(key=lambda r: (r.date, r.id)).read(['date', 'id', 'total_amount', 'name', 'partner_id', 'operation_type'])
|
||||||
|
|
||||||
|
deposit_ids = [deposit['id'] for deposit in deposit_values]
|
||||||
|
for deposit_id in deposit_ids:
|
||||||
|
stmt_line_values = self.generate_statement_line_from_deposit(deposit_id)
|
||||||
|
stmt_line = self.env['account.bank.statement.line'].create(stmt_line_values)
|
||||||
|
deposit_lines.extend(stmt_line.read(['date', 'id']))
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
Search for orphan statement lines
|
||||||
|
'''
|
||||||
|
orphan_lines = self.env['account.bank.statement.line'].search([
|
||||||
|
('statement_id', '=', False),
|
||||||
|
('state', '=', 'posted'),
|
||||||
|
('journal_id', '=', self.id),
|
||||||
|
('date', '<=', fields.Date.context_today(self)),
|
||||||
|
]).sorted(key=lambda r: (r.date, r.id)).read(['date', 'id'])
|
||||||
|
|
||||||
|
orphan_lines_iter_by_date = itertools.groupby(orphan_lines, lambda l: l['date'])
|
||||||
|
orphan_lines_by_date = [{'date': iter_date, 'lines': sorted([line['id'] for line in iter_lines])} for iter_date, iter_lines in orphan_lines_iter_by_date]
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
Collect lines by date
|
||||||
|
'''
|
||||||
|
stmt_line_ids_to_set = []
|
||||||
|
dates_sorted = sorted(set([group['date'] for group in orphan_lines_by_date if len(orphan_lines_by_date) > 0]))
|
||||||
|
for date in dates_sorted:
|
||||||
|
orphan_lines_for_date = [group['lines'] for group in orphan_lines_by_date if len(orphan_lines_by_date) > 0 and group['date'] == date]
|
||||||
|
for lines_grouped in orphan_lines_for_date:
|
||||||
|
stmt_line_ids_to_set.extend([line_id for line_id in lines_grouped])
|
||||||
|
|
||||||
|
if len(stmt_line_ids_to_set) > 0:
|
||||||
|
'''
|
||||||
|
Create statement
|
||||||
|
'''
|
||||||
|
stmt_vals = {
|
||||||
|
'name': f"Registre de caisse généré manuellement - {fields.Datetime.now()}",
|
||||||
|
'date': fields.Date.context_today(self),
|
||||||
|
'line_ids': [(6, 0, stmt_line_ids_to_set)],
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
new_stmt = self.env['account.bank.statement'].create(stmt_vals)
|
||||||
|
except Exception as e:
|
||||||
|
_logger.error("Error creating bank statement: %s" % str(e))
|
||||||
|
raise
|
||||||
|
|
||||||
|
'''
|
||||||
|
Resquence lines in statement
|
||||||
|
'''
|
||||||
|
sequence = 1
|
||||||
|
for line_to_set in stmt_line_ids_to_set:
|
||||||
|
new_stmt.write({'line_ids': [(1, line_to_set, {'sequence': sequence})]})
|
||||||
|
sequence += 1
|
||||||
|
|
||||||
|
'''
|
||||||
|
return form view for statement
|
||||||
|
'''
|
||||||
|
action = self.env['ir.actions.act_window']._for_xml_id('gn_cash.action_cash_statement_tree')
|
||||||
|
action['views'] = [[self.env.ref('gn_cash.view_cash_statement_form').id, "form"]]
|
||||||
|
action['res_id'] = new_stmt.id
|
||||||
|
return action
|
||||||
|
else:
|
||||||
|
raise ValidationError("No bank statement to generate")
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
from odoo import models, api, _, fields
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class AccountPayment(models.Model):
|
||||||
|
_inherit = "account.payment"
|
||||||
|
|
||||||
|
reconciled_statement_ids = fields.Many2many(
|
||||||
|
comodel_name='account.bank.statement',
|
||||||
|
string="Reconciled Statements",
|
||||||
|
compute='_compute_stat_statement_button',
|
||||||
|
help="Statements matched to this payment",
|
||||||
|
)
|
||||||
|
reconciled_statement_count = fields.Integer(
|
||||||
|
string="# Reconciled Statement",
|
||||||
|
compute="_compute_stat_statement_button",
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends('reconciled_statement_line_ids')
|
||||||
|
def _compute_stat_statement_button(self):
|
||||||
|
for pay in self:
|
||||||
|
statement_ids = {line.statement_id.id for line in pay.reconciled_statement_line_ids if line.statement_id}
|
||||||
|
pay.reconciled_statement_ids = [(6, 0, list(statement_ids))]
|
||||||
|
pay.reconciled_statement_count = len(statement_ids)
|
||||||
|
|
||||||
|
|
||||||
|
def button_open_statements(self):
|
||||||
|
self.ensure_one()
|
||||||
|
action = {
|
||||||
|
'name': _("Statements"),
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'account.bank.statement',
|
||||||
|
'context': {'create': False, 'journal_type': 'cash'},
|
||||||
|
}
|
||||||
|
if len(self.reconciled_statement_ids) == 1:
|
||||||
|
action.update({
|
||||||
|
'views': [[self.env.ref('gn_cash.view_cash_statement_form').id, "form"]],
|
||||||
|
'res_id': self.reconciled_statement_ids.id,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
action.update({
|
||||||
|
'views': [[False, "list"], [self.env.ref('gn_cash.view_cash_statement_form').id, "form"]],
|
||||||
|
'domain': [('id', 'in', self.reconciled_statement_ids.ids)],
|
||||||
|
})
|
||||||
|
return action
|
@ -0,0 +1,224 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import api, fields, models, _
|
||||||
|
from odoo.exceptions import UserError, ValidationError, RedirectWarning
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class AccountCashboxLine(models.Model):
|
||||||
|
""" Cash Box Details """
|
||||||
|
_name = 'gn_cash.account.cashbox.line'
|
||||||
|
_description = 'CashBox Line'
|
||||||
|
_rec_name = 'coin_value'
|
||||||
|
_order = 'coin_value'
|
||||||
|
|
||||||
|
cash_unit_id = fields.Many2one(
|
||||||
|
"cash.unit", required=True, domain="[('currency_id', '=', currency_id)]"
|
||||||
|
)
|
||||||
|
tree_order = fields.Float(related="cash_unit_id.tree_order", store=True)
|
||||||
|
|
||||||
|
cashbox_id = fields.Many2one('gn_cash.account.bank.statement.cashbox', string="Cashbox")
|
||||||
|
currency_id = fields.Many2one('res.currency', related='cashbox_id.currency_id')
|
||||||
|
|
||||||
|
qty = fields.Integer(string='#Coins/Bills', help='Opening Unit Numbers')
|
||||||
|
_sql_constraints = [
|
||||||
|
("qty_positive", "CHECK(qty >= 0)", "The quantity must be positive or null."),
|
||||||
|
(
|
||||||
|
"cash_unit_unique",
|
||||||
|
"unique(cash_unit_id, cashbox_id)",
|
||||||
|
"A line already exists for this cash unit.",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
coin_value = fields.Float(string='Coin/Bill Value', required=False, digits=0)
|
||||||
|
|
||||||
|
subtotal = fields.Float(compute='_compute_subtotal', string='Subtotal', digits=0, readonly=True)
|
||||||
|
|
||||||
|
@api.constrains("currency_id", "cash_unit_id")
|
||||||
|
def _check_lines(self):
|
||||||
|
for line in self:
|
||||||
|
if (
|
||||||
|
line.currency_id
|
||||||
|
and line.cash_unit_id
|
||||||
|
and line.currency_id != line.cash_unit_id.currency_id
|
||||||
|
):
|
||||||
|
raise ValidationError(
|
||||||
|
_(
|
||||||
|
"You must delete cash lines that are linked to a currency "
|
||||||
|
"other than %s."
|
||||||
|
)
|
||||||
|
% line.currency_id.name
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends("cash_unit_id", "qty")
|
||||||
|
def _compute_subtotal(self):
|
||||||
|
for line in self:
|
||||||
|
subtotal = 0
|
||||||
|
if line.cash_unit_id:
|
||||||
|
subtotal = line.cash_unit_id.total_value * line.qty
|
||||||
|
line.subtotal = subtotal
|
||||||
|
|
||||||
|
class AccountBankStmtCashWizard(models.Model):
|
||||||
|
"""
|
||||||
|
Account Bank Statement popup that allows entering cash details.
|
||||||
|
"""
|
||||||
|
_name = 'gn_cash.account.bank.statement.cashbox'
|
||||||
|
_description = 'Bank Statement Cashbox'
|
||||||
|
_rec_name = 'id'
|
||||||
|
|
||||||
|
cashbox_line_ids = fields.One2many('gn_cash.account.cashbox.line', 'cashbox_id', string='Cashbox Lines')
|
||||||
|
start_bank_stmt_ids = fields.One2many('account.bank.statement', 'cashbox_start_id')
|
||||||
|
end_bank_stmt_ids = fields.One2many('account.bank.statement', 'cashbox_end_id')
|
||||||
|
total = fields.Float(compute='_compute_total')
|
||||||
|
currency_id = fields.Many2one('res.currency', compute='_compute_currency')
|
||||||
|
|
||||||
|
@api.depends('start_bank_stmt_ids', 'end_bank_stmt_ids')
|
||||||
|
def _compute_currency(self):
|
||||||
|
for cashbox in self:
|
||||||
|
cashbox.currency_id = False
|
||||||
|
if cashbox.end_bank_stmt_ids:
|
||||||
|
cashbox.currency_id = cashbox.end_bank_stmt_ids[0].currency_id
|
||||||
|
if cashbox.start_bank_stmt_ids:
|
||||||
|
cashbox.currency_id = cashbox.start_bank_stmt_ids[0].currency_id
|
||||||
|
|
||||||
|
@api.depends('cashbox_line_ids', 'cashbox_line_ids.cash_unit_id', 'cashbox_line_ids.qty')
|
||||||
|
def _compute_total(self):
|
||||||
|
for cashbox in self:
|
||||||
|
cashbox.total = sum([line.subtotal for line in cashbox.cashbox_line_ids])
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def default_get(self, fields):
|
||||||
|
vals = super(AccountBankStmtCashWizard, self).default_get(fields)
|
||||||
|
balance = self.env.context.get('balance')
|
||||||
|
statement_id = self.env.context.get('statement_id')
|
||||||
|
if 'start_bank_stmt_ids' in fields and not vals.get('start_bank_stmt_ids') and statement_id and balance == 'start':
|
||||||
|
vals['start_bank_stmt_ids'] = [(6, 0, [statement_id])]
|
||||||
|
if 'end_bank_stmt_ids' in fields and not vals.get('end_bank_stmt_ids') and statement_id and balance == 'close':
|
||||||
|
vals['end_bank_stmt_ids'] = [(6, 0, [statement_id])]
|
||||||
|
|
||||||
|
return vals
|
||||||
|
|
||||||
|
def name_get(self):
|
||||||
|
result = []
|
||||||
|
for cashbox in self:
|
||||||
|
result.append((cashbox.id, str(cashbox.total)))
|
||||||
|
return result
|
||||||
|
|
||||||
|
@api.model_create_multi
|
||||||
|
def create(self, vals):
|
||||||
|
cashboxes = super(AccountBankStmtCashWizard, self).create(vals)
|
||||||
|
cashboxes._validate_cashbox()
|
||||||
|
return cashboxes
|
||||||
|
|
||||||
|
def write(self, vals):
|
||||||
|
res = super(AccountBankStmtCashWizard, self).write(vals)
|
||||||
|
self._validate_cashbox()
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _validate_cashbox(self):
|
||||||
|
for cashbox in self:
|
||||||
|
context = dict(self.env.context or {})
|
||||||
|
if cashbox.start_bank_stmt_ids:
|
||||||
|
cashbox.start_bank_stmt_ids[0].write({'balance_start': cashbox.total})
|
||||||
|
if cashbox.end_bank_stmt_ids:
|
||||||
|
cashbox.end_bank_stmt_ids[0].write({'balance_end_real': cashbox.total})
|
||||||
|
|
||||||
|
class BankStatement(models.Model):
|
||||||
|
_inherit = 'account.bank.statement'
|
||||||
|
|
||||||
|
cashbox_start_id = fields.Many2one('gn_cash.account.bank.statement.cashbox', string="Starting Cashbox")
|
||||||
|
cashbox_end_id = fields.Many2one('gn_cash.account.bank.statement.cashbox', string="Ending Cashbox")
|
||||||
|
is_reconciled = fields.Boolean(compute='_compute_is_reconciled', store=True)
|
||||||
|
|
||||||
|
@api.depends('line_ids.is_reconciled')
|
||||||
|
def _compute_is_reconciled(self):
|
||||||
|
for stmt in self:
|
||||||
|
stmt.is_reconciled = len(stmt.line_ids.filtered(lambda l: l.is_reconciled == True)) == len(stmt.line_ids)
|
||||||
|
|
||||||
|
def _create_closing_difference_line_values(self):
|
||||||
|
""" Check the balance_end_real (encoded manually by the user) is equals to the balance_end (computed by odoo).
|
||||||
|
For a cash statement, if there is a difference, the different is set automatically to a profit/loss account.
|
||||||
|
"""
|
||||||
|
for statement in self.filtered(lambda stmt: stmt.journal_id.type == 'cash'):
|
||||||
|
if not statement.is_reconciled:
|
||||||
|
raise UserError("you need to first reconcile all lines of statement")
|
||||||
|
if not statement.is_complete:
|
||||||
|
difference = statement.currency_id.round(statement.balance_end_real - statement.balance_end)
|
||||||
|
if difference != 0:
|
||||||
|
last_sequence = statement.line_ids.sorted(key=lambda r: r.sequence, reverse=True)[0].sequence
|
||||||
|
st_line_vals = {
|
||||||
|
'statement_id': statement.id,
|
||||||
|
'journal_id': statement.journal_id.id,
|
||||||
|
'amount': difference,
|
||||||
|
'date': statement.date,
|
||||||
|
'sequence': last_sequence + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if difference < 0:
|
||||||
|
if not statement.journal_id.loss_account_id:
|
||||||
|
raise UserError(_(
|
||||||
|
"Please go on the %s journal and define a Loss Account. "
|
||||||
|
"This account will be used to record cash difference.",
|
||||||
|
statement.journal_id.name
|
||||||
|
))
|
||||||
|
|
||||||
|
st_line_vals['payment_ref'] = _("Cash difference observed during the counting (Loss)")
|
||||||
|
st_line_vals['counterpart_account_id'] = statement.journal_id.loss_account_id.id
|
||||||
|
else:
|
||||||
|
# statement.difference > 0.0
|
||||||
|
if not statement.journal_id.profit_account_id:
|
||||||
|
raise UserError(_(
|
||||||
|
"Please go on the %s journal and define a Profit Account. "
|
||||||
|
"This account will be used to record cash difference.",
|
||||||
|
statement.journal_id.name
|
||||||
|
))
|
||||||
|
|
||||||
|
st_line_vals['payment_ref'] = _("Cash difference observed during the counting (Profit)")
|
||||||
|
st_line_vals['counterpart_account_id'] = statement.journal_id.profit_account_id.id
|
||||||
|
|
||||||
|
self.env['account.bank.statement.line'].create(st_line_vals)
|
||||||
|
|
||||||
|
|
||||||
|
def open_cashbox_id(self):
|
||||||
|
self.ensure_one()
|
||||||
|
context = dict(self.env.context or {})
|
||||||
|
if context.get('balance'):
|
||||||
|
context['statement_id'] = self.id
|
||||||
|
if context['balance'] == 'start':
|
||||||
|
cashbox_id = self.cashbox_start_id.id
|
||||||
|
elif context['balance'] == 'close':
|
||||||
|
cashbox_id = self.cashbox_end_id.id
|
||||||
|
else:
|
||||||
|
cashbox_id = False
|
||||||
|
|
||||||
|
action = {
|
||||||
|
'name': _('Cash Control'),
|
||||||
|
'view_mode': 'form',
|
||||||
|
'res_model': 'gn_cash.account.bank.statement.cashbox',
|
||||||
|
'view_id': self.env.ref('gn_cash.view_account_bnk_stmt_cashbox_footer').id,
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_id': cashbox_id,
|
||||||
|
'context': context,
|
||||||
|
'target': 'new'
|
||||||
|
}
|
||||||
|
|
||||||
|
return action
|
||||||
|
|
||||||
|
def _compute_closing_diff(self):
|
||||||
|
for stmt in self:
|
||||||
|
difference = stmt.currency_id.round(stmt.balance_end_real - stmt.balance_end)
|
||||||
|
if difference != 0:
|
||||||
|
return difference
|
||||||
|
|
||||||
|
def button_validate(self):
|
||||||
|
for statement in self:
|
||||||
|
if not statement.is_complete:
|
||||||
|
difference = statement._compute_closing_diff()
|
||||||
|
if difference:
|
||||||
|
action_id = self.env.ref('gn_cash.action_validate_cash_statement').id
|
||||||
|
raise RedirectWarning(
|
||||||
|
_("If you continue you will create move with difference %s, on statement %s, " % (difference, statement.id)),
|
||||||
|
action_id,
|
||||||
|
"Proceed",
|
||||||
|
additional_context={'statement_id': statement.id},
|
||||||
|
)
|
@ -0,0 +1,4 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_account_cashbox,account.bank.statement.cashbox,model_gn_cash_account_bank_statement_cashbox,account.group_account_user,1,1,1,1
|
||||||
|
access_account_cashbox_line,account.bank.statement.cashbox.line,model_gn_cash_account_cashbox_line,account.group_account_user,1,1,1,1
|
||||||
|
access_account_cash_deposit_wizard,account.cash.deposit.wizard,model_account_cash_deposit_wizard,account.group_account_user,1,1,1,1
|
|
@ -0,0 +1,99 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="gn_cash.view_cash_deposit_form" model="ir.ui.view">
|
||||||
|
<field name="name">gn_cash.account.cash.deposit.form</field>
|
||||||
|
<field name="model">account.cash.deposit</field>
|
||||||
|
<field name="inherit_id" ref="account_cash_deposit.account_cash_deposit_form"/>
|
||||||
|
<field name="priority">100</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="header" position="replace">
|
||||||
|
<header>
|
||||||
|
<field name="id" invisible="1"/>
|
||||||
|
<field name="cash_journal_type" invisible="0"/>
|
||||||
|
<field name="counterpart_journal_type" invisible="0"/>
|
||||||
|
<field name="is_reconcile" invisible="1"/>
|
||||||
|
<field name="is_matched" invisible="1"/>
|
||||||
|
<field name="partner_id" invisible="1"/>
|
||||||
|
<button
|
||||||
|
name="create_counterpart_deposit"
|
||||||
|
string="Créer la contrepartie"
|
||||||
|
type="object"
|
||||||
|
class="btn-primary"
|
||||||
|
attrs="{'invisible': [
|
||||||
|
'|',
|
||||||
|
('state', '!=', 'done'),
|
||||||
|
'|',
|
||||||
|
('is_reconcile', '=', True),
|
||||||
|
('partner_id', '!=', False)
|
||||||
|
]}"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
name="confirm_order_and_receive"
|
||||||
|
string="Confirm Order ++"
|
||||||
|
type="object"
|
||||||
|
class="btn-primary"
|
||||||
|
attrs="{'invisible': ['|', ('operation_type', '!=', 'order'), ('state', '!=', 'draft')]}"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
name="%(account_cash_deposit.account_cash_order_reception_action)d"
|
||||||
|
string="Cash Received"
|
||||||
|
type="action"
|
||||||
|
context="{'default_order_id': id}"
|
||||||
|
class="btn-primary"
|
||||||
|
attrs="{'invisible': ['|', ('operation_type', '!=', 'order'), ('state', '!=', 'confirmed')]}"
|
||||||
|
/>
|
||||||
|
<!-- deposit -->
|
||||||
|
<button
|
||||||
|
name="validate"
|
||||||
|
string="Validate"
|
||||||
|
type="object"
|
||||||
|
class="btn-primary"
|
||||||
|
attrs="{'invisible': ['|', ('operation_type', '!=', 'deposit'), ('state', '!=', 'draft')]}"
|
||||||
|
/>
|
||||||
|
<button name="get_report" string="Print" type="object" />
|
||||||
|
<button
|
||||||
|
name="backtodraft"
|
||||||
|
states="confirmed,done"
|
||||||
|
string="Back to Draft"
|
||||||
|
type="object"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="state"
|
||||||
|
widget="statusbar"
|
||||||
|
statusbar_visible="draft,done"
|
||||||
|
/>
|
||||||
|
</header>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//div[@class='oe_title']" position="before">
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="button_open_statement_lines" type="object" class="oe_stat_button" icon="fa-bars" attrs="{'invisible': [('is_matched','=', False)]}">
|
||||||
|
<div class="o_form_field o_stat_info">
|
||||||
|
<field name="reconciled_statement_lines_count"/>
|
||||||
|
<span> Ligne de relevé</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="button_open_statements" type="object" class="oe_stat_button" icon="fa-bars" attrs="{'invisible': [('is_matched','=', False)]}">
|
||||||
|
<div class="o_form_field o_stat_info">
|
||||||
|
<field name="reconciled_statements_count"/>
|
||||||
|
<span> Relevé</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='cash_journal_id']" position="attributes">
|
||||||
|
<attribute name="string">Journal de destination</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='bank_journal_id']" position="attributes">
|
||||||
|
<attribute name="attrs">{'invisible': 1}</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='coin_amount']" position="replace">
|
||||||
|
<field name="partner_id"/>
|
||||||
|
<field name="coin_amount"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="gn_cash.view_account_bnk_stmt_cashbox" model="ir.ui.view">
|
||||||
|
<field name="name">gn_cash.account.bnk_stmt_cashbox.form</field>
|
||||||
|
<field name="model">gn_cash.account.bank.statement.cashbox</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<sheet>
|
||||||
|
<field name="start_bank_stmt_ids" invisible="1"/>
|
||||||
|
<field name="end_bank_stmt_ids" invisible="1"/>
|
||||||
|
<field name="currency_id" invisible="1"/>
|
||||||
|
<group name="lines">
|
||||||
|
<field
|
||||||
|
name="cashbox_line_ids"
|
||||||
|
nolabel="1"
|
||||||
|
colspan="2"
|
||||||
|
context="{'default_currency_id': currency_id}"
|
||||||
|
>
|
||||||
|
<tree editable="bottom">
|
||||||
|
<field name="cash_unit_id" />
|
||||||
|
<field name="qty" />
|
||||||
|
<field name="subtotal" sum="1" />
|
||||||
|
<field name="currency_id" invisible="1" />
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</group>
|
||||||
|
<div>
|
||||||
|
<group>
|
||||||
|
<group class="oe_subtotal_footer oe_right" cols="6">
|
||||||
|
<field name="currency_id" invisible="1" />
|
||||||
|
<div class="o_td_label"></div>
|
||||||
|
<field name="total" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</div>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<record id="gn_cash.view_account_bnk_stmt_cashbox_footer" model="ir.ui.view">
|
||||||
|
<field name="name">gn_cash.account.bnk_stmt_cashbox.form</field>
|
||||||
|
<field name="model">gn_cash.account.bank.statement.cashbox</field>
|
||||||
|
<field name="priority">1000</field>
|
||||||
|
<field name="mode">primary</field>
|
||||||
|
<field name="inherit_id" ref="gn_cash.view_account_bnk_stmt_cashbox"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//sheet" position="after">
|
||||||
|
<footer>
|
||||||
|
<button string="Confirm" class="btn-primary" special="save" data-hotkey="v"/>
|
||||||
|
<button string="Cancel" class="btn-secondary" special="cancel" data-hotkey="z"/>
|
||||||
|
</footer>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="gn_cash.action_cash_statement_tree" model="ir.actions.act_window">
|
||||||
|
<field name="name">Cash Logs</field>
|
||||||
|
<field name="res_model">account.bank.statement</field>
|
||||||
|
<field name="view_mode">tree,form,pivot,graph</field>
|
||||||
|
<field name="domain">['|', ('journal_id', '=', False), ('journal_id.type', '=', 'cash')]</field>
|
||||||
|
<field name="context">{'journal_type':'cash'}</field>
|
||||||
|
<field name="search_view_id" ref="account.view_bank_statement_search"/>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="o_view_nocontent_smiling_face">
|
||||||
|
Create a new cash log
|
||||||
|
</p><p>
|
||||||
|
A Cash Register allows you to manage cash entries in your cash
|
||||||
|
journals. This feature provides an easy way to follow up cash
|
||||||
|
payments on a daily basis.
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<record id="gn_cash.view_cash_statement_form" model="ir.ui.view">
|
||||||
|
<field name="name">gn_cash.account.cash.statement.form</field>
|
||||||
|
<field name="model">account.bank.statement</field>
|
||||||
|
<field name="inherit_id" ref="account_statement_base.view_bank_statement_form"/>
|
||||||
|
<field name="priority">100</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//div[@role='alert']" position="before">
|
||||||
|
<header>
|
||||||
|
<field name="is_complete" invisible="1"/>
|
||||||
|
<field name="is_reconciled"/>
|
||||||
|
<button name="button_validate" invisible="context.get('journal_type', False) != 'cash'" attrs="{'invisible': [('is_complete', '=', True)]}" string="Clôturer" type="object" class="oe_highlight" />
|
||||||
|
</header>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='balance_start']" position="after" >
|
||||||
|
<button name="open_cashbox_id" invisible="context.get('journal_type', False) != 'cash'" string="→ Count" type="object" class="oe_edit_only oe_link oe_inline" context="{'balance':'start'}"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='balance_end_real']" position="after">
|
||||||
|
<button name="open_cashbox_id" invisible="context.get('journal_type', False) != 'cash'" string="→ Count" type="object" class="oe_edit_only oe_link oe_inline" context="{'balance':'close'}"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="gn_cash.view_account_journal_form" model="ir.ui.view">
|
||||||
|
<field name="name">gn_cash.account.journal.form</field>
|
||||||
|
<field name="model">account.journal</field>
|
||||||
|
<field name="inherit_id" ref="account.view_account_journal_form"/>
|
||||||
|
<field name="priority">200</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//field[@name='suspense_account_id']" position="after">
|
||||||
|
<field name='deposit_debit_account_id'
|
||||||
|
attrs="{'invisible': [('type', 'not in', ('bank', 'cash'))]}"/>
|
||||||
|
<field name='order_credit_account_id'
|
||||||
|
attrs="{'invisible': [('type', 'not in', ('bank', 'cash'))]}"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//page[@name='advanced_settings']/group" position="inside">
|
||||||
|
<group string="Statement Import Map for Cash" attrs="{'invisible': [('type','!=', 'cash')]}">
|
||||||
|
<field name="bank_statements_source" attrs="{'required': [('type', '=', 'cash')]}" widget="radio" groups="account.group_account_readonly"/>
|
||||||
|
<field name="default_sheet_mapping_id" />
|
||||||
|
</group>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="gn_cash.account_journal_dashboard_kanban_view" model="ir.ui.view">
|
||||||
|
<field name="name">gn_cash.journal.dashboard.kanban</field>
|
||||||
|
<field name="model">account.journal</field>
|
||||||
|
<field name="priority">100</field>
|
||||||
|
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr='//div[@name="bank_customer_payment"]' position='before'>
|
||||||
|
<div t-if="journal_type == 'cash'" name="new_statement">
|
||||||
|
<a role="menuitem" context="{'journal_type': 'cash'}" type="object" name="create_cash_statement">Nouveau Relevé</a>
|
||||||
|
</div>
|
||||||
|
<div t-if="journal_type == 'cash' or journal_type == 'bank'" name="new_cash_deposit_or_order">
|
||||||
|
<a
|
||||||
|
name="cash_in_or_out"
|
||||||
|
string="Cash In / Out"
|
||||||
|
type="object"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr='//button[@name="create_cash_statement"]' position='replace'>
|
||||||
|
<button t-if="dashboard.number_to_reconcile == 0" type="object" name="create_cash_statement" context="{'journal_type': 'cash'}" class="btn btn-primary" groups="account.group_account_invoice">Générer le relevé</button>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="gn_cash.view_account_payment_form" model="ir.ui.view">
|
||||||
|
<field name="name">gn_cash.account.payment.form</field>
|
||||||
|
<field name="inherit_id" ref="account.view_account_payment_form"/>
|
||||||
|
<field name="model">account.payment</field>
|
||||||
|
<field name="priority">100</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//button[@name='button_open_statement_lines']" position="before">
|
||||||
|
<button name="button_open_statements" type="object" class="oe_stat_button" icon="fa-bars" attrs="{'invisible': [('is_matched','=', False)]}">
|
||||||
|
<div class="o_form_field o_stat_info">
|
||||||
|
<field name="reconciled_statement_count"/>
|
||||||
|
<span> Relevé</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<delete model="ir.ui.view" id="gn_cash.view_account_journal_form"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import account_cash_deposit_bystep
|
@ -0,0 +1,219 @@
|
|||||||
|
from odoo import models, api, _, fields
|
||||||
|
from odoo.exceptions import ValidationError, UserError
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class AccountCashDepositWizard(models.TransientModel):
|
||||||
|
_name = "account.cash.deposit.wizard"
|
||||||
|
|
||||||
|
# Link to deposit id
|
||||||
|
deposit_id = fields.Many2one('account.cash.deposit', string="Cash Deposit")
|
||||||
|
|
||||||
|
# Duplicated fields from account.cash.deposit
|
||||||
|
'''
|
||||||
|
Here we do not use "related" because we want to use context to fill default values
|
||||||
|
'''
|
||||||
|
company_id = fields.Many2one(
|
||||||
|
"res.company",
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
partner_id = fields.Many2one(
|
||||||
|
comodel_name='res.partner',
|
||||||
|
domain=[('is_company','=', False), '|', ('parent_id', '=', False), ('parent_id.is_company', '=', True)],
|
||||||
|
string='Partner',
|
||||||
|
ondelete='cascade',
|
||||||
|
)
|
||||||
|
|
||||||
|
is_order = fields.Boolean(string="Is Order ?", default=True)
|
||||||
|
|
||||||
|
line_ids = fields.Many2many(
|
||||||
|
"account.cash.deposit.line",
|
||||||
|
string="Lines",
|
||||||
|
)
|
||||||
|
currency_id = fields.Many2one(
|
||||||
|
"res.currency",
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
order_date = fields.Date()
|
||||||
|
date = fields.Date(
|
||||||
|
copy=False,
|
||||||
|
help="Used as date for the journal entry.",
|
||||||
|
)
|
||||||
|
operating_journal_id = fields.Many2one(
|
||||||
|
"account.journal",
|
||||||
|
string="Operating Journal",
|
||||||
|
domain="[('company_id', '=', company_id), ('type', 'in', ['bank', 'cash'])]",
|
||||||
|
required=True,
|
||||||
|
check_company=True,
|
||||||
|
)
|
||||||
|
operating_journal_type = fields.Selection(related="operating_journal_id.type", string="Type of Journal where action performs")
|
||||||
|
|
||||||
|
counterpart_journal_id = fields.Many2one(
|
||||||
|
"account.journal",
|
||||||
|
string="Counterpart Journal",
|
||||||
|
domain="[('company_id', '=', company_id), ('type', 'in', ['bank', 'cash'])]",
|
||||||
|
required=False,
|
||||||
|
check_company=True,
|
||||||
|
)
|
||||||
|
counterpart_journal_type = fields.Selection(related="counterpart_journal_id.type", string="Type of Journal where counterpart occurs")
|
||||||
|
|
||||||
|
coin_amount = fields.Monetary(
|
||||||
|
string="Loose Coin Amount",
|
||||||
|
currency_field="currency_id",
|
||||||
|
help="If your bank has a coin counting machine, enter the total amount "
|
||||||
|
"of coins counted by the machine instead of creating a line for each type "
|
||||||
|
"of coin.",
|
||||||
|
)
|
||||||
|
total_amount = fields.Monetary(
|
||||||
|
compute="_compute_total_amount",
|
||||||
|
currency_field="currency_id",
|
||||||
|
)
|
||||||
|
notes = fields.Text()
|
||||||
|
|
||||||
|
# Specific fields needed in wizard
|
||||||
|
step = fields.Selection(
|
||||||
|
[
|
||||||
|
('type', "Type d'opération"),
|
||||||
|
('partner', "Choix du Partenaire"),
|
||||||
|
('content', "Détail de l'opération"),
|
||||||
|
('extra', "Date et Notes"),
|
||||||
|
],
|
||||||
|
default="type",
|
||||||
|
)
|
||||||
|
|
||||||
|
has_partner = fields.Boolean(string="Has partner?", default=True)
|
||||||
|
|
||||||
|
@api.depends("line_ids.subtotal", "coin_amount")
|
||||||
|
def _compute_total_amount(self):
|
||||||
|
for rec in self:
|
||||||
|
total_amount = rec.coin_amount
|
||||||
|
for line in rec.line_ids:
|
||||||
|
total_amount += line.subtotal
|
||||||
|
rec.total_amount = total_amount
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def default_get(self, fields_list):
|
||||||
|
res = super().default_get(fields_list)
|
||||||
|
company_id = self.env.context.get('default_company_id')
|
||||||
|
company = self.env['res.company'].browse(company_id) if company_id else self.env.company
|
||||||
|
currency_id = self.env.context.get('default_currency_id')
|
||||||
|
currency = self.env['res.currency'].browse(currency_id) if currency_id else company.currency_id
|
||||||
|
cash_units = self.env["cash.unit"].search(
|
||||||
|
[
|
||||||
|
("auto_create", "in", ("both", "order", "deposit")),
|
||||||
|
("currency_id", "=", currency.id),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
line_ids = self.env.context.get('default_line_ids')
|
||||||
|
res["line_ids"] = line_ids if line_ids else [(0, 0, {"cash_unit_id": cu.id}) for cu in cash_units]
|
||||||
|
return res
|
||||||
|
|
||||||
|
def action_confirm(self):
|
||||||
|
total_amount = self.total_amount if self.total_amount > 0 else False
|
||||||
|
if total_amount and \
|
||||||
|
((self.has_partner and self.partner_id) or \
|
||||||
|
(not self.has_partner and self.counterpart_journal_id)):
|
||||||
|
if self.is_order == True:
|
||||||
|
self.order_date = self.order_date if self.order_date else self.date if self.date else fields.Date.context_today(self)
|
||||||
|
self.date = False
|
||||||
|
else:
|
||||||
|
self.order_date = False
|
||||||
|
self.date = self.date if self.date else fields.Date.context_today(self)
|
||||||
|
deposit_values = {
|
||||||
|
'order_date': self.order_date,
|
||||||
|
'date': self.date,
|
||||||
|
'company_id': self.company_id.id,
|
||||||
|
'currency_id': self.currency_id.id,
|
||||||
|
'operation_type': 'order' if self.is_order else 'deposit',
|
||||||
|
'partner_id': self.partner_id.id,
|
||||||
|
'cash_journal_id': self.operating_journal_id.id,
|
||||||
|
'bank_journal_id': self.counterpart_journal_id.id if self.counterpart_journal_id else self.operating_journal_id.id,
|
||||||
|
'coin_amount': self.coin_amount,
|
||||||
|
'line_ids': [(6, 0, self.line_ids.ids)] if self.line_ids else False,
|
||||||
|
'notes': self.notes,
|
||||||
|
}
|
||||||
|
if not self.deposit_id:
|
||||||
|
deposit_id = self.env['account.cash.deposit'].create(deposit_values)
|
||||||
|
self.deposit_id = deposit_id.id
|
||||||
|
else:
|
||||||
|
self.deposit_id.update(deposit_values)
|
||||||
|
else:
|
||||||
|
missing_fields = [
|
||||||
|
("Montant total",total_amount)
|
||||||
|
]
|
||||||
|
if not self.has_partner and not self.counterpart_journal_id:
|
||||||
|
if self.is_order == True:
|
||||||
|
missing_fields.append(("Banque ou caisse de destination", self.counterpart_journal_id))
|
||||||
|
else:
|
||||||
|
missing_fields.append(("Banque ou caisse d'origine'", self.counterpart_journal_id))
|
||||||
|
if self.has_partner and not self.partner_id:
|
||||||
|
if self.is_order == True:
|
||||||
|
missing_fields.append(("Récipendiaire des fonds", self.partner_id))
|
||||||
|
else:
|
||||||
|
missing_fields.append(("Apporteur de fonds", self.partner_id))
|
||||||
|
raise ValidationError("Some fields require your attention: %s" % ' and '.join([
|
||||||
|
field[0] for field in missing_fields if not field[1]
|
||||||
|
]))
|
||||||
|
_logger.warning("deposit %s created/updated" % self.deposit_id.id)
|
||||||
|
return {
|
||||||
|
'type': "ir.actions.act_window",
|
||||||
|
'res_model': 'account.cash.deposit',
|
||||||
|
'res_id': self.deposit_id.id,
|
||||||
|
'view_mode': 'form',
|
||||||
|
'view_id': self.env.ref('gn_cash.view_cash_deposit_form').id,
|
||||||
|
'target': 'new',
|
||||||
|
}
|
||||||
|
|
||||||
|
@api.onchange('has_partner')
|
||||||
|
def prefill_partner(self):
|
||||||
|
if self.has_partner:
|
||||||
|
self.write({
|
||||||
|
'counterpart_journal_id': False
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
self.write({
|
||||||
|
'partner_id': False
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def conserve_wizard(self, line_ids=None):
|
||||||
|
action = self.env['ir.actions.act_window']._for_xml_id('gn_cash.account_cash_inorout_action_wizard')
|
||||||
|
new_title = "Cash %s %s %s" % (
|
||||||
|
"Order" if self.is_order else "Deposit",
|
||||||
|
" towards " if not self.is_order and self.operating_journal_id \
|
||||||
|
else " from " if self.is_order and self.operating_journal_id \
|
||||||
|
else " ",
|
||||||
|
self.operating_journal_id.name if self.operating_journal_id else ""
|
||||||
|
)
|
||||||
|
action['name'] = new_title
|
||||||
|
action['context'] = {
|
||||||
|
'default_company_id': self.company_id.id,
|
||||||
|
'default_currency_id': self.currency_id.id,
|
||||||
|
'default_operating_journal_id': self.operating_journal_id.id,
|
||||||
|
'default_counterpart_journal_id': self.counterpart_journal_id.id,
|
||||||
|
'default_step': self.step,
|
||||||
|
'default_has_partner': self.has_partner,
|
||||||
|
'default_partner_id': self.partner_id.id,
|
||||||
|
'default_coin_amount': self.coin_amount,
|
||||||
|
'default_deposit_id': self.deposit_id.id if self.deposit_id else False,
|
||||||
|
'default_line_ids': [(6, 0, line_ids)] if line_ids else False,
|
||||||
|
'default_is_order': self.is_order,
|
||||||
|
'default_notes': self.notes,
|
||||||
|
'default_date': self.date,
|
||||||
|
'default_order_date': self.order_date,
|
||||||
|
}
|
||||||
|
return action
|
||||||
|
|
||||||
|
def action_next(self):
|
||||||
|
steps = ['type', 'partner', 'content', 'extra']
|
||||||
|
current_index = steps.index(self.step)
|
||||||
|
if current_index < len(steps) - 1:
|
||||||
|
self.step = steps[current_index + 1]
|
||||||
|
return self.conserve_wizard(line_ids = self.line_ids.ids)
|
||||||
|
|
||||||
|
def action_prev(self):
|
||||||
|
steps = ['type', 'partner', 'content', 'extra']
|
||||||
|
current_index = steps.index(self.step)
|
||||||
|
if current_index > 0:
|
||||||
|
self.step = steps[current_index - 1]
|
||||||
|
return self.conserve_wizard(line_ids = self.line_ids.ids)
|
@ -0,0 +1,86 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<!--
|
||||||
|
Copyright 2024 Le Garage Numérique contact@legaragenumerique.fr)
|
||||||
|
@author: Florian ROGER <makayabou@gmail.com>
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
|
||||||
|
-->
|
||||||
|
<odoo>
|
||||||
|
<record id="gn_cash.account_cash_deposit_popup_wizard" model="ir.ui.view">
|
||||||
|
<field name="model">account.cash.deposit.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<header>
|
||||||
|
<field name="step" widget="statusbar" options="{'clickable': True}"/>
|
||||||
|
</header>
|
||||||
|
<group>
|
||||||
|
<field name="operating_journal_id" string="Compte de destination" readonly='1' attrs="{'invisible': [('is_order', '=', True)]}"/>
|
||||||
|
<field name="operating_journal_id" string="Compte de provenance" readonly='1' attrs="{'invisible': [('is_order', '!=', True)]}"/>
|
||||||
|
<!-- Invisible fields-->
|
||||||
|
<field name="company_id" invisible='1'/>
|
||||||
|
<field name="currency_id" invisible='1'/>
|
||||||
|
<field name="operating_journal_type" invisible='1'/>
|
||||||
|
</group>
|
||||||
|
<group name="Type d'opération" id="operation_type_step" attrs="{'invisible': [('step', '!=', 'type')]}">
|
||||||
|
<field name="is_order" widget="boolean_toggle"/>
|
||||||
|
</group>
|
||||||
|
<group name="Choice of Partner" id="partner_choice_step" attrs="{'invisible': [('step', '!=', 'partner')]}">
|
||||||
|
<group name="Type of Partner" id="partner_type_choice">
|
||||||
|
<field name="has_partner" widget="boolean_toggle"/>
|
||||||
|
</group>
|
||||||
|
<group name="Account of Partner" id="partner_account_choice" attrs="{'invisible': [('has_partner', '!=', True)]}">
|
||||||
|
<field name="partner_id" domain="[('id', '!=', context.get('uid'))]"/>
|
||||||
|
</group>
|
||||||
|
<group name="Counterpart Journal" id="counterpart_journal_choice" attrs="{'invisible': [('has_partner', '=', True)]}">
|
||||||
|
<field name="counterpart_journal_id"
|
||||||
|
domain="[('type', 'in', ['bank', 'cash']), ('id','!=', context.get('default_operating_journal_id'))]"
|
||||||
|
attrs="{'invisible': [('is_order', '!=', True)]}"
|
||||||
|
string="Compte de destination"/>
|
||||||
|
<field name="counterpart_journal_id"
|
||||||
|
domain="[('type', 'in', ['bank', 'cash']), ('id','!=', context.get('default_operating_journal_id'))]"
|
||||||
|
attrs="{'invisible': [('is_order', '=', True)]}"
|
||||||
|
string="Compte d'origine"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group name="Main Content" id="content" attrs="{'invisible': [('step', '!=', 'content')]}">
|
||||||
|
<field name="coin_amount" attrs="{'invisible': [('operating_journal_type', '=', 'bank')]}"/>
|
||||||
|
<field
|
||||||
|
name="line_ids"
|
||||||
|
nolabel="1"
|
||||||
|
colspan="2"
|
||||||
|
context="{'default_currency_id': currency_id}"
|
||||||
|
>
|
||||||
|
<tree editable="bottom">
|
||||||
|
<field name="cash_unit_id" />
|
||||||
|
<field name="qty" />
|
||||||
|
<field name="subtotal" sum="1" />
|
||||||
|
<field name="currency_id" invisible="1" />
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
<field name="total_amount"/>
|
||||||
|
</group>
|
||||||
|
<group name="Extra Informations" id="extra" attrs="{'invisible': [('step', '!=', 'extra')]}">
|
||||||
|
<field name="order_date" attrs="{'invisible': [('is_order', '!=', True)]}"/>
|
||||||
|
<field name="date" attrs="{'invisible': [('is_order', '=', True)]}"/>
|
||||||
|
<field name="notes"/>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button string="Save" class="btn btn-primary" type="object" name="action_confirm" data-hotkey="q" />
|
||||||
|
<button string="Cancel" class="btn-secondary" special="cancel" data-hotkey="z" />
|
||||||
|
<button string="Previous" class="btn btn-primary " type="object"
|
||||||
|
name="action_prev" attrs="{'invisible': [('step', '=', 'type')]}"
|
||||||
|
/>
|
||||||
|
<button string="Next" class="btn btn-primary" type="object"
|
||||||
|
name="action_next" attrs="{'invisible': [('step', '=', 'extra')]}"
|
||||||
|
/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<record id="gn_cash.account_cash_inorout_action_wizard" model="ir.actions.act_window">
|
||||||
|
<field name="name">Cash Deposit</field>
|
||||||
|
<field name="res_model">account.cash.deposit.wizard</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="gn_cash.account_cash_deposit_popup_wizard"/>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
@ -1,2 +0,0 @@
|
|||||||
__pycache__
|
|
||||||
models/__pycache__
|
|
@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
'name': "Gn Discount",
|
|
||||||
'version': '14.0.0.1.3',
|
|
||||||
'author': 'Garage Numérique',
|
|
||||||
'category': 'Sales',
|
|
||||||
'description': """
|
|
||||||
This module adds the ability to display the total before discount and the discount amount on sales orders and invoices.
|
|
||||||
|
|
||||||
This version only works when no taxes are applied
|
|
||||||
""",
|
|
||||||
'depends': ['sale', 'sale_discount_total'],
|
|
||||||
'data': [
|
|
||||||
'views/sale_view.xml',
|
|
||||||
'views/sale_report.xml',
|
|
||||||
'views/sale_portal.xml',
|
|
||||||
'views/invoice_view.xml',
|
|
||||||
'views/invoice_report.xml'
|
|
||||||
],
|
|
||||||
'translate': True,
|
|
||||||
'translations': [
|
|
||||||
('fr_FR', 'i18n/gn_discount.fr_FR.po'),
|
|
||||||
],
|
|
||||||
'installable': True,
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
msgid "Subtotal"
|
|
||||||
msgstr "Sous-total"
|
|
||||||
|
|
||||||
msgid "Discount"
|
|
||||||
msgtr "Remise"
|
|
||||||
|
|
||||||
msgid "Subtotal with discount"
|
|
||||||
msgtr "Sous-total après remise"
|
|
||||||
|
|
||||||
msgid "Total without discount"
|
|
||||||
msgtr "Total avant remise"
|
|
||||||
|
|
||||||
msgid "Total discounted"
|
|
||||||
msgtr "Total après remise"
|
|
@ -1,3 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import sale, invoice
|
|
@ -1,19 +0,0 @@
|
|||||||
from odoo import api, fields, models
|
|
||||||
|
|
||||||
class AccountMove(models.Model):
|
|
||||||
_inherit = 'account.move'
|
|
||||||
amount_undiscounted = fields.Monetary(compute='_compute_amount_undiscounted', store=True)
|
|
||||||
|
|
||||||
@api.depends('amount_untaxed', 'amount_discount')
|
|
||||||
def _compute_amount_undiscounted(self):
|
|
||||||
for record in self:
|
|
||||||
record.amount_undiscounted = record.amount_untaxed + record.amount_discount
|
|
||||||
|
|
||||||
class AccountMoveLine(models.Model):
|
|
||||||
_inherit = 'account.move.line'
|
|
||||||
price_subtotal_before_discount = fields.Monetary(compute='_compute_amount_undiscounted', store=True, string="Subtotal", translate="True")
|
|
||||||
|
|
||||||
@api.depends('price_unit', 'quantity')
|
|
||||||
def _compute_amount_undiscounted(self):
|
|
||||||
for record in self:
|
|
||||||
record.price_subtotal_before_discount = record.price_unit * record.quantity
|
|
@ -1,11 +0,0 @@
|
|||||||
from odoo import api, fields, models
|
|
||||||
|
|
||||||
class SaleOrderLine(models.Model):
|
|
||||||
_inherit = 'sale.order.line'
|
|
||||||
|
|
||||||
price_subtotal_before_discount = fields.Monetary(readonly=True, string="Subtotal", translate=True, compute='_compute_price_subtotal_before_discount')
|
|
||||||
|
|
||||||
@api.depends('price_unit', 'discount', 'product_uom_qty')
|
|
||||||
def _compute_price_subtotal_before_discount(self):
|
|
||||||
for line in self:
|
|
||||||
line.price_subtotal_before_discount = line.price_unit * line.product_uom_qty
|
|
@ -1,64 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<template id="gn_discount_report_invoice" inherit_id="account.report_invoice_document">
|
|
||||||
<!--<xpath expr="//span[@t-field='o.amount_untaxed']" position="replace">
|
|
||||||
<span t-field="o.amount_undiscounted"/>
|
|
||||||
|
|
||||||
</xpath>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<xpath expr="//tr[td[strong[text()='Subtotal']]]" position="replace">-->
|
|
||||||
<xpath expr="//t[@t-set='display_discount']" position="replace">
|
|
||||||
<t t-set="display_discount" t-value="false"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//tr[@class='border-black o_subtotal']" position="replace">
|
|
||||||
<t t-if="o.amount_discount > 0">
|
|
||||||
<tr class="border-black">
|
|
||||||
<td><strong>Subtotal</strong></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<span
|
|
||||||
t-if="o.amount_discount >= 0"
|
|
||||||
t-att-style="'text-decoration: line-through' or None"
|
|
||||||
t-att-class="'text-danger' or ''"
|
|
||||||
data-id="total_before_discount"
|
|
||||||
t-field="o.amount_undiscounted"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Discount**</td>
|
|
||||||
<td class="text-right">
|
|
||||||
<div>
|
|
||||||
<span>-</span>
|
|
||||||
<span t-if="o.amount_discount" t-field="o.amount_discount"/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><strong>Subtotal with discount</strong></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<div>
|
|
||||||
<div t-if="o.amount_discount" t-field="o.amount_untaxed">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</t>
|
|
||||||
<t-else>
|
|
||||||
<tr class="border-black">
|
|
||||||
<td><strong>Subtotal</strong></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<span t-field="o.amount_untaxed"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</t-else>
|
|
||||||
</xpath>
|
|
||||||
|
|
||||||
<xpath expr="//td[.//span[@t-field='line.price_subtotal']]" position="replace">
|
|
||||||
<td class="text-right o_price_total">
|
|
||||||
<span t-field="line.price_subtotal_before_discount"/>
|
|
||||||
</td>
|
|
||||||
</xpath>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</odoo>
|
|
@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<data>
|
|
||||||
<record id="gn_discount_invoice_view_form" model="ir.ui.view">
|
|
||||||
<field name="name">gn_discount.account.move.form</field>
|
|
||||||
<field name="model">account.move</field>
|
|
||||||
<field name="inherit_id" ref="account.view_move_form"/>
|
|
||||||
<field name="priority" eval="20"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="//field[@name='amount_untaxed']" position="replace">
|
|
||||||
<field name="amount_undiscounted" widget="monetary"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//field[@name='amount_by_group']" position="before">
|
|
||||||
<field name="amount_untaxed"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//field[@name='price_subtotal']" position="replace">
|
|
||||||
<field name="price_subtotal_before_discount" readonly="1"/>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
</data>
|
|
||||||
</odoo>
|
|
@ -1,76 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<template id="gn_discount.portal_order_view_template" inherit_id="sale.sale_order_portal_content">
|
|
||||||
<xpath expr="//td[.//span[@class='oe_order_line_price_subtotal']]" position="replace">
|
|
||||||
<td class="text-right">
|
|
||||||
<span class="oe_order_line_price_subtotal" t-field="line.price_subtotal_before_discount"/>
|
|
||||||
</td>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//td[div[@t-field='line.price_unit']]" position="replace">
|
|
||||||
<td t-attf-class="text-right {{ 'd-none d-sm-table-cell' if report_type == 'html' else '' }}">
|
|
||||||
<div t-field="line.price_unit" t-attf-class="text-right"/>
|
|
||||||
</td>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//t[@t-set='display_discount']" position="replace">
|
|
||||||
<t t-set="display_discount" t-value="false"/>
|
|
||||||
</xpath>
|
|
||||||
<!--<xpath expr="//strong[@class='text-info']" position="replace">
|
|
||||||
<strong t-if="line.discount > 0" class="text-info">
|
|
||||||
<t t-esc="'{:.2f}'.format(line.discount)"/>%
|
|
||||||
</strong>
|
|
||||||
</xpath>-->
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template id="gn_discount.portal_order_view_totals" inherit_id="sale.sale_order_portal_content_totals_table">
|
|
||||||
<xpath expr="//tr[@class='border-black'][1]" position="replace">
|
|
||||||
<t t-if="sale_order.amount_discount > 0">
|
|
||||||
<tr class="border-black">
|
|
||||||
<td><strong>Subtotal</strong></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<div>
|
|
||||||
<span
|
|
||||||
t-att-style="'text-decoration: line-through' or None"
|
|
||||||
t-att-class="'text-danger' or ''"
|
|
||||||
data-id="total_before_discount"
|
|
||||||
t-field="sale_order.amount_undiscounted"
|
|
||||||
t-options='{"widget": "monetary","display_currency": sale_order.pricelist_id.currency_id}'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Discount</td>
|
|
||||||
<td class="text-right">
|
|
||||||
<div>
|
|
||||||
<div t-if="sale_order.amount_discount">
|
|
||||||
<span>-</span><t t-esc="sale_order.amount_discount" t-options='{"widget": "monetary","display_currency": sale_order.pricelist_id.currency_id}'/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><strong>Subtotal with discount</strong></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<div>
|
|
||||||
<div t-if="sale_order.amount_discount">
|
|
||||||
<t t-esc="sale_order.amount_untaxed" t-options='{"widget": "monetary","display_currency": sale_order.pricelist_id.currency_id}'/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</t>
|
|
||||||
<t-else>
|
|
||||||
<tr class="border-black">
|
|
||||||
<td><strong>Subtotal</strong></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<div>
|
|
||||||
<span t-field="sale_order.amount_untaxed"/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</t-else>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
|
@ -1,55 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<template id="gn_discount_report_saleorder_document" inherit_id="sale.report_saleorder_document">
|
|
||||||
<xpath expr="//tr[@class='border-black o_subtotal']" position="replace">
|
|
||||||
<t t-if="doc.amount_discount > 0">
|
|
||||||
<tr class="border-black">
|
|
||||||
<td><strong>Subtotal</strong></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<span
|
|
||||||
t-att-style="'text-decoration: line-through' or None"
|
|
||||||
t-att-class="'text-danger' or ''"
|
|
||||||
data-id="total_before_discount"
|
|
||||||
t-field="doc.amount_undiscounted"
|
|
||||||
t-options='{"widget": "monetary","display_currency": doc.currency_id}'
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Discount**</td>
|
|
||||||
<td class="text-right">
|
|
||||||
<div>
|
|
||||||
<span>-</span>
|
|
||||||
<span t-if="doc.amount_discount" t-field="doc.amount_discount"/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><strong>Subtotal with discount</strong></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<div>
|
|
||||||
<div t-if="doc.amount_discount" t-field="doc.amount_untaxed">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</t>
|
|
||||||
<t-else>
|
|
||||||
<tr class="border-black">
|
|
||||||
<td><strong>Subtotal</strong></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<span t-field="doc.amount_untaxed"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</t-else>
|
|
||||||
</xpath>
|
|
||||||
|
|
||||||
<xpath expr="//td[@name='td_subtotal']" position="replace">
|
|
||||||
<td name="td_subtotal_before_discount" class="text-right">
|
|
||||||
<span t-field="line.price_subtotal_before_discount" t-options="{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}"/>
|
|
||||||
</td>
|
|
||||||
</xpath>
|
|
||||||
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</odoo>
|
|
@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<data>
|
|
||||||
<record id="gn_discount_sale_view_form" model="ir.ui.view">
|
|
||||||
<field name="name">gn_discount.sale.order.form</field>
|
|
||||||
<field name="model">sale.order</field>
|
|
||||||
<field name="inherit_id" ref="sale.view_order_form"/>
|
|
||||||
<field name="priority">99</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="//field[@name='amount_untaxed']" position="replace">
|
|
||||||
<field name="amount_undiscounted" widget="monetary" readonly="1"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//field[@name='amount_tax']" position="before">
|
|
||||||
<field name="amount_untaxed" readonly="1"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//field[@name='order_line']/tree/field[@name='price_subtotal']" position="replace">
|
|
||||||
<field name="price_subtotal_before_discount" readonly="1"/>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
</data>
|
|
||||||
</odoo>
|
|
@ -1,2 +0,0 @@
|
|||||||
__pycache__
|
|
||||||
models/__pycache__
|
|
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
'name': "Gn Donations",
|
|
||||||
'version': '14.0.0.1.1',
|
|
||||||
'author': 'Garage Numérique',
|
|
||||||
'category': 'Accounting',
|
|
||||||
'description': """
|
|
||||||
This module modify the fiscal receipt report so it is similar to Cerfa 11580.
|
|
||||||
It allows to edit fiscal receipts for in-kind donation (i.e. 0€ donation).
|
|
||||||
""",
|
|
||||||
'depends': ['donation'],
|
|
||||||
'data': [
|
|
||||||
'views/donation_thanks_report.xml',
|
|
||||||
'views/internal_layout.xml'
|
|
||||||
],
|
|
||||||
'translate': True,
|
|
||||||
'installable': True,
|
|
||||||
}
|
|
@ -1,127 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
from odoo import fields, models
|
|
||||||
import num2words
|
|
||||||
|
|
||||||
class TaxReceipt(models.Model):
|
|
||||||
_inherit = 'donation.tax.receipt'
|
|
||||||
amount_in_words = fields.Char(compute='_compute_amount_in_words', string='Amount in Words')
|
|
||||||
|
|
||||||
def _compute_amount_in_words(self):
|
|
||||||
for record in self:
|
|
||||||
record.amount_in_words = num2words.num2words(record.amount, lang='fr')
|
|
||||||
|
|
||||||
|
|
||||||
from odoo import _, api
|
|
||||||
from odoo.exceptions import UserError
|
|
||||||
from odoo.tools.misc import format_amount
|
|
||||||
|
|
||||||
from odoo.addons.account import _auto_install_l10n
|
|
||||||
# Rewriting donation to allow 0€ fiscal receipts
|
|
||||||
class DonationDonation(models.Model):
|
|
||||||
_inherit = 'donation.donation'
|
|
||||||
|
|
||||||
def validate(self):
|
|
||||||
check_total = self.env["res.users"].has_group(
|
|
||||||
"donation.group_donation_check_total"
|
|
||||||
)
|
|
||||||
for donation in self:
|
|
||||||
if donation.donation_date > fields.Date.context_today(self):
|
|
||||||
raise UserError(
|
|
||||||
_(
|
|
||||||
"The date of donation %s should be today "
|
|
||||||
"or in the past, not in the future!"
|
|
||||||
)
|
|
||||||
% donation.number
|
|
||||||
)
|
|
||||||
if not donation.line_ids:
|
|
||||||
raise UserError(
|
|
||||||
_(
|
|
||||||
"Cannot validate donation %s because it doesn't "
|
|
||||||
"have any lines!"
|
|
||||||
)
|
|
||||||
% donation.number
|
|
||||||
)
|
|
||||||
|
|
||||||
'''
|
|
||||||
# The part we don't want, in order ta validate 0€ fiscal receipts
|
|
||||||
if donation.currency_id.is_zero(donation.amount_total):
|
|
||||||
raise UserError(
|
|
||||||
_("Cannot validate donation %s because the " "total amount is 0!")
|
|
||||||
% donation.number
|
|
||||||
)
|
|
||||||
'''
|
|
||||||
|
|
||||||
if donation.state != "draft":
|
|
||||||
raise UserError(
|
|
||||||
_(
|
|
||||||
"Cannot validate donation %s because it is not "
|
|
||||||
"in draft state."
|
|
||||||
)
|
|
||||||
% donation.number
|
|
||||||
)
|
|
||||||
|
|
||||||
if check_total and donation.currency_id.compare_amounts(
|
|
||||||
donation.check_total, donation.amount_total
|
|
||||||
):
|
|
||||||
raise UserError(
|
|
||||||
_(
|
|
||||||
"The amount of donation %s (%s) is different "
|
|
||||||
"from the sum of the donation lines (%s)."
|
|
||||||
)
|
|
||||||
% (
|
|
||||||
donation.number,
|
|
||||||
format_amount(
|
|
||||||
self.env, donation.check_total, donation.currency_id
|
|
||||||
),
|
|
||||||
format_amount(
|
|
||||||
self.env, donation.amount_total, donation.currency_id
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
full_in_kind = all([line.in_kind for line in donation.line_ids])
|
|
||||||
if not donation.payment_mode_id and not full_in_kind:
|
|
||||||
raise UserError(
|
|
||||||
_(
|
|
||||||
"Payment Mode is not set on donation %s (only fully "
|
|
||||||
"in-kind donations don't require a payment mode)."
|
|
||||||
)
|
|
||||||
% donation.number
|
|
||||||
)
|
|
||||||
|
|
||||||
vals = {"state": "done"}
|
|
||||||
if full_in_kind and donation.payment_mode_id:
|
|
||||||
vals["payment_mode_id"] = False
|
|
||||||
|
|
||||||
if not full_in_kind:
|
|
||||||
move_vals = donation._prepare_donation_move()
|
|
||||||
# when we have a full in-kind donation: no account move
|
|
||||||
if move_vals:
|
|
||||||
move = self.env["account.move"].create(move_vals)
|
|
||||||
move.action_post()
|
|
||||||
vals["move_id"] = move.id
|
|
||||||
else:
|
|
||||||
donation.message_post(
|
|
||||||
body=_("Full in-kind donation: no account move generated")
|
|
||||||
)
|
|
||||||
|
|
||||||
receipt = donation.generate_each_tax_receipt()
|
|
||||||
if receipt:
|
|
||||||
vals["tax_receipt_id"] = receipt.id
|
|
||||||
|
|
||||||
donation.write(vals)
|
|
||||||
if donation.bank_statement_line_id:
|
|
||||||
donation._reconcile_donation_from_bank_statement()
|
|
||||||
donation.partner_id._update_donor_rank()
|
|
||||||
return
|
|
||||||
|
|
||||||
def generate_each_tax_receipt(self):
|
|
||||||
self.ensure_one()
|
|
||||||
receipt = False
|
|
||||||
if (
|
|
||||||
self.tax_receipt_option == "each"
|
|
||||||
and not self.tax_receipt_id
|
|
||||||
#and not self.company_currency_id.is_zero(self.tax_receipt_total)
|
|
||||||
):
|
|
||||||
receipt_vals = self._prepare_each_tax_receipt()
|
|
||||||
receipt = self.env["donation.tax.receipt"].create(receipt_vals)
|
|
||||||
return receipt
|
|
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<odoo>
|
|
||||||
<template id="gn_donations.internal_layout">
|
|
||||||
<div class="header">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="article" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')">
|
|
||||||
<t t-raw="0"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</odoo>
|
|
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
'name': "Gn FEC",
|
||||||
|
'version': '16.0.0.0.1',
|
||||||
|
'author': 'Garage Numérique',
|
||||||
|
'category': 'Accounting',
|
||||||
|
'description': """
|
||||||
|
This module allows to put year's result in corresponding account.
|
||||||
|
""",
|
||||||
|
'depends': ['l10n_fr_fec', 'l10n_fr_fec_oca'],
|
||||||
|
'data': [
|
||||||
|
],
|
||||||
|
'translate': True,
|
||||||
|
'installable': True,
|
||||||
|
}
|
@ -1,3 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from . import donation
|
from . import
|
@ -1,9 +0,0 @@
|
|||||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
|
||||||
|
|
||||||
|
|
||||||
from odoo import api, SUPERUSER_ID
|
|
||||||
from odoo.addons.account.models.chart_template import preserve_existing_tags_on_taxes
|
|
||||||
|
|
||||||
|
|
||||||
def _l10n_fr_post_init_hook(cr, registry):
|
|
||||||
preserve_existing_tags_on_taxes(cr, registry, "gn_l10n_fr_pcg_asso")
|
|
@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "France - ONG Chart of Account",
|
|
||||||
"version": "16.0.0.0.3",
|
|
||||||
"category": "Accounting/Localizations/Account Charts",
|
|
||||||
"summary": "Fork of l10n_fr_oca for ONG",
|
|
||||||
"author": "Le Garage Numérique",
|
|
||||||
"maintainers": ["alexis-via"],
|
|
||||||
"website": "https://odoo.legaragenumerique.fr",
|
|
||||||
"depends": [
|
|
||||||
"account_tax_unece",
|
|
||||||
"l10n_fr_oca"
|
|
||||||
],
|
|
||||||
"data": [
|
|
||||||
"data/l10n_fr_chart_data.xml",
|
|
||||||
"data/account.account.template.csv",
|
|
||||||
"data/account.group.template.csv",
|
|
||||||
"data/account_chart_template_data.xml",
|
|
||||||
"data/account_data.xml",
|
|
||||||
"data/account_tax_data.xml",
|
|
||||||
"data/account_account_template_default_tax.xml",
|
|
||||||
"data/account_fiscal_position_template_data.xml",
|
|
||||||
"data/account_reconcile_model_template.xml",
|
|
||||||
"data/account_chart_template_configure_data.xml",
|
|
||||||
],
|
|
||||||
"post_init_hook": "_l10n_fr_post_init_hook",
|
|
||||||
"license": "LGPL-3",
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
|||||||
"id","code_prefix_start","name","chart_template_id/id"
|
|
||||||
"pcg_group_1","1","Capitaux","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_10","10","Capital et réserves","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_11","11","Report à nouveau","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_12","12","Résultat de l'exercice","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_13","13","Subventions d'investissement","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_14","14","Provisions réglementées","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_15","15","Provisions","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_16","16","Emprunts et dettes","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_17","17","Dettes rattachées à des participations","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_18","18","Comptes de liaison des établissements et sociétés en participation","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_2","2","Immobilisations","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_20","20","Immobilisations incorporelles","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_21","21","Immobilisations corporelles","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_22","22","Immobilisations mises en concession","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_23","23","Immobilisations en cours","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_25","25","Parts dans des entreprises liées et créances sur des entreprises liées","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_26","26","Participations et créances rattachées à des participations","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_27","27","Autres immobilisations financières","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_28","28","Amortissements des immobilisations","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_29","29","Dépréciations des immobilisations","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_3","3","Stocks et en-cours","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_31","31","Matières premières et fournitures","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_32","32","Autres approvisionnements","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_33","33","En-cours de production de biens","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_34","34","En-cours de production de services","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_35","35","Stocks de produits","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_36","36","Stocks provenant d'immobilisations","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_37","37","Stocks de marchandises","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_38","38","Stocks en voie d'acheminement, mis en dépôt ou donnés en consignation","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_39","39","Dépréciations des stocks et en-cours","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_4","4","Tiers","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_40","40","Fournisseurs et comptes rattachés","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_41","41","Clients et comptes rattachés","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_42","42","Personnel et comptes rattachés","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_43","43","Sécurité sociale et autres organismes sociaux","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_44","44","État et autres collectivités publiques","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_45","45","Groupe et associés","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_46","46","Débiteurs divers et créditeurs divers","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_47","47","Comptes transitoires ou d'attente","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_48","48","Comptes de régularisation","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_49","49","Dépréciations des comptes de tiers","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_5","5","Comptes financiers","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_50","50","Valeurs mobilières de placement","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_51","51","Banques, établissements financiers et assimilés","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_52","52","Instruments de trésorerie","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_53","53","Caisse","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_54","54","Régies d'avances et accréditifs","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_58","58","Virements internes","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_59","59","Dépréciations des comptes financiers","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_6","6","Charges","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_60","60","Achats et variation de stock","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_61","61","Services extérieurs","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_62","62","Autres services extérieurs","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_63","63","Impôts, taxes et versements assimilés","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_64","64","Charges de personnel","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_65","65","Autres charges de gestion courante","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_66","66","Charges financières","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_67","67","Charges exceptionnelles","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_68","68","Dotations aux amortissements et provisions","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_69","69","Participation des salariés, impôts sur les bénéfices et assimilés","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_7","7","Produits","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_70","70","Ventes de produits et services","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_71","71","Production stockée","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_72","72","Production immobilisée","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_74","74","Subventions d'exploitation","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_75","75","Autres produits de gestion courante","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_76","76","Produits financiers","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_77","77","Produits exceptionnels","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_78","78","Reprises sur amortissements et provisions","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_79","79","Transferts de charges","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
||||||
"pcg_group_9","9","Comptes spéciaux","gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template"
|
|
|
@ -1,195 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
|
|
||||||
<!-- Default taxes on accounts -->
|
|
||||||
<!-- We can't put this in account.account.template.csv because we need to load
|
|
||||||
taxes before, and taxes need to be loaded after account.account.template.csv -->
|
|
||||||
|
|
||||||
<!-- Expenses -->
|
|
||||||
<record id="pcg_601" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6021" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6022" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6023" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6028" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_604" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_605" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6061" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6063" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6064" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6068" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6071" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_608" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_609" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_611" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6122" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6125" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6135" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6152" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6155" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6156" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6225" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6226" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6227" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6228" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6231" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6232" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6233" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6234" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6235" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6236" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6237" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6238" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6241" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6242" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6243" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6244" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_6247" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_purchase_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- Income -->
|
|
||||||
<record id="pcg_7011" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_sale_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_702" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_sale_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_703" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_sale_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_704" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_sale_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_705" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_sale_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_7061" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_sale_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_7071" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_sale_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="pcg_70851" model="account.account.template">
|
|
||||||
<field name="tax_ids" eval="[(6,0,[ref('tva_sale_200')])]" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
|
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo noupdate="1">
|
|
||||||
<function model="account.chart.template" name="try_loading">
|
|
||||||
<value eval="[ref('gn_l10n_fr_pcg_asso.l10n_fr_pcg_chart_template')]" />
|
|
||||||
</function>
|
|
||||||
</odoo>
|
|
@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<!-- oca-hooks:disable=xml-duplicate-record-id -->
|
|
||||||
<odoo>
|
|
||||||
<record id="l10n_fr_pcg_chart_template" model="account.chart.template">
|
|
||||||
<field name="property_account_receivable_id" ref="fr_pcg_recv" />
|
|
||||||
<field name="property_account_payable_id" ref="fr_pcg_pay" />
|
|
||||||
<field name="property_account_expense_categ_id" ref="pcg_6071" />
|
|
||||||
<field name="property_account_income_categ_id" ref="pcg_7071" />
|
|
||||||
<field name="income_currency_exchange_account_id" ref="pcg_766" />
|
|
||||||
<field name="expense_currency_exchange_account_id" ref="pcg_666" />
|
|
||||||
<field name="property_tax_payable_account_id" ref="pcg_44551" />
|
|
||||||
<field name="property_tax_receivable_account_id" ref="pcg_44567" />
|
|
||||||
<field name="default_pos_receivable_account_id" ref="fr_pcg_recv_pos" />
|
|
||||||
<field name="account_journal_early_pay_discount_loss_account_id" ref="pcg_665" />
|
|
||||||
<field name="account_journal_early_pay_discount_gain_account_id" ref="pcg_765" />
|
|
||||||
<field name="currency_id" ref="base.EUR" />
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,29 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo noupdate="1">
|
|
||||||
|
|
||||||
<!-- Account Tax Group -->
|
|
||||||
<record id="tax_group_tva_0" model="account.tax.group">
|
|
||||||
<field name="name">TVA 0%</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="tax_group_tva_20" model="account.tax.group">
|
|
||||||
<field name="name">TVA 20%</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="tax_group_tva_85" model="account.tax.group">
|
|
||||||
<field name="name">TVA 8,5%</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="tax_group_tva_55" model="account.tax.group">
|
|
||||||
<field name="name">TVA 5,5%</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="tax_group_tva_10" model="account.tax.group">
|
|
||||||
<field name="name">TVA 10%</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="tax_group_tva_21" model="account.tax.group">
|
|
||||||
<field name="name">TVA 2,1%</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</odoo>
|
|
@ -1,695 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<!-- Fiscal Position Templates -->
|
|
||||||
|
|
||||||
<record
|
|
||||||
id="fiscal_position_template_ong"
|
|
||||||
model="account.fiscal.position.template"
|
|
||||||
>
|
|
||||||
<field name="sequence">20</field>
|
|
||||||
<field name="name">Associations et Micro-entrepreneurs</field>
|
|
||||||
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template" />
|
|
||||||
<field
|
|
||||||
name="note"
|
|
||||||
>French VAT exemption according to articles 293 of "CGI"</field>
|
|
||||||
<field name="auto_apply" eval="True" />
|
|
||||||
<field name="country_group_id" ref="base.europe" />
|
|
||||||
<field name="vat_required" eval="True" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record
|
|
||||||
id="fiscal_position_template_domestic"
|
|
||||||
model="account.fiscal.position.template"
|
|
||||||
>
|
|
||||||
<field name="sequence">10</field>
|
|
||||||
<field name="name">France</field>
|
|
||||||
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template" />
|
|
||||||
<field name="auto_apply" eval="True" />
|
|
||||||
<field name="vat_required" eval="False" />
|
|
||||||
<field name="country_id" ref="base.fr" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record
|
|
||||||
id="fiscal_position_template_domestic_supplier_vat_on_payment"
|
|
||||||
model="account.fiscal.position.template"
|
|
||||||
>
|
|
||||||
<field name="sequence">20</field>
|
|
||||||
<field name="name">France - Fournisseur TVA sur encaissement</field>
|
|
||||||
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template" />
|
|
||||||
<field name="auto_apply" eval="False" />
|
|
||||||
<field name="vat_required" eval="False" />
|
|
||||||
<field name="country_id" ref="base.fr" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record
|
|
||||||
id="fiscal_position_template_intraeub2b"
|
|
||||||
model="account.fiscal.position.template"
|
|
||||||
>
|
|
||||||
<field name="sequence">30</field>
|
|
||||||
<field name="name">Intra-EU B2B</field>
|
|
||||||
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template" />
|
|
||||||
<field
|
|
||||||
name="note"
|
|
||||||
>French VAT exemption according to articles 262 ter I (for products) and/or 283-2 (for services) of "CGI"</field>
|
|
||||||
<field name="auto_apply" eval="True" />
|
|
||||||
<field name="country_group_id" ref="base.europe" />
|
|
||||||
<field name="vat_required" eval="True" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record
|
|
||||||
id="fiscal_position_template_intraeub2c"
|
|
||||||
model="account.fiscal.position.template"
|
|
||||||
>
|
|
||||||
<field name="sequence">40</field>
|
|
||||||
<field name="name">Intra-EU B2C</field>
|
|
||||||
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template" />
|
|
||||||
<field name="auto_apply" eval="True" />
|
|
||||||
<field name="country_group_id" ref="base.europe" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record
|
|
||||||
id="fiscal_position_template_import_export"
|
|
||||||
model="account.fiscal.position.template"
|
|
||||||
>
|
|
||||||
<field name="sequence">50</field>
|
|
||||||
<field name="name">Import/Export Hors UE + DOM-TOM</field>
|
|
||||||
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template" />
|
|
||||||
<field
|
|
||||||
name="note"
|
|
||||||
>French VAT exemption according to articles 291, 294 and 262 I of "CGI"</field>
|
|
||||||
<field name="auto_apply" eval="True" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- Intra EU B2B tax -->
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_200"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_200" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_100"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_100" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_85"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_85" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_55"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_55" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_21"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_21" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_200_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_200_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_100_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_100_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_85_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_85_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_55_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_55_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_sale_21_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_21_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_200"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_200" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_200_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_100"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_100" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_100_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_55"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_55" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_55_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_21"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_21" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_21_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_200_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_200_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_200_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_100_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_100_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_100_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_55_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_55_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_55_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_21_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_21_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_21_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_200_immo"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_200_immo" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_200_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_100_immo"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_100_immo" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_100_intracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_intraeub2b_tva_purchase_55_immo"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_55_immo" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_55_intracom" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- Intra EU B2B accounts -->
|
|
||||||
<record
|
|
||||||
id="fp_account_template_intraeub2b_pcg_7011"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="account_src_id" ref="pcg_7011" />
|
|
||||||
<field name="account_dest_id" ref="pcg_7012" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_account_template_intraeub2b_pcg_7061"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="account_src_id" ref="pcg_7061" />
|
|
||||||
<field name="account_dest_id" ref="pcg_7062" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_account_template_intraeub2b_pcg_7071"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="account_src_id" ref="pcg_7071" />
|
|
||||||
<field name="account_dest_id" ref="pcg_7072" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_account_template_intraeub2b_pcg_70851"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
|
|
||||||
<field name="account_src_id" ref="pcg_70851" />
|
|
||||||
<field name="account_dest_id" ref="pcg_70852" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- Intra EU B2C accounts -->
|
|
||||||
<record
|
|
||||||
id="fp_account_template_intraeub2c_pcg_7011"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2c" />
|
|
||||||
<field name="account_src_id" ref="pcg_7011" />
|
|
||||||
<field name="account_dest_id" ref="pcg_7013" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_account_template_intraeub2c_pcg_7061"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2c" />
|
|
||||||
<field name="account_src_id" ref="pcg_7061" />
|
|
||||||
<field name="account_dest_id" ref="pcg_7063" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_account_template_intraeub2c_pcg_7071"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2c" />
|
|
||||||
<field name="account_src_id" ref="pcg_7071" />
|
|
||||||
<field name="account_dest_id" ref="pcg_7073" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_account_template_intraeub2c_pcg_70851"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_intraeub2c" />
|
|
||||||
<field name="account_src_id" ref="pcg_70851" />
|
|
||||||
<field name="account_dest_id" ref="pcg_70853" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Import-Export tax -->
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_200"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_200" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_100"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_100" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_85"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_85" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_55"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_55" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_21"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_21" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_200_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_200_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_100_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_100_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_85_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_85_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_55_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_55_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_sale_21_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_21_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_200"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_200" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_200_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_100"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_100" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_100_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_55"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_55" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_55_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_21"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_21" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_21_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_200_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_200_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_200_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_100_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_100_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_100_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_55_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_55_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_55_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_21_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_21_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_21_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_200_immo"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_200_immo" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_200_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_100_immo"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_100_immo" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_100_extracom" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_extracom_tva_purchase_55_immo"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_55_immo" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_55_extracom" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- Import-Export accounts -->
|
|
||||||
<record
|
|
||||||
id="fp_account_template_extracom_pcg_7011"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="account_src_id" ref="pcg_7011" />
|
|
||||||
<field name="account_dest_id" ref="pcg_7014" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_account_template_extracom_pcg_7061"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="account_src_id" ref="pcg_7061" />
|
|
||||||
<field name="account_dest_id" ref="pcg_7064" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_account_template_extracom_pcg_7071"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="account_src_id" ref="pcg_7071" />
|
|
||||||
<field name="account_dest_id" ref="pcg_7074" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_account_template_extracom_pcg_70851"
|
|
||||||
model="account.fiscal.position.account.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_import_export" />
|
|
||||||
<field name="account_src_id" ref="pcg_70851" />
|
|
||||||
<field name="account_dest_id" ref="pcg_70854" />
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- Assos tax -->
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_200"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_200" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_100"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_100" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_85"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_85" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_55"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_55" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_21"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_21" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_200_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_200_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_100_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_100_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_85_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_85_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_55_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_55_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_sale_21_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_sale_21_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_sale_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_200"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_200" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_100"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_100" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_55"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_55" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_21"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_21" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_200_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_200_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_100_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_100_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_55_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_55_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_21_ttc"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_21_ttc" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_200_immo"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_200_immo" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_100_immo"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_100_immo" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="fp_tax_template_ong_tva_purchase_55_immo"
|
|
||||||
model="account.fiscal.position.tax.template"
|
|
||||||
>
|
|
||||||
<field name="position_id" ref="fiscal_position_template_ong" />
|
|
||||||
<field name="tax_src_id" ref="tva_purchase_55_immo" />
|
|
||||||
<field name="tax_dest_id" ref="tva_purchase_0_exo" />
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!--
|
|
||||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
|
||||||
-->
|
|
||||||
<odoo>
|
|
||||||
<record id="bank_charges_reconcile_model" model="account.reconcile.model.template">
|
|
||||||
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template" />
|
|
||||||
<field name="name">Frais bancaires</field>
|
|
||||||
</record>
|
|
||||||
<record
|
|
||||||
id="bank_charges_reconcile_model_line"
|
|
||||||
model="account.reconcile.model.line.template"
|
|
||||||
>
|
|
||||||
<field name="model_id" ref="bank_charges_reconcile_model" />
|
|
||||||
<field name="account_id" ref="pcg_6278" />
|
|
||||||
<field name="amount_type">percentage</field>
|
|
||||||
<field name="amount_string">100</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<!-- oca-hooks:disable=xml-duplicate-record-id -->
|
|
||||||
<odoo>
|
|
||||||
<!-- Chart template -->
|
|
||||||
<record id="l10n_fr_pcg_chart_template" model="account.chart.template">
|
|
||||||
<field name="name">Plan Comptable Général for ONGs</field>
|
|
||||||
<field name="currency_id" ref="base.EUR" />
|
|
||||||
<field name="code_digits" eval="6" />
|
|
||||||
<field name="bank_account_code_prefix">512</field>
|
|
||||||
<field name="cash_account_code_prefix">53</field>
|
|
||||||
<field name="transfer_account_code_prefix">58</field>
|
|
||||||
<field name="country_id" ref="base.fr" />
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,4 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
||||||
|
|
||||||
from . import models
|
|
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "France - Paye",
|
|
||||||
"version": "16.0.0.0.2",
|
|
||||||
"category": "Payroll",
|
|
||||||
"summary": "Configuration de la paie",
|
|
||||||
"author": "Le Garage Numérique",
|
|
||||||
"maintainers": ["makayabou"],
|
|
||||||
"website": "https://odoo.legaragenumerique.fr",
|
|
||||||
"depends": [
|
|
||||||
"payroll",
|
|
||||||
"hr_contract"
|
|
||||||
],
|
|
||||||
"data": [
|
|
||||||
"data/gn_payroll_cc.xml",
|
|
||||||
"data/gn_payroll_contract.xml",
|
|
||||||
"data/gn_payroll_salary.xml",
|
|
||||||
"data/gn_payroll_sickness.xml",
|
|
||||||
"data/gn_payroll_time.xml",
|
|
||||||
"data/gn_payroll_universal.xml",
|
|
||||||
"data/gn_payroll_structure.xml",
|
|
||||||
"views/gn_payroll_company.xml",
|
|
||||||
"security/ir.model.access.csv"
|
|
||||||
],
|
|
||||||
"license": "LGPL-3",
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<record id="gn_payroll.cc_1418" model="gn_payroll.cc">
|
|
||||||
<field name="name">Convention Eclat</field>
|
|
||||||
<field name="idcc">1418</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,46 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<delete model="hr.payroll.structure.type" id="hr_contract.structure_type_employee"/>
|
|
||||||
<delete model="hr.payroll.structure.type" id="hr_contract.structure_type_worker"/>
|
|
||||||
<record id="gn_payroll_structure_type_employe" model="hr.payroll.structure.type">
|
|
||||||
<field name="name">Employé(e)</field>
|
|
||||||
<field name="country_id" eval="False"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_structure_type_cadre" model="hr.payroll.structure.type">
|
|
||||||
<field name="name">Cadre</field>
|
|
||||||
<field name="country_id" eval="False"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_structure_type_service_civique" model="hr.payroll.structure.type">
|
|
||||||
<field name="name">Volontaire en Service civique</field>
|
|
||||||
<field name="country_id" eval="False"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_structure_type_intern" model="hr.payroll.structure.type">
|
|
||||||
<field name="name">Stagiaire</field>
|
|
||||||
<field name="country_id" eval="False"/>
|
|
||||||
</record>
|
|
||||||
<record id="payroll_structure_type_benevolent" model="hr.payroll.structure.type">
|
|
||||||
<field name="name">Administrateur bénévole</field>
|
|
||||||
<field name="country_id" eval="False"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_contract_cae" model="hr.contract.type">
|
|
||||||
<field name="name">PEC - CAE</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_contract_apprentissage" model="hr.contract.type">
|
|
||||||
<field name="name">Contrat d'apprentissage</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_contract_cdd" model="hr.contract.type">
|
|
||||||
<field name="name">CDD</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_contract_cdi" model="hr.contract.type">
|
|
||||||
<field name="name">CDI</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_contract_service_civique" model="hr.contract.type">
|
|
||||||
<field name="name">Service civique</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_contract_admin" model="hr.contract.type">
|
|
||||||
<field name="name">Administrateur bénévole</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_contract_internship" model="hr.contract.type">
|
|
||||||
<field name="name">Stage</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,58 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<record id="REMUNERATION" model="hr.salary.rule.category">
|
|
||||||
<field name="name">Rémunération</field>
|
|
||||||
<field name="code">REMUNERATION</field>
|
|
||||||
</record>
|
|
||||||
<record id="BRUT" model="hr.salary.rule">
|
|
||||||
<field name="name">Salaire Brut</field>
|
|
||||||
<field name="code">BRUT</field>
|
|
||||||
<field name="sequence" eval="200" />
|
|
||||||
<field name="category_id" ref="gn_payroll.REMUNERATION" />
|
|
||||||
<field name="condition_select">none</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
if inputs.BRUT and inputs.BRUT.amount > 0:
|
|
||||||
result = inputs.BRUT.amount + categories.ALW + categories.INDEMNCOT
|
|
||||||
elif inputs.BRUT and inputs.BRUT.amount == -1 :
|
|
||||||
result = 0
|
|
||||||
else:
|
|
||||||
hours_month = 0
|
|
||||||
dic_days = {0: 0, 1:0, 2: 0, 3: 0, 4:0}
|
|
||||||
for x in contract.resource_calendar_id.attendance_ids:
|
|
||||||
dic_days[int(x.dayofweek)] += (x.hour_to - x.hour_from)
|
|
||||||
|
|
||||||
# Calculating hours workable for the month
|
|
||||||
for x in range(1, int(JOURSMOIS) + 1):
|
|
||||||
day = payslip.date_from.replace(day = x).weekday()
|
|
||||||
if day in dic_days:
|
|
||||||
hours_month += dic_days[day]
|
|
||||||
|
|
||||||
hours_std = sum([(x.hour_to - x.hour_from) for x in contract.resource_calendar_id.attendance_ids]) * 52 /12
|
|
||||||
|
|
||||||
result = round( HOURS * contract.wage / hours_month , 2) + categories.ALW + categories.INDEMNCOT
|
|
||||||
|
|
||||||
#result = round( HOURS * contract.wage / hours_std , 2) + categories.ALW + categories.INDEMNCOT
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="BRUTSC" model="hr.salary.rule">
|
|
||||||
<field name="name">Indemnité de subsistance pour volontaire en service civique (Brut)</field>
|
|
||||||
<field name="code">BRUTSC</field>
|
|
||||||
<field name="sequence" eval="200" />
|
|
||||||
<field name="category_id" ref="gn_payroll.REMUNERATION" />
|
|
||||||
<field name="condition_select">none</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
if inputs.BRUT and inputs.BRUT.amount > 0:
|
|
||||||
result = inputs.BRUT.amount
|
|
||||||
else:
|
|
||||||
hours_std = sum([( x.hour_to - x.hour_from ) for x in contract.resource_calendar_id.attendance_ids]) * 52 / 12
|
|
||||||
result = round( HOURS * TXSERVICECIVIQUE / hours_std , 2)
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="BRUT_INPUT" model="hr.rule.input">
|
|
||||||
<field name="name">Montant du Salaire Brut (corriger le montant calculé si nécessaire)</field>
|
|
||||||
<field name="code">BRUT_INPUT</field>
|
|
||||||
<field name="input_id" ref="gn_payroll.BRUT"/>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,156 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<record id="SICKNESS" model="hr.salary.rule.category">
|
|
||||||
<field name="name">Gestion des arrêts maladie</field>
|
|
||||||
<field name="code">SICKNESS</field>
|
|
||||||
</record>
|
|
||||||
<record id ="CALENDAR_SICKNESS_DAYS" model="hr.salary.rule">
|
|
||||||
<field name="name">Arrêt maladie (Jours Calendaires)</field>
|
|
||||||
<field name="code">CALENDAR_SICKNESS_DAYS</field>
|
|
||||||
<field name="active">true</field>
|
|
||||||
<field name="appears_on_payslip">false</field>
|
|
||||||
<field name="sequence" eval="100" />
|
|
||||||
<field name="category_id" ref="gn_payroll.SICKNESS" />
|
|
||||||
<field name="condition_select">python</field>
|
|
||||||
<field name="condition_python">
|
|
||||||
if (inputs.SICKNESS_FIRST_DAY and inputs.SICKNESS_FIRST_DAY.amount > 0) or (inputs.SICKNESS_LAST_DAY and inputs.SICKNESS_LAST_DAY.amount > 0):
|
|
||||||
result = True
|
|
||||||
</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
first_day = payroll.date_from.day
|
|
||||||
if inputs.SICKNESS_FIRST_DAY and \
|
|
||||||
inputs.SICKNESS_FIRST_DAY.amount and \
|
|
||||||
inputs.SICKNESS_FIRST_DAY.amount > 0:
|
|
||||||
if (inputs.SICKNESS_FIRST_DAY.amount > payroll.date_to.day) or \
|
|
||||||
(payroll.date_from.day > inputs.SICKNESS_FIRST_DAY.amount):
|
|
||||||
raise UserError("La date de début de l'arrêt maladie ne peut pas être en dehors des dates de la fiche de paye.")
|
|
||||||
else:
|
|
||||||
first_day = inputs.SICKNESS_FIRST_DAY.amount
|
|
||||||
|
|
||||||
last_day = payroll.date_to.day
|
|
||||||
if inputs.SICKNESS_LAST_DAY and \
|
|
||||||
inputs.SICKNESS_LAST_DAY.amount and \
|
|
||||||
inputs.SICKNESS_LAST_DAY.amount > 0:
|
|
||||||
if (inputs.SICKNESS_LAST_DAY.amount > payroll.date_to.day) or \
|
|
||||||
(payroll.date_from.day > inputs.SICKNESS_LAST_DAY.amount):
|
|
||||||
raise UserError("La date de fin de l'arrêt maladie ne peut pas être en dehors des dates de la fiche de paye.")
|
|
||||||
else:
|
|
||||||
last_day = inputs.SICKNESS_LAST_DAY.amount
|
|
||||||
|
|
||||||
calendar_days = []
|
|
||||||
for day in range(first_day, last_day, 1):
|
|
||||||
calendar_days.append(first_day)
|
|
||||||
result = calendar_days
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="SICKNESS_FIRST_DAY" model="hr.rule.input">
|
|
||||||
<field name="name">Arrêt maladie (Jour du mois de début de l'arrêt maladie)</field>
|
|
||||||
<field name="code">SICKNESS_FIRST_DAY_INPUT</field>
|
|
||||||
<field name="input_id" ref="gn_payroll.CALENDAR_SICKNESS_DAYS" />
|
|
||||||
</record>
|
|
||||||
<record id="SICKNESS_LAST_DAY" model="hr.rule.input">
|
|
||||||
<field name="name">Arrêt maladie (Jour du mois de fin de l'arrêt maladie)</field>
|
|
||||||
<field name="code">SICKNESS_LAST_DAY_INPUT</field>
|
|
||||||
<field name="input_id" ref="gn_payroll.CALENDAR_SICKNESS_DAYS" />
|
|
||||||
</record>
|
|
||||||
<record id="NON_WORKED_SICKNESS_DAYS_INPUT" model="hr.rule.input">
|
|
||||||
<field name="name">Arrêt maladie (Jours non-travaillés)</field>
|
|
||||||
<field name="code">NON_WORKED_SICKNESS_DAYS_INPUT</field>
|
|
||||||
<field name="input_id" ref="gn_payroll.CALENDAR_SICKNESS_DAYS" />
|
|
||||||
</record>
|
|
||||||
<record id="CALENDAR_SICKNESS_DAYS_INPUT" model="hr.rule.input">
|
|
||||||
<field name="name">Arrêt maladie (Jours calendaires)</field>
|
|
||||||
<field name="code">CALENDAR_SICKNESS_DAYS_INPUT</field>
|
|
||||||
<field name="input_id" ref="gn_payroll.CALENDAR_SICKNESS_DAYS" />
|
|
||||||
</record>
|
|
||||||
<record id ="NON_WORKED_SICKNESS_DAYS" model="hr.salary.rule">
|
|
||||||
<field name="name">Arrêt maladie (Jours non-travaillés)</field>
|
|
||||||
<field name="code">NON_WORKED_SICKNESS_DAYS</field>
|
|
||||||
<field name="active">true</field>
|
|
||||||
<field name="appears_on_payslip">false</field>
|
|
||||||
<field name="sequence" eval="101" />
|
|
||||||
<field name="category_id" ref="gn_payroll.SICKNESS" />
|
|
||||||
<field name="condition_select">python</field>
|
|
||||||
<field name="condition_python">
|
|
||||||
if rules.CALENDAR_SICKNESS_DAYS:
|
|
||||||
result = True
|
|
||||||
</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
non_worked_days = []
|
|
||||||
for sick_day in CALENDAR_SICKNESS_DAYS:
|
|
||||||
is_day_worked = payslip.date_from.replace(day = sick_day).weekday()
|
|
||||||
for planned_day in contract.resource_calendar_id.attendance_ids:
|
|
||||||
if is_day_worked == int(x.dayofweek):
|
|
||||||
non_worked_days.append(sick_day)
|
|
||||||
break
|
|
||||||
result = non_worked_days
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id ="WAITING_SICKNESS_DAYS" model="hr.salary.rule">
|
|
||||||
<field name="name">Arrêt maladie (Jours de Carence)</field>
|
|
||||||
<field name="code">WAITING_SICKNESS_DAYS</field>
|
|
||||||
<field name="active">true</field>
|
|
||||||
<field name="appears_on_payslip">false</field>
|
|
||||||
<field name="sequence" eval="101" />
|
|
||||||
<field name="category_id" ref="gn_payroll.SICKNESS" />
|
|
||||||
<field name="condition_select">python</field>
|
|
||||||
<field name="condition_python">
|
|
||||||
if rules.CALENDAR_SICKNESS_DAYS:
|
|
||||||
result = True
|
|
||||||
</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
from operator import itemgetter
|
|
||||||
if payslip.company_id.cc.idcc == 1518:
|
|
||||||
sickness_start_day = payslip.date_from.replace(day=CALENDAR_SICKNESS_DAYS[0])
|
|
||||||
# Let's check if contract (or 1st contract if consecutive contracts) is older than 6 months:
|
|
||||||
first_contract_day = payslip.contract_id.date_start
|
|
||||||
employee_contracts = [contract for contract in payslip.employee_id.contract_ids if \
|
|
||||||
(contract.id != payslip.contract_id.id and payslip.date_from >= contract.date_start) else None]
|
|
||||||
sorted_employee_contracts = sorted(employee_contracts, key=itemgetter('date_start'), reverse=True)
|
|
||||||
|
|
||||||
for contract in sorted_employee_contracts:
|
|
||||||
if contract.date_end == first_contract_day - 1:
|
|
||||||
first_contract_day = contract.date_start
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
if 90 >= sickness_start_day - first_contract_day:
|
|
||||||
result = 3
|
|
||||||
else:
|
|
||||||
result = 0
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="WAITING_SICKNESS_DAYS_INPUT" model="hr.rule.input">
|
|
||||||
<field name="name">Arrêt maladie (Jours de Carence)</field>
|
|
||||||
<field name="code">WAITING_SICKNESS_DAYS_INPUT</field>
|
|
||||||
<field name="input_id" ref="gn_payroll.WAITING_SICKNESS_DAYS" />
|
|
||||||
</record>
|
|
||||||
<record id ="IJSS_SICKNESS" model="hr.salary.rule">
|
|
||||||
<field name="name">Arrêt maladie (Montant IJSS Brut)</field>
|
|
||||||
<field name="code">IJSS_SICKNESS</field>
|
|
||||||
<field name="active">true</field>
|
|
||||||
<field name="appears_on_payslip">false</field>
|
|
||||||
<field name="sequence" eval="101" />
|
|
||||||
<field name="category_id" ref="gn_payroll.SICKNESS" />
|
|
||||||
<field name="condition_select">python</field>
|
|
||||||
<field name="condition_python">
|
|
||||||
if rules.CALENDAR_SICKNESS_DAYS:
|
|
||||||
result = True
|
|
||||||
</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
daily_wage = contract.wage * 3 / 91.25
|
|
||||||
daily_ijss = daily_wage / 2
|
|
||||||
number_of_compensated_days = len(CALENDAR_SICKNESS_DAYS) - WAITING_SICKNESS_DAYS
|
|
||||||
result = daily_ijss * number_of_compensated_days
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="IJSS_SICKNESS_INPUT" model="hr.rule.input">
|
|
||||||
<field name="name">Arrêt maladie (Montant IJSS)</field>
|
|
||||||
<field name="code">IJSS_SICKNESS_INPUT</field>
|
|
||||||
<field name="input_id" ref="gn_payroll.IJSS_SICKNESS" />
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<record id="gn_payroll_structure_common" model="hr.payroll.structure">
|
|
||||||
<field name="name">Structure Salariale par Défaut</field>
|
|
||||||
<field name="company_id" eval="1"/>
|
|
||||||
<field name="rule_ids" eval="[
|
|
||||||
(6, 0, [
|
|
||||||
ref('CALENDAR_SICKNESS_DAYS'),
|
|
||||||
ref('NON_WORKED_SICKNESS_DAYS'),
|
|
||||||
ref('NON_WORKED_SICKNESS_DAYS'),
|
|
||||||
ref('WAITING_SICKNESS_DAYS'),
|
|
||||||
ref('IJSS_SICKNESS'),
|
|
||||||
ref('HOURS'),
|
|
||||||
ref('BRUT'),
|
|
||||||
ref('JOURSMOIS'),
|
|
||||||
ref('SMICH'),
|
|
||||||
ref('PMSS'),
|
|
||||||
ref('WAGE'),
|
|
||||||
ref('TXREMBTRANS')
|
|
||||||
])
|
|
||||||
]"/>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_structure_cadre" model="hr.payroll.structure">
|
|
||||||
<field name="name">Cadre</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_structure_service_civique" model="hr.payroll.structure">
|
|
||||||
<field name="name">Service civique</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_structure_intern" model="hr.payroll.structure">
|
|
||||||
<field name="name">Stage</field>
|
|
||||||
</record>
|
|
||||||
<record id="gn_payroll_structure_administrator" model="hr.payroll.structure">
|
|
||||||
<field name="name">Administrateur</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,87 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<record id="TIME" model="hr.salary.rule.category">
|
|
||||||
<field name="name">Calcul des heures</field>
|
|
||||||
<field name="code">TIME</field>
|
|
||||||
</record>
|
|
||||||
<record id="HOURS" model="hr.salary.rule">
|
|
||||||
<field name="name">Heures rémunérées</field>
|
|
||||||
<field name="code">HOURS</field>
|
|
||||||
<field name="sequence" eval="100" />
|
|
||||||
<field name="category_id" ref="gn_payroll.TIME" />
|
|
||||||
<field name="condition_select">none</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
day = 0
|
|
||||||
hours = 0
|
|
||||||
hours_month = 0
|
|
||||||
hours_std = sum([(x.hour_to - x.hour_from) for x in contract.resource_calendar_id.attendance_ids]) * 52 /12
|
|
||||||
|
|
||||||
# calculation for Service civique
|
|
||||||
if contract.struct_id.code == "VOLSERVCIV":
|
|
||||||
if payslip.date_from.day > 1:
|
|
||||||
result = hours_std * (31 - payslip.date_from.day) / 30
|
|
||||||
elif JOURSMOIS > payslip.date_to.day:
|
|
||||||
result = hours_std * payslip.date_to.day / 30
|
|
||||||
else:
|
|
||||||
result = hours_std
|
|
||||||
|
|
||||||
# other calculations
|
|
||||||
else:
|
|
||||||
dic_days = {0: 0, 1:0, 2: 0, 3: 0, 4:0}
|
|
||||||
for x in contract.resource_calendar_id.attendance_ids:
|
|
||||||
if ((not x.date_from) or ( payslip.date_from >= x.date_from )) and \
|
|
||||||
((not x.date_to) or ( x.date_to >= payslip.date_to )):
|
|
||||||
dic_days[int(x.dayofweek)] += (x.hour_to - x.hour_from)
|
|
||||||
|
|
||||||
# Calculating missed hours when payslip doesn't start / end at the beginning/ end of the month
|
|
||||||
|
|
||||||
if payslip.date_from.day > 1:
|
|
||||||
for x in range(payslip.date_from.day, 1, -1):
|
|
||||||
day = payslip.date_from.replace(day = x).weekday()
|
|
||||||
if day in dic_days:
|
|
||||||
hours += dic_days[day]
|
|
||||||
|
|
||||||
if JOURSMOIS > payslip.date_to.day:
|
|
||||||
for x in range(payslip.date_to.day + 1, int(JOURSMOIS)):
|
|
||||||
day = payslip.date_to.replace(day = x).weekday()
|
|
||||||
if day in dic_days:
|
|
||||||
hours += dic_days[day]
|
|
||||||
|
|
||||||
hours_missed = hours
|
|
||||||
|
|
||||||
# Calculating missed hours when absence or sickday
|
|
||||||
|
|
||||||
maladie = inputs.MALADIE.amount if inputs.MALADIE and inputs.MALADIE.amount > 0.0 else 0
|
|
||||||
absences = inputs.ABSENCE.amount if inputs.ABSENCE and inputs.ABSENCE.amount > 0.0 else 0
|
|
||||||
calendaires = inputs.CALENDAIRE.amount if inputs.CALENDAIRE and inputs.CALENDAIRE.amount > 0.0 else 0
|
|
||||||
|
|
||||||
if ( maladie != 0 or absences != 0):
|
|
||||||
if calendaires + absences == JOURSMOIS:
|
|
||||||
hours_std = 0
|
|
||||||
|
|
||||||
else:
|
|
||||||
days_off = absences + maladie
|
|
||||||
hours_off = days_off * contract.resource_calendar_id.hours_per_day
|
|
||||||
hours_missed += hours_off
|
|
||||||
|
|
||||||
# Final calculations
|
|
||||||
|
|
||||||
if worked_days.WORK100 and worked_days.WORK100.number_of_hours:
|
|
||||||
hours_done = worked_days.WORK100.number_of_hours
|
|
||||||
else:
|
|
||||||
hours_done = hours_std
|
|
||||||
|
|
||||||
####result = hours_done - hours_missed
|
|
||||||
#result = hours_done * hours_std / (hours_missed + hours_done)
|
|
||||||
#result = hours_std * (hours_done - hours_missed) / hours_done
|
|
||||||
result = hours_done - hours_missed
|
|
||||||
####result = hours_std - hours_missed
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="ABSENCE" model="hr.rule.input">
|
|
||||||
<field name="name">Absences non rémunérées ( hors arrêt maladie)</field>
|
|
||||||
<field name="code">ABSENCE</field>
|
|
||||||
<field name="input_id" ref="gn_payroll.HOURS" />
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,164 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<record id="UNIVERSAL" model="hr.salary.rule.category">
|
|
||||||
<field name="name">Universel</field>
|
|
||||||
<field name="code">UNIVERSAL</field>
|
|
||||||
</record>
|
|
||||||
<record id="JOURSMOIS" model="hr.salary.rule">
|
|
||||||
<field name="name">Jours dans le mois</field>
|
|
||||||
<field name="code">JOURSMOIS</field>
|
|
||||||
<field name="sequence" eval="2" />
|
|
||||||
<field name="category_id" ref="gn_payroll.UNIVERSAL" />
|
|
||||||
<field name="condition_select">none</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
if payslip.date_from.month in [1, 3, 5, 7, 8, 10, 12]:
|
|
||||||
result = 31
|
|
||||||
elif payslip.date_from.month == 2:
|
|
||||||
if payslip.date_from.year % 4 == 0:
|
|
||||||
result = 29
|
|
||||||
else:
|
|
||||||
result = 28
|
|
||||||
else:
|
|
||||||
result = 30
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="SMICH" model="hr.salary.rule">
|
|
||||||
<field name="name">Smic Horaire</field>
|
|
||||||
<field name="code">SMICH</field>
|
|
||||||
<field name="sequence" eval="2" />
|
|
||||||
<field name="category_id" ref="gn_payroll.UNIVERSAL" />
|
|
||||||
<field name="condition_select">none</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
rate_table = [
|
|
||||||
("2014-01-01", 9.53),
|
|
||||||
("2015-01-01", 9.61),
|
|
||||||
("2016-01-01", 9.67),
|
|
||||||
("2017-01-01", 9.76),
|
|
||||||
("2018-01-01", 9.88),
|
|
||||||
("2019-01-01", 10.03),
|
|
||||||
("2020-01-01", 10.15),
|
|
||||||
("2021-01-01", 10.25),
|
|
||||||
("2021-10-01", 10.48),
|
|
||||||
("2022-01-01", 10.57),
|
|
||||||
("2022-05-01", 10.85),
|
|
||||||
("2022-08-01", 11.07),
|
|
||||||
("2023-01-01", 11.27),
|
|
||||||
("2023-05-01", 11.52)
|
|
||||||
]
|
|
||||||
def parse_date(date_str):
|
|
||||||
year, month, day = map(int, date_str.split('-'))
|
|
||||||
return year, month, day
|
|
||||||
|
|
||||||
# Manually compare dates
|
|
||||||
smic = rate_table[0][1]
|
|
||||||
for rate_date_str, rate in rate_table:
|
|
||||||
rate_year, rate_month, rate_day = parse_date(rate_date_str)
|
|
||||||
payslip_year, payslip_month, payslip_day = parse_date(payslip.date_from.strftime('%Y-%m-%d'))
|
|
||||||
|
|
||||||
if (payslip_year, payslip_month, payslip_day) >= (rate_year, rate_month, rate_day):
|
|
||||||
smic = rate
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
result = smic
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="PMSS" model="hr.salary.rule">
|
|
||||||
<field name="name">Plafond Mensuel de Sécurité Sociale</field>
|
|
||||||
<field name="code">PMSS</field>
|
|
||||||
<field name="sequence" eval="2" />
|
|
||||||
<field name="category_id" ref="gn_payroll.UNIVERSAL" />
|
|
||||||
<field name="condition_select">none</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
rate_table = [
|
|
||||||
("2014-01-01", 3129),
|
|
||||||
("2015-01-01", 3170),
|
|
||||||
("2016-01-01", 3218),
|
|
||||||
("2017-01-01", 3269),
|
|
||||||
("2018-01-01", 3311),
|
|
||||||
("2019-01-01", 3377),
|
|
||||||
("2020-01-01", 3428),
|
|
||||||
("2023-01-01", 3666)
|
|
||||||
]
|
|
||||||
def parse_date(date_str):
|
|
||||||
year, month, day = map(int, date_str.split('-'))
|
|
||||||
return year, month, day
|
|
||||||
|
|
||||||
# Manually compare dates
|
|
||||||
pmss = rate_table[0][1]
|
|
||||||
for rate_date_str, rate in rate_table:
|
|
||||||
rate_year, rate_month, rate_day = parse_date(rate_date_str)
|
|
||||||
payslip_year, payslip_month, payslip_day = parse_date(payslip.date_from.strftime('%Y-%m-%d'))
|
|
||||||
|
|
||||||
if (payslip_year, payslip_month, payslip_day) >= (rate_year, rate_month, rate_day):
|
|
||||||
pmss = rate
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
result = pmss
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="TXSERVICECIVIQUE" model="hr.salary.rule">
|
|
||||||
<field name="name">Indemnité de Service civique</field>
|
|
||||||
<field name="code">TXSERVICECIVIQUE</field>
|
|
||||||
<field name="sequence" eval="2" />
|
|
||||||
<field name="category_id" ref="gn_payroll.UNIVERSAL" />
|
|
||||||
<field name="condition_select">none</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
rate_table = [
|
|
||||||
("2015-01-01", 106.31),
|
|
||||||
("2016-07-01", 106.94),
|
|
||||||
("2017-02-01", 107.58),
|
|
||||||
("2022-07-01", 111.35),
|
|
||||||
("2023-07-01", 113.02)
|
|
||||||
]
|
|
||||||
def parse_date(date_str):
|
|
||||||
year, month, day = map(int, date_str.split('-'))
|
|
||||||
return year, month, day
|
|
||||||
|
|
||||||
# Manually compare dates
|
|
||||||
indem_service_civique = rate_table[0][1]
|
|
||||||
for rate_date_str, rate in rate_table:
|
|
||||||
rate_year, rate_month, rate_day = parse_date(rate_date_str)
|
|
||||||
payslip_year, payslip_month, payslip_day = parse_date(payslip.date_from.strftime('%Y-%m-%d'))
|
|
||||||
|
|
||||||
if (payslip_year, payslip_month, payslip_day) >= (rate_year, rate_month, rate_day):
|
|
||||||
indem_service_civique = rate
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
result = indem_service_civique
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="WAGE" model="hr.salary.rule">
|
|
||||||
<field name="name">Salaire contractuel</field>
|
|
||||||
<field name="code">WAGE</field>
|
|
||||||
<field name="sequence" eval="2" />
|
|
||||||
<field name="category_id" ref="gn_payroll.UNIVERSAL" />
|
|
||||||
<field name="condition_select">none</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
result = contract.wage
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="TXREMBTRANS" model="hr.salary.rule">
|
|
||||||
<field name="name">Taux de Remboursement des Transports</field>
|
|
||||||
<field name="code">TXREMBTRANS</field>
|
|
||||||
<field name="sequence" eval="2" />
|
|
||||||
<field name="category_id" ref="gn_payroll.UNIVERSAL" />
|
|
||||||
<field name="condition_select">none</field>
|
|
||||||
<field name="amount_select">code</field>
|
|
||||||
<field name="amount_python_compute">
|
|
||||||
if 2023 > payslip.date_from.year:
|
|
||||||
result = 35
|
|
||||||
elif payslip.date_from.year == 2023:
|
|
||||||
result = 42.05
|
|
||||||
elif payslip.date_from.year == 2024:
|
|
||||||
result = 42.05
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
@ -1,6 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
||||||
|
|
||||||
from . import gn_payroll_cc
|
|
||||||
from . import gn_payroll_company
|
|
||||||
from . import gn_payroll_employee
|
|
@ -1,17 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
||||||
|
|
||||||
from odoo import fields, models
|
|
||||||
|
|
||||||
|
|
||||||
class ConventionCollective(models.Model):
|
|
||||||
_name = "gn_payroll.cc"
|
|
||||||
_description = "Convention Collective"
|
|
||||||
_order = 'idcc, name'
|
|
||||||
|
|
||||||
def copy(self, default=None):
|
|
||||||
raise UserError(_('Duplicating a company is not allowed. Please create a new company instead.'))
|
|
||||||
|
|
||||||
name = fields.Char(string='Nom complet de la Convention Collective', required=True, store=True, readonly=False)
|
|
||||||
active = fields.Boolean(default=True)
|
|
||||||
idcc = fields.Integer(string="IDCC", help='Used to order Conventions Collectives in the switcher', default=10)
|
|
@ -1,11 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
||||||
|
|
||||||
from odoo import fields, models
|
|
||||||
|
|
||||||
|
|
||||||
class ResCompany(models.Model):
|
|
||||||
_inherit = 'res.company'
|
|
||||||
|
|
||||||
cc = fields.Many2one('gn_payroll.cc', "Convention Collective appliquée")
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
from odoo import models, fields
|
|
||||||
|
|
||||||
class GnPayrollHrEmployee(models.Model):
|
|
||||||
_inherit = 'hr.employee'
|
|
||||||
employee_type = fields.Selection([
|
|
||||||
('employee', 'Employé'),
|
|
||||||
('student', 'Étudiant'),
|
|
||||||
('trainee', 'Stagiaire'),
|
|
||||||
('volunteer', 'Volontaire'),
|
|
||||||
('benevolent', 'Bénévole'),
|
|
||||||
], string='Employee Type', default='employee', required=True,
|
|
||||||
help="The employee type. Although the primary purpose may seem to categorize employees, this field has also an impact in the Contract History. Only Employee type is supposed to be under contract and will have a Contract History.")
|
|
@ -1,3 +0,0 @@
|
|||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
|
||||||
access_gn_payroll_cc_user,gn_payroll_cc_user,model_gn_payroll_cc,base.group_user,1,0,0,0
|
|
||||||
acces_gn_payroll_cc_admin,gn_payroll_cc_admin,model_gn_payroll_cc,hr_contract.group_hr_contract_manager,1,1,0,0
|
|
|
@ -1,16 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<record id="res_company_form_gn_payroll" model="ir.ui.view">
|
|
||||||
<field name="name">res.company.form.gnpayroll.fr</field>
|
|
||||||
<field name="model">res.company</field>
|
|
||||||
<field name="priority">30</field>
|
|
||||||
<field name="inherit_id" ref="account.view_company_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<data>
|
|
||||||
<xpath expr="//field[@name='company_registry']" position="after">
|
|
||||||
<field name="cc" attrs="{'invisible': [('country_code', '!=', 'FR')]}"/>
|
|
||||||
</xpath>
|
|
||||||
</data>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
Loading…
Reference in New Issue