@@ -19,19 +19,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import addons #TODO: not needed
import tools #TODO: currently not needed, but you may want to import _ from tools.translte
import pytz
import time
from osv import osv , fields
from datetime import datetime , timedelta
from lxml import etree
#TODO: try to space more your code for a batter readability (follow PEP8 standards for coding layout is nice (except 80 characters max per line which is outdated))
# - def _price_get(self,cr,uid,ids,name,arg,context=None):
# + def _price_get(self, cr, uid, ids, name, arg, context=None):
#TODO: add some docstrings on methods when it is needed
class lunch_order ( osv . Model ) :
""" lunch order """
@@ -39,10 +33,9 @@ class lunch_order(osv.Model):
_description = ' Lunch Order '
def _price_get ( self , cr , uid , ids , name , arg , context = None ) :
#TODO: `orders´ variable is not needed. You can use `for x in self.browse(...):´
orders = self . browse ( cr , uid , ids , context = context )
""" get and sum the order lines ' price """
result = { }
for order in orders :
for order in self . browse ( cr , uid , ids , context = context ) :
value = 0.0
for product in order . products : #TODO: use meaningful variable names `for order_line in ...´
if product . state != ' cancelled ' :
@@ -50,48 +43,47 @@ class lunch_order(osv.Model):
result [ order . id ] = value
return result
def add_preference ( self , cr , uid , ids , pref_id , context = None ) :
#TODO: docstring
def add_preference ( self , cr , uid , ids , pref_id , context = None ) :
""" create a new order line based on the preference selected (pref_id) """
pref_ref = self . pool . get ( " lunch.preference " )
orderline_ref = self . pool . get ( ' lunch.order.line ' )
prod_ref = self . pool . get ( ' lunch.product ' )
order = self . browse ( cr , uid , ids , context = context ) [ 0 ]
pref = pref_ref . browse ( cr , uid , pref_id , context = context )
#TODO: get your information on browse_record objects by using `.´ instead of `[]´ .
# e.g: `pref.user_id.id == uid´ instead of `pref['user_id'].id´
prod_ref = self . pool . get ( ' lunch.product ' ) #TODO: usually, all the statements for `self.pool.get(...)´ are grouped at the beginning of the method
if pref [ " user_id " ] . id == uid : #TODO: i don't get the meaning of this line...
#TODO: new_order_line = {
# 'date': order.date,
# ...
# }
new_order_line = { }
new_order_line [ ' date ' ] = order [ " date " ]
new_order_line [ ' user_id ' ] = uid
new_order_line [ ' product ' ] = pref [ " product " ] . id
new_order_line [ ' note ' ] = pref [ " note " ]
new_order_line [ ' order_id ' ] = order . id
new_order_line [ ' price ' ] = pref [ " price " ]
new_order_line [ ' supplier ' ] = prod_ref . browse ( cr , uid , pref [ " product " ] . id , context = context ) [ ' supplier ' ] . id
new_id = orderline_ref . create ( cr , uid , new_order_line ) #TODO: add missing `context´ arg
if pref . user_id . id == uid :
new_order_line = {
' date ' : order [ " date " ] ,
' user_id ' : uid ,
' product ' : pref [ " product " ] . id ,
' note ' : pref [ " note " ] ,
' order_id ' : order . id ,
' price ' : pref [ " price " ] ,
' supplier ' : prod_ref . browse ( cr , uid , pref [ " product " ] . id , context = context ) [ ' supplier ' ] . id
}
new_id = orderline_ref . create ( cr , uid , new_order_line )
order . products . append ( new_id )
#TODO: total is a computed field, so the write is useless, no?
# ---> If I remove it, the total for order are not good (I try many times)
total = self . _price_get ( cr , uid , ids , " " , " " , context = context )
self . write ( cr , uid , ids , { ' total ' : total } , context )
return True
def _alerts_get ( self , cr , uid , ids , name , arg , context = None ) :
def _alerts_get ( self , cr , uid , ids , name , arg , context = None ) :
""" get the alerts to display on the order form """
orders = self . browse ( cr , uid , ids , context = context )
alert_ref = self . pool . get ( ' lunch.alert ' )
alert_ids = alert_ref . search ( cr , uid , [ ] , context = context ) #TODO: not used
result = { }
alert_msg = self . _default_alerts_get ( cr , uid , arg , context )
alert_msg = self . _default_alerts_get ( cr , uid , arg , context = context )
for order in orders :
if order . state == ' new ' :
result [ order . id ] = alert_msg
return result
def check_day ( self , alert ) :
#TODO: docstring
def check_day ( self , alert ) :
""" This method is used by can_display_alert to
to check if the alert day corresponds
to the current day
"""
today = datetime . now ( ) . isoweekday ( )
if today == 1 :
if alert . monday == True :
@@ -116,53 +108,54 @@ class lunch_order(osv.Model):
return True
return False
def can_display_alert ( self , alert ) :
""" This method check if the alert can be displayed today """
if alert . day == ' specific ' :
#the alert is only activated a specific day
if alert . specific == fields . datetime . now ( ) . split ( ' ' ) [ 0 ] :
return True
elif alert . day == ' week ' :
#the alert is activated during some days of the week
return self . check_day ( alert )
elif alert . day == ' days ' :
#the alert is activated everyday
return True
return False
def _default_alerts_get ( self , cr , uid , arg , context = None ) :
#TODO: docstring
""" get the alerts to display on the order form """
alert_ref = self . pool . get ( ' lunch.alert ' )
alert_ids = alert_ref . search ( cr , uid , [ ( ' active ' , ' = ' , True ) ] , context = context ) #TODO: active=True is automatically added by orm, so this param can be removed
alert_msg = " "
for alert in alert_ref . browse ( cr , uid , alert_ids , context = context ) :
if alert : #TODO useless `if´ statement
#there are alerts
display = False #TODO: should refactor in order to check if there is an alert in one function. Then use `if self.check_alert():...´
if alert . day == ' specific ' :
#the alert is only activated a specific day
if alert . specific == fields . datetime . now ( ) . split ( ' ' ) [ 0 ] :
display = True
elif alert . day == ' week ' :
#the alert is activated during some days of the week
display = self . check_day ( alert )
elif alert . day == ' days ' :
#the alert is activated everyday
display = True
#Check if we can display the alert
if display == True :
if alert . active_from == alert . active_to :
#the alert is executing all the day
alert_msg + = " * "
if self . can_display_alert ( alert ) :
if alert . active_from == alert . active_to :
#the alert is executing all the day
alert_msg + = " ! "
alert_msg + = alert . message
alert_msg + = ' \n '
elif alert . active_from < alert . active_to :
#the alert is executing from ... to ...
now = datetime . utcnow ( )
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context )
tz = pytz . timezone ( user . tz ) if user . tz else pytz . utc
tzoffset = tz . utcoffset ( now )
mynow = now + tzoffset
hour_to = int ( alert . active_to )
min_to = int ( ( alert . active_to - hour_to ) * 60 )
to_alert = datetime . strptime ( str ( hour_to ) + " : " + str ( min_to ) , " % H: % M " )
hour_from = int ( alert . active_from )
min_from = int ( ( alert . active_from - hour_from ) * 60 )
from_alert = datetime . strptime ( str ( hour_from ) + " : " + str ( min_from ) , " % H: % M " )
if mynow . time ( ) > = from_alert . time ( ) and mynow . time ( ) < = to_alert . time ( ) :
alert_msg + = " ! "
alert_msg + = alert . message
alert_msg + = ' \n '
elif alert . active_from < alert . active_to :
#TODO: this part seems overcomplicated, so i skipped it for now :-)
#the alert is executing from ... to ...
now = datetime . utcnow ( )
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid )
tz = pytz . timezone ( user . tz ) if user . tz else pytz . utc
tzoffset = tz . utcoffset ( now )
mynow = now + tzoffset
hour_to = int ( alert . active_to )
min_to = int ( ( alert . active_to - hour_to ) * 60 )
to_alert = datetime . strptime ( str ( hour_to ) + " : " + str ( min_to ) , " % H: % M " )
hour_from = int ( alert . active_from )
min_from = int ( ( alert . active_from - hour_from ) * 60 )
from_alert = datetime . strptime ( str ( hour_from ) + " : " + str ( min_from ) , " % H: % M " )
if mynow . time ( ) > = from_alert . time ( ) and mynow . time ( ) < = to_alert . time ( ) :
alert_msg + = " * "
alert_msg + = alert . message
alert_msg + = ' \n '
return alert_msg
def onchange_price ( self , cr , uid , ids , products , context = None ) :
""" Onchange methode that refresh the total price of order """
res = { ' value ' : { ' total ' : 0.0 } }
if products :
tot = 0.0
@@ -176,7 +169,7 @@ class lunch_order(osv.Model):
else :
orderline = self . pool . get ( ' lunch.order.line ' ) . browse ( cr , uid , prod [ 1 ] , context = context )
tot + = orderline . price
res = { ' value ' : { ' total ' : tot } } #TODO: should be outside the loop
res = { ' value ' : { ' total ' : tot } }
return res
def create ( self , cr , uid , values , context = None ) :
@@ -184,28 +177,27 @@ class lunch_order(osv.Model):
pref_ids = pref_ref . search ( cr , uid , [ ] , context = context )
prod_ref = self . pool . get ( ' lunch.product ' )
new_id = super ( lunch_order , self ) . create ( cr , uid , values , context = context )
already_exists = False #TODO: what's that trick with already_exists?? it's weird.
#When we create a new order we also create new preference
if len ( values [ ' products ' ] ) > 0 and values [ ' user_id ' ] == uid :
for pref in pref_ref . browse ( cr , uid , pref_ids , context = context ) :
if pref [ ' product ' ] . id == values [ ' products ' ] [ 0 ] [ 2 ] [ ' product ' ] :
if pref [ ' note ' ] == values [ ' products ' ] [ 0 ] [ 2 ] [ ' note ' ] :
if pref [ ' price ' ] == values [ ' products ' ] [ 0 ] [ 2 ] [ ' price ' ] :
already_exists = True
if already_exists == False and len ( values [ ' products ' ] ) > 0 :
new_pref = pref_ref . create ( cr , uid , { ' date ' : values [ ' date ' ] , ' color ' : 0 , ' order_id ' : new_id , ' user_id ' : values [ ' user_id ' ] , ' product ' : values [ ' products ' ] [ 0 ] [ 2 ] [ ' product ' ] , ' product_name ' : prod_ref . browse ( cr , uid , values [ ' products ' ] [ 0 ] [ 2 ] [ ' product ' ] ) [ ' name ' ] , ' note ' : values [ ' products ' ] [ 0 ] [ 2 ] [ ' note ' ] , ' price ' : values [ ' products ' ] [ 0 ] [ 2 ] [ ' price ' ] } , context = context )
for prods in values [ ' products ' ] :
already_exists = False #alreadyexist is used to check if a preferece already exists.
for pref in pref_ref . browse ( cr , uid , pref_ids , context = context ) :
if pref [ ' product ' ] . id == prods [ 2 ] [ ' product ' ] :
if pref [ ' note ' ] == prods [ 2 ] [ ' note ' ] :
if pref [ ' price ' ] == prods [ 2 ] [ ' price ' ] :
already_exists = True
if already_exists == False :
new_pref = pref_ref . create ( cr , uid , { ' date ' : values [ ' date ' ] , ' color ' : 0 , ' order_id ' : new_id , ' user_id ' : values [ ' user_id ' ] , ' product ' : prods [ 2 ] [ ' product ' ] , ' product_name ' : prod_ref . browse ( cr , uid , prods [ 2 ] [ ' product ' ] ) [ ' name ' ] , ' note ' : prods [ 2 ] [ ' note ' ] , ' price ' : prods [ 2 ] [ ' price ' ] } , context = context )
return new_id
def _default_preference_get ( self , cr , uid , args , context = None ) :
pref_ref = self . pool . get ( ' lunch.preference ' )
pref_ids = pref_ref . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] , order = ' date desc ' , limit = 15 , context = context )
#TODO: heeeuu... return pref_ids ?
result = [ ]
for pref in pref_ref . browse ( cr , uid , pref_ids , context = context ) :
result . append ( pref . id )
return result
""" return a maximum of 15 last user preferences ordered by date """
return self . pool . get ( ' lunch.preference ' ) . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] , order = ' date desc ' , limit = 15 , context = context )
def __getattr__ ( self , attr ) :
#TODO: not reviewed
""" this method catch unexisting method call and if starts with
add_preference_ ' n ' we execute the add_preference method with
' n ' as parameter """
if attr . startswith ( ' add_preference_ ' ) :
pref_id = int ( attr [ 15 : ] )
def specific_function ( cr , uid , ids , context = None ) :
@@ -218,66 +210,54 @@ class lunch_order(osv.Model):
res = super ( lunch_order , self ) . fields_view_get ( cr , uid , view_id = view_id , view_type = view_type , context = context , toolbar = toolbar , submenu = submenu )
if view_type == ' form ' :
pref_ref = self . pool . get ( " lunch.preference " )
pref_ids = pref_ref . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] , context = context )
order_ref = self . pool . get ( " lunch.order " )
currency_obj = self . pool . get ( ' res.currency ' )
prod_ref = self . pool . get ( " lunch.product " )
preferences = pref_ref . browse ( cr , uid , pref_ids , context = context )
categories = { } #store the different categories of products in preference
for pref in preferences :
categories [ pref [ ' product ' ] [ ' category_id ' ] [ ' name ' ] ] = [ ]
for pref in preferences :
categories [ pref [ ' product ' ] [ ' category_id ' ] [ ' name ' ] ] . append ( pref )
length = len ( categories )
text_xml = " "
for key , value in categories . items ( ) :
text_xml + = ( '''
<div style= \" width: 33 % ; display: inline-block; \" >
<h1>
''' ) + str ( key ) + ( '''
</h1>
''' )
for val in value :
function_name = " add_preference_ " + str ( val . id )
text_xml + = ( '''
<div class= \" vignette \" >
''' ) + val [ ' product_name ' ] + ( '''
<span class= \" oe_tag \" >
''' ) + str ( val [ ' price ' ] ) + ( '''
</span>
<span class= \" oe_note \" >
''' ) + val [ ' note ' ] + ( '''
</span >
<button class= ' oe_button ' name= " ''' ) + function_name + ( ''' " type= " object " icon= " gtk-add " / >
</div >
''' )
text_xml + = ( ''' </div> ''' )
res [ ' arch ' ] = ( ''' <form string= \" Orders Form \" version= \" 7.0 \" >
<header >
<field name= \" state \" widget= \" statusbar \" statusbar_visible= \" new,confirmed \" modifiers= \" { "readonly": true} \" / >
</header >
<sheet >
<group >
<group>
<field name= \" user_id \" modifiers= \" { "readonly": [["state", "not in", ["new"]]], "required": true} \" />
</group>
<group>
<field name= \" date \" modifiers= \" { "readonly": [["state", "not in", ["new"]]], "required": true} \" />
</group>
</group>
<img src= \" /lunch/static/src/img/warning.png \" width= \" 30 \" height= \" 30 \" class= \" oe_left oe_avatar \" attrs= \" { ' invisible ' : [( ' state ' , ' != ' , ' new ' )]} \" modifiers= \" { "invisible": [["state", "!=", "new"]]} \" />
<div class= \" oe_title \" >
<field name= \" alerts \" attrs= \" { ' invisible ' : [( ' state ' , ' != ' , ' new ' )]} \" modifiers= \" { "invisible": [["state", "!=", "new"]], "readonly": true} \" />
</div>
<separator name= \" pref \" string= \" Quick Select a Product \" />
''' + text_xml + '''
<separator string= \" Select Products \" />
<field name= \" products \" colspan= \" 4 \" nolabel= \" 1 \" on_change= \" onchange_price(products) \" modifiers= \" { "readonly": [["state", "not in", ["new"]]]} \" >
</field>
<group class= \" oe_subtotal_footer oe_right \" >
<field name= \" total \" modifiers= \" { "readonly": true} \" />
</group>
<br/><br/>
</sheet>
</form> ''' )
pref_ids = pref_ref . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] , context = context )
order_ids = order_ref . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] , context = context )
if len ( order_ids ) > 0 :
preferences = pref_ref . browse ( cr , uid , pref_ids , context = context )
this_order = order_ref . browse ( cr , uid , order_ids [ 0 ] , context = context )
currency = currency_obj . browse ( cr , uid , this_order [ ' currency_id ' ] , context = context )
categories = { } #store the different categories of products in preference
for pref in preferences :
categories [ pref [ ' product ' ] [ ' category_id ' ] [ ' name ' ] ] = [ ]
for pref in preferences :
categories [ pref [ ' product ' ] [ ' category_id ' ] [ ' name ' ] ] . append ( pref )
length = len ( categories )
text_xml = """ <div class= " oe_lunch_view " > """
for key , value in categories . items ( ) :
text_xml + = """
<div class= " oe_lunch_30pc " >
<div class= " oe_lunch_title " > %s </div>
""" % ( key , )
for val in value :
function_name = " add_preference_ " + str ( val . id )
text_xml + = '''
<div class= " oe_lunch_vignette " >
<h3> %s </h3><span class= " oe_tag " > %.2f %s </span>
<br/ >
<div class= " oe_group_text_button oe_inline " >
<div class= " oe_lunch_note " >
%s
</div>
<div class= " oe_lunch_button " >
<button name= " %s " class= " oe_link oe_i " type= " object " string= " + " ></button >
<button name= " %s " class= " oe_link " type= " object " string= " Add " ></button >
</div >
</div >
</div >
''' % ( val [ ' product_name ' ] , val [ ' price ' ] or 0.0 , currency [ ' name ' ] , val [ ' note ' ] or ' ' , function_name , function_name )
text_xml + = ( ''' </div> ''' )
text_xml + = ( ''' </div> ''' )
# ADD into ARCH xml
doc = etree . XML ( res [ ' arch ' ] )
node = doc . xpath ( " //div[@name= ' preferences ' ] " )
to_add = etree . fromstring ( text_xml )
node [ 0 ] . append ( to_add )
res [ ' arch ' ] = etree . tostring ( doc )
return res
_columns = {
@@ -285,108 +265,105 @@ class lunch_order(osv.Model):
' date ' : fields . date ( ' Date ' , required = True , readonly = True , states = { ' new ' : [ ( ' readonly ' , False ) ] } ) ,
' products ' : fields . one2many ( ' lunch.order.line ' , ' order_id ' , ' Products ' , ondelete = " cascade " , readonly = True , states = { ' new ' : [ ( ' readonly ' , False ) ] } ) , #TODO: a good naming convention is to finish your field names with `_ids´ for *2many fields. BTW, the field name should reflect more it's nature: `order_line_ids´ for example
' total ' : fields . function ( _price_get , string = " Total " , store = True ) ,
' state ' : fields . selection ( [ ( ' new ' , ' New ' ) , ( ' confirmed ' , ' Confirmed ' ) , ( ' cancelled ' , ' Cancelled ' ) , ( ' partially ' , ' Parcially Confirmed ' ) ] , \
' Status ' , readonly = True , select = True ) , #TODO: parcially? #TODO: the labels are confusing. confirmed=='received' or 'delivered'...
' state ' : fields . selection ( [ ( ' new ' , ' New ' ) , ( ' confirmed ' , ' Confirmed ' ) , ( ' cancelled ' , ' Cancelled ' ) , ( ' partially ' , ' Parcially Confirmed ' ) ] , ' Status ' , readonly = True , select = True ) , #TODO: parcially? #TODO: the labels are confusing. confirmed=='received' or 'delivered'...
' alerts ' : fields . function ( _alerts_get , string = " Alerts " , type = ' text ' ) ,
' preferences ' : fields . many2many ( " lunch.preference " , ' lunch_preference_rel ' , ' preferences ' , ' order_id ' , ' Preferences ' ) , #TODO: preference_ids
' preferences ' : fields . many2many ( " lunch.preference " , ' lunch_preference_rel ' , ' preferences ' , ' order_id ' , ' Preferences ' ) ,
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = True ) ,
' currency_id ' : fields . related ( ' company_id ' , ' currency_id ' , string = " Currency " , readonly = True ) ,
}
_defaults = {
' user_id ' : lambda self , cr , uid , context : uid ,
' date ' : fields . date . context_today ,
' state ' : lambda self , cr , uid , context : ' new ' , #TODO: remove the lambda()
' state ' : ' new ' ,
' alerts ' : _default_alerts_get ,
' preferences ' : _default_preference_get ,
' company_id ' : lambda self , cr , uid , context : self . pool . get ( ' res.company ' ) . _company_default_get ( cr , uid , ' lunch.order ' , context = context ) ,
}
class lunch_order_line ( osv . Model ) : #define each product that will be in one ORDER.#TODO :D do not put comments because i said so, but because it's needed ^^
""" lunch order line """
class lunch_order_line ( osv . Model ) :
""" lunch order line : one lunch order can have many order lines """
_name = ' lunch.order.line '
_description = ' lunch order line '
def _price_get ( self , cr , uid , ids , name , arg , context = None ) :
orderLines = self . browse ( cr , uid , ids , context = context )
""" get the price of the product store in the order line """
result = { }
for orderLine in orderLines : #TODO: get rid of `orderLines´ variable #TODO: usually, we don't use the CamelCase notation. For a better consistency you should use `order_line´
result [ orderLine . id ] = orderLine . product . price
for order_line in self . browse ( cr , uid , ids , context = context ) :
result [ order_line . id ] = order_line . product . price
return result
def onchange_price ( self , cr , uid , ids , product , context = None ) :
""" Onchange methode to refresh the price """
if product :
price = self . pool . get ( ' lunch.product ' ) . read ( cr , uid , product , [ ' price ' ] ) [ ' price ' ] #TODO: pass `context´ in args or read()
price = self . pool . get ( ' lunch.product ' ) . read ( cr , uid , product , [ ' price ' ] , context = context ) [ ' price ' ]
return { ' value ' : { ' price ' : price } }
return { ' value ' : { ' price ' : 0.0 } }
def confirm ( self , cr , uid , ids , context = None ) :
# confirm one or more order. line, update order status and create new cashmove
""" confirm one or more order line, update order status and create new cashmove """
cashmove_ref = self . pool . get ( ' lunch.cashmove ' )
orders_ref = self . pool . get ( ' lunch.order ' )
for order in self . browse ( cr , uid , ids , context = context ) :
if order . state != ' confirmed ' :
new_id = cashmove_ref . create ( cr , uid , { ' user_id ' : order . user_id . id , ' amount ' : 0 - order . price , ' description ' : order . product . name , ' order_id ' : order . id , ' state ' : ' order ' , ' date ' : order . date } )
self . write ( cr , uid , [ order . id ] , { ' cashmove ' : [ ( ' 0 ' , new_id ) ] , ' state ' : ' confirmed ' } , context )
#TODO: how can this be working??? self is 'lunch.order.line' object, not 'lunch.order'... refactor
for order in self . browse ( cr , uid , ids , context = context ) :
for order_line in self . browse ( cr , uid , ids , context = context ) :
if order_line . state != ' confirmed ' :
new_id = cashmove_ref . create ( cr , uid , { ' user_id ' : order_line . user_id . id , ' amount ' : 0 - order_line . price , ' description ' : order_line . product . name , ' order_id ' : order_line . id , ' state ' : ' order ' , ' date ' : order_line . date } )
self . write ( cr , uid , [ order_line . id ] , { ' cashmove ' : [ ( ' 0 ' , new_id ) ] , ' state ' : ' confirmed ' } , context )
for order_line in self . browse ( cr , uid , ids , context = context ) :
isconfirmed = True
for product in order . order_id . products :
for product in order_line . order_id . products :
if product . state == ' new ' :
isconfirmed = False
if product . state == ' cancelled ' :
isconfirmed = False
orders_ref . write ( cr , uid , [ order . order_id . id ] , { ' state ' : ' partially ' } , context )
orders_ref . write ( cr , uid , [ order_line . order_id . id ] , { ' state ' : ' partially ' } , context = context )
if isconfirmed == True :
orders_ref . write ( cr , uid , [ order . order_id . id ] , { ' state ' : ' confirmed ' } , context ) #TODO: context is a kwarg
orders_ref . write ( cr , uid , [ order_line . order_id . id ] , { ' state ' : ' confirmed ' } , context = context )
return { }
def cancel ( self , cr , uid , ids , context = None ) :
# confirm one or more order.line, update order status and create new cashmove
""" confirm one or more order.line, update order status and create new cashmove """
cashmove_ref = self . pool . get ( ' lunch.cashmove ' )
orders_ref = self . pool . get ( ' lunch.order ' )
#TODO: how can this be working??? self is 'lunch.order.line' object, not 'lunch.order'... refactor
for order in self . browse ( cr , uid , ids , context = context ) :
self . write ( cr , uid , [ order . id ] , { ' state ' : ' cancelled ' } , context )
for cash in order . cashmove :
for order_line in self . browse ( cr , uid , ids , context = context ) :
self . write ( cr , uid , [ order_line . id ] , { ' state ' : ' cancelled ' } , context )
for cash in order_line . cashmove :
cashmove_ref . unlink ( cr , uid , cash . id , context )
#TODO: how can this be working??? self is 'lunch.order.line' object, not 'lunch.order'... refactor
for order in self . browse ( cr , uid , ids , context = context ) :
for order_line in self . browse ( cr , uid , ids , context = context ) :
hasconfirmed = False
hasnew = False
for product in order . order_id . products :
for product in order_line . order_id . products :
if product . state == ' confirmed ' :
hasconfirmed = True
if product . state == ' new ' :
hasnew = True
if hasnew == False :
if hasconfirmed == False :
orders_ref . write ( cr , uid , [ order . order_id . id ] , { ' state ' : ' cancelled ' } , context )
orders_ref . write ( cr , uid , [ order_line . order_id . id ] , { ' state ' : ' cancelled ' } , context )
return { }
orders_ref . write ( cr , uid , [ order . order_id . id ] , { ' state ' : ' partially ' } , context )
orders_ref . write ( cr , uid , [ order_line . order_id . id ] , { ' state ' : ' partially ' } , context )
return { }
_columns = {
' date ' : fields . related ( ' order_id ' , ' date ' , type = ' date ' , string = " Date " , readonly = True , store = True ) , #TODO: where is it used?
' supplier ' : fields . related ( ' product ' , ' supplier ' , type = ' many2one ' , relation = ' res.partner ' , string = " Supplier " , readonly = True , store = True ) , #TODO: where is it used?
' user_id ' : fields . related ( ' order_id ' , ' user_id ' , type = ' many2one ' , relation = ' res.users ' , string = ' User ' , readonly = True , store = True ) , #TODO: where is it used?
' product ' : fields . many2one ( ' lunch.product ' , ' Product ' , required = True ) , #one offer can have more than one product and one product can be in more than one offer
#TODO remove wrong (what's an `offer´ ?) and useless comment (people knows what's a many2one)
' note ' : fields . text ( ' Note ' , size = 256 , required = False ) , #TODO: required is False by default. Can be removed
' order_id ' : fields . many2one ( ' lunch.order ' , ' Order ' , ondelete = ' cascade ' ) , #TODO: this one should be required=True
' price ' : fields . function ( _price_get , string = " Price " , store = True ) , #TODO: isn't it a fields.related?
' date ' : fields . related ( ' order_id ' , ' date ' , type = ' date ' , string = " Date " , readonly = True , store = True ) ,
' supplier ' : fields . related ( ' product ' , ' supplier ' , type = ' many2one ' , relation = ' res.partner ' , string = " Supplier " , readonly = True , store = True ) ,
' user_id ' : fields . related ( ' order_id ' , ' user_id ' , type = ' many2one ' , relation = ' res.users ' , string = ' User ' , readonly = True , store = True ) ,
' product ' : fields . many2one ( ' lunch.product ' , ' Product ' , required = True ) ,
' note ' : fields . text ( ' Note ' , size = 256 , required = False ) ,
' order_id ' : fields . many2one ( ' lunch.order ' , ' Order ' , ondelete = ' cascade ' ) ,
' price ' : fields . related ( ' product ' , ' price ' , type = " float " , readonly = True , store = True ) ,
' state ' : fields . selection ( [ ( ' new ' , ' New ' ) , ( ' confirmed ' , ' Confirmed ' ) , ( ' cancelled ' , ' Cancelled ' ) ] , \
' Status ' , readonly = True , select = True ) , #TODO: labels are confusing. Should be: 'ordered', 'received' or 'not received'
' Status ' , readonly = True , select = True ) , #new confirmed and cancelled are the convention
' cashmove ' : fields . one2many ( ' lunch.cashmove ' , ' order_id ' , ' Cash Move ' , ondelete = ' cascade ' ) ,
}
_defaults = {
#TODO: remove lambda()
' state ' : lambda self , cr , uid , context : ' new ' ,
' state ' : ' new ' ,
}
class lunch_preference ( osv . Model ) :
#TODO: class not reviewed yet
""" lunch preference (based on user previous order lines) """
_name = ' lunch.preference '
_description = " user preferences "
@@ -405,7 +382,6 @@ class lunch_preference(osv.Model):
}
class lunch_product ( osv . Model ) :
#TODO: class not reviewed yet
""" lunch product """
_name = ' lunch.product '
_description = ' lunch product '
@@ -419,7 +395,6 @@ class lunch_product(osv.Model):
}
class lunch_product_category ( osv . Model ) :
#TODO: class not reviewed yet
""" lunch product category """
_name = ' lunch.product.category '
_description = ' lunch product category '
@@ -428,7 +403,6 @@ class lunch_product_category(osv.Model):
}
class lunch_cashmove ( osv . Model ) :
#TODO: class not reviewed yet
""" lunch cashmove => order or payment """
_name = ' lunch.cashmove '
_description = ' lunch cashmove '
@@ -447,7 +421,6 @@ class lunch_cashmove(osv.Model):
}
class lunch_alert ( osv . Model ) :
#TODO: class not reviewed yet
""" lunch alert """
_name = ' lunch.alert '
_description = ' lunch alert '
@@ -468,7 +441,6 @@ class lunch_alert(osv.Model):
}
class lunch_cancel ( osv . Model ) :
#TODO: class not reviewed yet
""" lunch cancel """
_name = ' lunch.cancel '
_description = ' cancel lunch order '
@@ -500,7 +472,6 @@ class lunch_cancel(osv.Model):
return { }
class lunch_validation ( osv . Model ) :
#TODO: class not reviewed yet
""" lunch validation """
_name = ' lunch.validation '
_description = ' lunch validation for order '