2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2006-12-07 13:41:40 +00:00
##############################################################################
2010-07-27 07:11:45 +00:00
#
2009-10-14 11:15:34 +00:00
# OpenERP, Open Source Management Solution
2010-01-12 09:18:39 +00:00
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2006-12-07 13:41:40 +00:00
#
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.
2006-12-07 13:41:40 +00:00
#
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.
2006-12-07 13:41:40 +00:00
#
2009-10-14 11:15:34 +00:00
# You should have received a copy of the GNU Affero General Public License
2010-07-27 07:11:45 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2006-12-07 13:41:40 +00:00
#
##############################################################################
from osv import fields , osv
2008-07-08 08:13:12 +00:00
from tools . translate import _
2007-09-11 14:14:18 +00:00
2006-12-07 13:41:40 +00:00
class hr_timesheet_invoice_factor ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_name = " hr_timesheet_invoice.factor "
2010-05-19 18:32:32 +00:00
_description = " Invoice Rate "
2008-07-22 15:11:28 +00:00
_columns = {
2010-10-17 16:42:26 +00:00
' name ' : fields . char ( ' Internal name ' , size = 128 , required = True , translate = True ) ,
' customer_name ' : fields . char ( ' Name ' , size = 128 , help = " Label for the customer " ) ,
2010-08-19 09:38:02 +00:00
' factor ' : fields . float ( ' Discount ( % ) ' , required = True , help = " Discount in percentage " ) ,
2008-07-22 15:11:28 +00:00
}
_defaults = {
' factor ' : lambda * a : 0.0 ,
}
2007-09-11 14:14:18 +00:00
2006-12-07 13:41:40 +00:00
hr_timesheet_invoice_factor ( )
2007-09-11 14:14:18 +00:00
2006-12-07 13:41:40 +00:00
class account_analytic_account ( osv . osv ) :
2010-07-27 07:11:45 +00:00
def _invoiced_calc ( self , cr , uid , ids , name , arg , context = None ) :
obj_invoice = self . pool . get ( ' account.invoice ' )
2008-07-22 15:11:28 +00:00
res = { }
2010-09-23 14:23:34 +00:00
2010-10-17 17:30:00 +00:00
cr . execute ( ' SELECT account_id as account_id, l.invoice_id '
' FROM hr_analytic_timesheet h LEFT JOIN account_analytic_line l '
' ON (h.line_id=l.id) '
' WHERE l.account_id = ANY( %s ) ' , ( ids , ) )
2010-09-23 14:23:34 +00:00
account_to_invoice_map = { }
for rec in cr . dictfetchall ( ) :
account_to_invoice_map . setdefault ( rec [ ' account_id ' ] , [ ] ) . append ( rec [ ' invoice_id ' ] )
2010-07-27 07:11:45 +00:00
for account in self . browse ( cr , uid , ids , context = context ) :
2010-09-23 14:23:34 +00:00
invoice_ids = filter ( None , list ( set ( account_to_invoice_map . get ( account . id , [ ] ) ) ) )
2010-07-27 07:11:45 +00:00
for invoice in obj_invoice . browse ( cr , uid , invoice_ids , context = context ) :
2008-07-22 15:11:28 +00:00
res . setdefault ( account . id , 0.0 )
res [ account . id ] + = invoice . amount_untaxed
for id in ids :
res [ id ] = round ( res . get ( id , 0.0 ) , 2 )
2010-09-23 14:23:34 +00:00
return res
2009-12-17 15:12:33 +00:00
2008-07-22 15:11:28 +00:00
_inherit = " account.analytic.account "
_columns = {
2012-05-30 13:34:36 +00:00
' pricelist_id ' : fields . many2one ( ' product.pricelist ' , ' Pricelist ' ,
2012-07-13 10:17:51 +00:00
help = " The product to invoice is defined on the employee form, the price will be deducted by this pricelist on the product. " ) ,
2011-12-18 19:36:38 +00:00
' amount_max ' : fields . float ( ' Max. Invoice Price ' ,
help = " Keep empty if this contract is not limited to a total fixed price. " ) ,
2011-07-01 23:41:24 +00:00
' amount_invoiced ' : fields . function ( _invoiced_calc , string = ' Invoiced Amount ' ,
2008-10-27 15:29:13 +00:00
help = " Total invoiced " ) ,
2012-06-25 15:55:40 +00:00
' to_invoice ' : fields . many2one ( ' hr_timesheet_invoice.factor ' , ' Timesheet Invoicing Ratio ' ,
2012-10-28 10:33:28 +00:00
help = " You usually invoice 100 % o f the timesheets. But if you mix fixed price and timesheet invoicing, you may use another ratio. For instance, if you do a 20 % a dvance invoice (fixed price, based on a sale order), you should invoice the rest on timesheet with a 80 % r atio. " ) ,
2008-10-27 15:29:13 +00:00
}
_defaults = {
2010-06-16 11:51:39 +00:00
' pricelist_id ' : lambda self , cr , uid , ctx : ctx . get ( ' pricelist_id ' , False ) ,
2008-07-22 15:11:28 +00:00
}
2012-06-15 08:12:54 +00:00
def on_change_use_timesheets ( self , cr , uid , ids , use_timesheets , context = None ) :
res = { ' value ' : { } }
if use_timesheets :
ir_model_obj = self . pool . get ( ' ir.model.data ' )
2012-06-15 09:12:15 +00:00
res [ ' value ' ] [ ' to_invoice ' ] = ir_model_obj . get_object_reference ( cr , uid , ' hr_timesheet_invoice ' , ' timesheet_invoice_factor1 ' ) [ 1 ]
2012-06-15 08:12:54 +00:00
return res
2012-06-15 09:12:15 +00:00
2012-10-02 10:29:15 +00:00
def on_change_partner_id ( self , cr , uid , ids , partner_id , name , context = None ) :
2012-09-19 13:39:50 +00:00
res = super ( account_analytic_account , self ) . on_change_partner_id ( cr , uid , ids , partner_id , name , context = context )
2012-06-15 13:10:56 +00:00
part = self . pool . get ( ' res.partner ' ) . browse ( cr , uid , partner_id , context = context )
2011-11-16 14:59:58 +00:00
pricelist = part . property_product_pricelist and part . property_product_pricelist . id or False
if pricelist :
res [ ' value ' ] [ ' pricelist_id ' ] = pricelist
return res
2010-12-22 11:05:57 +00:00
def set_close ( self , cr , uid , ids , context = None ) :
2012-09-19 13:39:50 +00:00
self . write ( cr , uid , ids , { ' state ' : ' close ' } , context = context )
2012-06-25 15:55:40 +00:00
message = _ ( " Contract has been <b>closed</b>. " )
2012-10-16 13:20:12 +00:00
self . message_post ( cr , uid , ids , body = message , subtype = " hr_timesheet_invoice.mt_account_closed " , context = context )
2012-06-22 09:10:08 +00:00
return True
2012-03-30 09:51:17 +00:00
2010-12-22 11:05:57 +00:00
def set_cancel ( self , cr , uid , ids , context = None ) :
2012-09-19 13:39:50 +00:00
self . write ( cr , uid , ids , { ' state ' : ' cancelled ' } , context = context )
message = _ ( " Contract has been <b>canceled</b>. " )
2012-10-16 13:20:12 +00:00
self . message_post ( cr , uid , ids , body = message , subtype = " hr_timesheet_invoice.mt_account_canceled " , context = context )
2012-06-22 09:10:08 +00:00
return True
2012-03-30 09:51:17 +00:00
2010-12-22 11:05:57 +00:00
def set_open ( self , cr , uid , ids , context = None ) :
2012-09-19 13:39:50 +00:00
self . write ( cr , uid , ids , { ' state ' : ' open ' } , context = context )
2012-06-25 15:55:40 +00:00
message = _ ( " Contract has been <b>opened</b>. " )
2012-08-17 10:03:02 +00:00
self . message_post ( cr , uid , ids , body = message , context = context )
2012-06-22 09:10:08 +00:00
return True
2012-03-30 09:51:17 +00:00
2010-12-22 11:05:57 +00:00
def set_pending ( self , cr , uid , ids , context = None ) :
2012-09-19 13:39:50 +00:00
self . write ( cr , uid , ids , { ' state ' : ' pending ' } , context = context )
2012-06-25 15:55:40 +00:00
message = _ ( " Contract has been set as <b>pending</b>. " )
2012-08-17 10:03:02 +00:00
self . message_post ( cr , uid , ids , body = message , context = context )
2012-06-22 09:10:08 +00:00
return True
2010-12-22 12:55:49 +00:00
2006-12-07 13:41:40 +00:00
account_analytic_account ( )
2007-09-11 14:14:18 +00:00
2006-12-07 13:41:40 +00:00
class account_analytic_line ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_inherit = ' account.analytic.line '
_columns = {
2010-07-27 07:11:45 +00:00
' invoice_id ' : fields . many2one ( ' account.invoice ' , ' Invoice ' , ondelete = " set null " ) ,
2010-09-14 10:59:42 +00:00
' to_invoice ' : fields . many2one ( ' hr_timesheet_invoice.factor ' , ' Type of Invoicing ' , help = " It allows to set the discount while making invoice " ) ,
2008-07-22 15:11:28 +00:00
}
2012-07-31 10:54:02 +00:00
def _default_journal ( self , cr , uid , context = None ) :
proxy = self . pool . get ( ' hr.employee ' )
record_ids = proxy . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] , context = context )
2012-10-09 11:59:28 +00:00
if record_ids :
employee = proxy . browse ( cr , uid , record_ids [ 0 ] , context = context )
return employee . journal_id and employee . journal_id . id or False
return False
2012-07-31 10:54:02 +00:00
def _default_general_account ( self , cr , uid , context = None ) :
proxy = self . pool . get ( ' hr.employee ' )
record_ids = proxy . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] , context = context )
2012-10-09 11:59:28 +00:00
if record_ids :
employee = proxy . browse ( cr , uid , record_ids [ 0 ] , context = context )
if employee . product_id and employee . product_id . property_account_income :
return employee . product_id . property_account_income . id
2012-07-31 10:54:02 +00:00
return False
_defaults = {
' journal_id ' : _default_journal ,
' general_account_id ' : _default_general_account ,
}
2008-07-22 15:11:28 +00:00
def write ( self , cr , uid , ids , vals , context = None ) :
2010-07-27 07:11:45 +00:00
self . _check_inv ( cr , uid , ids , vals )
2008-07-22 15:11:28 +00:00
return super ( account_analytic_line , self ) . write ( cr , uid , ids , vals ,
context = context )
2010-07-27 07:11:45 +00:00
def _check_inv ( self , cr , uid , ids , vals ) :
2008-07-22 15:11:28 +00:00
select = ids
if isinstance ( select , ( int , long ) ) :
select = [ ids ]
2009-12-17 15:12:33 +00:00
if ( not vals . has_key ( ' invoice_id ' ) ) or vals [ ' invoice_id ' ] == False :
for line in self . browse ( cr , uid , select ) :
if line . invoice_id :
2012-08-07 11:31:37 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) ,
2011-09-18 13:53:10 +00:00
_ ( ' You cannot modify an invoiced analytic line! ' ) )
2008-07-22 15:11:28 +00:00
return True
def copy ( self , cursor , user , obj_id , default = None , context = None ) :
if default is None :
default = { }
default = default . copy ( )
default . update ( { ' invoice_id ' : False } )
return super ( account_analytic_line , self ) . copy ( cursor , user , obj_id ,
2010-07-27 07:11:45 +00:00
default , context = context )
2007-12-11 08:14:37 +00:00
2006-12-07 13:41:40 +00:00
account_analytic_line ( )
2007-09-11 14:14:18 +00:00
2007-06-25 14:36:49 +00:00
class hr_analytic_timesheet ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_inherit = " hr.analytic.timesheet "
2012-10-11 17:41:26 +00:00
def on_change_account_id ( self , cr , uid , ids , account_id , user_id = False ) :
2008-07-22 15:11:28 +00:00
res = { }
if not account_id :
return res
res . setdefault ( ' value ' , { } )
2008-11-21 11:04:55 +00:00
acc = self . pool . get ( ' account.analytic.account ' ) . browse ( cr , uid , account_id )
st = acc . to_invoice . id
2008-07-22 15:11:28 +00:00
res [ ' value ' ] [ ' to_invoice ' ] = st or False
2008-11-21 11:04:55 +00:00
if acc . state == ' pending ' :
res [ ' warning ' ] = {
' title ' : ' Warning ' ,
' message ' : ' The analytic account is in pending state. \n You should not work on this account ! '
}
2008-07-22 15:11:28 +00:00
return res
def copy ( self , cursor , user , obj_id , default = None , context = None ) :
if default is None :
default = { }
default = default . copy ( )
default . update ( { ' invoice_id ' : False } )
return super ( hr_analytic_timesheet , self ) . copy ( cursor , user , obj_id ,
2010-07-27 07:11:45 +00:00
default , context = context )
2007-12-11 08:14:37 +00:00
2007-06-25 14:36:49 +00:00
hr_analytic_timesheet ( )
2012-10-02 10:29:15 +00:00
2007-06-25 14:36:49 +00:00
class account_invoice ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_inherit = " account.invoice "
2011-12-15 09:07:30 +00:00
def _get_analytic_lines ( self , cr , uid , id , context = None ) :
iml = super ( account_invoice , self ) . _get_analytic_lines ( cr , uid , id , context = context )
2008-07-22 15:11:28 +00:00
2012-01-03 12:33:39 +00:00
inv = self . browse ( cr , uid , [ id ] , context = context ) [ 0 ]
2008-07-22 15:11:28 +00:00
if inv . type == ' in_invoice ' :
2010-07-30 08:59:35 +00:00
obj_analytic_account = self . pool . get ( ' account.analytic.account ' )
2008-07-22 15:11:28 +00:00
for il in iml :
if il [ ' account_analytic_id ' ] :
2010-10-17 17:30:00 +00:00
# *-* browse (or refactor to avoid read inside the loop)
2012-01-03 12:33:39 +00:00
to_invoice = obj_analytic_account . read ( cr , uid , [ il [ ' account_analytic_id ' ] ] , [ ' to_invoice ' ] , context = context ) [ 0 ] [ ' to_invoice ' ]
2008-07-22 15:11:28 +00:00
if to_invoice :
il [ ' analytic_lines ' ] [ 0 ] [ 2 ] [ ' to_invoice ' ] = to_invoice [ 0 ]
return iml
2007-09-11 14:14:18 +00:00
2007-06-25 14:36:49 +00:00
account_invoice ( )
2008-07-23 14:41:47 +00:00
2012-10-02 10:29:15 +00:00
2011-04-07 05:36:42 +00:00
class account_move_line ( osv . osv ) :
_inherit = " account.move.line "
def create_analytic_lines ( self , cr , uid , ids , context = None ) :
res = super ( account_move_line , self ) . create_analytic_lines ( cr , uid , ids , context = context )
analytic_line_obj = self . pool . get ( ' account.analytic.line ' )
2011-04-07 05:42:43 +00:00
for move_line in self . browse ( cr , uid , ids , context = context ) :
2011-04-07 05:36:42 +00:00
for line in move_line . analytic_lines :
toinv = line . account_id . to_invoice . id
if toinv :
analytic_line_obj . write ( cr , uid , line . id , { ' to_invoice ' : toinv } )
return res
account_move_line ( )
2008-07-23 14:41:47 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: