[MERGE] staging branch with new version of lunch module, made by api

bzr revid: qdp-launchpad@openerp.com-20121107111043-hoxenf5bsl0dmxfl
This commit is contained in:
Quentin (OpenERP) 2012-11-07 12:10:43 +01:00
commit f22e2397d6
34 changed files with 1487 additions and 1159 deletions

View File

@ -168,10 +168,8 @@
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"/>

View File

@ -2,7 +2,7 @@
##############################################################################
#
# 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
@ -20,7 +20,5 @@
##############################################################################
import lunch
import wizard
import report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
import wizard

View File

@ -2,7 +2,7 @@
##############################################################################
#
# 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
@ -22,31 +22,31 @@
{
'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.
""",
'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',
'report/report_lunch_order_view.xml',
'lunch_installer_view.xml'
],
'demo': ['lunch_demo.xml'],
'test': ['test/test_lunch.yml', 'test/lunch_report.yml'],
'installable': True,
'images': ['images/cash_moves.jpeg','images/lunch_orders.jpeg','images/products.jpeg'],
}
Many companies order sandwiches, pizzas and other, from usual suppliers, for their employees to offer them more facilities.
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
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 employees 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','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',
'security/ir.model.access.csv',],
'css':['static/src/css/lunch.css'],
'demo': ['lunch_demo.xml',],
'installable': True,
'application' : True,
'certificate' : '001292377792581874189',
'images': [],
}

View File

@ -19,234 +19,451 @@
#
##############################################################################
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_category(osv.osv):
""" Lunch category """
_name = 'lunch.category'
_description = "Category"
_columns = {
'name': fields.char('Name', required=True, size=50),
}
_order = 'name'
lunch_category()
class lunch_product(osv.osv):
""" Lunch Product """
_name = 'lunch.product'
_description = "Lunch Product"
_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'),
}
_defaults = {
'active': lambda *a : True,
}
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 users ID for security checks,
@param ids: List of create menus 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
_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'),
}
lunch_cashbox()
class lunch_cashmove(osv.osv):
""" Move cash """
_name = 'lunch.cashmove'
_description = "Cash Move"
_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,
}
lunch_cashmove()
class lunch_order(osv.osv):
""" Apply lunch order """
class lunch_order(osv.Model):
"""
lunch order (contains one or more lunch order line(s))
"""
_name = 'lunch.order'
_description = "Lunch Order"
_rec_name = "user_id"
_description = 'Lunch Order'
def _price_get(self, cr, uid, ids, name, args, context=None):
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
""" Get Price of Product
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Lunch orders IDs
@param context: A standard dictionary for contextual values """
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)
res = {}
for price in self.browse(cr, uid, ids, context=context):
res[price.id] = price.product.price
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
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 = {
'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, 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'),
}
_defaults = {
'user_id': lambda self, cr, uid, context: uid,
'date': fields.date.context_today,
'state': lambda self, cr, uid, context: 'draft',
'state': 'new',
'alerts': _default_alerts_get,
}
def confirm(self, cr, uid, ids, box, context=None):
""" confirm order
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of confirm orders IDs
@param context: A standard dictionary for contextual values """
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 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'})
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 {}
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 users ID for security checks,
@param ids: List of create menus 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 users ID for security checks,
@param ids: List of create menus 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"
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 = {
'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),
'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 = {
'state': 'new',
}
def init(self, cr):
""" @param cr: the current row, from the database cursor"""
class lunch_product(osv.Model):
"""
lunch product
"""
_name = 'lunch.product'
_description = 'lunch product'
_columns = {
'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'),
}
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
)""")
class lunch_product_category(osv.Model):
"""
lunch product category
"""
_name = 'lunch.product.category'
_description = 'lunch product category'
_columns = {
'name': fields.char('Category', required=True), #such as PIZZA, SANDWICH, PASTA, CHINESE, BURGER, ...
}
report_lunch_amount()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
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),
'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': 'payment',
}
class lunch_alert(osv.Model):
"""
lunch alert
"""
_name = 'lunch.alert'
_description = 'Lunch Alert'
_columns = {
'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,
}

View File

@ -2,23 +2,180 @@
<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>

View File

@ -1,52 +0,0 @@
<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>

View File

@ -4,8 +4,8 @@
<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"
/>

View File

@ -1,393 +1,486 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- Top menu item -->
<menuitem name="Tools" id="base.menu_tools" sequence="160"/>
<!--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">
<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>
</search>
</field>
</record>
<menuitem name="Lunch Order" parent="base.menu_tools"
id="menu_lunch" sequence="1" />
<!--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"/>
<filter name='is_payment' string="Payment" domain="[('state','=','payment')]"/>
<separator/>
<filter name='is_mine' string="My Account" domain="[('user_id','=',uid)]"/>
</search>
</field>
</record>
<menuitem name="Reporting" parent="base.menu_tools"
id="base.menu_lunch_reporting" sequence="6" groups="base.group_tool_manager"/>
<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 name='group_by_user' string="By Employee" context="{'group_by':'user_id'}"/>
</group>
</search>
</field>
</record>
<menuitem name="Lunch"
parent="base.menu_reporting"
id="menu_lunch_reporting_order" sequence="55" />
<!--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="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" />
<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">
<search string="Search">
<field name="message"/>
</search>
</field>
</record>
<!-- Lunch order Form 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_order_form">
<field name="name">Order</field>
<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"/>
<!--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="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>
<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" />
<!--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" />
<!--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" />
<!--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" />
<!--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="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="Products Form" version="7.0">
<sheet>
<group>
<field name='name' string="Product Category: "/>
</group>
</sheet>
</form>
</field>
</record>
<menuitem name="Product Categories" parent="menu_lunch_config" id="menu_lunch_product_categories" action="action_lunch_product_categories" />
<!--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 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>
<!--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>
<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="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>
<form string='Orders Form' version='7.0' class="oe_lunch">
<header>
<field name='state' widget='statusbar' statusbar_visible='new,confirmed'/>
</header>
<sheet>
<group>
<field name="product" on_change="onchange_product(product)"/>
<field name="descript"/>
<field name="price"/>
<field name="category"/>
<group>
<field name='user_id'/>
</group>
<group>
<field name='date'/>
</group>
</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>
<!--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">
<field name="name"/>
<field name="category_id"/>
<field name="supplier"/>
<field name="description"/>
<field name="price"/>
</tree>
</field>
</record>
<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">
<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>
<!--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="cashmove tree">
<field name="date"/>
<field name="user_id"/>
<field name="description"/>
<field name="amount" sum="Total"/>
</tree>
</field>
</record>
<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="cashmove form" version="7.0">
<sheet>
<group>
<field name="user_id"/>
<field name="cashmove"/>
<field name="date"/>
<field name="amount"/>
</group>
</group>
<label for='description'/>
<field name="description"/>
</sheet>
</form>
</field>
</record>
<!--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">
<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>
<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>
</sheet>
</form>
</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"/>
<field name="user_id"/>
<field name="product"/>
<field name="descript"/>
<field name="category"/>
<field name="price" sum="Total price"/>
<field name="state"/>
</tree>
</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'))]"/>
<field name="user_id"/>
<group expand="0" string="Group By...">
<filter string="Category" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'category'}"/>
</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>
</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>
<field name="arch" type="xml">
<form string="Cashboxes" version="7.0">
<group colspan="4">
<field name="name"/>
<field name="manager"/>
</group>
</form>
</field>
</record>
<!-- Cash Box Tree view -->
<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&lt;=0">
<field name="name"/>
<field name="manager"/>
<field name="sum_remain"/>
</tree>
</field>
</record>
<!-- 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>
</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>
</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>
</field>
</record>
<!-- 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>
</field>
</record>
<!-- 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>
</record>
<menuitem name="Cash Moves" parent="menu_lunch"
id="menu_lunch_cashmove_form"
action="action_lunch_cashmove_form" />
<!-- Lunch Category Form view -->
<record model="ir.ui.view" id="view_lunch_category_form">
<field name="name"> Category of product </field>
<field name="model">lunch.category</field>
<field name="arch" type="xml">
<form string="Category" version="7.0">
<group>
<field name="name"/>
</group>
</form>
</field>
</record>
<!-- Lunch Category Tree view -->
<record model="ir.ui.view" id="view_lunch_category_tree">
<field name="name">Category</field>
<field name="model">lunch.category</field>
<field name="arch" type="xml">
<tree string="Order">
<field name="name"/>
</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>
</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>
<field name="arch" type="xml">
<form string="Products" version="7.0">
<sheet>
<group>
<group>
<field name="name"/>
<field name="category_id"/>
<field name="price" />
</group>
<group>
<field name="active"/>
</group>
<field name="description" placeholder="Add a description" nolabel="1" colspan="4"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- Lunch Product Tree view -->
<record model="ir.ui.view" id="view_lunch_product_tree">
<field name="name">Products</field>
<field name="model">lunch.product</field>
<field name="arch" type="xml">
<tree string="Products">
<field name="name"/>
<field name="category_id"/>
<field name="price"/>
<field name="description"/>
</tree>
</field>
</record>
<!-- Lunch Product Search view -->
<record model="ir.ui.view" id="view_lunch_product_search">
<field name="name">Products</field>
<field name="model">lunch.product</field>
<field name="arch" type="xml">
<search string="Products">
<field name="name" string="Product"/>
<field name="price"/>
<field name="category_id"/>
</search>
</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>
<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"/>
<field name="user_id"/>
<field name="amount" sum="Total box" />
</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>
<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>
</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>
<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>
</field>
</record>
<!-- Lunch Amount Action -->
<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"/>
</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>

View File

@ -26,14 +26,14 @@ from osv import osv
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:
@ -54,6 +54,12 @@ class order(report_sxw.rml_parse):
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
@ -63,9 +69,10 @@ class order(report_sxw.rml_parse):
'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:

View File

@ -137,7 +137,7 @@
</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>
@ -149,13 +149,13 @@
<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>
@ -172,7 +172,7 @@
<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>

View File

@ -23,7 +23,7 @@ import tools
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'
@ -35,32 +35,29 @@ class report_lunch_order(osv.osv):
('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()

View File

@ -2,50 +2,6 @@
<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>

View File

@ -1,8 +1,13 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_lunch_order_user,lunch.order user,model_lunch_order,base.group_tool_user,1,1,1,1
access_lunch_cashmove_user,lunch.cashmove user,model_lunch_cashmove,base.group_tool_user,1,1,1,1
access_report_lunch_amount_manager,report.lunch.amount manager,model_report_lunch_amount,base.group_tool_manager,1,1,1,1
access_lunch_category_manager,lunch.category.user,model_lunch_category,base.group_tool_user,1,1,1,1
access_report_lunch_order_manager,report.lunch.order manager,model_report_lunch_order,base.group_tool_manager,1,1,1,1
access_lunch_product_user,lunch.product user,model_lunch_product,base.group_tool_user,1,1,1,1
access_lunch_cashbox_user,lunch.cashbox user,model_lunch_cashbox,base.group_tool_user,1,1,1,1
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
1 id name model_id:id model_id/id group_id:id group_id/id perm_read perm_write perm_create perm_unlink
2 access_lunch_order_user order_user lunch.order user Order user model_lunch_order model_lunch_order base.group_tool_user group_lunch_manager 1 1 1 1
3 access_lunch_cashmove_user order_line_user lunch.cashmove user Order Line user model_lunch_cashmove model_lunch_order_line base.group_tool_user group_lunch_manager 1 1 1 1
4 access_report_lunch_amount_manager cashmove_user report.lunch.amount manager Cashmove user model_report_lunch_amount model_lunch_cashmove base.group_tool_manager group_lunch_manager 1 1 1 1
5 access_lunch_category_manager product_user lunch.category.user Product user model_lunch_category model_lunch_product base.group_tool_user group_lunch_manager 1 1 1 1
6 access_report_lunch_order_manager product_category_user report.lunch.order manager Product category user model_report_lunch_order model_lunch_product_category base.group_tool_manager group_lunch_manager 1 1 1 1
7 access_lunch_product_user alert_user lunch.product user Alert user model_lunch_product model_lunch_alert base.group_tool_user group_lunch_manager 1 1 1 1
8 access_lunch_cashbox_user order_user lunch.cashbox user Order user model_lunch_cashbox model_lunch_order base.group_tool_user group_lunch_user 1 1 1 1 0
9 order_line_user Order Line user model_lunch_order_line group_lunch_user 1 1 1 1
10 cashmove_user Cashmove user model_lunch_cashmove group_lunch_user 1 0 0 0
11 product_user Product user model_lunch_product group_lunch_user 1 0 0 0
12 product_category_user Product category user model_lunch_product_category group_lunch_user 1 0 0 0
13 alert_user Alert user model_lunch_alert group_lunch_user 1 0 0 0

View File

@ -1,17 +1,11 @@
<?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>

View File

@ -0,0 +1,3 @@
lunch.css: lunch.sass
sass -t expanded lunch.sass lunch.css

View File

@ -0,0 +1,43 @@
@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;
}

View File

@ -0,0 +1,36 @@
@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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

@ -1,8 +0,0 @@
-
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)

View File

@ -1,128 +0,0 @@
- |
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

View File

@ -0,0 +1,27 @@
# -*- 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:

View File

@ -0,0 +1,92 @@
# -*- 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==[])

View File

@ -1,8 +1,8 @@
# -*- 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
@ -15,13 +15,10 @@
# 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

View File

@ -2,7 +2,7 @@
##############################################################################
#
# 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
@ -18,28 +18,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from osv import osv, fields
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 users ID for security checks,
@param ids: List Lunch Order Cancels 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:
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)

View File

@ -0,0 +1,32 @@
<?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>

View File

@ -1,65 +0,0 @@
# -*- 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 users ID for security checks,
@param ids: List Lunch cashbox Cleans 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:

View File

@ -1,39 +0,0 @@
<?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>

View File

@ -0,0 +1,29 @@
# -*- 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)

View File

@ -1,39 +0,0 @@
<?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>

View File

@ -1,56 +0,0 @@
# -*- 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 users ID for security checks,
@param ids: List Lunch Order confirms 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:

View File

@ -1,40 +0,0 @@
<?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>

View File

@ -0,0 +1,31 @@
<?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>

View File

@ -0,0 +1,29 @@
# -*- 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)

View File

@ -0,0 +1,30 @@
<?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>