mirror of
https://github.com/OCA/account-financial-tools.git
synced 2025-02-02 12:47:26 +02:00
Merge pull request #462 from QANSEE/10-account_credit_control-migration
Migration of the module account_credit_control for Odoo v10
This commit is contained in:
@@ -1,11 +1,21 @@
|
||||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
|
||||
==============
|
||||
Credit Control
|
||||
==============
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Just install it
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
=============
|
||||
|
||||
Configure the policies and policy levels in ``Accounting > Configuration >
|
||||
Credit Control > Credit Policies``.
|
||||
Credit Control > Credit Control Policies``.
|
||||
You can define as many policy levels as you need.
|
||||
|
||||
Configure a tolerance for the Credit control and a default policy
|
||||
@@ -14,16 +24,59 @@ applied on all partners in each company, under the Accounting tab.
|
||||
You are able to specify a particular policy for one partner or one invoice.
|
||||
|
||||
Usage
|
||||
-----
|
||||
=====
|
||||
|
||||
Menu entries are located in ``Accounting > Periodical Processing > Credit
|
||||
Control``.
|
||||
Menu entries are located in ``Accounting > Adviser > Credit Control``.
|
||||
|
||||
Create a new "run" in the ``Credit Control Run`` menu with the controlling date.
|
||||
Then, use the ``Compute credit lines`` button. All the credit control lines will
|
||||
Then, use the ``Compute Credit Lines`` button. All the credit control lines will
|
||||
be generated. You can find them in the ``Credit Control Lines`` menu.
|
||||
|
||||
On each generated line, you have many choices:
|
||||
* Send a email
|
||||
* Print a letter
|
||||
* Change the state (so you can ignore or reopen lines)
|
||||
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/92/10.0
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues
|
||||
<https://github.com/OCA/account-financial-tools/issues>`_. In case of trouble, please
|
||||
check there if your issue has already been reported. If you spotted it first,
|
||||
help us smash it by providing detailed and welcomed feedback.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Images
|
||||
------
|
||||
|
||||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Nicolas Bessi (Camptocamp)
|
||||
* Guewen Baconnier (Camptocamp)
|
||||
* Sylvain Van Hoof (Okia SPRL) <sylvain@okia.be>
|
||||
* Akim Juillerat (Camptocamp <akim.juillerat@camptocamp.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
To contribute to this module, please visit https://odoo-community.org.
|
||||
|
||||
@@ -1,29 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import mail
|
||||
from . import run
|
||||
from . import line
|
||||
from . import account
|
||||
from . import partner
|
||||
from . import policy
|
||||
from . import company
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from . import models
|
||||
from . import wizard
|
||||
from . import invoice
|
||||
|
||||
@@ -1,51 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
{'name': 'Account Credit Control',
|
||||
'version': '8.0.0.3.0',
|
||||
'author': "Camptocamp,Odoo Community Association (OCA)",
|
||||
'version': '10.0.1.0.0',
|
||||
'author': "Camptocamp,Odoo Community Association (OCA),Okia",
|
||||
'maintainer': 'Camptocamp',
|
||||
'category': 'Finance',
|
||||
'complexity': "normal",
|
||||
'depends': ['base',
|
||||
'account',
|
||||
'email_template',
|
||||
],
|
||||
'website': 'http://www.camptocamp.com',
|
||||
'data': ["report/report.xml",
|
||||
"report/report_credit_control_summary.xml",
|
||||
"data.xml",
|
||||
"line_view.xml",
|
||||
"account_view.xml",
|
||||
"partner_view.xml",
|
||||
"policy_view.xml",
|
||||
"run_view.xml",
|
||||
"company_view.xml",
|
||||
"wizard/credit_control_emailer_view.xml",
|
||||
"wizard/credit_control_marker_view.xml",
|
||||
"wizard/credit_control_printer_view.xml",
|
||||
"wizard/credit_control_policy_changer_view.xml",
|
||||
"security/ir.model.access.csv"],
|
||||
'demo': ["credit_control_demo.xml"],
|
||||
'tests': [],
|
||||
'installable': False,
|
||||
'depends': [
|
||||
'base',
|
||||
'account',
|
||||
'mail',
|
||||
],
|
||||
'website': 'https://www.camptocamp.com',
|
||||
'data': [
|
||||
"security/res_groups.xml",
|
||||
# Reports
|
||||
"report/report.xml",
|
||||
"report/report_credit_control_summary.xml",
|
||||
|
||||
# Data
|
||||
"data/data.xml",
|
||||
|
||||
# Views
|
||||
"views/account_invoice.xml",
|
||||
"views/credit_control_line.xml",
|
||||
"views/credit_control_policy.xml",
|
||||
"views/credit_control_run.xml",
|
||||
"views/res_company.xml",
|
||||
"views/res_partner.xml",
|
||||
|
||||
# Wizards
|
||||
"wizard/credit_control_emailer_view.xml",
|
||||
"wizard/credit_control_marker_view.xml",
|
||||
"wizard/credit_control_printer_view.xml",
|
||||
"wizard/credit_control_policy_changer_view.xml",
|
||||
|
||||
# Security
|
||||
"security/ir.model.access.csv",
|
||||
],
|
||||
'installable': True,
|
||||
'license': 'AGPL-3',
|
||||
'application': True
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields
|
||||
|
||||
|
||||
class AccountAccount(models.Model):
|
||||
""" Add a link to a credit control policy on account.account """
|
||||
|
||||
_inherit = "account.account"
|
||||
|
||||
credit_control_line_ids = fields.One2many('credit.control.line',
|
||||
'account_id',
|
||||
string='Credit Lines',
|
||||
readonly=True)
|
||||
@@ -1,45 +0,0 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<act_window
|
||||
id="act_account_credit_relation_relation"
|
||||
name="Credit Lines"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user"
|
||||
domain="[('account_id', '=', active_id)]"
|
||||
res_model="credit.control.line"
|
||||
src_model="account.account"/>
|
||||
|
||||
<record id="invoice_followup_form_view" model="ir.ui.view">
|
||||
<field name="name">invoice.followup.form.view</field>
|
||||
<field name="model">account.invoice</field>
|
||||
<field name="inherit_id" ref="account.invoice_form" />
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page string="Credit Control"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user,account_credit_control.group_account_credit_control_info">
|
||||
<group>
|
||||
<field name="credit_policy_id" widget="selection"
|
||||
string="Manual Credit Control Policy"
|
||||
attrs="{'invisible': [('credit_policy_id', '=', False)]}"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user,account_credit_control.group_account_credit_control_info"/>
|
||||
</group>
|
||||
<separator string="Issued Lines" colspan="4"/>
|
||||
<field name="credit_control_line_ids" colspan="4" nolabel="1"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user,account_credit_control.group_account_credit_control_info" >
|
||||
<tree string="Credit Control Lines">
|
||||
<field name="date"/>
|
||||
<field name="level"/>
|
||||
<field name="state"/>
|
||||
<field name="channel"/>
|
||||
<field name="balance_due"/>
|
||||
<field name="policy_level_id"/>
|
||||
<field name="policy_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,37 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
""" Add credit control parameters """
|
||||
_inherit = 'res.company'
|
||||
|
||||
credit_control_tolerance = fields.Float(string='Credit Control Tolerance',
|
||||
default=0.1)
|
||||
# This is not a property on the partner because we cannot search
|
||||
# on fields.property (subclass fields.function).
|
||||
credit_policy_id = fields.Many2one('credit.control.policy',
|
||||
string='Credit Control Policy',
|
||||
help="The Credit Control Policy used "
|
||||
"on partners by default. "
|
||||
"This setting can be overridden"
|
||||
" on partners or invoices.")
|
||||
@@ -1,15 +0,0 @@
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="credit_control_company_form" model="ir.ui.view">
|
||||
<field name="name">credit.control.company.form</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="currency_id" position="after">
|
||||
<field name="credit_policy_id" widget="selection"/>
|
||||
<field name="credit_control_tolerance"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,30 +0,0 @@
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="a_recv_1" model="account.account">
|
||||
<field name="code">X11002-a</field>
|
||||
<field name="name">B2B Debtors - (test)</field>
|
||||
<field ref="account.cas" name="parent_id"/>
|
||||
<field name="type">receivable</field>
|
||||
<field eval="True" name="reconcile"/>
|
||||
<field name="user_type" ref="account.data_account_type_receivable"/>
|
||||
</record>
|
||||
|
||||
<record id="a_recv_2" model="account.account">
|
||||
<field name="code">X11002-b</field>
|
||||
<field name="name">B2C Debtors - (test)</field>
|
||||
<field ref="account.cas" name="parent_id"/>
|
||||
<field name="type">receivable</field>
|
||||
<field eval="True" name="reconcile"/>
|
||||
<field name="user_type" ref="account.data_account_type_receivable"/>
|
||||
</record>
|
||||
|
||||
<record id="a_recv_3" model="account.account">
|
||||
<field name="code">X11002-c</field>
|
||||
<field name="name">New Debtors - (test)</field>
|
||||
<field ref="account.cas" name="parent_id"/>
|
||||
<field name="type">receivable</field>
|
||||
<field eval="True" name="reconcile"/>
|
||||
<field name="user_type" ref="account.data_account_type_receivable"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,230 +0,0 @@
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<!--Email template -->
|
||||
<record id="email_template_credit_control_base" model="email.template">
|
||||
<field name="name">Credit Control Email</field>
|
||||
<field name="email_from">noreply@localhost</field>
|
||||
<field name="subject">Credit Control: (${object.current_policy_level.name or 'n/a'})</field>
|
||||
<field name="email_to">${object.get_email() or ''}</field>
|
||||
<field name="model_id" ref="model_credit_control_communication"/>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="lang">${object.get_contact_address().lang or 'en_US'}</field>
|
||||
<field name="report_template" ref="credit_control_summary"/>
|
||||
<field name="body_html"><![CDATA[
|
||||
Dear ${object.contact_address.name or ''}
|
||||
<br/>
|
||||
<br/>
|
||||
${object.current_policy_level.custom_mail_text | safe}
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<!-- policy no follow -->
|
||||
<record model="credit.control.policy"
|
||||
id="credit_control_no_follow">
|
||||
<field name="name">No follow</field>
|
||||
<field name="do_nothing" eval="1"/>
|
||||
</record>
|
||||
|
||||
<!-- no follow policy -->
|
||||
<record model="credit.control.policy.level"
|
||||
id="no_follow_1">
|
||||
<field name="name">No follow</field>
|
||||
<field name="level" eval="1"/>
|
||||
<field name="computation_mode">net_days</field>
|
||||
<field name="delay_days" eval="0"/>
|
||||
<field name="email_template_id" ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_no_follow"/>
|
||||
<field name="channel">email</field>
|
||||
<field name="custom_text">Manual no follow</field>
|
||||
|
||||
<field name="custom_mail_text">Manual no follow</field>
|
||||
</record>
|
||||
|
||||
<!-- policy 1 -->
|
||||
<record model="credit.control.policy"
|
||||
id="credit_control_3_time">
|
||||
<field name="name">3 time policy</field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="3_time_1">
|
||||
<field name="name">10 days net</field>
|
||||
<field name="level" eval="1"/>
|
||||
<field name="computation_mode">net_days</field>
|
||||
<field name="delay_days" eval="10"/>
|
||||
<field name="email_template_id" ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_3_time"/>
|
||||
<field name="channel">email</field>
|
||||
<field name="custom_text">Our records indicate that we have not received the payment of the above mentioned invoice.
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we have not received the payment of the invoices mentioned in the attached document.<br/>
|
||||
<br/>
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="3_time_2">
|
||||
<field name="name">30 days end of month</field>
|
||||
<field name="level" eval="2"/>
|
||||
<field name="computation_mode">end_of_month</field>
|
||||
<field name="delay_days" eval="30"/>
|
||||
<field name="email_template_id" ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_3_time"/>
|
||||
<field name="channel">email</field>
|
||||
<field name="custom_text">Our records indicate that we have not yet received the payment of the above mentioned invoice despite our first reminder.
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 5 days.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we have not yet received the payment of the invoices mentioned in the attached document despite our first reminder.<br/>
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 5 days.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="3_time_3">
|
||||
<field name="name">10 days last reminder</field>
|
||||
<field name="level" eval="3"/>
|
||||
<field name="computation_mode">previous_date</field>
|
||||
<field name="delay_days" eval="10"/>
|
||||
<field name="email_template_id" ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_3_time"/>
|
||||
<field name="channel">letter</field>
|
||||
<field name="custom_text">
|
||||
Our records indicate that we still have not received the payment of the above mentioned invoice despite our two reminders.
|
||||
If payment have already been sent, please disregard this notice. If not, please proceed with payment.
|
||||
If your payment has not been received in the next 5 days, your file will be transfered to our debt collection agency.
|
||||
|
||||
Should you need us to arrange a payment plan for you, please advise.
|
||||
A customer account statement is enclosed for you convenience.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we still have not received the payment of the invoices mentioned in the attached document despite our two reminders.<br/>
|
||||
If payment have already been sent, please disregard this notice. If not, please proceed with payment.<br/>
|
||||
If your payment has not been received in the next 5 days, your file will be transfered to our debt collection agency.<br/>
|
||||
<br/>
|
||||
Should you need us to arrange a payment plan for you, please advise.<br/>
|
||||
A customer account statement is enclosed for you convenience.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<!-- policy 2 -->
|
||||
<record model="credit.control.policy"
|
||||
id="credit_control_2_time">
|
||||
<field name="name">2 time policy</field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="2_time_1">
|
||||
<field name="name">30 days end of month</field>
|
||||
<field name="level" eval="1"/>
|
||||
<field name="computation_mode">end_of_month</field>
|
||||
<field name="delay_days" eval="30"/>
|
||||
<field name="email_template_id" ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_2_time"/>
|
||||
<field name="channel">email</field>
|
||||
<field name="custom_text">Our records indicate that we have not received the payment of the above mentioned invoice.
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we have not received the payment of the invoices mentioned in the attached document.<br/>
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="2_time_2">
|
||||
<field name="name">60 days last reminder</field>
|
||||
<field name="level" eval="2"/>
|
||||
<field name="computation_mode">previous_date</field>
|
||||
<field name="delay_days" eval="60"/>
|
||||
<field name="email_template_id" ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_2_time"/>
|
||||
<field name="channel">letter</field>
|
||||
<field name="custom_text">Our records indicate that we still have not received the payment of the above mentioned invoice despite our reminder.
|
||||
|
||||
If payment have already been sent, please disregard this notice. If not, please proceed with payment.
|
||||
If your payment has not been received in the next 5 days, your file will be transfered to our debt
|
||||
collection agency.
|
||||
|
||||
Should you need us to arrange a payment plan for you, please advise.
|
||||
A customer account statement is enclosed for you convenience.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we still have not received the payment of the invoices mentioned in the attached document despite our reminder.
|
||||
<br/>
|
||||
<br/>
|
||||
If payment have already been sent, please disregard this notice. If not, please proceed with payment.<br/>
|
||||
If your payment has not been received in the next 5 days, your file will be transfered to our debt<br/>
|
||||
collection agency.<br/>
|
||||
<br/>
|
||||
Should you need us to arrange a payment plan for you, please advise.<br/>
|
||||
A customer account statement is enclosed for you convenience.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<record id="group_account_credit_control_manager" model="res.groups">
|
||||
<field name="name">Credit Control Manager</field>
|
||||
<field name="category_id" ref="base.module_category_accounting_and_finance"/>
|
||||
</record>
|
||||
|
||||
<record id="group_account_credit_control_user" model="res.groups" context="{'noadmin':True}">
|
||||
<field name="name">Credit Control User</field>
|
||||
<field name="category_id" ref="base.module_category_accounting_and_finance"/>
|
||||
</record>
|
||||
|
||||
<record id="group_account_credit_control_info" model="res.groups" context="{'noadmin':True}">
|
||||
<field name="name">Credit Control Info</field>
|
||||
<field name="category_id" ref="base.module_category_accounting_and_finance"/>
|
||||
</record>
|
||||
|
||||
<record id="base.main_company" model="res.company">
|
||||
<field name="credit_policy_id" ref="credit_control_3_time"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
224
account_credit_control/data/data.xml
Normal file
224
account_credit_control/data/data.xml
Normal file
@@ -0,0 +1,224 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo noupdate="1">
|
||||
<!--Email template -->
|
||||
<record id="email_template_credit_control_base" model="mail.template">
|
||||
<field name="name">Credit Control Email</field>
|
||||
<field name="email_from">${object.partner_id.company_id.email or ''}</field>
|
||||
<field name="subject">Credit Control:
|
||||
(${object.current_policy_level.name or 'n/a'})
|
||||
</field>
|
||||
<field name="email_to">${object.get_email() or ''}</field>
|
||||
<field name="model_id" ref="model_credit_control_communication"/>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="lang">
|
||||
${object.get_contact_address().lang or 'en_US'}
|
||||
</field>
|
||||
<field name="report_template" ref="credit_control_summary"/>
|
||||
<field name="body_html"><![CDATA[
|
||||
Dear ${object.contact_address.name or ''}
|
||||
<br/>
|
||||
<br/>
|
||||
${object.current_policy_level.custom_mail_text | safe}
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<!-- policy no follow -->
|
||||
<record model="credit.control.policy"
|
||||
id="credit_control_no_follow">
|
||||
<field name="name">No follow</field>
|
||||
<field name="do_nothing" eval="1"/>
|
||||
</record>
|
||||
|
||||
<!-- no follow policy -->
|
||||
<record model="credit.control.policy.level"
|
||||
id="no_follow_1">
|
||||
<field name="name">No follow</field>
|
||||
<field name="level" eval="1"/>
|
||||
<field name="computation_mode">net_days</field>
|
||||
<field name="delay_days" eval="0"/>
|
||||
<field name="email_template_id"
|
||||
ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_no_follow"/>
|
||||
<field name="channel">email</field>
|
||||
<field name="custom_text">Manual no follow</field>
|
||||
|
||||
<field name="custom_mail_text">Manual no follow</field>
|
||||
</record>
|
||||
|
||||
<!-- policy 1 -->
|
||||
<record model="credit.control.policy"
|
||||
id="credit_control_3_time">
|
||||
<field name="name">3 time policy</field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="3_time_1">
|
||||
<field name="name">10 days net</field>
|
||||
<field name="level" eval="1"/>
|
||||
<field name="computation_mode">net_days</field>
|
||||
<field name="delay_days" eval="10"/>
|
||||
<field name="email_template_id"
|
||||
ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_3_time"/>
|
||||
<field name="channel">email</field>
|
||||
<field name="custom_text">Our records indicate that we have not received the payment of the invoice mentioned below.
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we have not received the payment of the invoices mentioned in the attached document.<br/>
|
||||
<br/>
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="3_time_2">
|
||||
<field name="name">30 days end of month</field>
|
||||
<field name="level" eval="2"/>
|
||||
<field name="computation_mode">end_of_month</field>
|
||||
<field name="delay_days" eval="30"/>
|
||||
<field name="email_template_id"
|
||||
ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_3_time"/>
|
||||
<field name="channel">email</field>
|
||||
<field name="custom_text">Our records indicate that we have not yet received the payment of the invoice mentioned below despite our first reminder.
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 5 days.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we have not yet received the payment of the invoices mentioned in the attached document despite our first reminder.<br/>
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 5 days.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="3_time_3">
|
||||
<field name="name">10 days last reminder</field>
|
||||
<field name="level" eval="3"/>
|
||||
<field name="computation_mode">previous_date</field>
|
||||
<field name="delay_days" eval="10"/>
|
||||
<field name="email_template_id"
|
||||
ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_3_time"/>
|
||||
<field name="channel">letter</field>
|
||||
<field name="custom_text">
|
||||
Our records indicate that we still have not received the payment of the invoice mentioned below despite our two reminders.
|
||||
If payment have already been sent, please disregard this notice. If not, please proceed with payment.
|
||||
If your payment has not been received in the next 5 days, your file will be transfered to our debt collection agency.
|
||||
|
||||
Should you need us to arrange a payment plan for you, please advise.
|
||||
A customer account statement is enclosed for you convenience.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we still have not received the payment of the invoices mentioned in the attached document despite our two reminders.<br/>
|
||||
If payment have already been sent, please disregard this notice. If not, please proceed with payment.<br/>
|
||||
If your payment has not been received in the next 5 days, your file will be transfered to our debt collection agency.<br/>
|
||||
<br/>
|
||||
Should you need us to arrange a payment plan for you, please advise.<br/>
|
||||
A customer account statement is enclosed for you convenience.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<!-- policy 2 -->
|
||||
<record model="credit.control.policy"
|
||||
id="credit_control_2_time">
|
||||
<field name="name">2 time policy</field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="2_time_1">
|
||||
<field name="name">30 days end of month</field>
|
||||
<field name="level" eval="1"/>
|
||||
<field name="computation_mode">end_of_month</field>
|
||||
<field name="delay_days" eval="30"/>
|
||||
<field name="email_template_id"
|
||||
ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_2_time"/>
|
||||
<field name="channel">email</field>
|
||||
<field name="custom_text">Our records indicate that we have not received the payment of the invoice mentioned below.
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we have not received the payment of the invoices mentioned in the attached document.<br/>
|
||||
If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<record model="credit.control.policy.level"
|
||||
id="2_time_2">
|
||||
<field name="name">60 days last reminder</field>
|
||||
<field name="level" eval="2"/>
|
||||
<field name="computation_mode">previous_date</field>
|
||||
<field name="delay_days" eval="60"/>
|
||||
<field name="email_template_id"
|
||||
ref="email_template_credit_control_base"/>
|
||||
<field name="policy_id" ref="credit_control_2_time"/>
|
||||
<field name="channel">letter</field>
|
||||
<field name="custom_text">Our records indicate that we still have not received the payment of the mentioned below invoice despite our reminder.
|
||||
|
||||
If payment have already been sent, please disregard this notice. If not, please proceed with payment.
|
||||
If your payment has not been received in the next 5 days, your file will be transfered to our debt collection agency.
|
||||
|
||||
Should you need us to arrange a payment plan for you, please advise.
|
||||
A customer account statement is enclosed for you convenience.
|
||||
|
||||
Thank you in advance for your anticipated cooperation in this matter.
|
||||
|
||||
Best regards
|
||||
</field>
|
||||
<field name="custom_mail_text"><![CDATA[
|
||||
Our records indicate that we still have not received the payment of the invoices mentioned in the attached document despite our reminder.
|
||||
<br/>
|
||||
<br/>
|
||||
If payment have already been sent, please disregard this notice. If not, please proceed with payment.<br/>
|
||||
If your payment has not been received in the next 5 days, your file will be transfered to our debt<br/>
|
||||
collection agency.<br/>
|
||||
<br/>
|
||||
Should you need us to arrange a payment plan for you, please advise.<br/>
|
||||
A customer account statement is enclosed for you convenience.<br/>
|
||||
<br/>
|
||||
Thank you in advance for your anticipated cooperation in this matter.<br/>
|
||||
<br/>
|
||||
Best regards
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="base.main_company" model="res.company">
|
||||
<field name="credit_policy_id" ref="credit_control_3_time"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,171 +0,0 @@
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="credit_control_line_form" model="ir.ui.view">
|
||||
<field name="name">credit.control.line.form</field>
|
||||
<field name="model">credit.control.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Control Credit Lines">
|
||||
<header>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="draft,to_be_sent,sent"
|
||||
statusbar_colors='{"error":"red","email_error":"red"}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="partner_id"/>
|
||||
<field name="policy_level_id"/>
|
||||
<field name="policy_id"/>
|
||||
<field name="level"/>
|
||||
<field name="manually_overridden"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="date"/>
|
||||
<field name="date_due"/>
|
||||
<field name="channel"/>
|
||||
<field name="date_sent"/>
|
||||
<field name="mail_message_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="invoice_id"/>
|
||||
<field name="move_line_id"/>
|
||||
<field name="account_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="amount_due"/>
|
||||
<field name="balance_due"/>
|
||||
<field name="currency_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_line_search" model="ir.ui.view">
|
||||
<field name="name">Credit Control Lines</field>
|
||||
<field name="model">credit.control.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Control Credit Lines">
|
||||
<group string="Filters">
|
||||
<filter name="filter_draft" icon="terp-mail-message-new"
|
||||
string="Draft" domain="[('state', '=', 'draft')]"
|
||||
help="Draft lines have to be triaged."/>
|
||||
<filter name="filter_to_be_sent" icon="terp-mail-forward"
|
||||
string="Ready To Send" domain="[('state', '=', 'to_be_sent')]"
|
||||
help="These lines are ready to send by email or by letter using the Actions."/>
|
||||
<filter name="filter_ignored" icon="terp-mail_delete"
|
||||
string="Ignored" domain="[('state', '=', 'ignored')]"
|
||||
help="Lines which have been ignored from previous runs."/>
|
||||
<filter name="filter_sent" icon="terp-mail-replied"
|
||||
string="Sent" domain="[('state', '=', 'sent')]"
|
||||
help="Lines already sent."/>
|
||||
<filter name="filter_error" icon="terp-gtk-stop" string="Error"
|
||||
domain="[('state', 'in', ('error', 'email_error'))]"
|
||||
help="An error has occured during the sending of the email."/>
|
||||
<filter name="filter_manual" icon="terp-gtk-stop" string="Manual change"
|
||||
domain="[('manually_overridden', '=', True)]"
|
||||
help="The line was deprecated by a manual change of policy on invoice."/>
|
||||
<separator orientation="vertical"/>
|
||||
|
||||
<field name="date"/>
|
||||
<field name="channel" />
|
||||
<field name="policy_id"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="0" string="More...">
|
||||
<field name="partner_id"/>
|
||||
<field name="account_id"/>
|
||||
<field name="invoice_id"/>
|
||||
<field name="level"/>
|
||||
<field name="policy_level_id"/>
|
||||
</group>
|
||||
|
||||
<newline/>
|
||||
<group expand="0" string="Group By...">
|
||||
<separator orientation="vertical"/>
|
||||
<filter domain='[]' context="{'group_by': 'date'}"
|
||||
icon="terp-go-month" string="Run date"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter domain='[]' context="{'group_by': 'level'}"
|
||||
icon="terp-gtk-jump-to-rtl" string="Level"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter domain='[]' context="{'group_by': 'partner_id'}"
|
||||
icon="terp-partner" string="Partner"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter domain='[]' context="{'group_by': 'account_id'}"
|
||||
icon="terp-folder-green" string="Account"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter domain='[]' context="{'group_by': 'invoice_id'}"
|
||||
icon="terp-document-new" string="Invoice"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter domain='[]' context="{'group_by': 'policy_id'}"
|
||||
icon="terp-document-new" string="Credit policy"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter domain='[]' context="{'group_by': 'policy_level_id'}"
|
||||
icon="terp-document-new" string="Credit policy level"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter domain='[]' context="{'group_by': 'channel'}"
|
||||
icon="terp-document-new" string="Channel"/>
|
||||
<filter domain='[]' context="{'group_by': 'manually_overridden'}"
|
||||
icon="terp-document-new" string="Manual change"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_line_tree" model="ir.ui.view">
|
||||
<field name="name">credit.control.line.tree</field>
|
||||
<field name="model">credit.control.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Control Credit Lines" colors="green:state == 'sent';red:state in ('error', 'email_error');">
|
||||
<field name="date"/>
|
||||
<field name="date_due"/>
|
||||
<field name="level"/>
|
||||
<field name="manually_overridden"/>
|
||||
<field name="state"/>
|
||||
<field name="channel"/>
|
||||
<field name="invoice_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="amount_due"/>
|
||||
<field name="balance_due"/>
|
||||
<field name="currency_id"/>
|
||||
<field name="move_line_id"/>
|
||||
<field name="account_id"/>
|
||||
<field name="policy_level_id"/>
|
||||
<field name="policy_id"/>
|
||||
<field name="mail_message_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Credit Control"
|
||||
parent="account.menu_finance_periodical_processing"
|
||||
id="base_credit_control_menu"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="credit_control_line_action">
|
||||
<field name="name">Credit Control Lines</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">credit.control.line</field>
|
||||
<field name="domain"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="credit_control_line_tree"/>
|
||||
<field name="context">{'search_default_filter_draft': 1, 'search_default_filter_to_be_sent': 1}</field>
|
||||
<field name="search_view_id" ref="credit_control_line_search"/>
|
||||
</record>
|
||||
|
||||
|
||||
<menuitem
|
||||
name="Credit Control Lines"
|
||||
parent="base_credit_control_menu"
|
||||
action="credit_control_line_action"
|
||||
sequence="20"
|
||||
id="credit_control_line_action_menu"/>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,29 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields
|
||||
|
||||
|
||||
class Mail(models.Model):
|
||||
_inherit = 'mail.mail'
|
||||
|
||||
# use HTML fields instead of text
|
||||
body_html = fields.Html('Rich-text Contents',
|
||||
help="Rich-text/HTML message")
|
||||
@@ -1,26 +0,0 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
import logging
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.modules.registry import RegistryManager
|
||||
|
||||
uid = SUPERUSER_ID
|
||||
|
||||
__name__ = 'Change custom_mail_text text field to hmtl field'
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def migrate_replace_text_with_html(cr, registry):
|
||||
cr.execute("""update credit_control_policy_level set
|
||||
custom_mail_text=regexp_replace(custom_mail_text, E'[\\n]',
|
||||
'<br/>','g')""")
|
||||
cr.execute("""update ir_translation set
|
||||
value=regexp_replace(value, E'[\\n]','<br/>','g')
|
||||
where name='credit.control.policy.level,custom_mail_text'""")
|
||||
|
||||
|
||||
def migrate(cr, version):
|
||||
if not version:
|
||||
# it is the installation of the module
|
||||
return
|
||||
registry = RegistryManager.get(cr.dbname)
|
||||
migrate_replace_text_with_html(cr, registry)
|
||||
11
account_credit_control/models/__init__.py
Normal file
11
account_credit_control/models/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from . import account_account
|
||||
from . import account_invoice
|
||||
from . import credit_control_line
|
||||
from . import credit_control_policy
|
||||
from . import credit_control_run
|
||||
from . import mail_mail
|
||||
from . import res_company
|
||||
from . import res_partner
|
||||
16
account_credit_control/models/account_account.py
Normal file
16
account_credit_control/models/account_account.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class AccountAccount(models.Model):
|
||||
""" Add a link to a credit control policy on account.account """
|
||||
|
||||
_inherit = "account.account"
|
||||
|
||||
credit_control_line_ids = fields.One2many('credit.control.line',
|
||||
'account_id',
|
||||
string='Credit Lines',
|
||||
readonly=True)
|
||||
@@ -1,24 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Vincent Renaville
|
||||
# Copyright 2013 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields, api, _
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
@@ -56,7 +41,7 @@ class AccountInvoice(models.Model):
|
||||
('state', '!=', 'draft')]
|
||||
cc_nondraft_lines = cc_line_obj.search(nondraft_domain)
|
||||
if cc_nondraft_lines:
|
||||
raise api.Warning(
|
||||
raise UserError(
|
||||
_('You cannot cancel this invoice.\n'
|
||||
'A payment reminder has already been '
|
||||
'sent to the customer.\n'
|
||||
@@ -1,28 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
logger = logging.getLogger('credit.line.control')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CreditControlLine(models.Model):
|
||||
@@ -40,7 +25,7 @@ class CreditControlLine(models.Model):
|
||||
|
||||
date = fields.Date(string='Controlling date',
|
||||
required=True,
|
||||
select=True)
|
||||
index=True)
|
||||
# maturity date of related move line we do not use
|
||||
# a related field in order to
|
||||
# allow manual changes
|
||||
@@ -130,7 +115,7 @@ class CreditControlLine(models.Model):
|
||||
store=True,
|
||||
readonly=True)
|
||||
|
||||
level = fields.Integer('credit.control.policy.level',
|
||||
level = fields.Integer('Level',
|
||||
related='policy_level_id.level',
|
||||
store=True,
|
||||
readonly=True)
|
||||
@@ -149,8 +134,8 @@ class CreditControlLine(models.Model):
|
||||
data['date_due'] = move_line.date_maturity
|
||||
data['state'] = 'draft'
|
||||
data['channel'] = level.channel
|
||||
data['invoice_id'] = (move_line.invoice.id if
|
||||
move_line.invoice else False)
|
||||
data['invoice_id'] = (move_line.invoice_id.id if
|
||||
move_line.invoice_id else False)
|
||||
data['partner_id'] = move_line.partner_id.id
|
||||
data['amount_due'] = (move_line.amount_currency or move_line.debit or
|
||||
move_line.credit)
|
||||
@@ -194,7 +179,10 @@ class CreditControlLine(models.Model):
|
||||
|
||||
new_lines = self.browse()
|
||||
for move_line in lines:
|
||||
open_amount = move_line.amount_residual_currency
|
||||
if move_line.currency_id:
|
||||
open_amount = move_line.amount_residual_currency
|
||||
else:
|
||||
open_amount = move_line.amount_residual
|
||||
cur_tolerance = tolerance.get(move_line.currency_id.id,
|
||||
tolerance_base)
|
||||
if check_tolerance and open_amount < cur_tolerance:
|
||||
@@ -204,7 +192,7 @@ class CreditControlLine(models.Model):
|
||||
controlling_date,
|
||||
open_amount)
|
||||
line = self.create(vals)
|
||||
new_lines += line
|
||||
new_lines |= line
|
||||
|
||||
# when we have lines generated earlier in draft,
|
||||
# on the same level, it means that we have left
|
||||
@@ -222,7 +210,7 @@ class CreditControlLine(models.Model):
|
||||
def unlink(self):
|
||||
for line in self:
|
||||
if line.state != 'draft':
|
||||
raise api.Warning(
|
||||
raise UserError(
|
||||
_('You are not allowed to delete a credit control '
|
||||
'line that is not in draft state.')
|
||||
)
|
||||
@@ -1,24 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields, api, _
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class CreditControlPolicy(models.Model):
|
||||
@@ -39,7 +24,7 @@ class CreditControlPolicy(models.Model):
|
||||
'account.account',
|
||||
string='Accounts',
|
||||
required=True,
|
||||
domain="[('type', '=', 'receivable')]",
|
||||
domain="[('internal_type', '=', 'receivable')]",
|
||||
help="This policy will be active only"
|
||||
" for the selected accounts",
|
||||
)
|
||||
@@ -51,7 +36,7 @@ class CreditControlPolicy(models.Model):
|
||||
self.ensure_one()
|
||||
return [('account_id', 'in', self.account_ids.ids),
|
||||
('date_maturity', '<=', controlling_date),
|
||||
('reconcile_id', '=', False),
|
||||
('reconciled', '=', False),
|
||||
('partner_id', '!=', False)]
|
||||
|
||||
@api.multi
|
||||
@@ -71,7 +56,7 @@ class CreditControlPolicy(models.Model):
|
||||
move_l_obj = self.env['account.move.line']
|
||||
user = self.env.user
|
||||
if user.company_id.credit_policy_id.id != self.id:
|
||||
return move_l_obj.browse()
|
||||
return move_l_obj
|
||||
domain_line = self._move_lines_domain(controlling_date)
|
||||
return move_l_obj.search(domain_line)
|
||||
|
||||
@@ -97,11 +82,10 @@ class CreditControlPolicy(models.Model):
|
||||
self.ensure_one()
|
||||
# MARK possible place for a good optimisation
|
||||
my_obj = self.env[model]
|
||||
move_l_obj = self.env['account.move.line']
|
||||
default_domain = self._move_lines_domain(controlling_date)
|
||||
|
||||
to_add = move_l_obj.browse()
|
||||
to_remove = move_l_obj.browse()
|
||||
to_add = self.env['account.move.line']
|
||||
to_remove = self.env['account.move.line']
|
||||
|
||||
# The lines which are linked to this policy have to be included in the
|
||||
# run for this policy.
|
||||
@@ -110,7 +94,7 @@ class CreditControlPolicy(models.Model):
|
||||
if add_objs:
|
||||
domain = list(default_domain)
|
||||
domain.append((move_relation_field, 'in', add_objs.ids))
|
||||
to_add = move_l_obj.search(domain)
|
||||
to_add = to_add.search(domain)
|
||||
|
||||
# The lines which are linked to another policy do not have to be
|
||||
# included in the run for this policy.
|
||||
@@ -119,7 +103,7 @@ class CreditControlPolicy(models.Model):
|
||||
if neg_objs:
|
||||
domain = list(default_domain)
|
||||
domain.append((move_relation_field, 'in', neg_objs.ids))
|
||||
to_remove = move_l_obj.search(domain)
|
||||
to_remove = to_remove.search(domain)
|
||||
return to_add, to_remove
|
||||
|
||||
@api.multi
|
||||
@@ -150,7 +134,7 @@ class CreditControlPolicy(models.Model):
|
||||
the process
|
||||
"""
|
||||
return self._move_lines_subset(controlling_date, 'account.invoice',
|
||||
'invoice')
|
||||
'invoice_id')
|
||||
|
||||
@api.multi
|
||||
@api.returns('account.move.line')
|
||||
@@ -177,8 +161,7 @@ class CreditControlPolicy(models.Model):
|
||||
existing credit line but with a different policy.
|
||||
"""
|
||||
self.ensure_one()
|
||||
move_line_obj = self.env['account.move.line']
|
||||
different_lines = move_line_obj.browse()
|
||||
different_lines = self.env['account.move.line']
|
||||
if not lines:
|
||||
return different_lines
|
||||
cr = self.env.cr
|
||||
@@ -188,7 +171,7 @@ class CreditControlPolicy(models.Model):
|
||||
(self.id, tuple(lines.ids)))
|
||||
res = cr.fetchall()
|
||||
if res:
|
||||
return move_line_obj.browse([row[0] for row in res])
|
||||
return different_lines.browse([row[0] for row in res])
|
||||
return different_lines
|
||||
|
||||
@api.multi
|
||||
@@ -199,7 +182,7 @@ class CreditControlPolicy(models.Model):
|
||||
if account in x.account_ids or x.do_nothing]
|
||||
if self not in allowed:
|
||||
allowed_names = u"\n".join(x.name for x in allowed)
|
||||
raise api.Warning(
|
||||
raise UserError(
|
||||
_('You can only use a policy set on '
|
||||
'account %s.\n'
|
||||
'Please choose one of the following '
|
||||
@@ -229,7 +212,7 @@ class CreditControlPolicyLevel(models.Model):
|
||||
required=True
|
||||
)
|
||||
delay_days = fields.Integer(string='Delay (in days)', required=True)
|
||||
email_template_id = fields.Many2one('email.template',
|
||||
email_template_id = fields.Many2one('mail.template',
|
||||
string='Email Template',
|
||||
required=True)
|
||||
channel = fields.Selection([('letter', 'Letter'),
|
||||
@@ -246,17 +229,20 @@ class CreditControlPolicyLevel(models.Model):
|
||||
'UNIQUE (policy_id, level)',
|
||||
'Level must be unique per policy')]
|
||||
|
||||
@api.one
|
||||
@api.multi
|
||||
@api.constrains('level', 'computation_mode')
|
||||
def _check_level_mode(self):
|
||||
""" The smallest level of a policy cannot be computed on the
|
||||
"previous_date".
|
||||
"""
|
||||
smallest_level = self.search([('policy_id', '=', self.policy_id.id)],
|
||||
order='level asc', limit=1)
|
||||
if smallest_level.computation_mode == 'previous_date':
|
||||
return api.ValidationError(_('The smallest level can not be of '
|
||||
'type Previous Reminder'))
|
||||
|
||||
for policy_level in self:
|
||||
smallest_level = \
|
||||
self.search([('policy_id', '=', policy_level.policy_id.id)],
|
||||
order='level asc', limit=1)
|
||||
if smallest_level.computation_mode == 'previous_date':
|
||||
raise ValidationError(_('The smallest level can not be '
|
||||
'of type Previous Reminder'))
|
||||
|
||||
@api.multi
|
||||
def _previous_level(self):
|
||||
@@ -294,7 +280,7 @@ class CreditControlPolicyLevel(models.Model):
|
||||
return "(cr_line.date + %(delay)s)::date <= date(%(controlling_date)s)"
|
||||
|
||||
@api.multi
|
||||
def _get_sql_date_boundary_for_computation_mode(self, controlling_date):
|
||||
def _get_sql_date_boundary_for_computation_mode(self):
|
||||
""" Return a where clauses statement for the given controlling
|
||||
date and computation mode of the level
|
||||
"""
|
||||
@@ -321,7 +307,7 @@ class CreditControlPolicyLevel(models.Model):
|
||||
self.ensure_one()
|
||||
move_line_obj = self.env['account.move.line']
|
||||
if not lines:
|
||||
return move_line_obj.browse()
|
||||
return move_line_obj
|
||||
cr = self.env.cr
|
||||
sql = ("SELECT DISTINCT mv_line.id\n"
|
||||
" FROM account_move_line mv_line\n"
|
||||
@@ -337,7 +323,7 @@ class CreditControlPolicyLevel(models.Model):
|
||||
" AND (mv_line.debit IS NOT NULL AND mv_line.debit != 0.0)\n")
|
||||
sql += " AND"
|
||||
_get_sql_date_part = self._get_sql_date_boundary_for_computation_mode
|
||||
sql += _get_sql_date_part(controlling_date)
|
||||
sql += _get_sql_date_part()
|
||||
data_dict = {'controlling_date': controlling_date,
|
||||
'line_ids': tuple(lines.ids),
|
||||
'delay': self.delay_days}
|
||||
@@ -345,7 +331,7 @@ class CreditControlPolicyLevel(models.Model):
|
||||
res = cr.fetchall()
|
||||
if res:
|
||||
return move_line_obj.browse([row[0] for row in res])
|
||||
return move_line_obj.browse()
|
||||
return move_line_obj
|
||||
|
||||
@api.multi
|
||||
@api.returns('account.move.line')
|
||||
@@ -355,7 +341,7 @@ class CreditControlPolicyLevel(models.Model):
|
||||
self.ensure_one()
|
||||
move_line_obj = self.env['account.move.line']
|
||||
if not lines:
|
||||
return move_line_obj.browse()
|
||||
return move_line_obj
|
||||
cr = self.env.cr
|
||||
sql = ("SELECT mv_line.id\n"
|
||||
" FROM account_move_line mv_line\n"
|
||||
@@ -377,7 +363,7 @@ class CreditControlPolicyLevel(models.Model):
|
||||
" AND mv_line.id in %(line_ids)s\n")
|
||||
sql += " AND "
|
||||
_get_sql_date_part = self._get_sql_date_boundary_for_computation_mode
|
||||
sql += _get_sql_date_part(controlling_date)
|
||||
sql += _get_sql_date_part()
|
||||
previous_level = self._previous_level()
|
||||
data_dict = {'controlling_date': controlling_date,
|
||||
'line_ids': tuple(lines.ids),
|
||||
@@ -389,15 +375,14 @@ class CreditControlPolicyLevel(models.Model):
|
||||
res = cr.fetchall()
|
||||
if res:
|
||||
return move_line_obj.browse([row[0] for row in res])
|
||||
return move_line_obj.browse()
|
||||
return move_line_obj
|
||||
|
||||
@api.multi
|
||||
@api.returns('account.move.line')
|
||||
def get_level_lines(self, controlling_date, lines):
|
||||
""" get all move lines in entry lines that match the current level """
|
||||
self.ensure_one()
|
||||
move_line_obj = self.env['account.move.line']
|
||||
matching_lines = move_line_obj.browse()
|
||||
matching_lines = self.env['account.move.line']
|
||||
if self._previous_level() is None:
|
||||
method = self._get_first_level_move_lines
|
||||
else:
|
||||
@@ -1,28 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
logger = logging.getLogger('credit.control.run')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CreditControlRun(models.Model):
|
||||
@@ -74,7 +59,7 @@ class CreditControlRun(models.Model):
|
||||
copy=False,
|
||||
)
|
||||
|
||||
@api.multi
|
||||
@api.model
|
||||
def _check_run_date(self, controlling_date):
|
||||
""" Ensure that there is no credit line in the future
|
||||
using controlling_date
|
||||
@@ -83,33 +68,31 @@ class CreditControlRun(models.Model):
|
||||
runs = self.search([('date', '>', controlling_date)],
|
||||
order='date DESC', limit=1)
|
||||
if runs:
|
||||
raise api.Warning(_('A run has already been executed more '
|
||||
'recently than %s') % (runs.date))
|
||||
raise UserError(_('A run has already been executed more '
|
||||
'recently than %s') % (runs.date))
|
||||
|
||||
line_obj = self.env['credit.control.line']
|
||||
lines = line_obj.search([('date', '>', controlling_date)],
|
||||
order='date DESC', limit=1)
|
||||
if lines:
|
||||
raise api.Warning(_('A credit control line more '
|
||||
'recent than %s exists at %s') %
|
||||
(controlling_date, lines.date))
|
||||
raise UserError(_('A credit control line more '
|
||||
'recent than %s exists at %s') %
|
||||
(controlling_date, lines.date))
|
||||
|
||||
@api.multi
|
||||
@api.returns('credit.control.line')
|
||||
def _generate_credit_lines(self):
|
||||
""" Generate credit control lines. """
|
||||
self.ensure_one()
|
||||
cr_line_obj = self.env['credit.control.line']
|
||||
move_line_obj = self.env['account.move.line']
|
||||
manually_managed_lines = move_line_obj.browse()
|
||||
manually_managed_lines = self.env['account.move.line']
|
||||
self._check_run_date(self.date)
|
||||
|
||||
policies = self.policy_ids
|
||||
if not policies:
|
||||
raise api.Warning(_('Please select a policy'))
|
||||
raise UserError(_('Please select a policy'))
|
||||
|
||||
report = ''
|
||||
generated = cr_line_obj.browse()
|
||||
generated = self.env['credit.control.line']
|
||||
for policy in policies:
|
||||
if policy.do_nothing:
|
||||
continue
|
||||
@@ -117,11 +100,11 @@ class CreditControlRun(models.Model):
|
||||
manual_lines = policy._lines_different_policy(lines)
|
||||
lines -= manual_lines
|
||||
manually_managed_lines |= manual_lines
|
||||
policy_lines_generated = cr_line_obj.browse()
|
||||
policy_lines_generated = self.env['credit.control.line']
|
||||
if lines:
|
||||
# policy levels are sorted by level
|
||||
# so iteration is in the correct order
|
||||
create = cr_line_obj.create_or_update_from_mv_lines
|
||||
create = policy_lines_generated.create_or_update_from_mv_lines
|
||||
for level in reversed(policy.level_ids):
|
||||
level_lines = level.get_level_lines(self.date, lines)
|
||||
policy_lines_generated += create(level_lines,
|
||||
@@ -158,8 +141,8 @@ class CreditControlRun(models.Model):
|
||||
except Exception:
|
||||
# In case of exception openerp will do a rollback
|
||||
# for us and free the lock
|
||||
raise api.Warning(_('A credit control run is already running'
|
||||
' in background, please try later.'))
|
||||
raise UserError(_('A credit control run is already running '
|
||||
'in background, please try later.'))
|
||||
|
||||
self._generate_credit_lines()
|
||||
return True
|
||||
13
account_credit_control/models/mail_mail.py
Normal file
13
account_credit_control/models/mail_mail.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class Mail(models.Model):
|
||||
_inherit = 'mail.mail'
|
||||
|
||||
# use HTML fields instead of text
|
||||
body_html = fields.Html('Rich-text Contents',
|
||||
help="Rich-text/HTML message")
|
||||
21
account_credit_control/models/res_company.py
Normal file
21
account_credit_control/models/res_company.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
""" Add credit control parameters """
|
||||
_inherit = 'res.company'
|
||||
|
||||
credit_control_tolerance = fields.Float(string='Credit Control Tolerance',
|
||||
default=0.1)
|
||||
# This is not a property on the partner because we cannot search
|
||||
# on fields.property (subclass fields.function).
|
||||
credit_policy_id = fields.Many2one('credit.control.policy',
|
||||
string='Credit Control Policy',
|
||||
help="The Credit Control Policy used "
|
||||
"on partners by default. "
|
||||
"This setting can be overridden"
|
||||
" on partners or invoices.")
|
||||
@@ -1,25 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields, api
|
||||
from openerp.exceptions import Warning, ValidationError
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import api, fields, models
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
@@ -32,7 +16,7 @@ class ResPartner(models.Model):
|
||||
credit_policy_id = fields.Many2one(
|
||||
'credit.control.policy',
|
||||
string='Credit Control Policy',
|
||||
domain="[('account_ids', 'in', property_account_receivable)]",
|
||||
domain="[('account_ids', 'in', property_account_receivable_id)]",
|
||||
help="The Credit Control Policy used for this "
|
||||
"partner. This setting can be forced on the "
|
||||
"invoice. If nothing is defined, it will use "
|
||||
@@ -43,17 +27,17 @@ class ResPartner(models.Model):
|
||||
string='Credit Control Lines',
|
||||
readonly=True)
|
||||
|
||||
@api.constrains('credit_policy_id', 'property_account_receivable')
|
||||
@api.constrains('credit_policy_id', 'property_account_receivable_id')
|
||||
def _check_credit_policy(self):
|
||||
""" Ensure that policy on partner are limited to the account policy """
|
||||
for partner in self:
|
||||
if (not partner.property_account_receivable or
|
||||
if (not partner.property_account_receivable_id or
|
||||
not partner.credit_policy_id):
|
||||
continue
|
||||
account = partner.property_account_receivable
|
||||
account = partner.property_account_receivable_id
|
||||
policy = partner.credit_policy_id
|
||||
try:
|
||||
policy.check_policy_against_account(account)
|
||||
except Warning as err:
|
||||
except UserError as err:
|
||||
# constrains should raise ValidationError exceptions
|
||||
raise ValidationError(err)
|
||||
@@ -1,24 +0,0 @@
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="partner_followup_form_view" model="ir.ui.view">
|
||||
<field name="name">partner.credit_control.form.view</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="account.view_partner_property_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="credit_limit" position="after">
|
||||
<field name="credit_policy_id" widget="selection"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_use"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window
|
||||
id="act_partner_credit_relation_relation"
|
||||
name="Credit Lines"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user"
|
||||
domain="[('partner_id', '=', active_id)]"
|
||||
res_model="credit.control.line"
|
||||
src_model="res.partner"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,131 +0,0 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="credit_control_policy_form" model="ir.ui.view">
|
||||
<field name="name">credit.control.policy.form</field>
|
||||
<field name="model">credit.control.policy</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Credit control policy">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="do_nothing"/>
|
||||
<field name="company_id"/>
|
||||
<field name="active"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Policy levels">
|
||||
<field name="level_ids" nolabel="1" colspan="4" >
|
||||
<tree string="Credit control policy Level">
|
||||
<field name="name"/>
|
||||
<field name="level"/>
|
||||
<field name="channel"/>
|
||||
<field name="delay_days"/>
|
||||
<field name="computation_mode"/>
|
||||
<field name="email_template_id"/>
|
||||
</tree>
|
||||
<form string="Policy level">
|
||||
<field name="name"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Delay Setting">
|
||||
<group>
|
||||
<field name="level"/>
|
||||
<field name="channel"/>
|
||||
<field name="delay_days"/>
|
||||
<field name="computation_mode"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Mail and reporting">
|
||||
<group>
|
||||
<field name="email_template_id"/>
|
||||
<newline/>
|
||||
<field name="custom_text" colspan="4"/>
|
||||
<newline/>
|
||||
<field name="custom_mail_text" colspan="4"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Accounts">
|
||||
<field name="account_ids" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_policy_tree" model="ir.ui.view">
|
||||
<field name="name">credit.control.policy.tree</field>
|
||||
<field name="model">credit.control.policy</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Credit control policy">
|
||||
<field name="name"/>
|
||||
<field name="do_nothing"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Credit Control"
|
||||
parent="account.menu_finance_configuration"
|
||||
id="base_credit_control_configuration_menu"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="credit_policy_configuration_action">
|
||||
<field name="name">Credit Control Policies</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">credit.control.policy</field>
|
||||
<field name="domain"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="credit_control_policy_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Credit Control Policies"
|
||||
parent="base_credit_control_configuration_menu"
|
||||
action="credit_policy_configuration_action"
|
||||
id="credit_policy_configuration_action_menu"/>
|
||||
|
||||
<record id="credit_mangement_policy_level_form" model="ir.ui.view">
|
||||
<field name="name">credit.mangement.policy.level.form</field>
|
||||
<field name="model">credit.control.policy.level</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Policy level">
|
||||
<field name="name"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Delay Setting">
|
||||
<group>
|
||||
<field name="level"/>
|
||||
<field name="channel"/>
|
||||
<field name="delay_days"/>
|
||||
<field name="computation_mode"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Mail and reporting">
|
||||
<group>
|
||||
<field name="email_template_id"/>
|
||||
<field name="custom_text"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_policy_level_tree" model="ir.ui.view">
|
||||
<field name="name">credit.control.policy.level.tree</field>
|
||||
<field name="model">credit.control.policy.level</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Credit control policy level">
|
||||
<field name="name"/>
|
||||
<field name="level"/>
|
||||
<field name="channel"/>
|
||||
<field name="delay_days"/>
|
||||
<field name="computation_mode"/>
|
||||
<field name="email_template_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,15 +1,12 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<report
|
||||
id="credit_control_summary"
|
||||
model="credit.control.communication"
|
||||
string="Credit Control Summary"
|
||||
report_type="qweb-pdf"
|
||||
name="account_credit_control.report_credit_control_summary"
|
||||
file="account_credit_control.report_credit_control_summary"
|
||||
auto="False"
|
||||
/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
id="credit_control_summary"
|
||||
model="credit.control.communication"
|
||||
string="Credit Control Summary"
|
||||
report_type="qweb-pdf"
|
||||
name="account_credit_control.report_credit_control_summary"
|
||||
file="account_credit_control.report_credit_control_summary"
|
||||
auto="False"
|
||||
/>
|
||||
</odoo>
|
||||
|
||||
@@ -1,99 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="report_credit_control_summary_document">
|
||||
<t t-call="report.external_layout">
|
||||
<div class="page">
|
||||
<div class="row" id="address">
|
||||
<div class="col-xs-5 col-xs-offset-7">
|
||||
<address t-field="o.contact_address"
|
||||
t-field-options='{"widget": "contact",
|
||||
<t t-call="report.external_layout">
|
||||
<div class="page">
|
||||
<div class="row" id="address">
|
||||
<div class="col-xs-5 col-xs-offset-7">
|
||||
<address t-field="doc.contact_address"
|
||||
t-field-options='{"widget": "contact",
|
||||
"fields": ["address", "name"],
|
||||
"no_marker": true}' />
|
||||
"no_marker": true}'/>
|
||||
</div>
|
||||
<div class="col-xs-5 col-xs-offset-7">
|
||||
<span t-field="doc.report_date"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="policy_level">
|
||||
<span t-field="doc.current_policy_level.name"/>
|
||||
</h2>
|
||||
|
||||
<div class="col-xs-12">
|
||||
<span t-field="doc.current_policy_level.custom_text" />
|
||||
</div>
|
||||
|
||||
<h3>Summary</h3>
|
||||
|
||||
<table class="table table-condensed" id="summary_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Invoice number</th>
|
||||
<th>Invoice date</th>
|
||||
<th>Date due</th>
|
||||
<th class="text-right">Invoiced amount</th>
|
||||
<th class="text-right">Open amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="doc.credit_control_line_ids" t-as="l">
|
||||
<t t-if="l.invoice_id">
|
||||
<td>
|
||||
<span t-field="l.invoice_id.number"/>
|
||||
<t t-if="l.invoice_id.name">
|
||||
<span t-field="l.invoice_id.name"/>
|
||||
</t>
|
||||
</td>
|
||||
</t>
|
||||
<t t-if="not l.invoice_id">
|
||||
<td>
|
||||
<span t-field="l.move_line_id.name"/>
|
||||
</td>
|
||||
</t>
|
||||
<td>
|
||||
<span t-field="l.date_entry"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="l.date_due"/>
|
||||
</td>
|
||||
|
||||
<td class="text-right">
|
||||
<span t-field="l.amount_due"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-field="l.balance_due"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-4 pull-right">
|
||||
<table class="table table-condensed">
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Total Invoiced</strong>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-field="doc.total_invoiced" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Total Due</strong>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-field="doc.total_due"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-xs-5 col-xs-offset-7">
|
||||
<span t-field="o.report_date"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="policy_level">
|
||||
<span t-field="o.current_policy_level.name"/>
|
||||
</h2>
|
||||
|
||||
<p class="mt32 mb32" t-field="o.current_policy_level.custom_text"/>
|
||||
|
||||
<h3>Summary</h3>
|
||||
|
||||
<table class="table table-condensed" id="summary_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Invoice number</th>
|
||||
<th>Invoice date</th>
|
||||
<th>Date due</th>
|
||||
<th class="text-right">Invoiced amount</th>
|
||||
<th class="text-right">Open amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="o.credit_control_line_ids" t-as="l">
|
||||
<t t-if="l.invoice_id">
|
||||
<td><span t-field="l.invoice_id.number"/>
|
||||
<t t-if="l.invoice_id.name">
|
||||
<span t-field="l.invoice_id.name"/>
|
||||
</t>
|
||||
</td>
|
||||
</t>
|
||||
<t t-if="not l.invoice_id">
|
||||
<td><span t-field="l.move_line_id.name"/></td>
|
||||
</t>
|
||||
<td>
|
||||
<span t-field="l.date_entry"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="l.date_due"/>
|
||||
</td>
|
||||
|
||||
<td class="text-right">
|
||||
<span t-field="l.amount_due"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-field="l.balance_due"
|
||||
t-field-options='{"widget": "monetary",
|
||||
"display_currency": "l.currency_id or l.company_id.currency_id"}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-4 pull-right">
|
||||
<table class="table table-condensed">
|
||||
<tr>
|
||||
<td><strong>Total Invoiced</strong></td>
|
||||
<td class="text-right">
|
||||
<span t-field="o.total_invoiced" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Total Due</strong></td>
|
||||
<td class="text-right">
|
||||
<span t-field="o.total_due" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="report_credit_control_summary">
|
||||
<t t-call="report.html_container">
|
||||
<t t-foreach="doc_ids" t-as="doc_id">
|
||||
<t t-raw="translate_doc(doc_id, doc_model, 'partner_id.lang', 'account_credit_control.report_credit_control_summary_document')"/>
|
||||
<t t-call="report.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="account_credit_control.report_credit_control_summary_document" t-lang="doc.partner_id.lang" />
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="credit_control_run_tree" model="ir.ui.view">
|
||||
<field name="name">credit.control.run.tree</field>
|
||||
<field name="model">credit.control.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Credit control run">
|
||||
<field name="date"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_run_form" model="ir.ui.view">
|
||||
<field name="name">credit.control.run.form</field>
|
||||
<field name="model">credit.control.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Credit control run">
|
||||
<header>
|
||||
<button name="generate_credit_lines"
|
||||
string="Compute Credit Control Lines"
|
||||
class="oe_highlight"
|
||||
type="object" icon="gtk-execute"
|
||||
attrs="{'invisible': [('state', '!=', 'draft')]}"/>
|
||||
<button name="open_credit_lines"
|
||||
string="Open Credit Control Lines"
|
||||
type="object"
|
||||
attrs="{'invisible': [('state', '=', 'draft')]}"/>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="draft,done"
|
||||
statusbar_colors='{}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="date"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Policies">
|
||||
<field name="policy_ids" colspan="4" nolabel="1"/>
|
||||
<separator string="Report"
|
||||
attrs="{'invisible': [('report', '=', False)]}"/>
|
||||
<field name="report" colspan="4" nolabel="1"
|
||||
attrs="{'invisible': [('report', '=', False)]}"/>
|
||||
</page>
|
||||
<page string="Manual Lines" groups="base.group_no_one">
|
||||
<field name="manual_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.actions.act_window" id="credit_control_run">
|
||||
<field name="name">Credit Control Run</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">credit.control.run</field>
|
||||
<field name="domain"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="credit_control_run_tree"/>
|
||||
</record>
|
||||
|
||||
|
||||
<menuitem
|
||||
name="Credit Control Run"
|
||||
parent="base_credit_control_menu"
|
||||
action="credit_control_run"
|
||||
sequence="10"
|
||||
id="credit_control_run_menu"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,20 +1,20 @@
|
||||
"id","perm_create","perm_unlink","group_id/id","name","model_id/id","perm_read","perm_write"
|
||||
"account_credit_control.ir_model_access_270",1,1,"group_account_credit_control_manager","credit_control_manager_line","account_credit_control.model_credit_control_line",1,1
|
||||
"account_credit_control.ir_model_access_271",1,1,"group_account_credit_control_user","credit_control_user_line","account_credit_control.model_credit_control_line",1,1
|
||||
"account_credit_control.ir_model_access_272",0,0,"group_account_credit_control_info","credit_control_info_line","account_credit_control.model_credit_control_line",1,0
|
||||
"account_credit_control.ir_model_access_273",1,1,"group_account_credit_control_manager","credit_control_manager_mail_template","email_template.model_email_template",1,1
|
||||
"account_credit_control.ir_model_access_275",1,1,"group_account_credit_control_manager","credit_control_manager_mail_message","mail.model_mail_message",1,1
|
||||
"account_credit_control.ir_model_access_276",1,0,"group_account_credit_control_user","credit_control_user_mail_message","mail.model_mail_message",1,1
|
||||
"account_credit_control.ir_model_access_277",0,0,"group_account_credit_control_info","credit_control_info_mail_message","mail.model_mail_message",1,0
|
||||
"account_credit_control.ir_model_access_281",1,1,"group_account_credit_control_manager","credit_control_mananger_run","account_credit_control.model_credit_control_run",1,1
|
||||
"account_credit_control.ir_model_access_282",1,1,"group_account_credit_control_user","credit_control_user_run","account_credit_control.model_credit_control_run",1,1
|
||||
"account_credit_control.ir_model_access_283",0,0,"group_account_credit_control_info","credit_control_info_run","account_credit_control.model_credit_control_run",1,0
|
||||
"account_credit_control.ir_model_access_284",1,1,"group_account_credit_control_manager","credit_control_manager_policy","account_credit_control.model_credit_control_policy",1,1
|
||||
"account_credit_control.ir_model_access_285",0,0,"group_account_credit_control_user","credit_control_user_policy","account_credit_control.model_credit_control_policy",1,0
|
||||
"account_credit_control.ir_model_access_286",0,0,"group_account_credit_control_info","credit_control_info_policy","account_credit_control.model_credit_control_policy",1,0
|
||||
"account_credit_control.ir_model_access_287",1,1,"group_account_credit_control_manager","credit_control_manager_level","account_credit_control.model_credit_control_policy_level",1,1
|
||||
"account_credit_control.ir_model_access_288",0,0,"group_account_credit_control_user","credit_control_user_level","account_credit_control.model_credit_control_policy_level",1,0
|
||||
"account_credit_control.ir_model_access_289",0,0,"group_account_credit_control_info","credit_control_info_level","account_credit_control.model_credit_control_policy_level",1,0
|
||||
"account_credit_control.ir_model_access_290",0,0,"account.group_account_user","credit_control_fin_user_line","account_credit_control.model_credit_control_line",1,0
|
||||
"account_credit_control.ir_model_access_291",0,0,"account.group_account_invoice","credit_control_fin_invoice_line","account_credit_control.model_credit_control_line",1,0
|
||||
"account_credit_control.ir_model_access_292",1,1,"account.group_account_manager","credit_control_fin_manager_line","account_credit_control.model_credit_control_line",1,1
|
||||
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
|
||||
account_credit_control.ir_model_access_270,credit_control_manager_line,account_credit_control.model_credit_control_line,group_account_credit_control_manager,1,1,1,1
|
||||
account_credit_control.ir_model_access_271,credit_control_user_line,account_credit_control.model_credit_control_line,group_account_credit_control_user,1,1,1,1
|
||||
account_credit_control.ir_model_access_272,credit_control_info_line,account_credit_control.model_credit_control_line,group_account_credit_control_info,1,0,0,0
|
||||
account_credit_control.ir_model_access_273,credit_control_manager_mail_template,mail.model_mail_template,group_account_credit_control_manager,1,1,1,1
|
||||
account_credit_control.ir_model_access_275,credit_control_manager_mail_message,mail.model_mail_message,group_account_credit_control_manager,1,1,1,1
|
||||
account_credit_control.ir_model_access_276,credit_control_user_mail_message,mail.model_mail_message,group_account_credit_control_user,1,1,1,0
|
||||
account_credit_control.ir_model_access_277,credit_control_info_mail_message,mail.model_mail_message,group_account_credit_control_info,1,0,0,0
|
||||
account_credit_control.ir_model_access_281,credit_control_mananger_run,account_credit_control.model_credit_control_run,group_account_credit_control_manager,1,1,1,1
|
||||
account_credit_control.ir_model_access_282,credit_control_user_run,account_credit_control.model_credit_control_run,group_account_credit_control_user,1,1,1,1
|
||||
account_credit_control.ir_model_access_283,credit_control_info_run,account_credit_control.model_credit_control_run,group_account_credit_control_info,1,0,0,0
|
||||
account_credit_control.ir_model_access_284,credit_control_manager_policy,account_credit_control.model_credit_control_policy,group_account_credit_control_manager,1,1,1,1
|
||||
account_credit_control.ir_model_access_285,credit_control_user_policy,account_credit_control.model_credit_control_policy,group_account_credit_control_user,1,0,0,0
|
||||
account_credit_control.ir_model_access_286,credit_control_info_policy,account_credit_control.model_credit_control_policy,group_account_credit_control_info,1,0,0,0
|
||||
account_credit_control.ir_model_access_287,credit_control_manager_level,account_credit_control.model_credit_control_policy_level,group_account_credit_control_manager,1,1,1,1
|
||||
account_credit_control.ir_model_access_288,credit_control_user_level,account_credit_control.model_credit_control_policy_level,group_account_credit_control_user,1,0,0,0
|
||||
account_credit_control.ir_model_access_289,credit_control_info_level,account_credit_control.model_credit_control_policy_level,group_account_credit_control_info,1,0,0,0
|
||||
account_credit_control.ir_model_access_290,credit_control_fin_user_line,account_credit_control.model_credit_control_line,account.group_account_user,1,0,0,0
|
||||
account_credit_control.ir_model_access_291,credit_control_fin_invoice_line,account_credit_control.model_credit_control_line,account.group_account_invoice,1,0,0,0
|
||||
account_credit_control.ir_model_access_292,credit_control_fin_manager_line,account_credit_control.model_credit_control_line,account.group_account_manager,1,1,1,1
|
||||
|
||||
|
25
account_credit_control/security/res_groups.xml
Normal file
25
account_credit_control/security/res_groups.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="category_credit_control" model="ir.module.category">
|
||||
<field name="name">Credit Control</field>
|
||||
<field name="sequence" eval="99" />
|
||||
</record>
|
||||
|
||||
<record id="group_account_credit_control_info" model="res.groups" context="{'noadmin':True}">
|
||||
<field name="name">Info</field>
|
||||
<field name="category_id" ref="category_credit_control"/>
|
||||
</record>
|
||||
|
||||
<record id="group_account_credit_control_user" model="res.groups" context="{'noadmin':True}">
|
||||
<field name="name">User</field>
|
||||
<field name="category_id" ref="category_credit_control"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_account_credit_control_info'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="group_account_credit_control_manager" model="res.groups">
|
||||
<field name="name">Manager</field>
|
||||
<field name="category_id" ref="category_credit_control"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_account_credit_control_user'))]"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
7
account_credit_control/tests/__init__.py
Normal file
7
account_credit_control/tests/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from . import test_credit_control_policy
|
||||
from . import test_res_partner
|
||||
from . import test_account_invoice
|
||||
from . import test_credit_control_run
|
||||
111
account_credit_control/tests/test_account_invoice.py
Normal file
111
account_credit_control/tests/test_account_invoice.py
Normal file
@@ -0,0 +1,111 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from datetime import datetime
|
||||
from dateutil import relativedelta
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class TestAccountInvoice(TransactionCase):
|
||||
post_install = True
|
||||
at_install = False
|
||||
|
||||
def test_action_cancel(self):
|
||||
"""
|
||||
Test the method action_cancel on invoice
|
||||
We will create an old invoice, generate a control run
|
||||
and check if I can unlink this invoice
|
||||
:return:
|
||||
"""
|
||||
journal = self.env['account.invoice']._default_journal()
|
||||
|
||||
account_type_rec = self.env.ref('account.data_account_type_receivable')
|
||||
account = self.env['account.account'].create({
|
||||
'code': '400001',
|
||||
'name': 'Clients (test)',
|
||||
'user_type_id': account_type_rec.id,
|
||||
'reconcile': True,
|
||||
})
|
||||
|
||||
tag_operation = self.env.ref('account.account_tag_operating')
|
||||
account_type_inc = self.env.ref('account.data_account_type_revenue')
|
||||
analytic_account = self.env['account.account'].create({
|
||||
'code': '701001',
|
||||
'name': 'Ventes en Belgique (test)',
|
||||
'user_type_id': account_type_inc.id,
|
||||
'reconcile': True,
|
||||
'tag_ids': [(6, 0, [tag_operation.id])]
|
||||
})
|
||||
payment_term = self.env.ref('account.account_payment_term_immediate')
|
||||
|
||||
product = self.env['product.product'].create({
|
||||
'name': 'Product test'
|
||||
})
|
||||
|
||||
policy = self.env.ref('account_credit_control.credit_control_3_time')
|
||||
policy.write({
|
||||
'account_ids': [(6, 0, [account.id])]
|
||||
})
|
||||
|
||||
# There is a bug with Odoo ...
|
||||
# The field "credit_policy_id" is considered as an "old field" and
|
||||
# the field property_account_receivable_id like a "new field"
|
||||
# The ORM will create the record with old field
|
||||
# and update the record with new fields.
|
||||
# However constrains are applied after the first creation.
|
||||
partner = self.env['res.partner'].create({
|
||||
'name': 'Partner',
|
||||
'property_account_receivable_id': account.id,
|
||||
})
|
||||
partner.credit_policy_id = policy.id
|
||||
|
||||
date_invoice = datetime.today() - relativedelta.relativedelta(years=1)
|
||||
invoice = self.env['account.invoice'].create({
|
||||
'partner_id': partner.id,
|
||||
'journal_id': journal.id,
|
||||
'type': 'out_invoice',
|
||||
'payment_term_id': payment_term.id,
|
||||
'date_invoice': fields.Datetime.to_string(date_invoice),
|
||||
'date_due': fields.Datetime.to_string(date_invoice),
|
||||
})
|
||||
|
||||
invoice.invoice_line_ids.create({
|
||||
'invoice_id': invoice.id,
|
||||
'product_id': product.id,
|
||||
'name': product.name,
|
||||
'account_id': analytic_account.id,
|
||||
'quantity': 5,
|
||||
'price_unit': 100,
|
||||
})
|
||||
|
||||
# Validate the invoice
|
||||
invoice.action_invoice_open()
|
||||
|
||||
control_run = self.env['credit.control.run'].create({
|
||||
'date': fields.Date.today(),
|
||||
'policy_ids': [(6, 0, [policy.id])]
|
||||
})
|
||||
control_run.generate_credit_lines()
|
||||
|
||||
self.assertTrue(len(invoice.credit_control_line_ids), 1)
|
||||
control_line = invoice.credit_control_line_ids
|
||||
|
||||
control_marker = self.env['credit.control.marker']
|
||||
marker_line = control_marker\
|
||||
.with_context(active_model='credit.control.line',
|
||||
active_ids=[control_line.id])\
|
||||
._get_line_ids()
|
||||
|
||||
self.assertIn(control_line, marker_line)
|
||||
|
||||
marker = self.env['credit.control.marker'].create({
|
||||
'name': 'to_be_sent',
|
||||
'line_ids': [(6, 0, [control_line.id])]
|
||||
})
|
||||
marker.mark_lines()
|
||||
|
||||
with self.assertRaises(UserError):
|
||||
invoice.unlink()
|
||||
89
account_credit_control/tests/test_credit_control_policy.py
Normal file
89
account_credit_control/tests/test_credit_control_policy.py
Normal file
@@ -0,0 +1,89 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestCreditControlPolicy(TransactionCase):
|
||||
post_install = True
|
||||
at_install = False
|
||||
|
||||
def test_check_policy_against_account(self):
|
||||
"""
|
||||
Test the model check_policy_against_account with several case
|
||||
:return:
|
||||
"""
|
||||
policy = self.env.ref('account_credit_control.credit_control_3_time')
|
||||
|
||||
account_type = self.env.ref('account.data_account_type_receivable')
|
||||
account = self.env['account.account'].create({
|
||||
'code': '400001',
|
||||
'name': 'Test',
|
||||
'user_type_id': account_type.id,
|
||||
'reconcile': True,
|
||||
})
|
||||
|
||||
# The account is not included in the policy
|
||||
with self.assertRaises(UserError):
|
||||
policy.check_policy_against_account(account)
|
||||
|
||||
# We set the flag "do_nothing" to True
|
||||
policy.write({
|
||||
'account_ids': [(5, 0)],
|
||||
'do_nothing': True,
|
||||
})
|
||||
result = policy.check_policy_against_account(account)
|
||||
self.assertTrue(result)
|
||||
|
||||
# We add the account in the policy
|
||||
policy.write({
|
||||
'account_ids': [(6, 0, [account.id])]
|
||||
})
|
||||
result = policy.check_policy_against_account(account)
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_check_level_mode(self):
|
||||
"""
|
||||
Check the method _check_level_mode on policy level
|
||||
:return:
|
||||
"""
|
||||
level_1 = self.env.ref('account_credit_control.3_time_1')
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
level_1.computation_mode = 'previous_date'
|
||||
|
||||
def test_previous_level(self):
|
||||
"""
|
||||
Check the method _previous_level on policy level
|
||||
:return:
|
||||
"""
|
||||
level_1 = self.env.ref('account_credit_control.3_time_1')
|
||||
level_2 = self.env.ref('account_credit_control.3_time_2')
|
||||
|
||||
previous_level = level_2._previous_level()
|
||||
self.assertEqual(previous_level, level_1)
|
||||
|
||||
def test_get_sql_date_boundary_for_computation_mode(self):
|
||||
"""
|
||||
Check the where clauses statement return by the method
|
||||
_get_sql_date_boundary_for_computation_mode
|
||||
according the computation mode
|
||||
:return:
|
||||
"""
|
||||
level_2 = self.env.ref('account_credit_control.3_time_2')
|
||||
|
||||
level_2.computation_mode = 'net_days'
|
||||
where_clause = level_2._net_days_get_boundary()
|
||||
result = level_2._get_sql_date_boundary_for_computation_mode()
|
||||
self.assertEqual(result, where_clause)
|
||||
|
||||
level_2.computation_mode = 'end_of_month'
|
||||
where_clause = level_2._end_of_month_get_boundary()
|
||||
result = level_2._get_sql_date_boundary_for_computation_mode()
|
||||
self.assertEqual(result, where_clause)
|
||||
|
||||
level_2.computation_mode = 'previous_date'
|
||||
where_clause = level_2._previous_date_get_boundary()
|
||||
result = level_2._get_sql_date_boundary_for_computation_mode()
|
||||
self.assertEqual(result, where_clause)
|
||||
155
account_credit_control/tests/test_credit_control_run.py
Normal file
155
account_credit_control/tests/test_credit_control_run.py
Normal file
@@ -0,0 +1,155 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import re
|
||||
from datetime import datetime
|
||||
from dateutil import relativedelta
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class TestCreditControlRun(TransactionCase):
|
||||
post_install = True
|
||||
at_install = False
|
||||
|
||||
def setUp(self):
|
||||
super(TestCreditControlRun, self).setUp()
|
||||
|
||||
journal = self.env['account.invoice']._default_journal()
|
||||
|
||||
account_type_rec = self.env.ref('account.data_account_type_receivable')
|
||||
account = self.env['account.account'].create({
|
||||
'code': '400001',
|
||||
'name': 'Clients (test)',
|
||||
'user_type_id': account_type_rec.id,
|
||||
'reconcile': True,
|
||||
})
|
||||
|
||||
tag_operation = self.env.ref('account.account_tag_operating')
|
||||
account_type_inc = self.env.ref('account.data_account_type_revenue')
|
||||
analytic_account = self.env['account.account'].create({
|
||||
'code': '701001',
|
||||
'name': 'Ventes en Belgique (test)',
|
||||
'user_type_id': account_type_inc.id,
|
||||
'reconcile': True,
|
||||
'tag_ids': [(6, 0, [tag_operation.id])]
|
||||
})
|
||||
payment_term = self.env.ref('account.account_payment_term_immediate')
|
||||
|
||||
product = self.env['product.product'].create({
|
||||
'name': 'Product test'
|
||||
})
|
||||
|
||||
self.policy = \
|
||||
self.env.ref('account_credit_control.credit_control_3_time')
|
||||
self.policy.write({
|
||||
'account_ids': [(6, 0, [account.id])]
|
||||
})
|
||||
|
||||
# There is a bug with Odoo ...
|
||||
# The field "credit_policy_id" is considered as an "old field" and
|
||||
# the field property_account_receivable_id like a "new field"
|
||||
# The ORM will create the record with old field
|
||||
# and update the record with new fields.
|
||||
# However constrains are applied after the first creation.
|
||||
partner = self.env['res.partner'].create({
|
||||
'name': 'Partner',
|
||||
'property_account_receivable_id': account.id,
|
||||
})
|
||||
partner.credit_policy_id = self.policy.id
|
||||
|
||||
date_invoice = datetime.today() - relativedelta.relativedelta(years=1)
|
||||
self.invoice = self.env['account.invoice'].create({
|
||||
'partner_id': partner.id,
|
||||
'journal_id': journal.id,
|
||||
'type': 'out_invoice',
|
||||
'payment_term_id': payment_term.id,
|
||||
'date_invoice': fields.Datetime.to_string(date_invoice),
|
||||
'date_due': fields.Datetime.to_string(date_invoice),
|
||||
})
|
||||
|
||||
self.invoice.invoice_line_ids.create({
|
||||
'invoice_id': self.invoice.id,
|
||||
'product_id': product.id,
|
||||
'name': product.name,
|
||||
'account_id': analytic_account.id,
|
||||
'quantity': 5,
|
||||
'price_unit': 100,
|
||||
})
|
||||
|
||||
# Validate the invoice
|
||||
self.invoice.action_invoice_open()
|
||||
|
||||
def test_check_run_date(self):
|
||||
"""
|
||||
Create a control run older than the last control run
|
||||
:return:
|
||||
"""
|
||||
control_run = self.env['credit.control.run'].create({
|
||||
'date': fields.Date.today(),
|
||||
'policy_ids': [(6, 0, [self.policy.id])]
|
||||
})
|
||||
|
||||
with self.assertRaises(UserError):
|
||||
today = datetime.today()
|
||||
previous_date = today - relativedelta.relativedelta(days=15)
|
||||
previous_date_str = fields.Date.to_string(previous_date)
|
||||
control_run._check_run_date(previous_date_str)
|
||||
|
||||
def test_generate_credit_lines(self):
|
||||
"""
|
||||
Test the method generate_credit_lines
|
||||
:return:
|
||||
"""
|
||||
control_run = self.env['credit.control.run'].create({
|
||||
'date': fields.Date.today(),
|
||||
'policy_ids': [(6, 0, [self.policy.id])]
|
||||
})
|
||||
|
||||
control_run.with_context(lang='en_US').generate_credit_lines()
|
||||
|
||||
self.assertTrue(len(self.invoice.credit_control_line_ids), 1)
|
||||
self.assertEqual(control_run.state, 'done')
|
||||
|
||||
report_regex = \
|
||||
r'<p>Policy "<b>%s</b>" has generated <b>' \
|
||||
r'\d+ Credit Control Lines.</b><br></p>' % self.policy.name
|
||||
regex_result = re.match(report_regex, control_run.report)
|
||||
self.assertIsNotNone(regex_result)
|
||||
|
||||
def test_multi_credit_control_run(self):
|
||||
"""
|
||||
Generate several control run
|
||||
:return:
|
||||
"""
|
||||
|
||||
six_months = datetime.today() - relativedelta.relativedelta(months=6)
|
||||
six_months_str = fields.Date.to_string(six_months)
|
||||
three_months = datetime.today() - relativedelta.relativedelta(months=2)
|
||||
three_months_str = fields.Date.to_string(three_months)
|
||||
|
||||
# First run
|
||||
first_control_run = self.env['credit.control.run'].create({
|
||||
'date': six_months_str,
|
||||
'policy_ids': [(6, 0, [self.policy.id])]
|
||||
})
|
||||
first_control_run.with_context(lang='en_US').generate_credit_lines()
|
||||
self.assertTrue(len(self.invoice.credit_control_line_ids), 1)
|
||||
|
||||
# Second run
|
||||
second_control_run = self.env['credit.control.run'].create({
|
||||
'date': three_months_str,
|
||||
'policy_ids': [(6, 0, [self.policy.id])]
|
||||
})
|
||||
second_control_run.with_context(lang='en_US').generate_credit_lines()
|
||||
self.assertTrue(len(self.invoice.credit_control_line_ids), 2)
|
||||
|
||||
# Last run
|
||||
last_control_run = self.env['credit.control.run'].create({
|
||||
'date': fields.Date.today(),
|
||||
'policy_ids': [(6, 0, [self.policy.id])]
|
||||
})
|
||||
last_control_run.with_context(lang='en_US').generate_credit_lines()
|
||||
self.assertTrue(len(self.invoice.credit_control_line_ids), 2)
|
||||
37
account_credit_control/tests/test_res_partner.py
Normal file
37
account_credit_control/tests/test_res_partner.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class TestCreditControlPolicyLevel(TransactionCase):
|
||||
post_install = True
|
||||
at_install = False
|
||||
|
||||
def test_check_credit_policy(self):
|
||||
"""
|
||||
Test the constrains on res.partner
|
||||
First we try to assign an account and a policy with a wrong policy
|
||||
(this policy doesn't contains the account of the partner).
|
||||
After that we add the previous account in the policy and
|
||||
retry to assign this policy and this account on the partner
|
||||
:return:
|
||||
"""
|
||||
policy = self.env.ref('account_credit_control.credit_control_3_time')
|
||||
|
||||
partner = self.env['res.partner'].create({
|
||||
'name': 'Partner 1',
|
||||
})
|
||||
account = partner.property_account_receivable_id
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
partner.write({
|
||||
'credit_policy_id': policy.id,
|
||||
})
|
||||
|
||||
policy.write({
|
||||
'account_ids': [(6, 0, [account.id])]
|
||||
})
|
||||
partner.property_account_receivable_id = account.id
|
||||
partner.credit_policy_id = policy.id
|
||||
44
account_credit_control/views/account_invoice.xml
Normal file
44
account_credit_control/views/account_invoice.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<act_window
|
||||
id="act_account_credit_relation_relation"
|
||||
name="Credit Lines"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user"
|
||||
domain="[('account_id', '=', active_id)]"
|
||||
res_model="credit.control.line"
|
||||
src_model="account.account"/>
|
||||
|
||||
<record id="invoice_followup_form_view" model="ir.ui.view">
|
||||
<field name="name">invoice.followup.form.view</field>
|
||||
<field name="model">account.invoice</field>
|
||||
<field name="inherit_id" ref="account.invoice_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page string="Credit Control"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user,account_credit_control.group_account_credit_control_info">
|
||||
<group>
|
||||
<field name="credit_policy_id"
|
||||
string="Manual Credit Control Policy"
|
||||
attrs="{'invisible': [('credit_policy_id', '=', False)]}"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user,account_credit_control.group_account_credit_control_info"/>
|
||||
</group>
|
||||
<separator string="Issued Lines" colspan="4"/>
|
||||
<field name="credit_control_line_ids" colspan="4"
|
||||
nolabel="1"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user,account_credit_control.group_account_credit_control_info">
|
||||
<tree string="Credit Control Lines">
|
||||
<field name="date"/>
|
||||
<field name="level"/>
|
||||
<field name="state"/>
|
||||
<field name="channel"/>
|
||||
<field name="balance_due"/>
|
||||
<field name="policy_level_id"/>
|
||||
<field name="policy_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
171
account_credit_control/views/credit_control_line.xml
Normal file
171
account_credit_control/views/credit_control_line.xml
Normal file
@@ -0,0 +1,171 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="credit_control_line_form" model="ir.ui.view">
|
||||
<field name="name">credit.control.line.form</field>
|
||||
<field name="model">credit.control.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Control Credit Lines">
|
||||
<header>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="draft,to_be_sent,sent"
|
||||
statusbar_colors='{"error":"red","email_error":"red"}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="partner_id"/>
|
||||
<field name="policy_level_id"/>
|
||||
<field name="policy_id"/>
|
||||
<field name="level"/>
|
||||
<field name="manually_overridden"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="date"/>
|
||||
<field name="date_due"/>
|
||||
<field name="channel"/>
|
||||
<field name="date_sent"/>
|
||||
<field name="mail_message_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="invoice_id"/>
|
||||
<field name="move_line_id"/>
|
||||
<field name="account_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="amount_due"/>
|
||||
<field name="balance_due"/>
|
||||
<field name="currency_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_line_search" model="ir.ui.view">
|
||||
<field name="name">Credit Control Lines</field>
|
||||
<field name="model">credit.control.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Control Credit Lines">
|
||||
<group>
|
||||
<field name="date"/>
|
||||
<field name="channel"/>
|
||||
<field name="policy_id"/>
|
||||
<separator />
|
||||
<field name="partner_id"/>
|
||||
<field name="account_id"/>
|
||||
<field name="invoice_id"/>
|
||||
<field name="level"/>
|
||||
<field name="policy_level_id"/>
|
||||
</group>
|
||||
|
||||
<group string="Filters" name="filters">
|
||||
<filter name="filter_draft" icon="fa-envelope"
|
||||
string="Draft" domain="[('state', '=', 'draft')]"
|
||||
help="Draft lines have to be triaged."/>
|
||||
<filter name="filter_to_be_sent" icon="fa-share"
|
||||
string="Ready To Send"
|
||||
domain="[('state', '=', 'to_be_sent')]"
|
||||
help="These lines are ready to send by email or by letter using the Actions."/>
|
||||
<filter name="filter_ignored" icon="fa-times"
|
||||
string="Ignored"
|
||||
domain="[('state', '=', 'ignored')]"
|
||||
help="Lines which have been ignored from previous runs."/>
|
||||
<filter name="filter_sent" icon="fa-paper-plane"
|
||||
string="Sent" domain="[('state', '=', 'sent')]"
|
||||
help="Lines already sent."/>
|
||||
<filter name="filter_error" icon="fa-exclamation-triangle"
|
||||
string="Error"
|
||||
domain="[('state', 'in', ('error', 'email_error'))]"
|
||||
help="An error has occured during the sending of the email."/>
|
||||
<filter name="filter_manual" icon="fa-hand-paper-o"
|
||||
string="Manual change"
|
||||
domain="[('manually_overridden', '=', True)]"
|
||||
help="The line was deprecated by a manual change of policy on invoice."/>
|
||||
</group>
|
||||
<group expand="0" string="Group By" name="group_by">
|
||||
<filter domain='[]' context="{'group_by': 'date'}"
|
||||
icon="terp-go-month" string="Run date"/>
|
||||
<filter domain='[]' context="{'group_by': 'level'}"
|
||||
icon="terp-gtk-jump-to-rtl" string="Level"/>
|
||||
<filter domain='[]' context="{'group_by': 'partner_id'}"
|
||||
icon="terp-partner" string="Partner"/>
|
||||
<filter domain='[]' context="{'group_by': 'account_id'}"
|
||||
icon="terp-folder-green" string="Account"/>
|
||||
<filter domain='[]' context="{'group_by': 'invoice_id'}"
|
||||
icon="terp-document-new" string="Invoice"/>
|
||||
<filter domain='[]' context="{'group_by': 'policy_id'}"
|
||||
icon="terp-document-new" string="Credit policy"/>
|
||||
<filter domain='[]'
|
||||
context="{'group_by': 'policy_level_id'}"
|
||||
icon="terp-document-new"
|
||||
string="Credit policy level"/>
|
||||
<filter domain='[]' context="{'group_by': 'channel'}"
|
||||
icon="terp-document-new" string="Channel"/>
|
||||
<filter domain='[]'
|
||||
context="{'group_by': 'manually_overridden'}"
|
||||
icon="terp-document-new" string="Manual change"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_line_tree" model="ir.ui.view">
|
||||
<field name="name">credit.control.line.tree</field>
|
||||
<field name="model">credit.control.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Control Credit Lines"
|
||||
colors="green:state == 'sent';red:state in ('error', 'email_error');">
|
||||
<field name="date"/>
|
||||
<field name="date_due"/>
|
||||
<field name="level"/>
|
||||
<field name="manually_overridden"/>
|
||||
<field name="state"/>
|
||||
<field name="channel"/>
|
||||
<field name="invoice_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="amount_due"/>
|
||||
<field name="balance_due"/>
|
||||
<field name="currency_id"/>
|
||||
<field name="move_line_id"/>
|
||||
<field name="account_id"/>
|
||||
<field name="policy_level_id"/>
|
||||
<field name="policy_id"/>
|
||||
<field name="mail_message_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Credit Control"
|
||||
parent="account.menu_finance_entries"
|
||||
id="base_credit_control_menu" sequence="10"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user,account_credit_control.group_account_credit_control_info"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="credit_control_line_action">
|
||||
<field name="name">Credit Control Lines</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">credit.control.line</field>
|
||||
<field name="domain"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="credit_control_line_tree"/>
|
||||
<field name="context">{'search_default_filter_draft': 1,
|
||||
'search_default_filter_to_be_sent': 1}
|
||||
</field>
|
||||
<field name="search_view_id" ref="credit_control_line_search"/>
|
||||
</record>
|
||||
|
||||
|
||||
<menuitem
|
||||
name="Credit Control Lines"
|
||||
parent="base_credit_control_menu"
|
||||
action="credit_control_line_action"
|
||||
sequence="20"
|
||||
id="credit_control_line_action_menu"
|
||||
/>
|
||||
|
||||
|
||||
</odoo>
|
||||
133
account_credit_control/views/credit_control_policy.xml
Normal file
133
account_credit_control/views/credit_control_policy.xml
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="credit_control_policy_form" model="ir.ui.view">
|
||||
<field name="name">credit.control.policy.form</field>
|
||||
<field name="model">credit.control.policy</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Credit control policy">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="do_nothing"/>
|
||||
<field name="company_id"/>
|
||||
<field name="active"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Policy levels">
|
||||
<field name="level_ids" nolabel="1" colspan="4">
|
||||
<tree string="Credit control policy Level">
|
||||
<field name="name"/>
|
||||
<field name="level"/>
|
||||
<field name="channel"/>
|
||||
<field name="delay_days"/>
|
||||
<field name="computation_mode"/>
|
||||
<field name="email_template_id"/>
|
||||
</tree>
|
||||
<form string="Policy level">
|
||||
<field name="name"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Delay Setting">
|
||||
<group>
|
||||
<field name="level"/>
|
||||
<field name="channel"/>
|
||||
<field name="delay_days"/>
|
||||
<field name="computation_mode"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Mail and reporting">
|
||||
<group>
|
||||
<field name="email_template_id"/>
|
||||
<newline/>
|
||||
<field name="custom_text"
|
||||
colspan="4"/>
|
||||
<newline/>
|
||||
<field name="custom_mail_text"
|
||||
colspan="4"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Accounts">
|
||||
<field name="account_ids" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_policy_tree" model="ir.ui.view">
|
||||
<field name="name">credit.control.policy.tree</field>
|
||||
<field name="model">credit.control.policy</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Credit control policy">
|
||||
<field name="name"/>
|
||||
<field name="do_nothing"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Credit Control"
|
||||
parent="account.menu_finance_configuration"
|
||||
id="base_credit_control_configuration_menu"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user"/>
|
||||
|
||||
<record model="ir.actions.act_window"
|
||||
id="credit_policy_configuration_action">
|
||||
<field name="name">Credit Control Policies</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">credit.control.policy</field>
|
||||
<field name="domain"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="credit_control_policy_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Credit Control Policies"
|
||||
parent="base_credit_control_configuration_menu"
|
||||
action="credit_policy_configuration_action"
|
||||
id="credit_policy_configuration_action_menu"/>
|
||||
|
||||
<record id="credit_mangement_policy_level_form" model="ir.ui.view">
|
||||
<field name="name">credit.mangement.policy.level.form</field>
|
||||
<field name="model">credit.control.policy.level</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Policy level">
|
||||
<field name="name"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Delay Setting">
|
||||
<group>
|
||||
<field name="level"/>
|
||||
<field name="channel"/>
|
||||
<field name="delay_days"/>
|
||||
<field name="computation_mode"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Mail and reporting">
|
||||
<group>
|
||||
<field name="email_template_id"/>
|
||||
<field name="custom_text"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_policy_level_tree" model="ir.ui.view">
|
||||
<field name="name">credit.control.policy.level.tree</field>
|
||||
<field name="model">credit.control.policy.level</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Credit control policy level">
|
||||
<field name="name"/>
|
||||
<field name="level"/>
|
||||
<field name="channel"/>
|
||||
<field name="delay_days"/>
|
||||
<field name="computation_mode"/>
|
||||
<field name="email_template_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
74
account_credit_control/views/credit_control_run.xml
Normal file
74
account_credit_control/views/credit_control_run.xml
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="credit_control_run_tree" model="ir.ui.view">
|
||||
<field name="name">credit.control.run.tree</field>
|
||||
<field name="model">credit.control.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Credit control run">
|
||||
<field name="date"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="credit_control_run_form" model="ir.ui.view">
|
||||
<field name="name">credit.control.run.form</field>
|
||||
<field name="model">credit.control.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Credit control run">
|
||||
<header>
|
||||
<button name="generate_credit_lines"
|
||||
string="Compute Credit Control Lines"
|
||||
class="oe_highlight"
|
||||
type="object" icon="fa-cogs"
|
||||
attrs="{'invisible': [('state', '!=', 'draft')]}"/>
|
||||
<button name="open_credit_lines"
|
||||
string="Open Credit Control Lines"
|
||||
type="object"
|
||||
attrs="{'invisible': [('state', '=', 'draft')]}"/>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="draft,done"
|
||||
statusbar_colors='{}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="date"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Policies">
|
||||
<field name="policy_ids" colspan="4" nolabel="1"/>
|
||||
<separator string="Report"
|
||||
attrs="{'invisible': [('report', '=', False)]}"/>
|
||||
<field name="report" colspan="4" nolabel="1"
|
||||
attrs="{'invisible': [('report', '=', False)]}"/>
|
||||
</page>
|
||||
<page string="Manual Lines" groups="base.group_no_one">
|
||||
<field name="manual_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.actions.act_window" id="credit_control_run">
|
||||
<field name="name">Credit Control Run</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">credit.control.run</field>
|
||||
<field name="domain"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="credit_control_run_tree"/>
|
||||
</record>
|
||||
|
||||
|
||||
<menuitem
|
||||
name="Credit Control Run"
|
||||
parent="base_credit_control_menu"
|
||||
action="credit_control_run"
|
||||
sequence="10"
|
||||
id="credit_control_run_menu"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user"/>
|
||||
|
||||
</odoo>
|
||||
14
account_credit_control/views/res_company.xml
Normal file
14
account_credit_control/views/res_company.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="credit_control_company_form" model="ir.ui.view">
|
||||
<field name="name">credit.control.company.form</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="currency_id" position="after">
|
||||
<field name="credit_policy_id" widget="selection"/>
|
||||
<field name="credit_control_tolerance"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
23
account_credit_control/views/res_partner.xml
Normal file
23
account_credit_control/views/res_partner.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="partner_followup_form_view" model="ir.ui.view">
|
||||
<field name="name">partner.credit_control.form.view</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="account.view_partner_property_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="credit" position="after">
|
||||
<field name="credit_policy_id" widget="selection"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window
|
||||
id="act_partner_credit_relation_relation"
|
||||
name="Credit Lines"
|
||||
groups="account_credit_control.group_account_credit_control_manager,account_credit_control.group_account_credit_control_user"
|
||||
domain="[('partner_id', '=', active_id)]"
|
||||
res_model="credit.control.line"
|
||||
src_model="res.partner"/>
|
||||
|
||||
</odoo>
|
||||
@@ -1,23 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import credit_control_emailer
|
||||
from . import credit_control_marker
|
||||
from . import credit_control_printer
|
||||
|
||||
@@ -1,27 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
from openerp import models, fields, api
|
||||
from odoo import api, fields, models
|
||||
|
||||
logger = logging.getLogger('credit.control.line.mailing')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CreditCommunication(models.TransientModel):
|
||||
@@ -81,13 +65,14 @@ class CreditCommunication(models.TransientModel):
|
||||
balance_field = 'credit_control_line_ids.balance_due'
|
||||
return sum(self.mapped(balance_field))
|
||||
|
||||
@api.one
|
||||
@api.multi
|
||||
@api.depends('credit_control_line_ids',
|
||||
'credit_control_line_ids.amount_due',
|
||||
'credit_control_line_ids.balance_due')
|
||||
def _compute_total(self):
|
||||
self.total_invoiced = self._get_total()
|
||||
self.total_due = self._get_total_due()
|
||||
for communication in self:
|
||||
communication.total_invoiced = communication._get_total()
|
||||
communication.total_due = communication._get_total_due()
|
||||
|
||||
@api.model
|
||||
@api.returns('self', lambda value: value.id)
|
||||
@@ -176,30 +161,21 @@ class CreditCommunication(models.TransientModel):
|
||||
@api.returns('mail.mail')
|
||||
def _generate_emails(self):
|
||||
""" Generate email message using template related to level """
|
||||
email_message_obj = self.env['mail.mail']
|
||||
# Warning: still using the old-api on 'email.template' because
|
||||
# the method generate_email() does not follow the cr, uid, ids
|
||||
# convention and the new api wrapper can't translate the call
|
||||
email_template_obj = self.pool['email.template']
|
||||
att_obj = self.env['ir.attachment']
|
||||
emails = email_message_obj.browse()
|
||||
emails = self.env['mail.mail']
|
||||
attachments = self.env['ir.attachment']
|
||||
required_fields = ['subject',
|
||||
'body_html',
|
||||
'email_from',
|
||||
'email_to']
|
||||
cr, uid, context = self.env.cr, self.env.uid, self.env.context
|
||||
for comm in self:
|
||||
template = comm.current_policy_level.email_template_id
|
||||
email_values = email_template_obj.generate_email(cr, uid,
|
||||
template.id,
|
||||
comm.id,
|
||||
context=context)
|
||||
email_values = template.generate_email(comm.id)
|
||||
email_values['type'] = 'email'
|
||||
# model is Transient record (self) removed periodically so no point
|
||||
# of storing res_id
|
||||
email_values.pop('model', None)
|
||||
email_values.pop('res_id', None)
|
||||
email = email_message_obj.create(email_values)
|
||||
email = emails.create(email_values)
|
||||
|
||||
state = 'sent'
|
||||
# The mail will not be send, however it will be in the pool, in an
|
||||
@@ -213,7 +189,6 @@ class CreditCommunication(models.TransientModel):
|
||||
comm.credit_control_line_ids.write({'mail_message_id': email.id,
|
||||
'state': state})
|
||||
|
||||
attachments = att_obj.browse()
|
||||
for att in email_values.get('attachments', []):
|
||||
attach_fname = att[0]
|
||||
attach_datas = att[1]
|
||||
@@ -225,7 +200,7 @@ class CreditCommunication(models.TransientModel):
|
||||
'res_id': email.id,
|
||||
'type': 'binary',
|
||||
}
|
||||
attachments += att_obj.create(data_attach)
|
||||
attachments |= attachments.create(data_attach)
|
||||
email.write({'attachment_ids': [(6, 0, attachments.ids)]})
|
||||
emails += email
|
||||
return emails
|
||||
@@ -242,8 +217,7 @@ class CreditCommunication(models.TransientModel):
|
||||
@api.multi
|
||||
@api.returns('credit.control.line')
|
||||
def _mark_credit_line_as_sent(self):
|
||||
line_obj = self.env['credit.control.line']
|
||||
lines = line_obj.browse()
|
||||
lines = self.env['credit.control.line']
|
||||
for comm in self:
|
||||
lines |= comm.credit_control_line_ids
|
||||
|
||||
|
||||
@@ -1,25 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class CreditControlEmailer(models.TransientModel):
|
||||
@@ -59,7 +44,7 @@ class CreditControlEmailer(models.TransientModel):
|
||||
def email_lines(self):
|
||||
self.ensure_one()
|
||||
if not self.line_ids:
|
||||
raise api.Warning(_('No credit control lines selected.'))
|
||||
raise UserError(_('No credit control lines selected.'))
|
||||
|
||||
comm_obj = self.env['credit.control.communication']
|
||||
|
||||
|
||||
@@ -1,54 +1,52 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="credit_line_emailer_form" model="ir.ui.view">
|
||||
<field name="name">credit.line.emailer.form</field>
|
||||
<field name="model">credit.control.emailer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Mailer" version="7.0">
|
||||
<separator string="Send emails for the selected lines" colspan="4"/>
|
||||
<newline/>
|
||||
<notebook>
|
||||
<page string="Lines">
|
||||
<field name="line_ids" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
</notebook>
|
||||
<newline/>
|
||||
<footer>
|
||||
<button class="oe_highlight"
|
||||
name="email_lines"
|
||||
string="Send the emails"
|
||||
type="object"/>
|
||||
or
|
||||
<button
|
||||
class="oe_link"
|
||||
special="cancel"
|
||||
string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
<field name="name">credit.line.emailer.form</field>
|
||||
<field name="model">credit.control.emailer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Mailer" version="7.0">
|
||||
<separator string="Send emails for the selected lines"
|
||||
colspan="4"/>
|
||||
<newline/>
|
||||
<notebook>
|
||||
<page string="Lines">
|
||||
<field name="line_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<newline/>
|
||||
<footer>
|
||||
<button class="oe_highlight"
|
||||
name="email_lines"
|
||||
string="Send the emails"
|
||||
type="object"/>
|
||||
<button
|
||||
class="oe_link"
|
||||
special="cancel"
|
||||
string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- for menu -->
|
||||
<act_window name="Send By Email"
|
||||
res_model="credit.control.emailer"
|
||||
src_model="credit.control.line"
|
||||
view_mode="form"
|
||||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="open_credit_line_emailer_wizard_menu_action"/>
|
||||
res_model="credit.control.emailer"
|
||||
src_model="credit.control.line"
|
||||
view_mode="form"
|
||||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="open_credit_line_emailer_wizard_menu_action"/>
|
||||
|
||||
<!-- for button -->
|
||||
<record id="open_credit_line_emailer_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Send By Email</field>
|
||||
<field name="res_model">credit.control.emailer</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="credit_line_emailer_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Send an email for the selected lines.</field>
|
||||
<field name="name">Send By Email</field>
|
||||
<field name="res_model">credit.control.emailer</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="credit_line_emailer_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Send an email for the selected lines.</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,24 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields, api, _
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class CreditControlMarker(models.TransientModel):
|
||||
@@ -71,12 +56,12 @@ class CreditControlMarker(models.TransientModel):
|
||||
self.ensure_one()
|
||||
|
||||
if not self.line_ids:
|
||||
raise api.Warning(_('No credit control lines selected.'))
|
||||
raise UserError(_('No credit control lines selected.'))
|
||||
|
||||
filtered_lines = self._filter_lines(self.line_ids)
|
||||
if not filtered_lines:
|
||||
raise api.Warning(_('No lines will be changed. '
|
||||
'All the selected lines are already done.'))
|
||||
raise UserError(_('No lines will be changed. '
|
||||
'All the selected lines are already done.'))
|
||||
|
||||
self._mark_lines(filtered_lines, self.name)
|
||||
|
||||
|
||||
@@ -1,39 +1,41 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="credit_line_marker_form" model="ir.ui.view">
|
||||
<field name="name">credit.line.marker.form</field>
|
||||
<field name="model">credit.control.marker</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Lines marker" version="7.0">
|
||||
<separator string="Change the state of the selected lines" colspan="4"/>
|
||||
<newline/>
|
||||
<label string="Warning: you will maybe not be able to revert this operation." colspan="4"></label>
|
||||
<newline/>
|
||||
<group>
|
||||
<group><field name="name"/></group>
|
||||
<group></group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Lines">
|
||||
<field name="line_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<newline/>
|
||||
<footer>
|
||||
<button
|
||||
class="oe_highlight"
|
||||
name="mark_lines"
|
||||
string="Change Lines' State"
|
||||
type="object"/>
|
||||
or
|
||||
<button
|
||||
class="oe_link"
|
||||
special="cancel"
|
||||
string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
<field name="name">credit.line.marker.form</field>
|
||||
<field name="model">credit.control.marker</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Lines marker" version="7.0">
|
||||
<separator string="Change the state of the selected lines"
|
||||
colspan="4"/>
|
||||
<newline/>
|
||||
<label string="Warning: you will maybe not be able to revert this operation."
|
||||
colspan="4"></label>
|
||||
<newline/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
</group>
|
||||
<group></group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Lines">
|
||||
<field name="line_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<newline/>
|
||||
<footer>
|
||||
<button
|
||||
class="oe_highlight"
|
||||
name="mark_lines"
|
||||
string="Change Lines' State"
|
||||
type="object"/>
|
||||
<button
|
||||
class="oe_link"
|
||||
special="cancel"
|
||||
string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- for menu -->
|
||||
@@ -46,15 +48,14 @@
|
||||
id="open_credit_line_marker_wizard_menu_action"/>
|
||||
|
||||
<record id="open_credit_line_marker_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Change Lines' State</field>
|
||||
<field name="res_model">credit.control.marker</field>
|
||||
<field name="src_model">credit.control.line</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="credit_line_marker_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Change the state of the selected lines.</field>
|
||||
<field name="name">Change Lines' State</field>
|
||||
<field name="res_model">credit.control.marker</field>
|
||||
<field name="src_model">credit.control.line</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="credit_line_marker_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Change the state of the selected lines.</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,29 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class credit_control_policy_changer(models.TransientModel):
|
||||
class CreditControlPolicyChanger(models.TransientModel):
|
||||
""" Wizard that is run from invoices and allows to set manually a policy
|
||||
Policy are actually apply to related move lines availabe
|
||||
in selection widget
|
||||
@@ -52,18 +39,17 @@ class credit_control_policy_changer(models.TransientModel):
|
||||
context = self.env.context
|
||||
active_ids = context.get('active_ids')
|
||||
invoice_obj = self.env['account.invoice']
|
||||
move_line_obj = self.env['account.move.line']
|
||||
if not active_ids:
|
||||
return False
|
||||
selected_lines = move_line_obj.browse()
|
||||
selected_lines = self.env['account.move.line']
|
||||
for invoice in invoice_obj.browse(active_ids):
|
||||
if invoice.type in ('in_invoice', 'in_refund', 'out_refund'):
|
||||
raise api.Warning(_('Please use wizard on customer invoices'))
|
||||
raise UserError(_('Please use wizard on customer invoices'))
|
||||
|
||||
domain = [('account_id', '=', invoice.account_id.id),
|
||||
('move_id', '=', invoice.move_id.id),
|
||||
('reconcile_id', '=', False)]
|
||||
move_lines = move_line_obj.search(domain)
|
||||
('reconciled', '=', False)]
|
||||
move_lines = selected_lines.search(domain)
|
||||
selected_lines |= move_lines
|
||||
return selected_lines
|
||||
|
||||
@@ -96,10 +82,7 @@ class credit_control_policy_changer(models.TransientModel):
|
||||
@api.model
|
||||
def _set_invoice_policy(self, move_lines, policy):
|
||||
""" Force policy on invoice """
|
||||
invoice_obj = self.env['account.invoice']
|
||||
invoice_ids = set(line.invoice.id for line in move_lines
|
||||
if line.invoice)
|
||||
invoices = invoice_obj.browse(invoice_ids)
|
||||
invoices = move_lines.mapped('invoice_id')
|
||||
invoices.write({'credit_policy_id': policy.id})
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<record id="credit_control_policy_changer_form" model="ir.ui.view">
|
||||
<field name="name">credit control policy form</field>
|
||||
<field name="model">credit.control.policy.changer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form version="7.0" string="Set current credit level">
|
||||
<separator string="Change the overdue level of current invoice" colspan="4"/>
|
||||
<label string="This wizard will let you set the overdue policy and level for selected invoices"/>
|
||||
<newline/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="new_policy_id"/>
|
||||
<field name="do_nothing"
|
||||
invisible="1"/>
|
||||
<field name="new_policy_level_id"
|
||||
domain="[('policy_id', '=', new_policy_id)]"/>
|
||||
</group>
|
||||
<group></group>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Move lines to affect">
|
||||
<field name="move_line_ids"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<footer>
|
||||
<button class="oe_highlight"
|
||||
name="set_new_policy"
|
||||
string="Set new policy"
|
||||
type="object"/>
|
||||
or
|
||||
<button class="oe_link"
|
||||
special="cancel"
|
||||
string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
<field name="name">credit control policy form</field>
|
||||
<field name="model">credit.control.policy.changer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form version="7.0" string="Set current credit level">
|
||||
<separator string="Change the overdue level of current invoice"
|
||||
colspan="4"/>
|
||||
<label string="This wizard will let you set the overdue policy and level for selected invoices"/>
|
||||
<newline/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="new_policy_id"/>
|
||||
<field name="do_nothing"
|
||||
invisible="1"/>
|
||||
<field name="new_policy_level_id"
|
||||
domain="[('policy_id', '=', new_policy_id)]"/>
|
||||
</group>
|
||||
<group></group>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Move lines to affect">
|
||||
<field name="move_line_ids"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<footer>
|
||||
<button class="oe_highlight"
|
||||
name="set_new_policy"
|
||||
string="Set new policy"
|
||||
type="object"/>
|
||||
<button class="oe_link"
|
||||
special="cancel"
|
||||
string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- for button -->
|
||||
<record id="action_wizard_credit_policy_changer" model="ir.actions.act_window">
|
||||
<field name="name">Change current credit policy</field>
|
||||
<field name="res_model">credit.control.policy.changer</field>
|
||||
<field name="src_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="credit_control_policy_changer_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Allows to manually change credit level</field>
|
||||
<record id="action_wizard_credit_policy_changer"
|
||||
model="ir.actions.act_window">
|
||||
<field name="name">Change current credit policy</field>
|
||||
<field name="res_model">credit.control.policy.changer</field>
|
||||
<field name="src_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="credit_control_policy_changer_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Allows to manually change credit level</field>
|
||||
</record>
|
||||
|
||||
<!-- for menu -->
|
||||
@@ -60,5 +60,4 @@
|
||||
key2="client_action_multi"
|
||||
id="action_wizard_credit_policy_changer_menu_action"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,25 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi, Guewen Baconnier
|
||||
# Copyright 2012-2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# Copyright 2012-2017 Camptocamp SA
|
||||
# Copyright 2017 Okia SPRL (https://okia.be)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class CreditControlPrinter(models.TransientModel):
|
||||
@@ -57,7 +42,7 @@ class CreditControlPrinter(models.TransientModel):
|
||||
self.ensure_one()
|
||||
comm_obj = self.env['credit.control.communication']
|
||||
if not self.line_ids:
|
||||
raise api.Warning(_('No credit control lines selected.'))
|
||||
raise UserError(_('No credit control lines selected.'))
|
||||
|
||||
lines = self._get_lines(self.line_ids, self._credit_line_predicate)
|
||||
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="credit_line_printer_form" model="ir.ui.view">
|
||||
<field name="name">credit.line.printer.form</field>
|
||||
<field name="model">credit.control.printer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Lines report" version="7.0">
|
||||
<separator string="Print the selected lines" colspan="4"/>
|
||||
<newline/>
|
||||
<group>
|
||||
<field name="mark_as_sent"
|
||||
colspan="4"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<notebook>
|
||||
<page string="Lines">
|
||||
<field name="line_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<footer>
|
||||
<button class="oe_highlight" name="print_lines" string="Print" type="object"/>
|
||||
or
|
||||
<button class="oe_link" special="cancel" string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
<field name="name">credit.line.printer.form</field>
|
||||
<field name="model">credit.control.printer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Lines report" version="7.0">
|
||||
<separator string="Print the selected lines" colspan="4"/>
|
||||
<newline/>
|
||||
<group>
|
||||
<field name="mark_as_sent"
|
||||
colspan="4"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<notebook>
|
||||
<page string="Lines">
|
||||
<field name="line_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<footer>
|
||||
<button class="oe_highlight" name="print_lines"
|
||||
string="Print" type="object"/>
|
||||
<button class="oe_link" special="cancel" string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- for menu -->
|
||||
@@ -37,15 +36,14 @@
|
||||
id="open_credit_line_printer_wizard_menu_action"/>
|
||||
|
||||
<record id="open_credit_line_printer_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Print Lines</field>
|
||||
<field name="res_model">credit.control.printer</field>
|
||||
<field name="src_model">credit.control.line</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="credit_line_printer_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Print selected lines</field>
|
||||
<field name="name">Print Lines</field>
|
||||
<field name="res_model">credit.control.printer</field>
|
||||
<field name="src_model">credit.control.line</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="credit_line_printer_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Print selected lines</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
1
setup/account_credit_control/odoo/__init__.py
Normal file
1
setup/account_credit_control/odoo/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
__import__('pkg_resources').declare_namespace(__name__)
|
||||
1
setup/account_credit_control/odoo/addons/__init__.py
Normal file
1
setup/account_credit_control/odoo/addons/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
__import__('pkg_resources').declare_namespace(__name__)
|
||||
1
setup/account_credit_control/odoo/addons/account_credit_control
Symbolic link
1
setup/account_credit_control/odoo/addons/account_credit_control
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../account_credit_control
|
||||
6
setup/account_credit_control/setup.py
Normal file
6
setup/account_credit_control/setup.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['setuptools-odoo'],
|
||||
odoo_addon=True,
|
||||
)
|
||||
Reference in New Issue
Block a user