Merge lp:~elbati/openobject-italia/l10n_it_withholding_tax_7 into lp:~openobject-italia-core-devs/openobject-italia/italian-addons-7.0
- l10n_it_withholding_tax_7
- Merge into italian-addons-7.0
Proposed by
Lorenzo Battistini
Status: | Merged |
---|---|
Merged at revision: | 221 |
Proposed branch: | lp:~elbati/openobject-italia/l10n_it_withholding_tax_7 |
Merge into: | lp:~openobject-italia-core-devs/openobject-italia/italian-addons-7.0 |
Diff against target: |
679 lines (+635/-0) 8 files modified
l10n_it_withholding_tax/AUTHORS.txt (+2/-0) l10n_it_withholding_tax/__init__.py (+24/-0) l10n_it_withholding_tax/__openerp__.py (+60/-0) l10n_it_withholding_tax/account.py (+204/-0) l10n_it_withholding_tax/account_demo.xml (+19/-0) l10n_it_withholding_tax/account_view.xml (+71/-0) l10n_it_withholding_tax/i18n/it.po (+150/-0) l10n_it_withholding_tax/test/purchase_payment.yml (+105/-0) |
To merge this branch: | bzr merge lp:~elbati/openobject-italia/l10n_it_withholding_tax_7 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Lorenzo Battistini | Approve | ||
Review via email: mp+159380@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 217. By Lorenzo Battistini
-
[add] tests first version
- 218. By Lorenzo Battistini
-
[imp] tests
- 219. By Lorenzo Battistini
-
[imp] tests
- 220. By Lorenzo Battistini
-
[ADD] field help
- 221. By Lorenzo Battistini
-
[fix] using right date and period when paying
Revision history for this message
Lorenzo Battistini (elbati) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory 'l10n_it_withholding_tax' | |||
2 | === added file 'l10n_it_withholding_tax/AUTHORS.txt' | |||
3 | --- l10n_it_withholding_tax/AUTHORS.txt 1970-01-01 00:00:00 +0000 | |||
4 | +++ l10n_it_withholding_tax/AUTHORS.txt 2013-05-09 14:32:26 +0000 | |||
5 | @@ -0,0 +1,2 @@ | |||
6 | 1 | Lorenzo Battistini <lorenzo.battistini@agilebg.com> | ||
7 | 2 | Paolo Chiara <p.chiara@isa.it> | ||
8 | 0 | 3 | ||
9 | === added file 'l10n_it_withholding_tax/__init__.py' | |||
10 | --- l10n_it_withholding_tax/__init__.py 1970-01-01 00:00:00 +0000 | |||
11 | +++ l10n_it_withholding_tax/__init__.py 2013-05-09 14:32:26 +0000 | |||
12 | @@ -0,0 +1,24 @@ | |||
13 | 1 | # -*- coding: utf-8 -*- | ||
14 | 2 | ############################################################################## | ||
15 | 3 | # | ||
16 | 4 | # Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>) | ||
17 | 5 | # Copyright (C) 2012 Domsense srl (<http://www.domsense.com>) | ||
18 | 6 | # Copyright (C) 2012-2013 Associazione OpenERP Italia | ||
19 | 7 | # (<http://www.openerp-italia.org>). | ||
20 | 8 | # | ||
21 | 9 | # This program is free software: you can redistribute it and/or modify | ||
22 | 10 | # it under the terms of the GNU Affero General Public License as published by | ||
23 | 11 | # the Free Software Foundation, either version 3 of the License, or | ||
24 | 12 | # (at your option) any later version. | ||
25 | 13 | # | ||
26 | 14 | # This program is distributed in the hope that it will be useful, | ||
27 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
28 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
29 | 17 | # GNU Affero General Public License for more details. | ||
30 | 18 | # | ||
31 | 19 | # You should have received a copy of the GNU Affero General Public License | ||
32 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
33 | 21 | # | ||
34 | 22 | ############################################################################## | ||
35 | 23 | |||
36 | 24 | import account | ||
37 | 0 | 25 | ||
38 | === added file 'l10n_it_withholding_tax/__openerp__.py' | |||
39 | --- l10n_it_withholding_tax/__openerp__.py 1970-01-01 00:00:00 +0000 | |||
40 | +++ l10n_it_withholding_tax/__openerp__.py 2013-05-09 14:32:26 +0000 | |||
41 | @@ -0,0 +1,60 @@ | |||
42 | 1 | # -*- coding: utf-8 -*- | ||
43 | 2 | ############################################################################## | ||
44 | 3 | # | ||
45 | 4 | # Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>) | ||
46 | 5 | # Copyright (C) 2012 Domsense srl (<http://www.domsense.com>) | ||
47 | 6 | # Copyright (C) 2012-2013 Associazione OpenERP Italia | ||
48 | 7 | # (<http://www.openerp-italia.org>). | ||
49 | 8 | # | ||
50 | 9 | # This program is free software: you can redistribute it and/or modify | ||
51 | 10 | # it under the terms of the GNU Affero General Public License as published by | ||
52 | 11 | # the Free Software Foundation, either version 3 of the License, or | ||
53 | 12 | # (at your option) any later version. | ||
54 | 13 | # | ||
55 | 14 | # This program is distributed in the hope that it will be useful, | ||
56 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
57 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
58 | 17 | # GNU Affero General Public License for more details. | ||
59 | 18 | # | ||
60 | 19 | # You should have received a copy of the GNU Affero General Public License | ||
61 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
62 | 21 | # | ||
63 | 22 | ############################################################################## | ||
64 | 23 | { | ||
65 | 24 | 'name': "Italian Localisation - Withholding tax", | ||
66 | 25 | 'version': '0.2', | ||
67 | 26 | 'category': 'Localisation/Italy', | ||
68 | 27 | 'description': """ | ||
69 | 28 | Ritenute d'acconto sulle fatture fornitore | ||
70 | 29 | ========================================== | ||
71 | 30 | |||
72 | 31 | Per utilizzare il modulo bisogna configurare i campi associati alla company: | ||
73 | 32 | - Termine di pagamento della ritenuta | ||
74 | 33 | - Conto di debito per le ritenute da versare | ||
75 | 34 | - Sezionale che conterrà le registrazioni legate alla ritenuta | ||
76 | 35 | |||
77 | 36 | Durante la compilazione di una fattura fornitore con ritenuta d'acconto, l'utente dovrà specificare l'importo della ritenuta. | ||
78 | 37 | |||
79 | 38 | Requisiti | ||
80 | 39 | --------- | ||
81 | 40 | http://wiki.openerp-italia.org/doku.php/area_utente/requisiti/ritenuta_d_acconto | ||
82 | 41 | |||
83 | 42 | Howto | ||
84 | 43 | ----- | ||
85 | 44 | http://planet.domsense.com/2012/06/come-registrare-in-openerp-le-fatture-fornitore-con-ritenuta-dacconto/ | ||
86 | 45 | """, | ||
87 | 46 | 'author': 'OpenERP Italian Community', | ||
88 | 47 | 'website': 'http://www.openerp-italia.org', | ||
89 | 48 | 'license': 'AGPL-3', | ||
90 | 49 | "depends" : ['account_voucher_cash_basis'], | ||
91 | 50 | "data" : [ | ||
92 | 51 | 'account_view.xml',], | ||
93 | 52 | "demo" : [ | ||
94 | 53 | 'account_demo.xml', | ||
95 | 54 | ], | ||
96 | 55 | 'test' : [ | ||
97 | 56 | 'test/purchase_payment.yml', | ||
98 | 57 | ], | ||
99 | 58 | "active": False, | ||
100 | 59 | "installable": True | ||
101 | 60 | } | ||
102 | 0 | 61 | ||
103 | === added file 'l10n_it_withholding_tax/account.py' | |||
104 | --- l10n_it_withholding_tax/account.py 1970-01-01 00:00:00 +0000 | |||
105 | +++ l10n_it_withholding_tax/account.py 2013-05-09 14:32:26 +0000 | |||
106 | @@ -0,0 +1,204 @@ | |||
107 | 1 | # -*- coding: utf-8 -*- | ||
108 | 2 | ############################################################################## | ||
109 | 3 | # | ||
110 | 4 | # Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>) | ||
111 | 5 | # Copyright (C) 2012 Domsense srl (<http://www.domsense.com>) | ||
112 | 6 | # Copyright (C) 2012-2013 Associazione OpenERP Italia | ||
113 | 7 | # (<http://www.openerp-italia.org>). | ||
114 | 8 | # | ||
115 | 9 | # This program is free software: you can redistribute it and/or modify | ||
116 | 10 | # it under the terms of the GNU Affero General Public License as published by | ||
117 | 11 | # the Free Software Foundation, either version 3 of the License, or | ||
118 | 12 | # (at your option) any later version. | ||
119 | 13 | # | ||
120 | 14 | # This program is distributed in the hope that it will be useful, | ||
121 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
122 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
123 | 17 | # GNU Affero General Public License for more details. | ||
124 | 18 | # | ||
125 | 19 | # You should have received a copy of the GNU Affero General Public License | ||
126 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
127 | 21 | # | ||
128 | 22 | ############################################################################## | ||
129 | 23 | |||
130 | 24 | from openerp.osv import fields, orm | ||
131 | 25 | from openerp.tools.translate import _ | ||
132 | 26 | import decimal_precision as dp | ||
133 | 27 | |||
134 | 28 | class res_company(orm.Model): | ||
135 | 29 | _inherit = 'res.company' | ||
136 | 30 | _columns = { | ||
137 | 31 | 'withholding_payment_term_id': fields.many2one('account.payment.term', | ||
138 | 32 | 'Withholding tax Payment Term', | ||
139 | 33 | help="The withholding tax will have to be paid within this term"), | ||
140 | 34 | 'withholding_account_id': fields.many2one('account.account','Withholding account', | ||
141 | 35 | help='Payable account used for amount due to tax authority', | ||
142 | 36 | domain=[('type', '=', 'payable')]), | ||
143 | 37 | 'withholding_journal_id': fields.many2one('account.journal','Withholding journal', | ||
144 | 38 | help="Journal used for registration of witholding amounts to be paid"), | ||
145 | 39 | 'authority_partner_id': fields.many2one('res.partner', 'Tax Authority Partner'), | ||
146 | 40 | } | ||
147 | 41 | |||
148 | 42 | class account_config_settings(orm.TransientModel): | ||
149 | 43 | _inherit = 'account.config.settings' | ||
150 | 44 | _columns = { | ||
151 | 45 | 'withholding_payment_term_id': fields.related( | ||
152 | 46 | 'company_id', 'withholding_payment_term_id', | ||
153 | 47 | type='many2one', | ||
154 | 48 | relation="account.payment.term", | ||
155 | 49 | string="Withholding tax Payment Term"), | ||
156 | 50 | 'withholding_account_id': fields.related( | ||
157 | 51 | 'company_id', 'withholding_account_id', | ||
158 | 52 | type='many2one', | ||
159 | 53 | relation="account.account", | ||
160 | 54 | string="Withholding account", | ||
161 | 55 | help='Payable account used for amount due to tax authority', | ||
162 | 56 | domain=[('type', '=', 'payable')]), | ||
163 | 57 | 'withholding_journal_id': fields.related( | ||
164 | 58 | 'company_id', 'withholding_journal_id', | ||
165 | 59 | type='many2one', | ||
166 | 60 | relation="account.journal", | ||
167 | 61 | string="Withholding journal", | ||
168 | 62 | help='Journal used for registration of witholding amounts to be paid'), | ||
169 | 63 | 'authority_partner_id': fields.related( | ||
170 | 64 | 'company_id', 'authority_partner_id', | ||
171 | 65 | type='many2one', | ||
172 | 66 | relation="res.partner", | ||
173 | 67 | string="Tax Authority Partner"), | ||
174 | 68 | } | ||
175 | 69 | |||
176 | 70 | def onchange_company_id(self, cr, uid, ids, company_id, context=None): | ||
177 | 71 | res = super(account_config_settings, self).onchange_company_id(cr, uid, ids, company_id, context=context) | ||
178 | 72 | if company_id: | ||
179 | 73 | company = self.pool.get('res.company').browse(cr, uid, company_id, context=context) | ||
180 | 74 | res['value'].update({ | ||
181 | 75 | 'withholding_payment_term_id': (company.withholding_payment_term_id | ||
182 | 76 | and company.withholding_payment_term_id.id or False), | ||
183 | 77 | 'withholding_account_id': (company.withholding_account_id | ||
184 | 78 | and company.withholding_account_id.id or False), | ||
185 | 79 | 'withholding_journal_id': (company.withholding_journal_id | ||
186 | 80 | and company.withholding_journal_id.id or False), | ||
187 | 81 | 'authority_partner_id': (company.authority_partner_id | ||
188 | 82 | and company.authority_partner_id.id or False), | ||
189 | 83 | }) | ||
190 | 84 | else: | ||
191 | 85 | res['value'].update({ | ||
192 | 86 | 'withholding_payment_term_id': False, | ||
193 | 87 | 'withholding_account_id': False, | ||
194 | 88 | 'withholding_journal_id': False, | ||
195 | 89 | 'authority_partner_id': False, | ||
196 | 90 | }) | ||
197 | 91 | return res | ||
198 | 92 | |||
199 | 93 | class account_invoice(orm.Model): | ||
200 | 94 | |||
201 | 95 | def _net_pay(self, cr, uid, ids, field_name, arg, context=None): | ||
202 | 96 | res = {} | ||
203 | 97 | for invoice in self.browse(cr, uid, ids, context): | ||
204 | 98 | res[invoice.id] = invoice.amount_total - invoice.withholding_amount | ||
205 | 99 | return res | ||
206 | 100 | |||
207 | 101 | _inherit = "account.invoice" | ||
208 | 102 | |||
209 | 103 | _columns = { | ||
210 | 104 | 'withholding_amount': fields.float('Withholding amount', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft':[('readonly',False)]}), | ||
211 | 105 | 'has_withholding': fields.boolean('With withholding tax', readonly=True, states={'draft':[('readonly',False)]}), | ||
212 | 106 | 'net_pay': fields.function(_net_pay, string="Net Pay"), | ||
213 | 107 | } | ||
214 | 108 | |||
215 | 109 | class account_voucher(orm.Model): | ||
216 | 110 | _inherit = "account.voucher" | ||
217 | 111 | |||
218 | 112 | _columns = { | ||
219 | 113 | 'withholding_move_ids': fields.many2many('account.move', 'voucher_withholding_move_rel', 'voucher_id', 'move_id', 'Withholding Tax Entries', readonly=True), | ||
220 | 114 | } | ||
221 | 115 | |||
222 | 116 | def reconcile_withholding_move(self, cr, uid, invoice, wh_move, context=None): | ||
223 | 117 | line_pool=self.pool.get('account.move.line') | ||
224 | 118 | rec_ids = [] | ||
225 | 119 | for inv_move_line in invoice.move_id.line_id: | ||
226 | 120 | if inv_move_line.account_id.type == 'payable' and not inv_move_line.reconcile_id: | ||
227 | 121 | rec_ids.append(inv_move_line.id) | ||
228 | 122 | for wh_line in wh_move.line_id: | ||
229 | 123 | if wh_line.account_id.type == 'payable' and invoice.company_id.withholding_account_id and invoice.company_id.withholding_account_id.id != wh_line.account_id.id and not wh_line.reconcile_id: | ||
230 | 124 | rec_ids.append(wh_line.id) | ||
231 | 125 | return line_pool.reconcile_partial(cr, uid, rec_ids, type='auto', context=context) | ||
232 | 126 | |||
233 | 127 | def action_move_line_create(self, cr, uid, ids, context=None): | ||
234 | 128 | res = super(account_voucher,self).action_move_line_create(cr, uid, ids, context) | ||
235 | 129 | inv_pool = self.pool.get('account.invoice') | ||
236 | 130 | move_pool = self.pool.get('account.move') | ||
237 | 131 | tax_pool = self.pool.get('account.tax') | ||
238 | 132 | curr_pool = self.pool.get('res.currency') | ||
239 | 133 | term_pool = self.pool.get('account.payment.term') | ||
240 | 134 | priod_obj = self.pool.get('account.period') | ||
241 | 135 | for voucher in self.browse(cr, uid, ids, context): | ||
242 | 136 | amounts_by_invoice = super(account_voucher,self).allocated_amounts_grouped_by_invoice(cr, uid,voucher, context) | ||
243 | 137 | for inv_id in amounts_by_invoice: | ||
244 | 138 | invoice = inv_pool.browse(cr, uid, inv_id, context) | ||
245 | 139 | if invoice.withholding_amount: | ||
246 | 140 | # only for supplier payments | ||
247 | 141 | if voucher.type != 'payment': | ||
248 | 142 | raise orm.except_orm(_('Error'), _('Can\'t handle withholding tax with voucher of type other than payment')) | ||
249 | 143 | if not invoice.company_id.withholding_account_id: | ||
250 | 144 | raise orm.except_orm(_('Error'), _('The company does not have an associated Withholding account') ) | ||
251 | 145 | if not invoice.company_id.withholding_payment_term_id: | ||
252 | 146 | raise orm.except_orm(_('Error'), _('The company does not have an associated Withholding Payment Term') ) | ||
253 | 147 | if not invoice.company_id.withholding_journal_id: | ||
254 | 148 | raise orm.except_orm(_('Error'), _('The company does not have an associated Withholding journal') ) | ||
255 | 149 | if not invoice.company_id.authority_partner_id: | ||
256 | 150 | raise orm.except_orm(_('Error'), _('The company does not have an associated Tax Authority partner') ) | ||
257 | 151 | # compute the new amount proportionally to paid amount | ||
258 | 152 | new_line_amount = curr_pool.round(cr, uid, voucher.company_id.currency_id, ((amounts_by_invoice[invoice.id]['allocated'] + amounts_by_invoice[invoice.id]['write-off']) / invoice.net_pay) * invoice.withholding_amount) | ||
259 | 153 | |||
260 | 154 | # compute the due date | ||
261 | 155 | due_list = term_pool.compute( | ||
262 | 156 | cr, uid, invoice.company_id.withholding_payment_term_id.id, new_line_amount, | ||
263 | 157 | date_ref=voucher.date or invoice.date_invoice, context=context) | ||
264 | 158 | if len(due_list) > 1: | ||
265 | 159 | raise orm.except_orm(_('Error'), | ||
266 | 160 | _('The payment term %s has too many due dates') | ||
267 | 161 | % invoice.company_id.withholding_payment_term_id.name) | ||
268 | 162 | if len(due_list) == 0: | ||
269 | 163 | raise orm.except_orm(_('Error'), | ||
270 | 164 | _('The payment term %s does not have due dates') | ||
271 | 165 | % invoice.company_id.withholding_payment_term_id.name) | ||
272 | 166 | |||
273 | 167 | period_ids = priod_obj.find(cr, uid, dt=voucher.date, context=context) | ||
274 | 168 | new_move = { | ||
275 | 169 | 'journal_id': invoice.company_id.withholding_journal_id.id, | ||
276 | 170 | 'period_id': period_ids and period_ids[0] or False, | ||
277 | 171 | 'date': voucher.date, | ||
278 | 172 | 'line_id': [ | ||
279 | 173 | (0,0,{ | ||
280 | 174 | 'name': invoice.number, | ||
281 | 175 | 'account_id': invoice.account_id.id, | ||
282 | 176 | 'partner_id': invoice.partner_id.id, | ||
283 | 177 | 'debit': new_line_amount, | ||
284 | 178 | 'credit': 0.0, | ||
285 | 179 | }), | ||
286 | 180 | (0,0,{ | ||
287 | 181 | 'name': _('Payable withholding - ') + invoice.number, | ||
288 | 182 | 'account_id': invoice.company_id.withholding_account_id.id, | ||
289 | 183 | 'partner_id': invoice.company_id.authority_partner_id.id, | ||
290 | 184 | 'debit': 0.0, | ||
291 | 185 | 'credit': new_line_amount, | ||
292 | 186 | 'date_maturity': due_list[0][0], | ||
293 | 187 | }), | ||
294 | 188 | ] | ||
295 | 189 | } | ||
296 | 190 | move_id = self.pool.get('account.move').create(cr, uid, new_move, context=context) | ||
297 | 191 | self.reconcile_withholding_move(cr, uid, invoice, move_pool.browse(cr, uid, move_id, context), context) | ||
298 | 192 | voucher.write({'withholding_move_ids': [(4, move_id)]}) | ||
299 | 193 | return res | ||
300 | 194 | |||
301 | 195 | def cancel_voucher(self, cr, uid, ids, context=None): | ||
302 | 196 | res = super(account_voucher,self).cancel_voucher(cr, uid, ids, context) | ||
303 | 197 | reconcile_pool = self.pool.get('account.move.reconcile') | ||
304 | 198 | move_pool = self.pool.get('account.move') | ||
305 | 199 | for voucher in self.browse(cr, uid, ids, context=context): | ||
306 | 200 | recs = [] | ||
307 | 201 | for move in voucher.withholding_move_ids: | ||
308 | 202 | move_pool.button_cancel(cr, uid, [move.id]) | ||
309 | 203 | move_pool.unlink(cr, uid, [move.id]) | ||
310 | 204 | return res | ||
311 | 0 | 205 | ||
312 | === added file 'l10n_it_withholding_tax/account_demo.xml' | |||
313 | --- l10n_it_withholding_tax/account_demo.xml 1970-01-01 00:00:00 +0000 | |||
314 | +++ l10n_it_withholding_tax/account_demo.xml 2013-05-09 14:32:26 +0000 | |||
315 | @@ -0,0 +1,19 @@ | |||
316 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
317 | 2 | <openerp> | ||
318 | 3 | <data noupdate="1"> | ||
319 | 4 | |||
320 | 5 | <record id="a_witholding" model="account.account"> | ||
321 | 6 | <field name="code">X1115</field> | ||
322 | 7 | <field name="name">Withholding tax to pay</field> | ||
323 | 8 | <field ref="account.cli" name="parent_id"/> | ||
324 | 9 | <field name="type">payable</field> | ||
325 | 10 | <field eval="True" name="reconcile"/> | ||
326 | 11 | <field name="user_type" ref="account.data_account_type_payable"/> | ||
327 | 12 | </record> | ||
328 | 13 | <record id="tax_authority" model="res.partner"> | ||
329 | 14 | <field name="name">Tax authority</field> | ||
330 | 15 | <field eval="1" name="supplier"/> | ||
331 | 16 | </record> | ||
332 | 17 | |||
333 | 18 | </data> | ||
334 | 19 | </openerp> | ||
335 | 0 | 20 | ||
336 | === added file 'l10n_it_withholding_tax/account_view.xml' | |||
337 | --- l10n_it_withholding_tax/account_view.xml 1970-01-01 00:00:00 +0000 | |||
338 | +++ l10n_it_withholding_tax/account_view.xml 2013-05-09 14:32:26 +0000 | |||
339 | @@ -0,0 +1,71 @@ | |||
340 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
341 | 2 | <openerp> | ||
342 | 3 | <data> | ||
343 | 4 | |||
344 | 5 | <!-- company --> | ||
345 | 6 | |||
346 | 7 | <record id="view_account_config_settings" model="ir.ui.view"> | ||
347 | 8 | <field name="name">view_account_config_settings</field> | ||
348 | 9 | <field name="model">account.config.settings</field> | ||
349 | 10 | <field name="inherit_id" ref="account.view_account_config_settings"/> | ||
350 | 11 | <field name="arch" type="xml"> | ||
351 | 12 | <xpath expr="/form/group[6]" position="after"> | ||
352 | 13 | <separator string="Witholding Tax"/> | ||
353 | 14 | <group name="withholding_tax"> | ||
354 | 15 | <label for="id" string="Configuration"/> | ||
355 | 16 | <div> | ||
356 | 17 | <div> | ||
357 | 18 | <label for="withholding_payment_term_id"/> | ||
358 | 19 | <field name="withholding_payment_term_id" class="oe_inline"/> | ||
359 | 20 | </div> | ||
360 | 21 | <div> | ||
361 | 22 | <label for="withholding_account_id"/> | ||
362 | 23 | <field name="withholding_account_id" class="oe_inline"/> | ||
363 | 24 | </div> | ||
364 | 25 | <div> | ||
365 | 26 | <label for="withholding_journal_id"/> | ||
366 | 27 | <field name="withholding_journal_id" class="oe_inline"/> | ||
367 | 28 | </div> | ||
368 | 29 | <div> | ||
369 | 30 | <label for="authority_partner_id"/> | ||
370 | 31 | <field name="authority_partner_id" class="oe_inline"/> | ||
371 | 32 | </div> | ||
372 | 33 | </div> | ||
373 | 34 | </group> | ||
374 | 35 | </xpath> | ||
375 | 36 | </field> | ||
376 | 37 | </record> | ||
377 | 38 | |||
378 | 39 | <!-- invoice --> | ||
379 | 40 | |||
380 | 41 | <record id="invoice_supplier_form" model="ir.ui.view"> | ||
381 | 42 | <field name="name">account.invoice.supplier.form</field> | ||
382 | 43 | <field name="model">account.invoice</field> | ||
383 | 44 | <field name="inherit_id" ref="account.invoice_supplier_form"/> | ||
384 | 45 | <field name="arch" type="xml"> | ||
385 | 46 | <field name="date_due" position="after"> | ||
386 | 47 | <field name="has_withholding"/> | ||
387 | 48 | </field> | ||
388 | 49 | <field name="amount_total" position="after"> | ||
389 | 50 | <field name="withholding_amount" attrs="{'invisible': [('has_withholding', '=', False)]}"/> | ||
390 | 51 | <field name="net_pay" attrs="{'invisible': [('has_withholding', '=', False)]}"/> | ||
391 | 52 | </field> | ||
392 | 53 | </field> | ||
393 | 54 | </record> | ||
394 | 55 | |||
395 | 56 | <!-- voucher --> | ||
396 | 57 | |||
397 | 58 | <record id="view_vendor_payment_form_wh_move" model="ir.ui.view"> | ||
398 | 59 | <field name="name">account.voucher.payment.form.wh.move</field> | ||
399 | 60 | <field name="model">account.voucher</field> | ||
400 | 61 | <field name="inherit_id" ref="account_voucher.view_vendor_payment_form"/> | ||
401 | 62 | <field name="arch" type="xml"> | ||
402 | 63 | <field name="move_ids" position="after"> | ||
403 | 64 | <separator string="Withholding tax entries" colspan="4"></separator> | ||
404 | 65 | <field name="withholding_move_ids" colspan="4" nolabel="1"/> | ||
405 | 66 | </field> | ||
406 | 67 | </field> | ||
407 | 68 | </record> | ||
408 | 69 | |||
409 | 70 | </data> | ||
410 | 71 | </openerp> | ||
411 | 0 | 72 | ||
412 | === added directory 'l10n_it_withholding_tax/i18n' | |||
413 | === added file 'l10n_it_withholding_tax/i18n/it.mo' | |||
414 | 1 | Binary files l10n_it_withholding_tax/i18n/it.mo 1970-01-01 00:00:00 +0000 and l10n_it_withholding_tax/i18n/it.mo 2013-05-09 14:32:26 +0000 differ | 73 | Binary files l10n_it_withholding_tax/i18n/it.mo 1970-01-01 00:00:00 +0000 and l10n_it_withholding_tax/i18n/it.mo 2013-05-09 14:32:26 +0000 differ |
415 | === added file 'l10n_it_withholding_tax/i18n/it.po' | |||
416 | --- l10n_it_withholding_tax/i18n/it.po 1970-01-01 00:00:00 +0000 | |||
417 | +++ l10n_it_withholding_tax/i18n/it.po 2013-05-09 14:32:26 +0000 | |||
418 | @@ -0,0 +1,150 @@ | |||
419 | 1 | # Translation of OpenERP Server. | ||
420 | 2 | # This file contains the translation of the following modules: | ||
421 | 3 | # * l10n_it_withholding_tax | ||
422 | 4 | # | ||
423 | 5 | msgid "" | ||
424 | 6 | msgstr "" | ||
425 | 7 | "Project-Id-Version: OpenERP Server 6.1\n" | ||
426 | 8 | "Report-Msgid-Bugs-To: \n" | ||
427 | 9 | "POT-Creation-Date: 2012-10-12 15:54+0000\n" | ||
428 | 10 | "PO-Revision-Date: 2012-10-12 18:02+0100\n" | ||
429 | 11 | "Last-Translator: Franco Tampieri <info@francotampieri.com>\n" | ||
430 | 12 | "Language-Team: \n" | ||
431 | 13 | "MIME-Version: 1.0\n" | ||
432 | 14 | "Content-Type: text/plain; charset=UTF-8\n" | ||
433 | 15 | "Content-Transfer-Encoding: 8bit\n" | ||
434 | 16 | "Plural-Forms: \n" | ||
435 | 17 | |||
436 | 18 | #. module: l10n_it_withholding_tax | ||
437 | 19 | #: code:addons/l10n_it_withholding_tax/account.py:90 | ||
438 | 20 | #, python-format | ||
439 | 21 | msgid "The company does not have an associated Withholding Payment Term" | ||
440 | 22 | msgstr "L'Azienda non ha associato nessun Termine di pagamento per le Ritenute" | ||
441 | 23 | |||
442 | 24 | #. module: l10n_it_withholding_tax | ||
443 | 25 | #: constraint:res.company:0 | ||
444 | 26 | msgid "Error! You can not create recursive companies." | ||
445 | 27 | msgstr "Errore! Non è possibile creare aziende ricorsive." | ||
446 | 28 | |||
447 | 29 | #. module: l10n_it_withholding_tax | ||
448 | 30 | #: code:addons/l10n_it_withholding_tax/account.py:106 | ||
449 | 31 | #, python-format | ||
450 | 32 | msgid "The payment term %s does not have due dates" | ||
451 | 33 | msgstr "The payment term %s does not have due dates" | ||
452 | 34 | |||
453 | 35 | #. module: l10n_it_withholding_tax | ||
454 | 36 | #: code:addons/l10n_it_withholding_tax/account.py:102 | ||
455 | 37 | #, python-format | ||
456 | 38 | msgid "The payment term %s has too many due dates" | ||
457 | 39 | msgstr "The payment term %s has too many due dates" | ||
458 | 40 | |||
459 | 41 | #. module: l10n_it_withholding_tax | ||
460 | 42 | #: view:account.voucher:0 | ||
461 | 43 | msgid "Withholding tax entries" | ||
462 | 44 | msgstr "Voci Tasse Ritenute" | ||
463 | 45 | |||
464 | 46 | #. module: l10n_it_withholding_tax | ||
465 | 47 | #: field:account.invoice,has_withholding:0 | ||
466 | 48 | msgid "With withholding tax" | ||
467 | 49 | msgstr "Con tasse ritenute" | ||
468 | 50 | |||
469 | 51 | #. module: l10n_it_withholding_tax | ||
470 | 52 | #: field:res.company,withholding_payment_term_id:0 | ||
471 | 53 | msgid "Withholding tax Payment Term" | ||
472 | 54 | msgstr "Termini Pagamento Ritenute" | ||
473 | 55 | |||
474 | 56 | #. module: l10n_it_withholding_tax | ||
475 | 57 | #: field:res.company,withholding_account_id:0 | ||
476 | 58 | msgid "Withholding account" | ||
477 | 59 | msgstr "Conto Ritenute" | ||
478 | 60 | |||
479 | 61 | #. module: l10n_it_withholding_tax | ||
480 | 62 | #: sql_constraint:res.company:0 | ||
481 | 63 | msgid "The company name must be unique !" | ||
482 | 64 | msgstr "Il nome azienda deve essere unico!" | ||
483 | 65 | |||
484 | 66 | #. module: l10n_it_withholding_tax | ||
485 | 67 | #: field:account.invoice,net_pay:0 | ||
486 | 68 | msgid "Net Pay" | ||
487 | 69 | msgstr "Netto da Pagare" | ||
488 | 70 | |||
489 | 71 | #. module: l10n_it_withholding_tax | ||
490 | 72 | #: model:ir.model,name:l10n_it_withholding_tax.model_res_company | ||
491 | 73 | msgid "Companies" | ||
492 | 74 | msgstr "Aziende" | ||
493 | 75 | |||
494 | 76 | #. module: l10n_it_withholding_tax | ||
495 | 77 | #: code:addons/l10n_it_withholding_tax/account.py:92 | ||
496 | 78 | #, python-format | ||
497 | 79 | msgid "The company does not have an associated Withholding journal" | ||
498 | 80 | msgstr "L'Azienda non ha un Sezionale associato per le Ritenute" | ||
499 | 81 | |||
500 | 82 | #. module: l10n_it_withholding_tax | ||
501 | 83 | #: code:addons/l10n_it_withholding_tax/account.py:86 | ||
502 | 84 | #: code:addons/l10n_it_withholding_tax/account.py:88 | ||
503 | 85 | #: code:addons/l10n_it_withholding_tax/account.py:90 | ||
504 | 86 | #: code:addons/l10n_it_withholding_tax/account.py:92 | ||
505 | 87 | #: code:addons/l10n_it_withholding_tax/account.py:101 | ||
506 | 88 | #: code:addons/l10n_it_withholding_tax/account.py:105 | ||
507 | 89 | #, python-format | ||
508 | 90 | msgid "Error" | ||
509 | 91 | msgstr "Errore" | ||
510 | 92 | |||
511 | 93 | #. module: l10n_it_withholding_tax | ||
512 | 94 | #: code:addons/l10n_it_withholding_tax/account.py:86 | ||
513 | 95 | #, python-format | ||
514 | 96 | msgid "Can't handle withholding tax with voucher of type other than payment" | ||
515 | 97 | msgstr "Can't handle withholding tax with voucher of type other than payment" | ||
516 | 98 | |||
517 | 99 | #. module: l10n_it_withholding_tax | ||
518 | 100 | #: help:res.company,withholding_account_id:0 | ||
519 | 101 | msgid "Payable account used for amount due to tax authority" | ||
520 | 102 | msgstr "Payable account used for amount due to tax authority" | ||
521 | 103 | |||
522 | 104 | #. module: l10n_it_withholding_tax | ||
523 | 105 | #: sql_constraint:account.invoice:0 | ||
524 | 106 | msgid "Invoice Number must be unique per Company!" | ||
525 | 107 | msgstr "Nell'azienda il numero fattura dev'essere univoco!" | ||
526 | 108 | |||
527 | 109 | #. module: l10n_it_withholding_tax | ||
528 | 110 | #: help:res.company,withholding_journal_id:0 | ||
529 | 111 | msgid "Journal used for registration of witholding amounts to be paid" | ||
530 | 112 | msgstr "Journal used for registration of witholding amounts to be paid" | ||
531 | 113 | |||
532 | 114 | #. module: l10n_it_withholding_tax | ||
533 | 115 | #: code:addons/l10n_it_withholding_tax/account.py:119 | ||
534 | 116 | #, python-format | ||
535 | 117 | msgid "Payable withholding - " | ||
536 | 118 | msgstr "Ritenute Pagabili - " | ||
537 | 119 | |||
538 | 120 | #. module: l10n_it_withholding_tax | ||
539 | 121 | #: model:ir.model,name:l10n_it_withholding_tax.model_account_voucher | ||
540 | 122 | msgid "Accounting Voucher" | ||
541 | 123 | msgstr "Voucher contabile" | ||
542 | 124 | |||
543 | 125 | #. module: l10n_it_withholding_tax | ||
544 | 126 | #: field:account.invoice,withholding_amount:0 | ||
545 | 127 | msgid "Withholding amount" | ||
546 | 128 | msgstr "Totale Ritenute" | ||
547 | 129 | |||
548 | 130 | #. module: l10n_it_withholding_tax | ||
549 | 131 | #: model:ir.model,name:l10n_it_withholding_tax.model_account_invoice | ||
550 | 132 | msgid "Invoice" | ||
551 | 133 | msgstr "Fattura" | ||
552 | 134 | |||
553 | 135 | #. module: l10n_it_withholding_tax | ||
554 | 136 | #: field:res.company,withholding_journal_id:0 | ||
555 | 137 | msgid "Withholding journal" | ||
556 | 138 | msgstr "Sezionale Ritenute" | ||
557 | 139 | |||
558 | 140 | #. module: l10n_it_withholding_tax | ||
559 | 141 | #: code:addons/l10n_it_withholding_tax/account.py:88 | ||
560 | 142 | #, python-format | ||
561 | 143 | msgid "The company does not have an associated Withholding account" | ||
562 | 144 | msgstr "L'Azienda non ha un conto associato per le Ritenute" | ||
563 | 145 | |||
564 | 146 | #. module: l10n_it_withholding_tax | ||
565 | 147 | #: field:account.voucher,withholding_move_ids:0 | ||
566 | 148 | msgid "Withholding Tax Entries" | ||
567 | 149 | msgstr "Voci Tasse Ritenute" | ||
568 | 150 | |||
569 | 0 | 151 | ||
570 | === added directory 'l10n_it_withholding_tax/test' | |||
571 | === added file 'l10n_it_withholding_tax/test/purchase_payment.yml' | |||
572 | --- l10n_it_withholding_tax/test/purchase_payment.yml 1970-01-01 00:00:00 +0000 | |||
573 | +++ l10n_it_withholding_tax/test/purchase_payment.yml 2013-05-09 14:32:26 +0000 | |||
574 | @@ -0,0 +1,105 @@ | |||
575 | 1 | - | ||
576 | 2 | I configure the main company | ||
577 | 3 | - | ||
578 | 4 | !record {model: res.company, id: base.main_company}: | ||
579 | 5 | withholding_payment_term_id: account.account_payment_term | ||
580 | 6 | withholding_account_id: a_witholding | ||
581 | 7 | withholding_journal_id: account.miscellaneous_journal | ||
582 | 8 | authority_partner_id: tax_authority | ||
583 | 9 | - | ||
584 | 10 | In order to test account invoice I create a new supplier invoice | ||
585 | 11 | - | ||
586 | 12 | I create a Tax Codes | ||
587 | 13 | - | ||
588 | 14 | !record {model: account.tax.code, id: tax_case}: | ||
589 | 15 | name: Tax_case | ||
590 | 16 | company_id: base.main_company | ||
591 | 17 | sign: 1 | ||
592 | 18 | - | ||
593 | 19 | I create a Tax | ||
594 | 20 | - | ||
595 | 21 | !record {model: account.tax, id: tax10}: | ||
596 | 22 | name: Tax 10.0 | ||
597 | 23 | amount: 10.0 | ||
598 | 24 | type: fixed | ||
599 | 25 | sequence: 1 | ||
600 | 26 | company_id: base.main_company | ||
601 | 27 | type_tax_use: all | ||
602 | 28 | tax_code_id: tax_case | ||
603 | 29 | - | ||
604 | 30 | I set the context | ||
605 | 31 | - | ||
606 | 32 | !context | ||
607 | 33 | 'type': 'in_invoice' | ||
608 | 34 | - | ||
609 | 35 | I create a supplier invoice | ||
610 | 36 | - | ||
611 | 37 | !record {model: account.invoice, id: account_invoice_supplier_0, view: invoice_supplier_form}: | ||
612 | 38 | account_id: account.a_pay | ||
613 | 39 | company_id: base.main_company | ||
614 | 40 | currency_id: base.EUR | ||
615 | 41 | invoice_line: | ||
616 | 42 | - account_id: account.a_expense | ||
617 | 43 | name: 'Lawyer service' | ||
618 | 44 | price_unit: 100.0 | ||
619 | 45 | quantity: 1.0 | ||
620 | 46 | invoice_line_tax_id: | ||
621 | 47 | - tax10 | ||
622 | 48 | journal_id: account.expenses_journal | ||
623 | 49 | partner_id: base.res_partner_12 | ||
624 | 50 | has_withholding: True | ||
625 | 51 | withholding_amount: 20.0 | ||
626 | 52 | - | ||
627 | 53 | I check that Initially supplier invoice state is "Draft" | ||
628 | 54 | - | ||
629 | 55 | !assert {model: account.invoice, id: account_invoice_supplier_0}: | ||
630 | 56 | - state == 'draft' | ||
631 | 57 | - | ||
632 | 58 | I change the state of invoice to open by clicking Validate button | ||
633 | 59 | - | ||
634 | 60 | !workflow {model: account.invoice, action: invoice_open, ref: account_invoice_supplier_0} | ||
635 | 61 | - | ||
636 | 62 | I check that the invoice state is now "Open" and 'Net Pay' is 90 | ||
637 | 63 | - | ||
638 | 64 | !assert {model: account.invoice, id: account_invoice_supplier_0}: | ||
639 | 65 | - state == 'open' | ||
640 | 66 | - net_pay == 90.0 | ||
641 | 67 | - | ||
642 | 68 | I create the voucher of payment with 90 | ||
643 | 69 | - | ||
644 | 70 | !record {model: account.voucher, id: account_voucher_0, view: account_voucher.view_vendor_payment_form}: | ||
645 | 71 | account_id: account.cash | ||
646 | 72 | amount: 90.0 | ||
647 | 73 | company_id: base.main_company | ||
648 | 74 | journal_id: account.bank_journal | ||
649 | 75 | name: 'Payment: invoice 0' | ||
650 | 76 | partner_id: base.res_partner_12 | ||
651 | 77 | period_id: account.period_3 | ||
652 | 78 | date: !eval time.strftime("%Y-03-10") | ||
653 | 79 | type: 'payment' | ||
654 | 80 | - | ||
655 | 81 | I check voucher state is draft | ||
656 | 82 | - | ||
657 | 83 | !assert {model: account.voucher, id: account_voucher_0}: | ||
658 | 84 | - state == 'draft' | ||
659 | 85 | - | ||
660 | 86 | I confirm the voucher | ||
661 | 87 | - | ||
662 | 88 | !workflow {model: account.voucher, action: proforma_voucher, ref: account_voucher_0} | ||
663 | 89 | - | ||
664 | 90 | I check the entries | ||
665 | 91 | - | ||
666 | 92 | !python {model: account.voucher}: | | ||
667 | 93 | import time | ||
668 | 94 | voucher = self.browse(cr, uid, ref('account_voucher_0')) | ||
669 | 95 | assert (voucher.state=='posted'), "Voucher is not in posted state: %s" % voucher.state | ||
670 | 96 | assert (len(voucher.withholding_move_ids) == 1), "Withholding entry must be one, not %s" % len(voucher.withholding_move_ids) | ||
671 | 97 | for move_line in voucher.withholding_move_ids[0].line_id: | ||
672 | 98 | if move_line.account_id.id == ref('a_witholding'): | ||
673 | 99 | assert (move_line.credit==20.0), "withholding move line credit must be 20 instead of %s" % move_line.credit | ||
674 | 100 | assert (move_line.date_maturity==time.strftime("%Y-04-30")), "due date must be %s instead of %s" % (time.strftime("%Y-04-30"),move_line.date_maturity) | ||
675 | 101 | - | ||
676 | 102 | Finally i will Confirm the state of the invoice is paid | ||
677 | 103 | - | ||
678 | 104 | !assert {model: account.invoice, id: account_invoice_supplier_0}: | ||
679 | 105 | - state == 'paid' |