context="{'default_customer': 0, 'search_default_supplier': 1, 'default_supplier': 1}"
domain="[('supplier', '=', True)]"/>
<field name="fiscal_position" widget="selection"/>
- <group>
- <field name="origin"/>
- <field name="supplier_invoice_number"/>
- </group>
+ <field name="origin"/>
+ <field name="supplier_invoice_number"/>
<label for="reference_type"/>
<div>
<field name="reference_type" class="oe_inline oe_edit_only"/>
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
+# Copyright (C) 2004-2012 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
##############################################################################
import lunch
-import wizard
import report
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+import wizard
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
+# Copyright (C) 2004-2012 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
{
'name': 'Lunch Orders',
'author': 'OpenERP SA',
- 'version': '0.1',
- 'depends': [],
+ 'version': '0.2',
+ 'depends': ['base'],
'category' : 'Tools',
+ 'summary': 'Lunch Order, Meal, Food',
'description': """
The base module to manage lunch.
================================
-keep track for the Lunch Order, Cash Moves, CashBox, Product. Apply Different
-Category for the product.
+Many companies order sandwiches, pizzas and other, from usual suppliers, for their employees to offer them more facilities.
+
+However lunches management within the company requires proper administration especially when the number of employees or suppliers is important.
+
+The “Lunch Order” module has been developed to make this management easier but also to offer employees more tools and usability.
+
+In addition to a full meal and supplier management, this module offers the possibility to display warning and provides quick order selection based on employee’s preferences.
+
+If you want to save your employees' time and avoid them to always have coins in their pockets, this module is essential.
""",
- 'data': [
- 'security/lunch_security.xml',
- 'security/ir.model.access.csv',
- 'wizard/lunch_order_cancel_view.xml',
- 'wizard/lunch_order_confirm_view.xml',
- 'wizard/lunch_cashbox_clean_view.xml',
- 'lunch_view.xml',
- 'lunch_report.xml',
+ 'data': ['security/lunch_security.xml','lunch_view.xml','wizard/lunch_order_view.xml','wizard/lunch_validation_view.xml','wizard/lunch_cancel_view.xml','lunch_report.xml',
'report/report_lunch_order_view.xml',
- 'lunch_installer_view.xml'
- ],
- 'demo': ['lunch_demo.xml'],
- 'test': ['test/test_lunch.yml', 'test/lunch_report.yml'],
+ 'security/ir.model.access.csv',],
+ 'css':['static/src/css/lunch.css'],
+ 'demo': ['lunch_demo.xml',],
'installable': True,
- 'images': ['images/cash_moves.jpeg','images/lunch_orders.jpeg','images/products.jpeg'],
+ 'application' : True,
+ 'certificate' : '001292377792581874189',
+ 'images': [],
}
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
#
##############################################################################
+from xml.sax.saxutils import escape
+import time
from osv import osv, fields
+from datetime import datetime
+from lxml import etree
+import tools
+from tools.translate import _
+
+class lunch_order(osv.Model):
+ """
+ lunch order (contains one or more lunch order line(s))
+ """
+ _name = 'lunch.order'
+ _description = 'Lunch Order'
-class lunch_category(osv.osv):
- """ Lunch category """
+ def _price_get(self, cr, uid, ids, name, arg, context=None):
+ """
+ get and sum the order lines' price
+ """
+ result = dict.fromkeys(ids, 0)
+ for order in self.browse(cr, uid, ids, context=context):
+ result[order.id] = sum(order_line.product_id.price
+ for order_line in order.order_line_ids)
+ return result
+
+ def _fetch_orders_from_lines(self, cr, uid, ids, name, context=None):
+ """
+ return the list of lunch orders to which belong the order lines `ids´
+ """
+ result = set()
+ for order_line in self.browse(cr, uid, ids, context=context):
+ if order_line.order_id:
+ result.add(order_line.order_id.id)
+ return list(result)
+
+ def add_preference(self, cr, uid, ids, pref_id, context=None):
+ """
+ create a new order line based on the preference selected (pref_id)
+ """
+ assert len(ids) == 1
+ orderline_ref = self.pool.get('lunch.order.line')
+ prod_ref = self.pool.get('lunch.product')
+ order = self.browse(cr, uid, ids[0], context=context)
+ pref = orderline_ref.browse(cr, uid, pref_id, context=context)
+ new_order_line = {
+ 'date': order.date,
+ 'user_id': uid,
+ 'product_id': pref.product_id.id,
+ 'note': pref.note,
+ 'order_id': order.id,
+ 'price': pref.product_id.price,
+ 'supplier': pref.product_id.supplier.id
+ }
+ return orderline_ref.create(cr, uid, new_order_line, context=context)
+
+ def _alerts_get(self, cr, uid, ids, name, arg, context=None):
+ """
+ get the alerts to display on the order form
+ """
+ result = {}
+ alert_msg = self._default_alerts_get(cr, uid, context=context)
+ for order in self.browse(cr, uid, ids, context=context):
+ if order.state == 'new':
+ result[order.id] = alert_msg
+ return result
+
+ def check_day(self, alert):
+ """
+ This method is used by can_display_alert
+ to check if the alert day corresponds
+ to the current day
+ """
+ today = datetime.now().isoweekday()
+ assert 1 <= today <= 7, "Should be between 1 and 7"
+ mapping = dict((idx, name) for idx, name in enumerate('monday tuestday wednesday thursday friday saturday sunday'.split()))
+ if today in mapping:
+ return mapping[today]
+
+ def can_display_alert(self, alert):
+ """
+ This method check if the alert can be displayed today
+ """
+ if alert.alter_type == 'specific':
+ #the alert is only activated on a specific day
+ return alert.specific_day == time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+ elif alert.alter_type == 'week':
+ #the alert is activated during some days of the week
+ return self.check_day(alert)
+
+ def _default_alerts_get(self, cr, uid, context=None):
+ """
+ get the alerts to display on the order form
+ """
+ alert_ref = self.pool.get('lunch.alert')
+ alert_ids = alert_ref.search(cr, uid, [], context=context)
+ alert_msg = []
+ for alert in alert_ref.browse(cr, uid, alert_ids, context=context):
+ #check if the address must be displayed today
+ if self.can_display_alert(alert):
+ #display the address only during its active time
+ mynow = fields.datetime.context_timestamp(cr, uid, datetime.now(), context=context)
+ 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.append(alert.message)
+ return '\n'.join(alert_msg)
+
+ def onchange_price(self, cr, uid, ids, order_line_ids, context=None):
+ """
+ Onchange methode that refresh the total price of order
+ """
+ res = {'value': {'total': 0.0}}
+ order_line_ids = self.resolve_o2m_commands_to_record_dicts(cr, uid, "order_line_ids", order_line_ids, ["price"], context=context)
+ if order_line_ids:
+ tot = 0.0
+ product_ref = self.pool.get("lunch.product")
+ for prod in order_line_ids:
+ if 'product_id' in prod:
+ tot += product_ref.browse(cr, uid, prod['product_id'], context=context).price
+ else:
+ tot += prod['price']
+ res = {'value': {'total': tot}}
+ return res
- _name = 'lunch.category'
- _description = "Category"
+ def __getattr__(self, attr):
+ """
+ this method catch unexisting method call and if it 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):
+ return self.add_preference(cr, uid, ids, pref_id, context=context)
+ return specific_function
+ return super(lunch_order,self).__getattr__(self,attr)
+
+ def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
+ """
+ Add preferences in the form view of order.line
+ """
+ res = super(lunch_order,self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
+ line_ref = self.pool.get("lunch.order.line")
+ if view_type == 'form':
+ doc = etree.XML(res['arch'])
+ pref_ids = line_ref.search(cr, uid, [('user_id', '=', uid)], order='create_date desc', context=context)
+ xml_start = etree.Element("div")
+ #If there are no preference (it's the first time for the user)
+ if len(pref_ids)==0:
+ #create Elements
+ xml_no_pref_1 = etree.Element("div")
+ xml_no_pref_1.set('class','oe_inline oe_lunch_intro')
+ xml_no_pref_2 = etree.Element("h3")
+ xml_no_pref_2.text = _("This is the first time you order a meal")
+ xml_no_pref_3 = etree.Element("p")
+ xml_no_pref_3.set('class','oe_grey')
+ xml_no_pref_3.text = _("Select a product and put your order comments on the note.")
+ xml_no_pref_4 = etree.Element("p")
+ xml_no_pref_4.set('class','oe_grey')
+ xml_no_pref_4.text = _("Your favorite meals will be created based on your last orders.")
+ xml_no_pref_5 = etree.Element("p")
+ xml_no_pref_5.set('class','oe_grey')
+ xml_no_pref_5.text = _("Don't forget the alerts displayed in the reddish area")
+ #structure Elements
+ xml_start.append(xml_no_pref_1)
+ xml_no_pref_1.append(xml_no_pref_2)
+ xml_no_pref_1.append(xml_no_pref_3)
+ xml_no_pref_1.append(xml_no_pref_4)
+ xml_no_pref_1.append(xml_no_pref_5)
+ #Else: the user already have preferences so we display them
+ else:
+ preferences = line_ref.browse(cr, uid, pref_ids, context=context)
+ categories = {} #store the different categories of products in preference
+ count = 0
+ for pref in preferences:
+ #For each preference
+ categories.setdefault(pref.product_id.category_id.name, {})
+ #if this product has already been added to the categories dictionnary
+ if pref.product_id.id in categories[pref.product_id.category_id.name]:
+ #we check if for the same product the note has already been added
+ if pref.note not in categories[pref.product_id.category_id.name][pref.product_id.id]:
+ #if it's not the case then we add this to preferences
+ categories[pref.product_id.category_id.name][pref.product_id.id][pref.note] = pref
+ #if this product is not in the dictionnay, we add it
+ else:
+ categories[pref.product_id.category_id.name][pref.product_id.id] = {}
+ categories[pref.product_id.category_id.name][pref.product_id.id][pref.note] = pref
+
+ currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id
+
+ #For each preferences that we get, we will create the XML structure
+ for key,value in categories.items():
+ xml_pref_1 = etree.Element("div")
+ xml_pref_1.set('class','oe_lunch_30pc')
+ xml_pref_2 = etree.Element("h2")
+ xml_pref_2.text = key
+ xml_pref_1.append(xml_pref_2)
+ i = 0
+ value = value.values()
+ for val in value:
+ for pref in val.values():
+ #We only show 5 preferences per category (or it will be too long)
+ if i==5: break
+ i+=1
+ xml_pref_3 = etree.Element("div")
+ xml_pref_3.set('class','oe_lunch_vignette')
+ xml_pref_1.append(xml_pref_3)
+
+ xml_pref_4 = etree.Element("span")
+ xml_pref_4.set('class','oe_lunch_button')
+ xml_pref_3.append(xml_pref_4)
+
+ xml_pref_5 = etree.Element("button")
+ xml_pref_5.set('name',"add_preference_"+str(pref.id))
+ xml_pref_5.set('class','oe_link oe_i oe_button_plus')
+ xml_pref_5.set('type','object')
+ xml_pref_5.set('string','+')
+ xml_pref_4.append(xml_pref_5)
+
+ xml_pref_6 = etree.Element("button")
+ xml_pref_6.set('name',"add_preference_"+str(pref.id))
+ xml_pref_6.set('class','oe_link oe_button_add')
+ xml_pref_6.set('type','object')
+ xml_pref_6.set('string',_("Add"))
+ xml_pref_4.append(xml_pref_6)
+
+ xml_pref_7 = etree.Element("div")
+ xml_pref_7.set('class','oe_group_text_button')
+ xml_pref_3.append(xml_pref_7)
+
+ xml_pref_8 = etree.Element("div")
+ xml_pref_8.set('class','oe_lunch_text')
+ xml_pref_8.text = escape(pref.product_id.name)+str(" ")
+ xml_pref_7.append(xml_pref_8)
+
+ price = pref.product_id.price or 0.0
+ cur = currency.name or ''
+ xml_pref_9 = etree.Element("span")
+ xml_pref_9.set('class','oe_tag')
+ xml_pref_9.text = str(price)+str(" ")+cur
+ xml_pref_8.append(xml_pref_9)
+
+ xml_pref_10 = etree.Element("div")
+ xml_pref_10.set('class','oe_grey')
+ xml_pref_10.text = escape(pref.note or '')
+ xml_pref_3.append(xml_pref_10)
+
+ xml_start.append(xml_pref_1)
+
+ first_node = doc.xpath("//div[@name='preferences']")
+ if first_node and len(first_node)>0:
+ first_node[0].append(xml_start)
+ res['arch'] = etree.tostring(doc)
+ return res
_columns = {
- 'name': fields.char('Name', required=True, size=50),
+ 'user_id': fields.many2one('res.users', 'User Name', required=True, readonly=True, states={'new':[('readonly', False)]}),
+ 'date': fields.date('Date', required=True, readonly=True, states={'new':[('readonly', False)]}),
+ 'order_line_ids': fields.one2many('lunch.order.line', 'order_id', 'Products', ondelete="cascade", readonly=True, states={'new':[('readonly', False)]}),
+ 'total': fields.function(_price_get, string="Total", store={
+ 'lunch.order.line': (_fetch_orders_from_lines, ['product_id','order_id'], 20),
+ }),
+ 'state': fields.selection([('new', 'New'), \
+ ('confirmed','Confirmed'), \
+ ('cancelled','Cancelled'), \
+ ('partially','Partially Confirmed')] \
+ ,'Status', readonly=True, select=True),
+ 'alerts': fields.function(_alerts_get, string="Alerts", type='text'),
}
- _order = 'name'
-lunch_category()
+ _defaults = {
+ 'user_id': lambda self, cr, uid, context: uid,
+ 'date': fields.date.context_today,
+ 'state': 'new',
+ 'alerts': _default_alerts_get,
+ }
-class lunch_product(osv.osv):
- """ Lunch Product """
+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 onchange_price(self, cr, uid, ids, product_id, context=None):
+ if product_id:
+ price = self.pool.get('lunch.product').browse(cr, uid, product_id, context=context).price
+ return {'value': {'price': price}}
+ return {'value': {'price': 0.0}}
+
+ def order(self, cr, uid, ids, context=None):
+ """
+ The order_line is ordered to the supplier but isn't received yet
+ """
+ for order_line in self.browse(cr, uid, ids, context=context):
+ order_line.write({'state': 'ordered'}, context=context)
+ return self._update_order_lines(cr, uid, ids, context=context)
+
+ def confirm(self, cr, uid, ids, context=None):
+ """
+ confirm one or more order line, update order status and create new cashmove
+ """
+ cashmove_ref = self.pool.get('lunch.cashmove')
+ for order_line in self.browse(cr, uid, ids, context=context):
+ if order_line.state != 'confirmed':
+ values = {
+ 'user_id': order_line.user_id.id,
+ 'amount': -order_line.price,
+ 'description': order_line.product_id.name,
+ 'order_id': order_line.id,
+ 'state': 'order',
+ 'date': order_line.date,
+ }
+ cashmove_ref.create(cr, uid, values, context=context)
+ order_line.write({'state': 'confirmed'}, context=context)
+ return self._update_order_lines(cr, uid, ids, context=context)
+
+ def _update_order_lines(self, cr, uid, ids, context=None):
+ """
+ Update the state of lunch.order based on its orderlines
+ """
+ orders_ref = self.pool.get('lunch.order')
+ orders = []
+ for order_line in self.browse(cr, uid, ids, context=context):
+ orders.append(order_line.order_id)
+ for order in set(orders):
+ isconfirmed = True
+ for orderline in order.order_line_ids:
+ if orderline.state == 'new':
+ isconfirmed = False
+ if orderline.state == 'cancelled':
+ isconfirmed = False
+ orders_ref.write(cr, uid, [order.id], {'state': 'partially'}, context=context)
+ if isconfirmed:
+ orders_ref.write(cr, uid, [order.id], {'state': 'confirmed'}, context=context)
+ return {}
- _name = 'lunch.product'
- _description = "Lunch Product"
+ def cancel(self, cr, uid, ids, context=None):
+ """
+ cancel one or more order.line, update order status and unlink existing cashmoves
+ """
+ cashmove_ref = self.pool.get('lunch.cashmove')
+ for order_line in self.browse(cr, uid, ids, context=context):
+ order_line.write({'state':'cancelled'}, context=context)
+ cash_ids = [cash.id for cash in order_line.cashmove]
+ cashmove_ref.unlink(cr, uid, cash_ids, context=context)
+ return self._update_order_lines(cr, uid, ids, context=context)
_columns = {
- 'name': fields.char('Name', size=50, required=True),
- 'category_id': fields.many2one('lunch.category', 'Category'),
- 'description': fields.text('Description', size=128, required=False),
- 'price': fields.float('Price', digits=(16,2)),
- 'active': fields.boolean('Active'),
- }
+ 'name': fields.related('product_id', 'name', readonly=True),
+ 'order_id': fields.many2one('lunch.order', 'Order', ondelete='cascade'),
+ 'product_id': fields.many2one('lunch.product', 'Product', required=True),
+ 'date': fields.related('order_id', 'date', type='date', string="Date", readonly=True, store=True),
+ 'supplier': fields.related('product_id', '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),
+ 'note': fields.text('Note'),
+ 'price': fields.float("Price"),
+ 'state': fields.selection([('new', 'New'), \
+ ('confirmed', 'Received'), \
+ ('ordered', 'Ordered'), \
+ ('cancelled', 'Cancelled')], \
+ 'Status', readonly=True, select=True),
+ 'cashmove': fields.one2many('lunch.cashmove', 'order_id', 'Cash Move', ondelete='cascade'),
+ }
_defaults = {
- 'active': lambda *a : True,
+ 'state': 'new',
}
-lunch_product()
-
-
-class lunch_cashbox(osv.osv):
- """ cashbox for Lunch """
-
- _name = 'lunch.cashbox'
- _description = "Cashbox for Lunch "
-
-
- def amount_available(self, cr, uid, ids, field_name, arg, context=None):
-
- """ count available amount
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of create menu’s IDs
- @param context: A standard dictionary for contextual values """
-
- cr.execute("SELECT box,sum(amount) from lunch_cashmove where active = 't' group by box")
- amount = dict(cr.fetchall())
- for i in ids:
- amount.setdefault(i, 0)
- return amount
+class lunch_product(osv.Model):
+ """
+ lunch product
+ """
+ _name = 'lunch.product'
+ _description = 'lunch product'
_columns = {
- 'manager': fields.many2one('res.users', 'Manager'),
- 'name': fields.char('Name', size=30, required=True, unique = True),
- 'sum_remain': fields.function(amount_available, string='Total Remaining'),
+ 'name': fields.char('Product', required=True, size=64),
+ 'category_id': fields.many2one('lunch.product.category', 'Category', required=True),
+ 'description': fields.text('Description', size=256),
+ 'price': fields.float('Price', digits=(16,2)), #TODO: use decimal precision of 'Account', move it from product to decimal_precision
+ 'supplier': fields.many2one('res.partner', 'Supplier'),
}
-lunch_cashbox()
-
-
-class lunch_cashmove(osv.osv):
- """ Move cash """
-
- _name = 'lunch.cashmove'
- _description = "Cash Move"
-
+class lunch_product_category(osv.Model):
+ """
+ lunch product category
+ """
+ _name = 'lunch.product.category'
+ _description = 'lunch product category'
_columns = {
- 'name': fields.char('Description', size=128),
- 'user_cashmove': fields.many2one('res.users', 'User Name', required=True),
- 'amount': fields.float('Amount', digits=(16, 2)),
- 'box': fields.many2one('lunch.cashbox', 'Box Name', size=30, required=True),
- 'active': fields.boolean('Active'),
- 'create_date': fields.datetime('Creation Date', readonly=True),
- }
-
- _defaults = {
- 'active': lambda *a: True,
+ 'name': fields.char('Category', required=True), #such as PIZZA, SANDWICH, PASTA, CHINESE, BURGER, ...
}
-lunch_cashmove()
-
-
-class lunch_order(osv.osv):
- """ Apply lunch order """
-
- _name = 'lunch.order'
- _description = "Lunch Order"
- _rec_name = "user_id"
-
- def _price_get(self, cr, uid, ids, name, args, context=None):
-
- """ Get Price of Product
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of Lunch order’s IDs
- @param context: A standard dictionary for contextual values """
-
- res = {}
- for price in self.browse(cr, uid, ids, context=context):
- res[price.id] = price.product.price
- return res
-
+class lunch_cashmove(osv.Model):
+ """
+ lunch cashmove => order or payment
+ """
+ _name = 'lunch.cashmove'
+ _description = 'lunch cashmove'
_columns = {
- 'user_id': fields.many2one('res.users', 'User Name', required=True, \
- readonly=True, states={'draft':[('readonly', False)]}),
- 'product': fields.many2one('lunch.product', 'Product', required=True, \
- readonly=True, states={'draft':[('readonly', False)]}, change_default=True),
- 'date': fields.date('Date', readonly=True, states={'draft':[('readonly', False)]}),
- 'cashmove': fields.many2one('lunch.cashmove', 'Cash Move' , readonly=True),
- 'descript': fields.char('Comment', readonly=True, size=250, \
- states = {'draft':[('readonly', False)]}),
- 'state': fields.selection([('draft', 'New'), ('confirmed', 'Confirmed'), ], \
- 'Status', readonly=True, select=True),
- 'price': fields.function(_price_get, string="Price"),
- 'category': fields.many2one('lunch.category','Category'),
+ 'user_id': fields.many2one('res.users', 'User Name', required=True),
+ 'date': fields.date('Date', required=True),
+ 'amount': fields.float('Amount', required=True), #depending on the kind of cashmove, the amount will be positive or negative
+ 'description': fields.text('Description'), #the description can be an order or a payment
+ 'order_id': fields.many2one('lunch.order.line', 'Order', ondelete='cascade'),
+ 'state': fields.selection([('order','Order'), ('payment','Payment')], 'Is an order or a Payment'),
}
-
_defaults = {
'user_id': lambda self, cr, uid, context: uid,
'date': fields.date.context_today,
- 'state': lambda self, cr, uid, context: 'draft',
+ 'state': 'payment',
}
- def confirm(self, cr, uid, ids, box, context=None):
-
- """ confirm order
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of confirm order’s IDs
- @param context: A standard dictionary for contextual values """
-
- cashmove_ref = self.pool.get('lunch.cashmove')
- for order in self.browse(cr, uid, ids, context=context):
- if order.state == 'confirmed':
- continue
- new_id = cashmove_ref.create(cr, uid, {'name': order.product.name+' order',
- 'amount':-order.product.price,
- 'user_cashmove':order.user_id.id,
- 'box':box,
- 'active':True,
- })
- self.write(cr, uid, [order.id], {'cashmove': new_id, 'state': 'confirmed'})
- return {}
-
- def lunch_order_cancel(self, cr, uid, ids, context=None):
-
- """" cancel order
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of create menu’s IDs
- @param context: A standard dictionary for contextual values """
-
- orders = self.browse(cr, uid, ids, context=context)
- for order in orders:
- if not order.cashmove:
- continue
- if order.cashmove.id:
- self.pool.get('lunch.cashmove').unlink(cr, uid, [order.cashmove.id])
- self.write(cr, uid, ids, {'state':'draft'})
- return {}
-
- def onchange_product(self, cr, uid, ids, product):
-
- """ Get price for Product
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of create menu’s IDs
- @product: Product To Ordered """
-
- if not product:
- return {'value': {'price': 0.0}}
- price = self.pool.get('lunch.product').read(cr, uid, product, ['price'])['price']
- categ_id = self.pool.get('lunch.product').browse(cr, uid, product).category_id.id
- return {'value': {'price': price,'category':categ_id}}
-
-lunch_order()
-
-
-class report_lunch_amount(osv.osv):
- """ Lunch Amount Report """
-
- _name = 'report.lunch.amount'
- _description = "Amount available by user and box"
- _auto = False
- _rec_name = "user_id"
-
+class lunch_alert(osv.Model):
+ """
+ lunch alert
+ """
+ _name = 'lunch.alert'
+ _description = 'Lunch Alert'
_columns = {
- 'user_id': fields.many2one('res.users', 'User Name', readonly=True),
- 'amount': fields.float('Amount', readonly=True, digits=(16, 2)),
- 'box': fields.many2one('lunch.cashbox', 'Box Name', size=30, readonly=True),
- 'year': fields.char('Year', size=4, readonly=True),
- 'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
- ('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
- ('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
- 'day': fields.char('Day', size=128, readonly=True),
- 'date': fields.date('Created Date', readonly=True),
+ 'message': fields.text('Message', size=256, required=True),
+ 'alter_type': fields.selection([('specific', 'Specific Day'), \
+ ('week', 'Every Week'), \
+ ('days', 'Every Day')], \
+ string='Recurrency', required=True, select=True),
+ 'specific_day': fields.date('Day'),
+ 'monday': fields.boolean('Monday'),
+ 'tuesday': fields.boolean('Tuesday'),
+ 'wednesday': fields.boolean('Wednesday'),
+ 'thursday': fields.boolean('Thursday'),
+ 'friday': fields.boolean('Friday'),
+ 'saturday': fields.boolean('Saturday'),
+ 'sunday': fields.boolean('Sunday'),
+ 'active_from': fields.float('Between', required=True),
+ 'active_to': fields.float('And', required=True),
+ }
+ _defaults = {
+ 'alter_type': 'specific',
+ 'specific_day': fields.date.context_today,
+ 'active_from': 7,
+ 'active_to': 23,
}
-
- def init(self, cr):
-
- """ @param cr: the current row, from the database cursor"""
-
- cr.execute("""
- create or replace view report_lunch_amount as (
- select
- min(lc.id) as id,
- to_date(to_char(lc.create_date, 'dd-MM-YYYY'),'dd-MM-YYYY') as date,
- to_char(lc.create_date, 'YYYY') as year,
- to_char(lc.create_date, 'MM') as month,
- to_char(lc.create_date, 'YYYY-MM-DD') as day,
- lc.user_cashmove as user_id,
- sum(amount) as amount,
- lc.box as box
- from
- lunch_cashmove lc
- where
- active = 't'
- group by lc.user_cashmove, lc.box, lc.create_date
- )""")
-
-report_lunch_amount()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
<openerp>
<data noupdate="1">
- <record model="lunch.category" id="categ_sandwich">
+ <record id="base.user_root" model="res.users">
+ <field name="groups_id" eval="[(4,ref('lunch.group_lunch_manager'))]"/>
+ </record>
+ <record id="base.user_demo" model="res.users">
+ <field name="groups_id" eval="[(4,ref('lunch.group_lunch_user'))]"/>
+ </record>
+
+ <record model="lunch.product.category" id="categ_sandwich">
<field name="name">Sandwich</field>
</record>
+ <record model="lunch.product.category" id="categ_pizza">
+ <field name="name">Pizza</field>
+ </record>
+ <record model="lunch.product.category" id="categ_pasta">
+ <field name="name">Pasta</field>
+ </record>
- <record model="lunch.product" id="product_club">
- <field name="name">Club</field>
+ <record model="res.partner" id="partner_coin_gourmand">
+ <field name="name">Coin gourmand</field>
+ <field name="supplier_lunch">True</field>
+ </record>
+
+ <record model="res.partner" id="partner_pizza_inn">
+ <field name="name">Pizza Inn</field>
+ <field name="supplier_lunch">True</field>
+ </record>
+
+ <record model="lunch.product" id="product_cheese_ham">
+ <field name="name">Cheese And Ham</field>
<field name="category_id" eval="str(ref('categ_sandwich'))"/>
- <field name="price">2.75</field>
+ <field name="price">3.30</field>
+ <field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
+ <field name="description">Cheese, Ham, Salad, Tomatoes, cucumbers, eggs</field>
</record>
- <record model="lunch.cashbox" id="cashbox_cashbox">
- <field name="name">Cashbox</field>
- <field name="manager" ref="base.user_root"/>
+ <record model="lunch.product" id="product_country">
+ <field name="name">The Country</field>
+ <field name="category_id" eval="str(ref('categ_sandwich'))"/>
+ <field name="price">3.30</field>
+ <field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
+ <field name="description">Brie, Honey, Walnut Kernels</field>
</record>
- <record id="base.user_demo" model="res.users">
- <field name="groups_id" eval="[(4,ref('base.group_tool_user'))]"/>
+ <record model="lunch.product" id="product_tuna">
+ <field name="name">Tuna</field>
+ <field name="category_id" eval="str(ref('categ_sandwich'))"/>
+ <field name="price">2.50</field>
+ <field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
+ <field name="description">Tuna, Mayonnaise</field>
+ </record>
+
+ <record model="lunch.product" id="product_gouda">
+ <field name="name">Gouda Cheese</field>
+ <field name="category_id" eval="str(ref('categ_sandwich'))"/>
+ <field name="price">2.50</field>
+ <field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
+ <field name="description"></field>
+ </record>
+
+ <record model="lunch.product" id="product_chicken_curry">
+ <field name="name">Chicken Curry</field>
+ <field name="category_id" eval="str(ref('categ_sandwich'))"/>
+ <field name="price">2.60</field>
+ <field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
+ <field name="description"></field>
+ </record>
+
+ <record model="lunch.product" id="product_margherita">
+ <field name="name">Pizza Margherita</field>
+ <field name="category_id" eval="str(ref('categ_pizza'))"/>
+ <field name="price">6.90</field>
+ <field name="supplier" eval="str(ref('partner_pizza_inn'))"/>
+ <field name="description">Tomatoes, Mozzarella</field>
+ </record>
+
+ <record model="lunch.product" id="product_italiana">
+ <field name="name">Pizza Italiana</field>
+ <field name="category_id" eval="str(ref('categ_pizza'))"/>
+ <field name="price">7.40</field>
+ <field name="supplier" eval="str(ref('partner_pizza_inn'))"/>
+ <field name="description">Fresh Tomatoes, Basil, Mozzarella</field>
+ </record>
+
+ <record model="lunch.product" id="product_Bolognese">
+ <field name="name">Bolognese Pasta</field>
+ <field name="category_id" eval="str(ref('categ_pasta'))"/>
+ <field name="price">7.70</field>
+ <field name="supplier" eval="str(ref('partner_pizza_inn'))"/>
+ <field name="description"></field>
+ </record>
+
+ <record model="lunch.product" id="product_Napoli">
+ <field name="name">Napoli Pasta</field>
+ <field name="category_id" eval="str(ref('categ_pasta'))"/>
+ <field name="price">7.70</field>
+ <field name="supplier" eval="str(ref('partner_pizza_inn'))"/>
+ <field name="description">Tomatoes, Basil</field>
+ </record>
+
+ <record model="lunch.order" id="order_1">
+ <field name="user_id" ref="base.user_root"/>
+ <field name="date" eval="time.strftime('2012-10-23')"/>
+ <field name="order_line_ids" eval="[]"/>
+ <field name="state">new</field>
+ <field name='company_id'>1</field>
+ </record>
+
+ <record model="lunch.order" id="order_2">
+ <field name="user_id" ref="base.user_root"/>
+ <field name="date" eval="time.strftime('2012-10-22')"/>
+ <field name="order_line_ids" eval="[]"/>
+ <field name="state">confirmed</field>
+ <field name='company_id'>1</field>
+ </record>
+
+ <record model="lunch.order" id="order_3">
+ <field name="user_id" ref="base.user_root"/>
+ <field name="date" eval="time.strftime('2012-10-24')"/>
+ <field name="order_line_ids" eval="[]"/>
+ <field name="state">cancelled</field>
+ <field name='company_id'>1</field>
+ </record>
+
+ <record model="lunch.order.line" id="order_line_1">
+ <field name="user_id" ref="base.user_root"/>
+ <field name="product_id" ref="product_Bolognese"/>
+ <field name="date" eval="time.strftime('2012-10-23')"/>
+ <field name="state">new</field>
+ <field name="supplier" ref="partner_pizza_inn"/>
+ <field name="note">+Emmental</field>
+ <field name="order_id" ref="order_1"/>
+ </record>
+
+ <record model="lunch.order.line" id="order_line_2">
+ <field name="user_id" ref="base.user_root"/>
+ <field name="product_id" ref="product_italiana"/>
+ <field name="date" eval="time.strftime('2012-10-22')"/>
+ <field name="state">confirmed</field>
+ <field name="supplier" ref="partner_pizza_inn"/>
+ <field name="note">+Mushrooms</field>
+ <field name="order_id" ref="order_2"/>
+ </record>
+
+ <record model="lunch.order.line" id="order_line_3">
+ <field name="user_id" ref="base.user_root"/>
+ <field name="product_id" ref="product_gouda"/>
+ <field name="date" eval="time.strftime('2012-10-24')"/>
+ <field name="state">cancelled</field>
+ <field name="supplier" ref="partner_coin_gourmand"/>
+ <field name="note">+Salad +Tomatoes +Cucumbers</field>
+ <field name="order_id" ref="order_3"/>
+ </record>
+
+
+ <record model="lunch.cashmove" id="cashmove_1">
+ <field name="user_id" ref="base.user_root"/>
+ <field name="date" eval="time.strftime('2012-10-23')"/>
+ <field name="description">Pizza Italiana</field>
+ <field name="amount">-7.40</field>
+ <field name="order_id" ref="order_2"/>
+ <field name="state">order</field>
+ </record>
+
+ <record model="lunch.cashmove" id="cashmove_2">
+ <field name="user_id" ref="base.user_root"/>
+ <field name="date" eval="time.strftime('2012-10-24')"/>
+ <field name="description">Payment: 5 lunch tickets (6€)</field>
+ <field name="amount">30</field>
+ <field name="state">payment</field>
+ </record>
+
+ <record model="lunch.alert" id="alert_1">
+ <field name="message">Lunch must be ordered before 10h30 am</field>
+ <field name="day">days</field>
</record>
</data>
+++ /dev/null
-<openerp>
- <data>
- <record model="ir.actions.act_window" id="view_lunch_product_form_installer">
- <field name="name">Define Your Lunch Products</field>
- <field name="type">ir.actions.act_window</field>
- <field name="res_model">lunch.product</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <field name="view_id" eval="False"/>
- <field name="help" type="html">
- <p class="oe_view_nocontent_create">
- Click to add a new product that can be ordered for the lunch.
- </p><p>
- We suggest you to put the real price so that the exact due
- amount is deduced from each employee's cash boxes when they
- order.
- </p><p>
- If you order lunch at several places, you can use the product
- categories to split by supplier. It will be easier to filter
- lunch orders.
- </p>
- </field>
- </record>
-
- <record id="view_lunch_product_form_todo" model="ir.actions.todo">
- <field name="action_id" ref="view_lunch_product_form_installer"/>
- <field name="sequence">50</field>
- </record>
-
- <record model="ir.actions.act_window" id="action_create_cashbox">
- <field name="name">Create Lunch Cash Boxes</field>
- <field name="type">ir.actions.act_window</field>
- <field name="res_model">lunch.cashbox</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <field name="help" type="html">
- <p class="oe_view_nocontent_create">
- Click to add a new cash box.
- </p><p>
- You can create on cash box by employee if you want to keep
- track of the amount due by employee according to what have been
- ordered.
- </p>
- </field>
- </record>
-
- <record id="action_create_cashbox_todo" model="ir.actions.todo">
- <field name="action_id" ref="action_create_cashbox" />
- <field name="sequence">51</field>
- </record>
- </data>
-</openerp>
<report
id="report_lunch_order"
string="Lunch Order"
- model="lunch.order"
- name="lunch.order"
+ model="lunch.order.line"
+ name="lunch.order.line"
rml="lunch/report/order.rml"
auto="False"
/>
<?xml version="1.0"?>
<openerp>
<data>
- <!-- Top menu item -->
- <menuitem name="Tools" id="base.menu_tools" sequence="160"/>
-
- <menuitem name="Lunch Order" parent="base.menu_tools"
- id="menu_lunch" sequence="1" />
-
- <menuitem name="Reporting" parent="base.menu_tools"
- id="base.menu_lunch_reporting" sequence="6" groups="base.group_tool_manager"/>
-
- <menuitem name="Lunch"
- parent="base.menu_reporting"
- id="menu_lunch_reporting_order" sequence="55" />
-
- <menuitem name="Configuration" parent="base.menu_tools"
- id="base.menu_lunch_survey_root" sequence="20" groups="base.group_tool_manager"/>
-
- <menuitem name="Lunch" parent="base.menu_lunch_survey_root"
- id="menu_lunch_category_root_configuration" sequence="1" />
-
-<!-- Lunch order Form view -->
-
- <record model="ir.ui.view" id="view_lunch_order_form">
- <field name="name">Order</field>
- <field name="model">lunch.order</field>
+ <!--Menu and Title-->
+ <menuitem id='menu_lunch' name='Lunch' sequence="300"/>
+ <menuitem name="Lunch" parent="menu_lunch" id="menu_lunch_title" sequence="50" />
+ <menuitem name="Administrate Orders" parent="menu_lunch" id="menu_lunch_admin" sequence="51" groups="group_lunch_manager"/>
+ <menuitem name="Administrate Cash Moves" parent="menu_lunch" id="menu_lunch_cash" sequence="52" groups="group_lunch_manager"/>
+ <menuitem name="Configuration" parent="menu_lunch" id="menu_lunch_config" sequence="53" groups="group_lunch_manager"/>
+
+ <!--View Search to group/filter by Supplier and time-->
+ <record model="ir.ui.view" id="lunch_order_line_search_view">
+ <field name="name">Search</field>
+ <field name="model">lunch.order.line</field>
+ <field name="type">search</field>
<field name="arch" type="xml">
- <form string="Lunch Order" version="7.0">
- <header>
- <button name="%(action_lunch_order_confirm)d" string="Confirm Order" type="action" states="draft" class="oe_highlight"/>
- <button name="%(action_lunch_order_cancel)d" string="Cancel Order" type="action" states="confirmed" />
- <field name="state" widget="statusbar" statusbar_visible="draft,confirmed"/>
- </header>
- <sheet string="Order">
- <group>
- <group>
- <field name="product" on_change="onchange_product(product)"/>
- <field name="descript"/>
- <field name="price"/>
- <field name="category"/>
- </group>
- <group>
- <field name="user_id"/>
- <field name="cashmove"/>
- <field name="date"/>
- </group>
+ <search string="Search">
+ <field name="name" filter_domain="['|', ('name', 'ilike', self), ('note', 'ilike', self)]"/>
+ <filter name="not_confirmed" string="Not Received" domain="[('state','!=',('confirmed'))]"/>
+ <filter name="comfirmed" string="Received" domain="[('state','=','confirmed')]"/>
+ <filter name="cancelled" string="Cancelled" domain="[('state','=','cancelled')]"/>
+ <separator/>
+ <filter name="today" string="Today" domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]"/>
+ <field name="user_id"/>
+ <group expand="0" string="Group By...">
+ <filter name="group_by_supplier" string="By Supplier" context="{'group_by':'supplier'}"/>
+ <filter name="group_by_date" string="By Date" context="{'group_by':'date'}"/>
</group>
- </sheet>
- </form>
+ </search>
</field>
</record>
-<!-- Lunch order Tree view -->
-
- <record model="ir.ui.view" id="view_lunch_order_tree">
- <field name="name">Order</field>
- <field name="model">lunch.order</field>
- <field name="arch" type="xml">
- <tree colors="blue:state == 'draft';black:state == 'confirmed'" string="Order">
- <field name="date"/>
+ <!--View Search to group by employee and input/output (cashmoves)-->
+ <record id="view_lunch_employee_payment_filter" model="ir.ui.view">
+ <field name='name'>lunch employee payment</field>
+ <field name='model'>lunch.cashmove</field>
+ <field name='type'>search</field>
+ <field name='arch' type='xml'>
+ <search string="lunch employee payment">
+ <field name="description"/>
<field name="user_id"/>
- <field name="product"/>
- <field name="descript"/>
- <field name="category"/>
- <field name="price" sum="Total price"/>
- <field name="state"/>
- </tree>
+ <filter name='is_payment' string="Payment" domain="[('state','=','payment')]"/>
+ <separator/>
+ <filter name='is_mine' string="My Account" domain="[('user_id','=',uid)]"/>
+ </search>
</field>
</record>
-<!-- Lunch order Search view -->
-
- <record id="view_lunch_order_filter" model="ir.ui.view">
- <field name="name">lunch.order.list.select</field>
- <field name="model">lunch.order</field>
- <field name="arch" type="xml">
- <search string="Search Lunch Order">
- <field name="date"/>
- <filter icon="terp-check" string="To Confirm" domain="[('state','=','draft')]"/>
- <filter icon="terp-camera_test" string="Confirmed" domain="[('state','=',('confirmed'))]"/>
+ <record id="view_lunch_cashmove_filter" model="ir.ui.view">
+ <field name='name'>lunch cashmove</field>
+ <field name='model'>lunch.cashmove</field>
+ <field name='type'>search</field>
+ <field name='arch' type='xml'>
+ <search string="lunch cashmove">
+ <field name="description"/>
<field name="user_id"/>
<group expand="0" string="Group By...">
- <filter string="Category" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'category'}"/>
+ <filter name='group_by_user' string="By Employee" context="{'group_by':'user_id'}"/>
</group>
</search>
</field>
</record>
-<!-- Lunch order Action -->
-
- <record model="ir.actions.act_window" id="action_lunch_order_form">
- <field name="name">Lunch Orders</field>
- <field name="res_model">lunch.order</field>
- <field name="view_mode">tree,form</field>
- <field name="search_view_id" ref="view_lunch_order_filter"/>
- <field name="context">{"search_default_Today":1}</field>
+ <!--View search for order-->
+ <record id="view_search_my_order" model="ir.ui.view">
+ <field name='name'>lunch orders</field>
+ <field name='model'>lunch.order</field>
+ <field name='type'>search</field>
+ <field name='arch' type='xml'>
+ <search string="lunch orders">
+ <field name="date"/>
+ <field name="order_line_ids"/>
+ <filter name='is_mine' string="My Orders" domain="[('user_id','=',uid)]"/>
+ </search>
+ </field>
</record>
- <menuitem name="Lunch Orders" parent="menu_lunch"
- id="menu_lunch_order_form" action="action_lunch_order_form" />
-
-<!-- Cash Box Form view -->
- <record model="ir.ui.view" id="view_lunch_cashbox_form">
- <field name="name">Cashboxes</field>
- <field name="model">lunch.cashbox</field>
+ <record model="ir.ui.view" id="alert_search_view">
+ <field name="name">Search</field>
+ <field name="model">lunch.alert</field>
+ <field name="type">search</field>
<field name="arch" type="xml">
- <form string="Cashboxes" version="7.0">
- <group colspan="4">
- <field name="name"/>
- <field name="manager"/>
- </group>
- </form>
+ <search string="Search">
+ <field name="message"/>
+ </search>
</field>
</record>
-<!-- Cash Box Tree view -->
+ <!--Action for Your Orders-->
+ <record model="ir.actions.act_window" id="action_lunch_order_form">
+ <field name="name">New Order</field>
+ <field name="res_model">lunch.order</field>
+ <field name="view_mode">form</field>
+ </record>
+ <menuitem name="New Order" parent="menu_lunch_title" id="menu_lunch_order_form" action="action_lunch_order_form" sequence="1"/>
- <record model="ir.ui.view" id="view_lunch_cashbox_tree">
- <field name="name">Cashboxes</field>
- <field name="model">lunch.cashbox</field>
- <field name="arch" type="xml">
- <tree string="Cashboxes" colors="red:sum_remain<=0">
- <field name="name"/>
- <field name="manager"/>
- <field name="sum_remain"/>
- </tree>
+ <record model="ir.actions.act_window" id="action_lunch_order_tree">
+ <field name="name">Your Orders</field>
+ <field name="res_model">lunch.order</field>
+ <field name="view_mode">tree,form</field>
+ <field name="search_view_id" ref="view_search_my_order"/>
+ <field name="context">{"search_default_is_mine":1}</field>
+ <field name="help" type="html">
+ <p class="oe_view_nocontent_create">
+ Click to create a lunch order.
+ </p>
+ <p>
+ A lunch order is defined by its user, date and order lines.
+ Each order line corresponds to a product, an additional note and a price.
+ Before selecting your order lines, don't forget to read the warnings displayed in the reddish area.
+ </p>
</field>
</record>
+ <menuitem name="Previous Orders" parent="menu_lunch_title" id="menu_lunch_order_tree" action="action_lunch_order_tree" sequence="2"/>
-<!-- Cash Box Action -->
-
- <record model="ir.actions.act_window" id="action_lunch_cashbox_form">
- <field name="name"> Cashboxes </field>
- <field name="res_model">lunch.cashbox</field>
+ <!--Action for Lunch cashmoves-->
+ <record model="ir.actions.act_window" id="action_lunch_cashmove_form">
+ <field name="name">Your Account</field>
+ <field name="res_model">lunch.cashmove</field>
+ <field name="view_mode">tree</field>
+ <field name="search_view_id" ref="view_lunch_employee_payment_filter"/>
+ <field name="context">{"search_default_is_mine":1}</field>
+ <field name="help" type="html">
+ <p>
+ Here you can see your cash moves.<br/>A cash moves can be either an expense or a payment.
+ An expense is automatically created when an order is received while a payment is a reimbursement to the company encoded by the manager.
+ </p>
+ </field>
</record>
-
- <menuitem name="Cashboxes"
- parent="menu_lunch_category_root_configuration"
- id="menu_lunch_cashbox_form"
- action="action_lunch_cashbox_form" />
-
-<!-- Cash Move Form view -->
-
- <record model="ir.ui.view" id="view_lunch_cashmove_form">
- <field name="name">CashMove</field>
- <field name="model">lunch.cashmove</field>
- <field name="arch" type="xml">
- <form string="CashMove" version="7.0">
- <sheet>
- <group col="4">
- <field name="name"/>
- <field name="user_cashmove"/>
- <field name="amount"/>
- <field name="box"/>
- <field name="create_date"/>
- <field name="active"/>
- </group>
- </sheet>
- </form>
+ <menuitem name="Your Lunch Account" parent="menu_lunch_title" id="menu_lunch_cashmove_form" action="action_lunch_cashmove_form" sequence="3"/>
+
+ <!--Action for Administrate Orders group by supplier-->
+ <record model="ir.actions.act_window" id="action_lunch_order_by_supplier_form">
+ <field name="name">Orders by Supplier</field>
+ <field name="res_model">lunch.order.line</field>
+ <field name="view_mode">tree</field>
+ <field name="search_view_id" ref="lunch_order_line_search_view"/>
+ <field name="context">{"search_default_group_by_supplier":1, "search_default_today":1}</field>
+ <field name="help" type="html">
+ <p>
+ Here you can see today's orders grouped by suppliers.
+ </p>
+ <p>
+ - Click on the <img src="../../../web/static/src/img/icons/terp-call-start.png"/> to announce that the order is ordered <br/>
+ - Click on the <img src="../../../web/static/src/img/icons/gtk-apply.png"/> to announce that the order is received <br/>
+ - Click on the <img src="../../../web/static/src/img/icons/gtk-cancel.png"/> to announce that the order isn't available
+ </p>
</field>
</record>
-
-<!-- Cash Move Tree view -->
-
- <record model="ir.ui.view" id="view_lunch_cashmove_tree">
- <field name="name">CashMove</field>
- <field name="model">lunch.cashmove</field>
- <field name="arch" type="xml">
- <tree string="CashMove" editable="top">
- <field name="create_date"/>
- <field name="box"/>
- <field name="name" required="1"/>
- <field name="user_cashmove"/>
- <field name="amount" sum="Total amount"/>
- </tree>
+ <menuitem name="Today's Orders by Supplier" parent="menu_lunch_admin" id="menu_lunch_order_by_supplier_form" action="action_lunch_order_by_supplier_form" />
+
+ <!--Action for control Supplier-->
+ <record model="ir.actions.act_window" id="action_lunch_control_suppliers">
+ <field name="name">Control Suppliers</field>
+ <field name="res_model">lunch.order.line</field>
+ <field name="view_mode">tree</field>
+ <field name="search_view_id" ref="lunch_order_line_search_view"/>
+ <field name="context">{"search_default_group_by_date":1, "search_default_group_by_supplier":1}</field>
+ <field name="help" type="html">
+ <p>
+ Here you can see every orders grouped by suppliers and by date.
+ </p>
+ <p>
+ - Click on the <img src="../../../web/static/src/img/icons/terp-call-start.png"/> to announce that the order is ordered <br/>
+ - Click on the <img src="../../../web/static/src/img/icons/gtk-apply.png"/> to announce that the order is received <br/>
+ - Click on the <img src="../../../web/static/src/img/icons/gtk-cancel.png"/> red X to announce that the order isn't available
+ </p>
</field>
</record>
+ <menuitem name="Orders by Supplier" parent="menu_lunch_admin" id="menu_lunch_control_suppliers" action="action_lunch_control_suppliers" />
-<!-- Cash Move Search View -->
-
- <record id="view_lunch_cashmove_filter" model="ir.ui.view">
- <field name="name">lunch.cashmove.list.select</field>
- <field name="model">lunch.cashmove</field>
- <field name="arch" type="xml">
- <search string="Search CashMove">
- <field name="create_date"/>
- <field name="user_cashmove"/>
- <group expand="0" string="Group By...">
- <filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'user_cashmove'}"/>
- <filter string="Box" icon="terp-dolar" domain="[]" context="{'group_by':'box'}"/>
- <filter string="Date" icon="terp-go-today" domain="[]" context="{'group_by':'create_date'}"/>
- </group>
- </search>
+ <!--Action for Control Accounts-->
+ <record model="ir.actions.act_window" id="action_lunch_control_accounts">
+ <field name="name">Control Accounts</field>
+ <field name="res_model">lunch.cashmove</field>
+ <field name="view_mode">tree,form</field>
+ <field name="search_view_id" ref="view_lunch_cashmove_filter"/>
+ <field name="context">{"search_default_group_by_user":1}</field>
+ <field name="help" type="html">
+ <p class="oe_view_nocontent_create">
+ Click to create a new payment.
+ </p>
+ <p>
+ A cashmove can either be an expense or a payment.<br/>
+ An expense is automatically created at the order receipt.<br/>
+ A payment represents the employee reimbursement to the company.
+ </p>
</field>
</record>
+ <menuitem name="Control Accounts" parent="menu_lunch_cash" id="menu_lunch_control_accounts" action="action_lunch_control_accounts" />
-<!-- Cash Move Action -->
- <record model="ir.actions.act_window" id="action_lunch_cashmove_form">
- <field name="name">Cash Moves</field>
- <field name="res_model">lunch.cashmove</field>
- <field name="search_view_id" ref="view_lunch_cashmove_filter"/>
- <field name="context">{"search_default_Today":1}</field>
+ <!--Action for Payment cashmove-->
+ <record model="ir.actions.act_window" id="action_lunch_cashmove">
+ <field name="name">Register Cash Moves</field>
+ <field name="res_model">lunch.cashmove</field>
+ <field name="view_mode">tree,form</field>
+ <field name="search_view_id" ref="view_lunch_employee_payment_filter"/>
+ <field name="context">{"search_default_is_payment":1}</field>
+ <field name="help" type="html">
+ <p class="oe_view_nocontent_create">
+ Click to create a payment.
+ </p>
+ <p>
+ Here you can see the employees' payment. A payment is a cash move from the employee to the company.
+ </p>
+ </field>
</record>
+ <menuitem name="Employee's Payment" parent="menu_lunch_cash" id="menu_lunch_cashmove" action="action_lunch_cashmove" />
- <menuitem name="Cash Moves" parent="menu_lunch"
- id="menu_lunch_cashmove_form"
- action="action_lunch_cashmove_form" />
+ <!--Action for Products-->
+ <record model="ir.actions.act_window" id="action_lunch_products">
+ <field name="name">Products</field>
+ <field name="res_model">lunch.product</field>
+ <field name="view_mode">tree,form</field>
+ <field name="help" type="html">
+ <p class="oe_view_nocontent_create">
+ Click to create a product for lunch.
+ </p>
+ <p>
+ A product is defined by its name, category, price and supplier.
+ </p>
+ </field>
+ </record>
+ <menuitem name="Products" parent="menu_lunch_config" id="menu_lunch_products" action="action_lunch_products" />
-<!-- Lunch Category Form view -->
+ <!--Action for Product categories-->
+ <record model="ir.actions.act_window" id="action_lunch_product_categories">
+ <field name="name">Product Categories</field>
+ <field name="res_model">lunch.product.category</field>
+ <field name="view_mode">tree,form</field>
+ <field name="help" type="html">
+ <p class="oe_view_nocontent_create">
+ Click to create a lunch category.
+ </p>
+ <p>
+ Here you can find every lunch categories for products.
+ </p>
+ </field>
+ </record>
- <record model="ir.ui.view" id="view_lunch_category_form">
- <field name="name"> Category of product </field>
- <field name="model">lunch.category</field>
+ <record model="ir.ui.view" id="product_category_form_view">
+ <field name="name">Product category Form</field>
+ <field name="model">lunch.product.category</field>
+ <field name="type">form</field>
<field name="arch" type="xml">
- <form string="Category" version="7.0">
+ <form string="Products Form" version="7.0">
+ <sheet>
<group>
- <field name="name"/>
+ <field name='name' string="Product Category: "/>
</group>
+ </sheet>
</form>
</field>
</record>
-<!-- Lunch Category Tree view -->
+ <menuitem name="Product Categories" parent="menu_lunch_config" id="menu_lunch_product_categories" action="action_lunch_product_categories" />
- <record model="ir.ui.view" id="view_lunch_category_tree">
- <field name="name">Category</field>
- <field name="model">lunch.category</field>
+ <!--Action for Alert-->
+ <record model="ir.actions.act_window" id="action_lunch_alert">
+ <field name="name">Alerts</field>
+ <field name="res_model">lunch.alert</field>
+ <field name="view_mode">tree,form</field>
+ <field name="search_view_id" ref="alert_search_view"/>
+ <field name="help" type="html">
+ <p class="oe_view_nocontent_create">
+ Click to create a lunch alert.
+ </p>
+ <p>
+ Alerts are used to warn employee from possible issues concerning the lunch orders.
+ To create a lunch alert you have to define its recurrency, the time interval during which the alert should be executed and the message to display.
+ </p>
+ <p>
+ Example: <br/>
+ - Recurency: Everyday<br/>
+ - Time interval: from 00h00 am to 11h59 pm<br/>
+ - Message: "You must order before 10h30 am"
+ </p>
+ </field>
+ </record>
+ <menuitem name="Alerts" parent="menu_lunch_config" id="menu_lunch_alert" action="action_lunch_alert" />
+
+ <!--View for Order lines-->
+ <record model="ir.ui.view" id="orders_order_lines_tree_view">
+ <field name="name">Order lines Tree</field>
+ <field name="model">lunch.order.line</field>
+ <field name="type">tree</field>
<field name="arch" type="xml">
- <tree string="Order">
- <field name="name"/>
+ <tree string="Order lines Tree">
+ <field name='date'/>
+ <field name='user_id'/>
+ <field name='supplier' invisible='1'/>
+ <field name='product_id'/>
+ <field name='note'/>
+ <field name='state'/>
+ <field name='price' sum="Total"/>
+ <button name="order" string="Order" type="object" icon="terp-call-start" attrs="{'invisible': ['|',('state','=','confirmed'),('state','=','ordered')]}"/>
+ <button name="confirm" string="Confirm" type="object" icon="gtk-apply" attrs="{'invisible': [('state','!=','ordered')]}"/>
+ <button name="cancel" string="Cancel" type="object" icon="gtk-cancel" attrs="{'invisible': [('state','=','cancelled')]}"/>
</tree>
</field>
</record>
-<!-- Lunch Category Action -->
-
- <record model="ir.actions.act_window" id="action_lunch_category_form">
- <field name="name"> Product Categories </field>
- <field name="res_model">lunch.category</field>
+ <!--View for Your orders-->
+ <record model="ir.ui.view" id="orders_tree_view">
+ <field name="name">Orders Tree View</field>
+ <field name="model">lunch.order</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="Orders Tree">
+ <field name="date"/>
+ <field name="order_line_ids"/>
+ <field name="state" />
+ <field name="total" sum="Total"/>
+ </tree>
+ </field>
</record>
-
-<!-- Lunch Product Form view -->
-
- <record model="ir.ui.view" id="view_lunch_product_form">
- <field name="name">Products</field>
- <field name="model">lunch.product</field>
+
+ <record model="ir.ui.view" id="orders_form_view">
+ <field name="name">Lunch Order</field>
+ <field name="model">lunch.order</field>
<field name="arch" type="xml">
- <form string="Products" version="7.0">
+ <form string='Orders Form' version='7.0' class="oe_lunch">
+ <header>
+ <field name='state' widget='statusbar' statusbar_visible='new,confirmed'/>
+ </header>
<sheet>
<group>
<group>
- <field name="name"/>
- <field name="category_id"/>
- <field name="price" />
+ <field name='user_id'/>
</group>
- <group>
- <field name="active"/>
+ <group>
+ <field name='date'/>
</group>
- <field name="description" placeholder="Add a description" nolabel="1" colspan="4"/>
</group>
+ <field name='alerts' attrs="{'invisible': ['|',('state','!=','new'),('alerts','=','')]}" class="oe_inline oe_lunch_alert"/>
+ <div name="preferences">
+ </div>
+ <separator string='Select your order'/>
+ <field name='order_line_ids' nolabel='1' on_change='onchange_price(order_line_ids)'>
+ <tree string='List' editable='bottom'>
+ <field name='product_id' on_change='onchange_price(product_id)'/>
+ <field name='note' />
+ <field name='price' />
+ <field name='supplier' invisible="1"/>
+ <field name="state" invisible="1"/>
+ </tree>
+ </field>
+ <group class='oe_subtotal_footer oe_right'>
+ <field name='total'/>
+ </group>
+ <br/><br/>
</sheet>
</form>
</field>
</record>
-<!-- Lunch Product Tree view -->
-
- <record model="ir.ui.view" id="view_lunch_product_tree">
- <field name="name">Products</field>
+ <!--View for Products-->
+ <record model="ir.ui.view" id="products_tree_view">
+ <field name="name">Products Tree</field>
<field name="model">lunch.product</field>
+ <field name="type">tree</field>
<field name="arch" type="xml">
- <tree string="Products">
+ <tree string="Products Tree">
<field name="name"/>
<field name="category_id"/>
- <field name="price"/>
+ <field name="supplier"/>
<field name="description"/>
+ <field name="price"/>
</tree>
</field>
</record>
-<!-- Lunch Product Search view -->
-
- <record model="ir.ui.view" id="view_lunch_product_search">
- <field name="name">Products</field>
+ <record model="ir.ui.view" id="products_form_view">
+ <field name="name">Products Form</field>
<field name="model">lunch.product</field>
+ <field name="type">form</field>
<field name="arch" type="xml">
- <search string="Products">
- <field name="name" string="Product"/>
- <field name="price"/>
- <field name="category_id"/>
- </search>
+ <form string="Products Form" version="7.0">
+ <header>
+ </header>
+ <sheet>
+ <group>
+ <field name='name'/>
+ <field name='category_id'/>
+ <field name='supplier'/>
+ <field name='price'/>
+ </group>
+ <label for='description'/>
+ <field name='description'/>
+ </sheet>
+ </form>
</field>
</record>
-<!-- Lunch Product Action -->
-
- <record model="ir.actions.act_window" id="action_lunch_product_form">
- <field name="name">Products</field>
- <field name="res_model">lunch.product</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <field name="view_id" ref="view_lunch_product_tree"/>
- <field name="search_view_id" ref="view_lunch_product_search"/>
- </record>
-
- <menuitem name="Products"
- parent="menu_lunch_category_root_configuration"
- id="menu_lunch_product_form" action="action_lunch_product_form"
- sequence="2" />
-
- <menuitem name="Product Categories"
- parent="menu_lunch_category_root_configuration"
- id="menu_lunch_category_form"
- action="action_lunch_category_form" sequence="1" />
-
-
-<!-- Lunch Amount Tree view -->
-
- <record model="ir.ui.view" id="view_report_lunch_amount_tree">
- <field name="name">Lunch amount</field>
- <field name="model">report.lunch.amount</field>
+ <!--view for cashmove-->
+ <record model="ir.ui.view" id="casmove_tree_view">
+ <field name="name">cashmove tree</field>
+ <field name="model">lunch.cashmove</field>
+ <field name="type">tree</field>
<field name="arch" type="xml">
- <tree string="Box Amount by User">
- <field name="date" invisible="1"/>
- <field name="year" invisible="1"/>
- <field name="day" invisible="1"/>
- <field name="month" invisible="1"/>
- <field name="box"/>
+ <tree string="cashmove tree">
+ <field name="date"/>
<field name="user_id"/>
- <field name="amount" sum="Total box" />
+ <field name="description"/>
+ <field name="amount" sum="Total"/>
</tree>
</field>
</record>
-<!-- Lunch Amount Form view -->
-
- <record model="ir.ui.view" id="view_report_lunch_amount_form">
- <field name="name">Lunch amount</field>
- <field name="model">report.lunch.amount</field>
+ <record model="ir.ui.view" id="casmove_form_view">
+ <field name="name">cashmove form</field>
+ <field name="model">lunch.cashmove</field>
+ <field name="type">form</field>
<field name="arch" type="xml">
- <form string="Box Amount by User" version="7.0">
- <sheet>
- <group col="4">
- <field name="user_id"/>
- <field name="box"/>
- <field name="amount"/>
- </group>
- </sheet>
+ <form string="cashmove form" version="7.0">
+ <sheet>
+ <group>
+ <field name="user_id"/>
+ <field name="date"/>
+ <field name="amount"/>
+ </group>
+ <label for='description'/>
+ <field name="description"/>
+ </sheet>
</form>
</field>
</record>
-<!-- Lunch Amount Search view -->
-
- <record model="ir.ui.view" id="view_report_lunch_amount_search">
- <field name="name">Lunch amount</field>
- <field name="model">report.lunch.amount</field>
+ <!--view for alerts-->
+ <record model="ir.ui.view" id="alert_tree_view">
+ <field name="name">alert tree</field>
+ <field name="model">lunch.alert</field>
+ <field name="type">tree</field>
<field name="arch" type="xml">
- <search string="Box Amount by User">
- <field name="date"/>
- <field name="box"/>
- <field name="amount"/>
- <field name="user_id"/>
- <group expand="0" string="Group By...">
- <filter string="Box" icon="terp-dolar" context="{'group_by':'box'}"/>
- </group>
- </search>
+ <tree string="alert tree">
+ <field name="message"/>
+ <field name="alter_type"/>
+ <field name='active_from' widget='float_time'/>
+ <field name='active_to' widget='float_time'/>
+ </tree>
</field>
</record>
-<!-- Lunch Amount Action -->
+ <record model="ir.ui.view" id="alert_form_view">
+ <field name="name">alert form</field>
+ <field name="model">lunch.alert</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="alert tree" version="7.0">
+ <sheet>
+ <group string="Schedule Date">
+ <group>
+ <field name="alter_type"/>
+ <field name="specific_day" attrs="{'invisible': [('alter_type','!=','specific')], 'required':[('alter_type','=','specific')]}"/>
+ </group>
+ </group>
+ <group attrs="{'invisible': [('alter_type','!=','week')]}">
+ <group>
+ <field name="monday"/>
+ <field name="tuesday"/>
+ <field name="wednesday"/>
+ <field name="thursday"/>
+ </group>
+ <group>
+ <field name="friday"/>
+ <field name="saturday"/>
+ <field name="sunday"/>
+ </group>
+ </group>
+ <group string="Schedule Hour">
+ <field name='active_from' widget='float_time'/>
+ <field name='active_to' widget='float_time'/>
+ </group>
+ <group string='Message'>
+ <field name='message' nolabel='1' placeholder="Write the message you want to display during the defined period..."/>
+ </group>
- <record model="ir.actions.act_window" id="action_report_lunch_amount_tree">
- <field name="name">Cash Position by User</field>
- <field name="res_model">report.lunch.amount</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <field name="context">{'search_default_year': 1,"search_default_month":1}</field>
- <field name="search_view_id" ref="view_report_lunch_amount_search"/>
+ </sheet>
+ </form>
+ </field>
</record>
- <menuitem name="Cash Position by User"
- parent="menu_lunch_reporting_order"
- action="action_report_lunch_amount_tree"
- id="menu_lunch_report_amount_tree" />
-
</data>
</openerp>
-
-
class order(report_sxw.rml_parse):
- def get_lines(self, user, objects):
+ def get_lines(self, user,objects):
lines=[]
for obj in objects:
if user.id==obj.user_id.id:
lines.append(obj)
return lines
- def get_total(self, user, objects):
+ def get_total(self, user,objects):
lines=[]
for obj in objects:
if user.id==obj.user_id.id:
users.append(obj.user_id)
return users
+ def get_note(self,objects):
+ notes=[]
+ for obj in objects:
+ notes.append(obj.note)
+ return notes
+
def __init__(self, cr, uid, name, context):
super(order, self).__init__(cr, uid, name, context)
self.net_total=0.0
'get_users': self.get_users,
'get_total': self.get_total,
'get_nettotal': self.get_nettotal,
+ 'get_note': self.get_note,
})
-report_sxw.report_sxw('report.lunch.order', 'lunch.order',
+report_sxw.report_sxw('report.lunch.order.line', 'lunch.order.line',
'addons/lunch/report/order.rml',parser=order, header='external')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
</para>
</td>
<td>
- <para style="terp_default_9_right_bold"><u>[[ formatLang(get_total(o,objects), currency_obj = o.company_id and o.company_id.currency_id) ]]</u></para>
+ <para style="terp_default_9_right_bold"><u>[[ formatLang(get_total(o,objects)) ]] [[ (o.company_id and o.company_id.currency_id and o.company_id.currency_id.symbol) or '' ]]</u></para>
</td>
</tr>
</blockTable>
<para style="terp_default_9_left9">[[ formatLang(lines.date,date='True') ]]</para>
</td>
<td>
- <para style="terp_default_9">[[ (lines.product and lines.product.name) or '' ]]</para>
+ <para style="terp_default_9">[[ (lines.product_id and lines.product_id.name) or '' ]]</para>
</td>
<td>
- <para style="terp_default_9">[[ lines.descript]]</para>
+ <para style="terp_default_9">[[ lines.note]]</para>
</td>
<td>
- <para style="terp_default_9_right">[[ formatLang(lines.price , currency_obj = o.company_id and o.company_id.currency_id) ]]</para>
+ <para style="terp_default_9_right">[[ lines.price ]] [[ (o.company_id and o.company_id.currency_id and o.company_id.currency_id.symbol) or '' ]]</para>
</td>
</tr>
</blockTable>
<para style="terp_tbl_detail_header">Total :</para>
</td>
<td>
- <para style="terp_default_9_right_bold">[[ formatLang(get_nettotal(), currency_obj = o.company_id and o.company_id.currency_id) ]]</para>
+ <para style="terp_default_9_right_bold">[[ formatLang(get_nettotal()) ]] [[ (o.company_id and o.company_id.currency_id and o.company_id.currency_id.symbol) or '' ]]</para>
</td>
</tr>
</blockTable>
from osv import fields,osv
class report_lunch_order(osv.osv):
- _name = "report.lunch.order"
+ _name = "report.lunch.order.line"
_description = "Lunch Orders Statistics"
_auto = False
_rec_name = 'date'
('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
'day': fields.char('Day', size=128, readonly=True),
'user_id': fields.many2one('res.users', 'User Name'),
- 'box_name': fields.char('Name', size=30),
'price_total':fields.float('Total Price', readonly=True),
+ 'note' : fields.text('Note',size=256,readonly=True),
}
_order = 'date desc'
def init(self, cr):
- tools.drop_view_if_exists(cr, 'report_lunch_order')
+ tools.drop_view_if_exists(cr, 'report_lunch_order_line')
cr.execute("""
- create or replace view report_lunch_order as (
+ create or replace view report_lunch_order_line as (
select
min(lo.id) as id,
+ lo.user_id as user_id,
lo.date as date,
to_char(lo.date, 'YYYY') as year,
to_char(lo.date, 'MM') as month,
to_char(lo.date, 'YYYY-MM-DD') as day,
- lo.user_id,
- cm.name as box_name,
+ lo.note as note,
sum(lp.price) as price_total
from
- lunch_order as lo
- left join lunch_cashmove as cm on (cm.id = lo.cashmove)
- left join lunch_cashbox as lc on (lc.id = cm.box)
- left join lunch_product as lp on (lo.product = lp.id)
-
+ lunch_order_line as lo
+ left join lunch_product as lp on (lo.product_id = lp.id)
group by
- lo.date,lo.user_id,cm.name
+ lo.date,lo.user_id,lo.note
)
""")
report_lunch_order()
<openerp>
<data>
- <record id="view_report_lunch_order_tree" model="ir.ui.view">
- <field name="name">report.lunch.order.tree</field>
- <field name="model">report.lunch.order</field>
- <field name="arch" type="xml">
- <tree string="Sales Analysis">
- <field name="date" invisible="1"/>
- <field name="year" invisible="1"/>
- <field name="day" invisible="1"/>
- <field name="month" invisible="1"/>
- <field name="user_id" />
- <field name="box_name"/>
- <field name="price_total"/>
- </tree>
- </field>
- </record>
-
- <record id="view_report_lunch_order_search" model="ir.ui.view">
- <field name="name">report.lunch.order.search</field>
- <field name="model">report.lunch.order</field>
- <field name="arch" type="xml">
- <search string="Lunch Order Analysis">
- <field name="date"/>
- <group expand="0" string="Group By...">
- <filter string="User" name="User" icon="terp-personal" context="{'group_by':'user_id'}"/>
- <filter string="Box" icon="terp-dolar" context="{'group_by':'box_name'}"/>
- <filter string="Day" icon="terp-go-today" context="{'group_by':'day'}"/>
- <filter string="Month" icon="terp-go-month" context="{'group_by':'month'}"/>
- <filter string="Year" icon="terp-go-year" context="{'group_by':'year'}"/>
- </group>
- </search>
- </field>
- </record>
-
- <record id="action_report_lunch_order_all" model="ir.actions.act_window">
- <field name="name">Lunch Order Analysis</field>
- <field name="res_model">report.lunch.order</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree</field>
- <field name="search_view_id" ref="view_report_lunch_order_search"/>
- <field name="context">{'search_default_month':1,'search_default_User':1}</field>
- </record>
-
-<!-- <menuitem name="Lunch Order Analysis" parent="menu_lunch_reporting_order"-->
-<!-- id="menu_lunch_order_analysis" action="action_report_lunch_order_all" sequence="1" />-->
</data>
</openerp>
-id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink\r
-access_lunch_order_user,lunch.order user,model_lunch_order,base.group_tool_user,1,1,1,1\r
-access_lunch_cashmove_user,lunch.cashmove user,model_lunch_cashmove,base.group_tool_user,1,1,1,1\r
-access_report_lunch_amount_manager,report.lunch.amount manager,model_report_lunch_amount,base.group_tool_manager,1,1,1,1\r
-access_lunch_category_manager,lunch.category.user,model_lunch_category,base.group_tool_user,1,1,1,1\r
-access_report_lunch_order_manager,report.lunch.order manager,model_report_lunch_order,base.group_tool_manager,1,1,1,1\r
-access_lunch_product_user,lunch.product user,model_lunch_product,base.group_tool_user,1,1,1,1\r
-access_lunch_cashbox_user,lunch.cashbox user,model_lunch_cashbox,base.group_tool_user,1,1,1,1\r
+id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
+order_user,"Order user",model_lunch_order,group_lunch_manager,1,1,1,1
+order_line_user,"Order Line user",model_lunch_order_line,group_lunch_manager,1,1,1,1
+cashmove_user,"Cashmove user",model_lunch_cashmove,group_lunch_manager,1,1,1,1
+product_user,"Product user",model_lunch_product,group_lunch_manager,1,1,1,1
+product_category_user,"Product category user",model_lunch_product_category,group_lunch_manager,1,1,1,1
+alert_user,"Alert user",model_lunch_alert,group_lunch_manager,1,1,1,1
+order_user,"Order user",model_lunch_order,group_lunch_user,1,1,1,0
+order_line_user,"Order Line user",model_lunch_order_line,group_lunch_user,1,1,1,1
+cashmove_user,"Cashmove user",model_lunch_cashmove,group_lunch_user,1,0,0,0
+product_user,"Product user",model_lunch_product,group_lunch_user,1,0,0,0
+product_category_user,"Product category user",model_lunch_product_category,group_lunch_user,1,0,0,0
+alert_user,"Alert user",model_lunch_alert,group_lunch_user,1,0,0,0
\ No newline at end of file
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" ?>
<openerp>
-<data noupdate="0">
-
- <record model="res.groups" id="base.group_tool_user">
- <field name="name">User</field>
- <field name="category_id" ref="base.module_category_tools"/>
- </record>
- <record model="res.groups" id="base.group_tool_manager">
- <field name="name">Manager</field>
- <field name="category_id" ref="base.module_category_tools"/>
- <field name="implied_ids" eval="[(4, ref('base.group_tool_user'))]"/>
- <field name="users" eval="[(4, ref('base.user_root'))]"/>
- </record>
-
-</data>
+ <data>
+ <record id="group_lunch_manager" model="res.groups">
+ <field name="name">Lunch / Manager</field>
+ </record>
+ <record id="group_lunch_user" model="res.groups">
+ <field name="name">Lunch / User</field>
+ </record>
+ </data>
</openerp>
--- /dev/null
+lunch.css: lunch.sass
+ sass -t expanded lunch.sass lunch.css
+
--- /dev/null
+@charset "utf-8";
+.openerp .oe_lunch .oe_lunch_alert textarea {
+ background-color: #ffc7c7;
+ padding: 10px;
+ height: 1em;
+ margin-bottom: 20px;
+}
+.openerp .oe_lunch button.oe_button_add {
+ position: relative;
+ top: -2px;
+ left: 3px;
+}
+.openerp .oe_lunch button.oe_button_plus {
+ margin: -2px;
+}
+.openerp .oe_lunch .oe_lunch_30pc {
+ width: 30%;
+ display: inline-block;
+ vertical-align: top;
+}
+.openerp .oe_lunch .oe_lunch_30pc:nth-child(3) {
+ padding-right: 0;
+}
+.openerp .oe_lunch .oe_lunch_30pc {
+ padding-right: 5%;
+}
+.openerp .oe_lunch h2 {
+ color: #7c7bad;
+}
+.openerp .oe_lunch .oe_lunch_button {
+ float: right;
+}
+.openerp .oe_lunch .oe_lunch_vignette {
+ border-bottom: 1px solid #dddddd;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+.openerp .oe_lunch .oe_lunch_vignette:last-child {
+ border: none;
+}
+.openerp .oe_lunch .oe_group_text_button {
+ margin-bottom: 3px;
+}
--- /dev/null
+@charset "utf-8"
+
+.openerp
+ .oe_lunch
+ .oe_lunch_alert
+ textarea
+ background-color: #ffc7c7
+ padding: 10px
+ height: 1em
+ margin-bottom: 20px
+ button.oe_button_add
+ position: relative
+ top: -2px
+ left: 3px
+ button.oe_button_plus
+ margin: -2px
+ .oe_lunch_30pc
+ width: 30%
+ display: inline-block
+ vertical-align: top
+ .oe_lunch_30pc:nth-child(3)
+ padding-right: 0
+ .oe_lunch_30pc
+ padding-right: 5%
+ h2
+ color: #7C7BAD
+ .oe_lunch_button
+ float: right
+ .oe_lunch_vignette
+ border-bottom: 1px solid #dddddd
+ padding-top: 5px
+ padding-bottom: 5px
+ .oe_lunch_vignette:last-child
+ border: none
+ .oe_group_text_button
+ margin-bottom: 3px
+++ /dev/null
--
- In order to test the PDF reports defined on a Lunch, we will print a Lunch Order Report
--
- !python {model: lunch.order}: |
- import netsvc, tools, os
- (data, format) = netsvc.LocalService('report.lunch.order').create(cr, uid, [ref('lunch.lunch_order_0'),ref('lunch.lunch_order_1')], {}, {})
- if tools.config['test_report_directory']:
- file(os.path.join(tools.config['test_report_directory'], 'lunch-lunch_order_report.'+format), 'wb+').write(data)
+++ /dev/null
-- |
- In order to test the Lunch module in OpenERP,
- I will create one lunch order and then check the effect on cashboxes and cashmoves
-
-- |
- Given that I have a category of lunch products "Burger".
--
- !record {model: lunch.category, id: lunch_category_burger0}:
- name: Burger
-- |
- Given that I have a product "Club1" in this category with a price of "2.75".
-
--
- !record {model: lunch.product, id: lunch_product_club1}:
- category_id: lunch_category_burger0
- name: Club1
- price: 2.75
-- |
- Given that I have a cashbox "Employee Cashbox"
--
- !record {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
- manager: base.user_root
- name: Employee Cashbox
-- |
- I create a lunch order "LU001" for the "Club1" product
-- |
- When I select the product "club1", the price of 2.75 is automatically proposed
--
- !record {model: lunch.order, id: lunch_order_0}:
- date: !eval time.strftime('%Y-%m-%d')
- product: 'lunch_product_club1'
- price: 2.75
-
-- |
- I check that lunch order is on draft state after having created it.
--
- !assert {model: lunch.order, id: lunch_order_0}:
- - state == 'draft'
-- |
- I confirm the order "LU001" using the "Confirm Order" wizard.
--
- !record {model: lunch.order.confirm, id: lunch_order_confirm_0}:
- confirm_cashbox: 'lunch_cashbox_cashbox0'
--
- I click on "Confirm Order" button of this wizard.
--
- !python {model: lunch.order.confirm}: |
- self.confirm(cr, uid, [ref('lunch_order_confirm_0')], {'active_ids': [ref('lunch_order_0')]})
-
-- |
- I check that the Cash Moves have been generated with the right box
- name
--
- !assert {model: lunch.order, id: lunch_order_0}:
- - cashmove.id != False
-
-- |
- I check that the Total on the "Employee Cashbox" is -2.75
-
--
- !assert {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
- - sum_remain == -2.75
-
-- |
- I create a new lunch order "LU002" for the "Club1" product, at another date.
--
- !record {model: lunch.order, id: lunch_order_1}:
- date: !eval "(datetime.now() + timedelta(2)).strftime('%Y-%m-%d')"
- product: 'lunch_product_club1'
- price: 2.75
-
-- |
- I confirm this order.open wizard and select "Employee Cashbox".
--
- !record {model: lunch.order.confirm, id: lunch_order_confirm_1}:
- confirm_cashbox: 'lunch_cashbox_cashbox0'
-- |
- Now I click on "Confirm Order" button of this wizard.
--
- !python {model: lunch.order.confirm}: |
- self.confirm(cr, uid, [ref('lunch_order_confirm_1')], {'active_ids': [ref('lunch_order_1')]})
-
-- |
- I check that the Total on the "Employee Cashbox" is -5.50
--
- !assert {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
- - sum_remain == -5.50
-
-- |
- I cancel the order "LU002"
--
- !record {model: lunch.order.cancel, id: lunch_order_cancel_0}:
- {}
-- |
- I click on "Yes" button of this wizard for cancel order.
-
--
- !python {model: lunch.order.cancel}: |
- self.cancel(cr, uid, [ref('lunch_order_cancel_0')], {'active_ids': [ref('lunch_order_1')]})
-
-- |
- I test that the Cash Moves record have been removed for the order LU002.
--
- !assert {model: lunch.order, id: lunch_order_1}:
- - cashmove.id == False
-
-- |
- I check that the Total on the "Employee Cashbox" is -2.75
--
- !assert {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
- - sum_remain == -2.75
-- |
- I reset the "Employee Cashbox" to zero using the "Set CashBox to Zero" wizard.
--
- !record {model: lunch.cashbox.clean, id: lunch_cashbox_clean_0}:
- {}
--
- Now click on "Set to Zero" button of this wizard.
--
- !python {model: lunch.cashbox.clean, id: lunch_cashbox_clean_0}: |
- self.set_to_zero(cr, uid, [ref('lunch_cashbox_clean_0')], {'active_ids': [ref('lunch_cashbox_cashbox0')]})
-
-- |
- I check that the Total on the "Employee Cashbox" is -5.50
--
- !assert {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
- - sum_remain == 0.00
-
--- /dev/null
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# 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.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from . import test_lunch
+
+checks = [
+ test_lunch,
+]
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
--- /dev/null
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# 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.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import tools
+from openerp.tests import common
+
+class Test_Lunch(common.TransactionCase):
+
+ def setUp(self):
+ """*****setUp*****"""
+ super(Test_Lunch, self).setUp()
+ cr, uid = self.cr, self.uid
+
+ self.res_users = self.registry('res.users')
+ self.lunch_order = self.registry('lunch.order')
+ self.lunch_order_line = self.registry('lunch.order.line')
+ self.lunch_cashmove = self.registry('lunch.cashmove')
+ self.lunch_product = self.registry('lunch.product')
+ self.lunch_alert = self.registry('lunch.alert')
+ self.lunch_product_category = self.registry('lunch.product.category')
+
+ self.demo_id = self.res_users.search(cr, uid, [('name', '=', 'Demo User')])
+ self.product_bolognese_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'lunch', 'product_Bolognese')
+ self.product_Bolognese_id = self.product_bolognese_ref and self.product_bolognese_ref[1] or False
+ self.new_id_order = self.lunch_order.create(cr,uid,{
+ 'user_id': self.demo_id[0],
+ 'order_line_ids':'[]',
+ },context=None)
+ self.new_id_order_line = self.lunch_order_line.create(cr,uid,{
+ 'order_id':self.new_id_order,
+ 'product_id':self.product_Bolognese_id,
+ 'note': '+Emmental',
+ 'cashmove': [],
+ 'price': self.lunch_product.browse(cr,uid,self.product_Bolognese_id,context=None).price,
+ })
+
+ def test_00_lunch_order(self):
+ """Change the state of an order line from 'new' to 'ordered'. Check that there are no cashmove linked to that order line"""
+ cr, uid = self.cr, self.uid
+ self.order_one = self.lunch_order_line.browse(cr,uid,self.new_id_order_line,context=None)
+ #we check that our order_line is a 'new' one and that there are no cashmove linked to that order_line:
+ self.assertEqual(self.order_one.state,'new')
+ self.assertEqual(self.order_one.cashmove, [])
+ #we order that orderline so it's state will be 'ordered'
+ self.order_one.order()
+ self.order_one = self.lunch_order_line.browse(cr,uid,self.new_id_order_line,context=None)
+ #we check that our order_line is a 'ordered' one and that there are no cashmove linked to that order_line:
+ self.assertEqual(self.order_one.state,'ordered')
+ self.assertEqual(self.order_one.cashmove, [])
+
+ def test_01_lunch_order(self):
+ """Change the state of an order line from 'new' to 'ordered' then to 'confirmed'. Check that there is a cashmove linked to the order line"""
+ cr, uid = self.cr, self.uid
+ self.test_00_lunch_order()
+ #We receive the order so we confirm the order line so it's state will be 'confirmed'
+ #A cashmove will be created and we will test that the cashmove amount equals the order line price
+ self.order_one.confirm()
+ self.order_one = self.lunch_order_line.browse(cr,uid,self.new_id_order_line,context=None)
+ #we check that our order_line is a 'confirmed' one and that there are a cashmove linked to that order_line with an amount equals to the order line price:
+ self.assertEqual(self.order_one.state,'confirmed')
+ self.assertTrue(self.order_one.cashmove!=[])
+ self.assertTrue(self.order_one.cashmove[0].amount==-self.order_one.price)
+
+ def test_02_lunch_order(self):
+ """Change the state of an order line from 'confirmed' to 'cancelled' and check that the cashmove linked to that order line will be deleted"""
+ cr, uid = self.cr, self.uid
+ self.test_01_lunch_order()
+ #We have a confirmed order with its associate cashmove
+ #We execute the cancel function
+ self.order_one.cancel()
+ self.order_one = self.lunch_order_line.browse(cr,uid,self.new_id_order_line,context=None)
+ #We check that the state is cancelled and that the cashmove has been deleted
+ self.assertEqual(self.order_one.state,'cancelled')
+ self.assertTrue(self.order_one.cashmove==[])
\ No newline at end of file
# -*- encoding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
+# Copyright (C) 2004-2012 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
-import lunch_order_confirm
-import lunch_order_cancel
-import lunch_cashbox_clean
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+import lunch_validation
+import lunch_cancel
+import lunch_order
--- /dev/null
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2012 Tiny SPRL (<http://tiny.be>).
+#
+# This program is free software: you can redistribute it and/or modify
+# 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.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from osv import osv, fields
+
+class lunch_cancel(osv.Model):
+ """ lunch cancel """
+ _name = 'lunch.cancel'
+ _description = 'cancel lunch order'
+
+ def cancel(self,cr,uid,ids,context=None):
+ return self.pool.get('lunch.order.line').cancel(cr, uid, ids, context=context)
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <record model="ir.ui.view" id="cancel_order_lines_view">
+ <field name="name">cancel order lines</field>
+ <field name="model">lunch.cancel</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="cancel order lines" version="7.0">
+ <separator string="Are you sure you want to cancel these meals?"/>
+ <p class="oe_grey">
+ Cancel a meal means that we didn't receive it from the supplier.
+ <br/>
+ A cancelled meal should not be paid by employees.
+ </p>
+ <footer>
+ <button name="cancel" string="Cancel Orders" type="object" class="oe_highlight"/>
+ or
+ <button string="Cancel" class="oe_link" special="cancel" />
+ </footer>
+ </form>
+ </field>
+ </record>
+
+ <act_window id="cancel_order_lines"
+ multi="True"
+ key2="client_action_multi" name="Cancel meals"
+ res_model="lunch.cancel" src_model="lunch.order.line"
+ view_mode="form" target="new" view_type="form" view_id="cancel_order_lines_view"/>
+
+ </data>
+</openerp>
\ No newline at end of file
+++ /dev/null
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
-#
-# This program is free software: you can redistribute it and/or modify
-# 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.
-#
-# 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
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-from osv import fields, osv
-
-class lunch_cashbox_clean(osv.osv_memory):
-
- _name = "lunch.cashbox.clean"
- _description = "clean cashbox"
-
- def set_to_zero(self, cr, uid, ids, context=None):
-
- """
- clean Cashbox. set active fields False.
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List Lunch cashbox Clean’s IDs
- @return:Dictionary {}.
- """
- #TOFIX: use orm methods
- if context is None:
- context = {}
- data = context and context.get('active_ids', []) or []
- cashmove_ref = self.pool.get('lunch.cashmove')
- cr.execute("select user_cashmove, box,sum(amount) from lunch_cashmove \
- where active = 't' and box IN %s group by user_cashmove, \
- box" , (tuple(data),))
- res = cr.fetchall()
-
- cr.execute("update lunch_cashmove set active = 'f' where active= 't' \
- and box IN %s" , (tuple(data),))
- #TOCHECK: Why need to create duplicate entry after clean box ?
-
- #for (user_id, box_id, amount) in res:
- # cashmove_ref.create(cr, uid, {
- # 'name': 'Summary for user' + str(user_id),
- # 'amount': amount,
- # 'user_cashmove': user_id,
- # 'box': box_id,
- # 'active': True,
- # })
- return {'type': 'ir.actions.act_window_close'}
-
-lunch_cashbox_clean()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
- <data>
-
-<!-- Lunch cashbox -->
-
- <record id="view_lunch_cashbox_clean" model="ir.ui.view">
- <field name="name">lunch.cashbox.clean.form</field>
- <field name="model">lunch.cashbox.clean</field>
- <field name="arch" type="xml">
- <form string="Reset cashbox" version="7.0">
- <group>
- <label string="Are you sure you want to reset this cashbox ?"/>
- </group>
- <footer>
- <button name="set_to_zero" string="Set to Zero" type="object" class="oe_highlight" />
- or
- <button string="Cancel" class="oe_link" special="cancel" />
- </footer>
- </form>
- </field>
- </record>
-
- <record id="action_lunch_cashbox_clean" model="ir.actions.act_window">
- <field name="name">Set CashBox to Zero</field>
- <field name="res_model">lunch.cashbox.clean</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <field name="view_id" ref="view_lunch_cashbox_clean"/>
- <field name="target">new</field>
- </record>
-
- <act_window id="action_lunch_cashbox_clean_values"
- key2="client_action_multi" name="Set CashBox to Zero"
- res_model="lunch.cashbox.clean" src_model="lunch.cashbox"
- view_mode="form" target="new" view_type="form" />
-
- </data>
-</openerp>
--- /dev/null
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2012 Tiny SPRL (<http://tiny.be>).
+#
+# This program is free software: you can redistribute it and/or modify
+# 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.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from osv import osv, fields
+
+class lunch_order_order(osv.Model):
+ """ lunch order meal """
+ _name = 'lunch.order.order'
+ _description = 'Wizard to order a meal'
+
+ def order(self,cr,uid,ids,context=None):
+ return self.pool.get('lunch.order.line').order(cr, uid, ids, context=context)
+++ /dev/null
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
-#
-# This program is free software: you can redistribute it and/or modify
-# 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.
-#
-# 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
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-from osv import fields, osv
-
-class lunch_order_cancel(osv.osv_memory):
- """
- Cancel Lunch Order
- """
- _name = "lunch.order.cancel"
- _description = "Cancel Order"
-
- def cancel(self, cr, uid, ids, context=None):
- """
- Cancel cashmove entry from cashmoves and update state to draft.
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List Lunch Order Cancel’s IDs
- """
- if context is None:
- context = {}
- data = context and context.get('active_ids', []) or []
- return self.pool.get('lunch.order').lunch_order_cancel(cr, uid, data, context)
-
-lunch_order_cancel()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
- <data>
-
-<!-- cancel order -->
-
- <record id="view_lunch_order_cancel" model="ir.ui.view">
- <field name="name">lunch.order.cancel.form</field>
- <field name="model">lunch.order.cancel</field>
- <field name="arch" type="xml">
- <form string="Cancel Order" version="7.0">
- <group col="4" >
- <label string="Are you sure you want to cancel this order ?"/>
- </group>
- <footer>
- <button name="cancel" string="Yes" type="object" class="oe_highlight" />
- or
- <button string="Cancel" class="oe_link" special="cancel" />
- </footer>
- </form>
- </field>
- </record>
-
- <record id="action_lunch_order_cancel" model="ir.actions.act_window">
- <field name="name">Cancel Order</field>
- <field name="res_model">lunch.order.cancel</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <field name="view_id" ref="view_lunch_order_cancel"/>
- <field name="target">new</field>
- </record>
-
- <act_window id="action_lunch_order_cancel_values"
- key2="client_action_multi" name="Cancel Order"
- res_model="lunch.order.cancel" src_model="lunch.order"
- view_mode="form" target="new" view_type="form" multi="True"/>
-
- </data>
-</openerp>
+++ /dev/null
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
-#
-# This program is free software: you can redistribute it and/or modify
-# 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.
-#
-# 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
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-from osv import fields, osv
-
-class lunch_order_confirm(osv.osv_memory):
- """
- Confirm Lunch Order
- """
- _name = "lunch.order.confirm"
- _description = "confirm Order"
-
- _columns = {
- 'confirm_cashbox':fields.many2one('lunch.cashbox', 'Name of box', required=True),
- }
-
- def confirm(self, cr, uid, ids, context=None):
- """
- confirm Lunch Order.Create cashmoves in launch cashmoves when state is
- confirm in lunch order.
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List Lunch Order confirm’s IDs
- @return: Dictionary {}.
- """
- if context is None:
- context = {}
- data = context and context.get('active_ids', []) or []
- order_ref = self.pool.get('lunch.order')
-
- for confirm_obj in self.browse(cr, uid, ids, context=context):
- order_ref.confirm(cr, uid, data, confirm_obj.confirm_cashbox.id, context)
- return {'type': 'ir.actions.act_window_close'}
-
-lunch_order_confirm()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
- <data>
-
-<!-- confirm order -->
-
- <record id="view_lunch_order_confirm" model="ir.ui.view">
- <field name="name">lunch.order.confirm.form</field>
- <field name="model">lunch.order.confirm</field>
- <field name="arch" type="xml">
- <form string="Confirm" version="7.0">
- <group col="4">
- <separator string="Orders Confirmation" colspan="4"/>
- <field name="confirm_cashbox"/>
- </group>
- <footer>
- <button name="confirm" string="Confirm Order" type="object" class="oe_highlight" />
- or
- <button string="Cancel" class="oe_link" special="cancel" />
- </footer>
- </form>
- </field>
- </record>
-
- <record id="action_lunch_order_confirm" model="ir.actions.act_window">
- <field name="name">Confirm Order</field>
- <field name="res_model">lunch.order.confirm</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <field name="view_id" ref="view_lunch_order_confirm"/>
- <field name="target">new</field>
- </record>
-
- <act_window id="action_lunch_order_confirm_values"
- key2="client_action_multi" name="Confirm Order"
- res_model="lunch.order.confirm" src_model="lunch.order"
- view_mode="form" target="new" view_type="form" multi="True"/>
-
- </data>
-</openerp>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <record model="ir.ui.view" id="order_order_lines_view">
+ <field name="name">Order meal</field>
+ <field name="model">lunch.order.order</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Order meal" version="7.0">
+ <separator string="Are you sure you want to order these meals?"/>
+ <p class="oe_grey">
+ Order a meal doesn't mean that we have to pay it.
+ A meal should be paid when it is received.
+ </p>
+ <footer>
+ <button name="order" string="Order Meals" type="object" class="oe_highlight"/>
+ or
+ <button name="cancel" string="Cancel" class="oe_link" special="cancel" />
+ </footer>
+ </form>
+ </field>
+ </record>
+
+ <act_window id="order_order_lines"
+ multi="True"
+ key2="client_action_multi" name="Order meals"
+ res_model="lunch.order.order" src_model="lunch.order.line"
+ view_mode="form" target="new" view_type="form" view_id="order_order_lines_view"/>
+
+ </data>
+</openerp>
--- /dev/null
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2012 Tiny SPRL (<http://tiny.be>).
+#
+# This program is free software: you can redistribute it and/or modify
+# 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.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from osv import osv, fields
+
+class lunch_validation(osv.Model):
+ """ lunch validation """
+ _name = 'lunch.validation'
+ _description = 'lunch validation for order'
+
+ def confirm(self,cr,uid,ids,context=None):
+ return self.pool.get('lunch.order.line').confirm(cr, uid, ids, context=context)
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <record model="ir.ui.view" id="validate_order_lines_view">
+ <field name="name">validate order lines</field>
+ <field name="model">lunch.validation</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="validate order lines" version="7.0">
+ <separator string="Did your received these meals?"/>
+ <p class="oe_grey">
+ Once a meal is received a new cash move is created for the employee.
+ </p>
+ <footer>
+ <button name="confirm" string="Receive Meals" type="object" class="oe_highlight"/>
+ or
+ <button name="cancel" string="Cancel" class="oe_link" special="cancel" />
+ </footer>
+ </form>
+ </field>
+ </record>
+
+ <act_window id="validate_order_lines"
+ multi="True"
+ key2="client_action_multi" name="Receive meals"
+ res_model="lunch.validation" src_model="lunch.order.line"
+ view_mode="form" target="new" view_type="form" view_id="validate_order_lines_view"/>
+
+ </data>
+</openerp>