Merge lp:~vauxoo/openerp-venezuela-localization/debit-credit-note into lp:~openerp-venezuela/openerp-venezuela-localization/6.0-trunk

Proposed by Javier Duran
Status: Merged
Approved by: Javier Duran
Approved revision: 469
Merge reported by: Javier Duran
Merged at revision: not available
Proposed branch: lp:~vauxoo/openerp-venezuela-localization/debit-credit-note
Merge into: lp:~openerp-venezuela/openerp-venezuela-localization/6.0-trunk
Diff against target: 818 lines (+777/-0)
8 files modified
debit_credit_note/__init__.py (+37/-0)
debit_credit_note/__openerp__.py (+53/-0)
debit_credit_note/account_invoice_view.xml (+90/-0)
debit_credit_note/invoice.py (+49/-0)
debit_credit_note/wizard/__init__.py (+37/-0)
debit_credit_note/wizard/account_invoice_debit.py (+233/-0)
debit_credit_note/wizard/account_invoice_debit_view.xml (+43/-0)
debit_credit_note/wizard/account_invoice_refund.py (+235/-0)
To merge this branch: bzr merge lp:~vauxoo/openerp-venezuela-localization/debit-credit-note
Reviewer Review Type Date Requested Status
Javier Duran (community) Approve
Gabriela Quilarque Needs Fixing
Nhomar - Vauxoo Pending
Review via email: mp+80959@code.launchpad.net

Description of the change

Se agrega modulo que genera notas de debitos y mejora la funcionalidad de notas de debito

To post a comment you must log in.
Revision history for this message
Gabriela Quilarque (gabrielaquilarque97) wrote :

Error arrojado al instentar instalar el modulo en una BD nueva.

[2011-11-01 18:40:19,708][javier_debit_credit2] ERROR:tools.convert.xml_import:Parse error in /home/operador/6_0/server/bin/addons/debit_credit_note/account_invoice_view.xml:55:
<record id="account_inv_ext_form_crdrc" model="ir.ui.view">
            <field name="name">invoice_ext.form.crdrc</field>
            <field name="model">account.invoice</field>
            <field name="type">tree</field>
            <field name="inherit_id" ref="account.invoice_form"/>
            <field name="arch" type="xml">
                <data><xpath expr="/form/group/field[@name='period_id']" position="after">
                    <field name="parent_id" attrs="{'required':[('type','=','out_refund')]}" domain="[('partner_id','=',partner_id),('id', '!=', active_id),('type','in',['out_invoice', 'out_refund'])]"/>
                </xpath>
                <xpath expr="//button[@string='Refund']" position="after">
                    <button name="%(action_account_invoice_debit)d" type="action" string="Debit Note" states="open,paid" icon="gtk-execute" domain="[('type','=','out_invoice')]"/>
                </xpath>
            </data></field>
        </record>
Traceback (most recent call last):
  File "/home/operador/6_0/server/bin/tools/convert.py", line 865, in parse
    self._tags[rec.tag](self.cr, rec, n)
  File "/home/operador/6_0/server/bin/tools/convert.py", line 832, in _tag_record
    id = self.pool.get('ir.model.data')._update(cr, self.uid, rec_model, self.module, res, rec_id or False, not self.isnoupdate(data_node), noupdate=self.isnoupdate(data_node), mode=self.mode, context=rec_context )
  File "/home/operador/6_0/server/bin/addons/base/ir/ir_model.py", line 691, in _update
    res_id = model_obj.create(cr, uid, values, context=context)
  File "/home/operador/6_0/server/bin/osv/orm.py", line 3690, in create
    self._validate(cr, user, [id_new], context)
  File "/home/operador/6_0/server/bin/osv/orm.py", line 946, in _validate
    raise except_orm('ValidateError', '\n'.join(error_msgs))
except_orm: ('ValidateError', u'Error occurred while validating the field(s) arch: Invalid XML for View Architecture!')

review: Needs Fixing
469. By Javier Duran

[IMP] mejoras menores en la vista y el parser del wizard de nota de debito

Revision history for this message
Javier Duran (javieredm) wrote :

Corrección realizada.

review: Needs Resubmitting
Revision history for this message
Gabriela Quilarque (gabrielaquilarque97) wrote :

Se crea un nuevo branch para:
- Unir l10n_ve_fiscal_requirements con debit_credit_note.
- Agregar traducciones del modulo debit_credit_note.
- Corregir el campo parent_id en la vista de factura.
- Agregar seguridad al modulo debit_credit_note.
- Agregar descripción acerca del modulo debit_credit_note en el archivo __openerp__.py del modulo l10n_ve_fiscal_requirements.

branch: https://code.launchpad.net/~vauxoo/openerp-venezuela-localization/gaby-merge-debit-credit-fiscal-requirements

Revision history for this message
Javier Duran (javieredm) wrote :

Merged en el trunk
revno: 474
Revision ID: <email address hidden>

review: Approve

Preview Diff

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