From 70e79662664e992d346ab993e7d9227c815969b9 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Tue, 28 Oct 2014 11:45:18 +0100 Subject: [PATCH] [MIG] account_credit_control: Migration to 8.0 --- account_credit_control/README.rst | 29 + account_credit_control/__init__.py | 29 + account_credit_control/__openerp__.py | 44 +- account_credit_control/account.py | 32 + account_credit_control/account_view.xml | 45 + account_credit_control/company.py | 37 + account_credit_control/company_view.xml | 15 + .../credit_control_demo.xml | 30 + account_credit_control/data.xml | 224 +++ .../i18n/account_credit_control.pot | 1160 ++++++++++++++ account_credit_control/i18n/de.po | 1190 +++++++++++++++ account_credit_control/i18n/fr.po | 1357 +++++++++++++++++ account_credit_control/invoice.py | 67 + account_credit_control/line.py | 230 +++ account_credit_control/line_view.xml | 171 +++ account_credit_control/mail.py | 29 + account_credit_control/partner.py | 58 + account_credit_control/partner_view.xml | 24 + account_credit_control/policy.py | 406 +++++ account_credit_control/policy_view.xml | 131 ++ account_credit_control/report/report.xml | 15 + .../report/report_credit_control_summary.xml | 99 ++ account_credit_control/run.py | 175 +++ account_credit_control/run_view.xml | 75 + .../features/00_credit_control_param.feature | 61 + .../01_credit_control_partners.feature | 105 ++ .../02_credit_control_invoices.feature | 588 +++++++ .../03_credit_control_run_jan.feature | 29 + .../04_credit_control_run_feb.feature | 33 + .../05_credit_control_run_mar.feature | 45 + .../06_credit_control_run_apr.feature | 44 + .../07_credit_control_run_may.feature | 59 + .../08_credit_control_run_jun.feature | 38 + .../09_credit_control_run_jul.feature | 35 + .../10_credit_control_run_aug.feature | 30 + .../11_credit_control_manual_setting.feature | 42 + .../features/steps/account_credit_control.py | 147 ++ .../steps/account_credit_control_changer.py | 79 + .../features/steps/account_voucher.py | 96 ++ .../security/ir.model.access.csv | 21 + account_credit_control/wizard/__init__.py | 25 + .../wizard/credit_control_communication.py | 239 +++ .../wizard/credit_control_emailer.py | 69 + .../wizard/credit_control_emailer_view.xml | 54 + .../wizard/credit_control_marker.py | 88 ++ .../wizard/credit_control_marker_view.xml | 60 + .../wizard/credit_control_policy_changer.py | 148 ++ .../credit_control_policy_changer_view.xml | 64 + .../wizard/credit_control_printer.py | 71 + .../wizard/credit_control_printer_view.xml | 51 + 50 files changed, 7957 insertions(+), 36 deletions(-) create mode 100644 account_credit_control/README.rst create mode 100644 account_credit_control/__init__.py create mode 100644 account_credit_control/account.py create mode 100644 account_credit_control/account_view.xml create mode 100644 account_credit_control/company.py create mode 100644 account_credit_control/company_view.xml create mode 100644 account_credit_control/credit_control_demo.xml create mode 100644 account_credit_control/data.xml create mode 100644 account_credit_control/i18n/account_credit_control.pot create mode 100644 account_credit_control/i18n/de.po create mode 100644 account_credit_control/i18n/fr.po create mode 100644 account_credit_control/invoice.py create mode 100644 account_credit_control/line.py create mode 100644 account_credit_control/line_view.xml create mode 100644 account_credit_control/mail.py create mode 100644 account_credit_control/partner.py create mode 100644 account_credit_control/partner_view.xml create mode 100644 account_credit_control/policy.py create mode 100644 account_credit_control/policy_view.xml create mode 100644 account_credit_control/report/report.xml create mode 100644 account_credit_control/report/report_credit_control_summary.xml create mode 100644 account_credit_control/run.py create mode 100644 account_credit_control/run_view.xml create mode 100644 account_credit_control/scenarios/features/00_credit_control_param.feature create mode 100644 account_credit_control/scenarios/features/01_credit_control_partners.feature create mode 100644 account_credit_control/scenarios/features/02_credit_control_invoices.feature create mode 100644 account_credit_control/scenarios/features/03_credit_control_run_jan.feature create mode 100644 account_credit_control/scenarios/features/04_credit_control_run_feb.feature create mode 100644 account_credit_control/scenarios/features/05_credit_control_run_mar.feature create mode 100644 account_credit_control/scenarios/features/06_credit_control_run_apr.feature create mode 100644 account_credit_control/scenarios/features/07_credit_control_run_may.feature create mode 100644 account_credit_control/scenarios/features/08_credit_control_run_jun.feature create mode 100644 account_credit_control/scenarios/features/09_credit_control_run_jul.feature create mode 100644 account_credit_control/scenarios/features/10_credit_control_run_aug.feature create mode 100644 account_credit_control/scenarios/features/11_credit_control_manual_setting.feature create mode 100644 account_credit_control/scenarios/features/steps/account_credit_control.py create mode 100644 account_credit_control/scenarios/features/steps/account_credit_control_changer.py create mode 100644 account_credit_control/scenarios/features/steps/account_voucher.py create mode 100644 account_credit_control/security/ir.model.access.csv create mode 100644 account_credit_control/wizard/__init__.py create mode 100644 account_credit_control/wizard/credit_control_communication.py create mode 100644 account_credit_control/wizard/credit_control_emailer.py create mode 100644 account_credit_control/wizard/credit_control_emailer_view.xml create mode 100644 account_credit_control/wizard/credit_control_marker.py create mode 100644 account_credit_control/wizard/credit_control_marker_view.xml create mode 100644 account_credit_control/wizard/credit_control_policy_changer.py create mode 100644 account_credit_control/wizard/credit_control_policy_changer_view.xml create mode 100644 account_credit_control/wizard/credit_control_printer.py create mode 100644 account_credit_control/wizard/credit_control_printer_view.xml diff --git a/account_credit_control/README.rst b/account_credit_control/README.rst new file mode 100644 index 000000000..4294fdb56 --- /dev/null +++ b/account_credit_control/README.rst @@ -0,0 +1,29 @@ +Credit Control +============== + +Configuration +------------- + +Configure the policies and policy levels in ``Accounting > Configuration > +Credit Control > Credit Policies``. +You can define as many policy levels as you need. + +Configure a tolerance for the Credit control and a default policy +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``. + +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 +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) diff --git a/account_credit_control/__init__.py b/account_credit_control/__init__.py new file mode 100644 index 000000000..531c9f6d3 --- /dev/null +++ b/account_credit_control/__init__.py @@ -0,0 +1,29 @@ +# -*- 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 . +# +############################################################################## +from . import mail +from . import run +from . import line +from . import account +from . import partner +from . import policy +from . import company +from . import wizard +from . import invoice diff --git a/account_credit_control/__openerp__.py b/account_credit_control/__openerp__.py index 0f8871bf0..003486a41 100644 --- a/account_credit_control/__openerp__.py +++ b/account_credit_control/__openerp__.py @@ -2,7 +2,7 @@ ############################################################################## # # Author: Nicolas Bessi, Guewen Baconnier -# Copyright 2012 Camptocamp SA +# 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 @@ -20,45 +20,17 @@ ############################################################################## {'name': 'Account Credit Control', 'version': '0.2.0', - 'author': 'Camptocamp', + 'author': "Camptocamp,Odoo Community Association (OCA)", 'maintainer': 'Camptocamp', 'category': 'Finance', 'complexity': "normal", - 'depends': ['base', 'account', - 'email_template', 'report_webkit'], - 'description': """ -Credit Control -============== - -Configuration -------------- - -Configure the policies and policy levels in ``Accounting > Configuration > -Credit Control > Credit Policies``. -You can define as many policy levels as you need. - -Configure a tolerance for the Credit control and a default policy -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``. - -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 -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) - """, + '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", @@ -71,7 +43,7 @@ On each generated line, you have many choices: "wizard/credit_control_printer_view.xml", "wizard/credit_control_policy_changer_view.xml", "security/ir.model.access.csv"], - 'demo_xml': ["credit_control_demo.xml"], + 'demo': ["credit_control_demo.xml"], 'tests': [], 'installable': True, 'license': 'AGPL-3', diff --git a/account_credit_control/account.py b/account_credit_control/account.py new file mode 100644 index 000000000..de4758c5f --- /dev/null +++ b/account_credit_control/account.py @@ -0,0 +1,32 @@ +# -*- 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 . +# +############################################################################## +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) diff --git a/account_credit_control/account_view.xml b/account_credit_control/account_view.xml new file mode 100644 index 000000000..5873e8ce3 --- /dev/null +++ b/account_credit_control/account_view.xml @@ -0,0 +1,45 @@ + + + + + + + invoice.followup.form.view + account.invoice + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/account_credit_control/company.py b/account_credit_control/company.py new file mode 100644 index 000000000..8deb708fa --- /dev/null +++ b/account_credit_control/company.py @@ -0,0 +1,37 @@ +# -*- 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 . +# +############################################################################## +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.") diff --git a/account_credit_control/company_view.xml b/account_credit_control/company_view.xml new file mode 100644 index 000000000..feb50c0d5 --- /dev/null +++ b/account_credit_control/company_view.xml @@ -0,0 +1,15 @@ + + + + credit.control.company.form + res.company + + + + + + + + + + diff --git a/account_credit_control/credit_control_demo.xml b/account_credit_control/credit_control_demo.xml new file mode 100644 index 000000000..107e26628 --- /dev/null +++ b/account_credit_control/credit_control_demo.xml @@ -0,0 +1,30 @@ + + + + X11002-a + B2B Debtors - (test) + + receivable + + + + + + X11002-b + B2C Debtors - (test) + + receivable + + + + + + X11002-c + New Debtors - (test) + + receivable + + + + + diff --git a/account_credit_control/data.xml b/account_credit_control/data.xml new file mode 100644 index 000000000..c629232d4 --- /dev/null +++ b/account_credit_control/data.xml @@ -0,0 +1,224 @@ + + + + + Credit Control Email + noreply@localhost + Credit Control: (${object.current_policy_level.name or 'n/a'}) + ${object.get_email() or ''} + + + ${object.get_contact_address().lang or 'en_US'} + + +
+ ${object.current_policy_level.custom_mail_text} + ]]>
+
+ + + + No follow + + + + + + No follow + + net_days + + + + email + Manual no follow + + Manual no follow + + + + + 3 time policy + + + + 10 days net + + net_days + + + + email + 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 + + + Our records indicate that we have not received the payment of the invoices mentioned in the attached document. + +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 + + + + + 30 days end of month + + end_of_month + + + + email + 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 + + Our records indicate that we have not yet received the payment of the invoices mentioned in the attached document 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 + + + + + 10 days last reminder + + previous_date + + + + letter + + 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 + + +Our records indicate that we still have not received the payment of the invoices mentioned in the attached document 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 + + + + + + 2 time policy + + + + 30 days end of month + + end_of_month + + + + email + 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 + + Our records indicate that we have not received the payment of the invoices mentioned in the attached document. +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 + + + + + 60 days last reminder + + previous_date + + + + letter + 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 + + Our records indicate that we still have not received the payment of the invoices mentioned in the attached document 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 + + + + + Credit Control Manager + + + + + Credit Control User + + + + + Credit Control Info + + + + + + + +
+
diff --git a/account_credit_control/i18n/account_credit_control.pot b/account_credit_control/i18n/account_credit_control.pot new file mode 100644 index 000000000..e23733290 --- /dev/null +++ b/account_credit_control/i18n/account_credit_control.pot @@ -0,0 +1,1160 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_credit_control +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-01-26 10:32+0000\n" +"PO-Revision-Date: 2015-01-26 10:32+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.3_time_3 +msgid "\n" +" Our records indicate that we still have not received the payment of the above mentioned invoice despite our two reminders.\n" +" If payment have already been sent, please disregard this notice. If not, please proceed with payment.\n" +" If your payment has not been received in the next 5 days, your file will be transfered to our debt collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:email.template,body_html:account_credit_control.email_template_credit_control_base +msgid "\n" +" Dear ${object.contact_address.name or ''}\n" +"
\n" +"
\n" +" ${object.current_policy_level.custom_mail_text}\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.3_time_3 +msgid "10 days last reminder" +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.3_time_1 +msgid "10 days net" +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.2_time_1 +#: model:credit.control.policy.level,name:account_credit_control.3_time_2 +msgid "30 days end of month" +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.2_time_2 +msgid "60 days last reminder" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_line +msgid "A credit control line" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:87 +#, python-format +msgid "A credit control line more recent than %s exists at %s" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_policy_level +msgid "A credit control policy level" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:154 +#, python-format +msgid "A credit control run is already running in background, please try later." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:80 +#, python-format +msgid "A run has already been executed more recently than %s" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,account_id:0 +#: model:ir.model,name:account_credit_control.model_account_account +msgid "Account" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: field:credit.control.policy,account_ids:0 +msgid "Accounts" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy,active:0 +msgid "Active" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.action_wizard_credit_policy_changer +msgid "Allows to manually change credit level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "An error has occured during the sending of the email." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/policy.py:308 +#, python-format +msgid "Can not get function for computation mode: %s is not implemented" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Cancel" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_marker_wizard +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_marker_wizard_menu_action +msgid "Change Lines' State" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.action_wizard_credit_policy_changer +#: model:ir.actions.act_window,name:account_credit_control.action_wizard_credit_policy_changer_menu_action +msgid "Change current credit policy" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Change the overdue level of current invoice" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +msgid "Change the state of the selected lines" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.open_credit_line_marker_wizard +msgid "Change the state of the selected lines." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,channel:0 +#: field:credit.control.policy.level,channel:0 +msgid "Channel" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_res_company +msgid "Companies" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,company_id:0 +#: field:credit.control.line,company_id:0 +#: field:credit.control.policy,company_id:0 +msgid "Company" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +msgid "Compute Credit Control Lines" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,computation_mode:0 +msgid "Compute Mode" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,contact_address:0 +msgid "Contact Address" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_form +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: view:credit.control.line:account_credit_control.credit_control_line_tree +msgid "Control Credit Lines" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.run,date:0 +msgid "Controlling Date" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,date:0 +msgid "Controlling date" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,create_uid:0 +#: field:credit.control.emailer,create_uid:0 +#: field:credit.control.line,create_uid:0 +#: field:credit.control.marker,create_uid:0 +#: field:credit.control.policy,create_uid:0 +#: field:credit.control.policy.changer,create_uid:0 +#: field:credit.control.policy.level,create_uid:0 +#: field:credit.control.printer,create_uid:0 +#: field:credit.control.run,create_uid:0 +msgid "Created by" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,create_date:0 +#: field:credit.control.emailer,create_date:0 +#: field:credit.control.line,create_date:0 +#: field:credit.control.marker,create_date:0 +#: field:credit.control.policy,create_date:0 +#: field:credit.control.policy.changer,create_date:0 +#: field:credit.control.policy.level,create_date:0 +#: field:credit.control.printer,create_date:0 +#: field:credit.control.run,create_date:0 +msgid "Created on" +msgstr "" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +#: model:ir.ui.menu,name:account_credit_control.base_credit_control_configuration_menu +#: model:ir.ui.menu,name:account_credit_control.base_credit_control_menu +msgid "Credit Control" +msgstr "" + +#. module: account_credit_control +#: model:res.groups,name:account_credit_control.group_account_credit_control_info +msgid "Credit Control Info" +msgstr "" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +#: field:credit.control.emailer,line_ids:0 +#: field:credit.control.marker,line_ids:0 +#: field:credit.control.printer,line_ids:0 +#: model:ir.actions.act_window,name:account_credit_control.credit_control_line_action +#: model:ir.ui.menu,name:account_credit_control.credit_control_line_action_menu +#: field:res.partner,credit_control_line_ids:0 +msgid "Credit Control Lines" +msgstr "" + +#. module: account_credit_control +#: model:res.groups,name:account_credit_control.group_account_credit_control_manager +msgid "Credit Control Manager" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.credit_policy_configuration_action +#: model:ir.ui.menu,name:account_credit_control.credit_policy_configuration_action_menu +msgid "Credit Control Policies" +msgstr "" + +#. module: account_credit_control +#: field:account.invoice,credit_policy_id:0 +#: field:res.company,credit_policy_id:0 +#: field:res.partner,credit_policy_id:0 +msgid "Credit Control Policy" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.credit_control_run +#: model:ir.ui.menu,name:account_credit_control.credit_control_run_menu +msgid "Credit Control Run" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.report.xml,name:account_credit_control.credit_control_summary +msgid "Credit Control Summary" +msgstr "" + +#. module: account_credit_control +#: field:res.company,credit_control_tolerance:0 +msgid "Credit Control Tolerance" +msgstr "" + +#. module: account_credit_control +#: model:res.groups,name:account_credit_control.group_account_credit_control_user +msgid "Credit Control User" +msgstr "" + +#. module: account_credit_control +#: model:email.template,subject:account_credit_control.email_template_credit_control_base +msgid "Credit Control: (${object.current_policy_level.name or 'n/a'})" +msgstr "" + +#. module: account_credit_control +#: field:account.account,credit_control_line_ids:0 +#: field:account.invoice,credit_control_line_ids:0 +#: field:credit.control.communication,credit_control_line_ids:0 +#: model:ir.actions.act_window,name:account_credit_control.act_account_credit_relation_relation +#: model:ir.actions.act_window,name:account_credit_control.act_partner_credit_relation_relation +msgid "Credit Lines" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_run +msgid "Credit control line generator" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy:account_credit_control.credit_control_policy_tree +msgid "Credit control policy" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +msgid "Credit control policy Level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.level:account_credit_control.credit_control_policy_level_tree +msgid "Credit control policy level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +#: view:credit.control.run:account_credit_control.credit_control_run_tree +msgid "Credit control run" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Credit policy" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Credit policy level" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,currency_id:0 +#: field:credit.control.line,currency_id:0 +msgid "Currency" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,custom_mail_text:0 +msgid "Custom Mail Message" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,custom_text:0 +msgid "Custom Message" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Date due" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_policy +msgid "Define a reminder policy" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,delay_days:0 +msgid "Delay (in days)" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy.level:account_credit_control.credit_mangement_policy_level_form +msgid "Delay Setting" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy,do_nothing:0 +msgid "Do nothing" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.line,state:0 +#: selection:credit.control.marker,name:0 +#: selection:credit.control.run,state:0 +msgid "Done" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +#: selection:credit.control.run,state:0 +msgid "Draft" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Draft lines have to be triaged." +msgstr "" + +#. module: account_credit_control +#: help:credit.control.line,state:0 +msgid "Draft lines need to be triaged.\n" +"Ignored lines are lines for which we do not want to send something.\n" +"Draft and ignored lines will be generated again on the next run." +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,amount_due:0 +msgid "Due Amount Tax incl." +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.policy.level,computation_mode:0 +msgid "Due Date" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.policy.level,computation_mode:0 +msgid "Due Date, End Of Month" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,balance_due:0 +msgid "Due balance" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,date_due:0 +msgid "Due date" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.line,channel:0 +#: selection:credit.control.policy.level,channel:0 +msgid "Email" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,email_template_id:0 +msgid "Email Template" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.line,state:0 +msgid "Emailing Error" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,date_entry:0 +msgid "Entry date" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +msgid "Error" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Filters" +msgstr "" + +#. module: account_credit_control +#: help:credit.control.policy,do_nothing:0 +msgid "For policies which should not generate lines or are obsolete" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.run,line_ids:0 +msgid "Generated lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Group By..." +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,id:0 +#: field:credit.control.emailer,id:0 +#: field:credit.control.line,id:0 +#: field:credit.control.marker,id:0 +#: field:credit.control.policy,id:0 +#: field:credit.control.policy.changer,id:0 +#: field:credit.control.policy.level,id:0 +#: field:credit.control.printer,id:0 +#: field:credit.control.run,id:0 +msgid "ID" +msgstr "" + +#. module: account_credit_control +#: help:credit.control.run,manual_ids:0 +msgid "If a credit control line has been generatedon a policy and the policy has been changed in the meantime, it has to be handled manually" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +#: selection:credit.control.marker,name:0 +msgid "Ignored" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,invoice_id:0 +#: model:ir.model,name:account_credit_control.model_account_invoice +msgid "Invoice" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Invoice date" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Invoice number" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Invoiced amount" +msgstr "" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +msgid "Issued Lines" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,write_uid:0 +#: field:credit.control.emailer,write_uid:0 +#: field:credit.control.line,write_uid:0 +#: field:credit.control.marker,write_uid:0 +#: field:credit.control.policy,write_uid:0 +#: field:credit.control.policy.changer,write_uid:0 +#: field:credit.control.policy.level,write_uid:0 +#: field:credit.control.printer,write_uid:0 +#: field:credit.control.run,write_uid:0 +msgid "Last Updated by" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,write_date:0 +#: field:credit.control.emailer,write_date:0 +#: field:credit.control.line,write_date:0 +#: field:credit.control.marker,write_date:0 +#: field:credit.control.policy,write_date:0 +#: field:credit.control.policy.changer,write_date:0 +#: field:credit.control.policy.level,write_date:0 +#: field:credit.control.printer,write_date:0 +#: field:credit.control.run,write_date:0 +msgid "Last Updated on" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.line,channel:0 +#: selection:credit.control.policy.level,channel:0 +msgid "Letter" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,current_policy_level:0 +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.policy.level,level:0 +msgid "Level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Lines already sent." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +msgid "Lines marker" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Lines report" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.run,manual_ids:0 +msgid "Lines to handle manually" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Lines which have been ignored from previous runs." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy.level:account_credit_control.credit_mangement_policy_level_form +msgid "Mail and reporting" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +msgid "Mailer" +msgstr "" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +msgid "Manual Credit Control Policy" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +msgid "Manual Lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Manual change" +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.no_follow_1 +#: model:credit.control.policy.level,custom_text:account_credit_control.no_follow_1 +msgid "Manual no follow" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,manually_overridden:0 +msgid "Manually overridden" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.marker,name:0 +msgid "Mark as" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.printer,mark_as_sent:0 +msgid "Mark letter lines as sent" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_emailer +msgid "Mass credit line emailer" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_marker +msgid "Mass marker" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_printer +msgid "Mass printer" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "More..." +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,move_line_id:0 +msgid "Move line" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.changer,move_line_ids:0 +msgid "Move line to change" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Move lines to affect" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy,name:0 +#: field:credit.control.policy.level,name:0 +msgid "Name" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.changer,new_policy_id:0 +msgid "New Policy to Apply" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.changer,new_policy_level_id:0 +msgid "New level to apply" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/wizard/credit_control_emailer.py:62 +#: code:addons/account_credit_control/wizard/credit_control_marker.py:74 +#: code:addons/account_credit_control/wizard/credit_control_printer.py:60 +#, python-format +msgid "No credit control lines selected." +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.no_follow_1 +msgid "No follow" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.changer,do_nothing:0 +msgid "No follow policy" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/wizard/credit_control_marker.py:78 +#, python-format +msgid "No lines will be changed. All the selected lines are already done." +msgstr "" + +#. module: account_credit_control +#: help:credit.control.printer,mark_as_sent:0 +msgid "Only letter lines will be marked." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +msgid "Open Credit Control Lines" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Open amount" +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.2_time_1 +msgid "Our records indicate that we have not received the payment of the above mentioned invoice.\n" +" If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.3_time_1 +msgid "Our records indicate that we have not received the payment of the above mentioned invoice.\n" +"If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.3_time_1 +msgid "Our records indicate that we have not received the payment of the invoices mentioned in the attached document.\n" +"\n" +"If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.2_time_1 +msgid "Our records indicate that we have not received the payment of the invoices mentioned in the attached document.\n" +"If it has already been sent, please disregard this notice. If not, please proceed with payment within 10 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.3_time_2 +msgid "Our records indicate that we have not yet received the payment of the above mentioned invoice despite our first reminder.\n" +" If it has already been sent, please disregard this notice. If not, please proceed with payment within 5 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.3_time_2 +msgid "Our records indicate that we have not yet received the payment of the invoices mentioned in the attached document despite our first reminder.\n" +" If it has already been sent, please disregard this notice. If not, please proceed with payment within 5 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.2_time_2 +msgid "Our records indicate that we still have not received the payment of the above mentioned invoice despite our reminder.\n" +"\n" +" If payment have already been sent, please disregard this notice. If not, please proceed with payment.\n" +" If your payment has not been received in the next 5 days, your file will be transfered to our debt\n" +" collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.2_time_2 +msgid "Our records indicate that we still have not received the payment of the invoices mentioned in the attached document despite our reminder.\n" +"\n" +"If payment have already been sent, please disregard this notice. If not, please proceed with payment.\n" +"If your payment has not been received in the next 5 days, your file will be transfered to our debt\n" +" collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.3_time_3 +msgid "Our records indicate that we still have not received the payment of the invoices mentioned in the attached document despite our two reminders.\n" +" If payment have already been sent, please disregard this notice. If not, please proceed with payment.\n" +" If your payment has not been received in the next 5 days, your file will be transfered to our debt collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,policy_level_id:0 +msgid "Overdue Level" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,partner_id:0 +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,partner_id:0 +#: model:ir.model,name:account_credit_control.model_res_partner +msgid "Partner" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:103 +#, python-format +msgid "Please select a policy" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/wizard/credit_control_policy_changer.py:61 +#, python-format +msgid "Please use wizard on customer invoices" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +#: field:credit.control.run,policy_ids:0 +msgid "Policies" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:132 +#, python-format +msgid "Policy \"%s\" has generated %d Credit Control Lines.
" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:136 +#, python-format +msgid "Policy \"%s\" has not generated any Credit Control Lines.
" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy,level_ids:0 +msgid "Policy Levels" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy.level:account_credit_control.credit_mangement_policy_level_form +msgid "Policy level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +msgid "Policy levels" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.policy.level,computation_mode:0 +msgid "Previous Reminder" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Print" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_printer_wizard +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_printer_wizard_menu_action +msgid "Print Lines" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.open_credit_line_printer_wizard +msgid "Print selected lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Print the selected lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +#: selection:credit.control.marker,name:0 +msgid "Ready To Send" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,policy_id:0 +#: field:credit.control.policy.level,policy_id:0 +msgid "Related Policy" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Reminder" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +#: field:credit.control.run,report:0 +msgid "Report" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,report_date:0 +msgid "Report Date" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Run date" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_emailer_wizard +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_emailer_wizard_menu_action +msgid "Send By Email" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.open_credit_line_emailer_wizard +msgid "Send an email for the selected lines." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +msgid "Send emails for the selected lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +msgid "Send the emails" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Sent" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,mail_message_id:0 +msgid "Sent Email" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,date_sent:0 +msgid "Sent date" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Set current credit level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Set new policy" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,run_id:0 +msgid "Source" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,state:0 +#: field:credit.control.run,state:0 +msgid "State" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Summary" +msgstr "" + +#. module: account_credit_control +#: help:account.invoice,credit_policy_id:0 +msgid "The Credit Control Policy used for this invoice. If nothing is defined, it will use the account setting or the partner setting." +msgstr "" + +#. module: account_credit_control +#: help:res.partner,credit_policy_id:0 +msgid "The Credit Control Policy used for this partner. This setting can be forced on the invoice. If nothing is defined, it will use the company setting." +msgstr "" + +#. module: account_credit_control +#: help:res.company,credit_policy_id:0 +msgid "The Credit Control Policy used on partners by default. This setting can be overridden on partners or invoices." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "The line was deprecated by a manual change of policy on invoice." +msgstr "" + +#. module: account_credit_control +#: help:credit.control.line,currency_id:0 +msgid "The optional other currency if it is a multi-currency entry." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/policy.py:258 +#, python-format +msgid "The smallest level can not be of type Previous Reminder" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "These lines are ready to send by email or by letter using the Actions." +msgstr "" + +#. module: account_credit_control +#: help:credit.control.policy,account_ids:0 +msgid "This policy will be active only for the selected accounts" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "This wizard will let you set the overdue policy and level for selected invoices" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Total Due" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Total Invoiced" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,user_id:0 +msgid "User" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +msgid "Warning: you will maybe not be able to revert this operation." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/line.py:223 +#, python-format +msgid "You are not allowed to delete a credit control line that is not in draft state." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/policy.py:203 +#, python-format +msgid "You can only use a policy set on account %s.\n" +"Please choose one of the following policies:\n" +" %s" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/invoice.py:57 +#, python-format +msgid "You cannot cancel this invoice.\n" +"A payment reminder has already been sent to the customer.\n" +"You must create a credit note and issue a new invoice." +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_communication +msgid "credit control communication" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,level:0 +msgid "credit.control.policy.level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "or" +msgstr "" + diff --git a/account_credit_control/i18n/de.po b/account_credit_control/i18n/de.po new file mode 100644 index 000000000..c68bfdb9a --- /dev/null +++ b/account_credit_control/i18n/de.po @@ -0,0 +1,1190 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_credit_control +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-01-26 10:32+0000\n" +"PO-Revision-Date: 2014-10-30 14:59+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.3_time_3 +msgid "" +"\n" +" Our records indicate that we still have not received the payment of " +"the above mentioned invoice despite our two reminders.\n" +" If payment have already been sent, please disregard this notice. If " +"not, please proceed with payment.\n" +" If your payment has not been received in the next 5 days, your file " +"will be transfered to our debt collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please " +"advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:email.template,body_html:account_credit_control.email_template_credit_control_base +msgid "" +"\n" +" Dear ${object.contact_address.name or ''}\n" +"
\n" +"
\n" +" ${object.current_policy_level.custom_mail_text}\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.3_time_3 +msgid "10 days last reminder" +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.3_time_1 +msgid "10 days net" +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.2_time_1 +#: model:credit.control.policy.level,name:account_credit_control.3_time_2 +msgid "30 days end of month" +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.2_time_2 +msgid "60 days last reminder" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_line +msgid "A credit control line" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:87 +#, python-format +msgid "A credit control line more recent than %s exists at %s" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_policy_level +msgid "A credit control policy level" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:154 +#, python-format +msgid "" +"A credit control run is already running in background, please try later." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:80 +#, python-format +msgid "A run has already been executed more recently than %s" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,account_id:0 +#: model:ir.model,name:account_credit_control.model_account_account +msgid "Account" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: field:credit.control.policy,account_ids:0 +msgid "Accounts" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy,active:0 +msgid "Active" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.action_wizard_credit_policy_changer +msgid "Allows to manually change credit level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "An error has occured during the sending of the email." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/policy.py:308 +#, python-format +msgid "Can not get function for computation mode: %s is not implemented" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Cancel" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_marker_wizard +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_marker_wizard_menu_action +msgid "Change Lines' State" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.action_wizard_credit_policy_changer +#: model:ir.actions.act_window,name:account_credit_control.action_wizard_credit_policy_changer_menu_action +msgid "Change current credit policy" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Change the overdue level of current invoice" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +msgid "Change the state of the selected lines" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.open_credit_line_marker_wizard +msgid "Change the state of the selected lines." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,channel:0 +#: field:credit.control.policy.level,channel:0 +msgid "Channel" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_res_company +msgid "Companies" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,company_id:0 +#: field:credit.control.line,company_id:0 +#: field:credit.control.policy,company_id:0 +msgid "Company" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +msgid "Compute Credit Control Lines" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,computation_mode:0 +msgid "Compute Mode" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,contact_address:0 +msgid "Contact Address" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_form +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: view:credit.control.line:account_credit_control.credit_control_line_tree +msgid "Control Credit Lines" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.run,date:0 +msgid "Controlling Date" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,date:0 +msgid "Controlling date" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,create_uid:0 +#: field:credit.control.emailer,create_uid:0 +#: field:credit.control.line,create_uid:0 +#: field:credit.control.marker,create_uid:0 +#: field:credit.control.policy,create_uid:0 +#: field:credit.control.policy.changer,create_uid:0 +#: field:credit.control.policy.level,create_uid:0 +#: field:credit.control.printer,create_uid:0 +#: field:credit.control.run,create_uid:0 +msgid "Created by" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,create_date:0 +#: field:credit.control.emailer,create_date:0 +#: field:credit.control.line,create_date:0 +#: field:credit.control.marker,create_date:0 +#: field:credit.control.policy,create_date:0 +#: field:credit.control.policy.changer,create_date:0 +#: field:credit.control.policy.level,create_date:0 +#: field:credit.control.printer,create_date:0 +#: field:credit.control.run,create_date:0 +msgid "Created on" +msgstr "" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +#: model:ir.ui.menu,name:account_credit_control.base_credit_control_configuration_menu +#: model:ir.ui.menu,name:account_credit_control.base_credit_control_menu +msgid "Credit Control" +msgstr "" + +#. module: account_credit_control +#: model:res.groups,name:account_credit_control.group_account_credit_control_info +msgid "Credit Control Info" +msgstr "" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +#: field:credit.control.emailer,line_ids:0 +#: field:credit.control.marker,line_ids:0 +#: field:credit.control.printer,line_ids:0 +#: model:ir.actions.act_window,name:account_credit_control.credit_control_line_action +#: model:ir.ui.menu,name:account_credit_control.credit_control_line_action_menu +#: field:res.partner,credit_control_line_ids:0 +msgid "Credit Control Lines" +msgstr "" + +#. module: account_credit_control +#: model:res.groups,name:account_credit_control.group_account_credit_control_manager +msgid "Credit Control Manager" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.credit_policy_configuration_action +#: model:ir.ui.menu,name:account_credit_control.credit_policy_configuration_action_menu +msgid "Credit Control Policies" +msgstr "" + +#. module: account_credit_control +#: field:account.invoice,credit_policy_id:0 +#: field:res.company,credit_policy_id:0 field:res.partner,credit_policy_id:0 +msgid "Credit Control Policy" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.credit_control_run +#: model:ir.ui.menu,name:account_credit_control.credit_control_run_menu +msgid "Credit Control Run" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.report.xml,name:account_credit_control.credit_control_summary +msgid "Credit Control Summary" +msgstr "" + +#. module: account_credit_control +#: field:res.company,credit_control_tolerance:0 +msgid "Credit Control Tolerance" +msgstr "" + +#. module: account_credit_control +#: model:res.groups,name:account_credit_control.group_account_credit_control_user +msgid "Credit Control User" +msgstr "" + +#. module: account_credit_control +#: model:email.template,subject:account_credit_control.email_template_credit_control_base +msgid "Credit Control: (${object.current_policy_level.name or 'n/a'})" +msgstr "" + +#. module: account_credit_control +#: field:account.account,credit_control_line_ids:0 +#: field:account.invoice,credit_control_line_ids:0 +#: field:credit.control.communication,credit_control_line_ids:0 +#: model:ir.actions.act_window,name:account_credit_control.act_account_credit_relation_relation +#: model:ir.actions.act_window,name:account_credit_control.act_partner_credit_relation_relation +msgid "Credit Lines" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_run +msgid "Credit control line generator" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy:account_credit_control.credit_control_policy_tree +msgid "Credit control policy" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +msgid "Credit control policy Level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.level:account_credit_control.credit_control_policy_level_tree +msgid "Credit control policy level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +#: view:credit.control.run:account_credit_control.credit_control_run_tree +msgid "Credit control run" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Credit policy" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Credit policy level" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,currency_id:0 +msgid "Currency" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,custom_mail_text:0 +msgid "Custom Mail Message" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,custom_text:0 +msgid "Custom Message" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Date due" +msgstr "Rechnungdatum" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_policy +msgid "Define a reminder policy" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,delay_days:0 +msgid "Delay (in days)" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy.level:account_credit_control.credit_mangement_policy_level_form +msgid "Delay Setting" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy,do_nothing:0 +msgid "Do nothing" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.line,state:0 +#: selection:credit.control.marker,name:0 selection:credit.control.run,state:0 +msgid "Done" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 selection:credit.control.run,state:0 +msgid "Draft" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Draft lines have to be triaged." +msgstr "" + +#. module: account_credit_control +#: help:credit.control.line,state:0 +msgid "" +"Draft lines need to be triaged.\n" +"Ignored lines are lines for which we do not want to send something.\n" +"Draft and ignored lines will be generated again on the next run." +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,amount_due:0 +msgid "Due Amount Tax incl." +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.policy.level,computation_mode:0 +msgid "Due Date" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.policy.level,computation_mode:0 +msgid "Due Date, End Of Month" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,balance_due:0 +msgid "Due balance" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,date_due:0 +msgid "Due date" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.line,channel:0 +#: selection:credit.control.policy.level,channel:0 +msgid "Email" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.level,email_template_id:0 +msgid "Email Template" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.line,state:0 +msgid "Emailing Error" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,date_entry:0 +msgid "Entry date" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +msgid "Error" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Filters" +msgstr "" + +#. module: account_credit_control +#: help:credit.control.policy,do_nothing:0 +msgid "For policies which should not generate lines or are obsolete" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Group By..." +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,id:0 field:credit.control.emailer,id:0 +#: field:credit.control.line,id:0 field:credit.control.marker,id:0 +#: field:credit.control.policy,id:0 field:credit.control.policy.changer,id:0 +#: field:credit.control.policy.level,id:0 field:credit.control.printer,id:0 +#: field:credit.control.run,id:0 +msgid "ID" +msgstr "" + +#. module: account_credit_control +#: help:credit.control.run,manual_ids:0 +msgid "" +"If a credit control line has been generatedon a policy and the policy has " +"been changed in the meantime, it has to be handled manually" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +#: selection:credit.control.marker,name:0 +msgid "Ignored" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,invoice_id:0 +#: model:ir.model,name:account_credit_control.model_account_invoice +msgid "Invoice" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Invoice date" +msgstr "Rechnungdatum" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Invoice number" +msgstr "Rechnungsnummer" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Invoiced amount" +msgstr "Betrag" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +msgid "Issued Lines" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,write_uid:0 +#: field:credit.control.emailer,write_uid:0 +#: field:credit.control.line,write_uid:0 +#: field:credit.control.marker,write_uid:0 +#: field:credit.control.policy,write_uid:0 +#: field:credit.control.policy.changer,write_uid:0 +#: field:credit.control.policy.level,write_uid:0 +#: field:credit.control.printer,write_uid:0 +#: field:credit.control.run,write_uid:0 +msgid "Last Updated by" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,write_date:0 +#: field:credit.control.emailer,write_date:0 +#: field:credit.control.line,write_date:0 +#: field:credit.control.marker,write_date:0 +#: field:credit.control.policy,write_date:0 +#: field:credit.control.policy.changer,write_date:0 +#: field:credit.control.policy.level,write_date:0 +#: field:credit.control.printer,write_date:0 +#: field:credit.control.run,write_date:0 +msgid "Last Updated on" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.line,channel:0 +#: selection:credit.control.policy.level,channel:0 +msgid "Letter" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,current_policy_level:0 +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.policy.level,level:0 +msgid "Level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Lines already sent." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +msgid "Lines marker" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Lines report" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.run,manual_ids:0 +msgid "Lines to handle manually" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Lines which have been ignored from previous runs." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy.level:account_credit_control.credit_mangement_policy_level_form +msgid "Mail and reporting" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +msgid "Mailer" +msgstr "" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +msgid "Manual Credit Control Policy" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +msgid "Manual Lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Manual change" +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.no_follow_1 +#: model:credit.control.policy.level,custom_text:account_credit_control.no_follow_1 +msgid "Manual no follow" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,manually_overridden:0 +msgid "Manually overridden" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.marker,name:0 +msgid "Mark as" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.printer,mark_as_sent:0 +msgid "Mark letter lines as sent" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_emailer +msgid "Mass credit line emailer" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_marker +msgid "Mass marker" +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_printer +msgid "Mass printer" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "More..." +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,move_line_id:0 +msgid "Move line" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.changer,move_line_ids:0 +msgid "Move line to change" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Move lines to affect" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy,name:0 field:credit.control.policy.level,name:0 +msgid "Name" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.changer,new_policy_id:0 +msgid "New Policy to Apply" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.changer,new_policy_level_id:0 +msgid "New level to apply" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/wizard/credit_control_emailer.py:62 +#: code:addons/account_credit_control/wizard/credit_control_marker.py:74 +#: code:addons/account_credit_control/wizard/credit_control_printer.py:60 +#, python-format +msgid "No credit control lines selected." +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.no_follow_1 +msgid "No follow" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy.changer,do_nothing:0 +msgid "No follow policy" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/wizard/credit_control_marker.py:78 +#, python-format +msgid "No lines will be changed. All the selected lines are already done." +msgstr "" + +#. module: account_credit_control +#: help:credit.control.printer,mark_as_sent:0 +msgid "Only letter lines will be marked." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +msgid "Open Credit Control Lines" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Open amount" +msgstr "Offener Betrag" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.2_time_1 +msgid "" +"Our records indicate that we have not received the payment of the above " +"mentioned invoice.\n" +" If it has already been sent, please disregard this notice. If not, " +"please proceed with payment within 10 days.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.3_time_1 +msgid "" +"Our records indicate that we have not received the payment of the above " +"mentioned invoice.\n" +"If it has already been sent, please disregard this notice. If not, please " +"proceed with payment within 10 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.3_time_1 +msgid "" +"Our records indicate that we have not received the payment of the invoices " +"mentioned in the attached document.\n" +"\n" +"If it has already been sent, please disregard this notice. If not, please " +"proceed with payment within 10 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.2_time_1 +msgid "" +"Our records indicate that we have not received the payment of the invoices " +"mentioned in the attached document.\n" +"If it has already been sent, please disregard this notice. If not, please " +"proceed with payment within 10 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.3_time_2 +msgid "" +"Our records indicate that we have not yet received the payment of the above " +"mentioned invoice despite our first reminder.\n" +" If it has already been sent, please disregard this notice. If not, " +"please proceed with payment within 5 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.3_time_2 +msgid "" +"Our records indicate that we have not yet received the payment of the " +"invoices mentioned in the attached document despite our first reminder.\n" +" If it has already been sent, please disregard this notice. If not, " +"please proceed with payment within 5 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.2_time_2 +msgid "" +"Our records indicate that we still have not received the payment of the " +"above mentioned invoice despite our reminder.\n" +"\n" +" If payment have already been sent, please disregard this notice. If " +"not, please proceed with payment.\n" +" If your payment has not been received in the next 5 days, your file " +"will be transfered to our debt\n" +" collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please " +"advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.2_time_2 +msgid "" +"Our records indicate that we still have not received the payment of the " +"invoices mentioned in the attached document despite our reminder.\n" +"\n" +"If payment have already been sent, please disregard this notice. If not, " +"please proceed with payment.\n" +"If your payment has not been received in the next 5 days, your file will be " +"transfered to our debt\n" +" collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please " +"advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.3_time_3 +msgid "" +"Our records indicate that we still have not received the payment of the " +"invoices mentioned in the attached document despite our two reminders.\n" +" If payment have already been sent, please disregard this notice. If " +"not, please proceed with payment.\n" +" If your payment has not been received in the next 5 days, your file " +"will be transfered to our debt collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please " +"advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,policy_level_id:0 +msgid "Overdue Level" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,partner_id:0 +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,partner_id:0 +#: model:ir.model,name:account_credit_control.model_res_partner +msgid "Partner" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:103 +#, python-format +msgid "Please select a policy" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/wizard/credit_control_policy_changer.py:61 +#, python-format +msgid "Please use wizard on customer invoices" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +#: field:credit.control.run,policy_ids:0 +msgid "Policies" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:126 +#, python-format +msgid "Policy \"%s\" has generated %d Credit Control Lines.\n" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:130 +#, python-format +msgid "Policy \"%s\" has not generated any Credit Control Lines.\n" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.policy,level_ids:0 +msgid "Policy Levels" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy.level:account_credit_control.credit_mangement_policy_level_form +msgid "Policy level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +msgid "Policy levels" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.policy.level,computation_mode:0 +msgid "Previous Reminder" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Print" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_printer_wizard +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_printer_wizard_menu_action +msgid "Print Lines" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.open_credit_line_printer_wizard +msgid "Print selected lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Print the selected lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +#: selection:credit.control.marker,name:0 +msgid "Ready To Send" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,policy_id:0 +#: field:credit.control.policy.level,policy_id:0 +msgid "Related Policy" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +#: field:credit.control.run,report:0 +msgid "Report" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Run date" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_emailer_wizard +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_emailer_wizard_menu_action +msgid "Send By Email" +msgstr "" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.open_credit_line_emailer_wizard +msgid "Send an email for the selected lines." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +msgid "Send emails for the selected lines" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +msgid "Send the emails" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Sent" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,mail_message_id:0 +msgid "Sent Email" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,date_sent:0 +msgid "Sent date" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Set current credit level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Set new policy" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,state:0 field:credit.control.run,state:0 +msgid "State" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Summary" +msgstr "Extrakt" + +#. module: account_credit_control +#: help:account.invoice,credit_policy_id:0 +msgid "" +"The Credit Control Policy used for this invoice. If nothing is defined, it " +"will use the account setting or the partner setting." +msgstr "" + +#. module: account_credit_control +#: help:res.partner,credit_policy_id:0 +msgid "" +"The Credit Control Policy used for this partner. This setting can be forced " +"on the invoice. If nothing is defined, it will use the company setting." +msgstr "" + +#. module: account_credit_control +#: help:res.company,credit_policy_id:0 +msgid "" +"The Credit Control Policy used on partners by default. This setting can be " +"overridden on partners or invoices." +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "The line was deprecated by a manual change of policy on invoice." +msgstr "" + +#. module: account_credit_control +#: help:credit.control.line,currency_id:0 +msgid "The optional other currency if it is a multi-currency entry." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/policy.py:258 +#, python-format +msgid "The smallest level can not be of type Previous Reminder" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "These lines are ready to send by email or by letter using the Actions." +msgstr "" + +#. module: account_credit_control +#: help:credit.control.policy,account_ids:0 +msgid "This policy will be active only for the selected accounts" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "" +"This wizard will let you set the overdue policy and level for selected " +"invoices" +msgstr "" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Total Due" +msgstr "Fälliger Restbetrag" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Total Invoiced" +msgstr "Endbetrag" + +#. module: account_credit_control +#: field:credit.control.communication,user_id:0 +msgid "User" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +msgid "Warning: you will maybe not be able to revert this operation." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/line.py:223 +#, python-format +msgid "" +"You are not allowed to delete a credit control line that is not in draft " +"state." +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/policy.py:203 +#, python-format +msgid "" +"You can only use a policy set on account %s.\n" +"Please choose one of the following policies:\n" +" %s" +msgstr "" + +#. module: account_credit_control +#: code:addons/account_credit_control/invoice.py:57 +#, python-format +msgid "" +"You cannot cancel this invoice.\n" +"A payment reminder has already been sent to the customer.\n" +"You must create a credit note and issue a new invoice." +msgstr "" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_communication +msgid "credit control communication" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.line,level:0 +msgid "credit.control.policy.level" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "or" +msgstr "" diff --git a/account_credit_control/i18n/fr.po b/account_credit_control/i18n/fr.po new file mode 100644 index 000000000..651ff4030 --- /dev/null +++ b/account_credit_control/i18n/fr.po @@ -0,0 +1,1357 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_credit_control +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-01-26 10:32+0000\n" +"PO-Revision-Date: 2014-10-30 14:59+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.3_time_3 +msgid "" +"\n" +" Our records indicate that we still have not received the payment of " +"the above mentioned invoice despite our two reminders.\n" +" If payment have already been sent, please disregard this notice. If " +"not, please proceed with payment.\n" +" If your payment has not been received in the next 5 days, your file " +"will be transfered to our debt collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please " +"advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" +"\n" +"Notre comptabilité nous indique que vous avez encore des factures ouvertes " +"malgré nos précédents rappels.\n" +" Si ce courrier à croisé votre paiement veuillez le considérer comme " +"nul et non avenu.\n" +" Si le paiement n'est pas effectué dans les 5 jours votre dossier " +"sera transféré à une société de recouvrement.\n" +"\n" +" Si vous désirez un accord de payment n'hésitez pas à nous contacter " +"advise.\n" +" Un décompte est disponible ci-joint.\n" +"\n" +" En vous remerciant de votre coopération \n" +" " + +#. module: account_credit_control +#: model:email.template,body_html:account_credit_control.email_template_credit_control_base +msgid "" +"\n" +" Dear ${object.contact_address.name or ''}\n" +"
\n" +"
\n" +" ${object.current_policy_level.custom_mail_text}\n" +" " +msgstr "" +"\n" +" Cher/Chère ${object.contact_address.name or ''}\n" +"
\n" +"
\n" +" ${object.current_policy_level.custom_mail_text}\n" +" " + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.3_time_3 +msgid "10 days last reminder" +msgstr "10 jours depuis la dernière relance" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.3_time_1 +msgid "10 days net" +msgstr "10 jours net" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.2_time_1 +#: model:credit.control.policy.level,name:account_credit_control.3_time_2 +msgid "30 days end of month" +msgstr "30 jours fin de mois" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.2_time_2 +msgid "60 days last reminder" +msgstr "Dernier rappel à 60 jours" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_line +msgid "A credit control line" +msgstr "Ligne de relance" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:87 +#, python-format +msgid "A credit control line more recent than %s exists at %s" +msgstr "Une ligne plus récente que %s existe au %s" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_policy_level +msgid "A credit control policy level" +msgstr "Une politique de relance" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:154 +#, python-format +msgid "" +"A credit control run is already running in background, please try later." +msgstr "" +"Un contrôle de relance est déjà en train de tourner en arrière-plan, merci " +"d'essayer à nouveau plus tard." + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:80 +#, python-format +msgid "A run has already been executed more recently than %s" +msgstr "Un contrôle a déjà été exécuté plus récemment que le %s " + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,account_id:0 +#: model:ir.model,name:account_credit_control.model_account_account +msgid "Account" +msgstr "Compte" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: field:credit.control.policy,account_ids:0 +msgid "Accounts" +msgstr "Comptes" + +#. module: account_credit_control +#: field:credit.control.policy,active:0 +msgid "Active" +msgstr "Actif" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.action_wizard_credit_policy_changer +msgid "Allows to manually change credit level" +msgstr "Permet de changer manuellement le niveau de relance" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "An error has occured during the sending of the email." +msgstr "Erreur lors de la génération des mails." + +#. module: account_credit_control +#: code:addons/account_credit_control/policy.py:308 +#, python-format +msgid "Can not get function for computation mode: %s is not implemented" +msgstr "" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Cancel" +msgstr "Annuler" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_marker_wizard +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_marker_wizard_menu_action +msgid "Change Lines' State" +msgstr "Modifier le statut des lignes" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.action_wizard_credit_policy_changer +#: model:ir.actions.act_window,name:account_credit_control.action_wizard_credit_policy_changer_menu_action +msgid "Change current credit policy" +msgstr "Changer la politique de relance courante" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Change the overdue level of current invoice" +msgstr "Changer le niveau de relance de la facture courante" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +msgid "Change the state of the selected lines" +msgstr "Modifier l'état des lignes sélectionnées." + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.open_credit_line_marker_wizard +msgid "Change the state of the selected lines." +msgstr "Modifier l'état des lignes sélectionnées." + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,channel:0 +#: field:credit.control.policy.level,channel:0 +msgid "Channel" +msgstr "Canal" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_res_company +msgid "Companies" +msgstr "Société" + +#. module: account_credit_control +#: field:credit.control.communication,company_id:0 +#: field:credit.control.line,company_id:0 +#: field:credit.control.policy,company_id:0 +msgid "Company" +msgstr "Société" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +msgid "Compute Credit Control Lines" +msgstr "Calculer les relances" + +#. module: account_credit_control +#: field:credit.control.policy.level,computation_mode:0 +msgid "Compute Mode" +msgstr "Mode de calcul" + +#. module: account_credit_control +#: field:credit.control.communication,contact_address:0 +msgid "Contact Address" +msgstr "Adresse de contact" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_form +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: view:credit.control.line:account_credit_control.credit_control_line_tree +msgid "Control Credit Lines" +msgstr "Lignes de relance" + +#. module: account_credit_control +#: field:credit.control.run,date:0 +msgid "Controlling Date" +msgstr "Date de contrôle" + +#. module: account_credit_control +#: field:credit.control.line,date:0 +msgid "Controlling date" +msgstr "Date de relance" + +#. module: account_credit_control +#: field:credit.control.communication,create_uid:0 +#: field:credit.control.emailer,create_uid:0 +#: field:credit.control.line,create_uid:0 +#: field:credit.control.marker,create_uid:0 +#: field:credit.control.policy,create_uid:0 +#: field:credit.control.policy.changer,create_uid:0 +#: field:credit.control.policy.level,create_uid:0 +#: field:credit.control.printer,create_uid:0 +#: field:credit.control.run,create_uid:0 +msgid "Created by" +msgstr "Créé par" + +#. module: account_credit_control +#: field:credit.control.communication,create_date:0 +#: field:credit.control.emailer,create_date:0 +#: field:credit.control.line,create_date:0 +#: field:credit.control.marker,create_date:0 +#: field:credit.control.policy,create_date:0 +#: field:credit.control.policy.changer,create_date:0 +#: field:credit.control.policy.level,create_date:0 +#: field:credit.control.printer,create_date:0 +#: field:credit.control.run,create_date:0 +msgid "Created on" +msgstr "Créé le" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +#: model:ir.ui.menu,name:account_credit_control.base_credit_control_configuration_menu +#: model:ir.ui.menu,name:account_credit_control.base_credit_control_menu +msgid "Credit Control" +msgstr "Relances Clients" + +#. module: account_credit_control +#: model:res.groups,name:account_credit_control.group_account_credit_control_info +msgid "Credit Control Info" +msgstr "Informations de rappel" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +#: field:credit.control.emailer,line_ids:0 +#: field:credit.control.marker,line_ids:0 +#: field:credit.control.printer,line_ids:0 +#: model:ir.actions.act_window,name:account_credit_control.credit_control_line_action +#: model:ir.ui.menu,name:account_credit_control.credit_control_line_action_menu +#: field:res.partner,credit_control_line_ids:0 +msgid "Credit Control Lines" +msgstr "Lignes de relance" + +#. module: account_credit_control +#: model:res.groups,name:account_credit_control.group_account_credit_control_manager +msgid "Credit Control Manager" +msgstr "Responsable Relance client" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.credit_policy_configuration_action +#: model:ir.ui.menu,name:account_credit_control.credit_policy_configuration_action_menu +msgid "Credit Control Policies" +msgstr "Politique de relance" + +#. module: account_credit_control +#: field:account.invoice,credit_policy_id:0 +#: field:res.company,credit_policy_id:0 field:res.partner,credit_policy_id:0 +msgid "Credit Control Policy" +msgstr "Politique de relance" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.credit_control_run +#: model:ir.ui.menu,name:account_credit_control.credit_control_run_menu +msgid "Credit Control Run" +msgstr "Lancer le calcul des rappels" + +#. module: account_credit_control +#: model:ir.actions.report.xml,name:account_credit_control.credit_control_summary +msgid "Credit Control Summary" +msgstr "Résumé des relances" + +#. module: account_credit_control +#: field:res.company,credit_control_tolerance:0 +msgid "Credit Control Tolerance" +msgstr "Pas de relance inférieure à : " + +#. module: account_credit_control +#: model:res.groups,name:account_credit_control.group_account_credit_control_user +msgid "Credit Control User" +msgstr "Utilisateur du module de relance" + +#. module: account_credit_control +#: model:email.template,subject:account_credit_control.email_template_credit_control_base +msgid "Credit Control: (${object.current_policy_level.name or 'n/a'})" +msgstr "Rappel: (${object.current_policy_level.name or 'n/a'})" + +#. module: account_credit_control +#: field:account.account,credit_control_line_ids:0 +#: field:account.invoice,credit_control_line_ids:0 +#: field:credit.control.communication,credit_control_line_ids:0 +#: model:ir.actions.act_window,name:account_credit_control.act_account_credit_relation_relation +#: model:ir.actions.act_window,name:account_credit_control.act_partner_credit_relation_relation +msgid "Credit Lines" +msgstr "Lignes de relance" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_run +msgid "Credit control line generator" +msgstr "Générateur de relance" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy:account_credit_control.credit_control_policy_tree +msgid "Credit control policy" +msgstr "Niveau de relance" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +msgid "Credit control policy Level" +msgstr "Niveau de relance" + +#. module: account_credit_control +#: view:credit.control.policy.level:account_credit_control.credit_control_policy_level_tree +msgid "Credit control policy level" +msgstr "Niveau de relance" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +#: view:credit.control.run:account_credit_control.credit_control_run_tree +msgid "Credit control run" +msgstr "Passe de contrôle de relance" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Credit policy" +msgstr "Politique de relance" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Credit policy level" +msgstr "Niveau de relance" + +#. module: account_credit_control +#: field:credit.control.communication,currency_id:0 +#: field:credit.control.line,currency_id:0 +msgid "Currency" +msgstr "Devise" + +#. module: account_credit_control +#: field:credit.control.policy.level,custom_mail_text:0 +msgid "Custom Mail Message" +msgstr "Email personnalisé" + +#. module: account_credit_control +#: field:credit.control.policy.level,custom_text:0 +msgid "Custom Message" +msgstr "Message personnalisable" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Date due" +msgstr "Date d'échéance" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_policy +msgid "Define a reminder policy" +msgstr "Définir une politique de relance" + +#. module: account_credit_control +#: field:credit.control.policy.level,delay_days:0 +msgid "Delay (in days)" +msgstr "Retard (en jours)" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy.level:account_credit_control.credit_mangement_policy_level_form +msgid "Delay Setting" +msgstr "Paramétrages jours de retard" + +#. module: account_credit_control +#: field:credit.control.policy,do_nothing:0 +msgid "Do nothing" +msgstr "Ignorer" + +#. module: account_credit_control +#: selection:credit.control.line,state:0 +#: selection:credit.control.marker,name:0 selection:credit.control.run,state:0 +msgid "Done" +msgstr "Fait" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 selection:credit.control.run,state:0 +msgid "Draft" +msgstr "Brouillon" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Draft lines have to be triaged." +msgstr "Les lignes brouillon doivent être triées" + +#. module: account_credit_control +#: help:credit.control.line,state:0 +msgid "" +"Draft lines need to be triaged.\n" +"Ignored lines are lines for which we do not want to send something.\n" +"Draft and ignored lines will be generated again on the next run." +msgstr "" +"Lignes brouillons à traiter.\n" +"Les lignes ignorées ne seront pas traitées.\n" +"Les lignes brouillons ou ignorées seront régénérées lors du prochain " +"contrôle." + +#. module: account_credit_control +#: field:credit.control.line,amount_due:0 +msgid "Due Amount Tax incl." +msgstr "Montant dû TTC." + +#. module: account_credit_control +#: selection:credit.control.policy.level,computation_mode:0 +msgid "Due Date" +msgstr "Date d'échéance" + +#. module: account_credit_control +#: selection:credit.control.policy.level,computation_mode:0 +msgid "Due Date, End Of Month" +msgstr "Date d'échéance, fin de mois" + +#. module: account_credit_control +#: field:credit.control.line,balance_due:0 +msgid "Due balance" +msgstr "Montant total" + +#. module: account_credit_control +#: field:credit.control.line,date_due:0 +msgid "Due date" +msgstr "Date d'échéance" + +#. module: account_credit_control +#: selection:credit.control.line,channel:0 +#: selection:credit.control.policy.level,channel:0 +msgid "Email" +msgstr "E-mail" + +#. module: account_credit_control +#: field:credit.control.policy.level,email_template_id:0 +msgid "Email Template" +msgstr "Modèle d'e-mail" + +#. module: account_credit_control +#: selection:credit.control.line,state:0 +msgid "Emailing Error" +msgstr "Erreur sur E-mail" + +#. module: account_credit_control +#: field:credit.control.line,date_entry:0 +msgid "Entry date" +msgstr "Date de l'écriture" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +msgid "Error" +msgstr "Erreur" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Filters" +msgstr "Filtres" + +#. module: account_credit_control +#: help:credit.control.policy,do_nothing:0 +msgid "For policies which should not generate lines or are obsolete" +msgstr "" +"Pour les politiques qui ne doivent pas générer de lignes ou sont obsolètes" + +#. module: account_credit_control +#: field:credit.control.run,line_ids:0 +msgid "Generated lines" +msgstr "Lignes générées" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Group By..." +msgstr "Grouper Par..." + +#. module: account_credit_control +#: field:credit.control.communication,id:0 field:credit.control.emailer,id:0 +#: field:credit.control.line,id:0 field:credit.control.marker,id:0 +#: field:credit.control.policy,id:0 field:credit.control.policy.changer,id:0 +#: field:credit.control.policy.level,id:0 field:credit.control.printer,id:0 +#: field:credit.control.run,id:0 +msgid "ID" +msgstr "" + +#. module: account_credit_control +#: help:credit.control.run,manual_ids:0 +msgid "" +"If a credit control line has been generatedon a policy and the policy has " +"been changed in the meantime, it has to be handled manually" +msgstr "" +"Si la ligne a été générée avec une politique de relance différente elle doit " +"être traitée manuellement" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +#: selection:credit.control.marker,name:0 +msgid "Ignored" +msgstr "Ignorée" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,invoice_id:0 +#: model:ir.model,name:account_credit_control.model_account_invoice +msgid "Invoice" +msgstr "Facture" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Invoice date" +msgstr "Date de facture" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Invoice number" +msgstr "Numéro de facture" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Invoiced amount" +msgstr "Total de la facture" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +msgid "Issued Lines" +msgstr "Lignes de relance" + +#. module: account_credit_control +#: field:credit.control.communication,write_uid:0 +#: field:credit.control.emailer,write_uid:0 +#: field:credit.control.line,write_uid:0 +#: field:credit.control.marker,write_uid:0 +#: field:credit.control.policy,write_uid:0 +#: field:credit.control.policy.changer,write_uid:0 +#: field:credit.control.policy.level,write_uid:0 +#: field:credit.control.printer,write_uid:0 +#: field:credit.control.run,write_uid:0 +msgid "Last Updated by" +msgstr "" + +#. module: account_credit_control +#: field:credit.control.communication,write_date:0 +#: field:credit.control.emailer,write_date:0 +#: field:credit.control.line,write_date:0 +#: field:credit.control.marker,write_date:0 +#: field:credit.control.policy,write_date:0 +#: field:credit.control.policy.changer,write_date:0 +#: field:credit.control.policy.level,write_date:0 +#: field:credit.control.printer,write_date:0 +#: field:credit.control.run,write_date:0 +msgid "Last Updated on" +msgstr "" + +#. module: account_credit_control +#: selection:credit.control.line,channel:0 +#: selection:credit.control.policy.level,channel:0 +msgid "Letter" +msgstr "Lettre" + +#. module: account_credit_control +#: field:credit.control.communication,current_policy_level:0 +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.policy.level,level:0 +msgid "Level" +msgstr "Niveau" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Lines" +msgstr "Lignes" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Lines already sent." +msgstr "Lignes déjà traitées." + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +msgid "Lines marker" +msgstr "Traiter les lignes" + +#. module: account_credit_control +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Lines report" +msgstr "Lignes de relance" + +#. module: account_credit_control +#: field:credit.control.run,manual_ids:0 +msgid "Lines to handle manually" +msgstr "A traiter manuellement" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Lines which have been ignored from previous runs." +msgstr "Lignes ignorées lors des relances précédentes." + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy.level:account_credit_control.credit_mangement_policy_level_form +msgid "Mail and reporting" +msgstr "Lettres et e-mails" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +msgid "Mailer" +msgstr "Mailer" + +#. module: account_credit_control +#: view:account.invoice:account_credit_control.invoice_followup_form_view +msgid "Manual Credit Control Policy" +msgstr "Politique de relance manuelle" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +msgid "Manual Lines" +msgstr "Lignes manuelles" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Manual change" +msgstr "Changement manuel" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.no_follow_1 +#: model:credit.control.policy.level,custom_text:account_credit_control.no_follow_1 +msgid "Manual no follow" +msgstr "Ne pas suivre (Manuel)" + +#. module: account_credit_control +#: field:credit.control.line,manually_overridden:0 +msgid "Manually overridden" +msgstr "Mise à jour manuelle" + +#. module: account_credit_control +#: field:credit.control.marker,name:0 +msgid "Mark as" +msgstr "Marquer comme" + +#. module: account_credit_control +#: field:credit.control.printer,mark_as_sent:0 +msgid "Mark letter lines as sent" +msgstr "Marquer comme traitées" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_emailer +msgid "Mass credit line emailer" +msgstr "Publipostage par e-mail des rappels" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_marker +msgid "Mass marker" +msgstr "Traiter en masse" + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_printer +msgid "Mass printer" +msgstr "Imprimer en masse" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "More..." +msgstr "Plus..." + +#. module: account_credit_control +#: field:credit.control.line,move_line_id:0 +msgid "Move line" +msgstr "Écriture comptable" + +#. module: account_credit_control +#: field:credit.control.policy.changer,move_line_ids:0 +msgid "Move line to change" +msgstr "Écriture comptable à changer" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Move lines to affect" +msgstr "Écriture comptable à traiter" + +#. module: account_credit_control +#: field:credit.control.policy,name:0 field:credit.control.policy.level,name:0 +msgid "Name" +msgstr "Nom" + +#. module: account_credit_control +#: field:credit.control.policy.changer,new_policy_id:0 +msgid "New Policy to Apply" +msgstr "Nouvelle politique" + +#. module: account_credit_control +#: field:credit.control.policy.changer,new_policy_level_id:0 +msgid "New level to apply" +msgstr "Nouveau niveau de relance" + +#. module: account_credit_control +#: code:addons/account_credit_control/wizard/credit_control_emailer.py:62 +#: code:addons/account_credit_control/wizard/credit_control_marker.py:74 +#: code:addons/account_credit_control/wizard/credit_control_printer.py:60 +#, python-format +msgid "No credit control lines selected." +msgstr "Pas de ligne de relance sélectionnée" + +#. module: account_credit_control +#: model:credit.control.policy.level,name:account_credit_control.no_follow_1 +msgid "No follow" +msgstr "Pas de suivi" + +#. module: account_credit_control +#: field:credit.control.policy.changer,do_nothing:0 +msgid "No follow policy" +msgstr "Politique sans suivi" + +#. module: account_credit_control +#: code:addons/account_credit_control/wizard/credit_control_marker.py:78 +#, python-format +msgid "No lines will be changed. All the selected lines are already done." +msgstr "" +"Aucune ligne ne sera modifiée. Toutes les lignes sélectionnées sont déjà " +"terminées." + +#. module: account_credit_control +#: help:credit.control.printer,mark_as_sent:0 +msgid "Only letter lines will be marked." +msgstr "Seules les relances par courrier seront traitées." + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +msgid "Open Credit Control Lines" +msgstr "Ouvrir les lignes de relance" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Open amount" +msgstr "Restant dû" + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.2_time_1 +msgid "" +"Our records indicate that we have not received the payment of the above " +"mentioned invoice.\n" +" If it has already been sent, please disregard this notice. If not, " +"please proceed with payment within 10 days.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" +"Notre comptabilité nous informe que les factures ci-dessous n'ont pas été " +"payées malgré un précédent rappel.\n" +" Si ce courrier à croisé votre paiement veuillez le considérer comme " +"nul et non avenu. Sinon, Merci de procéder au paiement dans les 10 jours.\n" +"\n" +" En vous remerciant de votre coopération.\n" +"\n" +"Salutations\n" +" " + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.3_time_1 +msgid "" +"Our records indicate that we have not received the payment of the above " +"mentioned invoice.\n" +"If it has already been sent, please disregard this notice. If not, please " +"proceed with payment within 10 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" +"Notre comptabilité nous informe que les factures ci-dessous n'ont pas été " +"payées malgré un précédent rappel.\n" +" Si ce courrier a croisé votre paiement veuillez le considérer comme " +"nul et non avenu. Sinon, Merci de procéder au paiement dans les 10 jours.\n" +"\n" +" En vous remerciant de votre coopération.\n" +"\n" +"Salutations\n" +" " + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.3_time_1 +msgid "" +"Our records indicate that we have not received the payment of the invoices " +"mentioned in the attached document.\n" +"\n" +"If it has already been sent, please disregard this notice. If not, please " +"proceed with payment within 10 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" +"Notre comptabilité nous informe que les factures mentionnées dans le " +"document ci-joint n'ont pas été payées malgré un précédent rappel.\n" +" Si ce courrier a croisé votre paiement veuillez le considérer comme " +"nul et non avenu. Sinon, Merci de procéder au paiement dans les 10 jours.\n" +"\n" +" En vous remerciant de votre coopération.\n" +"\n" +"Salutations\n" +" " + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.2_time_1 +msgid "" +"Our records indicate that we have not received the payment of the invoices " +"mentioned in the attached document.\n" +"If it has already been sent, please disregard this notice. If not, please " +"proceed with payment within 10 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" +"Notre comptabilité nous informe que les factures mentionnées dans le " +"document ci-joint n'ont pas été payées malgré un précédent rappel.\n" +" Si ce courrier a croisé votre paiement veuillez le considérer comme " +"nul et non avenu. Sinon, Merci de procéder au paiement dans les 10 jours.\n" +"\n" +" En vous remerciant de votre coopération.\n" +"\n" +"Salutations\n" +" " + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.3_time_2 +msgid "" +"Our records indicate that we have not yet received the payment of the above " +"mentioned invoice despite our first reminder.\n" +" If it has already been sent, please disregard this notice. If not, " +"please proceed with payment within 5 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" +"Notre comptabilité nous informe que les factures ci-dessous n'ont pas été " +"payées malgré un précédent rappel.\n" +" Si ce courrier à croisé votre paiement veuillez le considérer comme " +"nul et non avenu. Sinon, Merci de procéder au paiement dans les 5 jours.\n" +"\n" +" En vous remerciant de votre coopération.\n" +"\n" +"Salutations\n" +" " + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.3_time_2 +msgid "" +"Our records indicate that we have not yet received the payment of the " +"invoices mentioned in the attached document despite our first reminder.\n" +" If it has already been sent, please disregard this notice. If not, " +"please proceed with payment within 5 days.\n" +"\n" +"Thank you in advance for your anticipated cooperation in this matter.\n" +"\n" +"Best regards\n" +" " +msgstr "" +"Notre comptabilité nous informe que les factures mentionnées dans le " +"document ci-joint n'ont pas été payées malgré un précédent rappel.\n" +" Si ce courrier à croisé votre paiement veuillez le considérer comme " +"nul et non avenu. Sinon, Merci de procéder au paiement dans les 5 jours.\n" +"\n" +" En vous remerciant de votre coopération.\n" +"\n" +"Salutations\n" +" " + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_text:account_credit_control.2_time_2 +msgid "" +"Our records indicate that we still have not received the payment of the " +"above mentioned invoice despite our reminder.\n" +"\n" +" If payment have already been sent, please disregard this notice. If " +"not, please proceed with payment.\n" +" If your payment has not been received in the next 5 days, your file " +"will be transfered to our debt\n" +" collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please " +"advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" +"Notre comptabilité nous indique que vous avez encore des factures ouvertes " +"malgré nos précédents rappels.\n" +" Si ce courrier a croisé votre paiement veuillez le considérer comme " +"nul et non avenu.\n" +" Si le paiement n'est pas effectué dans les 5 jours votre dossier " +"sera transféré à une société de recouvrement.\n" +"\n" +" Si vous désirez un accord de paiement n'hésitez pas à nous " +"contacter. \n" +" Un décompte est disponible ci-joint.\n" +"\n" +" En vous remerciant de votre coopération\n" +" " + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.2_time_2 +msgid "" +"Our records indicate that we still have not received the payment of the " +"invoices mentioned in the attached document despite our reminder.\n" +"\n" +"If payment have already been sent, please disregard this notice. If not, " +"please proceed with payment.\n" +"If your payment has not been received in the next 5 days, your file will be " +"transfered to our debt\n" +" collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please " +"advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" +"Notre comptabilité nous indique que vous avez encore des factures ouvertes " +"malgré nos précédents rappels.\n" +" Si ce courrier a croisé votre paiement veuillez le considérer comme " +"nul et non avenu.\n" +" Si le paiement n'est pas effectué dans les 5 jours votre dossier " +"sera transféré à une société de recouvrement.\n" +"\n" +" Si vous désirez un accord de paiement n'hésitez pas à nous " +"contacter. \n" +" Un décompte est disponible ci-joint.\n" +"\n" +" En vous remerciant de votre coopération " + +#. module: account_credit_control +#: model:credit.control.policy.level,custom_mail_text:account_credit_control.3_time_3 +msgid "" +"Our records indicate that we still have not received the payment of the " +"invoices mentioned in the attached document despite our two reminders.\n" +" If payment have already been sent, please disregard this notice. If " +"not, please proceed with payment.\n" +" If your payment has not been received in the next 5 days, your file " +"will be transfered to our debt collection agency.\n" +"\n" +" Should you need us to arrange a payment plan for you, please " +"advise.\n" +" A customer account statement is enclosed for you convenience.\n" +"\n" +" Thank you in advance for your anticipated cooperation in this " +"matter.\n" +"\n" +" Best regards\n" +" " +msgstr "" +"Notre comptabilité nous indique que vous avez encore des factures ouvertes " +"malgré nos précédents rappels.\n" +" Si ce courrier a croisé votre paiement veuillez le considérer comme " +"nul et non avenu.\n" +" Si le paiement n'est pas effectué dans les 5 jours votre dossier " +"sera transféré à une société de recouvrement.\n" +"\n" +" Si vous désirez un accord de paiement n'hésitez pas à nous " +"contacter. \n" +" Un décompte est disponible ci-joint.\n" +"\n" +" En vous remerciant de votre coopération \n" +" " + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_mail_mail +msgid "Outgoing Mails" +msgstr "Courriels envoyés" + +#. module: account_credit_control +#: field:credit.control.line,policy_level_id:0 +msgid "Overdue Level" +msgstr "Niveau de relance" + +#. module: account_credit_control +#: field:credit.control.communication,partner_id:0 +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: field:credit.control.line,partner_id:0 +#: model:ir.model,name:account_credit_control.model_res_partner +msgid "Partner" +msgstr "Client" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:103 +#, python-format +msgid "Please select a policy" +msgstr "Choisissez une politique" + +#. module: account_credit_control +#: code:addons/account_credit_control/wizard/credit_control_policy_changer.py:61 +#, python-format +msgid "Please use wizard on customer invoices" +msgstr "Utilisez l'action sur les factures clients" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +#: field:credit.control.run,policy_ids:0 +msgid "Policies" +msgstr "Politiques" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:132 +#, python-format +msgid "Policy \"%s\" has generated %d Credit Control Lines.
" +msgstr "" +"La politique de relance \"%s\" a généré %d lignes de relance." +"
" + +#. module: account_credit_control +#: code:addons/account_credit_control/run.py:136 +#, python-format +msgid "Policy \"%s\" has not generated any Credit Control Lines.
" +msgstr "" +"La politique de relance \"%s\" n'a pas généré de lignes de relance." +"
" + +#. module: account_credit_control +#: field:credit.control.policy,level_ids:0 +msgid "Policy Levels" +msgstr "Niveaux de relance" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +#: view:credit.control.policy.level:account_credit_control.credit_mangement_policy_level_form +msgid "Policy level" +msgstr "Niveau de relance" + +#. module: account_credit_control +#: view:credit.control.policy:account_credit_control.credit_control_policy_form +msgid "Policy levels" +msgstr "Niveaux de relance" + +#. module: account_credit_control +#: selection:credit.control.policy.level,computation_mode:0 +msgid "Previous Reminder" +msgstr "Précédent rappel" + +#. module: account_credit_control +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Print" +msgstr "Imprimer" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_printer_wizard +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_printer_wizard_menu_action +msgid "Print Lines" +msgstr "Imprimer la sélection" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.open_credit_line_printer_wizard +msgid "Print selected lines" +msgstr "Imprimer la sélection" + +#. module: account_credit_control +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "Print the selected lines" +msgstr "Imprimer la sélection" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +#: selection:credit.control.line,state:0 +#: selection:credit.control.marker,name:0 +msgid "Ready To Send" +msgstr "Prêt à l'envoi" + +#. module: account_credit_control +#: field:credit.control.line,policy_id:0 +#: field:credit.control.policy.level,policy_id:0 +msgid "Related Policy" +msgstr "Niveau de relance" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Reminder" +msgstr "Rappel" + +#. module: account_credit_control +#: view:credit.control.run:account_credit_control.credit_control_run_form +#: field:credit.control.run,report:0 +msgid "Report" +msgstr "Lettre" + +#. module: account_credit_control +#: field:credit.control.communication,report_date:0 +msgid "Report Date" +msgstr "Date du rapport" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Run date" +msgstr "Date de relance" + +#. module: account_credit_control +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_emailer_wizard +#: model:ir.actions.act_window,name:account_credit_control.open_credit_line_emailer_wizard_menu_action +msgid "Send By Email" +msgstr "Envoyer par email" + +#. module: account_credit_control +#: model:ir.actions.act_window,help:account_credit_control.open_credit_line_emailer_wizard +msgid "Send an email for the selected lines." +msgstr "Envoyer les rappels par email." + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +msgid "Send emails for the selected lines" +msgstr "Envoyer un email depuis les lignes de relances sélectionnées" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +msgid "Send the emails" +msgstr "Envoyer les courriels" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "Sent" +msgstr "Envoyées" + +#. module: account_credit_control +#: field:credit.control.line,mail_message_id:0 +msgid "Sent Email" +msgstr "Courriels envoyés" + +#. module: account_credit_control +#: field:credit.control.line,date_sent:0 +msgid "Sent date" +msgstr "Date d'envoi" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Set current credit level" +msgstr "Définir le niveau de relance actuel" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "Set new policy" +msgstr "Définir une nouvelle politique de relance" + +#. module: account_credit_control +#: field:credit.control.line,run_id:0 +msgid "Source" +msgstr "Source" + +#. module: account_credit_control +#: field:credit.control.line,state:0 field:credit.control.run,state:0 +msgid "State" +msgstr "État" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Summary" +msgstr "Listes des factures en attente de règlement" + +#. module: account_credit_control +#: help:account.invoice,credit_policy_id:0 +msgid "" +"The Credit Control Policy used for this invoice. If nothing is defined, it " +"will use the account setting or the partner setting." +msgstr "" +"Il s'agit de la politique de relance propre à cette facture Si vide, la " +"politique de relance par défaut sera utilisée." + +#. module: account_credit_control +#: help:res.partner,credit_policy_id:0 +msgid "" +"The Credit Control Policy used for this partner. This setting can be forced " +"on the invoice. If nothing is defined, it will use the company setting." +msgstr "" +"Politique de relance utilisée pour ce client. (Vous pouvez aussi en définir " +"une autre au niveau d'une des factures de ce client.) Si vide, la politique " +"par défaut (au niveau de la société) sera appliquée." + +#. module: account_credit_control +#: help:res.company,credit_policy_id:0 +msgid "" +"The Credit Control Policy used on partners by default. This setting can be " +"overridden on partners or invoices." +msgstr "" +"Politique de relance par défaut du client. (Ce paramétrage peut être défini " +"plus spécifiquement au niveau de la facture)." + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "The line was deprecated by a manual change of policy on invoice." +msgstr "" +"La ligne a été remplacée par un changement manuel de politique sur la " +"facture." + +#. module: account_credit_control +#: help:credit.control.line,currency_id:0 +msgid "The optional other currency if it is a multi-currency entry." +msgstr "Les autres devises optionnelles en cas de multi-devises." + +#. module: account_credit_control +#: code:addons/account_credit_control/policy.py:258 +#, python-format +msgid "The smallest level can not be of type Previous Reminder" +msgstr "Le premier niveau ne peut pas être basé sur un précédent rappel" + +#. module: account_credit_control +#: view:credit.control.line:account_credit_control.credit_control_line_search +msgid "These lines are ready to send by email or by letter using the Actions." +msgstr "Ces lignes sont prêtes à être traitées" + +#. module: account_credit_control +#: help:credit.control.policy,account_ids:0 +msgid "This policy will be active only for the selected accounts" +msgstr "" +"Cette politique de relance sera active seulement pour les comptes " +"sélectionnés" + +#. module: account_credit_control +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +msgid "" +"This wizard will let you set the overdue policy and level for selected " +"invoices" +msgstr "" +"Cette action vous permet de définir une politique et un niveau de relance " +"pour les factures sélectionnées" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Total Due" +msgstr "Total dû" + +#. module: account_credit_control +#: view:website:account_credit_control.report_credit_control_summary_document +msgid "Total Invoiced" +msgstr "Total facturé" + +#. module: account_credit_control +#: field:credit.control.communication,user_id:0 +msgid "User" +msgstr "Utilisateur" + +#. module: account_credit_control +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +msgid "Warning: you will maybe not be able to revert this operation." +msgstr "Attention: Cette opération ne peut pas être annulée" + +#. module: account_credit_control +#: code:addons/account_credit_control/line.py:223 +#, python-format +msgid "" +"You are not allowed to delete a credit control line that is not in draft " +"state." +msgstr "" +"Vous ne pouvez pas supprimer une ligne de relance qui n'est pas en brouillon" + +#. module: account_credit_control +#: code:addons/account_credit_control/policy.py:203 +#, python-format +msgid "" +"You can only use a policy set on account %s.\n" +"Please choose one of the following policies:\n" +" %s" +msgstr "" +"Vous ne pouvez utiliser qu'une politique associée au compte %s.Vous pouvez " +"choisir une des politique suivantes:\n" +" %s" + +#. module: account_credit_control +#: code:addons/account_credit_control/invoice.py:57 +#, python-format +msgid "" +"You cannot cancel this invoice.\n" +"A payment reminder has already been sent to the customer.\n" +"You must create a credit note and issue a new invoice." +msgstr "" +"Vous ne pouvez pas annuler cette facture ! Une lettre de relance a été " +"envoyé au client. Vous devez créer un avoir et établir une nouvelle facture." + +#. module: account_credit_control +#: model:ir.model,name:account_credit_control.model_credit_control_communication +msgid "credit control communication" +msgstr "Lettre de relance" + +#. module: account_credit_control +#: field:credit.control.line,level:0 +msgid "credit.control.policy.level" +msgstr "Une politique de relance" + +#. module: account_credit_control +#: view:credit.control.emailer:account_credit_control.credit_line_emailer_form +#: view:credit.control.marker:account_credit_control.credit_line_marker_form +#: view:credit.control.policy.changer:account_credit_control.credit_control_policy_changer_form +#: view:credit.control.printer:account_credit_control.credit_line_printer_form +msgid "or" +msgstr "ou" diff --git a/account_credit_control/invoice.py b/account_credit_control/invoice.py new file mode 100644 index 000000000..f74be82c0 --- /dev/null +++ b/account_credit_control/invoice.py @@ -0,0 +1,67 @@ +# -*- 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 . +# +############################################################################## +from openerp import models, fields, api, _ + + +class AccountInvoice(models.Model): + """Check on cancelling of an invoice""" + _inherit = 'account.invoice' + + credit_policy_id = fields.Many2one( + 'credit.control.policy', + string='Credit Control Policy', + help="The Credit Control Policy used for this " + "invoice. If nothing is defined, it will " + "use the account setting or the partner " + "setting.", + readonly=True, + copy=False, + ) + + credit_control_line_ids = fields.One2many( + 'credit.control.line', 'invoice_id', + string='Credit Lines', + readonly=True, + copy=False, + ) + + @api.multi + def action_cancel(self): + """Prevent to cancel invoice related to credit line""" + # We will search if this invoice is linked with credit + cc_line_obj = self.env['credit.control.line'] + for invoice in self: + nondraft_domain = [('invoice_id', '=', invoice.id), + ('state', '!=', 'draft')] + cc_nondraft_lines = cc_line_obj.search(nondraft_domain) + if cc_nondraft_lines: + raise api.Warning( + _('You cannot cancel this invoice.\n' + 'A payment reminder has already been ' + 'sent to the customer.\n' + 'You must create a credit note and ' + 'issue a new invoice.') + ) + draft_domain = [('invoice_id', '=', invoice.id), + ('state', '=', 'draft')] + cc_draft_line = cc_line_obj.search(draft_domain) + cc_draft_line.unlink() + return super(AccountInvoice, self).action_cancel() diff --git a/account_credit_control/line.py b/account_credit_control/line.py new file mode 100644 index 000000000..326778870 --- /dev/null +++ b/account_credit_control/line.py @@ -0,0 +1,230 @@ +# -*- 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 . +# +############################################################################## +import logging + +from openerp import models, fields, api, _ + +logger = logging.getLogger('credit.line.control') + + +class CreditControlLine(models.Model): + """ A credit control line describes an amount due by a customer for a due date. + + A line is created once the due date of the payment is exceeded. + It is created in "draft" and some actions are available (send by email, + print, ...) + """ + + _name = "credit.control.line" + _description = "A credit control line" + _rec_name = "id" + _order = "date DESC" + + date = fields.Date(string='Controlling date', + required=True, + select=True) + # maturity date of related move line we do not use + # a related field in order to + # allow manual changes + date_due = fields.Date(string='Due date', + required=True, + readonly=True, + states={'draft': [('readonly', False)]}) + + date_entry = fields.Date(string='Entry date', + related='move_line_id.date', + store=True, + readonly=True) + + date_sent = fields.Date(string='Sent date', + readonly=True, + states={'draft': [('readonly', False)]}) + + state = fields.Selection([('draft', 'Draft'), + ('ignored', 'Ignored'), + ('to_be_sent', 'Ready To Send'), + ('sent', 'Done'), + ('error', 'Error'), + ('email_error', 'Emailing Error')], + 'State', + required=True, + readonly=True, + default='draft', + help="Draft lines need to be triaged.\n" + "Ignored lines are lines for which we do " + "not want to send something.\n" + "Draft and ignored lines will be " + "generated again on the next run.") + + channel = fields.Selection([('letter', 'Letter'), + ('email', 'Email')], + string='Channel', + required=True, + readonly=True, + states={'draft': [('readonly', False)]}) + + invoice_id = fields.Many2one('account.invoice', + string='Invoice', + readonly=True) + + partner_id = fields.Many2one('res.partner', + string='Partner', + required=True) + + amount_due = fields.Float(string='Due Amount Tax incl.', + required=True, readonly=True) + + balance_due = fields.Float(string='Due balance', required=True, + readonly=True) + + mail_message_id = fields.Many2one('mail.mail', string='Sent Email', + readonly=True) + + move_line_id = fields.Many2one('account.move.line', + string='Move line', + required=True, + readonly=True) + + account_id = fields.Many2one('account.account', + related='move_line_id.account_id', + store=True, + readonly=True) + + currency_id = fields.Many2one('res.currency', + related='move_line_id.currency_id', + store=True, + readonly=True) + + company_id = fields.Many2one('res.company', + related='move_line_id.company_id', + store=True, + readonly=True) + + # we can allow a manual change of policy in draft state + policy_level_id = fields.Many2one('credit.control.policy.level', + string='Overdue Level', + required=True, + readonly=True, + states={'draft': [('readonly', False)]}) + + policy_id = fields.Many2one('credit.control.policy', + related='policy_level_id.policy_id', + store=True, + readonly=True) + + level = fields.Integer('credit.control.policy.level', + related='policy_level_id.level', + store=True, + readonly=True) + + manually_overridden = fields.Boolean(string='Manually overridden') + + run_id = fields.Many2one(comodel_name='credit.control.run', + string='Source') + + @api.model + def _prepare_from_move_line(self, move_line, level, controlling_date, + open_amount): + """ Create credit control line """ + data = {} + data['date'] = controlling_date + 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['partner_id'] = move_line.partner_id.id + data['amount_due'] = (move_line.amount_currency or move_line.debit or + move_line.credit) + data['balance_due'] = open_amount + data['policy_level_id'] = level.id + data['move_line_id'] = move_line.id + return data + + @api.model + def create_or_update_from_mv_lines(self, lines, level, controlling_date, + check_tolerance=True): + """ Create or update line based on levels + + if check_tolerance is true credit line will not be + created if open amount is too small. + eg. we do not want to send a letter for 10 cents + of open amount. + + :param lines: move.line id recordset + :param level: credit.control.policy.level record + :param controlling_date: date string of the credit controlling date. + Generally it should be the same + as create date + :param check_tolerance: boolean if True credit line + will not be generated if open amount + is smaller than company defined + tolerance + + :returns: recordset of created credit lines + """ + currency_obj = self.env['res.currency'] + user = self.env.user + currencies = currency_obj.search([]) + + tolerance = {} + tolerance_base = user.company_id.credit_control_tolerance + user_currency = user.company_id.currency_id + for currency in currencies: + tolerance[currency.id] = currency.compute(tolerance_base, + user_currency) + + new_lines = self.browse() + for move_line in lines: + open_amount = move_line.amount_residual_currency + cur_tolerance = tolerance.get(move_line.currency_id.id, + tolerance_base) + if check_tolerance and open_amount < cur_tolerance: + continue + vals = self._prepare_from_move_line(move_line, + level, + controlling_date, + open_amount) + line = self.create(vals) + new_lines += line + + # when we have lines generated earlier in draft, + # on the same level, it means that we have left + # them, so they are to be considered as ignored + previous_drafts = self.search([('move_line_id', '=', move_line.id), + ('policy_level_id', '=', level.id), + ('state', '=', 'draft'), + ('id', '!=', line.id)]) + if previous_drafts: + previous_drafts.write({'state': 'ignored'}) + + return new_lines + + @api.multi + def unlink(self): + for line in self: + if line.state != 'draft': + raise api.Warning( + _('You are not allowed to delete a credit control ' + 'line that is not in draft state.') + ) + + return super(CreditControlLine, self).unlink() diff --git a/account_credit_control/line_view.xml b/account_credit_control/line_view.xml new file mode 100644 index 000000000..9538c577b --- /dev/null +++ b/account_credit_control/line_view.xml @@ -0,0 +1,171 @@ + + + + credit.control.line.form + credit.control.line + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + Credit Control Lines + credit.control.line + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + credit.control.line.tree + credit.control.line + + + + + + + + + + + + + + + + + + + + + + + + + + Credit Control Lines + ir.actions.act_window + credit.control.line + + form + tree,form + + {'search_default_filter_draft': 1, 'search_default_filter_to_be_sent': 1} + + + + + + + +
+
diff --git a/account_credit_control/mail.py b/account_credit_control/mail.py new file mode 100644 index 000000000..7ec9be86d --- /dev/null +++ b/account_credit_control/mail.py @@ -0,0 +1,29 @@ +# -*- 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 . +# +############################################################################## +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") diff --git a/account_credit_control/partner.py b/account_credit_control/partner.py new file mode 100644 index 000000000..d7669c101 --- /dev/null +++ b/account_credit_control/partner.py @@ -0,0 +1,58 @@ +# -*- 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 . +# +############################################################################## +from openerp import models, fields, api + + +class ResPartner(models.Model): + """ Add a settings on the credit control policy to use on the partners, + and links to the credit control lines. + """ + + _inherit = "res.partner" + + credit_policy_id = fields.Many2one( + 'credit.control.policy', + string='Credit Control Policy', + domain="[('account_ids', 'in', property_account_receivable)]", + help="The Credit Control Policy used for this " + "partner. This setting can be forced on the " + "invoice. If nothing is defined, it will use " + "the company setting.", + ) + credit_control_line_ids = fields.One2many('credit.control.line', + 'invoice_id', + string='Credit Control Lines', + readonly=True) + + @api.constrains('credit_policy_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 + not partner.credit_policy_id): + continue + account = partner.property_account_receivable + policy = partner.credit_policy_id + try: + policy.check_policy_against_account(account) + except api.Warning as err: + # constrains should raise ValidationError exceptions + raise api.ValidationError(err) diff --git a/account_credit_control/partner_view.xml b/account_credit_control/partner_view.xml new file mode 100644 index 000000000..c6c4c89fd --- /dev/null +++ b/account_credit_control/partner_view.xml @@ -0,0 +1,24 @@ + + + + partner.credit_control.form.view + res.partner + + + + + + + + + + + + diff --git a/account_credit_control/policy.py b/account_credit_control/policy.py new file mode 100644 index 000000000..0e2b03dfe --- /dev/null +++ b/account_credit_control/policy.py @@ -0,0 +1,406 @@ +# -*- 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 . +# +############################################################################## +from openerp import models, fields, api, _ + + +class CreditControlPolicy(models.Model): + """ Define a policy of reminder """ + + _name = "credit.control.policy" + _description = """Define a reminder policy""" + + name = fields.Char('Name', required=True) + level_ids = fields.One2many('credit.control.policy.level', + 'policy_id', + string='Policy Levels') + do_nothing = fields.Boolean('Do nothing', + help='For policies which should not ' + 'generate lines or are obsolete') + company_id = fields.Many2one('res.company', string='Company') + account_ids = fields.Many2many( + 'account.account', + string='Accounts', + required=True, + domain="[('type', '=', 'receivable')]", + help="This policy will be active only" + " for the selected accounts", + ) + active = fields.Boolean('Active', default=True) + + @api.multi + def _move_lines_domain(self, controlling_date): + """ Build the default domain for searching move lines """ + self.ensure_one() + return [('account_id', 'in', self.account_ids.ids), + ('date_maturity', '<=', controlling_date), + ('reconcile_id', '=', False), + ('partner_id', '!=', False)] + + @api.multi + @api.returns('account.move.line') + def _due_move_lines(self, controlling_date): + """ Get the due move lines for the policy of the company. + + The set of ids will be reduced and extended according + to the specific policies defined on partners and invoices. + + Do not use direct SQL in order to respect security rules. + + Assume that only the receivable lines have a maturity date and that + accounts used in the policy are reconcilable. + """ + self.ensure_one() + 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() + domain_line = self._move_lines_domain(controlling_date) + return move_l_obj.search(domain_line) + + @api.multi + @api.returns('account.move.line') + def _move_lines_subset(self, controlling_date, model, move_relation_field): + """ Get the move lines related to one model for a policy. + + Do not use direct SQL in order to respect security rules. + + Assume that only the receivable lines have a maturity date and that + accounts used in the policy are reconcilable. + + The policy relation field must be named credit_policy_id. + + :param str controlling_date: date of credit control + :param str model: name of the model where is defined a credit_policy_id + :param str move_relation_field: name of the field in account.move.line + which is a many2one to `model` + :return: recordset to add in the process, recordset to remove from + the process + """ + 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() + + # The lines which are linked to this policy have to be included in the + # run for this policy. + # If another object override the credit_policy_id (ie. invoice after + add_objs = my_obj.search([('credit_policy_id', '=', self.id)]) + if add_objs: + domain = list(default_domain) + domain.append((move_relation_field, 'in', add_objs.ids)) + to_add = move_l_obj.search(domain) + + # The lines which are linked to another policy do not have to be + # included in the run for this policy. + neg_objs = my_obj.search([('credit_policy_id', '!=', self.id), + ('credit_policy_id', '!=', False)]) + if neg_objs: + domain = list(default_domain) + domain.append((move_relation_field, 'in', neg_objs.ids)) + to_remove = move_l_obj.search(domain) + return to_add, to_remove + + @api.multi + @api.returns('account.move.line') + def _get_partner_related_lines(self, controlling_date): + """ Get the move lines for a policy related to a partner. + + :param str controlling_date: date of credit control + :param str model: name of the model where is defined a credit_policy_id + :param str move_relation_field: name of the field in account.move.line + which is a many2one to `model` + :return: recordset to add in the process, recordset to remove from + the process + """ + return self._move_lines_subset(controlling_date, 'res.partner', + 'partner_id') + + @api.multi + @api.returns('account.move.line') + def _get_invoice_related_lines(self, controlling_date): + """ Get the move lines for a policy related to an invoice. + + :param str controlling_date: date of credit control + :param str model: name of the model where is defined a credit_policy_id + :param str move_relation_field: name of the field in account.move.line + which is a many2one to `model` + :return: recordset to add in the process, recordset to remove from + the process + """ + return self._move_lines_subset(controlling_date, 'account.invoice', + 'invoice') + + @api.multi + @api.returns('account.move.line') + def _get_move_lines_to_process(self, controlling_date): + """ Build a list of move lines ids to include in a run + for a policy at a given date. + + :param str controlling_date: date of credit control + :return: recordset to include in the run + """ + self.ensure_one() + # there is a priority between the lines, depicted by the calls below + lines = self._due_move_lines(controlling_date) + to_add, to_remove = self._get_partner_related_lines(controlling_date) + lines = (lines | to_add) - to_remove + to_add, to_remove = self._get_invoice_related_lines(controlling_date) + lines = (lines | to_add) - to_remove + return lines + + @api.multi + @api.returns('account.move.line') + def _lines_different_policy(self, lines): + """ Return a set of move lines ids for which there is an + 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() + if not lines: + return different_lines + cr = self.env.cr + cr.execute("SELECT move_line_id FROM credit_control_line" + " WHERE policy_id != %s and move_line_id in %s" + " AND manually_overridden IS false", + (self.id, tuple(lines.ids))) + res = cr.fetchall() + if res: + return move_line_obj.browse([row[0] for row in res]) + return different_lines + + @api.multi + def check_policy_against_account(self, account): + """ Ensure that the policy corresponds to account relation """ + policies = self.search([]) + allowed = [x for x in policies + 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( + _('You can only use a policy set on ' + 'account %s.\n' + 'Please choose one of the following ' + 'policies:\n %s') % (account.name, allowed_names) + ) + return True + + +class CreditControlPolicyLevel(models.Model): + """Define a policy level. A level allows to determine if + a move line is due and the level of overdue of the line""" + + _name = "credit.control.policy.level" + _order = 'level' + _description = """A credit control policy level""" + + name = fields.Char(string='Name', required=True, translate=True) + policy_id = fields.Many2one('credit.control.policy', + string='Related Policy', + required=True) + level = fields.Integer(string='Level', required=True) + computation_mode = fields.Selection( + [('net_days', 'Due Date'), + ('end_of_month', 'Due Date, End Of Month'), + ('previous_date', 'Previous Reminder')], + string='Compute Mode', + required=True + ) + delay_days = fields.Integer(string='Delay (in days)', required=True) + email_template_id = fields.Many2one('email.template', + string='Email Template', + required=True) + channel = fields.Selection([('letter', 'Letter'), + ('email', 'Email')], + string='Channel', + required=True) + custom_text = fields.Text(string='Custom Message', + required=True, + translate=True) + custom_mail_text = fields.Text(string='Custom Mail Message', + required=True, translate=True) + + _sql_constraint = [('unique level', + 'UNIQUE (policy_id, level)', + 'Level must be unique per policy')] + + @api.one + @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')) + + @api.multi + def _previous_level(self): + """ For one policy level, returns the id of the previous level + + If there is no previous level, it returns None, it means that's the + first policy level + + :return: previous level or None if there is no previous level + """ + self.ensure_one() + previous_levels = self.search([('policy_id', '=', self.policy_id.id), + ('level', '<', self.level)], + order='level desc', + limit=1) + if not previous_levels: + return None + return previous_levels + + # ----- sql time related methods --------- + + @staticmethod + def _net_days_get_boundary(): + return (" (mv_line.date_maturity + %(delay)s)::date <= " + "date(%(controlling_date)s)") + + @staticmethod + def _end_of_month_get_boundary(): + return ("(date_trunc('MONTH', (mv_line.date_maturity + %(delay)s))+" + "INTERVAL '1 MONTH - 1 day')::date" + "<= date(%(controlling_date)s)") + + @staticmethod + def _previous_date_get_boundary(): + return "(cr_line.date + %(delay)s)::date <= date(%(controlling_date)s)" + + @api.multi + def _get_sql_date_boundary_for_computation_mode(self, controlling_date): + """ Return a where clauses statement for the given controlling + date and computation mode of the level + """ + self.ensure_one() + fname = "_%s_get_boundary" % (self.computation_mode, ) + if hasattr(self, fname): + fnc = getattr(self, fname) + return fnc() + else: + raise NotImplementedError( + _('Can not get function for computation mode: ' + '%s is not implemented') % (fname, ) + ) + + # ----------------------------------------- + + @api.multi + @api.returns('account.move.line') + def _get_first_level_move_lines(self, controlling_date, lines): + """ Retrieve all the move lines that are linked to a first level. + We use Raw SQL for performance. Security rule where applied in + policy object when the first set of lines were retrieved + """ + self.ensure_one() + move_line_obj = self.env['account.move.line'] + if not lines: + return move_line_obj.browse() + cr = self.env.cr + sql = ("SELECT DISTINCT mv_line.id\n" + " FROM account_move_line mv_line\n" + " WHERE mv_line.id in %(line_ids)s\n" + " AND NOT EXISTS (SELECT id\n" + " FROM credit_control_line\n" + " WHERE move_line_id = mv_line.id\n" + # lines from a previous level with a draft or ignored state + # or manually overridden + # have to be generated again for the previous level + " AND NOT manually_overridden\n" + " AND state NOT IN ('draft', 'ignored'))" + " 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) + data_dict = {'controlling_date': controlling_date, + 'line_ids': tuple(lines.ids), + 'delay': self.delay_days} + cr.execute(sql, data_dict) + res = cr.fetchall() + if res: + return move_line_obj.browse([row[0] for row in res]) + return move_line_obj.browse() + + @api.multi + @api.returns('account.move.line') + def _get_other_level_move_lines(self, controlling_date, lines): + """ Retrieve the move lines for other levels than first level. + """ + self.ensure_one() + move_line_obj = self.env['account.move.line'] + if not lines: + return move_line_obj.browse() + cr = self.env.cr + sql = ("SELECT mv_line.id\n" + " FROM account_move_line mv_line\n" + " JOIN credit_control_line cr_line\n" + " ON (mv_line.id = cr_line.move_line_id)\n" + " WHERE cr_line.id = (SELECT credit_control_line.id " + " FROM credit_control_line\n" + " WHERE credit_control_line.move_line_id = mv_line.id\n" + " AND state != 'ignored'" + " AND NOT manually_overridden" + " ORDER BY credit_control_line.level desc limit 1)\n" + " AND cr_line.level = %(previous_level)s\n" + " AND (mv_line.debit IS NOT NULL AND mv_line.debit != 0.0)\n" + # lines from a previous level with a draft or ignored state + # or manually overridden + # have to be generated again for the previous level + " AND NOT manually_overridden\n" + " AND cr_line.state NOT IN ('draft', 'ignored')\n" + " 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) + previous_level = self._previous_level() + data_dict = {'controlling_date': controlling_date, + 'line_ids': tuple(lines.ids), + 'delay': self.delay_days, + 'previous_level': previous_level.level} + + # print cr.mogrify(sql, data_dict) + cr.execute(sql, data_dict) + res = cr.fetchall() + if res: + return move_line_obj.browse([row[0] for row in res]) + return move_line_obj.browse() + + @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() + if self._previous_level() is None: + method = self._get_first_level_move_lines + else: + method = self._get_other_level_move_lines + matching_lines |= method(controlling_date, lines) + return matching_lines diff --git a/account_credit_control/policy_view.xml b/account_credit_control/policy_view.xml new file mode 100644 index 000000000..7158389f1 --- /dev/null +++ b/account_credit_control/policy_view.xml @@ -0,0 +1,131 @@ + + + + + credit.control.policy.form + credit.control.policy + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + credit.control.policy.tree + credit.control.policy + + + + + + + + + + + + Credit Control Policies + ir.actions.act_window + credit.control.policy + + form + tree,form + + + + + + + credit.mangement.policy.level.form + credit.control.policy.level + +
+ + + + + + + + + + + + + + + + + + +
+
+ + + credit.control.policy.level.tree + credit.control.policy.level + + + + + + + + + + + +
+
diff --git a/account_credit_control/report/report.xml b/account_credit_control/report/report.xml new file mode 100644 index 000000000..2d24c0862 --- /dev/null +++ b/account_credit_control/report/report.xml @@ -0,0 +1,15 @@ + + + + + + + diff --git a/account_credit_control/report/report_credit_control_summary.xml b/account_credit_control/report/report_credit_control_summary.xml new file mode 100644 index 000000000..1b02093c8 --- /dev/null +++ b/account_credit_control/report/report_credit_control_summary.xml @@ -0,0 +1,99 @@ + + + + + + + + diff --git a/account_credit_control/run.py b/account_credit_control/run.py new file mode 100644 index 000000000..c6afb1d1e --- /dev/null +++ b/account_credit_control/run.py @@ -0,0 +1,175 @@ +# -*- 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 . +# +############################################################################## +import logging + +from openerp import models, fields, api, _ + +logger = logging.getLogger('credit.control.run') + + +class CreditControlRun(models.Model): + """ Credit Control run generate all credit control lines and reject """ + + _name = "credit.control.run" + _rec_name = 'date' + _description = "Credit control line generator" + + date = fields.Date(string='Controlling Date', required=True, + readonly=True, + states={'draft': [('readonly', False)]}) + + @api.model + def _get_policies(self): + return self.env['credit.control.policy'].search([]) + + policy_ids = fields.Many2many( + 'credit.control.policy', + rel="credit_run_policy_rel", + id1='run_id', id2='policy_id', + string='Policies', + readonly=True, + states={'draft': [('readonly', False)]}, + default=_get_policies, + ) + report = fields.Html(string='Report', readonly=True, copy=False) + state = fields.Selection([('draft', 'Draft'), + ('done', 'Done')], + string='State', + required=True, + readonly=True, + default='draft') + + line_ids = fields.One2many( + comodel_name='credit.control.line', + inverse_name='run_id', + string='Generated lines') + + manual_ids = fields.Many2many( + 'account.move.line', + rel="credit_runreject_rel", + string='Lines to handle manually', + help='If a credit control line has been generated' + 'on a policy and the policy has been changed ' + 'in the meantime, it has to be handled ' + 'manually', + readonly=True, + copy=False, + ) + + @api.multi + def _check_run_date(self, controlling_date): + """ Ensure that there is no credit line in the future + using controlling_date + + """ + 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)) + + 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)) + + @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() + self._check_run_date(self.date) + + policies = self.policy_ids + if not policies: + raise api.Warning(_('Please select a policy')) + + report = '' + generated = cr_line_obj.browse() + for policy in policies: + if policy.do_nothing: + continue + lines = policy._get_move_lines_to_process(self.date) + manual_lines = policy._lines_different_policy(lines) + lines -= manual_lines + manually_managed_lines |= manual_lines + policy_lines_generated = cr_line_obj.browse() + 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 + for level in reversed(policy.level_ids): + level_lines = level.get_level_lines(self.date, lines) + policy_lines_generated += create(level_lines, + level, + self.date) + generated |= policy_lines_generated + if policy_lines_generated: + report += (_("Policy \"%s\" has generated %d Credit " + "Control Lines.
") % + (policy.name, len(policy_lines_generated))) + else: + report += _( + "Policy \"%s\" has not generated any " + "Credit Control Lines.
" % policy.name + ) + + vals = {'state': 'done', + 'report': report, + 'manual_ids': [(6, 0, manually_managed_lines.ids)], + 'line_ids': [(6, 0, generated.ids)]} + self.write(vals) + return generated + + @api.multi + def generate_credit_lines(self): + """ Generate credit control lines + + Lock the ``credit_control_run`` Postgres table to avoid concurrent + calls of this method. + """ + try: + self.env.cr.execute('SELECT id FROM credit_control_run' + ' LIMIT 1 FOR UPDATE NOWAIT') + 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.')) + + self._generate_credit_lines() + return True + + @api.multi + def open_credit_lines(self): + """ Open the generated lines """ + self.ensure_one() + action_name = 'account_credit_control.credit_control_line_action' + action = self.env.ref(action_name) + action = action.read()[0] + action['domain'] = [('id', 'in', self.line_ids.ids)] + return action diff --git a/account_credit_control/run_view.xml b/account_credit_control/run_view.xml new file mode 100644 index 000000000..aa3cd0ea0 --- /dev/null +++ b/account_credit_control/run_view.xml @@ -0,0 +1,75 @@ + + + + + credit.control.run.tree + credit.control.run + + + + + + + + + + credit.control.run.form + credit.control.run + +
+
+
+ + + + + + + + + + + + + + + +
+
+
+ + + + Credit Control Run + ir.actions.act_window + credit.control.run + + form + tree,form + + + + + + +
+
diff --git a/account_credit_control/scenarios/features/00_credit_control_param.feature b/account_credit_control/scenarios/features/00_credit_control_param.feature new file mode 100644 index 000000000..c02bb6384 --- /dev/null +++ b/account_credit_control/scenarios/features/00_credit_control_param.feature @@ -0,0 +1,61 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2009 Camptocamp SA +# +# +# The base scenario for the finance data must be executed before this +# one. The finance scenario is included in the oerpscenario base and +# the tag to run it is: @base_finance +# +# +############################################################################## +############################################################################## +# Branch # Module # Processes # System +@account_credit_control @account_credit_control_setup + +Feature: General parameters in order to test the credit control module + + + @account_credit_control_setup_install_modules + Scenario: MODULES INSTALLATION + + Given I do not want all demo data to be loaded on install + Given I install the required modules with dependencies: + | name | + | account_credit_control | + + Then my modules should have been installed and models reloaded + + + @deactivate_journal_control + Scenario: Journal setup to avoid unfixed voucher bug + Given I execute the SQL commands + """ + UPDATE account_journal SET allow_date = false; + """ + + @email_params_mailtrap + Scenario: E-MAIL PARAMS WITH EMAIL EATER (http://mailtrap.io) + Given I need a "ir.mail_server" with name: mailstrap_testings + And having: + | name | value | + | smtp_host | mailtrap.io | + | sequence | 1 | + | smtp_port | 2525 | + | smtp_user | camptocamp1 | + | smtp_pass | 20468fa2f2879cb9 | + + @account_credit_control_policy_2_times + Scenario: Configure the credit control policy in 2 times + Given I configure the following accounts on the credit control policy with oid: "account_credit_control.credit_control_2_time": + | account code | + | 4111 | + | 4112 | + + @account_credit_control_policy_3_times + Scenario: Configure the credit control policy in 3 times + Given I configure the following accounts on the credit control policy with oid: "account_credit_control.credit_control_3_time": + | account code | + | 4111 | + | 4112 | diff --git a/account_credit_control/scenarios/features/01_credit_control_partners.feature b/account_credit_control/scenarios/features/01_credit_control_partners.feature new file mode 100644 index 000000000..9edb192c7 --- /dev/null +++ b/account_credit_control/scenarios/features/01_credit_control_partners.feature @@ -0,0 +1,105 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2009 Camptocamp SA +# +############################################################################## +############################################################################## +# Branch # Module # Processes # System +@account_credit_control @account_credit_control_add_policy @account_credit_control_setup + +Feature: I add policy to partners already created + @account_credit_control_partner_1 + Scenario: Partner_1 + Given I need a "res.partner" with oid: scen.partner_1 + And having: + | name | value | + | name | partner_1 | + | credit_policy_id | by name: No follow | + + @account_credit_control_customer_1 + Scenario: Customer_1 + Given I need a "res.partner" with oid: scen.customer_1 + And having: + | name | value | + | name | customer_1 | + | credit_policy_id | by name: 2 time policy | + + @account_credit_control_customer_2 + Scenario: Customer_2 + Given I need a "res.partner" with oid: scen.customer_2 + And having: + | name | value | + | name | customer_2 | + | credit_policy_id | by name: 2 time policy | + + @account_credit_control_customer_3 + Scenario: Customer_3 + Given I need a "res.partner" with oid: scen.customer_3 + And having: + | name | value | + | name | customer_3 | + | credit_policy_id | by name: 2 time policy | + + @account_credit_control_customer_4 + Scenario: Customer_4 + Given I need a "res.partner" with oid: scen.customer_4 + And having: + | name | value | + | name | customer_4 | + # the credit policy must be 3 time policy (inherited from company) + + @account_credit_control_customer_5 + Scenario: Customer_5 + Given I need a "res.partner" with oid: scen.customer_5 + And having: + | name | value | + | name | customer_5_usd | + | credit_policy_id | by name: 3 time policy | + + @account_credit_control_customer_6 + Scenario: Customer_6 + Given I need a "res.partner" with oid: scen.customer_6 + And having: + | name | value | + | name | customer_6 | + | credit_policy_id | by name: 3 time policy | + + @account_credit_control_customer_partial_pay + Scenario: A customer who like to do partial payments + Given I need a "res.partner" with oid: scen.customer_partial_pay + And having: + | name | value | + | name | Scrooge McDuck | + | zip | 1000 | + | city | Duckburg | + | email | openerp@locahost.dummy | + | phone | | + | street | Duckstreet | + + + @account_credit_control_customer_multiple_payterm + Scenario: A customer who use payment terms in 2 times + Given I need a "res.partner" with oid: scen.customer_multiple_payterm + And having: + | name | value | + | name | Donald Duck | + | zip | 1100 | + | city | Duckburg | + | email | openerp@locahost.dummy | + | phone | | + | street | Duckstreet | + + @account_credit_control_customer_multiple_payterm2 + Scenario: A customer who use payment terms in 2 times + Given I need a "res.partner" with oid: scen.customer_multiple_payterm2 + And having: + | name | value | + | name | Gus Goose | + | type | default | + | name | Gus Goose | + | zip | 1100 | + | city | Duckburg | + | email | openerp@locahost.dummy | + | phone | | + | street | Duckstreet | diff --git a/account_credit_control/scenarios/features/02_credit_control_invoices.feature b/account_credit_control/scenarios/features/02_credit_control_invoices.feature new file mode 100644 index 000000000..a153d39f7 --- /dev/null +++ b/account_credit_control/scenarios/features/02_credit_control_invoices.feature @@ -0,0 +1,588 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + + +@account_credit_control @account_credit_control_setup @account_credit_control_base_data @account_credit_control_invoices + +Feature: Invoices creation + +##################### Partner 1 ########################################################## + + @inv_1 + Scenario: Create invoice 1 + + Given I need a "account.invoice" with oid: scen._inv_1 + And having: + | name | value | + | name | SI_1 | + | date_invoice | 2013-01-15 | + | partner_id | by oid: scen.partner_1 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30 Days End of Month | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv1_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1000 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_1 | + Given I find a "account.invoice" with oid: scen._inv_1 + + Given I need a "account.invoice.line" with oid: scen._inv1_line2 + And having: + | name | value | + | name | invoice line 2 | + | quantity | 1 | + | price_unit | 1000 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_1 | + Given I find a "account.invoice" with oid: scen._inv_1 + And I open the credit invoice + + @inv_2 + Scenario: Create invoice 2 + Given I need a "account.invoice" with oid: scen._inv_2 + And having: + | name | value | + | name | SI_2 | + | date_invoice | 2013-02-15 | + | partner_id | by oid: scen.partner_1 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30 Days End of Month | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv2_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1200 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_2 | + Given I find a "account.invoice" with oid: scen._inv_2 + And I open the credit invoice + + + @inv_3 + Scenario: Create invoice 3 + Given I need a "account.invoice" with oid: scen._inv_3 + And having: + | name | value | + | name | SI_3 | + | date_invoice | 2013-03-15 | + | partner_id | by oid: scen.partner_1 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30 Days End of Month | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv3_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1500 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_3 | + Given I find a "account.invoice" with oid: scen._inv_3 + And I open the credit invoice + +##################### Customer 2 ########################################################## + + @inv_4 + Scenario: Create invoice 4 + + Given I need a "account.invoice" with oid: scen._inv_4 + And having: + | name | value | + | name | SI_4 | + | date_invoice | 2013-01-18 | + | partner_id | by oid: scen.customer_2 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30 Days End of Month | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv4_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1000 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_4 | + Given I find a "account.invoice" with oid: scen._inv_4 + And I open the credit invoice + + + + @inv_5 + Scenario: Create invoice 5 + Given I need a "account.invoice" with oid: scen._inv_5 + And having: + | name | value | + | name | SI_5 | + | date_invoice | 2013-02-15 | + | partner_id | by oid: scen.customer_2 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30 Days End of Month | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv5_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1200 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_5 | + Given I find a "account.invoice" with oid: scen._inv_5 + And I open the credit invoice + + + @inv_6 + Scenario: Create invoice 6 + Given I need a "account.invoice" with oid: scen._inv_6 + And having: + | name | value | + | name | SI_6 | + | date_invoice | 2013-03-15 | + | partner_id | by oid: scen.customer_2 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30 Days End of Month | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv6_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1500 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_6 | + Given I find a "account.invoice" with oid: scen._inv_6 + And I open the credit invoice + +##################### Customer 3 ########################################################## + + @inv_7 + Scenario: Create invoice 7 + + Given I need a "account.invoice" with oid: scen._inv_7 + And having: + | name | value | + | name | SI_7 | + | date_invoice | 2013-01-18 | + | partner_id | by oid: scen.customer_3 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv7_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1000 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_7 | + Given I find a "account.invoice" with oid: scen._inv_7 + And I open the credit invoice + + + + @inv_8 + Scenario: Create invoice 8 + Given I need a "account.invoice" with oid: scen._inv_8 + And having: + | name | value | + | name | SI_8 | + | date_invoice | 2013-02-15 | + | partner_id | by oid: scen.customer_3 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv8_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1200 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_8 | + Given I find a "account.invoice" with oid: scen._inv_8 + And I open the credit invoice + + + @inv_9 + Scenario: Create invoice 9 + Given I need a "account.invoice" with oid: scen._inv_9 + And having: + | name | value | + | name | SI_9 | + | date_invoice | 2013-03-15 | + | partner_id | by oid: scen.customer_3 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv9_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1500 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_9 | + Given I find a "account.invoice" with oid: scen._inv_9 + And I open the credit invoice + +##################### Customer 4 ########################################################## + + @inv_10 + Scenario: Create invoice 10 + + Given I need a "account.invoice" with oid: scen._inv_10 + And having: + | name | value | + | name | SI_10 | + | date_invoice | 2013-01-18 | + | partner_id | by oid: scen.customer_4 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30% Advance End 30 Days | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv10_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1000 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_10 | + Given I find a "account.invoice" with oid: scen._inv_10 + And I open the credit invoice + + + + @inv_11 + Scenario: Create invoice 11 + Given I need a "account.invoice" with oid: scen._inv_11 + And having: + | name | value | + | name | SI_11 | + | date_invoice | 2013-02-15 | + | partner_id | by oid: scen.customer_4 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30% Advance End 30 Days | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv11_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1200 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_11 | + Given I find a "account.invoice" with oid: scen._inv_11 + And I open the credit invoice + + + @inv_12 + Scenario: Create invoice 12 + Given I need a "account.invoice" with oid: scen._inv_12 + And having: + | name | value | + | name | SI_12 | + | date_invoice | 2013-03-15 | + | partner_id | by oid: scen.customer_4 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30% Advance End 30 Days | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv12_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1500 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_12 | + Given I find a "account.invoice" with oid: scen._inv_12 + And I open the credit invoice + +##################### Customer 5 ########################################################## + + @inv_13 + Scenario: Create invoice 13 + + Given I need a "account.invoice" with oid: scen._inv_13 + And having: + | name | value | + | name | SI_13 | + | date_invoice | 2013-01-18 | + | partner_id | by oid: scen.customer_5 | + | account_id | by name: Debtors USD | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv13_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1000 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_13 | + Given I find a "account.invoice" with oid: scen._inv_13 + And I open the credit invoice + + + + @inv_14 + Scenario: Create invoice 14 + Given I need a "account.invoice" with oid: scen._inv_14 + And having: + | name | value | + | name | SI_14 | + | date_invoice | 2013-02-15 | + | partner_id | by oid: scen.customer_5 | + | account_id | by name: Debtors USD | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv14_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1200 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_14 | + Given I find a "account.invoice" with oid: scen._inv_14 + And I open the credit invoice + + + @inv_15 + Scenario: Create invoice 15 + Given I need a "account.invoice" with oid: scen._inv_15 + And having: + | name | value | + | name | SI_15 | + | date_invoice | 2013-03-15 | + | partner_id | by oid: scen.customer_5 | + | account_id | by name: Debtors USD | + | journal_id | by name: Sales | + | currency_id | by name: USD | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + + Given I need a "account.invoice.line" with oid: scen._inv15_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1500 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_15 | + Given I find a "account.invoice" with oid: scen._inv_15 + And I open the credit invoice + + @inv_16 + Scenario: Create invoice 16 + Given I need a "account.invoice" with oid: scen._inv_16 + And having: + | name | value | + | name | SI_16 | + | date_invoice | 2013-03-15 | + | partner_id | by oid: scen.customer_4 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + And I need a "account.invoice.line" with oid: scen._inv16_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1500 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_16 | + Then I find a "account.invoice" with oid: scen._inv_16 + And I open the credit invoice + + @inv_17 + Scenario: Create invoice 17 + Given I need a "account.invoice" with oid: scen._inv_17 + And having: + | name | value | + | name | SI_17 | + | date_invoice | 2013-03-15 | + | partner_id | by oid: scen.customer_partial_pay | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + And I need a "account.invoice.line" with oid: scen._inv17_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1500 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_17 | + Then I find a "account.invoice" with oid: scen._inv_17 + And I open the credit invoice + + @inv_18 + Scenario: Create invoice 18 + Given I need a "account.invoice" with oid: scen._inv_18 + And having: + | name | value | + | name | SI_18 | + | date_invoice | 2013-03-15 | + | partner_id | by oid: scen.customer_multiple_payterm | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30% Advance End 30 Days | + | type | out_invoice | + + And I need a "account.invoice.line" with oid: scen._inv18_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1500 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_18 | + Then I find a "account.invoice" with oid: scen._inv_18 + And I open the credit invoice + + @inv_19 + Scenario: Create invoice 19 + Given I need a "account.invoice" with oid: scen._inv_19 + And having: + | name | value | + | name | SI_19 | + | date_invoice | 2013-03-15 | + | partner_id | by oid: scen.customer_multiple_payterm2 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30% Advance End 30 Days | + | type | out_invoice | + And I need a "account.invoice.line" with oid: scen._inv19_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 1500 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_19 | + Then I find a "account.invoice" with oid: scen._inv_19 + And I open the credit invoice + + @inv_20 + Scenario: Create invoice 20 + Given I need a "account.invoice" with oid: scen._inv_20 + And having: + | name | value | + | name | SI_20_test_tolerance | + | date_invoice | 2013-03-23 | + | partner_id | by oid: scen.customer_6 | + | account_id | by name: Debtors | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + And I need a "account.invoice.line" with oid: scen._inv20_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 0.09 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_20 | + Then I find a "account.invoice" with oid: scen._inv_20 + And I open the credit invoice + + @inv_20 + Scenario: Create invoice 21 (this receivable account must not be chased-> no credit line creation) + Given I need a "account.invoice" with oid: scen._inv_21 + And having: + | name | value | + | name | SI_21_test_receivable_account_excluded | + | date_invoice | 2013-03-25 | + | partner_id | by oid: scen.customer_6 | + | account_id | by name: Debtors GBP | + | journal_id | by name: Sales | + | currency_id | by name: EUR | + | payment_term | by name: 30 Net Days | + | type | out_invoice | + + And I need a "account.invoice.line" with oid: scen._inv21_line1 + And having: + | name | value | + | name | invoice line 1 | + | quantity | 1 | + | price_unit | 6666 | + | account_id | by name: Sales | + | invoice_id | by oid: scen._inv_21 | + Then I find a "account.invoice" with oid: scen._inv_21 + And I open the credit invoice diff --git a/account_credit_control/scenarios/features/03_credit_control_run_jan.feature b/account_credit_control/scenarios/features/03_credit_control_run_jan.feature new file mode 100644 index 000000000..9839f9bf1 --- /dev/null +++ b/account_credit_control/scenarios/features/03_credit_control_run_jan.feature @@ -0,0 +1,29 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + +# Features Generic tags (none for all) +############################################################################## + +@account_credit_control @account_credit_control_run @account_credit_control_run_jan + +Feature: Ensure that mail credit line generation first pass is correct + + Scenario: clean data + Given I clean all the credit lines + #Given I unreconcile and clean all move line + + @account_credit_control_run_month + Scenario: Create run + Given I need a "credit.control.run" with oid: credit_control.run1 + And having: + | name | value | + | date | 2013-01-31 | + When I launch the credit run + Then my credit run should be in state "done" + And the generated credit lines should have the following values: + | balance | date due | account | policy | date | partner | channel | level | move line | policy level | state | amount due | currency | + | 300 | 2013-01-18 | Debtors | 3 time policy | 2013-01-31 | customer_4 | email | 1 | SI_10 | 10 days net | draft | 300 | | diff --git a/account_credit_control/scenarios/features/04_credit_control_run_feb.feature b/account_credit_control/scenarios/features/04_credit_control_run_feb.feature new file mode 100644 index 000000000..f9b1865ca --- /dev/null +++ b/account_credit_control/scenarios/features/04_credit_control_run_feb.feature @@ -0,0 +1,33 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + +# Features Generic tags (none for all) +############################################################################## + +@account_credit_control @account_credit_control_run @account_credit_control_run_feb + +Feature: Ensure that mail credit line generation first pass is correct + + @account_credit_control_mark + Scenario: mark lines + Given there is "draft" credit lines + And I mark all draft email to state "to_be_sent" + Then the draft line should be in state "to_be_sent" + + @account_credit_control_run_month + Scenario: Create run + Given I need a "credit.control.run" with oid: credit_control.run2 + And having: + | name | value | + | date | 2013-02-28 | + When I launch the credit run + Then my credit run should be in state "done" + And the generated credit lines should have the following values: + | balance | date due | account | policy | date | partner | channel | level | move line | policy level | state | amount due | currency | + | 360 | 2013-02-15 | Debtors | 3 time policy | 2013-02-28 | customer_4 | email | 1 | SI_11 | 10 days net | draft | 360 | USD | + | 1000 | 2013-02-17 | Debtors USD | 3 time policy | 2013-02-28 | customer_5_usd | email | 1 | SI_13 | 10 days net | draft | 1000 | USD | + | 300 | 2013-01-18 | Debtors | 3 time policy | 2013-02-28 | customer_4 | email | 2 | SI_10 | 30 days end of month | draft | 300 | | diff --git a/account_credit_control/scenarios/features/05_credit_control_run_mar.feature b/account_credit_control/scenarios/features/05_credit_control_run_mar.feature new file mode 100644 index 000000000..af5199b10 --- /dev/null +++ b/account_credit_control/scenarios/features/05_credit_control_run_mar.feature @@ -0,0 +1,45 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + +# Features Generic tags (none for all) +############################################################################## + +@account_credit_control @account_credit_control_run @account_credit_control_run_mar + +Feature: Ensure that email credit line generation first pass is correct + + @account_credit_control_mark + Scenario: mark lines + Given there is "draft" credit lines + And I mark all draft email to state "to_be_sent" + Then the draft line should be in state "to_be_sent" + + @pay_invoice_si_19_part1 + Scenario: I pay a part of the first part of the invoice SI 19, + Given I pay 300.0 on the invoice "SI_19" + Then My invoice "SI_19" is in state "open" reconciled with a residual amount of "1200.0" + + @account_credit_control_run_month_mar + Scenario: Create run + Given I need a "credit.control.run" with oid: credit_control.run3 + And having: + | name | value | + | date | 2013-03-31 | + When I launch the credit run + Then my credit run should be in state "done" + And the generated credit lines should have the following values: + | balance | date due | account | policy | date | partner | channel | level | move line | policy level | state | amount due | currency | + | 1000 | 2013-02-28 | Debtors | 2 time policy | 2013-03-31 | customer_2 | email | 1 | SI_4 | 30 days end of month | draft | 1000 | | + | 1000 | 2013-02-17 | Debtors | 2 time policy | 2013-03-31 | customer_3 | email | 1 | SI_7 | 30 days end of month | draft | 1000 | | + | 700 | 2013-02-28 | Debtors | 3 time policy | 2013-03-31 | customer_4 | email | 1 | SI_10 | 10 days net | draft | 700 | | + | 449.99 | 2013-03-15 | Debtors | 3 time policy | 2013-03-31 | customer_4 | email | 1 | SI_12 | 10 days net | draft | 449.99 | USD | + | 1200 | 2013-03-17 | Debtors USD | 3 time policy | 2013-03-31 | customer_5_usd | email | 1 | SI_14 | 10 days net | draft | 1200 | USD | + | 360 | 2013-02-15 | Debtors | 3 time policy | 2013-03-31 | customer_4 | email | 2 | SI_11 | 30 days end of month | draft | 360 | USD | + | 1000 | 2013-02-17 | Debtors USD | 3 time policy | 2013-03-31 | customer_5_usd | email | 2 | SI_13 | 30 days end of month | draft | 1000 | USD | + | 300 | 2013-01-18 | Debtors | 3 time policy | 2013-03-31 | customer_4 | letter | 3 | SI_10 | 10 days last reminder | draft | 300 | | + | 450 | 2013-03-15 | Debtors | 3 time policy | 2013-03-31 | Donald Duck | email | 1 | SI_18 | 10 days net | draft | 450 | | + | 150 | 2013-03-15 | Debtors | 3 time policy | 2013-03-31 | Gus Goose | email | 1 | SI_19 | 10 days net | draft | 450 | | diff --git a/account_credit_control/scenarios/features/06_credit_control_run_apr.feature b/account_credit_control/scenarios/features/06_credit_control_run_apr.feature new file mode 100644 index 000000000..635bfeee7 --- /dev/null +++ b/account_credit_control/scenarios/features/06_credit_control_run_apr.feature @@ -0,0 +1,44 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + +# Features Generic tags (none for all) +############################################################################## + +@account_credit_control @account_credit_control_run @account_credit_control_run_apr + +Feature: Ensure that email credit line generation first pass is correct + + @account_credit_control_mark + Scenario: mark lines + Given there is "draft" credit lines + And I mark all draft email to state "to_be_sent" + Then the draft line should be in state "to_be_sent" + + @account_credit_control_run_month + Scenario: Create run + Given I need a "credit.control.run" with oid: credit_control.run4 + And having: + | name | value | + | date | 2013-04-30 | + + When I launch the credit run + Then my credit run should be in state "done" + And the generated credit lines should have the following values: + | balance | date due | account | policy | date | partner | channel | level | move line | policy level | state | amount due | currency | + | 360 | 2013-02-15 | Debtors | 3 time policy | 2013-04-30 | customer_4 | letter | 3 | SI_11 | 10 days last reminder | draft | 360 | USD | + | 1200 | 2013-03-31 | Debtors | 2 time policy | 2013-04-30 | customer_2 | email | 1 | SI_5 | 30 days end of month | draft | 1200 | USD | + | 1200 | 2013-03-17 | Debtors | 2 time policy | 2013-04-30 | customer_3 | email | 1 | SI_8 | 30 days end of month | draft | 1200 | USD | + | 700 | 2013-02-28 | Debtors | 3 time policy | 2013-04-30 | customer_4 | email | 2 | SI_10 | 30 days end of month | draft | 700 | | + | 840 | 2013-03-31 | Debtors | 3 time policy | 2013-04-30 | customer_4 | email | 1 | SI_11 | 10 days net | draft | 840 | USD | + | 449.99 | 2013-03-15 | Debtors | 3 time policy | 2013-04-30 | customer_4 | email | 2 | SI_12 | 30 days end of month | draft | 449.99 | USD | + | 1500 | 2013-04-14 | Debtors USD | 3 time policy | 2013-04-30 | customer_5_usd | email | 1 | SI_15 | 10 days net | draft | 1500 | USD | + | 1200 | 2013-03-17 | Debtors USD | 3 time policy | 2013-04-30 | customer_5_usd | email | 2 | SI_14 | 30 days end of month | draft | 1200 | USD | + | 1500 | 2013-04-14 | Debtors USD | 3 time policy | 2013-04-30 | customer_5_usd | email | 1 | SI_15 | 10 days net | draft | 1500 | USD | + | 1500 | 2013-04-14 | Debtors | 3 time policy | 2013-04-30 | customer_4 | email | 1 | SI_16 | 10 days net | draft | 1500 | | + | 1500 | 2013-04-14 | Debtors | 3 time policy | 2013-04-30 | Scrooge McDuck | email | 1 | SI_17 | 10 days net | draft | 1500 | | + | 450 | 2013-03-15 | Debtors | 3 time policy | 2013-04-30 | Donald Duck | email | 2 | SI_18 | 30 days end of month | draft | 450 | | + | 150 | 2013-03-15 | Debtors | 3 time policy | 2013-04-30 | Gus Goose | email | 2 | SI_19 | 30 days end of month | draft | 450 | | diff --git a/account_credit_control/scenarios/features/07_credit_control_run_may.feature b/account_credit_control/scenarios/features/07_credit_control_run_may.feature new file mode 100644 index 000000000..2b73fa660 --- /dev/null +++ b/account_credit_control/scenarios/features/07_credit_control_run_may.feature @@ -0,0 +1,59 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + +# Features Generic tags (none for all) +############################################################################## + +@account_credit_control @account_credit_control_run @account_credit_control_run_may + +Feature: Ensure that email credit line generation first pass is correct + + @account_credit_control_mark + Scenario: mark lines + Given there is "draft" credit lines + And I mark all draft email to state "to_be_sent" + Then the draft line should be in state "to_be_sent" + + @pay_invoice_si_16 + Scenario: I pay entirely the invoice SI 16, so it should no longer appear in the credit control lines + Given I pay the full amount on the invoice "SI_16" + Then My invoice "SI_16" is in state "paid" reconciled with a residual amount of "0.0" + + @pay_invoice_si_17 + Scenario: I pay entirely the invoice SI 17, so it should no longer appear in the credit control lines + Given I pay 1000.0 on the invoice "SI_17" + Then My invoice "SI_17" is in state "open" reconciled with a residual amount of "500.0" + + @pay_invoice_si_18_part1 + Scenario: I pay the first part of the invoice SI 18, so it should no longer appear in the credit control lines however, the second move lines should still appears + Given I pay 450.0 on the invoice "SI_18" + Then My invoice "SI_18" is in state "open" reconciled with a residual amount of "1050.0" + + @account_credit_control_run_month + Scenario: Create run + Given I need a "credit.control.run" with oid: credit_control.run5 + And having: + | name | value | + | date | 2013-05-31 | + When I launch the credit run + Then my credit run should be in state "done" + And the generated credit lines should have the following values: + | balance | date due | account | policy | date | partner | channel | level | move line | policy level | state | amount due | currency | + | 1500 | 2013-04-30 | Debtors | 2 time policy | 2013-05-31 | customer_2 | email | 1 | SI_6 | 30 days end of month | draft | 1500 | USD | + | 1000 | 2013-02-28 | Debtors | 2 time policy | 2013-05-31 | customer_2 | letter | 2 | SI_4 | 60 days last reminder | draft | 1000 | | + | 1000 | 2013-02-17 | Debtors | 2 time policy | 2013-05-31 | customer_3 | letter | 2 | SI_7 | 60 days last reminder | draft | 1000 | | + | 1500 | 2013-04-14 | Debtors | 2 time policy | 2013-05-31 | customer_3 | email | 1 | SI_9 | 30 days end of month | draft | 1500 | | + | 840 | 2013-03-31 | Debtors | 3 time policy | 2013-05-31 | customer_4 | email | 2 | SI_11 | 30 days end of month | draft | 840 | USD | + | 1500 | 2013-04-14 | Debtors USD | 3 time policy | 2013-05-31 | customer_5_usd | email | 2 | SI_15 | 30 days end of month | draft | 1500 | USD | + | 700 | 2013-02-28 | Debtors | 3 time policy | 2013-05-31 | customer_4 | letter | 3 | SI_10 | 10 days last reminder | draft | 700 | | + | 449.99 | 2013-03-15 | Debtors | 3 time policy | 2013-05-31 | customer_4 | letter | 3 | SI_12 | 10 days last reminder | draft | 449.99 | USD | + | 1050.01 | 2013-04-30 | Debtors | 3 time policy | 2013-05-31 | customer_4 | email | 1 | SI_12 | 10 days net | draft | 1050.01 | USD | + | 1200 | 2013-03-17 | Debtors USD | 3 time policy | 2013-05-31 | customer_5_usd | letter | 3 | SI_14 | 10 days last reminder | draft | 1200 | USD | + | 500 | 2013-04-14 | Debtors | 3 time policy | 2013-05-31 | Scrooge McDuck | email | 2 | SI_17 | 30 days end of month | draft | 1500 | | + | 1050 | 2013-04-30 | Debtors | 3 time policy | 2013-05-31 | Donald Duck | email | 1 | SI_18 | 10 days net | draft | 1050 | | + | 150 | 2013-03-15 | Debtors | 3 time policy | 2013-05-31 | Gus Goose | letter | 3 | SI_19 | 10 days last reminder | draft | 450 | | + | 1050 | 2013-04-30 | Debtors | 3 time policy | 2013-05-31 | Gus Goose | email | 1 | SI_19 | 10 days net | draft | 1050 | | diff --git a/account_credit_control/scenarios/features/08_credit_control_run_jun.feature b/account_credit_control/scenarios/features/08_credit_control_run_jun.feature new file mode 100644 index 000000000..75c7df7f5 --- /dev/null +++ b/account_credit_control/scenarios/features/08_credit_control_run_jun.feature @@ -0,0 +1,38 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + +# Features Generic tags (none for all) +############################################################################## + +@account_credit_control @account_credit_control_run @account_credit_control_run_jun + +Feature: Ensure that email credit line generation first pass is correct + + @account_credit_control_mark + Scenario: mark lines + Given there is "draft" credit lines + And I mark all draft email to state "to_be_sent" + Then the draft line should be in state "to_be_sent" + + @account_credit_control_run_month + Scenario: Create run + Given I need a "credit.control.run" with oid: credit_control.run6 + And having: + | name | value | + | date | 2013-06-30 | + When I launch the credit run + Then my credit run should be in state "done" + And the generated credit lines should have the following values: + | balance | date due | account | policy | date | partner | channel | level | move line | policy level | state | amount due | currency | + | 1200 | 2013-03-31 | Debtors | 2 time policy | 2013-06-30 | customer_2 | letter | 2 | SI_5 | 60 days last reminder | draft | 1200 | USD | + | 1200 | 2013-03-17 | Debtors | 2 time policy | 2013-06-30 | customer_3 | letter | 2 | SI_8 | 60 days last reminder | draft | 1200 | USD | + | 1050.01 | 2013-04-30 | Debtors | 3 time policy | 2013-06-30 | customer_4 | email | 2 | SI_12 | 30 days end of month | draft | 1050.01 | USD | + | 840 | 2013-03-31 | Debtors | 3 time policy | 2013-06-30 | customer_4 | letter | 3 | SI_11 | 10 days last reminder | draft | 840 | USD | + | 1500 | 2013-04-14 | Debtors USD | 3 time policy | 2013-06-30 | customer_5_usd | letter | 3 | SI_15 | 10 days last reminder | draft | 1500 | USD | + | 500 | 2013-04-14 | Debtors | 3 time policy | 2013-06-30 | Scrooge McDuck | letter | 3 | SI_17 | 10 days last reminder | draft | 1500 | | + | 1050 | 2013-04-30 | Debtors | 3 time policy | 2013-06-30 | Donald Duck | email | 2 | SI_18 | 30 days end of month | draft | 1050 | | + | 1050 | 2013-04-30 | Debtors | 3 time policy | 2013-06-30 | Gus Goose | email | 2 | SI_19 | 30 days end of month | draft | 1050 | | diff --git a/account_credit_control/scenarios/features/09_credit_control_run_jul.feature b/account_credit_control/scenarios/features/09_credit_control_run_jul.feature new file mode 100644 index 000000000..df0aa4c55 --- /dev/null +++ b/account_credit_control/scenarios/features/09_credit_control_run_jul.feature @@ -0,0 +1,35 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + +# Features Generic tags (none for all) +############################################################################## + +@account_credit_control @account_credit_control_run @account_credit_control_run_jul + +Feature: Ensure that email credit line generation first pass is correct + + @account_credit_control_mark + Scenario: mark lines + Given there is "draft" credit lines + And I mark all draft email to state "to_be_sent" + Then the draft line should be in state "to_be_sent" + + @account_credit_control_run_month + Scenario: Create run + Given I need a "credit.control.run" with oid: credit_control.run7 + And having: + | name | value | + | date | 2013-07-31 | + When I launch the credit run + Then my credit run should be in state "done" + And the generated credit lines should have the following values: + | balance | date due | account | policy | date | partner | channel | level | move line | policy level | state | amount due | currency | + | 1500 | 2013-04-30 | Debtors | 2 time policy | 2013-07-31 | customer_2 | letter | 2 | SI_6 | 60 days last reminder | draft | 1500 | USD | + | 1500 | 2013-04-14 | Debtors | 2 time policy | 2013-07-31 | customer_3 | letter | 2 | SI_9 | 60 days last reminder | draft | 1500 | USD | + | 1050.01 | 2013-04-30 | Debtors | 3 time policy | 2013-07-31 | customer_4 | letter | 3 | SI_12 | 10 days last reminder | draft | 1050.01 | USD | + | 1050 | 2013-04-30 | Debtors | 3 time policy | 2013-07-31 | Donald Duck | letter | 3 | SI_18 | 10 days last reminder | draft | 1050 | | + | 1050 | 2013-04-30 | Debtors | 3 time policy | 2013-07-31 | Gus Goose | letter | 3 | SI_19 | 10 days last reminder | draft | 1050 | | diff --git a/account_credit_control/scenarios/features/10_credit_control_run_aug.feature b/account_credit_control/scenarios/features/10_credit_control_run_aug.feature new file mode 100644 index 000000000..5351b4b9c --- /dev/null +++ b/account_credit_control/scenarios/features/10_credit_control_run_aug.feature @@ -0,0 +1,30 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + +# Features Generic tags (none for all) +############################################################################## + +@account_credit_control @account_credit_control_run @account_credit_control_run_aug + +Feature: Ensure that ignore feature works as expected + + @account_credit_control_mark_as_ignore + Scenario: mark last line as ignore + Given I ignore the "Gus Goose" credit line at level "3" for move line "SI_19" with amount "1050.0" + + @account_credit_control_run_month_aug + Scenario: Create run + Given I need a "credit.control.run" with oid: credit_control.runignored + And having: + | name | value | + | date | 2013-08-30 | + When I launch the credit run + Then my credit run should be in state "done" + + @check_ignored_line + Scenario: Check ignored lines + Given I have for "Gus Goose" "2" credit lines at level "3" for move line "SI_19" with amount "1050.0" respectively in state "draft" and "ignored" diff --git a/account_credit_control/scenarios/features/11_credit_control_manual_setting.feature b/account_credit_control/scenarios/features/11_credit_control_manual_setting.feature new file mode 100644 index 000000000..6c30d67b1 --- /dev/null +++ b/account_credit_control/scenarios/features/11_credit_control_manual_setting.feature @@ -0,0 +1,42 @@ +############################################################################### +# +# OERPScenario, OpenERP Functional Tests +# Copyright 2012-2014 Camptocamp SA +# Author Nicolas Bessi +############################################################################## + +# Features Generic tags (none for all) +############################################################################## + +@account_credit_control @account_credit_control_run @account_credit_control_run_change_level + +Feature: Ensure that manually changing an invoice level feature works as expected + + @account_credit_control_change_level + Scenario: Change level + Given I change level for invoice "SAJ/2014/0004" to "10 days net" of policy "3 time policy" + Then wizard selected move lines should be: + | name | + | SI_4 | + When I confirm the level change + And I should have "3" credit control lines overridden + And one new credit control line of level "10 days net" related to invoice "SAJ/2014/0004" + Then I force date of generated credit line to "2013-09-15" + + @account_credit_control_run_month_sept + Scenario: Create run + Given there is "draft" credit lines + And I mark all draft email to state "to_be_sent" + Then the draft line should be in state "to_be_sent" + Given I need a "credit.control.run" with oid: credit_control.manual_change + And having: + | name | value | + | date | 2013-09-30 | + When I launch the credit run + Then my credit run should be in state "done" + + @account_credit_control_manual_next_step + Scenario: Check manually managed line on run + Given the invoice "SAJ/2014/0004" with manual changes + And the invoice has "1" line of level "1" for policy "3 time policy" + And the invoice has "1" line of level "2" for policy "3 time policy" diff --git a/account_credit_control/scenarios/features/steps/account_credit_control.py b/account_credit_control/scenarios/features/steps/account_credit_control.py new file mode 100644 index 000000000..2a292d0a5 --- /dev/null +++ b/account_credit_control/scenarios/features/steps/account_credit_control.py @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- +# flake8: noqa +import time +from behave import given, when +from support import model, assert_equal + +@given(u'I configure the following accounts on the credit control policy with oid: "{policy_oid}"') +def impl(ctx, policy_oid): + policy = model('credit.control.policy').get(policy_oid) + assert policy, 'No policy % found' % policy_oid + acc_obj = model('account.account') + accounts = [] + for row in ctx.table: + acc = acc_obj.get(['code = %s' % row['account code']]) + assert acc, "Account with code %s not found" % row['account code'] + accounts.append(acc) + policy.write({'account_ids': [x.id for x in accounts]}) + + +@when(u'I launch the credit run') +def impl(ctx): + assert ctx.found_item + # Must be a cleaner way to do it + assert 'credit.control.run' == ctx.found_item._model._name + ctx.found_item.generate_credit_lines() + +@given(u'I clean all the credit lines') +def impl(ctx): + model('credit.control.line').browse([]).unlink() + +@then(u'my credit run should be in state "done"') +def impl(ctx): + assert ctx.found_item + # Must be a cleaner way to do it + assert model("credit.control.run").get(ctx.found_item.id).state == 'done' + +@then(u'the generated credit lines should have the following values') +def impl(ctx): + def _row_to_dict(row): + return dict((name, row[name]) for name in row.headings if row[name]) + rows = map(_row_to_dict, ctx.table) + + def _parse_date(value): + return time.strftime(value) if '%' in value else value + + for row in rows: + account = model('account.account').get(['name = %s' % row['account']]) + assert account, "no account named %s found" % row['account'] + + policy = model('credit.control.policy').get(['name = %s' % row['policy']]) + assert policy, "No policy %s found" % row['policy'] + + partner = model('res.partner').get(['name = %s' % row['partner']]) + assert partner, "No partner %s found" % row['partner'] + + maturity_date = _parse_date(row['date due']) + move_line = model('account.move.line').get(['name = %s' % row['move line'], + 'date_maturity = %s' % maturity_date]) + assert move_line, "No move line %s found" % row['move line'] + + level = model('credit.control.policy.level').get(['name = %s' % row['policy level'], + 'policy_id = %s' % policy.id]) + assert level, "No level % found" % row['policy level'] + + domain = [['account_id', '=', account.id], + ['policy_id', '=', policy.id], + ['partner_id', '=', partner.id], + ['policy_level_id', '=', level.id], + ['amount_due', '=', row.get('amount due', 0.0)], + ['state', '=', row['state']], + ['level', '=', row.get('level', 0.0)], + ['channel', '=', row['channel']], + ['balance_due', '=', row.get('balance', 0.0)], + ['date_due', '=', _parse_date(row['date due'])], + ['date', '=', _parse_date(row['date'])], + ['move_line_id', '=', move_line.id], + ] + if row.get('currency'): + curreny = model('res.currency').get(['name = %s' % row['currency']]) + assert curreny, "No currency %s found" % row['currency'] + domain.append(('currency_id', '=', curreny.id)) + + lines = model('credit.control.line').search(domain) + assert lines, "no line found for %s" % repr(row) + assert len(lines) == 1, "Too many lines found for %s" % repr(row) + date_lines = model('credit.control.line').search([('date', '=', ctx.found_item.date)]) + assert len(date_lines) == len(ctx.table.rows), "Too many lines generated" + + +def open_invoice(ctx): + assert ctx.found_item + ctx.found_item._send('invoice_open') + # _send refresh object + assert ctx.found_item.state == 'open' + +@then(u'I open the credit invoice') +def impl(ctx): + open_invoice(ctx) + +@given(u'I open the credit invoice') +def impl(ctx): + open_invoice(ctx) + +@given(u'there is "{state}" credit lines') +def impl(ctx, state): + assert model('credit.control.line').search(['state = %s' % state]) + +@given(u'I mark all draft email to state "{state}"') +def impl(ctx, state): + wiz = model('credit.control.marker').create({'name': state}) + lines = model('credit.control.line').search([('state', '=', 'draft')]) + assert lines + ctx.lines = lines + wiz.write({'line_ids': lines}) + wiz.mark_lines() + +@then(u'the draft line should be in state "{state}"') +def impl(ctx, state): + assert ctx.lines + lines = model('credit.control.line').search([('state', '!=', state), + ('id', 'in', ctx.lines)]) + assert not lines + +@given(u'I ignore the "{partner}" credit line at level "{level:d}" for move line "{move_line_name}" with amount "{amount:f}"') +def impl(ctx, partner, level, move_line_name, amount): + print ctx, partner, level, move_line_name, amount + to_ignore = model('credit.control.line').search([('partner_id.name', '=', partner), + ('level', '=', level), + ('amount_due', '=', amount), + ('move_line_id.name', '=', move_line_name)]) + assert to_ignore + wiz = model('credit.control.marker').create({'name': 'ignored'}) + ctx.lines = to_ignore + wiz.write({'line_ids': to_ignore}) + wiz.mark_lines() + assert model('credit.control.line').get(to_ignore[0]).state == 'ignored' + +@given(u'I have for "{partner}" "{number:d}" credit lines at level "{level:d}" for move line "{move_line_name}" with amount "{amount:f}" respectively in state "draft" and "ignored"') +def impl(ctx, partner, number, level, move_line_name, amount): + to_check = model('credit.control.line').search([('partner_id.name', '=', partner), + ('level', '=', level), + ('amount_due', '=', amount), + ('move_line_id.name', '=', move_line_name), + ('state', 'in', ('draft', 'ignored'))]) + assert_equal(len(to_check), int(number), msg="More than %s found" % number) + lines = model('credit.control.line').browse(to_check) + assert set(['ignored', 'draft']) == set(lines.state) diff --git a/account_credit_control/scenarios/features/steps/account_credit_control_changer.py b/account_credit_control/scenarios/features/steps/account_credit_control_changer.py new file mode 100644 index 000000000..6f46d11fc --- /dev/null +++ b/account_credit_control/scenarios/features/steps/account_credit_control_changer.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +from support import model, assert_equal, assert_in, assert_true + +# flake8: noqa +@given(u'I change level for invoice "{invoice_name}" to "{level_name}" of policy "{policy_name}"') +def impl(ctx, invoice_name, level_name, policy_name): + invoice = model('account.invoice').get([('number', '=', invoice_name)]) + assert_true(invoice, msg='No invoices found') + level = model('credit.control.policy.level').get([('name', '=', level_name)]) + assert_true(level, 'level not found') + policy = model('credit.control.policy').get([('name', '=', policy_name)]) + assert_true(policy, 'Policy not found') + assert_equal(policy.id, level.policy_id.id) + context = {'active_ids': [invoice.id]} + data = {'new_policy_id': policy.id, + 'new_policy_level_id': level.id} + wizard = model('credit.control.policy.changer').create(data, context=context) + ctx.wizard = wizard + +@then(u'wizard selected move lines should be') +def impl(ctx): + assert_true(ctx.wizard) + names = [x.name for x in ctx.wizard.move_line_ids] + for line in ctx.table: + assert_in(line['name'], names) + +@when(u'I confirm the level change') +def impl(ctx): + assert_true(ctx.wizard) + ctx.wizard.set_new_policy() + +@when(u'I should have "{line_number:d}" credit control lines overridden') +def impl(ctx, line_number): + assert_true(ctx.wizard) + move_ids = [x.id for x in ctx.wizard.move_line_ids] + overridden = model('credit.control.line').search([('move_line_id', 'in', move_ids), + ('manually_overridden', '=', True)]) +# assert len(overridden) == line_number + +@when(u'one new credit control line of level "{level_name}" related to invoice "{invoice_name}"') +def impl(ctx, level_name, invoice_name): + invoice = model('account.invoice').get([('number', '=', invoice_name)]) + assert_true(invoice, msg='No invoices found') + level = model('credit.control.policy.level').get([('name', '=', level_name)]) + assert_true(level, 'level not found') + assert_true(ctx.wizard) + move_ids = [x.id for x in ctx.wizard.move_line_ids] + created_id = model('credit.control.line').search([('move_line_id', 'in', move_ids), + ('manually_overridden', '=', False)]) + + assert len(created_id) == 1 + created = model('credit.control.line').get(created_id[0]) + ctx.created = created + assert_equal(created.policy_level_id.id, level.id) + assert_equal(created.invoice_id.id, invoice.id) + assert_equal(created.invoice_id.credit_policy_id.id, level.policy_id.id) + +@then(u'I force date of generated credit line to "{date}"') +def impl(ctx, date): + assert_true(ctx.created) + ctx.created.write({'date': date}) + +@given(u'the invoice "{invoice_name}" with manual changes') +def impl(ctx, invoice_name): + invoice = model('account.invoice').get([('number', '=', invoice_name)]) + assert_true(invoice, msg='No invoices found') + man_lines = (x for x in invoice.credit_control_line_ids if x.manually_overridden) + assert_true(next(man_lines, None), 'No manual change on the invoice') + ctx.invoice = invoice + +@given(u'the invoice has "{line_number:d}" line of level "{level:d}" for policy "{policy_name}"') +def impl(ctx, line_number, level, policy_name): + assert_true(ctx.invoice) + policy = model('credit.control.policy').get([('name', '=', policy_name)]) + assert_true(policy) + lines = model('credit.control.line').search([('invoice_id', '=', ctx.invoice.id), + ('level', '=', level), + ('policy_id', '=', policy.id)]) + assert_equal(len(lines), line_number) diff --git a/account_credit_control/scenarios/features/steps/account_voucher.py b/account_credit_control/scenarios/features/steps/account_voucher.py new file mode 100644 index 000000000..6d314316f --- /dev/null +++ b/account_credit_control/scenarios/features/steps/account_voucher.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# flake8: noqa +from support import model, assert_equal, assert_almost_equal +import datetime + + +@step('I pay the full amount on the invoice "{inv_name}"') +def impl(ctx, inv_name): + Invoice = model('account.invoice') + invoice = Invoice.get([('name', '=', inv_name)]) + assert invoice + ctx.execute_steps(""" + When I pay %f on the invoice "%s" + """ % (invoice.residual, inv_name)) + + +@step('I pay {amount:f} on the invoice "{inv_name}"') +def impl(ctx, amount, inv_name): + Partner = model('res.partner') + Invoice = model('account.invoice') + Voucher = model('account.voucher') + VoucherLine = model('account.voucher.line') + Journal = model('account.journal') + invoice = Invoice.get([('name', '=', inv_name)]) + assert invoice + journal = Journal.get('scen.eur_journal') + values = { + 'partner_id': invoice.partner_id.commercial_partner_id.id, + 'reference': invoice.name, + 'amount': amount, + 'date': invoice.date_invoice, + 'currency_id': invoice.currency_id.id, + 'company_id': invoice.company_id.id, + 'journal_id': journal.id, + } + + if invoice.type in ('out_invoice','out_refund'): + values['type'] = 'receipt' + else: + values['type'] = 'payment' + + onchange = Voucher.onchange_partner_id([], values['partner_id'], + values['journal_id'], + values['amount'], + values['currency_id'], + values['type'], + values['date']) + values.update(onchange['value']) + + onchange = Voucher.onchange_date([], values['date'], + values['currency_id'], + False, + values['amount'], + values['company_id']) + values.update(onchange['value']) + + onchange = Voucher.onchange_amount([], values['amount'], + False, + values['partner_id'], + values['journal_id'], + values['currency_id'], + values['type'], + values['date'], + False, + values['company_id']) + values.update(onchange['value']) + values['line_cr_ids'] = False + + voucher = Voucher.create(values) + + vals = voucher.recompute_voucher_lines(voucher.partner_id.id, + voucher.journal_id.id, + voucher.amount, + voucher.currency_id.id, + voucher.type, + voucher.date) + for line in vals['value']['line_cr_ids']: + line['voucher_id'] = voucher.id + VoucherLine.create(line) + + for line in vals['value']['line_dr_ids']: + line['voucher_id'] = voucher.id + VoucherLine.create(line) + + voucher.button_proforma_voucher() + # Workaround to force recomputation of the residual. + # Must be removed once this bug is fixed: + # https://github.com/odoo/odoo/issues/3395 + invoice.write({'currency_id': invoice.currency_id.id}) + + +@step('My invoice "{inv_name}" is in state "{state}" reconciled with a residual amount of "{amount:f}"') +def impl(ctx, inv_name, state, amount): + invoice = model('account.invoice').get([('name', '=', inv_name)]) + assert_almost_equal(invoice.residual, amount) + assert_equal(invoice.state, state) diff --git a/account_credit_control/security/ir.model.access.csv b/account_credit_control/security/ir.model.access.csv new file mode 100644 index 000000000..c47087e6e --- /dev/null +++ b/account_credit_control/security/ir.model.access.csv @@ -0,0 +1,21 @@ +"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_274",1,1,"group_account_credit_control_manager","credit_control_manager_mail_template_preview","email_template.model_email_template_preview",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 \ No newline at end of file diff --git a/account_credit_control/wizard/__init__.py b/account_credit_control/wizard/__init__.py new file mode 100644 index 000000000..82938e856 --- /dev/null +++ b/account_credit_control/wizard/__init__.py @@ -0,0 +1,25 @@ +# -*- 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 . +# +############################################################################## +from . import credit_control_emailer +from . import credit_control_marker +from . import credit_control_printer +from . import credit_control_communication +from . import credit_control_policy_changer diff --git a/account_credit_control/wizard/credit_control_communication.py b/account_credit_control/wizard/credit_control_communication.py new file mode 100644 index 000000000..7ef92585e --- /dev/null +++ b/account_credit_control/wizard/credit_control_communication.py @@ -0,0 +1,239 @@ +# -*- 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 . +# +############################################################################## +import logging +from openerp import models, fields, api + +logger = logging.getLogger('credit.control.line.mailing') + + +class CreditCommunication(models.TransientModel): + """Shell class used to provide a base model to email template and reporting + Il use this approche in version 7 a browse record + will exist even if not saved + + """ + _name = "credit.control.communication" + _description = "credit control communication" + _rec_name = 'partner_id' + + partner_id = fields.Many2one('res.partner', 'Partner', required=True) + + current_policy_level = fields.Many2one('credit.control.policy.level', + 'Level', + required=True) + + currency_id = fields.Many2one('res.currency', 'Currency', required=True) + + credit_control_line_ids = fields.Many2many('credit.control.line', + rel='comm_credit_rel', + string='Credit Lines') + + contact_address = fields.Many2one('res.partner', + string='Contact Address', + readonly=True) + report_date = fields.Date(string='Report Date', + default=fields.Date.context_today) + + @api.model + def _get_company(self): + company_obj = self.env['res.company'] + return company_obj._company_default_get('credit.control.policy') + + company_id = fields.Many2one('res.company', + string='Company', + default=_get_company, + required=True) + user_id = fields.Many2one('res.users', + default=lambda self: self.env.user, + string='User') + + total_invoiced = fields.Float(string='Total Invoiced', + compute='_compute_total') + + total_due = fields.Float(string='Total Invoiced', + compute='_compute_total') + + @api.depends('credit_control_line_ids', + 'credit_control_line_ids.amount_due', + 'credit_control_line_ids.balance_due') + def _compute_total(self): + amount_field = 'credit_control_line_ids.amount_due' + balance_field = 'credit_control_line_ids.balance_due' + self.total_invoiced = sum(self.mapped(amount_field)) + self.total_due = sum(self.mapped(balance_field)) + + @api.model + @api.returns('self', lambda value: value.id) + def create(self, vals): + if vals.get('partner_id'): + # the computed field does not work in TransientModel, + # just set a value on creation + partner_id = vals['partner_id'] + vals['contact_address'] = self._get_contact_address(partner_id).id + return super(CreditCommunication, self).create(vals) + + @api.multi + def get_email(self): + """ Return a valid email for customer """ + self.ensure_one() + contact = self.contact_address + return contact.email + + @api.multi + @api.returns('res.partner') + def get_contact_address(self): + """ Compatibility method, please use the contact_address field """ + self.ensure_one() + return self.contact_address + + @api.model + @api.returns('res.partner') + def _get_contact_address(self, partner_id): + partner_obj = self.env['res.partner'] + partner = partner_obj.browse(partner_id) + add_ids = partner.address_get(adr_pref=['invoice']) or {} + add_id = add_ids['invoice'] + return partner_obj.browse(add_id) + + @api.model + @api.returns('credit.control.line') + def _get_credit_lines(self, line_ids, partner_id, level_id, currency_id): + """ Return credit lines related to a partner and a policy level """ + cr_line_obj = self.env['credit.control.line'] + cr_lines = cr_line_obj.search([('id', 'in', line_ids), + ('partner_id', '=', partner_id), + ('policy_level_id', '=', level_id), + ('currency_id', '=', currency_id)]) + return cr_lines + + @api.model + def _generate_comm_from_credit_lines(self, lines): + """ Aggregate credit control line by partner, level, and currency + It also generate a communication object per aggregation. + """ + comms = self.browse() + if not lines: + return comms + sql = ( + "SELECT distinct partner_id, policy_level_id, " + " credit_control_line.currency_id, " + " credit_control_policy_level.level" + " FROM credit_control_line JOIN credit_control_policy_level " + " ON (credit_control_line.policy_level_id = " + " credit_control_policy_level.id)" + " WHERE credit_control_line.id in %s" + " ORDER by credit_control_policy_level.level, " + " credit_control_line.currency_id" + ) + cr = self.env.cr + cr.execute(sql, (tuple(lines.ids), )) + res = cr.dictfetchall() + company_currency = self.env.user.company_id.currency_id + for group in res: + data = {} + level_lines = self._get_credit_lines(lines.ids, + group['partner_id'], + group['policy_level_id'], + group['currency_id'] + ) + + data['credit_control_line_ids'] = [(6, 0, level_lines.ids)] + data['partner_id'] = group['partner_id'] + data['current_policy_level'] = group['policy_level_id'] + data['currency_id'] = group['currency_id'] or company_currency.id + comm = self.create(data) + comms += comm + return comms + + @api.multi + @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() + 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['type'] = 'email' + + email = email_message_obj.create(email_values) + + state = 'sent' + # The mail will not be send, however it will be in the pool, in an + # error state. So we create it, link it with + # the credit control line + # and put this latter in a `email_error` state we not that we have + # a problem with the email + if not all(email_values.get(field) for field in required_fields): + state = 'email_error' + + 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] + data_attach = { + 'name': attach_fname, + 'datas': attach_datas, + 'datas_fname': attach_fname, + 'res_model': 'mail.mail', + 'res_id': email.id, + 'type': 'binary', + } + attachments += att_obj.create(data_attach) + email.write({'attachment_ids': [(6, 0, attachments.ids)]}) + emails += email + return emails + + @api.multi + def _generate_report(self): + """ Will generate a report by inserting mako template + of related policy template + + """ + report_name = 'account_credit_control.report_credit_control_summary' + return self.env['report'].get_pdf(self, report_name) + + @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() + for comm in self: + lines |= comm.credit_control_line_ids + + lines.write({'state': 'sent'}) + return lines diff --git a/account_credit_control/wizard/credit_control_emailer.py b/account_credit_control/wizard/credit_control_emailer.py new file mode 100644 index 000000000..981892e64 --- /dev/null +++ b/account_credit_control/wizard/credit_control_emailer.py @@ -0,0 +1,69 @@ +# -*- 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 . +# +############################################################################## + +from openerp import models, fields, api, _ + + +class CreditControlEmailer(models.TransientModel): + """ Send emails for each selected credit control lines. """ + + _name = "credit.control.emailer" + _description = """Mass credit line emailer""" + _rec_name = 'id' + + @api.model + def _get_line_ids(self): + context = self.env.context + if not (context.get('active_model') == 'credit.control.line' and + context.get('active_ids')): + return False + line_obj = self.env['credit.control.line'] + lines = line_obj.browse(context['active_id']) + return self._filter_lines(lines) + + line_ids = fields.Many2many('credit.control.line', + string='Credit Control Lines', + default=_get_line_ids, + domain=[('state', '=', 'to_be_sent'), + ('channel', '=', 'email')]) + + @api.model + @api.returns('credit.control.line') + def _filter_lines(self, lines): + """ filter lines to use in the wizard """ + line_obj = self.env['credit.control.line'] + domain = [('state', '=', 'to_be_sent'), + ('id', 'in', lines.ids), + ('channel', '=', 'email')] + return line_obj.search(domain) + + @api.multi + def email_lines(self): + self.ensure_one() + if not self.line_ids: + raise api.Warning(_('No credit control lines selected.')) + + comm_obj = self.env['credit.control.communication'] + + filtered_lines = self._filter_lines(self.line_ids) + comms = comm_obj._generate_comm_from_credit_lines(filtered_lines) + comms._generate_emails() + return {'type': 'ir.actions.act_window_close'} diff --git a/account_credit_control/wizard/credit_control_emailer_view.xml b/account_credit_control/wizard/credit_control_emailer_view.xml new file mode 100644 index 000000000..2c299a64b --- /dev/null +++ b/account_credit_control/wizard/credit_control_emailer_view.xml @@ -0,0 +1,54 @@ + + + + + credit.line.emailer.form + credit.control.emailer + +
+ + + + + + + + +
+
+ +
+
+ + + + + + + Send By Email + credit.control.emailer + form + form + + new + Send an email for the selected lines. + + + +
+
diff --git a/account_credit_control/wizard/credit_control_marker.py b/account_credit_control/wizard/credit_control_marker.py new file mode 100644 index 000000000..516c4febc --- /dev/null +++ b/account_credit_control/wizard/credit_control_marker.py @@ -0,0 +1,88 @@ +# -*- 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 . +# +############################################################################## +from openerp import models, fields, api, _ + + +class CreditControlMarker(models.TransientModel): + """ Change the state of lines in mass """ + + _name = 'credit.control.marker' + _description = 'Mass marker' + + @api.model + def _get_line_ids(self): + context = self.env.context + if not (context.get('active_model') == 'credit.control.line' and + context.get('active_ids')): + return False + line_obj = self.env['credit.control.line'] + lines = line_obj.browse(context['active_ids']) + return self._filter_lines(lines) + + name = fields.Selection([('ignored', 'Ignored'), + ('to_be_sent', 'Ready To Send'), + ('sent', 'Done')], + string='Mark as', + default='to_be_sent', + required=True) + line_ids = fields.Many2many('credit.control.line', + string='Credit Control Lines', + default=_get_line_ids, + domain="[('state', '!=', 'sent')]") + + @api.model + @api.returns('credit.control.line') + def _filter_lines(self, lines): + """ get line to be marked filter done lines """ + line_obj = self.env['credit.control.line'] + domain = [('state', '!=', 'sent'), ('id', 'in', lines.ids)] + return line_obj.search(domain) + + @api.model + @api.returns('credit.control.line') + def _mark_lines(self, filtered_lines, state): + """ write hook """ + assert state + filtered_lines.write({'state': state}) + return filtered_lines + + @api.multi + def mark_lines(self): + """ Write state of selected credit lines to the one in entry + done credit line will be ignored """ + self.ensure_one() + + if not self.line_ids: + raise api.Warning(_('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.')) + + self._mark_lines(filtered_lines, self.name) + + return {'domain': unicode([('id', 'in', filtered_lines.ids)]), + 'view_type': 'form', + 'view_mode': 'tree,form', + 'view_id': False, + 'res_model': 'credit.control.line', + 'type': 'ir.actions.act_window'} diff --git a/account_credit_control/wizard/credit_control_marker_view.xml b/account_credit_control/wizard/credit_control_marker_view.xml new file mode 100644 index 000000000..c32cc8e18 --- /dev/null +++ b/account_credit_control/wizard/credit_control_marker_view.xml @@ -0,0 +1,60 @@ + + + + + credit.line.marker.form + credit.control.marker + +
+ + + + + + + + + + + + + + +
+
+ +
+
+ + + + + + Change Lines' State + credit.control.marker + credit.control.line + form + form + + new + Change the state of the selected lines. + + +
+
diff --git a/account_credit_control/wizard/credit_control_policy_changer.py b/account_credit_control/wizard/credit_control_policy_changer.py new file mode 100644 index 000000000..6829d7aff --- /dev/null +++ b/account_credit_control/wizard/credit_control_policy_changer.py @@ -0,0 +1,148 @@ +# -*- 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 . +# +############################################################################## +import logging +from openerp import models, fields, api, _ +logger = logging.getLogger(__name__) + + +class credit_control_policy_changer(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 + + """ + _name = "credit.control.policy.changer" + + new_policy_id = fields.Many2one('credit.control.policy', + string='New Policy to Apply', + required=True) + new_policy_level_id = fields.Many2one('credit.control.policy.level', + string='New level to apply', + required=True) + # Only used to provide dynamic filtering on form + do_nothing = fields.Boolean(string='No follow policy') + + @api.model + def _get_default_lines(self): + """ Get default lines for fields move_line_ids + of wizard. Only take lines that are on the same account + and move of the invoice and not reconciled + + :return: list of compliant move lines + + """ + 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() + 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')) + + domain = [('account_id', '=', invoice.account_id.id), + ('move_id', '=', invoice.move_id.id), + ('reconcile_id', '=', False)] + move_lines = move_line_obj.search(domain) + selected_lines |= move_lines + return selected_lines + + move_line_ids = fields.Many2many('account.move.line', + rel='credit_changer_ml_rel', + string='Move line to change', + default=_get_default_lines) + + @api.onchange('new_policy_level_id') + def onchange_policy_id(self): + if not self.new_policy_id: + return + self.do_nothing = self.new_policy_id.do_nothing + + @api.model + @api.returns('credit.control.line') + def _mark_as_overridden(self, move_lines): + """ Mark `move_lines` related credit control line as overridden + This is done by setting manually_overridden fields to True + + :param move_lines: move line to mark as overridden + :return: list of credit lines that where marked as overridden + """ + credit_obj = self.env['credit.control.line'] + domain = [('move_line_id', 'in', move_lines.ids)] + credit_lines = credit_obj.search(domain) + credit_lines.write({'manually_overridden': True}) + return credit_lines + + @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.write({'credit_policy_id': policy.id}) + + @api.model + def _check_accounts_policies(self, lines, policy): + accounts = set(line.account_id for line in lines) + for account in accounts: + policy.check_policy_against_account(account) + return True + + @api.multi + def set_new_policy(self): + """ Set new policy on an invoice. + + This is done by creating a new credit control line + related to the move line and the policy setted in + the wizard form + + :return: ir.actions.act_windows dict + + """ + self.ensure_one() + credit_line_obj = self.env['credit.control.line'] + + controlling_date = fields.date.today() + self._check_accounts_policies(self.move_line_ids, self.new_policy_id) + self._mark_as_overridden(self.move_line_ids) + # As disscused with business expert + # draft lines should be passed to ignored + # if same level as the new one + # As it is a manual action + # We also ignore rounding tolerance + create = credit_line_obj.create_or_update_from_mv_lines + generated_lines = create(self.move_line_ids, + self.new_policy_level_id, + controlling_date, + check_tolerance=False) + self._set_invoice_policy(self.move_line_ids, self.new_policy_id) + + if not generated_lines: + return {'type': 'ir.actions.act_window_close'} + + action_ref = 'account_credit_control.credit_control_line_action' + action = self.env.ref(action_ref) + action = action.read()[0] + action['domain'] = [('id', 'in', generated_lines.ids)] + return action diff --git a/account_credit_control/wizard/credit_control_policy_changer_view.xml b/account_credit_control/wizard/credit_control_policy_changer_view.xml new file mode 100644 index 000000000..cee46799d --- /dev/null +++ b/account_credit_control/wizard/credit_control_policy_changer_view.xml @@ -0,0 +1,64 @@ + + + + + credit control policy form + credit.control.policy.changer + +
+ +
+
+ + + + Change current credit policy + credit.control.policy.changer + account.invoice + form + form + + new + Allows to manually change credit level + + + + + +
+
diff --git a/account_credit_control/wizard/credit_control_printer.py b/account_credit_control/wizard/credit_control_printer.py new file mode 100644 index 000000000..f6e0bf04d --- /dev/null +++ b/account_credit_control/wizard/credit_control_printer.py @@ -0,0 +1,71 @@ +# -*- 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 . +# +############################################################################## + +from openerp import models, fields, api, _ + + +class CreditControlPrinter(models.TransientModel): + """ Print lines """ + + _name = "credit.control.printer" + _rec_name = 'id' + _description = 'Mass printer' + + @api.model + def _get_line_ids(self): + context = self.env.context + if context.get('active_model') != 'credit.control.line': + return False + return context.get('active_ids', False) + + mark_as_sent = fields.Boolean(string='Mark letter lines as sent', + default=True, + help="Only letter lines will be marked.") + line_ids = fields.Many2many('credit.control.line', + string='Credit Control Lines', + default=_get_line_ids) + + @api.model + def _credit_line_predicate(self, line): + return True + + @api.model + @api.returns('credit.control.line') + def _get_lines(self, lines, predicate): + return lines.filtered(predicate) + + @api.multi + def print_lines(self): + self.ensure_one() + comm_obj = self.env['credit.control.communication'] + if not self.line_ids: + raise api.Warning(_('No credit control lines selected.')) + + lines = self._get_lines(self.line_ids, self._credit_line_predicate) + + comms = comm_obj._generate_comm_from_credit_lines(lines) + + if self.mark_as_sent: + comms._mark_credit_line_as_sent() + + report_name = 'account_credit_control.report_credit_control_summary' + report_obj = self.env['report'].with_context(active_ids=comms.ids) + return report_obj.get_action(comms, report_name) diff --git a/account_credit_control/wizard/credit_control_printer_view.xml b/account_credit_control/wizard/credit_control_printer_view.xml new file mode 100644 index 000000000..5a388ca9f --- /dev/null +++ b/account_credit_control/wizard/credit_control_printer_view.xml @@ -0,0 +1,51 @@ + + + + + credit.line.printer.form + credit.control.printer + +
+ + + + + + + + + + + +
+
+ +
+
+ + + + + + Print Lines + credit.control.printer + credit.control.line + form + form + + new + Print selected lines + + +
+