2010-01-18 10:43:33 +00:00
# -*- encoding: utf-8 -*-
##############################################################################
#
2010-04-09 00:32:46 +00:00
# OpenERP, Open Source Management Solution
2010-08-05 11:23:26 +00:00
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
2010-01-18 10:43:33 +00:00
# $Id$
#
# This program is free software: you can redistribute it and/or modify
2010-10-28 06:54:18 +00:00
# it under the terms of the GNU Affero General Public License as published by
2010-01-18 10:43:33 +00:00
# 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
2010-10-28 06:54:18 +00:00
# GNU Affero General Public License for more details.
2010-01-18 10:43:33 +00:00
#
2010-10-28 06:54:18 +00:00
# You should have received a copy of the GNU Affero General Public License
2010-01-18 10:43:33 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
2011-12-02 07:27:55 +00:00
from datetime import datetime
from dateutil . relativedelta import relativedelta
2010-06-23 11:53:20 +00:00
import time
2013-07-30 10:31:27 +00:00
from openerp . osv import fields , osv
2012-12-06 14:56:32 +00:00
from openerp . tools . translate import _
2012-12-17 15:23:03 +00:00
import openerp . addons . decimal_precision as dp
2010-01-18 10:43:33 +00:00
2010-04-09 07:18:17 +00:00
class purchase_requisition ( osv . osv ) :
_name = " purchase.requisition "
2013-07-30 10:31:27 +00:00
_description = " Purchase Requisition "
2012-08-22 15:31:45 +00:00
_inherit = [ ' mail.thread ' , ' ir.needaction_mixin ' ]
2013-05-29 09:51:50 +00:00
def _get_po_line ( self , cr , uid , ids , field_names , arg = None , context = None ) :
2013-07-31 17:16:25 +00:00
result = { } . fromkeys ( ids , [ ] )
2013-05-29 09:51:50 +00:00
for element in self . browse ( cr , uid , ids , context = context ) :
for po in element . purchase_ids :
2013-07-31 17:16:25 +00:00
result [ element . id ] + = [ po_line . id for po_line in po . order_line ]
2013-05-29 09:51:50 +00:00
return result
2010-01-18 10:43:33 +00:00
_columns = {
2013-07-30 10:31:27 +00:00
' name ' : fields . char ( ' Call for Bids Reference ' , size = 32 , required = True ) ,
2012-10-08 10:41:51 +00:00
' origin ' : fields . char ( ' Source Document ' , size = 32 ) ,
2013-07-31 17:16:25 +00:00
' ordering_date ' : fields . date ( ' Scheduled Ordering Date ' ) ,
2013-06-19 12:59:51 +00:00
' date_end ' : fields . datetime ( ' Bid Submission Deadline ' ) ,
2013-07-31 17:16:25 +00:00
' schedule_date ' : fields . date ( ' Scheduled Date ' , select = True , help = " The expected and scheduled date where all the products are received " ) ,
2010-01-18 10:43:33 +00:00
' user_id ' : fields . many2one ( ' res.users ' , ' Responsible ' ) ,
2013-07-30 10:31:27 +00:00
' exclusive ' : fields . selection ( [ ( ' exclusive ' , ' Select only one RFQ (exclusive) ' ) , ( ' multiple ' , ' Select multiple RFQ ' ) ] , ' Bid Selection Type ' , required = True , help = " Select only one RFQ (exclusive): On the confirmation of a purchase order, it cancels the remaining purchase order. \n Select multiple RFQ: It allows to have multiple purchase orders.On confirmation of a purchase order it does not cancel the remaining orders " " " ) ,
2010-01-18 10:43:33 +00:00
' description ' : fields . text ( ' Description ' ) ,
2010-04-23 07:24:58 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = True ) ,
2013-07-30 10:31:27 +00:00
' purchase_ids ' : fields . one2many ( ' purchase.order ' , ' requisition_id ' , ' Purchase Orders ' , states = { ' done ' : [ ( ' readonly ' , True ) ] } ) ,
2013-05-29 09:51:50 +00:00
' po_line_ids ' : fields . function ( _get_po_line , method = True , type = ' one2many ' , relation = ' purchase.order.line ' , string = ' Products by supplier ' ) ,
2013-07-31 17:16:25 +00:00
' line_ids ' : fields . one2many ( ' purchase.requisition.line ' , ' requisition_id ' , ' Products to Purchase ' , states = { ' done ' : [ ( ' readonly ' , True ) ] } ) ,
2014-02-17 15:05:38 +00:00
' procurement_id ' : fields . many2one ( ' procurement.order ' , ' Procurement ' , ondelete = ' set null ' ) ,
2013-07-30 10:31:27 +00:00
' warehouse_id ' : fields . many2one ( ' stock.warehouse ' , ' Warehouse ' ) ,
' state ' : fields . selection ( [ ( ' draft ' , ' Draft ' ) , ( ' in_progress ' , ' Confirmed ' ) , ( ' open ' , ' Bid Selection ' ) , ( ' done ' , ' PO Created ' ) , ( ' cancel ' , ' Cancelled ' ) ] ,
2013-05-31 07:38:56 +00:00
' Status ' , track_visibility = ' onchange ' , required = True ) ,
' multiple_rfq_per_supplier ' : fields . boolean ( ' Multiple RFQ per supplier ' ) ,
2013-07-30 10:31:27 +00:00
' account_analytic_id ' : fields . many2one ( ' account.analytic.account ' , ' Analytic Account ' ) ,
2013-09-10 09:12:18 +00:00
' picking_type_id ' : fields . many2one ( ' stock.picking.type ' , ' Picking Type ' , required = True ) ,
2010-01-18 10:43:33 +00:00
}
2013-09-10 09:12:18 +00:00
def _get_picking_in ( self , cr , uid , context = None ) :
obj_data = self . pool . get ( ' ir.model.data ' )
return obj_data . get_object_reference ( cr , uid , ' stock ' , ' picking_type_in ' ) [ 1 ]
2010-01-18 10:43:33 +00:00
_defaults = {
2010-06-23 11:53:20 +00:00
' state ' : ' draft ' ,
' exclusive ' : ' multiple ' ,
2010-07-01 06:59:57 +00:00
' company_id ' : lambda self , cr , uid , c : self . pool . get ( ' res.company ' ) . _company_default_get ( cr , uid , ' purchase.requisition ' , context = c ) ,
2013-07-30 10:31:27 +00:00
' user_id ' : lambda self , cr , uid , c : self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , c ) . id ,
2010-04-09 07:18:17 +00:00
' name ' : lambda obj , cr , uid , context : obj . pool . get ( ' ir.sequence ' ) . get ( cr , uid , ' purchase.order.requisition ' ) ,
2013-09-10 09:12:18 +00:00
' picking_type_id ' : _get_picking_in ,
2010-01-18 10:43:33 +00:00
}
2010-04-16 04:42:36 +00:00
2010-11-22 10:37:53 +00:00
def copy ( self , cr , uid , id , default = None , context = None ) :
2013-07-31 17:16:25 +00:00
default = default or { }
2010-08-25 11:39:56 +00:00
default . update ( {
2013-07-30 10:31:27 +00:00
' state ' : ' draft ' ,
' purchase_ids ' : [ ] ,
2010-08-25 11:39:56 +00:00
' name ' : self . pool . get ( ' ir.sequence ' ) . get ( cr , uid , ' purchase.order.requisition ' ) ,
} )
return super ( purchase_requisition , self ) . copy ( cr , uid , id , default , context )
2013-07-30 10:31:27 +00:00
2010-06-23 11:53:20 +00:00
def tender_cancel ( self , cr , uid , ids , context = None ) :
2010-04-12 06:58:25 +00:00
purchase_order_obj = self . pool . get ( ' purchase.order ' )
2013-05-31 12:24:24 +00:00
#try to set all associated quotations to cancel state
2013-07-31 17:16:25 +00:00
purchase_ids = [ ]
for tender in self . browse ( cr , uid , ids , context = context ) :
2013-08-06 12:38:01 +00:00
for purchase_order in tender . purchase_ids :
purchase_order_obj . action_cancel ( cr , uid , [ purchase_order . id ] , context = context )
purchase_order_obj . message_post ( cr , uid , [ purchase_order . id ] , body = _ ( ' Cancelled by the tender associated to this quotation. ' ) , context = context )
2012-12-18 17:03:06 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' cancel ' } )
2010-07-01 06:59:57 +00:00
2010-06-23 11:53:20 +00:00
def tender_in_progress ( self , cr , uid , ids , context = None ) :
2013-07-30 10:31:27 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' in_progress ' } , context = context )
2010-07-01 06:59:57 +00:00
2013-05-29 09:51:50 +00:00
def tender_open ( self , cr , uid , ids , context = None ) :
2013-07-30 10:31:27 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' open ' } , context = context )
2010-07-01 06:59:57 +00:00
2010-06-23 11:53:20 +00:00
def tender_reset ( self , cr , uid , ids , context = None ) :
2013-06-11 13:03:43 +00:00
self . write ( cr , uid , ids , { ' state ' : ' draft ' } )
for p_id in ids :
# Deleting the existing instance of workflow for PO
2013-07-30 14:33:01 +00:00
self . delete_workflow ( cr , uid , [ p_id ] )
self . create_workflow ( cr , uid , [ p_id ] )
2013-06-11 13:03:43 +00:00
return True
2010-07-01 06:59:57 +00:00
2010-06-23 11:53:20 +00:00
def tender_done ( self , cr , uid , ids , context = None ) :
2013-07-31 17:16:25 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' done ' } , context = context )
2011-12-02 07:27:55 +00:00
2013-05-29 09:51:50 +00:00
def open_product_line ( self , cr , uid , ids , context = None ) :
""" This opens product line view to view all lines from the different quotations, groupby default by product and partner to show comparaison
between supplier price
@return : the product line tree view
"""
if context is None :
context = { }
2013-07-30 10:31:27 +00:00
res = self . pool . get ( ' ir.actions.act_window ' ) . for_xml_id ( cr , uid , ' purchase_requisition ' , ' purchase_line_tree ' , context = context )
2013-05-29 09:51:50 +00:00
res [ ' context ' ] = context
2013-11-04 10:26:46 +00:00
po_lines = self . browse ( cr , uid , ids , context = context ) [ 0 ] . po_line_ids
res [ ' context ' ] = {
2013-07-30 10:31:27 +00:00
' search_default_groupby_product ' : True ,
2013-06-04 13:48:41 +00:00
' search_default_hide_cancelled ' : True ,
2013-11-04 10:26:46 +00:00
}
res [ ' domain ' ] = [ ( ' id ' , ' in ' , [ line . id for line in po_lines ] ) ]
2013-05-29 09:51:50 +00:00
return res
2013-06-19 14:56:12 +00:00
def open_rfq ( self , cr , uid , ids , context = None ) :
2013-06-25 09:49:27 +00:00
""" This opens rfq view to view all quotations associated to the call for bids
2013-06-19 14:56:12 +00:00
@return : the RFQ tree view
"""
if context is None :
context = { }
2013-07-30 10:31:27 +00:00
res = self . pool . get ( ' ir.actions.act_window ' ) . for_xml_id ( cr , uid , ' purchase ' , ' purchase_rfq ' , context = context )
2013-06-19 14:56:12 +00:00
res [ ' context ' ] = context
2013-07-31 17:16:25 +00:00
po_ids = [ po . id for po in self . browse ( cr , uid , ids , context = context ) [ 0 ] . purchase_ids ]
2013-07-30 10:31:27 +00:00
res [ ' domain ' ] = [ ( ' id ' , ' in ' , po_ids ) ]
2013-06-19 14:56:12 +00:00
return res
2012-06-04 13:26:53 +00:00
2013-06-03 12:59:00 +00:00
def _prepare_purchase_order ( self , cr , uid , requisition , supplier , context = None ) :
2013-07-31 17:16:25 +00:00
supplier_pricelist = supplier . property_product_pricelist_purchase and supplier . property_product_pricelist_purchase . id or False
2013-09-10 15:48:22 +00:00
picking_type_in = self . pool . get ( " purchase.order " ) . _get_picking_in ( cr , uid , context = context )
2013-06-03 12:59:00 +00:00
return {
' origin ' : requisition . name ,
2013-08-06 09:37:17 +00:00
' date_order ' : requisition . date_end or fields . date . context_today ( self , cr , uid , context = context ) ,
2013-06-03 12:59:00 +00:00
' partner_id ' : supplier . id ,
2013-07-31 17:16:25 +00:00
' pricelist_id ' : supplier_pricelist ,
2013-09-10 09:12:18 +00:00
' location_id ' : requisition . picking_type_id . default_location_dest_id . id ,
2013-06-03 12:59:00 +00:00
' company_id ' : requisition . company_id . id ,
' fiscal_position ' : supplier . property_account_position and supplier . property_account_position . id or False ,
2013-07-30 10:31:27 +00:00
' requisition_id ' : requisition . id ,
' notes ' : requisition . description ,
2013-09-10 15:48:22 +00:00
' picking_type_id ' : picking_type_in ,
2013-06-03 12:59:00 +00:00
}
2011-12-02 07:27:55 +00:00
2013-06-04 08:59:56 +00:00
def _prepare_purchase_order_line ( self , cr , uid , requisition , requisition_line , purchase_id , supplier , context = None ) :
2013-07-31 17:16:25 +00:00
po_line_obj = self . pool . get ( ' purchase.order.line ' )
2011-12-02 07:27:55 +00:00
product_uom = self . pool . get ( ' product.uom ' )
product = requisition_line . product_id
default_uom_po_id = product . uom_po_id . id
2013-07-31 17:16:25 +00:00
date_order = requisition . ordering_date or fields . date . context_today ( self , cr , uid , context = context )
2011-12-02 07:27:55 +00:00
qty = product_uom . _compute_qty ( cr , uid , requisition_line . product_uom_id . id , requisition_line . product_qty , default_uom_po_id )
2013-07-31 17:16:25 +00:00
supplier_pricelist = supplier . property_product_pricelist_purchase and supplier . property_product_pricelist_purchase . id or False
vals = po_line_obj . onchange_product_id ( cr , uid , [ ] , supplier_pricelist , product . id , qty , default_uom_po_id ,
supplier . id , date_order = date_order , fiscal_position_id = supplier . property_account_position , date_planned = requisition_line . schedule_date ,
name = False , price_unit = False , state = ' draft ' , context = context ) [ ' value ' ]
vals . update ( {
2013-06-03 12:59:00 +00:00
' order_id ' : purchase_id ,
' product_id ' : product . id ,
2013-07-31 17:16:25 +00:00
' account_analytic_id ' : requisition_line . account_analytic_id . id ,
} )
return vals
2011-12-02 07:27:55 +00:00
def make_purchase_order ( self , cr , uid , ids , partner_id , context = None ) :
"""
Create New RFQ for Supplier
"""
if context is None :
context = { }
assert partner_id , ' Supplier should be specified '
purchase_order = self . pool . get ( ' purchase.order ' )
purchase_order_line = self . pool . get ( ' purchase.order.line ' )
res_partner = self . pool . get ( ' res.partner ' )
supplier = res_partner . browse ( cr , uid , partner_id , context = context )
res = { }
for requisition in self . browse ( cr , uid , ids , context = context ) :
2013-07-30 10:31:27 +00:00
if not requisition . multiple_rfq_per_supplier and supplier . id in filter ( lambda x : x , [ rfq . state != ' cancel ' and rfq . partner_id . id or None for rfq in requisition . purchase_ids ] ) :
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( ' You have already one %s purchase order for this partner, you must cancel this purchase order to create a new quotation. ' ) % rfq . state )
2013-03-05 10:48:01 +00:00
context . update ( { ' mail_create_nolog ' : True } )
2013-06-03 12:59:00 +00:00
purchase_id = purchase_order . create ( cr , uid , self . _prepare_purchase_order ( cr , uid , requisition , supplier , context = context ) , context = context )
2013-02-20 05:42:49 +00:00
purchase_order . message_post ( cr , uid , [ purchase_id ] , body = _ ( " RFQ created " ) , context = context )
2011-12-02 07:27:55 +00:00
res [ requisition . id ] = purchase_id
for line in requisition . line_ids :
2013-06-04 08:59:56 +00:00
purchase_order_line . create ( cr , uid , self . _prepare_purchase_order_line ( cr , uid , requisition , line , purchase_id , supplier , context = context ) , context = context )
2011-12-02 07:27:55 +00:00
return res
2013-05-31 07:38:56 +00:00
def check_valid_quotation ( self , cr , uid , quotation , context = None ) :
"""
Check if a quotation has all his order lines bid in order to confirm it if its the case
return True if all order line have been selected during bidding process , else return False
2010-01-18 10:43:33 +00:00
2013-05-31 07:38:56 +00:00
args : ' quotation ' must be a browse record
"""
for line in quotation . order_line :
if line . state != ' confirmed ' or line . product_qty != line . quantity_bid :
return False
return True
2010-07-01 06:59:57 +00:00
2013-11-04 10:19:57 +00:00
def _prepare_po_from_tender ( self , cr , uid , tender , context = None ) :
""" Prepare the values to write in the purchase order
2013-11-04 14:07:24 +00:00
created from a tender .
2013-11-04 10:19:57 +00:00
: param tender : the source tender from which we generate a purchase order
"""
return { ' order_line ' : [ ] ,
' requisition_id ' : tender . id ,
' origin ' : tender . name }
2013-11-04 14:07:24 +00:00
def _prepare_po_line_from_tender ( self , cr , uid , tender , line , purchase_id , context = None ) :
2013-11-04 10:19:57 +00:00
""" Prepare the values to write in the purchase order line
2013-11-04 14:07:24 +00:00
created from a line of the tender .
2013-11-04 10:19:57 +00:00
: param tender : the source tender from which we generate a purchase order
: param line : the source tender ' s line from which we generate a line
: param purchase_id : the id of the new purchase
"""
return { ' product_qty ' : line . quantity_bid ,
' order_id ' : purchase_id }
2013-07-31 17:16:25 +00:00
def generate_po ( self , cr , uid , ids , context = None ) :
2013-05-29 09:51:50 +00:00
"""
Generate all purchase order based on selected lines , should only be called on one tender at a time
"""
2013-07-31 17:16:25 +00:00
if context is None :
contex = { }
2013-05-29 12:28:33 +00:00
po = self . pool . get ( ' purchase.order ' )
poline = self . pool . get ( ' purchase.order.line ' )
2013-05-29 09:51:50 +00:00
id_per_supplier = { }
2013-07-31 17:16:25 +00:00
for tender in self . browse ( cr , uid , ids , context = context ) :
if tender . state == ' done ' :
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( ' You have already generate the purchase order(s). ' ) )
2013-05-31 07:38:56 +00:00
2013-07-31 17:16:25 +00:00
confirm = False
#check that we have at least confirm one line
2013-06-21 14:07:40 +00:00
for po_line in tender . po_line_ids :
if po_line . state == ' confirmed ' :
confirm = True
break
if not confirm :
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( ' You have no line selected for buying. ' ) )
2013-05-31 07:38:56 +00:00
2013-07-31 17:16:25 +00:00
#check for complete RFQ
for quotation in tender . purchase_ids :
if ( self . check_valid_quotation ( cr , uid , quotation , context = context ) ) :
#use workflow to set PO state to confirm
po . signal_purchase_confirm ( cr , uid , [ quotation . id ] )
2010-07-01 06:59:57 +00:00
2013-07-31 17:16:25 +00:00
#get other confirmed lines per supplier
for po_line in tender . po_line_ids :
#only take into account confirmed line that does not belong to already confirmed purchase order
if po_line . state == ' confirmed ' and po_line . order_id . state in [ ' draft ' , ' sent ' , ' bid ' ] :
if id_per_supplier . get ( po_line . partner_id . id ) :
id_per_supplier [ po_line . partner_id . id ] . append ( po_line )
else :
id_per_supplier [ po_line . partner_id . id ] = [ po_line ]
#generate po based on supplier and cancel all previous RFQ
ctx = context . copy ( )
ctx [ ' force_requisition_id ' ] = True
for supplier , product_line in id_per_supplier . items ( ) :
#copy a quotation for this supplier and change order_line then validate it
quotation_id = po . search ( cr , uid , [ ( ' requisition_id ' , ' = ' , tender . id ) , ( ' partner_id ' , ' = ' , supplier ) ] , limit = 1 ) [ 0 ]
2013-11-04 10:19:57 +00:00
vals = self . _prepare_po_from_tender ( cr , uid , tender , context = context )
2013-11-04 14:07:24 +00:00
new_po = po . copy ( cr , uid , quotation_id , default = vals , context = ctx )
2013-07-31 17:16:25 +00:00
#duplicate po_line and change product_qty if needed and associate them to newly created PO
for line in product_line :
2013-11-04 14:07:24 +00:00
vals = self . _prepare_po_line_from_tender ( cr , uid , tender , line , new_po , context = context )
2013-11-04 10:19:57 +00:00
poline . copy ( cr , uid , line . id , default = vals , context = context )
2013-07-31 17:16:25 +00:00
#use workflow to set new PO state to confirm
po . signal_purchase_confirm ( cr , uid , [ new_po ] )
#cancel other orders
self . cancel_unconfirmed_quotations ( cr , uid , tender , context = context )
#set tender to state done
self . signal_done ( cr , uid , [ tender . id ] )
2013-05-31 07:38:56 +00:00
return True
2013-06-04 13:27:39 +00:00
2013-07-31 17:16:25 +00:00
def cancel_unconfirmed_quotations ( self , cr , uid , tender , context = None ) :
2013-06-04 13:27:39 +00:00
#cancel other orders
2013-06-04 15:39:38 +00:00
po = self . pool . get ( ' purchase.order ' )
2013-06-04 13:27:39 +00:00
for quotation in tender . purchase_ids :
if quotation . state in [ ' draft ' , ' sent ' , ' bid ' ] :
2013-07-30 14:33:01 +00:00
self . pool . get ( ' purchase.order ' ) . signal_purchase_cancel ( cr , uid , [ quotation . id ] )
2013-06-25 09:49:27 +00:00
po . message_post ( cr , uid , [ quotation . id ] , body = _ ( ' Cancelled by the call for bids associated to this request for quotation. ' ) , context = context )
2013-06-04 13:27:39 +00:00
return True
2010-01-18 10:43:33 +00:00
2010-07-01 06:59:57 +00:00
2013-07-30 10:31:27 +00:00
class purchase_requisition_line ( osv . osv ) :
2010-04-09 07:18:17 +00:00
_name = " purchase.requisition.line "
2013-07-30 10:31:27 +00:00
_description = " Purchase Requisition Line "
2010-04-09 00:32:46 +00:00
_rec_name = ' product_id '
2010-07-01 06:59:57 +00:00
2010-04-09 00:32:46 +00:00
_columns = {
2013-07-30 10:31:27 +00:00
' product_id ' : fields . many2one ( ' product.product ' , ' Product ' ) ,
2012-04-25 12:09:08 +00:00
' product_uom_id ' : fields . many2one ( ' product.uom ' , ' Product Unit of Measure ' ) ,
' product_qty ' : fields . float ( ' Quantity ' , digits_compute = dp . get_precision ( ' Product Unit of Measure ' ) ) ,
2013-07-30 10:31:27 +00:00
' requisition_id ' : fields . many2one ( ' purchase.requisition ' , ' Call for Bids ' , ondelete = ' cascade ' ) ,
' company_id ' : fields . related ( ' requisition_id ' , ' company_id ' , type = ' many2one ' , relation = ' res.company ' , string = ' Company ' , store = True , readonly = True ) ,
' account_analytic_id ' : fields . many2one ( ' account.analytic.account ' , ' Analytic Account ' , ) ,
2013-06-11 13:03:43 +00:00
' schedule_date ' : fields . date ( ' Scheduled Date ' ) ,
2010-04-09 00:32:46 +00:00
}
2010-04-12 10:23:28 +00:00
2013-06-06 13:10:26 +00:00
def onchange_product_id ( self , cr , uid , ids , product_id , product_uom_id , parent_analytic_account , analytic_account , parent_date , date , context = None ) :
2010-04-09 13:57:28 +00:00
""" Changes UoM and name if product_id changes.
@param name : Name of the field
@param product_id : Changed product_id
@return : Dictionary of changed values
"""
2010-05-20 11:10:36 +00:00
value = { ' product_uom_id ' : ' ' }
2010-04-09 13:57:28 +00:00
if product_id :
2010-11-23 11:31:52 +00:00
prod = self . pool . get ( ' product.product ' ) . browse ( cr , uid , product_id , context = context )
2013-07-30 10:31:27 +00:00
value = { ' product_uom_id ' : prod . uom_id . id , ' product_qty ' : 1.0 }
2013-06-06 13:10:26 +00:00
if not analytic_account :
value . update ( { ' account_analytic_id ' : parent_analytic_account } )
if not date :
value . update ( { ' schedule_date ' : parent_date } )
2010-04-09 13:57:28 +00:00
return { ' value ' : value }
2010-05-05 12:48:59 +00:00
2010-04-23 07:24:58 +00:00
_defaults = {
2010-07-01 06:59:57 +00:00
' company_id ' : lambda self , cr , uid , c : self . pool . get ( ' res.company ' ) . _company_default_get ( cr , uid , ' purchase.requisition.line ' , context = c ) ,
2010-08-13 12:20:05 +00:00
}
2010-04-09 00:32:46 +00:00
2010-01-18 10:43:33 +00:00
class purchase_order ( osv . osv ) :
_inherit = " purchase.order "
2013-05-31 07:38:56 +00:00
2010-01-18 10:43:33 +00:00
_columns = {
2013-07-30 10:31:27 +00:00
' requisition_id ' : fields . many2one ( ' purchase.requisition ' , ' Call for Bids ' ) ,
2010-01-18 10:43:33 +00:00
}
2012-06-04 13:26:53 +00:00
2010-11-22 10:37:53 +00:00
def wkf_confirm_order ( self , cr , uid , ids , context = None ) :
res = super ( purchase_order , self ) . wkf_confirm_order ( cr , uid , ids , context = context )
2011-03-08 14:52:52 +00:00
proc_obj = self . pool . get ( ' procurement.order ' )
2010-11-22 10:37:53 +00:00
for po in self . browse ( cr , uid , ids , context = context ) :
2013-07-30 10:31:27 +00:00
if po . requisition_id and ( po . requisition_id . exclusive == ' exclusive ' ) :
2010-04-09 07:18:17 +00:00
for order in po . requisition_id . purchase_ids :
2012-06-27 14:48:36 +00:00
if order . id != po . id :
2010-07-09 11:35:54 +00:00
proc_ids = proc_obj . search ( cr , uid , [ ( ' purchase_id ' , ' = ' , order . id ) ] )
2013-07-30 10:31:27 +00:00
if proc_ids and po . state == ' confirmed ' :
2011-02-25 11:40:03 +00:00
proc_obj . write ( cr , uid , proc_ids , { ' purchase_id ' : po . id } )
2013-01-31 10:30:15 +00:00
self . signal_purchase_cancel ( cr , uid , [ order . id ] )
2011-12-02 05:15:06 +00:00
po . requisition_id . tender_done ( context = context )
2010-01-18 10:43:33 +00:00
return res
2010-04-09 00:32:46 +00:00
2013-06-06 13:33:28 +00:00
def copy ( self , cr , uid , id , default = None , context = None ) :
2013-07-31 17:16:25 +00:00
if context is None :
context = { }
if not context . get ( ' force_requisition_id ' ) :
default = default or { }
default . update ( { ' requisition_id ' : False } )
2013-07-30 10:31:27 +00:00
return super ( purchase_order , self ) . copy ( cr , uid , id , default = default , context = context )
2010-04-23 07:24:58 +00:00
2014-02-17 15:05:38 +00:00
def _prepare_order_line_move ( self , cr , uid , order , order_line , picking_id , group_id , context = None ) :
stock_move_lines = super ( purchase_order , self ) . _prepare_order_line_move ( cr , uid , order , order_line , picking_id , group_id , context = context )
if order . requisition_id and order . requisition_id . procurement_id and order . requisition_id . procurement_id . move_dest_id :
for i in range ( 0 , len ( stock_move_lines ) ) :
stock_move_lines [ i ] [ ' move_dest_id ' ] = order . requisition_id . procurement_id . move_dest_id . id
return stock_move_lines
2013-07-29 09:40:43 +00:00
2013-05-29 09:51:50 +00:00
class purchase_order_line ( osv . osv ) :
_inherit = ' purchase.order.line '
2013-07-30 10:31:27 +00:00
_columns = {
2013-07-31 17:16:25 +00:00
' quantity_bid ' : fields . float ( ' Quantity Bid ' , digits_compute = dp . get_precision ( ' Product Unit of Measure ' ) , help = " Technical field for not loosing the initial information about the quantity proposed in the bid " ) ,
2013-05-29 09:51:50 +00:00
}
def action_draft ( self , cr , uid , ids , context = None ) :
self . write ( cr , uid , ids , { ' state ' : ' draft ' } , context = context )
def action_confirm ( self , cr , uid , ids , context = None ) :
super ( purchase_order_line , self ) . action_confirm ( cr , uid , ids , context = context )
for element in self . browse ( cr , uid , ids , context = context ) :
if not element . quantity_bid :
self . write ( cr , uid , ids , { ' quantity_bid ' : element . product_qty } , context = context )
return True
2013-07-31 17:16:25 +00:00
def generate_po ( self , cr , uid , tender_id , context = None ) :
#call generate_po from tender with active_id. Called from js widget
return self . pool . get ( ' purchase.requisition ' ) . generate_po ( cr , uid , [ tender_id ] , context = context )
2013-07-30 10:31:27 +00:00
2010-04-23 07:24:58 +00:00
2014-05-27 07:42:52 +00:00
class product_template ( osv . osv ) :
_inherit = ' product.template '
2010-07-01 06:59:57 +00:00
2010-04-09 00:32:46 +00:00
_columns = {
2013-06-19 12:59:51 +00:00
' purchase_requisition ' : fields . boolean ( ' Call for Bids ' , help = " Check this box to generate Call for Bids instead of generating requests for quotation from procurement. " )
2010-04-09 00:32:46 +00:00
}
2010-05-27 12:47:06 +00:00
class procurement_order ( osv . osv ) :
_inherit = ' procurement.order '
2010-07-09 09:26:48 +00:00
_columns = {
2013-07-30 10:31:27 +00:00
' requisition_id ' : fields . many2one ( ' purchase.requisition ' , ' Latest Requisition ' )
2010-07-09 09:26:48 +00:00
}
2013-07-31 17:16:25 +00:00
def _run ( self , cr , uid , procurement , context = None ) :
2012-06-19 13:33:00 +00:00
requisition_obj = self . pool . get ( ' purchase.requisition ' )
2012-06-21 06:00:34 +00:00
warehouse_obj = self . pool . get ( ' stock.warehouse ' )
2014-01-21 14:54:44 +00:00
if procurement . rule_id and procurement . rule_id . action == ' buy ' and procurement . product_id . purchase_requisition :
2013-07-30 14:33:01 +00:00
warehouse_id = warehouse_obj . search ( cr , uid , [ ( ' company_id ' , ' = ' , procurement . company_id . id ) ] , context = context )
2013-07-31 17:16:25 +00:00
requisition_id = requisition_obj . create ( cr , uid , {
2013-07-30 10:31:27 +00:00
' origin ' : procurement . origin ,
' date_end ' : procurement . date_planned ,
' warehouse_id ' : warehouse_id and warehouse_id [ 0 ] or False ,
' company_id ' : procurement . company_id . id ,
2014-02-17 15:05:38 +00:00
' procurement_id ' : procurement . id ,
2013-07-30 10:31:27 +00:00
' line_ids ' : [ ( 0 , 0 , {
' product_id ' : procurement . product_id . id ,
' product_uom_id ' : procurement . product_uom . id ,
' product_qty ' : procurement . product_qty
} ) ] ,
} )
2014-02-17 15:05:38 +00:00
self . message_post ( cr , uid , [ procurement . id ] , body = _ ( " Purchase Requisition created " ) , context = context )
2013-07-31 17:16:25 +00:00
return self . write ( cr , uid , [ procurement . id ] , { ' requisition_id ' : requisition_id } , context = context )
return super ( procurement_order , self ) . _run ( cr , uid , procurement , context = context )
2010-07-01 06:59:57 +00:00
2014-02-17 15:05:38 +00:00
def _check ( self , cr , uid , procurement , context = None ) :
requisition_obj = self . pool . get ( ' purchase.requisition ' )
if procurement . rule_id and procurement . rule_id . action == ' buy ' and procurement . product_id . purchase_requisition :
if procurement . requisition_id . state == ' done ' :
if any ( [ purchase . shipped for purchase in procurement . requisition_id . purchase_ids ] ) :
return True
return False
return super ( procurement_order , self ) . _check ( cr , uid , procurement , context = context )
2010-06-23 11:53:20 +00:00
2010-08-24 12:37:11 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: