2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2006-12-07 13:41:40 +00:00
##############################################################################
2011-05-12 13:25:34 +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>).
2008-06-16 11:00:21 +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
2011-05-12 13:25:34 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2006-12-07 13:41:40 +00:00
#
##############################################################################
2009-10-14 11:15:34 +00:00
2008-09-20 08:50:20 +00:00
import time
2008-12-12 00:53:47 +00:00
from osv import fields , osv
2008-07-08 08:13:12 +00:00
from tools . translate import _
2006-12-07 13:41:40 +00:00
class delivery_carrier ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_name = " delivery.carrier "
2010-05-19 18:32:32 +00:00
_description = " Carrier "
2008-09-20 08:50:20 +00:00
2010-11-19 13:48:01 +00:00
def name_get ( self , cr , uid , ids , context = None ) :
2010-04-23 11:50:16 +00:00
if not len ( ids ) :
return [ ]
2010-11-23 07:05:05 +00:00
if context is None :
2010-11-19 13:48:01 +00:00
context = { }
2010-04-23 11:50:16 +00:00
order_id = context . get ( ' order_id ' , False )
if not order_id :
res = super ( delivery_carrier , self ) . name_get ( cr , uid , ids , context = context )
else :
2010-11-23 11:31:52 +00:00
order = self . pool . get ( ' sale.order ' ) . browse ( cr , uid , order_id , context = context )
2010-04-26 05:37:13 +00:00
currency = order . pricelist_id . currency_id . name or ' '
2010-04-23 11:50:16 +00:00
res = [ ( r [ ' id ' ] , r [ ' name ' ] + ' ( ' + ( str ( r [ ' price ' ] ) ) + ' ' + currency + ' ) ' ) for r in self . read ( cr , uid , ids , [ ' name ' , ' price ' ] , context ) ]
return res
2011-06-10 09:11:37 +00:00
2010-11-19 13:48:01 +00:00
def get_price ( self , cr , uid , ids , field_name , arg = None , context = None ) :
2008-09-20 08:50:20 +00:00
res = { }
2010-11-23 07:05:05 +00:00
if context is None :
2010-11-19 13:48:01 +00:00
context = { }
2008-09-20 08:50:20 +00:00
sale_obj = self . pool . get ( ' sale.order ' )
grid_obj = self . pool . get ( ' delivery.grid ' )
2010-11-19 13:48:01 +00:00
for carrier in self . browse ( cr , uid , ids , context = context ) :
2008-09-20 08:50:20 +00:00
order_id = context . get ( ' order_id ' , False )
price = False
2008-10-27 23:58:25 +00:00
if order_id :
2010-11-23 11:31:52 +00:00
order = sale_obj . browse ( cr , uid , order_id , context = context )
2008-09-20 08:50:20 +00:00
carrier_grid = self . grid_get ( cr , uid , [ carrier . id ] , order . partner_shipping_id . id , context )
2008-12-14 16:46:57 +00:00
if carrier_grid :
price = grid_obj . get_price ( cr , uid , carrier_grid , order , time . strftime ( ' % Y- % m- %d ' ) , context )
else :
price = 0.0
2008-10-27 23:58:25 +00:00
res [ carrier . id ] = price
2008-09-20 08:50:20 +00:00
return res
2011-06-10 09:11:37 +00:00
2008-07-22 15:11:28 +00:00
_columns = {
2011-10-01 22:18:03 +00:00
' name ' : fields . char ( ' Delivery Method ' , size = 64 , required = True ) ,
' partner_id ' : fields . many2one ( ' res.partner ' , ' Transport Company ' , required = True , help = " The partner that is doing the delivery service. " ) ,
2008-08-26 22:18:32 +00:00
' product_id ' : fields . many2one ( ' product.product ' , ' Delivery Product ' , required = True ) ,
' grids_id ' : fields . one2many ( ' delivery.grid ' , ' carrier_id ' , ' Delivery Grids ' ) ,
2011-07-06 14:56:44 +00:00
' price ' : fields . function ( get_price , string = ' Price ' ) ,
2011-05-12 13:25:34 +00:00
' active ' : fields . boolean ( ' Active ' , help = " If the active field is set to False, it will allow you to hide the delivery carrier without removing it. " ) ,
2011-10-01 22:18:03 +00:00
' normal_price ' : fields . float ( ' Normal Price ' , help = " Keep empty if the pricing depends on the advanced pricing per destination " ) ,
' free_if_more_than ' : fields . boolean ( ' Free If More Than ' , help = " If the order is more expensive than a certain amount, the customer can benefit from a free shipping " ) ,
' amount ' : fields . float ( ' Amount ' , help = " Amount of the order to benefit from a free shipping, expressed in the company currency " ) ,
' use_detailed_pricelist ' : fields . boolean ( ' Advanced Pricing per Destination ' , help = " Check this box if you want to manage delivery prices that depends on the destination, the weight, the total of the order, etc. " ) ,
2011-08-18 11:55:20 +00:00
' pricelist_ids ' : fields . one2many ( ' delivery.grid ' , ' carrier_id ' , ' Advanced Pricing ' ) ,
2008-07-22 15:11:28 +00:00
}
2011-05-13 07:50:46 +00:00
2008-07-22 15:11:28 +00:00
_defaults = {
2011-06-10 09:11:37 +00:00
' active ' : 1 ,
' free_if_more_than ' : False ,
2008-07-22 15:11:28 +00:00
}
2011-05-13 07:50:46 +00:00
2010-11-19 13:48:01 +00:00
def grid_get ( self , cr , uid , ids , contact_id , context = None ) :
2010-11-23 11:31:52 +00:00
contact = self . pool . get ( ' res.partner.address ' ) . browse ( cr , uid , contact_id , context = context )
2010-11-19 13:48:01 +00:00
for carrier in self . browse ( cr , uid , ids , context = context ) :
2008-07-22 15:11:28 +00:00
for grid in carrier . grids_id :
get_id = lambda x : x . id
country_ids = map ( get_id , grid . country_ids )
state_ids = map ( get_id , grid . state_ids )
if country_ids and not contact . country_id . id in country_ids :
continue
if state_ids and not contact . state_id . id in state_ids :
continue
if grid . zip_from and ( contact . zip or ' ' ) < grid . zip_from :
continue
if grid . zip_to and ( contact . zip or ' ' ) > grid . zip_to :
continue
return grid . id
return False
2011-05-12 13:25:34 +00:00
def create_grid_lines ( self , cr , uid , ids , vals , context = None ) :
2012-02-14 14:08:25 +00:00
if context is None :
2011-05-12 13:25:34 +00:00
context = { }
grid_line_pool = self . pool . get ( ' delivery.grid.line ' )
grid_pool = self . pool . get ( ' delivery.grid ' )
for record in self . browse ( cr , uid , ids , context = context ) :
2012-02-14 14:08:25 +00:00
# if using advanced pricing per destination: do not change
if record . use_detailed_pricelist :
continue
# not using advanced pricing per destination: override grid
2012-01-02 11:05:56 +00:00
grid_id = grid_pool . search ( cr , uid , [ ( ' carrier_id ' , ' = ' , record . id ) ] , context = context )
2011-10-01 22:18:03 +00:00
2012-02-14 14:08:25 +00:00
if grid_id and not ( record . normal_price or record . free_if_more_than ) :
grid_pool . unlink ( cr , uid , grid_id , context = context )
2011-10-01 22:18:03 +00:00
if not ( record . normal_price or record . free_if_more_than ) :
continue
2011-05-12 13:25:34 +00:00
if not grid_id :
2012-01-06 13:11:37 +00:00
grid_data = {
2011-10-01 22:18:03 +00:00
' name ' : record . name ,
2011-05-12 13:25:34 +00:00
' carrier_id ' : record . id ,
2012-01-02 11:05:56 +00:00
' sequence ' : 10 ,
2011-05-12 13:25:34 +00:00
}
2012-01-06 13:11:37 +00:00
grid_id = [ grid_pool . create ( cr , uid , grid_data , context = context ) ]
2011-05-12 13:25:34 +00:00
2011-10-01 22:18:03 +00:00
lines = grid_line_pool . search ( cr , uid , [ ( ' grid_id ' , ' in ' , grid_id ) ] , context = context )
if lines :
grid_line_pool . unlink ( cr , uid , lines , context = context )
2011-06-10 09:11:37 +00:00
#create the grid lines
2011-05-12 13:25:34 +00:00
if record . free_if_more_than :
2012-01-06 13:11:37 +00:00
line_data = {
2011-05-12 13:25:34 +00:00
' grid_id ' : grid_id and grid_id [ 0 ] ,
2011-10-01 22:18:03 +00:00
' name ' : _ ( ' Free if more than %.2f ' ) % record . amount ,
2011-05-12 13:25:34 +00:00
' type ' : ' price ' ,
' operator ' : ' >= ' ,
' max_value ' : record . amount ,
' standard_price ' : 0.0 ,
' list_price ' : 0.0 ,
}
2012-01-25 13:21:46 +00:00
grid_line_pool . create ( cr , uid , line_data , context = context )
2011-05-12 13:25:34 +00:00
if record . normal_price :
2012-01-06 13:11:37 +00:00
line_data = {
2011-05-12 13:25:34 +00:00
' grid_id ' : grid_id and grid_id [ 0 ] ,
' name ' : _ ( ' Default price ' ) ,
' type ' : ' price ' ,
2011-05-13 10:41:58 +00:00
' operator ' : ' >= ' ,
' max_value ' : 0.0 ,
2011-05-12 13:25:34 +00:00
' standard_price ' : record . normal_price ,
' list_price ' : record . normal_price ,
}
2012-01-06 13:11:37 +00:00
grid_line_pool . create ( cr , uid , line_data , context = context )
2011-05-12 13:25:34 +00:00
return True
def write ( self , cr , uid , ids , vals , context = None ) :
2012-02-10 15:16:49 +00:00
if isinstance ( ids , ( int , long ) ) :
ids = [ ids ]
res = super ( delivery_carrier , self ) . write ( cr , uid , ids , vals , context = context )
2011-05-12 13:25:34 +00:00
self . create_grid_lines ( cr , uid , ids , vals , context = context )
2012-02-10 15:16:49 +00:00
return res
2011-05-12 13:25:34 +00:00
def create ( self , cr , uid , vals , context = None ) :
2011-05-13 10:41:58 +00:00
res_id = super ( delivery_carrier , self ) . create ( cr , uid , vals , context = context )
2011-05-12 13:25:34 +00:00
self . create_grid_lines ( cr , uid , [ res_id ] , vals , context = context )
return res_id
2006-12-07 13:41:40 +00:00
delivery_carrier ( )
class delivery_grid ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_name = " delivery.grid "
2008-08-26 22:18:32 +00:00
_description = " Delivery Grid "
2008-07-22 15:11:28 +00:00
_columns = {
' name ' : fields . char ( ' Grid Name ' , size = 64 , required = True ) ,
2009-12-21 13:14:12 +00:00
' sequence ' : fields . integer ( ' Sequence ' , size = 64 , required = True , help = " Gives the sequence order when displaying a list of delivery grid. " ) ,
2008-07-22 15:11:28 +00:00
' carrier_id ' : fields . many2one ( ' delivery.carrier ' , ' Carrier ' , required = True , ondelete = ' cascade ' ) ,
' country_ids ' : fields . many2many ( ' res.country ' , ' delivery_grid_country_rel ' , ' grid_id ' , ' country_id ' , ' Countries ' ) ,
' state_ids ' : fields . many2many ( ' res.country.state ' , ' delivery_grid_state_rel ' , ' grid_id ' , ' state_id ' , ' States ' ) ,
' zip_from ' : fields . char ( ' Start Zip ' , size = 12 ) ,
' zip_to ' : fields . char ( ' To Zip ' , size = 12 ) ,
' line_ids ' : fields . one2many ( ' delivery.grid.line ' , ' grid_id ' , ' Grid Line ' ) ,
2010-11-15 13:15:55 +00:00
' active ' : fields . boolean ( ' Active ' , help = " If the active field is set to False, it will allow you to hide the delivery grid without removing it. " ) ,
2008-07-22 15:11:28 +00:00
}
_defaults = {
' active ' : lambda * a : 1 ,
' sequence ' : lambda * a : 1 ,
}
_order = ' sequence '
2010-11-19 13:48:01 +00:00
def get_price ( self , cr , uid , id , order , dt , context = None ) :
2008-07-22 15:11:28 +00:00
total = 0
weight = 0
2008-10-27 23:58:25 +00:00
volume = 0
for line in order . order_line :
2008-07-22 15:11:28 +00:00
if not line . product_id :
continue
total + = line . price_subtotal or 0.0
weight + = ( line . product_id . weight or 0.0 ) * line . product_uom_qty
volume + = ( line . product_id . volume or 0.0 ) * line . product_uom_qty
2010-11-19 13:48:01 +00:00
return self . get_price_from_picking ( cr , uid , id , total , weight , volume , context = context )
2008-07-22 15:11:28 +00:00
2010-11-19 13:48:01 +00:00
def get_price_from_picking ( self , cr , uid , id , total , weight , volume , context = None ) :
grid = self . browse ( cr , uid , id , context = context )
2008-07-22 15:11:28 +00:00
price = 0.0
ok = False
for line in grid . line_ids :
price_dict = { ' price ' : total , ' volume ' : volume , ' weight ' : weight , ' wv ' : volume * weight }
test = eval ( line . type + line . operator + str ( line . max_value ) , price_dict )
if test :
if line . price_type == ' variable ' :
price = line . list_price * price_dict [ line . variable_factor ]
else :
price = line . list_price
ok = True
break
if not ok :
2011-12-31 07:57:20 +00:00
raise osv . except_osv ( _ ( ' No price available! ' ) , _ ( ' No line matched this product or order in the choosed delivery grid. ' ) )
2008-07-22 15:11:28 +00:00
return price
2006-12-07 13:41:40 +00:00
delivery_grid ( )
class delivery_grid_line ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_name = " delivery.grid.line "
2010-05-19 18:32:32 +00:00
_description = " Delivery Grid Line "
2008-07-22 15:11:28 +00:00
_columns = {
2012-01-06 10:18:50 +00:00
' name ' : fields . char ( ' Name ' , size = 64 , required = True ) ,
2011-10-01 22:18:03 +00:00
' grid_id ' : fields . many2one ( ' delivery.grid ' , ' Grid ' , required = True , ondelete = ' cascade ' ) ,
2011-05-12 13:25:34 +00:00
' type ' : fields . selection ( [ ( ' weight ' , ' Weight ' ) , ( ' volume ' , ' Volume ' ) , \
2011-05-17 08:36:18 +00:00
( ' wv ' , ' Weight * Volume ' ) , ( ' price ' , ' Price ' ) ] , \
2011-05-12 13:25:34 +00:00
' Variable ' , required = True ) ,
2010-06-22 09:39:41 +00:00
' operator ' : fields . selection ( [ ( ' == ' , ' = ' ) , ( ' <= ' , ' <= ' ) , ( ' >= ' , ' >= ' ) ] , ' Operator ' , required = True ) ,
2008-07-22 15:11:28 +00:00
' max_value ' : fields . float ( ' Maximum Value ' , required = True ) ,
' price_type ' : fields . selection ( [ ( ' fixed ' , ' Fixed ' ) , ( ' variable ' , ' Variable ' ) ] , ' Price Type ' , required = True ) ,
' variable_factor ' : fields . selection ( [ ( ' weight ' , ' Weight ' ) , ( ' volume ' , ' Volume ' ) , ( ' wv ' , ' Weight * Volume ' ) , ( ' price ' , ' Price ' ) ] , ' Variable Factor ' , required = True ) ,
' list_price ' : fields . float ( ' Sale Price ' , required = True ) ,
' standard_price ' : fields . float ( ' Cost Price ' , required = True ) ,
}
_defaults = {
' type ' : lambda * args : ' weight ' ,
' operator ' : lambda * args : ' <= ' ,
' price_type ' : lambda * args : ' fixed ' ,
' variable_factor ' : lambda * args : ' weight ' ,
}
_order = ' list_price '
2006-12-07 13:41:40 +00:00
delivery_grid_line ( )
2011-09-23 13:30:30 +00:00
class define_delivery_steps ( osv . osv_memory ) :
_name = ' delivery.define.delivery.steps.wizard '
2006-12-07 13:41:40 +00:00
2011-09-23 13:30:30 +00:00
_columns = {
2011-10-02 16:08:04 +00:00
' picking_policy ' : fields . selection ( [ ( ' direct ' , ' Deliver each product when available ' ) , ( ' one ' , ' Deliver all products at once ' ) ] , ' Picking Policy ' ) ,
2011-10-02 16:04:10 +00:00
}
_defaults = {
' picking_policy ' : lambda s , c , u , ctx : s . pool . get ( ' sale.order ' ) . default_get ( c , u , [ ' picking_policy ' ] , context = ctx ) [ ' picking_policy ' ]
2011-09-23 13:30:30 +00:00
}
def apply_cb ( self , cr , uid , ids , context = None ) :
ir_values_obj = self . pool . get ( ' ir.values ' )
wizard = self . browse ( cr , uid , ids , context = context ) [ 0 ]
ir_values_obj . set ( cr , uid , ' default ' , False , ' picking_policy ' , [ ' sale.order ' ] , wizard . picking_policy )
return { ' type ' : ' ir.actions.act_window_close ' }
define_delivery_steps ( )
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: