2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2008-11-28 14:44:41 +00:00
##############################################################################
2009-11-13 05:41:16 +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-28 14:44:41 +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-28 14:44:41 +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-28 14:44:41 +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-13 05:41:16 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2008-11-28 14:44:41 +00:00
#
##############################################################################
import time
from osv import fields , osv
import netsvc
import mx . DateTime
from mx . DateTime import RelativeDateTime , today , DateTime , localtime
from tools import config
2009-03-06 22:18:24 +00:00
from tools . translate import _
2010-03-06 20:52:19 +00:00
import decimal_precision as dp
2009-03-06 22:18:24 +00:00
2008-11-28 14:44:41 +00:00
class mrp_repair ( osv . osv ) :
_name = ' mrp.repair '
2010-05-19 18:32:32 +00:00
_description = ' Repair Order '
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
def _amount_untaxed ( self , cr , uid , ids , field_name , arg , context ) :
2010-04-06 06:52:09 +00:00
""" Calculates untaxed amount.
@param self : The object pointer
@param cr : The current row , from the database cursor ,
@param uid : The current user ID for security checks
@param ids : List of selected IDs
@param field_name : Name of field .
@param arg : Argument
@param context : A standard dictionary for contextual values
2010-08-13 12:20:05 +00:00
@return : Dictionary of values .
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
res = { }
2010-04-06 06:52:09 +00:00
cur_obj = self . pool . get ( ' res.currency ' )
2008-11-28 14:44:41 +00:00
for repair in self . browse ( cr , uid , ids ) :
res [ repair . id ] = 0.0
for line in repair . operations :
res [ repair . id ] + = line . price_subtotal
for line in repair . fees_lines :
res [ repair . id ] + = line . price_subtotal
cur = repair . pricelist_id . currency_id
res [ repair . id ] = cur_obj . round ( cr , uid , cur , res [ repair . id ] )
return res
def _amount_tax ( self , cr , uid , ids , field_name , arg , context ) :
2010-04-06 06:52:09 +00:00
""" Calculates taxed amount.
@param field_name : Name of field .
@param arg : Argument
2010-08-13 12:20:05 +00:00
@return : Dictionary of values .
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
res = { }
2010-04-06 06:52:09 +00:00
cur_obj = self . pool . get ( ' res.currency ' )
tax_obj = self . pool . get ( ' account.tax ' )
2008-11-28 14:44:41 +00:00
for repair in self . browse ( cr , uid , ids ) :
val = 0.0
2010-04-06 06:52:09 +00:00
cur = repair . pricelist_id . currency_id
2008-11-28 14:44:41 +00:00
for line in repair . operations :
2008-12-04 09:20:40 +00:00
if line . to_invoice :
2010-04-06 06:52:09 +00:00
for c in tax_obj . compute ( cr , uid , line . tax_id , line . price_unit , line . product_uom_qty , repair . partner_invoice_id . id , line . product_id , repair . partner_id ) :
val + = c [ ' amount ' ]
2008-11-28 14:44:41 +00:00
for line in repair . fees_lines :
2008-12-04 09:20:40 +00:00
if line . to_invoice :
2010-04-06 06:52:09 +00:00
for c in tax_obj . compute ( cr , uid , line . tax_id , line . price_unit , line . product_uom_qty , repair . partner_invoice_id . id , line . product_id , repair . partner_id ) :
val + = c [ ' amount ' ]
res [ repair . id ] = cur_obj . round ( cr , uid , cur , val )
2008-11-28 14:44:41 +00:00
return res
def _amount_total ( self , cr , uid , ids , field_name , arg , context ) :
2010-04-06 06:52:09 +00:00
""" Calculates total amount.
@param field_name : Name of field .
@param arg : Argument
2010-08-13 12:20:05 +00:00
@return : Dictionary of values .
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
res = { }
untax = self . _amount_untaxed ( cr , uid , ids , field_name , arg , context )
tax = self . _amount_tax ( cr , uid , ids , field_name , arg , context )
2010-04-06 06:52:09 +00:00
cur_obj = self . pool . get ( ' res.currency ' )
2008-11-28 14:44:41 +00:00
for id in ids :
2010-04-06 06:52:09 +00:00
repair = self . browse ( cr , uid , [ id ] ) [ 0 ]
cur = repair . pricelist_id . currency_id
2008-11-28 14:44:41 +00:00
res [ id ] = cur_obj . round ( cr , uid , cur , untax . get ( id , 0.0 ) + tax . get ( id , 0.0 ) )
return res
2008-12-04 09:20:40 +00:00
2008-11-28 14:44:41 +00:00
_columns = {
2010-04-06 06:52:09 +00:00
' name ' : fields . char ( ' Repair Reference ' , size = 24 , required = True ) ,
2008-11-28 14:44:41 +00:00
' product_id ' : fields . many2one ( ' product.product ' , string = ' Product to Repair ' , required = True , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2008-12-03 15:43:48 +00:00
' partner_id ' : fields . many2one ( ' res.partner ' , ' Partner ' , select = True , help = ' This field allow you to choose the parner that will be invoiced and delivered ' ) ,
2008-11-28 14:44:41 +00:00
' address_id ' : fields . many2one ( ' res.partner.address ' , ' Delivery Address ' , domain = " [( ' partner_id ' , ' = ' ,partner_id)] " ) ,
' prodlot_id ' : fields . many2one ( ' stock.production.lot ' , ' Lot Number ' , select = True , domain = " [( ' product_id ' , ' = ' ,product_id)] " ) ,
' state ' : fields . selection ( [
( ' draft ' , ' Quotation ' ) ,
( ' confirmed ' , ' Confirmed ' ) ,
2008-12-03 11:29:25 +00:00
( ' ready ' , ' Ready to Repair ' ) ,
2008-11-28 14:44:41 +00:00
( ' under_repair ' , ' Under Repair ' ) ,
2008-12-03 15:06:41 +00:00
( ' 2binvoiced ' , ' To be Invoiced ' ) ,
2008-11-28 14:44:41 +00:00
( ' invoice_except ' , ' Invoice Exception ' ) ,
( ' done ' , ' Done ' ) ,
( ' cancel ' , ' Cancel ' )
2009-12-29 12:36:59 +00:00
] , ' Repair State ' , readonly = True ,
help = ' * The \' Draft \' state is used when a user is encoding a new and unconfirmed repair order. \
\n * The \' Confirmed \' state is used when a user confirms the repair order. \
\n * The \' Ready to Repair \' state is used to start to repairing, user can start repairing only after repair order is confirmed. \
\n * The \' To be Invoiced \' state is used to generate the invoice before or after repairing done. \
\n * The \' Done \' state is set when repairing is completed. \
\n * The \' Cancelled \' state is used when user cancel repair order. ' ) ,
2010-03-11 14:24:49 +00:00
' location_id ' : fields . many2one ( ' stock.location ' , ' Current Location ' , select = True , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2008-12-03 11:29:25 +00:00
' location_dest_id ' : fields . many2one ( ' stock.location ' , ' Delivery Location ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2008-12-03 15:06:41 +00:00
' move_id ' : fields . many2one ( ' stock.move ' , ' Move ' , required = True , domain = " [( ' product_id ' , ' = ' ,product_id)] " , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2009-12-22 06:45:51 +00:00
' guarantee_limit ' : fields . date ( ' Guarantee limit ' , help = " The guarantee limit is computed as: last move date + warranty defined on selected product. If the current date is below the guarantee limit, each operation and fee you will add will be set as ' not to invoiced ' by default. Note that you can change manually afterwards. " ) ,
2008-12-03 15:06:41 +00:00
' operations ' : fields . one2many ( ' mrp.repair.line ' , ' repair_id ' , ' Operation Lines ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2008-12-03 15:43:48 +00:00
' pricelist_id ' : fields . many2one ( ' product.pricelist ' , ' Pricelist ' , help = ' The pricelist comes from the selected partner, by default. ' ) ,
2008-12-08 17:08:40 +00:00
' partner_invoice_id ' : fields . many2one ( ' res.partner.address ' , ' Invoicing Address ' , domain = " [( ' partner_id ' , ' = ' ,partner_id)] " ) ,
2008-11-28 14:44:41 +00:00
' invoice_method ' : fields . selection ( [
( " none " , " No Invoice " ) ,
( " b4repair " , " Before Repair " ) ,
( " after_repair " , " After Repair " )
2009-01-20 08:48:19 +00:00
] , " Invoice Method " ,
2008-12-03 15:43:48 +00:00
select = True , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , readonly = True , help = ' This field allow you to change the workflow of the repair order. If value selected is different from \' No Invoice \' , it also allow you to select the pricelist and invoicing address. ' ) ,
2008-11-28 14:44:41 +00:00
' invoice_id ' : fields . many2one ( ' account.invoice ' , ' Invoice ' , readonly = True ) ,
2009-11-13 05:41:16 +00:00
' picking_id ' : fields . many2one ( ' stock.picking ' , ' Picking ' , readonly = True ) ,
2010-04-06 06:52:09 +00:00
' fees_lines ' : fields . one2many ( ' mrp.repair.fee ' , ' repair_id ' , ' Fees Lines ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' internal_notes ' : fields . text ( ' Internal Notes ' ) ,
' quotation_notes ' : fields . text ( ' Quotation Notes ' ) ,
2009-11-25 09:31:44 +00:00
' deliver_bool ' : fields . boolean ( ' Deliver ' , help = " Check this box if you want to manage the delivery once the product is repaired. If cheked, it will create a picking with selected product. Note that you can select the locations in the Info tab, if you have the extended view. " ) ,
2008-11-28 14:44:41 +00:00
' invoiced ' : fields . boolean ( ' Invoiced ' , readonly = True ) ,
2010-04-06 06:52:09 +00:00
' repaired ' : fields . boolean ( ' Repaired ' , readonly = True ) ,
2008-11-28 14:44:41 +00:00
' amount_untaxed ' : fields . function ( _amount_untaxed , method = True , string = ' Untaxed Amount ' ) ,
' amount_tax ' : fields . function ( _amount_tax , method = True , string = ' Taxes ' ) ,
' amount_total ' : fields . function ( _amount_total , method = True , string = ' Total ' ) ,
}
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
_defaults = {
' state ' : lambda * a : ' draft ' ,
2008-12-03 11:29:25 +00:00
' deliver_bool ' : lambda * a : True ,
2008-11-28 14:44:41 +00:00
' name ' : lambda obj , cr , uid , context : obj . pool . get ( ' ir.sequence ' ) . get ( cr , uid , ' mrp.repair ' ) ,
' invoice_method ' : lambda * a : ' none ' ,
2010-06-16 11:51:39 +00:00
' pricelist_id ' : lambda self , cr , uid , context : self . pool . get ( ' product.pricelist ' ) . search ( cr , uid , [ ( ' type ' , ' = ' , ' sale ' ) ] ) [ 0 ]
2008-11-28 14:44:41 +00:00
}
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
def copy ( self , cr , uid , id , default = None , context = None ) :
if not default :
2009-01-20 08:48:19 +00:00
default = { }
2008-11-28 14:44:41 +00:00
default . update ( {
' state ' : ' draft ' ,
' repaired ' : False ,
' invoiced ' : False ,
' invoice_id ' : False ,
' picking_id ' : False ,
' name ' : self . pool . get ( ' ir.sequence ' ) . get ( cr , uid , ' mrp.repair ' ) ,
} )
return super ( mrp_repair , self ) . copy ( cr , uid , id , default , context )
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
def onchange_product_id ( self , cr , uid , ids , product_id = None ) :
2010-04-06 06:52:09 +00:00
""" On change of product sets some values.
@param product_id : Changed product
2010-08-13 12:20:05 +00:00
@return : Dictionary of values .
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
return { ' value ' : {
2009-01-20 08:48:19 +00:00
' prodlot_id ' : False ,
' move_id ' : False ,
' guarantee_limit ' : False ,
' location_id ' : False ,
2008-11-28 14:44:41 +00:00
' location_dest_id ' : False ,
}
}
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
def onchange_move_id ( self , cr , uid , ids , prod_id = False , move_id = False ) :
2010-04-06 06:52:09 +00:00
""" On change of move id sets values of guarantee limit, source location,
destination location , partner and partner address .
@param prod_id : Id of product in current record .
@param move_id : Changed move .
2010-08-13 12:20:05 +00:00
@return : Dictionary of values .
2010-04-06 06:52:09 +00:00
"""
2008-12-03 11:29:25 +00:00
data = { }
data [ ' value ' ] = { }
2008-11-28 14:44:41 +00:00
if not prod_id :
2008-12-03 11:29:25 +00:00
return data
2008-11-28 14:44:41 +00:00
if move_id :
move = self . pool . get ( ' stock.move ' ) . browse ( cr , uid , move_id )
product = self . pool . get ( ' product.product ' ) . browse ( cr , uid , prod_id )
2008-12-03 15:06:41 +00:00
date = move . date_planned
2008-11-28 14:44:41 +00:00
limit = mx . DateTime . strptime ( date , ' % Y- % m- %d % H: % M: % S ' ) + RelativeDateTime ( months = product . warranty )
2008-12-03 11:29:25 +00:00
data [ ' value ' ] [ ' guarantee_limit ' ] = limit . strftime ( ' % Y- % m- %d ' )
data [ ' value ' ] [ ' location_id ' ] = move . location_dest_id . id
data [ ' value ' ] [ ' location_dest_id ' ] = move . location_dest_id . id
2008-12-04 09:20:40 +00:00
if move . address_id :
data [ ' value ' ] [ ' partner_id ' ] = move . address_id . partner_id and move . address_id . partner_id . id
else :
data [ ' value ' ] [ ' partner_id ' ] = False
2008-12-03 11:29:25 +00:00
data [ ' value ' ] [ ' address_id ' ] = move . address_id and move . address_id . id
d = self . onchange_partner_id ( cr , uid , ids , data [ ' value ' ] [ ' partner_id ' ] , data [ ' value ' ] [ ' address_id ' ] )
data [ ' value ' ] . update ( d [ ' value ' ] )
return data
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
def button_dummy ( self , cr , uid , ids , context = None ) :
return True
2008-12-03 11:29:25 +00:00
def onchange_partner_id ( self , cr , uid , ids , part , address_id ) :
2010-08-13 12:20:05 +00:00
""" On change of partner sets the values of partner address,
2010-04-06 06:52:09 +00:00
partner invoice address and pricelist .
@param part : Changed id of partner .
@param address_id : Address id from current record .
2010-08-13 12:20:05 +00:00
@return : Dictionary of values .
2010-04-06 06:52:09 +00:00
"""
part_obj = self . pool . get ( ' res.partner ' )
pricelist_obj = self . pool . get ( ' product.pricelist ' )
2008-11-28 14:44:41 +00:00
if not part :
return { ' value ' : {
' address_id ' : False ,
' partner_invoice_id ' : False ,
2010-04-06 06:52:09 +00:00
' pricelist_id ' : pricelist_obj . search ( cr , uid , [ ( ' type ' , ' = ' , ' sale ' ) ] ) [ 0 ]
2008-11-28 14:44:41 +00:00
}
}
2010-04-06 06:52:09 +00:00
addr = part_obj . address_get ( cr , uid , [ part ] , [ ' delivery ' , ' invoice ' , ' default ' ] )
partner = part_obj . browse ( cr , uid , part )
2008-11-28 14:44:41 +00:00
pricelist = partner . property_product_pricelist and partner . property_product_pricelist . id or False
return { ' value ' : {
2009-01-20 08:48:19 +00:00
' address_id ' : address_id or addr [ ' delivery ' ] ,
2008-11-28 14:44:41 +00:00
' partner_invoice_id ' : addr [ ' invoice ' ] ,
' pricelist_id ' : pricelist
}
}
def onchange_lot_id ( self , cr , uid , ids , lot , product_id ) :
2010-04-06 06:52:09 +00:00
""" On change of production lot sets the values of source location,
destination location , move and guarantee limit .
@param lot : Changed id of production lot .
@param product_id : Product id from current record .
2010-08-13 12:20:05 +00:00
@return : Dictionary of values .
2010-04-06 06:52:09 +00:00
"""
prodlot_obj = self . pool . get ( ' stock.production.lot ' )
move_obj = self . pool . get ( ' stock.move ' )
2008-12-03 11:29:25 +00:00
data = { }
data [ ' value ' ] = {
' location_id ' : False ,
' location_dest_id ' : False ,
' move_id ' : False ,
' guarantee_limit ' : False
}
2008-11-28 14:44:41 +00:00
if not lot :
2008-12-03 11:29:25 +00:00
return data
2010-04-06 06:52:09 +00:00
lot_info = prodlot_obj . browse ( cr , uid , lot )
move_ids = move_obj . search ( cr , uid , [ ( ' prodlot_id ' , ' = ' , lot ) ] )
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
if not len ( move_ids ) :
2008-12-03 11:29:25 +00:00
return data
2008-11-28 14:44:41 +00:00
def get_last_move ( lst_move ) :
2008-12-03 15:06:41 +00:00
while lst_move . move_dest_id and lst_move . move_dest_id . state == ' done ' :
2008-11-28 14:44:41 +00:00
lst_move = lst_move . move_dest_id
return lst_move
move_id = move_ids [ 0 ]
2010-04-06 06:52:09 +00:00
move = get_last_move ( move_obj . browse ( cr , uid , move_id ) )
2008-12-03 11:29:25 +00:00
data [ ' value ' ] [ ' move_id ' ] = move . id
d = self . onchange_move_id ( cr , uid , ids , product_id , move . id )
data [ ' value ' ] . update ( d [ ' value ' ] )
return data
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
def action_cancel_draft ( self , cr , uid , ids , * args ) :
2010-04-06 06:52:09 +00:00
""" Cancels repair order when it is in ' Draft ' state.
@param * arg : Arguments
2010-08-13 12:20:05 +00:00
@return : True
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
if not len ( ids ) :
return False
mrp_line_obj = self . pool . get ( ' mrp.repair.line ' )
for repair in self . browse ( cr , uid , ids ) :
mrp_line_obj . write ( cr , uid , [ l . id for l in repair . operations ] , { ' state ' : ' draft ' } )
self . write ( cr , uid , ids , { ' state ' : ' draft ' } )
wf_service = netsvc . LocalService ( " workflow " )
for id in ids :
wf_service . trg_create ( uid , ' mrp.repair ' , id , cr )
return True
2008-12-03 15:06:41 +00:00
def action_confirm ( self , cr , uid , ids , * args ) :
2010-04-06 06:52:09 +00:00
""" Repair order state is set to ' To be invoiced ' when invoice method
is ' Before repair ' else state becomes ' Confirmed ' .
@param * arg : Arguments
2010-08-13 12:20:05 +00:00
@return : True
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
mrp_line_obj = self . pool . get ( ' mrp.repair.line ' )
for o in self . browse ( cr , uid , ids ) :
2008-12-03 15:06:41 +00:00
if ( o . invoice_method == ' b4repair ' ) :
2008-11-28 14:44:41 +00:00
self . write ( cr , uid , [ o . id ] , { ' state ' : ' 2binvoiced ' } )
else :
2009-01-20 08:48:19 +00:00
self . write ( cr , uid , [ o . id ] , { ' state ' : ' confirmed ' } )
2008-11-28 14:44:41 +00:00
mrp_line_obj . write ( cr , uid , [ l . id for l in o . operations ] , { ' state ' : ' confirmed ' } )
return True
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
def action_cancel ( self , cr , uid , ids , context = None ) :
2010-04-06 06:52:09 +00:00
""" Cancels repair order.
2010-08-13 12:20:05 +00:00
@return : True
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
ok = True
mrp_line_obj = self . pool . get ( ' mrp.repair.line ' )
for repair in self . browse ( cr , uid , ids ) :
mrp_line_obj . write ( cr , uid , [ l . id for l in repair . operations ] , { ' state ' : ' cancel ' } )
self . write ( cr , uid , ids , { ' state ' : ' cancel ' } )
return True
def wkf_invoice_create ( self , cr , uid , ids , * args ) :
return self . action_invoice_create ( cr , uid , ids )
def action_invoice_create ( self , cr , uid , ids , group = False , context = None ) :
2010-04-06 06:52:09 +00:00
""" Creates invoice(s) for repair order.
@param group : It is set to true when group invoice is to be generated .
2010-08-13 12:20:05 +00:00
@return : Invoice Ids .
2010-04-06 06:52:09 +00:00
"""
res = { }
2008-11-28 14:44:41 +00:00
invoices_group = { }
2010-04-06 06:52:09 +00:00
inv_line_obj = self . pool . get ( ' account.invoice.line ' )
inv_obj = self . pool . get ( ' account.invoice ' )
repair_line_obj = self . pool . get ( ' mrp.repair.line ' )
repair_fee_obj = self . pool . get ( ' mrp.repair.fee ' )
2010-08-13 12:20:05 +00:00
for repair in self . browse ( cr , uid , ids , context = context ) :
2010-04-06 06:52:09 +00:00
res [ repair . id ] = False
2008-12-02 14:00:15 +00:00
if repair . state in ( ' draft ' , ' cancel ' ) or repair . invoice_id :
continue
2008-11-28 14:44:41 +00:00
if not ( repair . partner_id . id and repair . partner_invoice_id . id ) :
2010-03-11 14:24:49 +00:00
raise osv . except_osv ( _ ( ' No partner ! ' ) , _ ( ' You have to select a Partner Invoice Address in the repair form ! ' ) )
2010-04-06 06:52:09 +00:00
comment = repair . quotation_notes
2008-11-28 14:44:41 +00:00
if ( repair . invoice_method != ' none ' ) :
if group and repair . partner_invoice_id . id in invoices_group :
2010-04-06 06:52:09 +00:00
inv_id = invoices_group [ repair . partner_invoice_id . id ]
invoice = inv_obj . browse ( cr , uid , inv_id )
2008-11-28 14:44:41 +00:00
invoice_vals = {
' name ' : invoice . name + ' , ' + repair . name ,
2009-01-20 08:48:19 +00:00
' origin ' : invoice . origin + ' , ' + repair . name ,
2008-11-28 14:44:41 +00:00
' comment ' : ( comment and ( invoice . comment and invoice . comment + " \n " + comment or comment ) ) or ( invoice . comment and invoice . comment or ' ' ) ,
2008-12-03 15:06:41 +00:00
}
2010-07-01 13:40:10 +00:00
inv_obj . write ( cr , uid , [ inv_id ] , invoice_vals , context = context )
2008-11-28 14:44:41 +00:00
else :
2010-05-11 09:15:36 +00:00
if not repair . partner_id . property_account_receivable :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' No account defined for partner " %s " . ' ) % repair . partner_id . name )
account_id = repair . partner_id . property_account_receivable . id
2008-11-28 14:44:41 +00:00
inv = {
' name ' : repair . name ,
' origin ' : repair . name ,
2008-12-03 15:06:41 +00:00
' type ' : ' out_invoice ' ,
2010-05-11 09:15:36 +00:00
' account_id ' : account_id ,
2008-11-28 14:44:41 +00:00
' partner_id ' : repair . partner_id . id ,
' address_invoice_id ' : repair . address_id . id ,
' currency_id ' : repair . pricelist_id . currency_id . id ,
' comment ' : repair . quotation_notes ,
2009-02-11 13:32:54 +00:00
' fiscal_position ' : repair . partner_id . property_account_position . id
2008-11-28 14:44:41 +00:00
}
inv_id = inv_obj . create ( cr , uid , inv )
2009-01-20 08:48:19 +00:00
invoices_group [ repair . partner_invoice_id . id ] = inv_id
2010-04-06 06:52:09 +00:00
self . write ( cr , uid , repair . id , { ' invoiced ' : True , ' invoice_id ' : inv_id } )
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
for operation in repair . operations :
2008-12-03 15:06:41 +00:00
if operation . to_invoice == True :
2008-11-28 14:44:41 +00:00
if group :
name = repair . name + ' - ' + operation . name
else :
name = operation . name
2010-05-11 09:15:36 +00:00
if operation . product_id . property_account_income :
2010-07-09 08:48:23 +00:00
account_id = operation . product_id . property_account_income . id
2010-05-11 09:15:36 +00:00
elif operation . product_id . categ_id . property_account_income_categ :
account_id = operation . product_id . categ_id . property_account_income_categ . id
else :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' No account defined for product " %s " . ' ) % operation . product_id . name )
2010-04-06 06:52:09 +00:00
invoice_line_id = inv_line_obj . create ( cr , uid , {
2009-01-20 08:48:19 +00:00
' invoice_id ' : inv_id ,
2008-11-28 14:44:41 +00:00
' name ' : name ,
2010-04-06 06:52:09 +00:00
' origin ' : repair . name ,
2010-08-13 12:20:05 +00:00
' account_id ' : account_id ,
2010-04-06 06:52:09 +00:00
' quantity ' : operation . product_uom_qty ,
2008-11-28 14:44:41 +00:00
' invoice_line_tax_id ' : [ ( 6 , 0 , [ x . id for x in operation . tax_id ] ) ] ,
2010-04-06 06:52:09 +00:00
' uos_id ' : operation . product_uom . id ,
' price_unit ' : operation . price_unit ,
' price_subtotal ' : operation . product_uom_qty * operation . price_unit ,
' product_id ' : operation . product_id and operation . product_id . id or False
2010-08-13 12:20:05 +00:00
} )
2010-04-06 06:52:09 +00:00
repair_line_obj . write ( cr , uid , [ operation . id ] , { ' invoiced ' : True , ' invoice_line_id ' : invoice_line_id } )
2008-11-28 14:44:41 +00:00
for fee in repair . fees_lines :
if fee . to_invoice == True :
if group :
name = repair . name + ' - ' + fee . name
else :
name = fee . name
2010-04-06 06:52:09 +00:00
invoice_fee_id = inv_line_obj . create ( cr , uid , {
2008-11-28 14:44:41 +00:00
' invoice_id ' : inv_id ,
' name ' : name ,
2010-04-06 06:52:09 +00:00
' origin ' : repair . name ,
2008-11-28 14:44:41 +00:00
' account_id ' : a ,
' quantity ' : fee . product_uom_qty ,
' invoice_line_tax_id ' : [ ( 6 , 0 , [ x . id for x in fee . tax_id ] ) ] ,
' uos_id ' : fee . product_uom . id ,
' product_id ' : fee . product_id and fee . product_id . id or False ,
' price_unit ' : fee . price_unit ,
' price_subtotal ' : fee . product_uom_qty * fee . price_unit
2010-08-13 12:20:05 +00:00
} )
2010-04-06 06:52:09 +00:00
repair_fee_obj . write ( cr , uid , [ fee . id ] , { ' invoiced ' : True , ' invoice_line_id ' : invoice_fee_id } )
res [ repair . id ] = inv_id
2008-11-28 14:44:41 +00:00
return res
2008-12-03 11:29:25 +00:00
def action_repair_ready ( self , cr , uid , ids , context = None ) :
2010-04-06 06:52:09 +00:00
""" Writes repair order state to ' Ready '
2010-08-13 12:20:05 +00:00
@return : True
2010-04-06 06:52:09 +00:00
"""
self . write ( cr , uid , ids , { ' state ' : ' ready ' } )
2008-12-03 11:29:25 +00:00
return True
2008-11-28 14:44:41 +00:00
def action_invoice_cancel ( self , cr , uid , ids , context = None ) :
2010-04-06 06:52:09 +00:00
""" Writes repair order state to ' Exception in invoice '
2010-08-13 12:20:05 +00:00
@return : True
2010-04-06 06:52:09 +00:00
"""
self . write ( cr , uid , ids , { ' state ' : ' invoice_except ' } )
2008-11-28 14:44:41 +00:00
return True
def action_repair_start ( self , cr , uid , ids , context = None ) :
2010-04-06 06:52:09 +00:00
""" Writes repair order state to ' Under Repair '
2010-08-13 12:20:05 +00:00
@return : True
2010-04-06 06:52:09 +00:00
"""
self . write ( cr , uid , ids , { ' state ' : ' under_repair ' } )
2008-11-28 14:44:41 +00:00
return True
2009-01-20 08:48:19 +00:00
2008-12-03 15:06:41 +00:00
def action_invoice_end ( self , cr , uid , ids , context = None ) :
2010-04-06 06:52:09 +00:00
""" Writes repair order state to ' Ready ' if invoice method is Before repair.
2010-08-13 12:20:05 +00:00
@return : True
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
for order in self . browse ( cr , uid , ids ) :
2009-01-20 08:48:19 +00:00
val = { }
2010-04-06 06:52:09 +00:00
if ( order . invoice_method == ' b4repair ' ) :
2008-12-03 11:29:25 +00:00
val [ ' state ' ] = ' ready '
2008-12-03 15:06:41 +00:00
else :
2008-11-28 14:44:41 +00:00
pass
self . write ( cr , uid , [ order . id ] , val )
2009-01-20 08:48:19 +00:00
return True
2008-11-28 14:44:41 +00:00
def action_repair_end ( self , cr , uid , ids , context = None ) :
2010-08-13 12:20:05 +00:00
""" Writes repair order state to ' To be invoiced ' if invoice method is
2010-04-06 06:52:09 +00:00
After repair else state is set to ' Ready ' .
2010-08-13 12:20:05 +00:00
@return : True
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
for order in self . browse ( cr , uid , ids ) :
val = { }
2010-04-06 06:52:09 +00:00
val [ ' repaired ' ] = True
2008-11-28 14:44:41 +00:00
if ( not order . invoiced and order . invoice_method == ' after_repair ' ) :
2008-12-03 15:06:41 +00:00
val [ ' state ' ] = ' 2binvoiced '
2008-11-28 14:44:41 +00:00
elif ( not order . invoiced and order . invoice_method == ' b4repair ' ) :
2008-12-03 11:29:25 +00:00
val [ ' state ' ] = ' ready '
2008-12-03 15:06:41 +00:00
else :
2008-11-28 14:44:41 +00:00
pass
self . write ( cr , uid , [ order . id ] , val )
2009-01-20 08:48:19 +00:00
return True
2008-11-28 14:44:41 +00:00
def wkf_repair_done ( self , cr , uid , ids , * args ) :
2010-04-06 06:52:09 +00:00
res = self . action_repair_done ( cr , uid , ids )
2008-11-28 14:44:41 +00:00
return True
2009-01-20 08:48:19 +00:00
2008-12-03 15:06:41 +00:00
def action_repair_done ( self , cr , uid , ids , context = None ) :
2010-04-06 06:52:09 +00:00
""" Creates stock move and picking for repair order.
2010-08-13 12:20:05 +00:00
@return : Picking ids .
2010-04-06 06:52:09 +00:00
"""
2009-01-20 08:48:19 +00:00
res = { }
2010-04-06 06:52:09 +00:00
move_obj = self . pool . get ( ' stock.move ' )
wf_service = netsvc . LocalService ( " workflow " )
repair_line_obj = self . pool . get ( ' mrp.repair.line ' )
seq_obj = self . pool . get ( ' ir.sequence ' )
pick_obj = self . pool . get ( ' stock.picking ' )
2008-11-28 14:44:41 +00:00
company = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid ) . company_id
2009-01-20 08:48:19 +00:00
for repair in self . browse ( cr , uid , ids , context = context ) :
2008-12-03 15:06:41 +00:00
for move in repair . operations :
2010-04-06 06:52:09 +00:00
move_id = move_obj . create ( cr , uid , {
2008-12-03 15:06:41 +00:00
' name ' : move . name ,
' product_id ' : move . product_id . id ,
' product_qty ' : move . product_uom_qty ,
' product_uom ' : move . product_uom . id ,
' address_id ' : repair . address_id and repair . address_id . id or False ,
' location_id ' : move . location_id . id ,
' location_dest_id ' : move . location_dest_id . id ,
' tracking_id ' : False ,
2008-12-08 17:08:40 +00:00
' state ' : ' done ' ,
2008-12-03 15:06:41 +00:00
} )
2010-04-06 06:52:09 +00:00
repair_line_obj . write ( cr , uid , [ move . id ] , { ' move_id ' : move_id } )
2008-12-03 11:29:25 +00:00
if repair . deliver_bool :
2010-04-06 06:52:09 +00:00
pick_name = seq_obj . get ( cr , uid , ' stock.picking.out ' )
picking = pick_obj . create ( cr , uid , {
2010-03-12 11:50:12 +00:00
' name ' : pick_name ,
2008-12-03 11:29:25 +00:00
' origin ' : repair . name ,
' state ' : ' draft ' ,
' move_type ' : ' one ' ,
' address_id ' : repair . address_id and repair . address_id . id or False ,
' note ' : repair . internal_notes ,
' invoice_state ' : ' none ' ,
2008-12-08 17:08:40 +00:00
' type ' : ' out ' ,
2008-12-03 11:29:25 +00:00
} )
2010-04-06 06:52:09 +00:00
move_id = move_obj . create ( cr , uid , {
2008-12-03 11:29:25 +00:00
' name ' : repair . name ,
' picking_id ' : picking ,
' product_id ' : repair . product_id . id ,
' product_qty ' : 1.0 ,
' product_uom ' : repair . product_id . uom_id . id ,
' prodlot_id ' : repair . prodlot_id and repair . prodlot_id . id or False ,
' address_id ' : repair . address_id and repair . address_id . id or False ,
' location_id ' : repair . location_id . id ,
' location_dest_id ' : repair . location_dest_id . id ,
' tracking_id ' : False ,
2010-08-13 12:20:05 +00:00
' state ' : ' assigned ' ,
2008-12-03 11:29:25 +00:00
} )
2010-08-05 12:16:59 +00:00
wf_service . trg_validate ( uid , ' stock.picking ' , picking , ' button_confirm ' , cr )
2010-04-06 06:52:09 +00:00
self . write ( cr , uid , [ repair . id ] , { ' state ' : ' done ' , ' picking_id ' : picking } )
2008-12-03 11:29:25 +00:00
res [ repair . id ] = picking
else :
2010-04-06 06:52:09 +00:00
self . write ( cr , uid , [ repair . id ] , { ' state ' : ' done ' } )
2008-12-03 15:06:41 +00:00
return res
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
mrp_repair ( )
class ProductChangeMixin ( object ) :
2010-08-13 12:20:05 +00:00
def product_id_change ( self , cr , uid , ids , pricelist , product , uom = False ,
2010-04-06 06:52:09 +00:00
product_uom_qty = 0 , partner_id = False , guarantee_limit = False ) :
""" On change of product it sets product quantity, tax account, name,
uom of product , unit price and price subtotal .
@param pricelist : Pricelist of current record .
@param product : Changed id of product .
@param uom : UoM of current record .
@param product_uom_qty : Quantity of current record .
@param partner_id : Partner of current record .
@param guarantee_limit : Guarantee limit of current record .
@return : Dictionary of values and warning message .
"""
2008-11-28 14:44:41 +00:00
result = { }
2009-01-20 08:48:19 +00:00
warning = { }
2008-12-04 12:13:42 +00:00
2008-11-28 14:44:41 +00:00
if not product_uom_qty :
product_uom_qty = 1
2009-01-20 08:48:19 +00:00
result [ ' product_uom_qty ' ] = product_uom_qty
2008-11-28 14:44:41 +00:00
if product :
2010-04-06 06:52:09 +00:00
product_obj = self . pool . get ( ' product.product ' ) . browse ( cr , uid , product )
2008-12-04 09:20:40 +00:00
if partner_id :
partner = self . pool . get ( ' res.partner ' ) . browse ( cr , uid , partner_id )
2009-01-20 08:48:19 +00:00
result [ ' tax_id ' ] = self . pool . get ( ' account.fiscal.position ' ) . map_tax ( cr , uid , partner . property_account_position , product_obj . taxes_id )
2008-12-04 09:20:40 +00:00
2008-11-28 14:44:41 +00:00
result [ ' name ' ] = product_obj . partner_ref
result [ ' product_uom ' ] = product_obj . uom_id and product_obj . uom_id . id or False
if not pricelist :
2010-04-06 06:52:09 +00:00
warning = {
2008-11-28 14:44:41 +00:00
' title ' : ' No Pricelist ! ' ,
' message ' :
' You have to select a pricelist in the Repair form ! \n '
' Please set one before choosing a product. '
}
else :
price = self . pool . get ( ' product.pricelist ' ) . price_get ( cr , uid , [ pricelist ] ,
product , product_uom_qty , partner_id , { ' uom ' : uom , } ) [ pricelist ]
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
if price is False :
2010-04-06 06:52:09 +00:00
warning = {
2008-11-28 14:44:41 +00:00
' title ' : ' No valid pricelist line found ! ' ,
' message ' :
" Couldn ' t find a pricelist line matching this product and quantity. \n "
" You have to change either the product, the quantity or the pricelist. "
2010-08-13 12:20:05 +00:00
}
2008-11-28 14:44:41 +00:00
else :
2010-04-06 06:52:09 +00:00
result . update ( { ' price_unit ' : price , ' price_subtotal ' : price * product_uom_qty } )
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
return { ' value ' : result , ' warning ' : warning }
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
class mrp_repair_line ( osv . osv , ProductChangeMixin ) :
_name = ' mrp.repair.line '
2010-05-19 18:32:32 +00:00
_description = ' Repair Line '
2009-01-20 08:48:19 +00:00
2009-02-04 13:12:10 +00:00
def copy_data ( self , cr , uid , id , default = None , context = None ) :
2008-11-28 14:44:41 +00:00
if not default : default = { }
2010-04-06 06:52:09 +00:00
default . update ( { ' invoice_line_id ' : False , ' move_id ' : False , ' invoiced ' : False , ' state ' : ' draft ' } )
2009-02-04 13:12:10 +00:00
return super ( mrp_repair_line , self ) . copy_data ( cr , uid , id , default , context )
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
def _amount_line ( self , cr , uid , ids , field_name , arg , context ) :
2010-04-06 06:52:09 +00:00
""" Calculates amount.
@param field_name : Name of field .
@param arg : Argument
2010-08-13 12:20:05 +00:00
@return : Dictionary of values .
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
res = { }
cur_obj = self . pool . get ( ' res.currency ' )
for line in self . browse ( cr , uid , ids ) :
res [ line . id ] = line . to_invoice and line . price_unit * line . product_uom_qty or 0
cur = line . repair_id . pricelist_id . currency_id
res [ line . id ] = cur_obj . round ( cr , uid , cur , res [ line . id ] )
return res
_columns = {
2008-12-03 11:29:25 +00:00
' name ' : fields . char ( ' Description ' , size = 64 , required = True ) ,
2009-12-22 09:38:41 +00:00
' repair_id ' : fields . many2one ( ' mrp.repair ' , ' Repair Order Reference ' , ondelete = ' cascade ' , select = True ) ,
2008-12-03 15:06:41 +00:00
' type ' : fields . selection ( [ ( ' add ' , ' Add ' ) , ( ' remove ' , ' Remove ' ) ] , ' Type ' , required = True ) ,
' to_invoice ' : fields . boolean ( ' To Invoice ' ) ,
' product_id ' : fields . many2one ( ' product.product ' , ' Product ' , domain = [ ( ' sale_ok ' , ' = ' , True ) ] , required = True ) ,
' invoiced ' : fields . boolean ( ' Invoiced ' , readonly = True ) ,
2010-03-06 20:52:19 +00:00
' price_unit ' : fields . float ( ' Unit Price ' , required = True , digits_compute = dp . get_precision ( ' Sale Price ' ) ) ,
' price_subtotal ' : fields . function ( _amount_line , method = True , string = ' Subtotal ' , digits_compute = dp . get_precision ( ' Sale Price ' ) ) ,
2008-12-03 15:06:41 +00:00
' tax_id ' : fields . many2many ( ' account.tax ' , ' repair_operation_line_tax ' , ' repair_operation_line_id ' , ' tax_id ' , ' Taxes ' ) ,
2008-11-28 14:44:41 +00:00
' product_uom_qty ' : fields . float ( ' Quantity (UoM) ' , digits = ( 16 , 2 ) , required = True ) ,
2008-12-03 15:06:41 +00:00
' product_uom ' : fields . many2one ( ' product.uom ' , ' Product UoM ' , required = True ) ,
' invoice_line_id ' : fields . many2one ( ' account.invoice.line ' , ' Invoice Line ' , readonly = True ) ,
2009-01-23 05:56:14 +00:00
' location_id ' : fields . many2one ( ' stock.location ' , ' Source Location ' , required = True , select = True ) ,
' location_dest_id ' : fields . many2one ( ' stock.location ' , ' Dest. Location ' , required = True , select = True ) ,
2008-12-03 15:06:41 +00:00
' move_id ' : fields . many2one ( ' stock.move ' , ' Inventory Move ' , readonly = True ) ,
2009-12-29 12:36:59 +00:00
' state ' : fields . selection ( [
( ' draft ' , ' Draft ' ) ,
( ' confirmed ' , ' Confirmed ' ) ,
( ' done ' , ' Done ' ) ,
( ' cancel ' , ' Canceled ' ) ] , ' State ' , required = True , readonly = True ,
help = ' * The \' Draft \' state is set automatically as draft when repair order in draft state. \
\n * The \' Confirmed \' state is set automatically as confirm when repair order in confirm state. \
\n * The \' Done \' state is set automatically when repair order is completed. \
\n * The \' Cancelled \' state is set automatically when user cancel repair order. ' ) ,
2008-11-28 14:44:41 +00:00
}
2008-12-03 15:06:41 +00:00
_defaults = {
2008-11-28 14:44:41 +00:00
' state ' : lambda * a : ' draft ' ,
2010-04-06 06:52:09 +00:00
' product_uom_qty ' : lambda * a : 1 ,
2008-11-28 14:44:41 +00:00
}
2009-01-20 08:48:19 +00:00
2008-12-03 15:06:41 +00:00
def onchange_operation_type ( self , cr , uid , ids , type , guarantee_limit ) :
2010-04-06 06:52:09 +00:00
""" On change of operation type it sets source location, destination location
and to invoice field .
@param product : Changed operation type .
@param guarantee_limit : Guarantee limit of current record .
@return : Dictionary of values .
"""
2008-11-28 14:44:41 +00:00
if not type :
return { ' value ' : {
' location_id ' : False ,
' location_dest_id ' : False
}
}
2008-12-01 11:00:42 +00:00
produc_id = self . pool . get ( ' stock.location ' ) . search ( cr , uid , [ ( ' name ' , ' = ' , ' Production ' ) ] ) [ 0 ]
2008-11-28 14:44:41 +00:00
if type == ' add ' :
2008-12-03 15:06:41 +00:00
stock_id = self . pool . get ( ' stock.location ' ) . search ( cr , uid , [ ( ' name ' , ' = ' , ' Stock ' ) ] ) [ 0 ]
2010-04-06 06:52:09 +00:00
to_invoice = False
2008-12-03 15:06:41 +00:00
if guarantee_limit and today ( ) > mx . DateTime . strptime ( guarantee_limit , ' % Y- % m- %d ' ) :
to_invoice = True
2008-11-28 14:44:41 +00:00
return { ' value ' : {
' to_invoice ' : to_invoice ,
' location_id ' : stock_id ,
2010-04-06 06:52:09 +00:00
' location_dest_id ' : produc_id
2008-11-28 14:44:41 +00:00
}
}
2008-12-03 15:06:41 +00:00
return { ' value ' : {
' to_invoice ' : False ,
' location_id ' : produc_id ,
2010-04-06 06:52:09 +00:00
' location_dest_id ' : False
2008-11-28 14:44:41 +00:00
}
2008-12-03 15:06:41 +00:00
}
2008-11-28 14:44:41 +00:00
mrp_repair_line ( )
class mrp_repair_fee ( osv . osv , ProductChangeMixin ) :
_name = ' mrp.repair.fee '
2010-05-19 18:32:32 +00:00
_description = ' Repair Fees Line '
2010-08-13 12:20:05 +00:00
2009-02-04 13:12:10 +00:00
def copy_data ( self , cr , uid , id , default = None , context = None ) :
2008-11-28 14:44:41 +00:00
if not default : default = { }
2010-04-06 06:52:09 +00:00
default . update ( { ' invoice_line_id ' : False , ' invoiced ' : False } )
2009-02-04 13:12:10 +00:00
return super ( mrp_repair_fee , self ) . copy_data ( cr , uid , id , default , context )
2010-08-13 12:20:05 +00:00
2008-11-28 14:44:41 +00:00
def _amount_line ( self , cr , uid , ids , field_name , arg , context ) :
2010-04-06 06:52:09 +00:00
""" Calculates amount.
@param field_name : Name of field .
@param arg : Argument
2010-08-13 12:20:05 +00:00
@return : Dictionary of values .
2010-04-06 06:52:09 +00:00
"""
2008-11-28 14:44:41 +00:00
res = { }
2010-04-06 06:52:09 +00:00
cur_obj = self . pool . get ( ' res.currency ' )
2008-11-28 14:44:41 +00:00
for line in self . browse ( cr , uid , ids ) :
res [ line . id ] = line . to_invoice and line . price_unit * line . product_uom_qty or 0
cur = line . repair_id . pricelist_id . currency_id
res [ line . id ] = cur_obj . round ( cr , uid , cur , res [ line . id ] )
return res
_columns = {
2009-12-22 09:38:41 +00:00
' repair_id ' : fields . many2one ( ' mrp.repair ' , ' Repair Order Reference ' , required = True , ondelete = ' cascade ' , select = True ) ,
2008-11-28 14:44:41 +00:00
' name ' : fields . char ( ' Description ' , size = 64 , select = True , required = True ) ,
' product_id ' : fields . many2one ( ' product.product ' , ' Product ' ) ,
' product_uom_qty ' : fields . float ( ' Quantity ' , digits = ( 16 , 2 ) , required = True ) ,
' price_unit ' : fields . float ( ' Unit Price ' , required = True ) ,
' product_uom ' : fields . many2one ( ' product.uom ' , ' Product UoM ' , required = True ) ,
2010-03-06 20:52:19 +00:00
' price_subtotal ' : fields . function ( _amount_line , method = True , string = ' Subtotal ' , digits_compute = dp . get_precision ( ' Sale Price ' ) ) ,
2008-11-28 14:44:41 +00:00
' tax_id ' : fields . many2many ( ' account.tax ' , ' repair_fee_line_tax ' , ' repair_fee_line_id ' , ' tax_id ' , ' Taxes ' ) ,
' invoice_line_id ' : fields . many2one ( ' account.invoice.line ' , ' Invoice Line ' , readonly = True ) ,
' to_invoice ' : fields . boolean ( ' To Invoice ' ) ,
' invoiced ' : fields . boolean ( ' Invoiced ' , readonly = True ) ,
}
_defaults = {
' to_invoice ' : lambda * a : True ,
}
2009-01-20 08:48:19 +00:00
2008-11-28 14:44:41 +00:00
mrp_repair_fee ( )
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: