2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2006-12-07 13:41:40 +00:00
##############################################################################
2009-11-26 07:07:14 +00:00
#
2009-01-20 08:48:19 +00:00
# OpenERP, Open Source Management Solution
2010-01-12 09:18:39 +00:00
# Copyright (C) 2004-2010 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
2009-11-26 07:07:14 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2006-12-07 13:41:40 +00:00
#
##############################################################################
import time
2010-04-22 10:34:40 +00:00
from osv import osv , fields
2008-07-08 08:13:12 +00:00
from tools . translate import _
2006-12-07 13:41:40 +00:00
2010-04-22 10:34:40 +00:00
## Create an invoice based on selected timesheet lines
2006-12-07 13:41:40 +00:00
#
#
# TODO: check unit of measure !!!
#
2010-04-22 10:34:40 +00:00
class hr_timesheet_invoice_create ( osv . osv_memory ) :
_name = ' hr.timesheet.invoice.create '
_description = ' Create invoice from timesheet '
_columns = {
' accounts ' : fields . many2many ( ' account.analytic.account ' , ' invoice_id ' , ' account_id ' , ' Analytic Accounts ' , required = True ) ,
' date ' : fields . boolean ( ' Date ' , help = ' The real date of each work will be displayed on the invoice ' ) ,
' time ' : fields . boolean ( ' Time spent ' , help = ' The time of each work done will be displayed on the invoice ' ) ,
' name ' : fields . boolean ( ' Name of entry ' , help = ' The detail of each work done will be displayed on the invoice ' ) ,
' price ' : fields . boolean ( ' Cost ' , help = ' The cost of each work done will be displayed on the invoice. You probably don \' t want to check this ' ) ,
' product ' : fields . many2one ( ' product.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. ' ) ,
}
def _get_accounts ( self , cr , uid , context = None ) :
if context is None :
context = { }
if not len ( context [ ' active_ids ' ] ) :
2008-07-22 15:11:28 +00:00
return { }
2009-12-10 09:40:49 +00:00
#Checking whether the analytic line is invoiced or not
2010-07-27 07:11:45 +00:00
analytic_line_obj = self . pool . get ( ' account.analytic.line ' ) . browse ( cr , uid , context [ ' active_ids ' ] , context = context )
2009-12-10 09:40:49 +00:00
for obj_acc in analytic_line_obj :
if obj_acc . invoice_id and obj_acc . invoice_id . state != ' cancel ' :
2010-04-22 10:34:40 +00:00
raise osv . except_osv ( _ ( ' Warning ' ) , _ ( ' The analytic entry " %s " is already invoiced! ' ) % ( obj_acc . name , ) )
2010-06-10 13:34:19 +00:00
cr . execute ( " SELECT distinct(account_id) from account_analytic_line where id IN %s " , ( tuple ( context [ ' active_ids ' ] ) , ) )
2008-07-22 15:11:28 +00:00
account_ids = cr . fetchall ( )
2010-04-22 10:34:40 +00:00
return [ x [ 0 ] for x in account_ids ]
_defaults = {
' accounts ' : _get_accounts
}
def do_create ( self , cr , uid , ids , context = None ) :
mod_obj = self . pool . get ( ' ir.model.data ' )
analytic_account_obj = self . pool . get ( ' account.analytic.account ' )
res_partner_obj = self . pool . get ( ' res.partner ' )
account_payment_term_obj = self . pool . get ( ' account.payment.term ' )
2010-07-27 07:11:45 +00:00
invoice_obj = self . pool . get ( ' account.invoice ' )
product_obj = self . pool . get ( ' product.product ' )
invoice_factor_obj = self . pool . get ( ' hr_timesheet_invoice.factor ' )
pro_price_obj = self . pool . get ( ' product.pricelist ' )
fiscal_pos_obj = self . pool . get ( ' account.fiscal.position ' )
product_uom_obj = self . pool . get ( ' product.uom ' )
invoice_line_obj = self . pool . get ( ' account.invoice.line ' )
2010-04-22 10:34:40 +00:00
invoices = [ ]
2010-07-27 07:11:45 +00:00
if context is None :
context = { }
2009-09-24 10:46:21 +00:00
result = mod_obj . _get_id ( cr , uid , ' account ' , ' view_account_invoice_filter ' )
2010-07-27 07:11:45 +00:00
res = mod_obj . read ( cr , uid , result , [ ' res_id ' ] , context = context )
data = self . read ( cr , uid , ids , [ ] , context = context ) [ 0 ]
2010-04-22 10:34:40 +00:00
account_ids = data [ ' accounts ' ]
2010-07-27 07:11:45 +00:00
for account in analytic_account_obj . browse ( cr , uid , account_ids , context = context ) :
2008-07-22 15:11:28 +00:00
partner = account . partner_id
if ( not partner ) or not ( account . pricelist_id ) :
2010-04-22 10:34:40 +00:00
raise osv . except_osv ( _ ( ' Analytic Account incomplete ' ) ,
2009-03-12 06:00:39 +00:00
_ ( ' 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 :
2010-04-22 10:34:40 +00:00
raise osv . except_osv ( _ ( ' 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
}
2010-07-27 07:11:45 +00:00
last_invoice = invoice_obj . create ( cr , uid , curr_invoice , context = context )
2008-07-22 15:11:28 +00:00
invoices . append ( last_invoice )
2010-07-01 16:05:16 +00:00
context2 = context . copy ( )
2008-07-22 15:11:28 +00:00
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 " \
2010-06-10 13:34:19 +00:00
" AND id IN %s AND to_invoice IS NOT NULL " \
2010-07-27 07:11:45 +00:00
" GROUP BY product_id,to_invoice " , ( account . id , tuple ( context [ ' active_ids ' ] ) , ) )
2009-09-14 12:00:17 +00:00
2010-07-27 07:11:45 +00:00
for product_id , factor_id , qty in cr . fetchall ( ) :
product = product_obj . browse ( cr , uid , product_id , context2 )
2008-07-22 15:11:28 +00:00
if not product :
2010-04-22 10:34:40 +00:00
raise osv . except_osv ( _ ( ' Error ' ) , _ ( ' At least one line has no product ! ' ) )
2008-07-22 15:11:28 +00:00
factor_name = ' '
2010-07-27 07:11:45 +00:00
factor = invoice_factor_obj . browse ( cr , uid , factor_id , context2 )
2009-11-26 07:07:14 +00:00
2010-04-22 10:34:40 +00:00
if not data [ ' product ' ] :
2009-09-14 12:00:17 +00:00
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 :
2010-07-27 07:11:45 +00:00
factor_name = product_obj . name_get ( cr , uid , [ data [ ' product ' ] ] , context = context ) [ 0 ] [ 1 ]
2009-11-26 07:07:14 +00:00
2008-07-22 15:11:28 +00:00
if account . pricelist_id :
pl = account . pricelist_id . id
2010-07-27 07:11:45 +00:00
price = pro_price_obj . price_get ( cr , uid , [ pl ] , data [ ' 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
2010-07-27 07:11:45 +00:00
tax = fiscal_pos_obj . 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 ,
2010-04-22 10:34:40 +00:00
' product_id ' : data [ ' product ' ] or product_id ,
2008-07-22 15:11:28 +00:00
' invoice_line_tax_id ' : [ ( 6 , 0 , tax ) ] ,
' uos_id ' : product . uom_id . id ,
' account_id ' : account_id ,
' account_analytic_id ' : account . id ,
}
2009-11-26 07:07:14 +00:00
2008-07-22 15:11:28 +00:00
#
# Compute for lines
#
2010-07-01 16:05:16 +00:00
cr . execute ( " SELECT * FROM account_analytic_line WHERE account_id = %s and id IN %s AND product_id= %s and to_invoice= %s ORDER BY account_analytic_line.date " , ( account . id , tuple ( data [ ' ids ' ] ) , product_id , factor_id ) )
2010-02-01 08:29:39 +00:00
2008-07-22 15:11:28 +00:00
line_ids = cr . dictfetchall ( )
note = [ ]
for line in line_ids :
# set invoice_line_note
details = [ ]
2010-04-22 10:34:40 +00:00
if data [ ' date ' ] :
2008-07-22 15:11:28 +00:00
details . append ( line [ ' date ' ] )
2010-04-22 10:34:40 +00:00
if data [ ' time ' ] :
2008-12-05 00:18:08 +00:00
if line [ ' product_uom_id ' ] :
2010-07-27 07:11:45 +00:00
details . append ( " %s %s " % ( line [ ' unit_amount ' ] , product_uom_obj . browse ( cr , uid , [ line [ ' product_uom_id ' ] ] , context2 ) [ 0 ] . name ) )
2008-12-05 00:18:08 +00:00
else :
details . append ( " %s " % ( line [ ' unit_amount ' ] , ) )
2010-04-22 10:34:40 +00:00
if data [ ' name ' ] :
2008-07-22 15:11:28 +00:00
details . append ( line [ ' name ' ] )
2010-04-22 10:34:40 +00:00
#if data['price']:
2008-07-22 15:11:28 +00:00
# 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 ) )
2010-07-27 07:11:45 +00:00
invoice_line_obj . create ( cr , uid , curr_line , context = context )
2010-06-16 11:51:39 +00:00
cr . execute ( " update account_analytic_line set invoice_id= %s WHERE account_id = %s and id IN %s " , ( last_invoice , account . id , tuple ( data [ ' ids ' ] ) ) )
2009-11-26 07:07:14 +00:00
2010-07-27 07:11:45 +00:00
invoice_obj . button_reset_taxes ( cr , uid , [ last_invoice ] , context )
2009-11-26 07:07:14 +00:00
2010-04-22 10:34:40 +00:00
mod_obj = self . pool . get ( ' ir.model.data ' )
act_obj = self . pool . get ( ' ir.actions.act_window ' )
2009-11-04 06:46:25 +00:00
2010-07-27 07:11:45 +00:00
mod_ids = mod_obj . search ( cr , uid , [ ( ' name ' , ' = ' , ' action_invoice_tree1 ' ) ] , context = context ) [ 0 ]
res_id = mod_obj . read ( cr , uid , mod_ids , [ ' res_id ' ] , context = context ) [ ' res_id ' ]
act_win = act_obj . read ( cr , uid , res_id , [ ] , context = context )
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
2009-11-26 07:07:14 +00:00
2009-05-12 06:50:06 +00:00
# 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
2010-04-22 10:34:40 +00:00
hr_timesheet_invoice_create ( )
2008-07-23 14:41:47 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: