Merge lp:~vauxoo/openerp-venezuela-localization/gaby-merge-debit-credit-fiscal-requirements into lp:~openerp-venezuela/openerp-venezuela-localization/6.0-trunk

Proposed by Gabriela Quilarque
Status: Merged
Merged at revision: 472
Proposed branch: lp:~vauxoo/openerp-venezuela-localization/gaby-merge-debit-credit-fiscal-requirements
Merge into: lp:~openerp-venezuela/openerp-venezuela-localization/6.0-trunk
Diff against target: 814 lines (+730/-0) (has conflicts)
10 files modified
l10n_ve_fiscal_requirements/__init__.py (+1/-0)
l10n_ve_fiscal_requirements/__openerp__.py (+9/-0)
l10n_ve_fiscal_requirements/account_invoice_view.xml (+92/-0)
l10n_ve_fiscal_requirements/i18n/es_VE.po (+112/-0)
l10n_ve_fiscal_requirements/invoice.py (+2/-0)
l10n_ve_fiscal_requirements/security/ir.model.access.csv (+1/-0)
l10n_ve_fiscal_requirements/wizard/__init__.py (+2/-0)
l10n_ve_fiscal_requirements/wizard/account_invoice_debit.py (+233/-0)
l10n_ve_fiscal_requirements/wizard/account_invoice_debit_view.xml (+43/-0)
l10n_ve_fiscal_requirements/wizard/account_invoice_refund.py (+235/-0)
Text conflict in l10n_ve_fiscal_requirements/__openerp__.py
To merge this branch: bzr merge lp:~vauxoo/openerp-venezuela-localization/gaby-merge-debit-credit-fiscal-requirements
Reviewer Review Type Date Requested Status
Nhomar - Vauxoo Pending
Gabriela Quilarque Pending
Review via email: mp+81218@code.launchpad.net

Description of the change

Merge debit_credit_note to l10n_ve_fiscal_requirements:

Improvements:
-Translations.
-Security.
-Update invoice view.
-Update description in __openerp__.py.
-Merge modules.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'l10n_ve_fiscal_requirements/__init__.py'
2--- l10n_ve_fiscal_requirements/__init__.py 2011-10-25 20:33:16 +0000
3+++ l10n_ve_fiscal_requirements/__init__.py 2011-11-03 23:12:26 +0000
4@@ -29,4 +29,5 @@
5 import seniat_url
6 import l10n_ut
7 import wizard
8+
9 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
10
11=== modified file 'l10n_ve_fiscal_requirements/__openerp__.py'
12--- l10n_ve_fiscal_requirements/__openerp__.py 2011-11-03 19:22:42 +0000
13+++ l10n_ve_fiscal_requirements/__openerp__.py 2011-11-03 23:12:26 +0000
14@@ -38,9 +38,16 @@
15 Automatically on install wizard.
16 - Damaged "Legal free forms" declaration.
17 - Tax Units configuration.
18+<<<<<<< TREE
19 - When a partner is updated by using the SENIAT Update Button, its name changes to
20 readonly to avoid manual changes.
21 ---------------------------------------------------------------------------
22+=======
23+ - Added field Parent in the invoice of customers and suppliers, for link the invoice
24+ that generated debit or credit note.
25+ --Added wizard for generate debit note from invoice and done accounting entry.
26+ -------------------------------------------------------------------------------------------
27+>>>>>>> MERGE-SOURCE
28 For damaged invoices (Free form formats), you must go to the company and, under the configuration section,
29 create the corresponding journal and account.
30 TODO : Include this on wizard configuration.
31@@ -69,6 +76,8 @@
32 'wizard/wizard_nro_ctrl_view.xml',
33 'wizard/wizard_url_seniat_view.xml',
34 'wizard/update_info_partner.xml',
35+ 'wizard/account_invoice_debit_view.xml',
36+ 'account_invoice_view.xml',
37 ],
38 'demo_xml': [
39 'demo/demo_partners.xml',
40
41=== added file 'l10n_ve_fiscal_requirements/account_invoice_view.xml'
42--- l10n_ve_fiscal_requirements/account_invoice_view.xml 1970-01-01 00:00:00 +0000
43+++ l10n_ve_fiscal_requirements/account_invoice_view.xml 2011-11-03 23:12:26 +0000
44@@ -0,0 +1,92 @@
45+<?xml version="1.0" encoding="utf-8"?>
46+<openerp>
47+ <data>
48+
49+
50+
51+ <!--
52+ =====================================================
53+ Invoices Extension
54+ =====================================================
55+ -->
56+
57+ <record id="account_inv_ext_view_form_crdr" model="ir.ui.view">
58+ <field name="name">invoice_extended.form.crdr</field>
59+ <field name="model">account.invoice</field>
60+ <field name="type">form</field>
61+ <field name="inherit_id" ref="account.invoice_form"/>
62+ <field name="arch" type="xml">
63+ <notebook>
64+ <page string="Debit-Credit Notes" position="inside">
65+ <field name="child_ids" nolabel="1" widget="many2many" domain="[('partner_id','=',partner_id),('id', '!=', active_id),('type','in',['out_invoice', 'out_refund'])]"/>
66+ </page>
67+ </notebook>
68+ </field>
69+ </record>
70+
71+
72+
73+ <record id="account_inv_ext_view_supp_form_crdr" model="ir.ui.view">
74+ <field name="name">invoice_extended.supplier.form.crdr</field>
75+ <field name="model">account.invoice</field>
76+ <field name="type">form</field>
77+ <field name="inherit_id" ref="account.invoice_supplier_form"/>
78+ <field name="arch" type="xml">
79+ <notebook>
80+ <page string="Debit-Credit Notes" position="inside">
81+ <field name="child_ids" nolabel="1" widget="many2many" domain="[('partner_id','=',partner_id),('id', '!=', active_id),('type','in',['in_invoice', 'in_refund'])]"/>
82+ </page>
83+ </notebook>
84+ </field>
85+ </record>
86+
87+
88+ <record id="account_inv_ext_view_tree_crdr" model="ir.ui.view">
89+ <field name="name">invoice_extended.tree.crdr</field>
90+ <field name="model">account.invoice</field>
91+ <field name="type">tree</field>
92+ <field name="inherit_id" ref="account.invoice_tree"/>
93+ <field name="arch" type="xml">
94+ <xpath expr="/tree/field[@name='origin']" position="after">
95+ <field name="parent_id"/>
96+ </xpath>
97+ </field>
98+ </record>
99+ <record id="account_inv_ext_form_crdrc" model="ir.ui.view">
100+ <field name="name">invoice_ext.form.crdrc</field>
101+ <field name="model">account.invoice</field>
102+ <field name="type">tree</field>
103+ <field name="inherit_id" ref="account.invoice_form"/>
104+ <field name="arch" type="xml">
105+ <xpath expr="/form/group/group" position="after">
106+ <newline/>
107+ <field name="parent_id" attrs="{'required':[('type','=','out_refund')]}" domain="[('partner_id','=',partner_id),('id', '!=', active_id),('type','in',['out_invoice', 'out_refund'])]"/>
108+ </xpath>
109+ <xpath expr="//button[@string='Refund']" position="after">
110+ <button name="%(action_account_invoice_debit)d" type='action' string='Debit Note' states='open,paid' icon="gtk-execute" attrs="{'invisible':[('type','in',['in_refund', 'out_refund'])]}"/>
111+ </xpath>
112+ </field>
113+ </record>
114+ <record id="account_inv_ext_form_crdrs" model="ir.ui.view">
115+ <field name="name">invoice_ext.form.crdrs</field>
116+ <field name="model">account.invoice</field>
117+ <field name="type">tree</field>
118+ <field name="inherit_id" ref="account.invoice_supplier_form"/>
119+ <field name="arch" type="xml">
120+ <xpath expr="/form/group/group" position="after">
121+ <newline/>
122+ <field name="parent_id" attrs="{'required':[('type','=','in_refund')]}" domain="[('partner_id','=',partner_id),('id', '!=', active_id),('type','in',['in_invoice', 'in_refund'])]"/>
123+ </xpath>
124+ <xpath expr="//button[@string='Refund']" position="after">
125+ <button name="%(action_account_invoice_debit)d" type='action' string='Debit Note' states='open,paid' icon="gtk-execute" attrs="{'invisible':[('type','in',['in_refund', 'out_refund'])]}"/>
126+ </xpath>
127+ </field>
128+ </record>
129+
130+
131+
132+
133+
134+
135+ </data>
136+</openerp>
137
138=== modified file 'l10n_ve_fiscal_requirements/i18n/es_VE.po'
139--- l10n_ve_fiscal_requirements/i18n/es_VE.po 2011-11-02 13:13:38 +0000
140+++ l10n_ve_fiscal_requirements/i18n/es_VE.po 2011-11-03 23:12:26 +0000
141@@ -390,3 +390,115 @@
142 msgid "Date on which goes into effect the new Unit Tax Unit"
143 msgstr "Fecha en la cual entra en vigencia la nueva Unidad Tributaria"
144
145+#. module: l10n_ve_fiscal_requirements
146+#: code:addons/l10n_ve_fiscal_requirements/wizard/account_invoice_debit.py:125
147+#, python-format
148+msgid "Can not create a debit note from invoice which is already reconciled, invoice should be unreconciled first. You can only Refund or Debit this invoice"
149+msgstr "Can not create a debit note from invoice which is already reconciled, invoice should be unreconciled first. You can only Refund or Debit this invoice"
150+
151+#. module: l10n_ve_fiscal_requirements
152+#: view:account.invoice:0
153+#: view:account.invoice.debit:0
154+#: model:ir.actions.act_window,name:l10n_ve_fiscal_requirements.action_account_invoice_debit
155+msgid "Debit Note"
156+msgstr "Nota de Debito"
157+
158+#. module: l10n_ve_fiscal_requirements
159+#: field:account.invoice,child_ids:0
160+msgid "Debit and Credit Notes"
161+msgstr "Notas de Débito/Crédito"
162+
163+#. module: l10n_ve_fiscal_requirements
164+#: view:account.invoice.debit:0
165+msgid "Debit Invoice: Creates the debit note invoice, ready for editing."
166+msgstr "Nota de Débito: Crea la nota de dédito lista para ser editada."
167+
168+#. module: l10n_ve_fiscal_requirements
169+#: view:account.invoice.debit:0
170+msgid "Debit Note Options"
171+msgstr "Opciones Nota de Débito"
172+
173+#. module: l10n_ve_fiscal_requirements
174+#: field:account.invoice.debit,comment:0
175+msgid "Comment"
176+msgstr "Comentario"
177+
178+#. module: l10n_ve_fiscal_requirements
179+#: code:addons/l10n_ve_fiscal_requirements/wizard/account_invoice_refund.py:109
180+#, python-format
181+msgid "Can not %s invoice which is already reconciled, invoice should be unreconciled first. You can only Refund this invoice"
182+msgstr "Imposible generar una nota de crédito cuando la factura %s ya esta conciliada, primero debes realizar la desconciliación."
183+
184+#. module: l10n_ve_fiscal_requirements
185+#: model:ir.model,name:l10n_ve_fiscal_requirements.model_account_invoice_debit
186+msgid "Invoice Debit Note"
187+msgstr "Nota de Débito"
188+
189+#. module: l10n_ve_fiscal_requirements
190+#: code:addons/l10n_ve_fiscal_requirements/wizard/account_invoice_debit.py:123
191+#, python-format
192+msgid "Can not create a debit note from draft/proforma/cancel invoice."
193+msgstr "Imposible crear nota de débito desde draft/proforma/cancel invoice."
194+
195+#. module: l10n_ve_fiscal_requirements
196+#: help:account.invoice.debit,journal_id:0
197+msgid "You can select here the journal to use for the refund invoice that will be created. If you leave that field empty, it will use the same journal as the current invoice."
198+msgstr "Puedes seleccionar un diario para la nota de débito que será creada. Si dejas este campo vacio, se usará el diario de la factura actual."
199+
200+#. module: l10n_ve_fiscal_requirements
201+#: code:addons/l10n_ve_fiscal_requirements/wizard/account_invoice_debit.py:168
202+#: code:addons/l10n_ve_fiscal_requirements/wizard/account_invoice_refund.py:148
203+#, python-format
204+msgid "Data Insufficient !"
205+msgstr "Datos Insuficientes !"
206+
207+#. module: l10n_ve_fiscal_requirements
208+#: field:account.invoice.debit,description:0
209+msgid "Description"
210+msgstr "Descripción"
211+
212+#. module: l10n_ve_fiscal_requirements
213+#: help:account.invoice.debit,date:0
214+msgid "This date will be used as the invoice date for Refund Invoice and Period will be chosen accordingly!"
215+msgstr "Puedes definir la fecha que tendrá la Nota de Débito."
216+
217+#. module: l10n_ve_fiscal_requirements
218+#: model:ir.model,name:l10n_ve_fiscal_requirements.model_account_invoice_refund
219+msgid "Invoice Refund"
220+msgstr "Nota de Crédito"
221+
222+#. module: l10n_ve_fiscal_requirements
223+#: view:account.invoice:0
224+msgid "Debit-Credit Notes"
225+msgstr "Notas de Débito/Crédito"
226+
227+#. module: l10n_ve_fiscal_requirements
228+#: help:account.invoice,parent_id:0
229+msgid "When this field has information, this invoice is a credit note or debit note. This field is used to reference to the invoice that originated this credit note or debit note."
230+msgstr "Cuando este campo contiene información, estamos en presencia de una Nota de Crédito o Débito. Es usado para referenciar a la factura desde donde se originó la Nota de Crédito o Débito."
231+
232+#. module: l10n_ve_fiscal_requirements
233+#: code:addons/l10n_ve_fiscal_requirements/wizard/account_invoice_debit.py:127
234+#, python-format
235+msgid "Can not make a debit note on a refund invoice."
236+msgstr "No puedes crear una nota de débito o credito."
237+
238+#. module: l10n_ve_fiscal_requirements
239+#: field:account.invoice,parent_id:0
240+msgid "Parent Invoice"
241+msgstr "Factura Origen"
242+
243+#. module: l10n_ve_fiscal_requirements
244+#: field:account.invoice.debit,date:0
245+msgid "Operation date"
246+msgstr "Fecha operación"
247+
248+#. module: l10n_ve_fiscal_requirements
249+#: field:account.invoice.debit,journal_id:0
250+msgid "Refund Journal"
251+msgstr "Diario Reembolso"
252+
253+#. module: l10n_ve_fiscal_requirements
254+#: field:account.invoice.debit,period:0
255+msgid "Force period"
256+msgstr "Periodo"
257
258=== modified file 'l10n_ve_fiscal_requirements/invoice.py'
259--- l10n_ve_fiscal_requirements/invoice.py 2011-10-25 20:33:16 +0000
260+++ l10n_ve_fiscal_requirements/invoice.py 2011-11-03 23:12:26 +0000
261@@ -31,6 +31,8 @@
262 _columns = {
263 'nro_ctrl': fields.char('Control Number', size=32, readonly=True, states={'draft':[('readonly',False)]}, help="Code used for intern invoice control"),
264 'sin_cred': fields.boolean('Tax-exempt?', readonly=False, help="Set it true if the invoice is V.A.T. exempt"),
265+ 'parent_id':fields.many2one('account.invoice', 'Parent Invoice', readonly=True, states={'draft':[('readonly',False)]}, help='When this field has information, this invoice is a credit note or debit note. This field is used to reference to the invoice that originated this credit note or debit note.'),
266+ 'child_ids':fields.one2many('account.invoice', 'parent_id', 'Debit and Credit Notes', readonly=True, states={'draft':[('readonly',False)]}),
267 }
268 account_invoice()
269
270
271=== modified file 'l10n_ve_fiscal_requirements/security/ir.model.access.csv'
272--- l10n_ve_fiscal_requirements/security/ir.model.access.csv 2011-10-29 15:51:25 +0000
273+++ l10n_ve_fiscal_requirements/security/ir.model.access.csv 2011-11-03 23:12:26 +0000
274@@ -4,3 +4,4 @@
275 "access_account_seniat_url_3","seniat.url","model_seniat_url","account.group_account_manager",1,1,1,1
276 "access_account_seniat_url_4","seniat.url","model_seniat_url","base.group_erp_manager",1,1,1,1
277 "access_account_seniat_url_5","seniat.url","model_seniat_url","base.group_partner_manager",1,0,0,0
278+"access_account_invoice_debit_6","account.invoice.debit","model_account_invoice_debit","base.group_partner_manager",1,0,0,0
279
280=== modified file 'l10n_ve_fiscal_requirements/wizard/__init__.py'
281--- l10n_ve_fiscal_requirements/wizard/__init__.py 2011-10-25 20:33:16 +0000
282+++ l10n_ve_fiscal_requirements/wizard/__init__.py 2011-11-03 23:12:26 +0000
283@@ -27,3 +27,5 @@
284 import wizard_invoice_nro_ctrl
285 import wizard_url_seniat
286 import update_info_partner
287+import account_invoice_refund
288+import account_invoice_debit
289
290=== added file 'l10n_ve_fiscal_requirements/wizard/account_invoice_debit.py'
291--- l10n_ve_fiscal_requirements/wizard/account_invoice_debit.py 1970-01-01 00:00:00 +0000
292+++ l10n_ve_fiscal_requirements/wizard/account_invoice_debit.py 2011-11-03 23:12:26 +0000
293@@ -0,0 +1,233 @@
294+# -*- coding: utf-8 -*-
295+##############################################################################
296+#
297+# OpenERP, Open Source Management Solution
298+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
299+#
300+# This program is free software: you can redistribute it and/or modify
301+# it under the terms of the GNU Affero General Public License as
302+# published by the Free Software Foundation, either version 3 of the
303+# License, or (at your option) any later version.
304+#
305+# This program is distributed in the hope that it will be useful,
306+# but WITHOUT ANY WARRANTY; without even the implied warranty of
307+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
308+# GNU Affero General Public License for more details.
309+#
310+# You should have received a copy of the GNU Affero General Public License
311+# along with this program. If not, see <http://www.gnu.org/licenses/>.
312+#
313+##############################################################################
314+
315+import time
316+
317+from osv import fields, osv
318+from tools.translate import _
319+import netsvc
320+
321+class account_invoice_debit(osv.osv_memory):
322+
323+ """Debits Note from Invoice"""
324+
325+ _name = "account.invoice.debit"
326+ _description = "Invoice Debit Note"
327+ _columns = {
328+ 'date': fields.date('Operation date', help='This date will be used as the invoice date for Refund Invoice and Period will be chosen accordingly!'),
329+ 'period': fields.many2one('account.period', 'Force period'),
330+ 'journal_id': fields.many2one('account.journal', 'Refund Journal', help='You can select here the journal to use for the refund invoice that will be created. If you leave that field empty, it will use the same journal as the current invoice.'),
331+ 'description': fields.char('Description', size=128, required=True),
332+ 'comment': fields.text('Comment', required=True),
333+ }
334+
335+ def _get_journal(self, cr, uid, context=None):
336+ obj_journal = self.pool.get('account.journal')
337+ if context is None:
338+ context = {}
339+ journal = obj_journal.search(cr, uid, [('type', '=', 'sale')])
340+ if context.get('type', False):
341+ if context['type'] in ('in_invoice', 'in_refund'):
342+ journal = obj_journal.search(cr, uid, [('type', '=', 'purchase')])
343+ return journal and journal[0] or False
344+
345+ _defaults = {
346+ 'date': lambda *a: time.strftime('%Y-%m-%d'),
347+ 'journal_id': _get_journal,
348+ 'filter_refund': 'modify',
349+ }
350+
351+ def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
352+ journal_obj = self.pool.get('account.journal')
353+ res = super(account_invoice_debit,self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
354+ #Debit note only from customer o purchase invoice
355+ #type = context.get('journal_type', 'sale_refund')
356+ type = context.get('journal_type', 'sale')
357+ if type in ('sale', 'sale_refund'):
358+ type = 'sale'
359+ else:
360+ type = 'purchase'
361+ for field in res['fields']:
362+ if field == 'journal_id':
363+ journal_select = journal_obj._name_search(cr, uid, '', [('type', '=', type)], context=context, limit=None, name_get_uid=1)
364+ res['fields'][field]['selection'] = journal_select
365+ return res
366+
367+ def _get_period(self, cr, uid, context={}):
368+ """
369+ Return default account period value
370+ """
371+ account_period_obj = self.pool.get('account.period')
372+ ids = account_period_obj.find(cr, uid, context=context)
373+ period_id = False
374+ if ids:
375+ period_id = ids[0]
376+ return period_id
377+
378+ def _get_orig(self, cr, uid, inv, ref, context={}):
379+ """
380+ Return default origin value
381+ """
382+ nro_ref = ref
383+ if inv.type == 'out_invoice':
384+ nro_ref = inv.number
385+ orig = 'FACT:' +(nro_ref or '') + '- DE FECHA:' + (inv.date_invoice or '') + (' TOTAL:' + str(inv.amount_total) or '')
386+ return orig
387+
388+ def compute_debit(self, cr, uid, ids, context=None):
389+ """
390+ @param cr: the current row, from the database cursor,
391+ @param uid: the current user’s ID for security checks,
392+ @param ids: the account invoice refund’s ID or list of IDs
393+
394+ """
395+ inv_obj = self.pool.get('account.invoice')
396+ reconcile_obj = self.pool.get('account.move.reconcile')
397+ account_m_line_obj = self.pool.get('account.move.line')
398+ mod_obj = self.pool.get('ir.model.data')
399+ act_obj = self.pool.get('ir.actions.act_window')
400+ wf_service = netsvc.LocalService('workflow')
401+ inv_tax_obj = self.pool.get('account.invoice.tax')
402+ inv_line_obj = self.pool.get('account.invoice.line')
403+ res_users_obj = self.pool.get('res.users')
404+ if context is None:
405+ context = {}
406+
407+ for form in self.read(cr, uid, ids, context=context):
408+ created_inv = []
409+ date = False
410+ period = False
411+ description = False
412+ company = res_users_obj.browse(cr, uid, uid, context=context).company_id
413+ journal_id = form.get('journal_id', False)
414+ for inv in inv_obj.browse(cr, uid, context.get('active_ids'), context=context):
415+ if inv.state in ['draft', 'proforma2', 'cancel']:
416+ raise osv.except_osv(_('Error !'), _('Can not create a debit note from draft/proforma/cancel invoice.'))
417+ if inv.reconciled and mode in ('cancel', 'modify'):
418+ raise osv.except_osv(_('Error !'), _('Can not create a debit note from invoice which is already reconciled, invoice should be unreconciled first. You can only Refund or Debit this invoice'))
419+ if inv.type not in ['in_invoice', 'out_invoice']:
420+ raise osv.except_osv(_('Error !'), _('Can not make a debit note on a refund invoice.'))
421+ if form['period']:
422+ period = form['period']
423+ else:
424+ #Take period from the current date
425+ #period = inv.period_id and inv.period_id.id or False
426+ period = self._get_period(cr, uid, context)
427+
428+ if not journal_id:
429+ journal_id = inv.journal_id.id
430+
431+ if form['date']:
432+ date = form['date']
433+ if not form['period']:
434+ cr.execute("select name from ir_model_fields \
435+ where model = 'account.period' \
436+ and name = 'company_id'")
437+ result_query = cr.fetchone()
438+ if result_query:
439+ #in multi company mode
440+ cr.execute("""select p.id from account_fiscalyear y, account_period p where y.id=p.fiscalyear_id \
441+ and date(%s) between p.date_start AND p.date_stop and y.company_id = %s limit 1""", (date, company.id,))
442+ else:
443+ #in mono company mode
444+ cr.execute("""SELECT id
445+ from account_period where date(%s)
446+ between date_start AND date_stop \
447+ limit 1 """, (date,))
448+ res = cr.fetchone()
449+ if res:
450+ period = res[0]
451+ else:
452+ #Take current date
453+ #date = inv.date_invoice
454+ date = time.strftime('%Y-%m-%d')
455+ if form['description']:
456+ description = form['description']
457+ else:
458+ description = inv.name
459+
460+ if not period:
461+ raise osv.except_osv(_('Data Insufficient !'), \
462+ _('No Period found on Invoice!'))
463+
464+ #we get original data of invoice to create a new invoice that is the copy of the original
465+ invoice = inv_obj.read(cr, uid, [inv.id],
466+ ['name', 'type', 'number', 'reference',
467+ 'comment', 'date_due', 'partner_id',
468+ 'address_contact_id', 'address_invoice_id',
469+ 'partner_insite', 'partner_contact',
470+ 'partner_ref', 'payment_term', 'account_id',
471+ 'currency_id', 'invoice_line', 'tax_line',
472+ 'journal_id', 'period_id'], context=context)
473+ invoice = invoice[0]
474+ del invoice['id']
475+ invoice_lines = []
476+ tax_lines = []
477+ #Add origin, parent and comment values
478+ orig = self._get_orig(cr, uid, inv, invoice['reference'], context)
479+ invoice.update({
480+ 'type': inv.type,
481+ 'date_invoice': date,
482+ 'state': 'draft',
483+ 'number': False,
484+ 'invoice_line': invoice_lines,
485+ 'tax_line': tax_lines,
486+ 'period_id': period,
487+ 'parent_id':inv.id,
488+ 'name': description,
489+ 'origin': orig,
490+ 'comment':form['comment']
491+ })
492+ #take the id part of the tuple returned for many2one fields
493+ for field in ('address_contact_id', 'address_invoice_id', 'partner_id',
494+ 'account_id', 'currency_id', 'payment_term', 'journal_id'):
495+ invoice[field] = invoice[field] and invoice[field][0]
496+ # create the new invoice
497+ inv_id = inv_obj.create(cr, uid, invoice, {})
498+ # we compute due date
499+ if inv.payment_term.id:
500+ data = inv_obj.onchange_payment_term_date_invoice(cr, uid, [inv_id], inv.payment_term.id, date)
501+ if 'value' in data and data['value']:
502+ inv_obj.write(cr, uid, [inv_id], data['value'])
503+ created_inv.append(inv_id)
504+ #we get the view id
505+ if inv.type in ('out_invoice', 'out_refund'):
506+ xml_id = 'action_invoice_tree1'
507+ else:
508+ xml_id = 'action_invoice_tree2'
509+ #we get the model
510+ result = mod_obj.get_object_reference(cr, uid, 'account', xml_id)
511+ id = result and result[1] or False
512+ # we read the act window
513+ result = act_obj.read(cr, uid, id, context=context)
514+ # we add the new invoices into domain list
515+ invoice_domain = eval(result['domain'])
516+ invoice_domain.append(('id', 'in', created_inv))
517+ result['domain'] = invoice_domain
518+ return result
519+
520+ def invoice_debit(self, cr, uid, ids, context=None):
521+ return self.compute_debit(cr, uid, ids, context=context)
522+
523+
524+account_invoice_debit()
525+
526+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
527
528=== added file 'l10n_ve_fiscal_requirements/wizard/account_invoice_debit_view.xml'
529--- l10n_ve_fiscal_requirements/wizard/account_invoice_debit_view.xml 1970-01-01 00:00:00 +0000
530+++ l10n_ve_fiscal_requirements/wizard/account_invoice_debit_view.xml 2011-11-03 23:12:26 +0000
531@@ -0,0 +1,43 @@
532+<?xml version="1.0" encoding="utf-8"?>
533+<openerp>
534+ <data>
535+
536+ <record id="view_account_invoice_debit" model="ir.ui.view">
537+ <field name="name">account.invoice.debit.form</field>
538+ <field name="model">account.invoice.debit</field>
539+ <field name="type">form</field>
540+ <field name="arch" type="xml">
541+ <form string="Debit Note">
542+ <separator string="Debit Note Options" colspan="4"/>
543+ <group colspan="4" >
544+ <field name="description"/>
545+ <field name="journal_id" widget='selection'/>
546+ <field name="date"/>
547+ <field name="period"/>
548+ <field name="comment" colspan="4"/>
549+ </group>
550+ <separator colspan="4"/>
551+ <group col="4" colspan="4" fill="1">
552+ <label align="0.0" width="300" string="Debit Invoice: Creates the debit note invoice, ready for editing."/>
553+ </group>
554+ <separator colspan="4"/>
555+ <group colspan="4" col="6">
556+ <button icon="gtk-cancel" special="cancel" string="Cancel"/>
557+ <button string='Debit Note' icon="gtk-execute" name="invoice_debit" type="object"/>
558+ </group>
559+ </form>
560+ </field>
561+ </record>
562+
563+ <record id="action_account_invoice_debit" model="ir.actions.act_window">
564+ <field name="name">Debit Note</field>
565+ <field name="res_model">account.invoice.debit</field>
566+ <field name="view_type">form</field>
567+ <field name="view_mode">tree,form</field>
568+ <field name="view_id" ref="view_account_invoice_debit"/>
569+ <field name="target">new</field>
570+ </record>
571+
572+
573+ </data>
574+</openerp>
575
576=== added file 'l10n_ve_fiscal_requirements/wizard/account_invoice_refund.py'
577--- l10n_ve_fiscal_requirements/wizard/account_invoice_refund.py 1970-01-01 00:00:00 +0000
578+++ l10n_ve_fiscal_requirements/wizard/account_invoice_refund.py 2011-11-03 23:12:26 +0000
579@@ -0,0 +1,235 @@
580+# -*- coding: utf-8 -*-
581+##############################################################################
582+#
583+# OpenERP, Open Source Management Solution
584+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
585+#
586+# This program is free software: you can redistribute it and/or modify
587+# it under the terms of the GNU Affero General Public License as
588+# published by the Free Software Foundation, either version 3 of the
589+# License, or (at your option) any later version.
590+#
591+# This program is distributed in the hope that it will be useful,
592+# but WITHOUT ANY WARRANTY; without even the implied warranty of
593+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
594+# GNU Affero General Public License for more details.
595+#
596+# You should have received a copy of the GNU Affero General Public License
597+# along with this program. If not, see <http://www.gnu.org/licenses/>.
598+#
599+##############################################################################
600+
601+import time
602+
603+from osv import fields, osv
604+from tools.translate import _
605+import netsvc
606+
607+class account_invoice_refund(osv.osv_memory):
608+
609+ """Refunds invoice"""
610+ _inherit = 'account.invoice.refund'
611+
612+ def _get_journal(self, cr, uid, context=None):
613+ obj_journal = self.pool.get('account.journal')
614+ if context is None:
615+ context = {}
616+ journal = obj_journal.search(cr, uid, [('type', '=', 'sale_refund')])
617+ if context.get('type', False):
618+ if context['type'] in ('in_invoice', 'in_refund'):
619+ journal = obj_journal.search(cr, uid, [('type', '=', 'purchase_refund')])
620+ return journal and journal[0] or False
621+
622+
623+ def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
624+ journal_obj = self.pool.get('account.journal')
625+ res = super(account_invoice_refund,self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
626+ type = context.get('journal_type', 'sale_refund')
627+ if type in ('sale', 'sale_refund'):
628+ type = 'sale_refund'
629+ else:
630+ type = 'purchase_refund'
631+ for field in res['fields']:
632+ if field == 'journal_id':
633+ journal_select = journal_obj._name_search(cr, uid, '', [('type', '=', type)], context=context, limit=None, name_get_uid=1)
634+ res['fields'][field]['selection'] = journal_select
635+ return res
636+
637+ def _get_period(self, cr, uid, context={}):
638+ """
639+ Return default account period value
640+ """
641+ account_period_obj = self.pool.get('account.period')
642+ ids = account_period_obj.find(cr, uid, context=context)
643+ period_id = False
644+ if ids:
645+ period_id = ids[0]
646+ return period_id
647+
648+ def _get_orig(self, cr, uid, inv, ref, context={}):
649+ """
650+ Return default origin value
651+ """
652+ nro_ref = ref
653+ if inv.type == 'out_invoice':
654+ nro_ref = inv.number
655+ orig = 'Devolucion FACT:' +(nro_ref or '') + '- DE FECHA:' + (inv.date_invoice or '') + (' TOTAL:' + str(inv.amount_total) or '')
656+ return orig
657+
658+ def compute_refund(self, cr, uid, ids, mode='refund', context=None):
659+ """
660+ @param cr: the current row, from the database cursor,
661+ @param uid: the current user’s ID for security checks,
662+ @param ids: the account invoice refund’s ID or list of IDs
663+
664+ """
665+ inv_obj = self.pool.get('account.invoice')
666+ reconcile_obj = self.pool.get('account.move.reconcile')
667+ account_m_line_obj = self.pool.get('account.move.line')
668+ mod_obj = self.pool.get('ir.model.data')
669+ act_obj = self.pool.get('ir.actions.act_window')
670+ wf_service = netsvc.LocalService('workflow')
671+ inv_tax_obj = self.pool.get('account.invoice.tax')
672+ inv_line_obj = self.pool.get('account.invoice.line')
673+ res_users_obj = self.pool.get('res.users')
674+ if context is None:
675+ context = {}
676+
677+ for form in self.read(cr, uid, ids, context=context):
678+ created_inv = []
679+ date = False
680+ period = False
681+ description = False
682+ company = res_users_obj.browse(cr, uid, uid, context=context).company_id
683+ journal_id = form.get('journal_id', False)
684+ for inv in inv_obj.browse(cr, uid, context.get('active_ids'), context=context):
685+ if inv.state in ['draft', 'proforma2', 'cancel']:
686+ raise osv.except_osv(_('Error !'), _('Can not %s draft/proforma/cancel invoice.') % (mode))
687+ if inv.reconciled and mode in ('cancel', 'modify'):
688+ raise osv.except_osv(_('Error !'), _('Can not %s invoice which is already reconciled, invoice should be unreconciled first. You can only Refund this invoice') % (mode))
689+ if form['period']:
690+ period = form['period']
691+ else:
692+ #Take period from the current date
693+ #period = inv.period_id and inv.period_id.id or False
694+ period = self._get_period(cr, uid, context)
695+
696+ if not journal_id:
697+ journal_id = inv.journal_id.id
698+
699+ if form['date']:
700+ date = form['date']
701+ if not form['period']:
702+ cr.execute("select name from ir_model_fields \
703+ where model = 'account.period' \
704+ and name = 'company_id'")
705+ result_query = cr.fetchone()
706+ if result_query:
707+ cr.execute("""select p.id from account_fiscalyear y, account_period p where y.id=p.fiscalyear_id \
708+ and date(%s) between p.date_start AND p.date_stop and y.company_id = %s limit 1""", (date, company.id,))
709+ else:
710+ cr.execute("""SELECT id
711+ from account_period where date(%s)
712+ between date_start AND date_stop \
713+ limit 1 """, (date,))
714+ res = cr.fetchone()
715+ if res:
716+ period = res[0]
717+ else:
718+ #Take current date
719+ #date = inv.date_invoice
720+ date = time.strftime('%Y-%m-%d')
721+ if form['description']:
722+ description = form['description']
723+ else:
724+ description = inv.name
725+
726+ if not period:
727+ raise osv.except_osv(_('Data Insufficient !'), \
728+ _('No Period found on Invoice!'))
729+
730+ refund_id = inv_obj.refund(cr, uid, [inv.id], date, period, description, journal_id)
731+ refund = inv_obj.browse(cr, uid, refund_id[0], context=context)
732+ #Add parent invoice
733+ inv_obj.write(cr, uid, [refund.id], {'date_due': date,
734+ 'check_total': inv.check_total,'parent_id':inv.id})
735+ inv_obj.button_compute(cr, uid, refund_id)
736+
737+ created_inv.append(refund_id[0])
738+ if mode in ('cancel', 'modify'):
739+ movelines = inv.move_id.line_id
740+ to_reconcile_ids = {}
741+ for line in movelines:
742+ if line.account_id.id == inv.account_id.id:
743+ to_reconcile_ids[line.account_id.id] = [line.id]
744+ if type(line.reconcile_id) != osv.orm.browse_null:
745+ reconcile_obj.unlink(cr, uid, line.reconcile_id.id)
746+ wf_service.trg_validate(uid, 'account.invoice', \
747+ refund.id, 'invoice_open', cr)
748+ refund = inv_obj.browse(cr, uid, refund_id[0], context=context)
749+ for tmpline in refund.move_id.line_id:
750+ if tmpline.account_id.id == inv.account_id.id:
751+ to_reconcile_ids[tmpline.account_id.id].append(tmpline.id)
752+ for account in to_reconcile_ids:
753+ account_m_line_obj.reconcile(cr, uid, to_reconcile_ids[account],
754+ writeoff_period_id=period,
755+ writeoff_journal_id = inv.journal_id.id,
756+ writeoff_acc_id=inv.account_id.id
757+ )
758+ if mode == 'modify':
759+ invoice = inv_obj.read(cr, uid, [inv.id],
760+ ['name', 'type', 'number', 'reference',
761+ 'comment', 'date_due', 'partner_id',
762+ 'address_contact_id', 'address_invoice_id',
763+ 'partner_insite', 'partner_contact',
764+ 'partner_ref', 'payment_term', 'account_id',
765+ 'currency_id', 'invoice_line', 'tax_line',
766+ 'journal_id', 'period_id'], context=context)
767+ invoice = invoice[0]
768+ del invoice['id']
769+ invoice_lines = inv_line_obj.read(cr, uid, invoice['invoice_line'], context=context)
770+ invoice_lines = inv_obj._refund_cleanup_lines(cr, uid, invoice_lines)
771+ tax_lines = inv_tax_obj.read(cr, uid, invoice['tax_line'], context=context)
772+ tax_lines = inv_obj._refund_cleanup_lines(cr, uid, tax_lines)
773+ #Add origin value
774+ orig = self._get_orig(cr, uid, inv, invoice['reference'], context)
775+ invoice.update({
776+ 'type': inv.type,
777+ 'date_invoice': date,
778+ 'state': 'draft',
779+ 'number': False,
780+ 'invoice_line': invoice_lines,
781+ 'tax_line': tax_lines,
782+ 'period_id': period,
783+ 'name': description,
784+ 'origin': orig,
785+ })
786+ for field in ('address_contact_id', 'address_invoice_id', 'partner_id',
787+ 'account_id', 'currency_id', 'payment_term', 'journal_id'):
788+ invoice[field] = invoice[field] and invoice[field][0]
789+ inv_id = inv_obj.create(cr, uid, invoice, {})
790+ if inv.payment_term.id:
791+ data = inv_obj.onchange_payment_term_date_invoice(cr, uid, [inv_id], inv.payment_term.id, date)
792+ if 'value' in data and data['value']:
793+ inv_obj.write(cr, uid, [inv_id], data['value'])
794+ created_inv.append(inv_id)
795+ if inv.type in ('out_invoice', 'out_refund'):
796+ xml_id = 'action_invoice_tree3'
797+ else:
798+ xml_id = 'action_invoice_tree4'
799+ result = mod_obj.get_object_reference(cr, uid, 'account', xml_id)
800+ id = result and result[1] or False
801+ result = act_obj.read(cr, uid, id, context=context)
802+ invoice_domain = eval(result['domain'])
803+ invoice_domain.append(('id', 'in', created_inv))
804+ result['domain'] = invoice_domain
805+ return result
806+
807+ def invoice_refund(self, cr, uid, ids, context=None):
808+ data_refund = self.read(cr, uid, ids, [],context=context)[0]['filter_refund']
809+ return self.compute_refund(cr, uid, ids, data_refund, context=context)
810+
811+
812+account_invoice_refund()
813+
814+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: