diff --git a/addons/lunch/__openerp__.py b/addons/lunch/__openerp__.py index 7ff520f8cfc..f25e75028e0 100644 --- a/addons/lunch/__openerp__.py +++ b/addons/lunch/__openerp__.py @@ -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, diff --git a/addons/lunch/lunch.py b/addons/lunch/lunch.py index 6b7d0e9b439..a8c495d5dae 100644 --- a/addons/lunch/lunch.py +++ b/addons/lunch/lunch.py @@ -19,19 +19,13 @@ # along with this program. If not, see . # ############################################################################## -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=from_alert.time() and mynow.time()<=to_alert.time(): + alert_msg+="! " alert_msg+=alert.message alert_msg+='\n' - elif alert.active_from=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+= (''' -
-

- ''')+str(key)+(''' -

- ''') - for val in value: - function_name = "add_preference_"+str(val.id) - text_xml+= (''' -
- ''')+val['product_name']+(''' - - ''')+str(val['price'])+(''' - - - ''')+val['note']+(''' - -
- ''') - text_xml+= ('''
''') - res['arch'] = ('''
-
- -
- - - - - - - - - - -
- -
- - '''+text_xml+''' - - - - - - -

-
-
''') + + 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 = """
""" + for key,value in categories.items(): + text_xml+=""" +
+
%s
+ """ % (key,) + for val in value: + function_name = "add_preference_"+str(val.id) + text_xml+= ''' +
+

%s

%.2f %s +
+
+
+ %s +
+
+ + +
+
+
+ ''' % (val['product_name'], val['price'] or 0.0, currency['name'], val['note'] or '', function_name, function_name) + text_xml+= ('''
''') + text_xml+= ('''
''') + # 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' diff --git a/addons/lunch/lunch_demo.xml b/addons/lunch/lunch_demo.xml index d789002f0ad..8b5b98b4960 100644 --- a/addons/lunch/lunch_demo.xml +++ b/addons/lunch/lunch_demo.xml @@ -112,6 +112,8 @@ new + 1 + 7.70 @@ -119,6 +121,8 @@ confirmed + 1 + 7.40 @@ -126,6 +130,8 @@ cancelled + 1 + 2.50 @@ -136,6 +142,7 @@ +Emmental + 7.70 @@ -146,6 +153,7 @@ +Champignons + 7.40 @@ -156,6 +164,7 @@ +Salade +Tomates +Comcombres + 2.50 diff --git a/addons/lunch/static/src/css/lunch_style.css b/addons/lunch/static/src/css/lunch_style.css new file mode 100644 index 00000000000..eeb6ae3f754 --- /dev/null +++ b/addons/lunch/static/src/css/lunch_style.css @@ -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; +} diff --git a/addons/lunch/view/lunch_view.xml b/addons/lunch/view/lunch_view.xml index 91e09efb2ea..6bfa10898b0 100644 --- a/addons/lunch/view/lunch_view.xml +++ b/addons/lunch/view/lunch_view.xml @@ -279,6 +279,7 @@ + @@ -295,30 +296,29 @@ + + - -
- + + +
- -
-
- + - + - +