2010-03-30 12:47:02 +00:00
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
2010-08-14 03:49:05 +00:00
2010-05-27 10:51:13 +00:00
import time
2010-03-30 12:47:02 +00:00
from osv import fields , osv
from tools . translate import _
import netsvc
class account_invoice_refund ( osv . osv_memory ) :
2010-08-14 05:05:55 +00:00
""" Refunds invoice """
2010-03-30 12:47:02 +00:00
_name = " account.invoice.refund "
_description = " Invoice Refund "
_columns = {
2012-05-09 12:41:39 +00:00
' date ' : fields . date ( ' Operation Date ' , help = ' This date will be used as the invoice date for credit note and period will be chosen accordingly! ' ) ,
2010-05-27 10:51:13 +00:00
' period ' : fields . many2one ( ' account.period ' , ' Force period ' ) ,
2012-05-09 12:41:39 +00:00
' journal_id ' : fields . many2one ( ' account.journal ' , ' Refund Journal ' , help = ' You can select here the journal to use for the credit note that will be created. If you leave that field empty, it will use the same journal as the current invoice. ' ) ,
2010-05-27 10:51:13 +00:00
' description ' : fields . char ( ' Description ' , size = 128 , required = True ) ,
2012-05-09 12:41:39 +00:00
' filter_refund ' : fields . selection ( [ ( ' refund ' , ' Create a draft refund ' ) , ( ' cancel ' , ' Cancel: create credit note and reconcile ' ) , ( ' modify ' , ' Modify: create credit note, reconcile and create a new draft invoice ' ) ] , " Refund Method " , required = True , help = ' Credit note base on this type. You can not Modify and Cancel if the invoice is already reconciled ' ) ,
2010-05-19 10:59:45 +00:00
}
2010-08-14 05:05:55 +00:00
def _get_journal ( self , cr , uid , context = None ) :
obj_journal = self . pool . get ( ' account.journal ' )
2011-06-15 08:51:38 +00:00
user_obj = self . pool . get ( ' res.users ' )
2010-08-14 05:05:55 +00:00
if context is None :
context = { }
2011-06-15 08:51:38 +00:00
inv_type = context . get ( ' type ' , ' out_invoice ' )
company_id = user_obj . browse ( cr , uid , uid , context = context ) . company_id . id
type = ( inv_type == ' out_invoice ' ) and ' sale_refund ' or \
( inv_type == ' out_refund ' ) and ' sale ' or \
( inv_type == ' in_invoice ' ) and ' purchase_refund ' or \
( inv_type == ' in_refund ' ) and ' purchase '
2011-06-20 11:35:32 +00:00
journal = obj_journal . search ( cr , uid , [ ( ' type ' , ' = ' , type ) , ( ' company_id ' , ' = ' , company_id ) ] , limit = 1 , context = context )
2010-08-14 05:05:55 +00:00
return journal and journal [ 0 ] or False
2010-05-19 10:59:45 +00:00
_defaults = {
2010-11-04 12:42:42 +00:00
' date ' : lambda * a : time . strftime ( ' % Y- % m- %d ' ) ,
2010-08-25 06:01:16 +00:00
' journal_id ' : _get_journal ,
2011-03-28 11:23:54 +00:00
' filter_refund ' : ' refund ' ,
2010-08-14 05:05:55 +00:00
}
2010-03-30 12:47:02 +00:00
2010-09-22 11:24:03 +00:00
def fields_view_get ( self , cr , uid , view_id = None , view_type = False , context = None , toolbar = False , submenu = False ) :
2012-06-05 10:50:33 +00:00
if context is None : context = { }
2010-09-22 11:24:03 +00:00
journal_obj = self . pool . get ( ' account.journal ' )
2011-06-15 08:51:38 +00:00
user_obj = self . pool . get ( ' res.users ' )
2011-12-19 14:53:05 +00:00
# remove the entry with key 'form_view_ref', otherwise fields_view_get crashes
context . pop ( ' form_view_ref ' , None )
2010-09-22 11:24:03 +00:00
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 )
2011-06-13 10:35:50 +00:00
type = context . get ( ' type ' , ' out_invoice ' )
2011-06-15 08:51:38 +00:00
company_id = user_obj . browse ( cr , uid , uid , context = context ) . company_id . id
2011-06-13 10:35:50 +00:00
journal_type = ( type == ' out_invoice ' ) and ' sale_refund ' or \
( type == ' out_refund ' ) and ' sale ' or \
( type == ' in_invoice ' ) and ' purchase_refund ' or \
( type == ' in_refund ' ) and ' purchase '
2010-09-22 11:24:03 +00:00
for field in res [ ' fields ' ] :
if field == ' journal_id ' :
2011-06-20 13:01:28 +00:00
journal_select = journal_obj . _name_search ( cr , uid , ' ' , [ ( ' type ' , ' = ' , journal_type ) , ( ' company_id ' , ' child_of ' , [ company_id ] ) ] , context = context )
2010-09-22 11:24:03 +00:00
res [ ' fields ' ] [ field ] [ ' selection ' ] = journal_select
return res
2010-05-27 10:51:13 +00:00
def compute_refund ( self , cr , uid , ids , mode = ' refund ' , context = None ) :
2010-03-30 12:47:02 +00:00
"""
@param cr : the current row , from the database cursor ,
@param uid : the current user ’ s ID for security checks ,
@param ids : the account invoice refund ’ s ID or list of IDs
"""
inv_obj = self . pool . get ( ' account.invoice ' )
reconcile_obj = self . pool . get ( ' account.move.reconcile ' )
account_m_line_obj = self . pool . get ( ' account.move.line ' )
mod_obj = self . pool . get ( ' ir.model.data ' )
act_obj = self . pool . get ( ' ir.actions.act_window ' )
2010-05-17 12:34:26 +00:00
wf_service = netsvc . LocalService ( ' workflow ' )
2010-08-25 06:01:16 +00:00
inv_tax_obj = self . pool . get ( ' account.invoice.tax ' )
inv_line_obj = self . pool . get ( ' account.invoice.line ' )
2010-10-15 13:35:22 +00:00
res_users_obj = self . pool . get ( ' res.users ' )
2010-04-29 06:35:55 +00:00
if context is None :
context = { }
2011-02-15 09:20:57 +00:00
for form in self . browse ( cr , uid , ids , context = context ) :
2010-03-30 12:47:02 +00:00
created_inv = [ ]
date = False
period = False
description = False
2010-12-13 06:43:09 +00:00
company = res_users_obj . browse ( cr , uid , uid , context = context ) . company_id
2011-02-15 09:20:57 +00:00
journal_id = form . journal_id . id
2010-07-09 06:26:26 +00:00
for inv in inv_obj . browse ( cr , uid , context . get ( ' active_ids ' ) , context = context ) :
2010-03-30 12:47:02 +00:00
if inv . state in [ ' draft ' , ' proforma2 ' , ' cancel ' ] :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' Can not %s draft/proforma/cancel invoice. ' ) % ( mode ) )
2010-08-26 03:42:04 +00:00
if inv . reconciled and mode in ( ' cancel ' , ' modify ' ) :
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 ) )
2011-02-15 09:20:57 +00:00
if form . period . id :
period = form . period . id
2010-03-30 12:47:02 +00:00
else :
period = inv . period_id and inv . period_id . id or False
2010-08-25 06:24:27 +00:00
if not journal_id :
journal_id = inv . journal_id . id
2010-08-14 05:05:55 +00:00
2011-02-15 09:20:57 +00:00
if form . date :
date = form . date
if not form . period . id :
2010-03-30 12:47:02 +00:00
cr . execute ( " select name from ir_model_fields \
where model = ' account.period ' \
and name = ' company_id ' " )
result_query = cr . fetchone ( )
if result_query :
2010-07-09 06:28:01 +00:00
cr . execute ( """ select p.id from account_fiscalyear y, account_period p where y.id=p.fiscalyear_id \
2010-07-09 06:26:26 +00:00
and date ( % s ) between p . date_start AND p . date_stop and y . company_id = % s limit 1 """ , (date, company.id,))
2010-03-30 12:47:02 +00:00
else :
cr . execute ( """ SELECT id
2010-05-27 10:01:47 +00:00
from account_period where date ( % s )
2010-03-30 12:47:02 +00:00
between date_start AND date_stop \
2010-05-27 10:01:47 +00:00
limit 1 """ , (date,))
2010-03-30 12:47:02 +00:00
res = cr . fetchone ( )
if res :
period = res [ 0 ]
else :
date = inv . date_invoice
2011-02-15 09:20:57 +00:00
if form . description :
description = form . description
2010-03-30 12:47:02 +00:00
else :
description = inv . name
if not period :
raise osv . except_osv ( _ ( ' Data Insufficient ! ' ) , \
_ ( ' No Period found on Invoice! ' ) )
2010-08-14 05:05:55 +00:00
refund_id = inv_obj . refund ( cr , uid , [ inv . id ] , date , period , description , journal_id )
2010-06-16 11:51:39 +00:00
refund = inv_obj . browse ( cr , uid , refund_id [ 0 ] , context = context )
2010-03-30 12:47:02 +00:00
inv_obj . write ( cr , uid , [ refund . id ] , { ' date_due ' : date ,
' check_total ' : inv . check_total } )
inv_obj . button_compute ( cr , uid , refund_id )
created_inv . append ( refund_id [ 0 ] )
if mode in ( ' cancel ' , ' modify ' ) :
movelines = inv . move_id . line_id
to_reconcile_ids = { }
2010-10-11 06:03:40 +00:00
for line in movelines :
if line . account_id . id == inv . account_id . id :
2010-03-30 12:47:02 +00:00
to_reconcile_ids [ line . account_id . id ] = [ line . id ]
2010-10-11 06:03:40 +00:00
if type ( line . reconcile_id ) != osv . orm . browse_null :
2010-03-30 12:47:02 +00:00
reconcile_obj . unlink ( cr , uid , line . reconcile_id . id )
wf_service . trg_validate ( uid , ' account.invoice ' , \
refund . id , ' invoice_open ' , cr )
2010-06-16 11:51:39 +00:00
refund = inv_obj . browse ( cr , uid , refund_id [ 0 ] , context = context )
2010-10-11 06:03:40 +00:00
for tmpline in refund . move_id . line_id :
if tmpline . account_id . id == inv . account_id . id :
2010-03-30 12:47:02 +00:00
to_reconcile_ids [ tmpline . account_id . id ] . append ( tmpline . id )
2010-10-11 06:03:40 +00:00
for account in to_reconcile_ids :
2010-03-30 12:47:02 +00:00
account_m_line_obj . reconcile ( cr , uid , to_reconcile_ids [ account ] ,
writeoff_period_id = period ,
2010-08-14 05:05:55 +00:00
writeoff_journal_id = inv . journal_id . id ,
2010-03-30 12:47:02 +00:00
writeoff_acc_id = inv . account_id . id
)
2010-05-27 10:51:13 +00:00
if mode == ' modify ' :
2010-03-30 12:47:02 +00:00
invoice = inv_obj . read ( cr , uid , [ inv . id ] ,
[ ' name ' , ' type ' , ' number ' , ' reference ' ,
' comment ' , ' date_due ' , ' partner_id ' ,
' partner_insite ' , ' partner_contact ' ,
' partner_ref ' , ' payment_term ' , ' account_id ' ,
' currency_id ' , ' invoice_line ' , ' tax_line ' ,
2010-06-16 11:51:39 +00:00
' journal_id ' , ' period_id ' ] , context = context )
2010-03-30 12:47:02 +00:00
invoice = invoice [ 0 ]
del invoice [ ' id ' ]
2010-08-25 06:01:16 +00:00
invoice_lines = inv_line_obj . read ( cr , uid , invoice [ ' invoice_line ' ] , context = context )
2010-03-30 12:47:02 +00:00
invoice_lines = inv_obj . _refund_cleanup_lines ( cr , uid , invoice_lines )
2010-08-25 06:01:16 +00:00
tax_lines = inv_tax_obj . read ( cr , uid , invoice [ ' tax_line ' ] , context = context )
2010-03-30 12:47:02 +00:00
tax_lines = inv_obj . _refund_cleanup_lines ( cr , uid , tax_lines )
invoice . update ( {
' type ' : inv . type ,
' date_invoice ' : date ,
' state ' : ' draft ' ,
' number ' : False ,
' invoice_line ' : invoice_lines ,
' tax_line ' : tax_lines ,
' period_id ' : period ,
' name ' : description
2010-07-09 06:26:26 +00:00
} )
2012-03-07 10:42:05 +00:00
for field in ( ' partner_id ' , ' account_id ' , ' currency_id ' ,
' payment_term ' , ' journal_id ' ) :
2010-03-30 12:47:02 +00:00
invoice [ field ] = invoice [ field ] and invoice [ field ] [ 0 ]
inv_id = inv_obj . create ( cr , uid , invoice , { } )
if inv . payment_term . id :
data = inv_obj . onchange_payment_term_date_invoice ( cr , uid , [ inv_id ] , inv . payment_term . id , date )
if ' value ' in data and data [ ' value ' ] :
inv_obj . write ( cr , uid , [ inv_id ] , data [ ' value ' ] )
created_inv . append ( inv_id )
2011-06-15 08:51:38 +00:00
xml_id = ( inv . type == ' out_refund ' ) and ' action_invoice_tree1 ' or \
2011-06-20 06:38:39 +00:00
( inv . type == ' in_refund ' ) and ' action_invoice_tree2 ' or \
2011-06-15 08:51:38 +00:00
( inv . type == ' out_invoice ' ) and ' action_invoice_tree3 ' or \
2011-06-20 06:38:39 +00:00
( inv . type == ' in_invoice ' ) and ' action_invoice_tree4 '
2010-10-28 08:35:00 +00:00
result = mod_obj . get_object_reference ( cr , uid , ' account ' , xml_id )
id = result and result [ 1 ] or False
2010-06-16 11:51:39 +00:00
result = act_obj . read ( cr , uid , id , context = context )
2010-10-19 09:13:05 +00:00
invoice_domain = eval ( result [ ' domain ' ] )
2010-10-25 11:25:40 +00:00
invoice_domain . append ( ( ' id ' , ' in ' , created_inv ) )
2010-10-19 09:13:05 +00:00
result [ ' domain ' ] = invoice_domain
2010-03-30 12:47:02 +00:00
return result
2010-10-25 05:49:21 +00:00
2010-08-14 05:05:55 +00:00
def invoice_refund ( self , cr , uid , ids , context = None ) :
2011-02-15 09:20:57 +00:00
data_refund = self . read ( cr , uid , ids , [ ' filter_refund ' ] , context = context ) [ 0 ] [ ' filter_refund ' ]
2010-08-25 06:01:16 +00:00
return self . compute_refund ( cr , uid , ids , data_refund , context = context )
2010-03-30 12:47:02 +00:00
2010-10-25 11:25:40 +00:00
2010-03-30 12:47:02 +00:00
account_invoice_refund ( )
2011-02-01 21:08:39 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: