2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2006-12-07 13:41:40 +00:00
##############################################################################
2009-10-14 11:15:34 +00:00
#
2009-01-20 08:48:19 +00:00
# OpenERP, Open Source Management Solution
2009-10-14 11:15:34 +00:00
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
2008-11-03 19:18:56 +00:00
#
# This program is free software: you can redistribute it and/or modify
2009-10-14 11:15:34 +00:00
# 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.
2008-11-03 19:18:56 +00:00
#
# 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
2009-10-14 11:15:34 +00:00
# GNU Affero General Public License for more details.
2008-11-03 19:18:56 +00:00
#
2009-10-14 11:15:34 +00:00
# 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/>.
2006-12-07 13:41:40 +00:00
#
##############################################################################
import wizard
import pooler
import time
2008-07-08 08:13:12 +00:00
from tools . translate import _
2006-12-07 13:41:40 +00:00
#
# Create an invoice based on selected timesheet lines
#
#
# TODO: check unit of measure !!!
#
class invoice_create ( wizard . interface ) :
2008-07-22 15:11:28 +00:00
def _get_accounts ( self , cr , uid , data , context ) :
if not len ( data [ ' ids ' ] ) :
return { }
cr . execute ( " SELECT distinct(account_id) from account_analytic_line where id IN ( %s ) " % ( ' , ' . join ( map ( str , data [ ' ids ' ] ) ) , ) )
account_ids = cr . fetchall ( )
return { ' accounts ' : [ x [ 0 ] for x in account_ids ] }
def _do_create ( self , cr , uid , data , context ) :
pool = pooler . get_pool ( cr . dbname )
2009-09-24 10:46:21 +00:00
mod_obj = pool . get ( ' ir.model.data ' )
result = mod_obj . _get_id ( cr , uid , ' account ' , ' view_account_invoice_filter ' )
res = mod_obj . read ( cr , uid , result , [ ' res_id ' ] )
2008-07-22 15:11:28 +00:00
analytic_account_obj = pool . get ( ' account.analytic.account ' )
res_partner_obj = pool . get ( ' res.partner ' )
account_payment_term_obj = pool . get ( ' account.payment.term ' )
account_ids = data [ ' form ' ] [ ' accounts ' ] [ 0 ] [ 2 ]
invoices = [ ]
for account in analytic_account_obj . browse ( cr , uid , account_ids , context ) :
partner = account . partner_id
if ( not partner ) or not ( account . pricelist_id ) :
2009-03-12 06:00:39 +00:00
raise wizard . except_wizard ( _ ( ' Analytic Account incomplete ' ) ,
_ ( ' Please fill in the Associate Partner and Sale Pricelist fields in the Analytic Account: \n %s ' ) % ( account . name , ) )
2008-12-08 17:08:40 +00:00
if not partner . address :
raise wizard . except_wizard ( _ ( ' Partner incomplete ' ) ,
2009-03-12 06:00:39 +00:00
_ ( ' Please fill in the Address field in the Partner: %s . ' ) % ( partner . name , ) )
2008-07-22 15:11:28 +00:00
date_due = False
if partner . property_payment_term :
pterm_list = account_payment_term_obj . compute ( cr , uid ,
partner . property_payment_term . id , value = 1 ,
date_ref = time . strftime ( ' % Y- % m- %d ' ) )
if pterm_list :
pterm_list = [ line [ 0 ] for line in pterm_list ]
pterm_list . sort ( )
date_due = pterm_list [ - 1 ]
curr_invoice = {
' name ' : time . strftime ( ' % D ' ) + ' - ' + account . name ,
' partner_id ' : account . partner_id . id ,
' address_contact_id ' : res_partner_obj . address_get ( cr , uid ,
[ account . partner_id . id ] , adr_pref = [ ' contact ' ] ) [ ' contact ' ] ,
' address_invoice_id ' : res_partner_obj . address_get ( cr , uid ,
[ account . partner_id . id ] , adr_pref = [ ' invoice ' ] ) [ ' invoice ' ] ,
' payment_term ' : partner . property_payment_term . id or False ,
' account_id ' : partner . property_account_receivable . id ,
' currency_id ' : account . pricelist_id . currency_id . id ,
' date_due ' : date_due ,
2009-02-11 13:32:54 +00:00
' fiscal_position ' : account . partner_id . property_account_position . id
2008-07-22 15:11:28 +00:00
}
last_invoice = pool . get ( ' account.invoice ' ) . create ( cr , uid , curr_invoice )
invoices . append ( last_invoice )
context2 = context . copy ( )
context2 [ ' lang ' ] = partner . lang
cr . execute ( " SELECT product_id, to_invoice, sum(unit_amount) " \
" FROM account_analytic_line as line " \
2008-12-10 14:29:55 +00:00
" WHERE account_id = %s " \
2008-07-22 15:11:28 +00:00
" AND id IN ( " + ' , ' . join ( [ str ( x ) for x in data [ ' ids ' ] ] ) + " ) " \
" AND to_invoice IS NOT NULL " \
" GROUP BY product_id,to_invoice " , ( account . id , ) )
2009-09-14 12:00:17 +00:00
2008-07-22 15:11:28 +00:00
for product_id , factor_id , qty in cr . fetchall ( ) :
product = pool . get ( ' product.product ' ) . browse ( cr , uid , product_id , context2 )
if not product :
2009-03-30 13:31:17 +00:00
raise wizard . except_wizard ( _ ( ' Error ' ) , _ ( ' At least one line has no product ! ' ) )
2008-07-22 15:11:28 +00:00
factor_name = ' '
factor = pool . get ( ' hr_timesheet_invoice.factor ' ) . browse ( cr , uid , factor_id , context2 )
2009-09-14 12:00:17 +00:00
if not data [ ' form ' ] [ ' product ' ] :
if factor . customer_name :
factor_name = product . name + ' - ' + factor . customer_name
else :
factor_name = product . name
2008-07-22 15:11:28 +00:00
else :
2009-09-14 12:00:17 +00:00
factor_name = pool . get ( ' product.product ' ) . name_get ( cr , uid , [ data [ ' form ' ] [ ' product ' ] ] , context = context ) [ 0 ] [ 1 ]
2008-07-22 15:11:28 +00:00
if account . pricelist_id :
pl = account . pricelist_id . id
2009-09-14 12:00:17 +00:00
price = pool . get ( ' product.pricelist ' ) . price_get ( cr , uid , [ pl ] , data [ ' form ' ] [ ' product ' ] or product_id , qty or 1.0 , account . partner_id . id ) [ pl ]
2008-07-22 15:11:28 +00:00
else :
price = 0.0
taxes = product . taxes_id
2009-01-20 08:48:19 +00:00
tax = pool . get ( ' account.fiscal.position ' ) . map_tax ( cr , uid , account . partner_id . property_account_position , taxes )
2008-07-22 15:11:28 +00:00
account_id = product . product_tmpl_id . property_account_income . id or product . categ_id . property_account_income_categ . id
curr_line = {
' price_unit ' : price ,
' quantity ' : qty ,
' discount ' : factor . factor ,
' invoice_line_tax_id ' : [ ( 6 , 0 , tax ) ] ,
' invoice_id ' : last_invoice ,
' name ' : factor_name ,
' product_id ' : data [ ' form ' ] [ ' product ' ] or product_id ,
' invoice_line_tax_id ' : [ ( 6 , 0 , tax ) ] ,
' uos_id ' : product . uom_id . id ,
' account_id ' : account_id ,
' account_analytic_id ' : account . id ,
}
2009-09-14 12:00:17 +00:00
2008-07-22 15:11:28 +00:00
#
# Compute for lines
#
2009-11-26 13:54:00 +00:00
cr . execute ( " SELECT * FROM account_analytic_line WHERE account_id = %s and id = ANY ( %s ) AND product_id= %s and to_invoice= %s " , ( account . id , data [ ' ids ' ] , product_id , factor_id ) )
2008-07-22 15:11:28 +00:00
line_ids = cr . dictfetchall ( )
note = [ ]
for line in line_ids :
# set invoice_line_note
details = [ ]
if data [ ' form ' ] [ ' date ' ] :
details . append ( line [ ' date ' ] )
if data [ ' form ' ] [ ' time ' ] :
2008-12-05 00:18:08 +00:00
if line [ ' product_uom_id ' ] :
details . append ( " %s %s " % ( line [ ' unit_amount ' ] , pool . get ( ' product.uom ' ) . browse ( cr , uid , [ line [ ' product_uom_id ' ] ] ) [ 0 ] . name ) )
else :
details . append ( " %s " % ( line [ ' unit_amount ' ] , ) )
2008-07-22 15:11:28 +00:00
if data [ ' form ' ] [ ' name ' ] :
details . append ( line [ ' name ' ] )
#if data['form']['price']:
# details.append(abs(line['amount']))
2009-11-26 13:54:00 +00:00
note . append ( u ' - ' . join ( map ( lambda x : unicode ( x ) or ' ' , details ) ) )
2008-07-22 15:11:28 +00:00
2009-11-26 13:54:00 +00:00
curr_line [ ' note ' ] = " \n " . join ( map ( lambda x : unicode ( x ) or ' ' , note ) )
2008-07-22 15:11:28 +00:00
pool . get ( ' account.invoice.line ' ) . create ( cr , uid , curr_line )
2008-12-10 14:29:55 +00:00
strids = ' , ' . join ( map ( str , data [ ' ids ' ] ) )
cr . execute ( " update account_analytic_line set invoice_id= %% s WHERE account_id = %% s and id IN ( %s ) " % strids , ( last_invoice , account . id , ) )
2009-05-12 06:50:06 +00:00
2009-04-06 13:57:40 +00:00
pool . get ( ' account.invoice ' ) . button_reset_taxes ( cr , uid , [ last_invoice ] , context )
2009-05-12 06:50:06 +00:00
mod_obj = pooler . get_pool ( cr . dbname ) . get ( ' ir.model.data ' )
2009-11-04 06:46:25 +00:00
act_obj = pooler . get_pool ( cr . dbname ) . get ( ' ir.actions.act_window ' )
2009-05-12 06:50:06 +00:00
mod_id = mod_obj . search ( cr , uid , [ ( ' name ' , ' = ' , ' action_invoice_tree1 ' ) ] ) [ 0 ]
res_id = mod_obj . read ( cr , uid , mod_id , [ ' res_id ' ] ) [ ' res_id ' ]
act_win = act_obj . read ( cr , uid , res_id , [ ] )
2009-10-15 14:51:25 +00:00
act_win [ ' domain ' ] = [ ( ' id ' , ' in ' , invoices ) , ( ' type ' , ' = ' , ' out_invoice ' ) ]
2009-05-12 06:50:06 +00:00
act_win [ ' name ' ] = _ ( ' Invoices ' )
return act_win
# return {
# 'domain': "[('id','in', ["+','.join(map(str,invoices))+"])]",
# 'name': _('Invoices'),
# 'view_type': 'form',
# 'view_mode': 'tree,form',
# 'res_model': 'account.invoice',
# 'view_id': False,
# 'context': "{'type':'out_invoice'}",
2009-11-04 06:46:25 +00:00
# 'type': 'ir.actions.act_window',
# 'search_view_id': res['res_id']
2009-05-12 06:50:06 +00:00
# }
2008-07-22 15:11:28 +00:00
_create_form = """ <?xml version= " 1.0 " ?>
2009-09-04 11:31:58 +00:00
< form string = " Invoice on analytic entries " >
2008-10-27 17:23:21 +00:00
< notebook >
< page string = " Invoicing Data " >
< separator string = " Do you want to show details of work in invoice ? " colspan = " 4 " / >
< field name = " date " / >
< field name = " time " / >
< field name = " name " / >
< field name = " price " / >
< separator string = " Force to use a specific product " colspan = " 4 " / >
< field name = " product " / >
< / page >
< page string = " Filter on Accounts " groups = " base.group_extended " >
< separator string = " Choose accounts you want to invoice " colspan = " 4 " / >
< field name = " accounts " colspan = " 4 " nolabel = " 1 " / >
< / page >
< / notebook >
2008-07-22 15:11:28 +00:00
< / form > """
_create_fields = {
' accounts ' : { ' string ' : ' Analytic Accounts ' , ' type ' : ' many2many ' , ' required ' : ' true ' , ' relation ' : ' account.analytic.account ' } ,
2008-10-27 17:23:21 +00:00
' date ' : { ' string ' : ' Date ' , ' type ' : ' boolean ' , ' help ' : ' The real date of each work will be displayed on the invoice ' } ,
' time ' : { ' string ' : ' Time spent ' , ' type ' : ' boolean ' , ' help ' : ' The time of each work done will be displayed on the invoice ' } ,
' name ' : { ' string ' : ' Name of entry ' , ' type ' : ' boolean ' , ' help ' : ' The detail of each work done will be displayed on the invoice ' } ,
' price ' : { ' string ' : ' Cost ' , ' type ' : ' boolean ' , ' help ' : ' The cost of each work done will be displayed on the invoice. You probably don \' t want to check this. ' } ,
' product ' : { ' string ' : ' Product ' , ' type ' : ' many2one ' , ' relation ' : ' product.product ' , ' help ' : " Complete this field only if you want to force to use a specific product. Keep empty to use the real product that comes from the cost. " } ,
2008-07-22 15:11:28 +00:00
}
states = {
' init ' : {
2009-01-20 08:48:19 +00:00
' actions ' : [ _get_accounts ] ,
2009-02-09 11:45:21 +00:00
' result ' : { ' type ' : ' form ' , ' arch ' : _create_form , ' fields ' : _create_fields , ' state ' : [ ( ' end ' , ' Cancel ' ) , ( ' create ' , ' Create Invoices ' ) ] } ,
2008-07-22 15:11:28 +00:00
} ,
' create ' : {
' actions ' : [ ] ,
' result ' : { ' type ' : ' action ' , ' action ' : _do_create , ' state ' : ' end ' } ,
} ,
}
2006-12-07 13:41:40 +00:00
invoice_create ( ' hr.timesheet.invoice.create ' )
2008-07-23 14:41:47 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: