Merge lp:~camptocamp/account-financial-tools/add-credit-control-legal-claim-nbi into lp:~camptocamp/account-financial-tools/add-manual-line-and-fees-nbi

Proposed by Nicolas Bessi - Camptocamp
Status: Work in progress
Proposed branch: lp:~camptocamp/account-financial-tools/add-credit-control-legal-claim-nbi
Merge into: lp:~camptocamp/account-financial-tools/add-manual-line-and-fees-nbi
Diff against target: 1479 lines (+1377/-0)
19 files modified
account_credit_control_legal_claim/__init__.py (+23/-0)
account_credit_control_legal_claim/__openerp__.py (+59/-0)
account_credit_control_legal_claim/model/__init__.py (+24/-0)
account_credit_control_legal_claim/model/claim_fees_scheme.py (+131/-0)
account_credit_control_legal_claim/model/claim_office.py (+55/-0)
account_credit_control_legal_claim/model/partner.py (+55/-0)
account_credit_control_legal_claim/model/policy.py (+46/-0)
account_credit_control_legal_claim/report/__init__.py (+21/-0)
account_credit_control_legal_claim/report/claim_requisition_report.py (+80/-0)
account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako (+259/-0)
account_credit_control_legal_claim/report/report.xml (+18/-0)
account_credit_control_legal_claim/tests/__init__.py (+23/-0)
account_credit_control_legal_claim/tests/test_claim_requisiton_print.py (+177/-0)
account_credit_control_legal_claim/view/claim_office_view.xml (+69/-0)
account_credit_control_legal_claim/view/claim_scheme_view.xml (+73/-0)
account_credit_control_legal_claim/view/credit_control_claim_printer_view.xml (+65/-0)
account_credit_control_legal_claim/view/policy_view.xml (+24/-0)
account_credit_control_legal_claim/wizard/__init__.py (+21/-0)
account_credit_control_legal_claim/wizard/credit_control_claim_printer.py (+154/-0)
To merge this branch: bzr merge lp:~camptocamp/account-financial-tools/add-credit-control-legal-claim-nbi
Reviewer Review Type Date Requested Status
Camptocamp Pending
Review via email: mp+220801@code.launchpad.net

Description of the change

Adds dunning/legal claim management based on credit control

To post a comment you must log in.
223. By Nicolas Bessi - Camptocamp

[MRG] from parent MP

224. By Nicolas Bessi - Camptocamp

[MRG] from parent MP

225. By Nicolas Bessi - Camptocamp

[TYPO] overriden -> overridden

Unmerged revisions

225. By Nicolas Bessi - Camptocamp

[TYPO] overriden -> overridden

224. By Nicolas Bessi - Camptocamp

[MRG] from parent MP

223. By Nicolas Bessi - Camptocamp

[MRG] from parent MP

222. By Nicolas Bessi - Camptocamp

[ADD] constraint to ensure that only highest level credit policy can trigger legal claim

221. By Nicolas Bessi - Camptocamp

[ADD] description in manifest

220. By Nicolas Bessi - Camptocamp

[ADD] test for account_credit_control_legal_claim

219. By Nicolas Bessi - Camptocamp

[ADD] docstring

218. By Nicolas Bessi - Camptocamp

[ADD] base of credit control legal claim

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'account_credit_control_legal_claim'
=== added file 'account_credit_control_legal_claim/__init__.py'
--- account_credit_control_legal_claim/__init__.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/__init__.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,23 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from . import model
22from . import wizard
23from . import report
024
=== added file 'account_credit_control_legal_claim/__openerp__.py'
--- account_credit_control_legal_claim/__openerp__.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/__openerp__.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,59 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21{'name': 'Credit Control Legal Claim',
22 'version': '0.1',
23 'author': 'Camptocamp',
24 'maintainer': 'Camptocamp',
25 'category': 'Accounting',
26 'complexity': 'normal',
27 'depends': ['base_location',
28 'base_headers_webkit',
29 'account_credit_control'],
30 'description': """
31Credit Control Legal Claim
32--------------------------
33
34This addons allows to manage legal claim requisition
35from credit controling.
36
37This is done by setting a boolean "Legal claim"
38on credit control policy level.
39
40
41From then you can print claim requisition letter from invoice
42user the: ::
43
44 more -> Print Legal Claim Letter
45
46""",
47 'website': 'http://www.camptocamp.com',
48 'data': ['view/claim_office_view.xml',
49 'view/claim_scheme_view.xml',
50 'view/credit_control_claim_printer_view.xml',
51 'report/report.xml',
52 'view/policy_view.xml'],
53 'demo': [],
54 'test': [],
55 'installable': True,
56 'auto_install': False,
57 'license': 'AGPL-3',
58 'application': False,
59 }
060
=== added directory 'account_credit_control_legal_claim/i18n'
=== added directory 'account_credit_control_legal_claim/model'
=== added file 'account_credit_control_legal_claim/model/__init__.py'
--- account_credit_control_legal_claim/model/__init__.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/model/__init__.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,24 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from . import claim_office
22from . import claim_fees_scheme
23from . import policy
24from . import partner
025
=== added file 'account_credit_control_legal_claim/model/claim_fees_scheme.py'
--- account_credit_control_legal_claim/model/claim_fees_scheme.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/model/claim_fees_scheme.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,131 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2013 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from operator import attrgetter
22from openerp.osv import orm, fields
23
24
25class claim_fees_scheme(orm.Model):
26 """Claim fees
27
28 Claim offices take fees based on open amount
29 whan a legal action is taken.
30
31 The model represent the scheme open amount/fees
32
33 """
34
35 _name = 'legal.claim.fees.scheme'
36
37 _columns = {
38 'name': fields.char('Name',
39 required=True),
40 'product_id': fields.many2one('product.product',
41 'Product',
42 required=True),
43 'claim_scheme_line_ids': fields.one2many('legal.claim.fees.scheme.line',
44 'claim_scheme_id',
45 'Price lists'),
46 'company_id': fields.many2one('res.company',
47 'Company'),
48 'currency_id': fields.many2one('res.currency',
49 'Currency',
50 required=True),
51 }
52
53 def _company_get(self, cr, uid, context=None):
54 """Return related company"""
55 return self.pool['res.company']._company_default_get(cr, uid,
56 'claim.fees.scheme',
57 context=context)
58 _defaults = {'company_id': _company_get}
59
60 def _due_from_invoices(self, invoices_records, context=None):
61 """Compute due amount form a list of invoice
62
63 :param invoices_record: list of invoice records
64
65 :returns: due amount (float)
66
67 """
68 return sum(x.residual for x in invoices_records)
69
70 def get_fees_from_amount(self, cr, uid, ids, due_amount, context=None):
71 """Get the fees from open amount
72
73 :param due_amount: float of the open (due) amount
74
75 :returns: fees amount (float)
76
77 """
78 assert len(ids) == 1, 'Only on id expected'
79 current = self.browse(cr, uid, ids[0], context=context)
80 lines = current.claim_scheme_line_ids
81 lines.sort(key=attrgetter('open_amount'), reverse=True)
82 for line in lines:
83 if due_amount >= line.open_amount:
84 return line.fees
85 return lines[-1].fees
86
87 def get_fees_from_invoices(self, cr, uid, ids, invoice_ids, context=None):
88 """Get the fees form a list of invoice ids
89
90 :param invoice_ids: list of invoice_ids
91
92 :returns: fees amount (float)
93
94 """
95 assert len(ids) == 1, 'Only on id expected'
96 invoices = self.pool['account.invoice'].browse(cr, uid, invoice_ids,
97 context=context)
98 return self._get_fees_from_invoices(cr, uid, ids, invoices,
99 context=context)
100
101 def _get_fees_from_invoices(self, cr, uid, ids, invoices, context=None):
102 """Get the fees form a list of invoice record
103
104 :param invoice_ids: list of invoice record
105
106 :returns: fees amount (float)
107
108 """
109 assert len(ids) == 1, 'Only on id expected'
110 current = self.browse(cr, uid, ids[0], context=context)
111 due = self._due_from_invoices(invoices, context=context)
112 return current.get_fees_from_amount(due)
113
114
115class claim_fees_scheme_line(orm.Model):
116 """Price list line of scheme
117 that contains price and qty"""
118
119 _name = 'legal.claim.fees.scheme.line'
120 _rec_name = "open_amount"
121 _order = "open_amount"
122
123 _columns = {
124 'claim_scheme_id': fields.many2one('legal.claim.fees.scheme',
125 'Price list',
126 required=True),
127 'open_amount': fields.integer('Open Amount',
128 required=True),
129 'fees': fields.float('Fees',
130 required=True),
131 }
0132
=== added file 'account_credit_control_legal_claim/model/claim_office.py'
--- account_credit_control_legal_claim/model/claim_office.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/model/claim_office.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,55 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from openerp.osv import orm, fields
22
23
24class claim_office(orm.Model):
25 """Claim office"""
26
27 _name = "legal.claim.office"
28 _columns = {
29
30 'name': fields.char('Name',
31 required=True),
32
33 'locations_ids': fields.one2many('res.better.zip',
34 'claim_office_id',
35 'Related zip'),
36
37 'fees_scheme_id': fields.many2one('legal.claim.fees.scheme',
38 'Fees Scheme',
39 select=1,
40 required=True),
41 'partner_id': fields.many2one('res.partner',
42 'Office Address',
43 required=True),
44 }
45
46
47class better_zip(orm.Model):
48 """Add relation to claim office"""
49
50 _inherit = "res.better.zip"
51 _columns = {
52 'claim_office_id': fields.many2one('legal.claim.office',
53 'Claim office',
54 select=True),
55 }
056
=== added file 'account_credit_control_legal_claim/model/partner.py'
--- account_credit_control_legal_claim/model/partner.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/model/partner.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,55 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from openerp.osv import orm, fields
22
23
24class res_partner(orm.Model):
25 """Add related claim office"""
26 def _get_claim_office(self, cr, uid, ids, field, args, context=None):
27 res = {}
28 location_model = self.pool['res.better.zip']
29 for partner in self.browse(cr, uid, ids, context=context):
30 res[partner.id] = False
31 domain = [('name', '=', partner.zip),
32 ('city', '=', partner.city),
33 ('claim_office_id', '!=', False)]
34 location_id = location_model.search(cr, uid, domain,
35 order='priority',
36 limit=1,
37 context=context)
38 if not location_id:
39 continue
40 loc = location_model.read(cr,
41 uid,
42 location_id,
43 ['claim_office_id'],
44 load='_classic_write',
45 context=context)
46 res[partner.id] = loc[0]['claim_office_id']
47 return res
48
49 _inherit = "res.partner"
50 _columns = {
51 'claim_office_id': fields.function(_get_claim_office,
52 type='many2one',
53 relation='legal.claim.office',
54 string='Claim office')
55 }
056
=== added file 'account_credit_control_legal_claim/model/policy.py'
--- account_credit_control_legal_claim/model/policy.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/model/policy.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,46 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from openerp.osv import orm, fields
22from openerp.tools.translate import _
23
24class credit_control_policy_level(orm.Model):
25 """Add claim type to policy level"""
26
27 _inherit = "credit.control.policy.level"
28 _columns = {
29 'is_legal_claim': fields.boolean('Legal Claim Action')
30 }
31
32 def _check_legal_claim_level(self, cr, uid, ids, context=None):
33 for current_level in self.browse(cr, uid, ids, context=context):
34 levels = current_level.policy_id.level_ids
35 highest = max(levels, key= lambda x: x.level)
36 for lvl in levels:
37 if lvl.is_legal_claim and lvl != highest:
38 raise orm.except_orm(
39 _('Only highest level can be tickes as legal claim'),
40 _('The current highest level is %s') % highest.name
41 )
42 return True
43
44 _constraints = [(_check_legal_claim_level,
45 'Only highest level can be legal claim',
46 ['is_legal_claim'])]
047
=== added directory 'account_credit_control_legal_claim/report'
=== added file 'account_credit_control_legal_claim/report/__init__.py'
--- account_credit_control_legal_claim/report/__init__.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/report/__init__.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,21 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from . import claim_requisition_report
022
=== added file 'account_credit_control_legal_claim/report/claim_requisition_report.py'
--- account_credit_control_legal_claim/report/claim_requisition_report.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/report/claim_requisition_report.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,80 @@
1 # -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21import time
22import operator
23from itertools import groupby
24from itertools import chain
25from openerp.report import report_sxw
26from openerp.osv import fields
27
28class CreditClaimRequisition(report_sxw.rml_parse):
29 def __init__(self, cr, uid, name, context):
30 super(CreditClaimRequisition, self).__init__(cr, uid, name,
31 context=context)
32 self.localcontext.update({
33 'time': time,
34 'cr': cr,
35 'uid': uid,
36 'today': fields.date.today(),
37 'compute_dunning_fees': self.compute_dunning_fees,
38 'compute_due_amount': self.compute_due_amount,
39 'get_legal_claim_fees': self.get_legal_claim_fees,
40 'compute_paid_amount': self.compute_paid_amount,
41 })
42
43 def _active_line(self, cr, uid, line, context=None):
44 return (line.state not in ('draft', 'ignored') and
45 not line.manually_overridden)
46
47 def compute_dunning_fees(self, invoices):
48 lines = chain.from_iterable([x.credit_control_line_ids for x in invoices])
49 return sum(x.dunning_fees_amount for x in lines
50 if self._active_line(self.cr, self. uid, x))
51
52 def get_legal_claim_fees(self, part, invoices):
53 scheme = part.claim_office_id.fees_scheme_id
54 return scheme.get_fees_from_invoices([x.id for x in invoices])
55
56 def compute_due_amount(self, invoices):
57 return sum(x.residual for x in invoices)
58
59 def compute_paid_amount(self, invoices):
60 return sum(x.amount_total - x.residual for x in invoices)
61
62 def set_context(self, objects, data, ids, report_type=None):
63 """Group invoice by partner and currency and replace objects
64 with partner
65
66 """
67 new_objects = []
68 for key, invoices in groupby(objects, lambda x: (x.partner_id, x.currency_id)):
69 part = key[0]
70 part.claim_invoices = list(invoices)
71 part.claim_currency = key[1]
72 new_objects.append(part)
73 return super(CreditClaimRequisition, self).set_context(
74 new_objects, data, id, report_type=report_type
75 )
76
77report_sxw.report_sxw('report.credit_control_legal_claim_requisition',
78 'credit.control.communication',
79 'addons/account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako',
80 parser=CreditClaimRequisition)
081
=== added file 'account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako'
--- account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako 2014-05-27 07:08:15 +0000
@@ -0,0 +1,259 @@
1## -*- coding: utf-8 -*-
2<html>
3 <head>
4 <style type="text/css">
5 ${css}
6body {
7
8 font-family: helvetica;
9 font-size: 12px;
10}
11
12.left_form_no{
13 font-family: helvetica;
14 font-size: 12px;
15 text-align: left;
16 border-bottom-style:solid;
17 border-width:1px;
18 width:30%;
19}
20
21.right_form_no{
22 font-family: helvetica;
23 font-size: 12px;
24 text-align: left;
25 border-bottom-style:solid;
26 border-width:1px;
27 width:30%;
28}
29.custom_text {
30 font-family: helvetica;
31 font-size: 12px;
32}
33
34.receive_date{
35 font-family: helvetica;
36 font-size: 12px;
37 text-align: left;
38 font-weight: bold;
39}
40
41
42.claim_office_address{
43 font-family: helvetica;
44 font-size: 12px;
45 text-align: left;
46 vertical-align:text-bottom;
47}
48
49.stake_holder_table td{
50 border-width:1px;
51 border-bottom-style:solid;
52 border-top-style:solid;
53}
54
55.stake_holder_table{
56 font-family: helvetica;
57 font-size: 12px;
58 border-collapse:collapse;
59 width: 100%;
60}
61
62.stake_holder_name{
63 vertical-align:text-top;
64 font-weight: bold;
65 text-decoration:underline;
66 width:30%;
67}
68
69.stake_holder_reference{
70 vertical-align:text-top;
71 width:30%;
72}
73
74.claim_reasons{
75 font-family: helvetica;
76 font-size: 12px;
77 font-weight:bold;
78
79}
80
81.claim_table{
82 font-family: helvetica;
83 font-size: 12px;
84 border-collapse:collapse;
85 width:55%
86}
87
88.summary_table{
89 font-family: helvetica;
90 font-size: 12px;
91 border-collapse:collapse;
92 width:55%
93}
94
95.paid_amount_summary_table{
96 font-family: helvetica;
97 font-size: 12px;
98 font-weight:bold;
99 border-collapse:collapse;
100}
101
102td.amount, th.amount {
103 text-align: right;
104 padding-right:2px;
105}
106
107.signature{
108 font-family: helvetica;
109 font-size: 12px;
110 border-collapse:collapse;
111}
112
113.date_and_place{
114 vertical-align:text-top;
115 width:30%;
116}
117
118.signature_address{
119 vertical-align:text-top;
120 width:30%;
121}
122
123.title{
124 text-align.center;
125}
126
127 </style>
128 </head>
129 <body>
130
131 %for part in objects :
132 <% setLang(part.lang) %>
133 <br/>
134 <h3 class="title" align="center">${_('Legal Claim Requisition')}</h3>
135 <table width="100%">
136 <tr>
137 <td class="left_form_no">${_('From. No')}</td>
138 <td></td>
139 <td class="right_form_no">${_('Claim No')}</td>
140 </tr>
141 <tr height="50px">
142 <td class="receive_date">${_('Claim receive by office, the:......')}</td>
143 <td colspan="2"></td>
144 <td></td>
145 </tr>
146 <tr>
147 <td></td>
148 <td></td>
149 <td class="claim_office_address">${part.claim_office_id.partner_id.display_name}<br/>
150 <% address_lines = part.claim_office_id.partner_id.contact_address.split("\n") %>
151 %for add_part in address_lines:
152 % if add_part:
153 ${add_part}<br/>
154 % endif
155 %endfor
156 </td>
157 </tr>
158 </table>
159 <br/>
160 <br/>
161 <br/>
162 <div class="state_style">${_('State:')} ${part.claim_office_id.partner_id.state_id.name}</div>
163 <table class="stake_holder_table">
164 <%
165 debtor = part
166 creditor = company.partner_id
167 %>
168 <tr class="stake_holder_line">
169 <td class="stake_holder_name">${_('Debtor:')}</td>
170 <td class="stake_holder_address">${part.display_name}<br/>
171 <% address_lines = part.contact_address.split("\n") %>
172 %for add_part in address_lines:
173 % if add_part:
174 ${add_part}<br/>
175 % endif
176 %endfor
177
178 </td>
179 <td class="stake_holder_reference">${part.ref or _('N/A')}
180 <br/>
181 <br/>
182 birthdate ${formatLang(part.birthday_date, date=True) or _('N/A')}
183 </td>
184 </tr>
185 <tr class="stake_holder_line">
186 <td class="stake_holder_name">${_('Creditor:')}</td>
187 <td class="stake_holder_address">${creditor.display_name} <br/>
188 <% address_lines = creditor.contact_address.split("\n") %>
189 %for add_part in address_lines:
190 % if add_part:
191 ${add_part}<br/>
192 % endif
193 %endfor
194 </td>
195 <td class="stake_holder_reference">${creditor.phone or ''} </td>
196 </tr>
197 </table>
198 <br/>
199 <br/>
200 <div class="claim_reasons">${_('Claim Reasons')}</div>
201 <div>
202
203 <table class="claim_table">
204 </tr>
205%for inv in part.claim_invoices:
206 <tr>
207 <td class="date">${_('Invoice')} ${inv.number} of ${formatLang(inv.date_invoice, date=True)}, due at ${formatLang(inv.date_due, date=True)}</td>
208 <td>${_('Due amount')}</td>
209 <td class="amount">${formatLang(inv.residual)} ${part.claim_currency.name}</td>
210 </tr>
211%endfor
212 </table>
213 <br/>
214 <br/>
215 <table class="summary_table">
216 <tr>
217 <td>${_('Amount due')}</td>
218 <td>${formatLang(compute_due_amount(part.claim_invoices))} ${part.claim_currency.name}</td>
219 <td></td>
220 </tr>
221 <tr>
222 <td>${_('Dunning Fees')}</td>
223 <td>${formatLang(compute_dunning_fees(part.claim_invoices))} ${part.claim_currency.name}</td>
224 <td></td>
225 </tr>
226 <tr>
227 <td>${_('Legal Claim Fees')}</td>
228 <td>${formatLang(get_legal_claim_fees(part, part.claim_invoices))} ${part.claim_currency.name}</td>
229 <td></td>
230 </tr>
231 </table>
232 <table class="paid_amount_summary_table">
233 <tr>
234 <td height="50px">${_('Debtor already paid amount')} ${formatLang(compute_paid_amount(part.claim_invoices))} ${part.claim_currency.name}</td>
235 </tr>
236 </table>
237 <br/>
238 <br/>
239 <table class="signature">
240 <tr>
241 <td class="date_and_place"><b>${_('Date and place')}</b> <br/><br/><br/>
242 ${creditor.city or ''}, ${formatLang(today, date=True)}
243 </td>
244 <td></td>
245 <td class="signature_address">${creditor.display_name} <br/>
246 <% address_lines = creditor.contact_address.split("\n") %>
247 %for add_part in address_lines:
248 % if add_part:
249 ${add_part}<br/>
250 % endif
251 %endfor
252 </td>
253 </tr>
254 </table>
255 <p style="page-break-after:always"></p>
256 %endfor
257
258 </body>
259</html>
0260
=== added file 'account_credit_control_legal_claim/report/report.xml'
--- account_credit_control_legal_claim/report/report.xml 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/report/report.xml 2014-05-27 07:08:15 +0000
@@ -0,0 +1,18 @@
1<openerp>
2 <data>
3 <report auto="False"
4 id="legal_claim_report_webkit"
5 model="account.invoice"
6 name="credit_control_legal_claim_requisition"
7 file="account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako"
8 string="Credit Summary Claim"
9 report_type="webkit"
10 webkit_header="base_headers_webkit.base_minimum_reports_portrait_header"/>
11
12 <record model="ir.actions.report.xml" id="legal_claim_report_webkit">
13 <field name="precise_mode" eval="True"/>
14 <field name="header" eval="False"/>
15 </record>
16
17 </data>
18</openerp>
019
=== added directory 'account_credit_control_legal_claim/security'
=== added directory 'account_credit_control_legal_claim/tests'
=== added file 'account_credit_control_legal_claim/tests/__init__.py'
--- account_credit_control_legal_claim/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/tests/__init__.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,23 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from . import test_claim_requisiton_print
22
23checks = [test_claim_requisiton_print]
024
=== added file 'account_credit_control_legal_claim/tests/test_claim_requisiton_print.py'
--- account_credit_control_legal_claim/tests/test_claim_requisiton_print.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/tests/test_claim_requisiton_print.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,177 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from mock import MagicMock, patch
22import openerp.tests.common as test_common
23
24
25class ClaimRequisitionTester(test_common.TransactionCase):
26
27 def setUp(self):
28 """Initialaize credit control level mock to test fees computations"""
29 super(ClaimRequisitionTester, self).setUp()
30 self.currency_model = self.registry('res.currency')
31 self.euro = self.currency_model.search(self.cr, self.uid,
32 [('name', '=', 'EUR')])
33 self.assertTrue(self.euro)
34 self.euro = self.registry('res.currency').browse(self.cr,
35 self.uid,
36 self.euro[0])
37
38 self.euro_level = MagicMock(name='Euro policy level')
39 self.euro_level.dunning_fixed_amount = 5.0
40 self.euro_level.dunning_currency_id = self.euro
41 self.euro_level.dunning_type = 'fixed'
42 self.euro_level.is_legal_claim = True
43
44 self.euro_level_no_claim = MagicMock(name='Euro policy level no claim')
45 self.euro_level_no_claim.dunning_fixed_amount = 5.0
46 self.euro_level_no_claim.dunning_currency_id = self.euro
47 self.euro_level_no_claim.dunning_type = 'fixed'
48 self.euro_level_no_claim.is_legal_claim = False
49
50 credit_line = MagicMock(name='Euro credit line')
51 credit_line.policy_level_id = self.euro_level
52 credit_line.currency_id = self.euro
53 credit_line.dunning_fees_amount = 10
54
55 no_claim_credit_line = MagicMock(name='No claim credit line')
56 no_claim_credit_line.policy_level_id = self.euro_level_no_claim
57 no_claim_credit_line.currency_id = self.euro
58 no_claim_credit_line.dunning_fees_amount = 33
59 self.credit_line = credit_line
60 self.no_claim_credit_line = no_claim_credit_line
61
62 self.claim_invoice_1 = MagicMock(name='Claim Invoice 1')
63 self.claim_invoice_1.partner_id = self.browse_ref("base.res_partner_12")
64 self.claim_invoice_1.currency_id = self.euro
65 self.claim_invoice_1.residual = 50.00
66 self.claim_invoice_1.amount_total = 130.00
67 self.claim_invoice_1.credit_control_line_ids = [credit_line,
68 credit_line]
69
70 self.claim_invoice_2 = MagicMock(name='Claim Invoice 1')
71 self.claim_invoice_2.partner_id = self.browse_ref("base.res_partner_12")
72 self.claim_invoice_2.currency_id = self.euro
73 self.claim_invoice_2.residual = 50.00
74 self.claim_invoice_2.amount_total = 130.00
75 self.claim_invoice_2.credit_control_line_ids = [credit_line,
76 credit_line]
77
78 self.non_claim_invoice_1 = MagicMock(name='Non Claim Invoice 1')
79 self.non_claim_invoice_1.partner_id = self.browse_ref("base.res_partner_12")
80 self.non_claim_invoice_1.currency_id = self.euro
81 self.non_claim_invoice_1.residual = 50.00
82 self.non_claim_invoice_1.amount_total = 130.00
83 self.non_claim_invoice_1.credit_control_line_ids = [no_claim_credit_line,
84 no_claim_credit_line]
85
86 scheme_id = self.registry('legal.claim.fees.scheme').create(
87 self.cr,
88 self.uid,
89 {
90 'name': 'r1',
91 'product_id': self.browse_ref('product.product_product_3').id,
92 'currency_id': self.euro.id,
93 }
94 )
95
96 self.registry('legal.claim.fees.scheme.line').create(
97 self.cr,
98 self.uid,
99 {
100 'claim_scheme_id': scheme_id,
101 'open_amount': 0,
102 'fees': 30
103 }
104 )
105
106 self.registry('legal.claim.fees.scheme.line').create(
107 self.cr,
108 self.uid,
109 {
110 'claim_scheme_id': scheme_id,
111 'open_amount': 500,
112 'fees': 70,
113 }
114 )
115
116 claim_office_id = self.registry('legal.claim.office').create(
117 self.cr,
118 self.uid,
119 {
120 'name': 'Lausanne',
121 'partner_id': self.browse_ref('base.res_partner_13').id,
122 'fees_scheme_id': scheme_id,
123 }
124 )
125
126 self.registry('res.better.zip').create(
127 self.cr,
128 self.uid,
129 {
130 'name': '1001',
131 'city': 'lausanne',
132 'claim_office_id': claim_office_id,
133 }
134 )
135
136 self.claim_office = self.registry('legal.claim.office').browse(
137 self.cr,
138 self.uid,
139 claim_office_id,
140 )
141
142 def test_00_filter(self):
143 """Test filter invoices"""
144 wiz_model = self.registry('credit.control.legal.claim.printer')
145 res = wiz_model._filter_claim_invoices(self.cr, self.uid,
146 [self.claim_invoice_1,
147 self.claim_invoice_2,
148 self.non_claim_invoice_1])
149 self.assertEqual(res, [self.claim_invoice_1,
150 self.claim_invoice_2])
151
152 def test_01_mark(self):
153 self.claim_invoice_1.credit_control_line_ids.append(self.no_claim_credit_line)
154 wiz_model = self.registry('credit.control.legal.claim.printer')
155 target = 'openerp.osv.orm.BaseModel.write'
156 with patch(target, MagicMock()):
157 res = wiz_model._mark_invoice_as_claimed(self.cr,
158 self.uid,
159 self.claim_invoice_1)
160 self.assertEqual(res, [self.no_claim_credit_line])
161
162 def test_02_get_fees(self):
163 scheme = self.claim_office.fees_scheme_id
164 fees = scheme.get_fees_from_amount(50.00)
165 self.assertEqual(fees, 30)
166 fees = scheme.get_fees_from_amount(550.00)
167 self.assertEqual(fees, 70)
168
169 def test_03_get_fees_from_invoices(self):
170 scheme = self.claim_office.fees_scheme_id
171 fees = scheme._get_fees_from_invoices([self.claim_invoice_1,
172 self.claim_invoice_1])
173 self.assertEqual(fees, 30)
174 self.claim_invoice_1.residual = 800
175 scheme = self.claim_office.fees_scheme_id
176 fees = scheme._get_fees_from_invoices([self.claim_invoice_1,
177 self.claim_invoice_1])
0178
=== added directory 'account_credit_control_legal_claim/view'
=== added file 'account_credit_control_legal_claim/view/claim_office_view.xml'
--- account_credit_control_legal_claim/view/claim_office_view.xml 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/view/claim_office_view.xml 2014-05-27 07:08:15 +0000
@@ -0,0 +1,69 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="claim_office_list_view" model="ir.ui.view">
6 <field name="name">claim office list view</field>
7 <field name="model">legal.claim.office</field>
8 <field name="arch" type="xml">
9 <tree version="7.0" string="Claim office">
10 <field name="name"/>
11 </tree>
12 </field>
13 </record>
14
15 <record id="claim_office_form_view" model="ir.ui.view">
16 <field name="name">claim office form view</field>
17 <field name="model">legal.claim.office</field>
18 <field name="arch" type="xml">
19 <form version="7.0" string="Claim office">
20 <header>
21 <button
22 type="action"
23 name="%(base_location.action_zip_tree)d"
24 string="Related Locations"/>
25 </header>
26 <group>
27 <field name="name"/>
28 <field name="partner_id"/>
29 <field name="fees_scheme_id"/>
30 </group>
31 </form>
32 </field>
33 </record>
34
35
36 <record model="ir.actions.act_window" id="claim_office_action">
37 <field name="name">Claim Office</field>
38 <field name="type">ir.actions.act_window</field>
39 <field name="res_model">legal.claim.office</field>
40 <field name="domain"></field>
41 <field name="view_type">form</field>
42 <field name="view_mode">tree,form</field>
43 <field name="view_id" ref="claim_office_list_view"/>
44 </record>
45
46 <menuitem
47 name="Credit control Legal Claim"
48 parent="account.menu_finance_configuration"
49 id="root_legal_claim_menu"/>
50
51 <menuitem
52 name="Claim Office"
53 parent="root_legal_claim_menu"
54 action="claim_office_action"
55 id="claim_office_action_menu"/>
56
57 <record id="add_office_to_location" model="ir.ui.view">
58 <field name="name">add office to location</field>
59 <field name="model">res.better.zip</field>
60 <field name="inherit_id" ref="base_location.better_zip_form" />
61 <field name="arch" type="xml">
62 <field name="country_id" position="after">
63 <field name="claim_office_id"/>
64 </field>
65 </field>
66 </record>
67
68 </data>
69</openerp>
070
=== added file 'account_credit_control_legal_claim/view/claim_scheme_view.xml'
--- account_credit_control_legal_claim/view/claim_scheme_view.xml 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/view/claim_scheme_view.xml 2014-05-27 07:08:15 +0000
@@ -0,0 +1,73 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="claim_scheme_list_view" model="ir.ui.view">
5 <field name="name">claime scheme list view</field>
6 <field name="model">legal.claim.fees.scheme</field>
7 <field name="arch" type="xml">
8 <tree version="7.0" string="Claim fees"> <!-- editable="bottom" -->
9 <field name="name" />
10 <field name="company_id" groups="base.group_multi_company" widget="selection"/>
11 <field name="product_id"/>
12 </tree>
13 </field>
14 </record>
15
16
17 <record id="claim_scheme_form_view" model="ir.ui.view">
18 <field name="name">Claim Scheme form</field>
19 <field name="model">legal.claim.fees.scheme</field>
20 <field name="arch" type="xml">
21 <form version="7.0" string="Claim Scheme">
22 <header>
23 </header>
24 <sheet>
25 <group>
26 <group>
27 <field name="name"/>
28 </group>
29 </group>
30 <group>
31 <group>
32 <field name="company_id" groups="base.group_multi_company" widget="selection"/>
33 <field name="product_id"/>
34 <field name="currency_id"/>
35 </group>
36 </group>
37
38 <notebook>
39 <page string="Scheme values" colspan="4">
40 <field name="claim_scheme_line_ids"
41 required="1">
42 <tree type="7.0" string="Line" editable="top">
43 <field name="open_amount"/>
44 <field name="fees"/>
45 </tree>
46 </field>
47 </page>
48 </notebook>
49 </sheet>
50 </form>
51 </field>
52 </record>
53
54 <record model="ir.actions.act_window" id="claim_scheme_menu_action">
55 <field name="name">Claim office</field>
56 <field name="type">ir.actions.act_window</field>
57 <field name="res_model">legal.claim.fees.scheme</field>
58 <field name="domain"></field>
59 <field name="view_type">form</field>
60 <field name="view_mode">tree,form</field>
61 <field name="view_id" ref="claim_scheme_list_view"/>
62 </record>
63
64
65
66 <menuitem
67 name="Claim scheme"
68 parent="root_legal_claim_menu"
69 action="claim_scheme_menu_action"
70 id="claim_scheme_menu_action_menu"/>
71
72 </data>
73</openerp>
074
=== added file 'account_credit_control_legal_claim/view/credit_control_claim_printer_view.xml'
--- account_credit_control_legal_claim/view/credit_control_claim_printer_view.xml 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/view/credit_control_claim_printer_view.xml 2014-05-27 07:08:15 +0000
@@ -0,0 +1,65 @@
1<openerp>
2 <data>
3
4 <record id="credit_control_claim_printer_view" model="ir.ui.view">
5 <field name="name">credit control claim printer view</field>
6 <field name="model">credit.control.legal.claim.printer</field>
7 <field name="arch" type="xml">
8 <form version="7.0"
9 string="Claim Printer">
10 <separator string="Print claim requisition letter for invoices" colspan="4"/>
11 <newline/>
12 <group>
13 <field name="mark_as_claimed"
14 colspan="4"
15 attrs="{'invisible': [('state', '=', 'done')]}"/>
16 </group>
17 <newline/>
18 <notebook>
19 <page string="Invoices" attrs="{'invisible': [('state', '=', 'done')]}">
20 <field name="invoice_ids" colspan="4" nolabel="1"
21 attrs="{'invisible': [('state', '=', 'done')]}" />
22 </page>
23 </notebook>
24 <field name="report_name"
25 invisible="1"/>
26 <field name="report_file"
27 colspan="4"
28 filename="report_name"
29 attrs="{'invisible': [('state', '!=', 'done')]}"/>
30 <field name="state" invisible="1" />
31 <newline/>
32 <footer>
33 <button class="oe_highlight" name="print_claims" string="Print" type="object" attrs="{'invisible': [('state', '==', 'done')]}"/>
34 <button special="cancel" string="Cancel" icon='gtk-cancel' attrs="{'invisible': [('state', '==', 'done')]}"/>
35 <button special="cancel" string="Close" icon='gtk-close' attrs="{'invisible': [('state', '!=', 'done')]}"/>
36 </footer>
37
38
39 </form>
40 </field>
41 </record>
42
43 <!-- for button -->
44 <record id="legal_claim_printer_action" model="ir.actions.act_window">
45 <field name="name">Print Claim Requisition</field>
46 <field name="res_model">credit.control.legal.claim.printer</field>
47 <field name="src_model">account.invoice</field>
48 <field name="view_type">form</field>
49 <field name="view_mode">form</field>
50 <field name="view_id" ref="credit_control_claim_printer_view"/>
51 <field name="target">new</field>
52 <field name="help"></field>
53 </record>
54
55 <!-- for menu -->
56 <act_window name="Print Claim Requisition"
57 res_model="credit.control.legal.claim.printer"
58 src_model="account.invoice"
59 view_mode="form"
60 target="new"
61 key2="client_action_multi"
62 id="legal_claim_printer_action_menu_action"/>
63
64 </data>
65</openerp>
066
=== added file 'account_credit_control_legal_claim/view/policy_view.xml'
--- account_credit_control_legal_claim/view/policy_view.xml 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/view/policy_view.xml 2014-05-27 07:08:15 +0000
@@ -0,0 +1,24 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="add_claim_on_policy_level" model="ir.ui.view">
5 <field name="name">add claim on policy level</field>
6 <field name="model">credit.control.policy</field>
7 <field name="inherit_id"
8 ref="account_credit_control.credit_control_policy_form"/>
9 <field name="arch" type="xml">
10 <page string="Mail and reporting" position="after">
11 <page string="Legal Claim">
12 <group>
13 <group>
14 <field name="is_legal_claim"/>
15 </group>
16 </group>
17 </page>
18 </page>
19
20 </field>
21 </record>
22
23 </data>
24</openerp>
025
=== added directory 'account_credit_control_legal_claim/wizard'
=== added file 'account_credit_control_legal_claim/wizard/__init__.py'
--- account_credit_control_legal_claim/wizard/__init__.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/wizard/__init__.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,21 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from . import credit_control_claim_printer
022
=== added file 'account_credit_control_legal_claim/wizard/credit_control_claim_printer.py'
--- account_credit_control_legal_claim/wizard/credit_control_claim_printer.py 1970-01-01 00:00:00 +0000
+++ account_credit_control_legal_claim/wizard/credit_control_claim_printer.py 2014-05-27 07:08:15 +0000
@@ -0,0 +1,154 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21import base64
22import netsvc
23from openerp.osv import orm, fields
24
25
26class credit_control_legal_printer(orm.TransientModel):
27 """Print claim requisition letter
28
29 And manage related credit lines
30
31 """
32
33 def _filter_claim_invoices(self, cr, uid, invoices, context=None):
34 """ Return invoices that are related to a claim
35 concretly that means the invoice must be related
36 to active credit line related to a claim policy level
37
38 :param invoices: list on invoices record to be filtered
39
40 """
41
42 filtered = []
43 for inv in invoices:
44 if any(x for x in inv.credit_control_line_ids
45 if x.policy_level_id.is_legal_claim):
46 filtered.append(inv)
47 return filtered
48
49 def _get_invoice_ids(self, cr, uid, context=None):
50 """Return invoices ids to be treated form context
51 A candidate invoice is related to a claim
52
53 """
54 inv_model = self.pool['account.invoice']
55 if context is None:
56 context = {}
57 res = False
58 if context.get('active_model') != 'account.invoice':
59 return res
60 res = context.get('active_ids', False)
61 if res:
62 invoices = inv_model.browse(cr, uid, res, context=context)
63 filtered = self._filter_claim_invoices(cr, uid, invoices,
64 context=context)
65 res = [x.id for x in filtered]
66 return res
67
68 _name = "credit.control.legal.claim.printer"
69 _rec_name = 'id'
70 _columns = {
71 'mark_as_claimed': fields.boolean('Mark as Claimed'),
72 'report_file': fields.binary('Report File',
73 readonly=True),
74 'report_name': fields.char('Report Name'),
75 'invoice_ids': fields.many2many('account.invoice',
76 string='Invoices'),
77 'state': fields.selection([('draft', 'Draft'),
78 ('done', 'Done')]),
79 }
80
81 _defaults = {
82 'invoice_ids': _get_invoice_ids,
83 'mark_as_claimed': True,
84 }
85
86 def _generate_report(self, cr, uid, invoice_ids, context=None):
87 """Generate claim requisition report.
88
89 :param invoice_ids: list of invoice ids to print
90
91 :returns: report file
92
93 """
94 service = netsvc.LocalService('report.credit_control_legal_claim_requisition')
95 result, format = service.create(cr, uid, invoice_ids, {}, {})
96 return result
97
98 def _mark_invoice_as_claimed(self, cr, uid, invoice, context=None):
99 """Mark related credit line of an invoice as overridden.
100
101 Only non claim credit line will be marked
102
103 :param invoice: invoice recorrd to treat
104
105 :returns: marked credit lines
106 """
107 lines = [x for x in invoice.credit_control_line_ids
108 if not x.policy_level_id.is_legal_claim]
109 credit_line_model = self.pool['credit.control.line']
110 data = {'manually_overridden': True}
111 credit_line_model.write(cr, uid,
112 [x.id for x in lines],
113 data,
114 context=context)
115 return lines
116
117 def print_claims(self, cr, uid, wiz_id, context=None):
118 """Generate claim requisition report and manage credit lines.
119
120 Non claim credit lines will be overridden
121
122 :param invoice_ids: list of invoice ids to print
123
124 :returns: an ir.action to himself
125
126 """
127 if isinstance(wiz_id, list):
128 assert len(wiz_id) == 1
129 wiz_id = wiz_id[0]
130
131 current = self.browse(cr, uid, wiz_id, context=context)
132 invs = self._filter_claim_invoices(cr, uid, current.invoice_ids,
133 context=context)
134 invoice_ids = [x.id for x in invs]
135 assert invoice_ids
136 report_file = self._generate_report(cr, uid, invoice_ids,
137 context=context)
138 current.write(
139 {'report_file': base64.b64encode(report_file),
140 'report_name': 'claim_letters_%s.pdf' % fields.datetime.now(),
141 'state': 'done'}
142 )
143 if current.mark_as_claimed:
144 for inv in invs:
145 self._mark_invoice_as_claimed(cr, uid, inv, context=context)
146
147 return {'type': 'ir.actions.act_window',
148 'res_model': 'credit.control.legal.claim.printer',
149 'view_mode': 'form',
150 'view_type': 'form',
151 'res_id': current.id,
152 'views': [(False, 'form')],
153 'target': 'new',
154 }

Subscribers

People subscribed via source and target branches

to all changes: