[CORRECT]Lunch
bzr revid: api@openerp.com-20121026113901-9o8wi1v1k0j8coj4
This commit is contained in:
parent
83c574bcca
commit
e3bcd71d1b
|
@ -36,6 +36,7 @@ Category for the product.
|
|||
'data': ['security/groups.xml','view/lunch_view.xml','view/partner_view.xml','view/lunch_validation_view.xml','view/lunch_cancel_view.xml','lunch_report.xml',
|
||||
'report/report_lunch_order_view.xml',
|
||||
'security/ir.model.access.csv',],
|
||||
'css':['static/src/css/lunch_style.css'],
|
||||
'demo': ['lunch_demo.xml',],
|
||||
'test': [],
|
||||
'installable': True,
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -112,6 +112,8 @@
|
|||
<field name="date" eval="time.strftime('2012-10-23')"/>
|
||||
<field name="products" eval="[]"/>
|
||||
<field name="state">new</field>
|
||||
<field name='company_id'>1</field>
|
||||
<field name='total'>7.70</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order" id="order_2">
|
||||
|
@ -119,6 +121,8 @@
|
|||
<field name="date" eval="time.strftime('2012-10-22')"/>
|
||||
<field name="products" eval="[]"/>
|
||||
<field name="state">confirmed</field>
|
||||
<field name='company_id'>1</field>
|
||||
<field name='total'>7.40</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order" id="order_3">
|
||||
|
@ -126,6 +130,8 @@
|
|||
<field name="date" eval="time.strftime('2012-10-24')"/>
|
||||
<field name="products" eval="[]"/>
|
||||
<field name="state">cancelled</field>
|
||||
<field name='company_id'>1</field>
|
||||
<field name='total'>2.50</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order.line" id="order_line_1">
|
||||
|
@ -136,6 +142,7 @@
|
|||
<field name="supplier" ref="partner_pizza_inn"/>
|
||||
<field name="note">+Emmental</field>
|
||||
<field name="order_id" ref="order_1"/>
|
||||
<field name="price">7.70</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order.line" id="order_line_2">
|
||||
|
@ -146,6 +153,7 @@
|
|||
<field name="supplier" ref="partner_pizza_inn"/>
|
||||
<field name="note">+Champignons</field>
|
||||
<field name="order_id" ref="order_2"/>
|
||||
<field name="price">7.40</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order.line" id="order_line_3">
|
||||
|
@ -156,6 +164,7 @@
|
|||
<field name="supplier" ref="partner_coin_gourmand"/>
|
||||
<field name="note">+Salade +Tomates +Comcombres</field>
|
||||
<field name="order_id" ref="order_3"/>
|
||||
<field name="price">2.50</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.preference" id="preference_1">
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
.openerp .oe_lunch_view {
|
||||
}
|
||||
|
||||
.openerp .oe_lunch_30pc {
|
||||
width: 33%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
.openerp .oe_lunch_title {
|
||||
font-weight: bold;
|
||||
font-size: 17px;
|
||||
margin-left: 10px;
|
||||
color: #7C7BAD;
|
||||
}
|
||||
|
||||
.openerp .oe_lunch_vignette {
|
||||
padding: 8px;
|
||||
min-height: 50px;
|
||||
border: 1px solid;
|
||||
border-color: grey;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 5px;
|
||||
-moz-border-radius: 15px;
|
||||
border-radius: 15px;
|
||||
box-shadow: grey 1.5px 1.5px 1.5px;
|
||||
}
|
||||
|
||||
.openerp .oe_small_textarea>textarea {
|
||||
min-height: 20px;
|
||||
height: 20px;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.openerp .oe_lunch_button {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
text-align: right;
|
||||
width: 29%;
|
||||
min-width: 55px;
|
||||
max-width: 30%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.openerp .oe_lunch_note {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
margin-top: 4px;
|
||||
text-align: left;
|
||||
font-style: italic;
|
||||
color: #6374AB;
|
||||
width: 69%;
|
||||
max-width: 70%;
|
||||
display: inline-block;
|
||||
}
|
|
@ -279,6 +279,7 @@
|
|||
<field name="state" />
|
||||
<field name="total" sum="Total"/>
|
||||
<field name="preferences" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -295,30 +296,29 @@
|
|||
<group>
|
||||
<group>
|
||||
<field name='user_id'/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name='currency_id' invisible='1'/>
|
||||
</group>
|
||||
<group>
|
||||
<field name='date'/>
|
||||
</group>
|
||||
</group>
|
||||
<img src='/lunch/static/src/img/warning.png' width='30' height='30' class='oe_left oe_avatar' attrs="{'invisible': [('state','!=','new')]}"/>
|
||||
<div class='oe_title'>
|
||||
<field name='alerts' attrs="{'invisible': [('state','!=','new')]}"/>
|
||||
<field name='alerts' class='oe_small_textarea' attrs="{'invisible': [('state','!=','new')]}"/>
|
||||
<separator name='pref' string='Favorites'/>
|
||||
<div name="preferences">
|
||||
</div>
|
||||
<separator name='pref' string='Quick Select a Product'/>
|
||||
<div name='pref'>
|
||||
</div>
|
||||
<separator string='Select Products'/>
|
||||
<separator string='Your order'/>
|
||||
<field name='products' colspan='4' nolabel='1' on_change='onchange_price(products)'>
|
||||
<tree string='List' editable='bottom'>
|
||||
<field name='product' colspan='2' on_change='onchange_price(product)'/>
|
||||
<field name='note' />
|
||||
<field name='supplier'/>
|
||||
<field name='supplier' invisible='1'/>
|
||||
<field name='state' invisible='1'/>
|
||||
<field name='price'/>
|
||||
</tree>
|
||||
</field>
|
||||
<group class='oe_subtotal_footer oe_right'>
|
||||
<field name='total'/>
|
||||
<field name='total' widget='monetary' options="{'currency_field': 'currency_id'}"/>
|
||||
</group>
|
||||
<br/><br/>
|
||||
</sheet>
|
||||
|
|
Loading…
Reference in New Issue