Merge lp:~camptocamp/account-financial-tools/add-credit-control-legal-claim-nbi into lp:~camptocamp/account-financial-tools/add-manual-line-and-fees-nbi
- add-credit-control-legal-claim-nbi
- Merge into 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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Camptocamp | Pending | ||
Review via email: mp+220801@code.launchpad.net |
Commit message
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
1 | === added directory 'account_credit_control_legal_claim' | |||
2 | === added file 'account_credit_control_legal_claim/__init__.py' | |||
3 | --- account_credit_control_legal_claim/__init__.py 1970-01-01 00:00:00 +0000 | |||
4 | +++ account_credit_control_legal_claim/__init__.py 2014-05-27 07:08:15 +0000 | |||
5 | @@ -0,0 +1,23 @@ | |||
6 | 1 | # -*- coding: utf-8 -*- | ||
7 | 2 | ############################################################################## | ||
8 | 3 | # | ||
9 | 4 | # Author: Nicolas Bessi | ||
10 | 5 | # Copyright 2014 Camptocamp SA | ||
11 | 6 | # | ||
12 | 7 | # This program is free software: you can redistribute it and/or modify | ||
13 | 8 | # it under the terms of the GNU Affero General Public License as | ||
14 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
15 | 10 | # License, or (at your option) any later version. | ||
16 | 11 | # | ||
17 | 12 | # This program is distributed in the hope that it will be useful, | ||
18 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | 15 | # GNU Affero General Public License for more details. | ||
21 | 16 | # | ||
22 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
23 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
24 | 19 | # | ||
25 | 20 | ############################################################################## | ||
26 | 21 | from . import model | ||
27 | 22 | from . import wizard | ||
28 | 23 | from . import report | ||
29 | 0 | 24 | ||
30 | === added file 'account_credit_control_legal_claim/__openerp__.py' | |||
31 | --- account_credit_control_legal_claim/__openerp__.py 1970-01-01 00:00:00 +0000 | |||
32 | +++ account_credit_control_legal_claim/__openerp__.py 2014-05-27 07:08:15 +0000 | |||
33 | @@ -0,0 +1,59 @@ | |||
34 | 1 | # -*- coding: utf-8 -*- | ||
35 | 2 | ############################################################################## | ||
36 | 3 | # | ||
37 | 4 | # Author: Nicolas Bessi | ||
38 | 5 | # Copyright 2014 Camptocamp SA | ||
39 | 6 | # | ||
40 | 7 | # This program is free software: you can redistribute it and/or modify | ||
41 | 8 | # it under the terms of the GNU Affero General Public License as | ||
42 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
43 | 10 | # License, or (at your option) any later version. | ||
44 | 11 | # | ||
45 | 12 | # This program is distributed in the hope that it will be useful, | ||
46 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
47 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
48 | 15 | # GNU Affero General Public License for more details. | ||
49 | 16 | # | ||
50 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
51 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
52 | 19 | # | ||
53 | 20 | ############################################################################## | ||
54 | 21 | {'name': 'Credit Control Legal Claim', | ||
55 | 22 | 'version': '0.1', | ||
56 | 23 | 'author': 'Camptocamp', | ||
57 | 24 | 'maintainer': 'Camptocamp', | ||
58 | 25 | 'category': 'Accounting', | ||
59 | 26 | 'complexity': 'normal', | ||
60 | 27 | 'depends': ['base_location', | ||
61 | 28 | 'base_headers_webkit', | ||
62 | 29 | 'account_credit_control'], | ||
63 | 30 | 'description': """ | ||
64 | 31 | Credit Control Legal Claim | ||
65 | 32 | -------------------------- | ||
66 | 33 | |||
67 | 34 | This addons allows to manage legal claim requisition | ||
68 | 35 | from credit controling. | ||
69 | 36 | |||
70 | 37 | This is done by setting a boolean "Legal claim" | ||
71 | 38 | on credit control policy level. | ||
72 | 39 | |||
73 | 40 | |||
74 | 41 | From then you can print claim requisition letter from invoice | ||
75 | 42 | user the: :: | ||
76 | 43 | |||
77 | 44 | more -> Print Legal Claim Letter | ||
78 | 45 | |||
79 | 46 | """, | ||
80 | 47 | 'website': 'http://www.camptocamp.com', | ||
81 | 48 | 'data': ['view/claim_office_view.xml', | ||
82 | 49 | 'view/claim_scheme_view.xml', | ||
83 | 50 | 'view/credit_control_claim_printer_view.xml', | ||
84 | 51 | 'report/report.xml', | ||
85 | 52 | 'view/policy_view.xml'], | ||
86 | 53 | 'demo': [], | ||
87 | 54 | 'test': [], | ||
88 | 55 | 'installable': True, | ||
89 | 56 | 'auto_install': False, | ||
90 | 57 | 'license': 'AGPL-3', | ||
91 | 58 | 'application': False, | ||
92 | 59 | } | ||
93 | 0 | 60 | ||
94 | === added directory 'account_credit_control_legal_claim/i18n' | |||
95 | === added directory 'account_credit_control_legal_claim/model' | |||
96 | === added file 'account_credit_control_legal_claim/model/__init__.py' | |||
97 | --- account_credit_control_legal_claim/model/__init__.py 1970-01-01 00:00:00 +0000 | |||
98 | +++ account_credit_control_legal_claim/model/__init__.py 2014-05-27 07:08:15 +0000 | |||
99 | @@ -0,0 +1,24 @@ | |||
100 | 1 | # -*- coding: utf-8 -*- | ||
101 | 2 | ############################################################################## | ||
102 | 3 | # | ||
103 | 4 | # Author: Nicolas Bessi | ||
104 | 5 | # Copyright 2014 Camptocamp SA | ||
105 | 6 | # | ||
106 | 7 | # This program is free software: you can redistribute it and/or modify | ||
107 | 8 | # it under the terms of the GNU Affero General Public License as | ||
108 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
109 | 10 | # License, or (at your option) any later version. | ||
110 | 11 | # | ||
111 | 12 | # This program is distributed in the hope that it will be useful, | ||
112 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
113 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
114 | 15 | # GNU Affero General Public License for more details. | ||
115 | 16 | # | ||
116 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
117 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
118 | 19 | # | ||
119 | 20 | ############################################################################## | ||
120 | 21 | from . import claim_office | ||
121 | 22 | from . import claim_fees_scheme | ||
122 | 23 | from . import policy | ||
123 | 24 | from . import partner | ||
124 | 0 | 25 | ||
125 | === added file 'account_credit_control_legal_claim/model/claim_fees_scheme.py' | |||
126 | --- account_credit_control_legal_claim/model/claim_fees_scheme.py 1970-01-01 00:00:00 +0000 | |||
127 | +++ account_credit_control_legal_claim/model/claim_fees_scheme.py 2014-05-27 07:08:15 +0000 | |||
128 | @@ -0,0 +1,131 @@ | |||
129 | 1 | # -*- coding: utf-8 -*- | ||
130 | 2 | ############################################################################## | ||
131 | 3 | # | ||
132 | 4 | # Author: Nicolas Bessi | ||
133 | 5 | # Copyright 2013 Camptocamp SA | ||
134 | 6 | # | ||
135 | 7 | # This program is free software: you can redistribute it and/or modify | ||
136 | 8 | # it under the terms of the GNU Affero General Public License as | ||
137 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
138 | 10 | # License, or (at your option) any later version. | ||
139 | 11 | # | ||
140 | 12 | # This program is distributed in the hope that it will be useful, | ||
141 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
142 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
143 | 15 | # GNU Affero General Public License for more details. | ||
144 | 16 | # | ||
145 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
146 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
147 | 19 | # | ||
148 | 20 | ############################################################################## | ||
149 | 21 | from operator import attrgetter | ||
150 | 22 | from openerp.osv import orm, fields | ||
151 | 23 | |||
152 | 24 | |||
153 | 25 | class claim_fees_scheme(orm.Model): | ||
154 | 26 | """Claim fees | ||
155 | 27 | |||
156 | 28 | Claim offices take fees based on open amount | ||
157 | 29 | whan a legal action is taken. | ||
158 | 30 | |||
159 | 31 | The model represent the scheme open amount/fees | ||
160 | 32 | |||
161 | 33 | """ | ||
162 | 34 | |||
163 | 35 | _name = 'legal.claim.fees.scheme' | ||
164 | 36 | |||
165 | 37 | _columns = { | ||
166 | 38 | 'name': fields.char('Name', | ||
167 | 39 | required=True), | ||
168 | 40 | 'product_id': fields.many2one('product.product', | ||
169 | 41 | 'Product', | ||
170 | 42 | required=True), | ||
171 | 43 | 'claim_scheme_line_ids': fields.one2many('legal.claim.fees.scheme.line', | ||
172 | 44 | 'claim_scheme_id', | ||
173 | 45 | 'Price lists'), | ||
174 | 46 | 'company_id': fields.many2one('res.company', | ||
175 | 47 | 'Company'), | ||
176 | 48 | 'currency_id': fields.many2one('res.currency', | ||
177 | 49 | 'Currency', | ||
178 | 50 | required=True), | ||
179 | 51 | } | ||
180 | 52 | |||
181 | 53 | def _company_get(self, cr, uid, context=None): | ||
182 | 54 | """Return related company""" | ||
183 | 55 | return self.pool['res.company']._company_default_get(cr, uid, | ||
184 | 56 | 'claim.fees.scheme', | ||
185 | 57 | context=context) | ||
186 | 58 | _defaults = {'company_id': _company_get} | ||
187 | 59 | |||
188 | 60 | def _due_from_invoices(self, invoices_records, context=None): | ||
189 | 61 | """Compute due amount form a list of invoice | ||
190 | 62 | |||
191 | 63 | :param invoices_record: list of invoice records | ||
192 | 64 | |||
193 | 65 | :returns: due amount (float) | ||
194 | 66 | |||
195 | 67 | """ | ||
196 | 68 | return sum(x.residual for x in invoices_records) | ||
197 | 69 | |||
198 | 70 | def get_fees_from_amount(self, cr, uid, ids, due_amount, context=None): | ||
199 | 71 | """Get the fees from open amount | ||
200 | 72 | |||
201 | 73 | :param due_amount: float of the open (due) amount | ||
202 | 74 | |||
203 | 75 | :returns: fees amount (float) | ||
204 | 76 | |||
205 | 77 | """ | ||
206 | 78 | assert len(ids) == 1, 'Only on id expected' | ||
207 | 79 | current = self.browse(cr, uid, ids[0], context=context) | ||
208 | 80 | lines = current.claim_scheme_line_ids | ||
209 | 81 | lines.sort(key=attrgetter('open_amount'), reverse=True) | ||
210 | 82 | for line in lines: | ||
211 | 83 | if due_amount >= line.open_amount: | ||
212 | 84 | return line.fees | ||
213 | 85 | return lines[-1].fees | ||
214 | 86 | |||
215 | 87 | def get_fees_from_invoices(self, cr, uid, ids, invoice_ids, context=None): | ||
216 | 88 | """Get the fees form a list of invoice ids | ||
217 | 89 | |||
218 | 90 | :param invoice_ids: list of invoice_ids | ||
219 | 91 | |||
220 | 92 | :returns: fees amount (float) | ||
221 | 93 | |||
222 | 94 | """ | ||
223 | 95 | assert len(ids) == 1, 'Only on id expected' | ||
224 | 96 | invoices = self.pool['account.invoice'].browse(cr, uid, invoice_ids, | ||
225 | 97 | context=context) | ||
226 | 98 | return self._get_fees_from_invoices(cr, uid, ids, invoices, | ||
227 | 99 | context=context) | ||
228 | 100 | |||
229 | 101 | def _get_fees_from_invoices(self, cr, uid, ids, invoices, context=None): | ||
230 | 102 | """Get the fees form a list of invoice record | ||
231 | 103 | |||
232 | 104 | :param invoice_ids: list of invoice record | ||
233 | 105 | |||
234 | 106 | :returns: fees amount (float) | ||
235 | 107 | |||
236 | 108 | """ | ||
237 | 109 | assert len(ids) == 1, 'Only on id expected' | ||
238 | 110 | current = self.browse(cr, uid, ids[0], context=context) | ||
239 | 111 | due = self._due_from_invoices(invoices, context=context) | ||
240 | 112 | return current.get_fees_from_amount(due) | ||
241 | 113 | |||
242 | 114 | |||
243 | 115 | class claim_fees_scheme_line(orm.Model): | ||
244 | 116 | """Price list line of scheme | ||
245 | 117 | that contains price and qty""" | ||
246 | 118 | |||
247 | 119 | _name = 'legal.claim.fees.scheme.line' | ||
248 | 120 | _rec_name = "open_amount" | ||
249 | 121 | _order = "open_amount" | ||
250 | 122 | |||
251 | 123 | _columns = { | ||
252 | 124 | 'claim_scheme_id': fields.many2one('legal.claim.fees.scheme', | ||
253 | 125 | 'Price list', | ||
254 | 126 | required=True), | ||
255 | 127 | 'open_amount': fields.integer('Open Amount', | ||
256 | 128 | required=True), | ||
257 | 129 | 'fees': fields.float('Fees', | ||
258 | 130 | required=True), | ||
259 | 131 | } | ||
260 | 0 | 132 | ||
261 | === added file 'account_credit_control_legal_claim/model/claim_office.py' | |||
262 | --- account_credit_control_legal_claim/model/claim_office.py 1970-01-01 00:00:00 +0000 | |||
263 | +++ account_credit_control_legal_claim/model/claim_office.py 2014-05-27 07:08:15 +0000 | |||
264 | @@ -0,0 +1,55 @@ | |||
265 | 1 | # -*- coding: utf-8 -*- | ||
266 | 2 | ############################################################################## | ||
267 | 3 | # | ||
268 | 4 | # Author: Nicolas Bessi | ||
269 | 5 | # Copyright 2014 Camptocamp SA | ||
270 | 6 | # | ||
271 | 7 | # This program is free software: you can redistribute it and/or modify | ||
272 | 8 | # it under the terms of the GNU Affero General Public License as | ||
273 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
274 | 10 | # License, or (at your option) any later version. | ||
275 | 11 | # | ||
276 | 12 | # This program is distributed in the hope that it will be useful, | ||
277 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
278 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
279 | 15 | # GNU Affero General Public License for more details. | ||
280 | 16 | # | ||
281 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
282 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
283 | 19 | # | ||
284 | 20 | ############################################################################## | ||
285 | 21 | from openerp.osv import orm, fields | ||
286 | 22 | |||
287 | 23 | |||
288 | 24 | class claim_office(orm.Model): | ||
289 | 25 | """Claim office""" | ||
290 | 26 | |||
291 | 27 | _name = "legal.claim.office" | ||
292 | 28 | _columns = { | ||
293 | 29 | |||
294 | 30 | 'name': fields.char('Name', | ||
295 | 31 | required=True), | ||
296 | 32 | |||
297 | 33 | 'locations_ids': fields.one2many('res.better.zip', | ||
298 | 34 | 'claim_office_id', | ||
299 | 35 | 'Related zip'), | ||
300 | 36 | |||
301 | 37 | 'fees_scheme_id': fields.many2one('legal.claim.fees.scheme', | ||
302 | 38 | 'Fees Scheme', | ||
303 | 39 | select=1, | ||
304 | 40 | required=True), | ||
305 | 41 | 'partner_id': fields.many2one('res.partner', | ||
306 | 42 | 'Office Address', | ||
307 | 43 | required=True), | ||
308 | 44 | } | ||
309 | 45 | |||
310 | 46 | |||
311 | 47 | class better_zip(orm.Model): | ||
312 | 48 | """Add relation to claim office""" | ||
313 | 49 | |||
314 | 50 | _inherit = "res.better.zip" | ||
315 | 51 | _columns = { | ||
316 | 52 | 'claim_office_id': fields.many2one('legal.claim.office', | ||
317 | 53 | 'Claim office', | ||
318 | 54 | select=True), | ||
319 | 55 | } | ||
320 | 0 | 56 | ||
321 | === added file 'account_credit_control_legal_claim/model/partner.py' | |||
322 | --- account_credit_control_legal_claim/model/partner.py 1970-01-01 00:00:00 +0000 | |||
323 | +++ account_credit_control_legal_claim/model/partner.py 2014-05-27 07:08:15 +0000 | |||
324 | @@ -0,0 +1,55 @@ | |||
325 | 1 | # -*- coding: utf-8 -*- | ||
326 | 2 | ############################################################################## | ||
327 | 3 | # | ||
328 | 4 | # Author: Nicolas Bessi | ||
329 | 5 | # Copyright 2014 Camptocamp SA | ||
330 | 6 | # | ||
331 | 7 | # This program is free software: you can redistribute it and/or modify | ||
332 | 8 | # it under the terms of the GNU Affero General Public License as | ||
333 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
334 | 10 | # License, or (at your option) any later version. | ||
335 | 11 | # | ||
336 | 12 | # This program is distributed in the hope that it will be useful, | ||
337 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
338 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
339 | 15 | # GNU Affero General Public License for more details. | ||
340 | 16 | # | ||
341 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
342 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
343 | 19 | # | ||
344 | 20 | ############################################################################## | ||
345 | 21 | from openerp.osv import orm, fields | ||
346 | 22 | |||
347 | 23 | |||
348 | 24 | class res_partner(orm.Model): | ||
349 | 25 | """Add related claim office""" | ||
350 | 26 | def _get_claim_office(self, cr, uid, ids, field, args, context=None): | ||
351 | 27 | res = {} | ||
352 | 28 | location_model = self.pool['res.better.zip'] | ||
353 | 29 | for partner in self.browse(cr, uid, ids, context=context): | ||
354 | 30 | res[partner.id] = False | ||
355 | 31 | domain = [('name', '=', partner.zip), | ||
356 | 32 | ('city', '=', partner.city), | ||
357 | 33 | ('claim_office_id', '!=', False)] | ||
358 | 34 | location_id = location_model.search(cr, uid, domain, | ||
359 | 35 | order='priority', | ||
360 | 36 | limit=1, | ||
361 | 37 | context=context) | ||
362 | 38 | if not location_id: | ||
363 | 39 | continue | ||
364 | 40 | loc = location_model.read(cr, | ||
365 | 41 | uid, | ||
366 | 42 | location_id, | ||
367 | 43 | ['claim_office_id'], | ||
368 | 44 | load='_classic_write', | ||
369 | 45 | context=context) | ||
370 | 46 | res[partner.id] = loc[0]['claim_office_id'] | ||
371 | 47 | return res | ||
372 | 48 | |||
373 | 49 | _inherit = "res.partner" | ||
374 | 50 | _columns = { | ||
375 | 51 | 'claim_office_id': fields.function(_get_claim_office, | ||
376 | 52 | type='many2one', | ||
377 | 53 | relation='legal.claim.office', | ||
378 | 54 | string='Claim office') | ||
379 | 55 | } | ||
380 | 0 | 56 | ||
381 | === added file 'account_credit_control_legal_claim/model/policy.py' | |||
382 | --- account_credit_control_legal_claim/model/policy.py 1970-01-01 00:00:00 +0000 | |||
383 | +++ account_credit_control_legal_claim/model/policy.py 2014-05-27 07:08:15 +0000 | |||
384 | @@ -0,0 +1,46 @@ | |||
385 | 1 | # -*- coding: utf-8 -*- | ||
386 | 2 | ############################################################################## | ||
387 | 3 | # | ||
388 | 4 | # Author: Nicolas Bessi | ||
389 | 5 | # Copyright 2014 Camptocamp SA | ||
390 | 6 | # | ||
391 | 7 | # This program is free software: you can redistribute it and/or modify | ||
392 | 8 | # it under the terms of the GNU Affero General Public License as | ||
393 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
394 | 10 | # License, or (at your option) any later version. | ||
395 | 11 | # | ||
396 | 12 | # This program is distributed in the hope that it will be useful, | ||
397 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
398 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
399 | 15 | # GNU Affero General Public License for more details. | ||
400 | 16 | # | ||
401 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
402 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
403 | 19 | # | ||
404 | 20 | ############################################################################## | ||
405 | 21 | from openerp.osv import orm, fields | ||
406 | 22 | from openerp.tools.translate import _ | ||
407 | 23 | |||
408 | 24 | class credit_control_policy_level(orm.Model): | ||
409 | 25 | """Add claim type to policy level""" | ||
410 | 26 | |||
411 | 27 | _inherit = "credit.control.policy.level" | ||
412 | 28 | _columns = { | ||
413 | 29 | 'is_legal_claim': fields.boolean('Legal Claim Action') | ||
414 | 30 | } | ||
415 | 31 | |||
416 | 32 | def _check_legal_claim_level(self, cr, uid, ids, context=None): | ||
417 | 33 | for current_level in self.browse(cr, uid, ids, context=context): | ||
418 | 34 | levels = current_level.policy_id.level_ids | ||
419 | 35 | highest = max(levels, key= lambda x: x.level) | ||
420 | 36 | for lvl in levels: | ||
421 | 37 | if lvl.is_legal_claim and lvl != highest: | ||
422 | 38 | raise orm.except_orm( | ||
423 | 39 | _('Only highest level can be tickes as legal claim'), | ||
424 | 40 | _('The current highest level is %s') % highest.name | ||
425 | 41 | ) | ||
426 | 42 | return True | ||
427 | 43 | |||
428 | 44 | _constraints = [(_check_legal_claim_level, | ||
429 | 45 | 'Only highest level can be legal claim', | ||
430 | 46 | ['is_legal_claim'])] | ||
431 | 0 | 47 | ||
432 | === added directory 'account_credit_control_legal_claim/report' | |||
433 | === added file 'account_credit_control_legal_claim/report/__init__.py' | |||
434 | --- account_credit_control_legal_claim/report/__init__.py 1970-01-01 00:00:00 +0000 | |||
435 | +++ account_credit_control_legal_claim/report/__init__.py 2014-05-27 07:08:15 +0000 | |||
436 | @@ -0,0 +1,21 @@ | |||
437 | 1 | # -*- coding: utf-8 -*- | ||
438 | 2 | ############################################################################## | ||
439 | 3 | # | ||
440 | 4 | # Author: Nicolas Bessi | ||
441 | 5 | # Copyright 2014 Camptocamp SA | ||
442 | 6 | # | ||
443 | 7 | # This program is free software: you can redistribute it and/or modify | ||
444 | 8 | # it under the terms of the GNU Affero General Public License as | ||
445 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
446 | 10 | # License, or (at your option) any later version. | ||
447 | 11 | # | ||
448 | 12 | # This program is distributed in the hope that it will be useful, | ||
449 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
450 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
451 | 15 | # GNU Affero General Public License for more details. | ||
452 | 16 | # | ||
453 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
454 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
455 | 19 | # | ||
456 | 20 | ############################################################################## | ||
457 | 21 | from . import claim_requisition_report | ||
458 | 0 | 22 | ||
459 | === added file 'account_credit_control_legal_claim/report/claim_requisition_report.py' | |||
460 | --- account_credit_control_legal_claim/report/claim_requisition_report.py 1970-01-01 00:00:00 +0000 | |||
461 | +++ account_credit_control_legal_claim/report/claim_requisition_report.py 2014-05-27 07:08:15 +0000 | |||
462 | @@ -0,0 +1,80 @@ | |||
463 | 1 | # -*- coding: utf-8 -*- | ||
464 | 2 | ############################################################################## | ||
465 | 3 | # | ||
466 | 4 | # Author: Nicolas Bessi | ||
467 | 5 | # Copyright 2014 Camptocamp SA | ||
468 | 6 | # | ||
469 | 7 | # This program is free software: you can redistribute it and/or modify | ||
470 | 8 | # it under the terms of the GNU Affero General Public License as | ||
471 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
472 | 10 | # License, or (at your option) any later version. | ||
473 | 11 | # | ||
474 | 12 | # This program is distributed in the hope that it will be useful, | ||
475 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
476 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
477 | 15 | # GNU Affero General Public License for more details. | ||
478 | 16 | # | ||
479 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
480 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
481 | 19 | # | ||
482 | 20 | ############################################################################## | ||
483 | 21 | import time | ||
484 | 22 | import operator | ||
485 | 23 | from itertools import groupby | ||
486 | 24 | from itertools import chain | ||
487 | 25 | from openerp.report import report_sxw | ||
488 | 26 | from openerp.osv import fields | ||
489 | 27 | |||
490 | 28 | class CreditClaimRequisition(report_sxw.rml_parse): | ||
491 | 29 | def __init__(self, cr, uid, name, context): | ||
492 | 30 | super(CreditClaimRequisition, self).__init__(cr, uid, name, | ||
493 | 31 | context=context) | ||
494 | 32 | self.localcontext.update({ | ||
495 | 33 | 'time': time, | ||
496 | 34 | 'cr': cr, | ||
497 | 35 | 'uid': uid, | ||
498 | 36 | 'today': fields.date.today(), | ||
499 | 37 | 'compute_dunning_fees': self.compute_dunning_fees, | ||
500 | 38 | 'compute_due_amount': self.compute_due_amount, | ||
501 | 39 | 'get_legal_claim_fees': self.get_legal_claim_fees, | ||
502 | 40 | 'compute_paid_amount': self.compute_paid_amount, | ||
503 | 41 | }) | ||
504 | 42 | |||
505 | 43 | def _active_line(self, cr, uid, line, context=None): | ||
506 | 44 | return (line.state not in ('draft', 'ignored') and | ||
507 | 45 | not line.manually_overridden) | ||
508 | 46 | |||
509 | 47 | def compute_dunning_fees(self, invoices): | ||
510 | 48 | lines = chain.from_iterable([x.credit_control_line_ids for x in invoices]) | ||
511 | 49 | return sum(x.dunning_fees_amount for x in lines | ||
512 | 50 | if self._active_line(self.cr, self. uid, x)) | ||
513 | 51 | |||
514 | 52 | def get_legal_claim_fees(self, part, invoices): | ||
515 | 53 | scheme = part.claim_office_id.fees_scheme_id | ||
516 | 54 | return scheme.get_fees_from_invoices([x.id for x in invoices]) | ||
517 | 55 | |||
518 | 56 | def compute_due_amount(self, invoices): | ||
519 | 57 | return sum(x.residual for x in invoices) | ||
520 | 58 | |||
521 | 59 | def compute_paid_amount(self, invoices): | ||
522 | 60 | return sum(x.amount_total - x.residual for x in invoices) | ||
523 | 61 | |||
524 | 62 | def set_context(self, objects, data, ids, report_type=None): | ||
525 | 63 | """Group invoice by partner and currency and replace objects | ||
526 | 64 | with partner | ||
527 | 65 | |||
528 | 66 | """ | ||
529 | 67 | new_objects = [] | ||
530 | 68 | for key, invoices in groupby(objects, lambda x: (x.partner_id, x.currency_id)): | ||
531 | 69 | part = key[0] | ||
532 | 70 | part.claim_invoices = list(invoices) | ||
533 | 71 | part.claim_currency = key[1] | ||
534 | 72 | new_objects.append(part) | ||
535 | 73 | return super(CreditClaimRequisition, self).set_context( | ||
536 | 74 | new_objects, data, id, report_type=report_type | ||
537 | 75 | ) | ||
538 | 76 | |||
539 | 77 | report_sxw.report_sxw('report.credit_control_legal_claim_requisition', | ||
540 | 78 | 'credit.control.communication', | ||
541 | 79 | 'addons/account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako', | ||
542 | 80 | parser=CreditClaimRequisition) | ||
543 | 0 | 81 | ||
544 | === added file 'account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako' | |||
545 | --- account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako 1970-01-01 00:00:00 +0000 | |||
546 | +++ account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako 2014-05-27 07:08:15 +0000 | |||
547 | @@ -0,0 +1,259 @@ | |||
548 | 1 | ## -*- coding: utf-8 -*- | ||
549 | 2 | <html> | ||
550 | 3 | <head> | ||
551 | 4 | <style type="text/css"> | ||
552 | 5 | ${css} | ||
553 | 6 | body { | ||
554 | 7 | |||
555 | 8 | font-family: helvetica; | ||
556 | 9 | font-size: 12px; | ||
557 | 10 | } | ||
558 | 11 | |||
559 | 12 | .left_form_no{ | ||
560 | 13 | font-family: helvetica; | ||
561 | 14 | font-size: 12px; | ||
562 | 15 | text-align: left; | ||
563 | 16 | border-bottom-style:solid; | ||
564 | 17 | border-width:1px; | ||
565 | 18 | width:30%; | ||
566 | 19 | } | ||
567 | 20 | |||
568 | 21 | .right_form_no{ | ||
569 | 22 | font-family: helvetica; | ||
570 | 23 | font-size: 12px; | ||
571 | 24 | text-align: left; | ||
572 | 25 | border-bottom-style:solid; | ||
573 | 26 | border-width:1px; | ||
574 | 27 | width:30%; | ||
575 | 28 | } | ||
576 | 29 | .custom_text { | ||
577 | 30 | font-family: helvetica; | ||
578 | 31 | font-size: 12px; | ||
579 | 32 | } | ||
580 | 33 | |||
581 | 34 | .receive_date{ | ||
582 | 35 | font-family: helvetica; | ||
583 | 36 | font-size: 12px; | ||
584 | 37 | text-align: left; | ||
585 | 38 | font-weight: bold; | ||
586 | 39 | } | ||
587 | 40 | |||
588 | 41 | |||
589 | 42 | .claim_office_address{ | ||
590 | 43 | font-family: helvetica; | ||
591 | 44 | font-size: 12px; | ||
592 | 45 | text-align: left; | ||
593 | 46 | vertical-align:text-bottom; | ||
594 | 47 | } | ||
595 | 48 | |||
596 | 49 | .stake_holder_table td{ | ||
597 | 50 | border-width:1px; | ||
598 | 51 | border-bottom-style:solid; | ||
599 | 52 | border-top-style:solid; | ||
600 | 53 | } | ||
601 | 54 | |||
602 | 55 | .stake_holder_table{ | ||
603 | 56 | font-family: helvetica; | ||
604 | 57 | font-size: 12px; | ||
605 | 58 | border-collapse:collapse; | ||
606 | 59 | width: 100%; | ||
607 | 60 | } | ||
608 | 61 | |||
609 | 62 | .stake_holder_name{ | ||
610 | 63 | vertical-align:text-top; | ||
611 | 64 | font-weight: bold; | ||
612 | 65 | text-decoration:underline; | ||
613 | 66 | width:30%; | ||
614 | 67 | } | ||
615 | 68 | |||
616 | 69 | .stake_holder_reference{ | ||
617 | 70 | vertical-align:text-top; | ||
618 | 71 | width:30%; | ||
619 | 72 | } | ||
620 | 73 | |||
621 | 74 | .claim_reasons{ | ||
622 | 75 | font-family: helvetica; | ||
623 | 76 | font-size: 12px; | ||
624 | 77 | font-weight:bold; | ||
625 | 78 | |||
626 | 79 | } | ||
627 | 80 | |||
628 | 81 | .claim_table{ | ||
629 | 82 | font-family: helvetica; | ||
630 | 83 | font-size: 12px; | ||
631 | 84 | border-collapse:collapse; | ||
632 | 85 | width:55% | ||
633 | 86 | } | ||
634 | 87 | |||
635 | 88 | .summary_table{ | ||
636 | 89 | font-family: helvetica; | ||
637 | 90 | font-size: 12px; | ||
638 | 91 | border-collapse:collapse; | ||
639 | 92 | width:55% | ||
640 | 93 | } | ||
641 | 94 | |||
642 | 95 | .paid_amount_summary_table{ | ||
643 | 96 | font-family: helvetica; | ||
644 | 97 | font-size: 12px; | ||
645 | 98 | font-weight:bold; | ||
646 | 99 | border-collapse:collapse; | ||
647 | 100 | } | ||
648 | 101 | |||
649 | 102 | td.amount, th.amount { | ||
650 | 103 | text-align: right; | ||
651 | 104 | padding-right:2px; | ||
652 | 105 | } | ||
653 | 106 | |||
654 | 107 | .signature{ | ||
655 | 108 | font-family: helvetica; | ||
656 | 109 | font-size: 12px; | ||
657 | 110 | border-collapse:collapse; | ||
658 | 111 | } | ||
659 | 112 | |||
660 | 113 | .date_and_place{ | ||
661 | 114 | vertical-align:text-top; | ||
662 | 115 | width:30%; | ||
663 | 116 | } | ||
664 | 117 | |||
665 | 118 | .signature_address{ | ||
666 | 119 | vertical-align:text-top; | ||
667 | 120 | width:30%; | ||
668 | 121 | } | ||
669 | 122 | |||
670 | 123 | .title{ | ||
671 | 124 | text-align.center; | ||
672 | 125 | } | ||
673 | 126 | |||
674 | 127 | </style> | ||
675 | 128 | </head> | ||
676 | 129 | <body> | ||
677 | 130 | |||
678 | 131 | %for part in objects : | ||
679 | 132 | <% setLang(part.lang) %> | ||
680 | 133 | <br/> | ||
681 | 134 | <h3 class="title" align="center">${_('Legal Claim Requisition')}</h3> | ||
682 | 135 | <table width="100%"> | ||
683 | 136 | <tr> | ||
684 | 137 | <td class="left_form_no">${_('From. No')}</td> | ||
685 | 138 | <td></td> | ||
686 | 139 | <td class="right_form_no">${_('Claim No')}</td> | ||
687 | 140 | </tr> | ||
688 | 141 | <tr height="50px"> | ||
689 | 142 | <td class="receive_date">${_('Claim receive by office, the:......')}</td> | ||
690 | 143 | <td colspan="2"></td> | ||
691 | 144 | <td></td> | ||
692 | 145 | </tr> | ||
693 | 146 | <tr> | ||
694 | 147 | <td></td> | ||
695 | 148 | <td></td> | ||
696 | 149 | <td class="claim_office_address">${part.claim_office_id.partner_id.display_name}<br/> | ||
697 | 150 | <% address_lines = part.claim_office_id.partner_id.contact_address.split("\n") %> | ||
698 | 151 | %for add_part in address_lines: | ||
699 | 152 | % if add_part: | ||
700 | 153 | ${add_part}<br/> | ||
701 | 154 | % endif | ||
702 | 155 | %endfor | ||
703 | 156 | </td> | ||
704 | 157 | </tr> | ||
705 | 158 | </table> | ||
706 | 159 | <br/> | ||
707 | 160 | <br/> | ||
708 | 161 | <br/> | ||
709 | 162 | <div class="state_style">${_('State:')} ${part.claim_office_id.partner_id.state_id.name}</div> | ||
710 | 163 | <table class="stake_holder_table"> | ||
711 | 164 | <% | ||
712 | 165 | debtor = part | ||
713 | 166 | creditor = company.partner_id | ||
714 | 167 | %> | ||
715 | 168 | <tr class="stake_holder_line"> | ||
716 | 169 | <td class="stake_holder_name">${_('Debtor:')}</td> | ||
717 | 170 | <td class="stake_holder_address">${part.display_name}<br/> | ||
718 | 171 | <% address_lines = part.contact_address.split("\n") %> | ||
719 | 172 | %for add_part in address_lines: | ||
720 | 173 | % if add_part: | ||
721 | 174 | ${add_part}<br/> | ||
722 | 175 | % endif | ||
723 | 176 | %endfor | ||
724 | 177 | |||
725 | 178 | </td> | ||
726 | 179 | <td class="stake_holder_reference">${part.ref or _('N/A')} | ||
727 | 180 | <br/> | ||
728 | 181 | <br/> | ||
729 | 182 | birthdate ${formatLang(part.birthday_date, date=True) or _('N/A')} | ||
730 | 183 | </td> | ||
731 | 184 | </tr> | ||
732 | 185 | <tr class="stake_holder_line"> | ||
733 | 186 | <td class="stake_holder_name">${_('Creditor:')}</td> | ||
734 | 187 | <td class="stake_holder_address">${creditor.display_name} <br/> | ||
735 | 188 | <% address_lines = creditor.contact_address.split("\n") %> | ||
736 | 189 | %for add_part in address_lines: | ||
737 | 190 | % if add_part: | ||
738 | 191 | ${add_part}<br/> | ||
739 | 192 | % endif | ||
740 | 193 | %endfor | ||
741 | 194 | </td> | ||
742 | 195 | <td class="stake_holder_reference">${creditor.phone or ''} </td> | ||
743 | 196 | </tr> | ||
744 | 197 | </table> | ||
745 | 198 | <br/> | ||
746 | 199 | <br/> | ||
747 | 200 | <div class="claim_reasons">${_('Claim Reasons')}</div> | ||
748 | 201 | <div> | ||
749 | 202 | |||
750 | 203 | <table class="claim_table"> | ||
751 | 204 | </tr> | ||
752 | 205 | %for inv in part.claim_invoices: | ||
753 | 206 | <tr> | ||
754 | 207 | <td class="date">${_('Invoice')} ${inv.number} of ${formatLang(inv.date_invoice, date=True)}, due at ${formatLang(inv.date_due, date=True)}</td> | ||
755 | 208 | <td>${_('Due amount')}</td> | ||
756 | 209 | <td class="amount">${formatLang(inv.residual)} ${part.claim_currency.name}</td> | ||
757 | 210 | </tr> | ||
758 | 211 | %endfor | ||
759 | 212 | </table> | ||
760 | 213 | <br/> | ||
761 | 214 | <br/> | ||
762 | 215 | <table class="summary_table"> | ||
763 | 216 | <tr> | ||
764 | 217 | <td>${_('Amount due')}</td> | ||
765 | 218 | <td>${formatLang(compute_due_amount(part.claim_invoices))} ${part.claim_currency.name}</td> | ||
766 | 219 | <td></td> | ||
767 | 220 | </tr> | ||
768 | 221 | <tr> | ||
769 | 222 | <td>${_('Dunning Fees')}</td> | ||
770 | 223 | <td>${formatLang(compute_dunning_fees(part.claim_invoices))} ${part.claim_currency.name}</td> | ||
771 | 224 | <td></td> | ||
772 | 225 | </tr> | ||
773 | 226 | <tr> | ||
774 | 227 | <td>${_('Legal Claim Fees')}</td> | ||
775 | 228 | <td>${formatLang(get_legal_claim_fees(part, part.claim_invoices))} ${part.claim_currency.name}</td> | ||
776 | 229 | <td></td> | ||
777 | 230 | </tr> | ||
778 | 231 | </table> | ||
779 | 232 | <table class="paid_amount_summary_table"> | ||
780 | 233 | <tr> | ||
781 | 234 | <td height="50px">${_('Debtor already paid amount')} ${formatLang(compute_paid_amount(part.claim_invoices))} ${part.claim_currency.name}</td> | ||
782 | 235 | </tr> | ||
783 | 236 | </table> | ||
784 | 237 | <br/> | ||
785 | 238 | <br/> | ||
786 | 239 | <table class="signature"> | ||
787 | 240 | <tr> | ||
788 | 241 | <td class="date_and_place"><b>${_('Date and place')}</b> <br/><br/><br/> | ||
789 | 242 | ${creditor.city or ''}, ${formatLang(today, date=True)} | ||
790 | 243 | </td> | ||
791 | 244 | <td></td> | ||
792 | 245 | <td class="signature_address">${creditor.display_name} <br/> | ||
793 | 246 | <% address_lines = creditor.contact_address.split("\n") %> | ||
794 | 247 | %for add_part in address_lines: | ||
795 | 248 | % if add_part: | ||
796 | 249 | ${add_part}<br/> | ||
797 | 250 | % endif | ||
798 | 251 | %endfor | ||
799 | 252 | </td> | ||
800 | 253 | </tr> | ||
801 | 254 | </table> | ||
802 | 255 | <p style="page-break-after:always"></p> | ||
803 | 256 | %endfor | ||
804 | 257 | |||
805 | 258 | </body> | ||
806 | 259 | </html> | ||
807 | 0 | 260 | ||
808 | === added file 'account_credit_control_legal_claim/report/report.xml' | |||
809 | --- account_credit_control_legal_claim/report/report.xml 1970-01-01 00:00:00 +0000 | |||
810 | +++ account_credit_control_legal_claim/report/report.xml 2014-05-27 07:08:15 +0000 | |||
811 | @@ -0,0 +1,18 @@ | |||
812 | 1 | <openerp> | ||
813 | 2 | <data> | ||
814 | 3 | <report auto="False" | ||
815 | 4 | id="legal_claim_report_webkit" | ||
816 | 5 | model="account.invoice" | ||
817 | 6 | name="credit_control_legal_claim_requisition" | ||
818 | 7 | file="account_credit_control_legal_claim/report/credit_control_legal_claim.html.mako" | ||
819 | 8 | string="Credit Summary Claim" | ||
820 | 9 | report_type="webkit" | ||
821 | 10 | webkit_header="base_headers_webkit.base_minimum_reports_portrait_header"/> | ||
822 | 11 | |||
823 | 12 | <record model="ir.actions.report.xml" id="legal_claim_report_webkit"> | ||
824 | 13 | <field name="precise_mode" eval="True"/> | ||
825 | 14 | <field name="header" eval="False"/> | ||
826 | 15 | </record> | ||
827 | 16 | |||
828 | 17 | </data> | ||
829 | 18 | </openerp> | ||
830 | 0 | 19 | ||
831 | === added directory 'account_credit_control_legal_claim/security' | |||
832 | === added directory 'account_credit_control_legal_claim/tests' | |||
833 | === added file 'account_credit_control_legal_claim/tests/__init__.py' | |||
834 | --- account_credit_control_legal_claim/tests/__init__.py 1970-01-01 00:00:00 +0000 | |||
835 | +++ account_credit_control_legal_claim/tests/__init__.py 2014-05-27 07:08:15 +0000 | |||
836 | @@ -0,0 +1,23 @@ | |||
837 | 1 | # -*- coding: utf-8 -*- | ||
838 | 2 | ############################################################################## | ||
839 | 3 | # | ||
840 | 4 | # Author: Nicolas Bessi | ||
841 | 5 | # Copyright 2014 Camptocamp SA | ||
842 | 6 | # | ||
843 | 7 | # This program is free software: you can redistribute it and/or modify | ||
844 | 8 | # it under the terms of the GNU Affero General Public License as | ||
845 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
846 | 10 | # License, or (at your option) any later version. | ||
847 | 11 | # | ||
848 | 12 | # This program is distributed in the hope that it will be useful, | ||
849 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
850 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
851 | 15 | # GNU Affero General Public License for more details. | ||
852 | 16 | # | ||
853 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
854 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
855 | 19 | # | ||
856 | 20 | ############################################################################## | ||
857 | 21 | from . import test_claim_requisiton_print | ||
858 | 22 | |||
859 | 23 | checks = [test_claim_requisiton_print] | ||
860 | 0 | 24 | ||
861 | === added file 'account_credit_control_legal_claim/tests/test_claim_requisiton_print.py' | |||
862 | --- account_credit_control_legal_claim/tests/test_claim_requisiton_print.py 1970-01-01 00:00:00 +0000 | |||
863 | +++ account_credit_control_legal_claim/tests/test_claim_requisiton_print.py 2014-05-27 07:08:15 +0000 | |||
864 | @@ -0,0 +1,177 @@ | |||
865 | 1 | # -*- coding: utf-8 -*- | ||
866 | 2 | ############################################################################## | ||
867 | 3 | # | ||
868 | 4 | # Author: Nicolas Bessi | ||
869 | 5 | # Copyright 2014 Camptocamp SA | ||
870 | 6 | # | ||
871 | 7 | # This program is free software: you can redistribute it and/or modify | ||
872 | 8 | # it under the terms of the GNU Affero General Public License as | ||
873 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
874 | 10 | # License, or (at your option) any later version. | ||
875 | 11 | # | ||
876 | 12 | # This program is distributed in the hope that it will be useful, | ||
877 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
878 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
879 | 15 | # GNU Affero General Public License for more details. | ||
880 | 16 | # | ||
881 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
882 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
883 | 19 | # | ||
884 | 20 | ############################################################################## | ||
885 | 21 | from mock import MagicMock, patch | ||
886 | 22 | import openerp.tests.common as test_common | ||
887 | 23 | |||
888 | 24 | |||
889 | 25 | class ClaimRequisitionTester(test_common.TransactionCase): | ||
890 | 26 | |||
891 | 27 | def setUp(self): | ||
892 | 28 | """Initialaize credit control level mock to test fees computations""" | ||
893 | 29 | super(ClaimRequisitionTester, self).setUp() | ||
894 | 30 | self.currency_model = self.registry('res.currency') | ||
895 | 31 | self.euro = self.currency_model.search(self.cr, self.uid, | ||
896 | 32 | [('name', '=', 'EUR')]) | ||
897 | 33 | self.assertTrue(self.euro) | ||
898 | 34 | self.euro = self.registry('res.currency').browse(self.cr, | ||
899 | 35 | self.uid, | ||
900 | 36 | self.euro[0]) | ||
901 | 37 | |||
902 | 38 | self.euro_level = MagicMock(name='Euro policy level') | ||
903 | 39 | self.euro_level.dunning_fixed_amount = 5.0 | ||
904 | 40 | self.euro_level.dunning_currency_id = self.euro | ||
905 | 41 | self.euro_level.dunning_type = 'fixed' | ||
906 | 42 | self.euro_level.is_legal_claim = True | ||
907 | 43 | |||
908 | 44 | self.euro_level_no_claim = MagicMock(name='Euro policy level no claim') | ||
909 | 45 | self.euro_level_no_claim.dunning_fixed_amount = 5.0 | ||
910 | 46 | self.euro_level_no_claim.dunning_currency_id = self.euro | ||
911 | 47 | self.euro_level_no_claim.dunning_type = 'fixed' | ||
912 | 48 | self.euro_level_no_claim.is_legal_claim = False | ||
913 | 49 | |||
914 | 50 | credit_line = MagicMock(name='Euro credit line') | ||
915 | 51 | credit_line.policy_level_id = self.euro_level | ||
916 | 52 | credit_line.currency_id = self.euro | ||
917 | 53 | credit_line.dunning_fees_amount = 10 | ||
918 | 54 | |||
919 | 55 | no_claim_credit_line = MagicMock(name='No claim credit line') | ||
920 | 56 | no_claim_credit_line.policy_level_id = self.euro_level_no_claim | ||
921 | 57 | no_claim_credit_line.currency_id = self.euro | ||
922 | 58 | no_claim_credit_line.dunning_fees_amount = 33 | ||
923 | 59 | self.credit_line = credit_line | ||
924 | 60 | self.no_claim_credit_line = no_claim_credit_line | ||
925 | 61 | |||
926 | 62 | self.claim_invoice_1 = MagicMock(name='Claim Invoice 1') | ||
927 | 63 | self.claim_invoice_1.partner_id = self.browse_ref("base.res_partner_12") | ||
928 | 64 | self.claim_invoice_1.currency_id = self.euro | ||
929 | 65 | self.claim_invoice_1.residual = 50.00 | ||
930 | 66 | self.claim_invoice_1.amount_total = 130.00 | ||
931 | 67 | self.claim_invoice_1.credit_control_line_ids = [credit_line, | ||
932 | 68 | credit_line] | ||
933 | 69 | |||
934 | 70 | self.claim_invoice_2 = MagicMock(name='Claim Invoice 1') | ||
935 | 71 | self.claim_invoice_2.partner_id = self.browse_ref("base.res_partner_12") | ||
936 | 72 | self.claim_invoice_2.currency_id = self.euro | ||
937 | 73 | self.claim_invoice_2.residual = 50.00 | ||
938 | 74 | self.claim_invoice_2.amount_total = 130.00 | ||
939 | 75 | self.claim_invoice_2.credit_control_line_ids = [credit_line, | ||
940 | 76 | credit_line] | ||
941 | 77 | |||
942 | 78 | self.non_claim_invoice_1 = MagicMock(name='Non Claim Invoice 1') | ||
943 | 79 | self.non_claim_invoice_1.partner_id = self.browse_ref("base.res_partner_12") | ||
944 | 80 | self.non_claim_invoice_1.currency_id = self.euro | ||
945 | 81 | self.non_claim_invoice_1.residual = 50.00 | ||
946 | 82 | self.non_claim_invoice_1.amount_total = 130.00 | ||
947 | 83 | self.non_claim_invoice_1.credit_control_line_ids = [no_claim_credit_line, | ||
948 | 84 | no_claim_credit_line] | ||
949 | 85 | |||
950 | 86 | scheme_id = self.registry('legal.claim.fees.scheme').create( | ||
951 | 87 | self.cr, | ||
952 | 88 | self.uid, | ||
953 | 89 | { | ||
954 | 90 | 'name': 'r1', | ||
955 | 91 | 'product_id': self.browse_ref('product.product_product_3').id, | ||
956 | 92 | 'currency_id': self.euro.id, | ||
957 | 93 | } | ||
958 | 94 | ) | ||
959 | 95 | |||
960 | 96 | self.registry('legal.claim.fees.scheme.line').create( | ||
961 | 97 | self.cr, | ||
962 | 98 | self.uid, | ||
963 | 99 | { | ||
964 | 100 | 'claim_scheme_id': scheme_id, | ||
965 | 101 | 'open_amount': 0, | ||
966 | 102 | 'fees': 30 | ||
967 | 103 | } | ||
968 | 104 | ) | ||
969 | 105 | |||
970 | 106 | self.registry('legal.claim.fees.scheme.line').create( | ||
971 | 107 | self.cr, | ||
972 | 108 | self.uid, | ||
973 | 109 | { | ||
974 | 110 | 'claim_scheme_id': scheme_id, | ||
975 | 111 | 'open_amount': 500, | ||
976 | 112 | 'fees': 70, | ||
977 | 113 | } | ||
978 | 114 | ) | ||
979 | 115 | |||
980 | 116 | claim_office_id = self.registry('legal.claim.office').create( | ||
981 | 117 | self.cr, | ||
982 | 118 | self.uid, | ||
983 | 119 | { | ||
984 | 120 | 'name': 'Lausanne', | ||
985 | 121 | 'partner_id': self.browse_ref('base.res_partner_13').id, | ||
986 | 122 | 'fees_scheme_id': scheme_id, | ||
987 | 123 | } | ||
988 | 124 | ) | ||
989 | 125 | |||
990 | 126 | self.registry('res.better.zip').create( | ||
991 | 127 | self.cr, | ||
992 | 128 | self.uid, | ||
993 | 129 | { | ||
994 | 130 | 'name': '1001', | ||
995 | 131 | 'city': 'lausanne', | ||
996 | 132 | 'claim_office_id': claim_office_id, | ||
997 | 133 | } | ||
998 | 134 | ) | ||
999 | 135 | |||
1000 | 136 | self.claim_office = self.registry('legal.claim.office').browse( | ||
1001 | 137 | self.cr, | ||
1002 | 138 | self.uid, | ||
1003 | 139 | claim_office_id, | ||
1004 | 140 | ) | ||
1005 | 141 | |||
1006 | 142 | def test_00_filter(self): | ||
1007 | 143 | """Test filter invoices""" | ||
1008 | 144 | wiz_model = self.registry('credit.control.legal.claim.printer') | ||
1009 | 145 | res = wiz_model._filter_claim_invoices(self.cr, self.uid, | ||
1010 | 146 | [self.claim_invoice_1, | ||
1011 | 147 | self.claim_invoice_2, | ||
1012 | 148 | self.non_claim_invoice_1]) | ||
1013 | 149 | self.assertEqual(res, [self.claim_invoice_1, | ||
1014 | 150 | self.claim_invoice_2]) | ||
1015 | 151 | |||
1016 | 152 | def test_01_mark(self): | ||
1017 | 153 | self.claim_invoice_1.credit_control_line_ids.append(self.no_claim_credit_line) | ||
1018 | 154 | wiz_model = self.registry('credit.control.legal.claim.printer') | ||
1019 | 155 | target = 'openerp.osv.orm.BaseModel.write' | ||
1020 | 156 | with patch(target, MagicMock()): | ||
1021 | 157 | res = wiz_model._mark_invoice_as_claimed(self.cr, | ||
1022 | 158 | self.uid, | ||
1023 | 159 | self.claim_invoice_1) | ||
1024 | 160 | self.assertEqual(res, [self.no_claim_credit_line]) | ||
1025 | 161 | |||
1026 | 162 | def test_02_get_fees(self): | ||
1027 | 163 | scheme = self.claim_office.fees_scheme_id | ||
1028 | 164 | fees = scheme.get_fees_from_amount(50.00) | ||
1029 | 165 | self.assertEqual(fees, 30) | ||
1030 | 166 | fees = scheme.get_fees_from_amount(550.00) | ||
1031 | 167 | self.assertEqual(fees, 70) | ||
1032 | 168 | |||
1033 | 169 | def test_03_get_fees_from_invoices(self): | ||
1034 | 170 | scheme = self.claim_office.fees_scheme_id | ||
1035 | 171 | fees = scheme._get_fees_from_invoices([self.claim_invoice_1, | ||
1036 | 172 | self.claim_invoice_1]) | ||
1037 | 173 | self.assertEqual(fees, 30) | ||
1038 | 174 | self.claim_invoice_1.residual = 800 | ||
1039 | 175 | scheme = self.claim_office.fees_scheme_id | ||
1040 | 176 | fees = scheme._get_fees_from_invoices([self.claim_invoice_1, | ||
1041 | 177 | self.claim_invoice_1]) | ||
1042 | 0 | 178 | ||
1043 | === added directory 'account_credit_control_legal_claim/view' | |||
1044 | === added file 'account_credit_control_legal_claim/view/claim_office_view.xml' | |||
1045 | --- account_credit_control_legal_claim/view/claim_office_view.xml 1970-01-01 00:00:00 +0000 | |||
1046 | +++ account_credit_control_legal_claim/view/claim_office_view.xml 2014-05-27 07:08:15 +0000 | |||
1047 | @@ -0,0 +1,69 @@ | |||
1048 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
1049 | 2 | <openerp> | ||
1050 | 3 | <data> | ||
1051 | 4 | |||
1052 | 5 | <record id="claim_office_list_view" model="ir.ui.view"> | ||
1053 | 6 | <field name="name">claim office list view</field> | ||
1054 | 7 | <field name="model">legal.claim.office</field> | ||
1055 | 8 | <field name="arch" type="xml"> | ||
1056 | 9 | <tree version="7.0" string="Claim office"> | ||
1057 | 10 | <field name="name"/> | ||
1058 | 11 | </tree> | ||
1059 | 12 | </field> | ||
1060 | 13 | </record> | ||
1061 | 14 | |||
1062 | 15 | <record id="claim_office_form_view" model="ir.ui.view"> | ||
1063 | 16 | <field name="name">claim office form view</field> | ||
1064 | 17 | <field name="model">legal.claim.office</field> | ||
1065 | 18 | <field name="arch" type="xml"> | ||
1066 | 19 | <form version="7.0" string="Claim office"> | ||
1067 | 20 | <header> | ||
1068 | 21 | <button | ||
1069 | 22 | type="action" | ||
1070 | 23 | name="%(base_location.action_zip_tree)d" | ||
1071 | 24 | string="Related Locations"/> | ||
1072 | 25 | </header> | ||
1073 | 26 | <group> | ||
1074 | 27 | <field name="name"/> | ||
1075 | 28 | <field name="partner_id"/> | ||
1076 | 29 | <field name="fees_scheme_id"/> | ||
1077 | 30 | </group> | ||
1078 | 31 | </form> | ||
1079 | 32 | </field> | ||
1080 | 33 | </record> | ||
1081 | 34 | |||
1082 | 35 | |||
1083 | 36 | <record model="ir.actions.act_window" id="claim_office_action"> | ||
1084 | 37 | <field name="name">Claim Office</field> | ||
1085 | 38 | <field name="type">ir.actions.act_window</field> | ||
1086 | 39 | <field name="res_model">legal.claim.office</field> | ||
1087 | 40 | <field name="domain"></field> | ||
1088 | 41 | <field name="view_type">form</field> | ||
1089 | 42 | <field name="view_mode">tree,form</field> | ||
1090 | 43 | <field name="view_id" ref="claim_office_list_view"/> | ||
1091 | 44 | </record> | ||
1092 | 45 | |||
1093 | 46 | <menuitem | ||
1094 | 47 | name="Credit control Legal Claim" | ||
1095 | 48 | parent="account.menu_finance_configuration" | ||
1096 | 49 | id="root_legal_claim_menu"/> | ||
1097 | 50 | |||
1098 | 51 | <menuitem | ||
1099 | 52 | name="Claim Office" | ||
1100 | 53 | parent="root_legal_claim_menu" | ||
1101 | 54 | action="claim_office_action" | ||
1102 | 55 | id="claim_office_action_menu"/> | ||
1103 | 56 | |||
1104 | 57 | <record id="add_office_to_location" model="ir.ui.view"> | ||
1105 | 58 | <field name="name">add office to location</field> | ||
1106 | 59 | <field name="model">res.better.zip</field> | ||
1107 | 60 | <field name="inherit_id" ref="base_location.better_zip_form" /> | ||
1108 | 61 | <field name="arch" type="xml"> | ||
1109 | 62 | <field name="country_id" position="after"> | ||
1110 | 63 | <field name="claim_office_id"/> | ||
1111 | 64 | </field> | ||
1112 | 65 | </field> | ||
1113 | 66 | </record> | ||
1114 | 67 | |||
1115 | 68 | </data> | ||
1116 | 69 | </openerp> | ||
1117 | 0 | 70 | ||
1118 | === added file 'account_credit_control_legal_claim/view/claim_scheme_view.xml' | |||
1119 | --- account_credit_control_legal_claim/view/claim_scheme_view.xml 1970-01-01 00:00:00 +0000 | |||
1120 | +++ account_credit_control_legal_claim/view/claim_scheme_view.xml 2014-05-27 07:08:15 +0000 | |||
1121 | @@ -0,0 +1,73 @@ | |||
1122 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
1123 | 2 | <openerp> | ||
1124 | 3 | <data> | ||
1125 | 4 | <record id="claim_scheme_list_view" model="ir.ui.view"> | ||
1126 | 5 | <field name="name">claime scheme list view</field> | ||
1127 | 6 | <field name="model">legal.claim.fees.scheme</field> | ||
1128 | 7 | <field name="arch" type="xml"> | ||
1129 | 8 | <tree version="7.0" string="Claim fees"> <!-- editable="bottom" --> | ||
1130 | 9 | <field name="name" /> | ||
1131 | 10 | <field name="company_id" groups="base.group_multi_company" widget="selection"/> | ||
1132 | 11 | <field name="product_id"/> | ||
1133 | 12 | </tree> | ||
1134 | 13 | </field> | ||
1135 | 14 | </record> | ||
1136 | 15 | |||
1137 | 16 | |||
1138 | 17 | <record id="claim_scheme_form_view" model="ir.ui.view"> | ||
1139 | 18 | <field name="name">Claim Scheme form</field> | ||
1140 | 19 | <field name="model">legal.claim.fees.scheme</field> | ||
1141 | 20 | <field name="arch" type="xml"> | ||
1142 | 21 | <form version="7.0" string="Claim Scheme"> | ||
1143 | 22 | <header> | ||
1144 | 23 | </header> | ||
1145 | 24 | <sheet> | ||
1146 | 25 | <group> | ||
1147 | 26 | <group> | ||
1148 | 27 | <field name="name"/> | ||
1149 | 28 | </group> | ||
1150 | 29 | </group> | ||
1151 | 30 | <group> | ||
1152 | 31 | <group> | ||
1153 | 32 | <field name="company_id" groups="base.group_multi_company" widget="selection"/> | ||
1154 | 33 | <field name="product_id"/> | ||
1155 | 34 | <field name="currency_id"/> | ||
1156 | 35 | </group> | ||
1157 | 36 | </group> | ||
1158 | 37 | |||
1159 | 38 | <notebook> | ||
1160 | 39 | <page string="Scheme values" colspan="4"> | ||
1161 | 40 | <field name="claim_scheme_line_ids" | ||
1162 | 41 | required="1"> | ||
1163 | 42 | <tree type="7.0" string="Line" editable="top"> | ||
1164 | 43 | <field name="open_amount"/> | ||
1165 | 44 | <field name="fees"/> | ||
1166 | 45 | </tree> | ||
1167 | 46 | </field> | ||
1168 | 47 | </page> | ||
1169 | 48 | </notebook> | ||
1170 | 49 | </sheet> | ||
1171 | 50 | </form> | ||
1172 | 51 | </field> | ||
1173 | 52 | </record> | ||
1174 | 53 | |||
1175 | 54 | <record model="ir.actions.act_window" id="claim_scheme_menu_action"> | ||
1176 | 55 | <field name="name">Claim office</field> | ||
1177 | 56 | <field name="type">ir.actions.act_window</field> | ||
1178 | 57 | <field name="res_model">legal.claim.fees.scheme</field> | ||
1179 | 58 | <field name="domain"></field> | ||
1180 | 59 | <field name="view_type">form</field> | ||
1181 | 60 | <field name="view_mode">tree,form</field> | ||
1182 | 61 | <field name="view_id" ref="claim_scheme_list_view"/> | ||
1183 | 62 | </record> | ||
1184 | 63 | |||
1185 | 64 | |||
1186 | 65 | |||
1187 | 66 | <menuitem | ||
1188 | 67 | name="Claim scheme" | ||
1189 | 68 | parent="root_legal_claim_menu" | ||
1190 | 69 | action="claim_scheme_menu_action" | ||
1191 | 70 | id="claim_scheme_menu_action_menu"/> | ||
1192 | 71 | |||
1193 | 72 | </data> | ||
1194 | 73 | </openerp> | ||
1195 | 0 | 74 | ||
1196 | === added file 'account_credit_control_legal_claim/view/credit_control_claim_printer_view.xml' | |||
1197 | --- account_credit_control_legal_claim/view/credit_control_claim_printer_view.xml 1970-01-01 00:00:00 +0000 | |||
1198 | +++ account_credit_control_legal_claim/view/credit_control_claim_printer_view.xml 2014-05-27 07:08:15 +0000 | |||
1199 | @@ -0,0 +1,65 @@ | |||
1200 | 1 | <openerp> | ||
1201 | 2 | <data> | ||
1202 | 3 | |||
1203 | 4 | <record id="credit_control_claim_printer_view" model="ir.ui.view"> | ||
1204 | 5 | <field name="name">credit control claim printer view</field> | ||
1205 | 6 | <field name="model">credit.control.legal.claim.printer</field> | ||
1206 | 7 | <field name="arch" type="xml"> | ||
1207 | 8 | <form version="7.0" | ||
1208 | 9 | string="Claim Printer"> | ||
1209 | 10 | <separator string="Print claim requisition letter for invoices" colspan="4"/> | ||
1210 | 11 | <newline/> | ||
1211 | 12 | <group> | ||
1212 | 13 | <field name="mark_as_claimed" | ||
1213 | 14 | colspan="4" | ||
1214 | 15 | attrs="{'invisible': [('state', '=', 'done')]}"/> | ||
1215 | 16 | </group> | ||
1216 | 17 | <newline/> | ||
1217 | 18 | <notebook> | ||
1218 | 19 | <page string="Invoices" attrs="{'invisible': [('state', '=', 'done')]}"> | ||
1219 | 20 | <field name="invoice_ids" colspan="4" nolabel="1" | ||
1220 | 21 | attrs="{'invisible': [('state', '=', 'done')]}" /> | ||
1221 | 22 | </page> | ||
1222 | 23 | </notebook> | ||
1223 | 24 | <field name="report_name" | ||
1224 | 25 | invisible="1"/> | ||
1225 | 26 | <field name="report_file" | ||
1226 | 27 | colspan="4" | ||
1227 | 28 | filename="report_name" | ||
1228 | 29 | attrs="{'invisible': [('state', '!=', 'done')]}"/> | ||
1229 | 30 | <field name="state" invisible="1" /> | ||
1230 | 31 | <newline/> | ||
1231 | 32 | <footer> | ||
1232 | 33 | <button class="oe_highlight" name="print_claims" string="Print" type="object" attrs="{'invisible': [('state', '==', 'done')]}"/> | ||
1233 | 34 | <button special="cancel" string="Cancel" icon='gtk-cancel' attrs="{'invisible': [('state', '==', 'done')]}"/> | ||
1234 | 35 | <button special="cancel" string="Close" icon='gtk-close' attrs="{'invisible': [('state', '!=', 'done')]}"/> | ||
1235 | 36 | </footer> | ||
1236 | 37 | |||
1237 | 38 | |||
1238 | 39 | </form> | ||
1239 | 40 | </field> | ||
1240 | 41 | </record> | ||
1241 | 42 | |||
1242 | 43 | <!-- for button --> | ||
1243 | 44 | <record id="legal_claim_printer_action" model="ir.actions.act_window"> | ||
1244 | 45 | <field name="name">Print Claim Requisition</field> | ||
1245 | 46 | <field name="res_model">credit.control.legal.claim.printer</field> | ||
1246 | 47 | <field name="src_model">account.invoice</field> | ||
1247 | 48 | <field name="view_type">form</field> | ||
1248 | 49 | <field name="view_mode">form</field> | ||
1249 | 50 | <field name="view_id" ref="credit_control_claim_printer_view"/> | ||
1250 | 51 | <field name="target">new</field> | ||
1251 | 52 | <field name="help"></field> | ||
1252 | 53 | </record> | ||
1253 | 54 | |||
1254 | 55 | <!-- for menu --> | ||
1255 | 56 | <act_window name="Print Claim Requisition" | ||
1256 | 57 | res_model="credit.control.legal.claim.printer" | ||
1257 | 58 | src_model="account.invoice" | ||
1258 | 59 | view_mode="form" | ||
1259 | 60 | target="new" | ||
1260 | 61 | key2="client_action_multi" | ||
1261 | 62 | id="legal_claim_printer_action_menu_action"/> | ||
1262 | 63 | |||
1263 | 64 | </data> | ||
1264 | 65 | </openerp> | ||
1265 | 0 | 66 | ||
1266 | === added file 'account_credit_control_legal_claim/view/policy_view.xml' | |||
1267 | --- account_credit_control_legal_claim/view/policy_view.xml 1970-01-01 00:00:00 +0000 | |||
1268 | +++ account_credit_control_legal_claim/view/policy_view.xml 2014-05-27 07:08:15 +0000 | |||
1269 | @@ -0,0 +1,24 @@ | |||
1270 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
1271 | 2 | <openerp> | ||
1272 | 3 | <data> | ||
1273 | 4 | <record id="add_claim_on_policy_level" model="ir.ui.view"> | ||
1274 | 5 | <field name="name">add claim on policy level</field> | ||
1275 | 6 | <field name="model">credit.control.policy</field> | ||
1276 | 7 | <field name="inherit_id" | ||
1277 | 8 | ref="account_credit_control.credit_control_policy_form"/> | ||
1278 | 9 | <field name="arch" type="xml"> | ||
1279 | 10 | <page string="Mail and reporting" position="after"> | ||
1280 | 11 | <page string="Legal Claim"> | ||
1281 | 12 | <group> | ||
1282 | 13 | <group> | ||
1283 | 14 | <field name="is_legal_claim"/> | ||
1284 | 15 | </group> | ||
1285 | 16 | </group> | ||
1286 | 17 | </page> | ||
1287 | 18 | </page> | ||
1288 | 19 | |||
1289 | 20 | </field> | ||
1290 | 21 | </record> | ||
1291 | 22 | |||
1292 | 23 | </data> | ||
1293 | 24 | </openerp> | ||
1294 | 0 | 25 | ||
1295 | === added directory 'account_credit_control_legal_claim/wizard' | |||
1296 | === added file 'account_credit_control_legal_claim/wizard/__init__.py' | |||
1297 | --- account_credit_control_legal_claim/wizard/__init__.py 1970-01-01 00:00:00 +0000 | |||
1298 | +++ account_credit_control_legal_claim/wizard/__init__.py 2014-05-27 07:08:15 +0000 | |||
1299 | @@ -0,0 +1,21 @@ | |||
1300 | 1 | # -*- coding: utf-8 -*- | ||
1301 | 2 | ############################################################################## | ||
1302 | 3 | # | ||
1303 | 4 | # Author: Nicolas Bessi | ||
1304 | 5 | # Copyright 2014 Camptocamp SA | ||
1305 | 6 | # | ||
1306 | 7 | # This program is free software: you can redistribute it and/or modify | ||
1307 | 8 | # it under the terms of the GNU Affero General Public License as | ||
1308 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
1309 | 10 | # License, or (at your option) any later version. | ||
1310 | 11 | # | ||
1311 | 12 | # This program is distributed in the hope that it will be useful, | ||
1312 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1313 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1314 | 15 | # GNU Affero General Public License for more details. | ||
1315 | 16 | # | ||
1316 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
1317 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1318 | 19 | # | ||
1319 | 20 | ############################################################################## | ||
1320 | 21 | from . import credit_control_claim_printer | ||
1321 | 0 | 22 | ||
1322 | === added file 'account_credit_control_legal_claim/wizard/credit_control_claim_printer.py' | |||
1323 | --- account_credit_control_legal_claim/wizard/credit_control_claim_printer.py 1970-01-01 00:00:00 +0000 | |||
1324 | +++ account_credit_control_legal_claim/wizard/credit_control_claim_printer.py 2014-05-27 07:08:15 +0000 | |||
1325 | @@ -0,0 +1,154 @@ | |||
1326 | 1 | # -*- coding: utf-8 -*- | ||
1327 | 2 | ############################################################################## | ||
1328 | 3 | # | ||
1329 | 4 | # Author: Nicolas Bessi | ||
1330 | 5 | # Copyright 2014 Camptocamp SA | ||
1331 | 6 | # | ||
1332 | 7 | # This program is free software: you can redistribute it and/or modify | ||
1333 | 8 | # it under the terms of the GNU Affero General Public License as | ||
1334 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
1335 | 10 | # License, or (at your option) any later version. | ||
1336 | 11 | # | ||
1337 | 12 | # This program is distributed in the hope that it will be useful, | ||
1338 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1339 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1340 | 15 | # GNU Affero General Public License for more details. | ||
1341 | 16 | # | ||
1342 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
1343 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1344 | 19 | # | ||
1345 | 20 | ############################################################################## | ||
1346 | 21 | import base64 | ||
1347 | 22 | import netsvc | ||
1348 | 23 | from openerp.osv import orm, fields | ||
1349 | 24 | |||
1350 | 25 | |||
1351 | 26 | class credit_control_legal_printer(orm.TransientModel): | ||
1352 | 27 | """Print claim requisition letter | ||
1353 | 28 | |||
1354 | 29 | And manage related credit lines | ||
1355 | 30 | |||
1356 | 31 | """ | ||
1357 | 32 | |||
1358 | 33 | def _filter_claim_invoices(self, cr, uid, invoices, context=None): | ||
1359 | 34 | """ Return invoices that are related to a claim | ||
1360 | 35 | concretly that means the invoice must be related | ||
1361 | 36 | to active credit line related to a claim policy level | ||
1362 | 37 | |||
1363 | 38 | :param invoices: list on invoices record to be filtered | ||
1364 | 39 | |||
1365 | 40 | """ | ||
1366 | 41 | |||
1367 | 42 | filtered = [] | ||
1368 | 43 | for inv in invoices: | ||
1369 | 44 | if any(x for x in inv.credit_control_line_ids | ||
1370 | 45 | if x.policy_level_id.is_legal_claim): | ||
1371 | 46 | filtered.append(inv) | ||
1372 | 47 | return filtered | ||
1373 | 48 | |||
1374 | 49 | def _get_invoice_ids(self, cr, uid, context=None): | ||
1375 | 50 | """Return invoices ids to be treated form context | ||
1376 | 51 | A candidate invoice is related to a claim | ||
1377 | 52 | |||
1378 | 53 | """ | ||
1379 | 54 | inv_model = self.pool['account.invoice'] | ||
1380 | 55 | if context is None: | ||
1381 | 56 | context = {} | ||
1382 | 57 | res = False | ||
1383 | 58 | if context.get('active_model') != 'account.invoice': | ||
1384 | 59 | return res | ||
1385 | 60 | res = context.get('active_ids', False) | ||
1386 | 61 | if res: | ||
1387 | 62 | invoices = inv_model.browse(cr, uid, res, context=context) | ||
1388 | 63 | filtered = self._filter_claim_invoices(cr, uid, invoices, | ||
1389 | 64 | context=context) | ||
1390 | 65 | res = [x.id for x in filtered] | ||
1391 | 66 | return res | ||
1392 | 67 | |||
1393 | 68 | _name = "credit.control.legal.claim.printer" | ||
1394 | 69 | _rec_name = 'id' | ||
1395 | 70 | _columns = { | ||
1396 | 71 | 'mark_as_claimed': fields.boolean('Mark as Claimed'), | ||
1397 | 72 | 'report_file': fields.binary('Report File', | ||
1398 | 73 | readonly=True), | ||
1399 | 74 | 'report_name': fields.char('Report Name'), | ||
1400 | 75 | 'invoice_ids': fields.many2many('account.invoice', | ||
1401 | 76 | string='Invoices'), | ||
1402 | 77 | 'state': fields.selection([('draft', 'Draft'), | ||
1403 | 78 | ('done', 'Done')]), | ||
1404 | 79 | } | ||
1405 | 80 | |||
1406 | 81 | _defaults = { | ||
1407 | 82 | 'invoice_ids': _get_invoice_ids, | ||
1408 | 83 | 'mark_as_claimed': True, | ||
1409 | 84 | } | ||
1410 | 85 | |||
1411 | 86 | def _generate_report(self, cr, uid, invoice_ids, context=None): | ||
1412 | 87 | """Generate claim requisition report. | ||
1413 | 88 | |||
1414 | 89 | :param invoice_ids: list of invoice ids to print | ||
1415 | 90 | |||
1416 | 91 | :returns: report file | ||
1417 | 92 | |||
1418 | 93 | """ | ||
1419 | 94 | service = netsvc.LocalService('report.credit_control_legal_claim_requisition') | ||
1420 | 95 | result, format = service.create(cr, uid, invoice_ids, {}, {}) | ||
1421 | 96 | return result | ||
1422 | 97 | |||
1423 | 98 | def _mark_invoice_as_claimed(self, cr, uid, invoice, context=None): | ||
1424 | 99 | """Mark related credit line of an invoice as overridden. | ||
1425 | 100 | |||
1426 | 101 | Only non claim credit line will be marked | ||
1427 | 102 | |||
1428 | 103 | :param invoice: invoice recorrd to treat | ||
1429 | 104 | |||
1430 | 105 | :returns: marked credit lines | ||
1431 | 106 | """ | ||
1432 | 107 | lines = [x for x in invoice.credit_control_line_ids | ||
1433 | 108 | if not x.policy_level_id.is_legal_claim] | ||
1434 | 109 | credit_line_model = self.pool['credit.control.line'] | ||
1435 | 110 | data = {'manually_overridden': True} | ||
1436 | 111 | credit_line_model.write(cr, uid, | ||
1437 | 112 | [x.id for x in lines], | ||
1438 | 113 | data, | ||
1439 | 114 | context=context) | ||
1440 | 115 | return lines | ||
1441 | 116 | |||
1442 | 117 | def print_claims(self, cr, uid, wiz_id, context=None): | ||
1443 | 118 | """Generate claim requisition report and manage credit lines. | ||
1444 | 119 | |||
1445 | 120 | Non claim credit lines will be overridden | ||
1446 | 121 | |||
1447 | 122 | :param invoice_ids: list of invoice ids to print | ||
1448 | 123 | |||
1449 | 124 | :returns: an ir.action to himself | ||
1450 | 125 | |||
1451 | 126 | """ | ||
1452 | 127 | if isinstance(wiz_id, list): | ||
1453 | 128 | assert len(wiz_id) == 1 | ||
1454 | 129 | wiz_id = wiz_id[0] | ||
1455 | 130 | |||
1456 | 131 | current = self.browse(cr, uid, wiz_id, context=context) | ||
1457 | 132 | invs = self._filter_claim_invoices(cr, uid, current.invoice_ids, | ||
1458 | 133 | context=context) | ||
1459 | 134 | invoice_ids = [x.id for x in invs] | ||
1460 | 135 | assert invoice_ids | ||
1461 | 136 | report_file = self._generate_report(cr, uid, invoice_ids, | ||
1462 | 137 | context=context) | ||
1463 | 138 | current.write( | ||
1464 | 139 | {'report_file': base64.b64encode(report_file), | ||
1465 | 140 | 'report_name': 'claim_letters_%s.pdf' % fields.datetime.now(), | ||
1466 | 141 | 'state': 'done'} | ||
1467 | 142 | ) | ||
1468 | 143 | if current.mark_as_claimed: | ||
1469 | 144 | for inv in invs: | ||
1470 | 145 | self._mark_invoice_as_claimed(cr, uid, inv, context=context) | ||
1471 | 146 | |||
1472 | 147 | return {'type': 'ir.actions.act_window', | ||
1473 | 148 | 'res_model': 'credit.control.legal.claim.printer', | ||
1474 | 149 | 'view_mode': 'form', | ||
1475 | 150 | 'view_type': 'form', | ||
1476 | 151 | 'res_id': current.id, | ||
1477 | 152 | 'views': [(False, 'form')], | ||
1478 | 153 | 'target': 'new', | ||
1479 | 154 | } |