[MERGE] staging branch with new version of lunch module, made by api
authorQuentin (OpenERP) <qdp-launchpad@openerp.com>
Wed, 7 Nov 2012 11:10:43 +0000 (12:10 +0100)
committerQuentin (OpenERP) <qdp-launchpad@openerp.com>
Wed, 7 Nov 2012 11:10:43 +0000 (12:10 +0100)
bzr revid: qdp-launchpad@openerp.com-20121107111043-hoxenf5bsl0dmxfl

35 files changed:
addons/account/account_invoice_view.xml
addons/lunch/__init__.py
addons/lunch/__openerp__.py
addons/lunch/lunch.py
addons/lunch/lunch_demo.xml
addons/lunch/lunch_installer_view.xml [deleted file]
addons/lunch/lunch_report.xml
addons/lunch/lunch_view.xml
addons/lunch/report/order.py
addons/lunch/report/order.rml
addons/lunch/report/report_lunch_order.py
addons/lunch/report/report_lunch_order_view.xml
addons/lunch/security/ir.model.access.csv
addons/lunch/security/lunch_security.xml
addons/lunch/static/src/css/Makefile [new file with mode: 0644]
addons/lunch/static/src/css/lunch.css [new file with mode: 0644]
addons/lunch/static/src/css/lunch.sass [new file with mode: 0644]
addons/lunch/static/src/img/icon.png
addons/lunch/test/lunch_report.yml [deleted file]
addons/lunch/test/test_lunch.yml [deleted file]
addons/lunch/tests/__init__.py [new file with mode: 0644]
addons/lunch/tests/test_lunch.py [new file with mode: 0644]
addons/lunch/wizard/__init__.py
addons/lunch/wizard/lunch_cancel.py [new file with mode: 0644]
addons/lunch/wizard/lunch_cancel_view.xml [new file with mode: 0644]
addons/lunch/wizard/lunch_cashbox_clean.py [deleted file]
addons/lunch/wizard/lunch_cashbox_clean_view.xml [deleted file]
addons/lunch/wizard/lunch_order.py [new file with mode: 0644]
addons/lunch/wizard/lunch_order_cancel.py [deleted file]
addons/lunch/wizard/lunch_order_cancel_view.xml [deleted file]
addons/lunch/wizard/lunch_order_confirm.py [deleted file]
addons/lunch/wizard/lunch_order_confirm_view.xml [deleted file]
addons/lunch/wizard/lunch_order_view.xml [new file with mode: 0644]
addons/lunch/wizard/lunch_validation.py [new file with mode: 0644]
addons/lunch/wizard/lunch_validation_view.xml [new file with mode: 0644]

index 2f722d0..4feb97c 100644 (file)
                               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"/>
index b94760a..fb4acc9 100644 (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
index 0feb1af..a70f6d8 100644 (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
 {
     'name': 'Lunch Orders',
     'author': 'OpenERP SA',
-    'version': '0.1',
-    'depends': [],
+    'version': '0.2',
+    'depends': ['base'],
     'category' : 'Tools',
+    'summary': 'Lunch Order, Meal, Food',
     'description': """
 The base module to manage lunch.
 ================================
 
-keep track for the Lunch Order, Cash Moves, CashBox, Product. Apply Different
-Category for the product.
+Many companies order sandwiches, pizzas and other, from usual suppliers, for their employees to offer them more facilities. 
+
+However lunches management within the company requires proper administration especially when the number of employees or suppliers is important. 
+
+The “Lunch Order” module has been developed to make this management easier but also to offer employees more tools and usability. 
+
+In addition to a full meal and supplier management, this module offers the possibility to display warning and provides quick order selection based on employee’s preferences.
+
+If you want to save your employees' time and avoid them to always have coins in their pockets, this module is essential.
     """,
-    'data': [
-        'security/lunch_security.xml',
-        'security/ir.model.access.csv',
-        'wizard/lunch_order_cancel_view.xml',
-        'wizard/lunch_order_confirm_view.xml',
-        'wizard/lunch_cashbox_clean_view.xml',
-        'lunch_view.xml',
-        'lunch_report.xml',
+    'data': ['security/lunch_security.xml','lunch_view.xml','wizard/lunch_order_view.xml','wizard/lunch_validation_view.xml','wizard/lunch_cancel_view.xml','lunch_report.xml',
         'report/report_lunch_order_view.xml',
-        'lunch_installer_view.xml'
-    ],
-    'demo': ['lunch_demo.xml'],
-    'test': ['test/test_lunch.yml', 'test/lunch_report.yml'],
+        'security/ir.model.access.csv',],
+    'css':['static/src/css/lunch.css'],
+    'demo': ['lunch_demo.xml',],
     'installable': True,
-    'images': ['images/cash_moves.jpeg','images/lunch_orders.jpeg','images/products.jpeg'],
+    'application' : True,
+    'certificate' : '001292377792581874189',
+    'images': [],
 }
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
index c249478..0d224ef 100644 (file)
 #
 ##############################################################################
 
+from xml.sax.saxutils import escape
+import time
 from osv import osv, fields
+from datetime import datetime
+from lxml import etree
+import tools
+from tools.translate import _
+
+class lunch_order(osv.Model):
+    """ 
+    lunch order (contains one or more lunch order line(s))
+    """
+    _name = 'lunch.order'
+    _description = 'Lunch Order'
 
-class lunch_category(osv.osv):
-    """ Lunch category """
+    def _price_get(self, cr, uid, ids, name, arg, context=None):
+        """ 
+        get and sum the order lines' price
+        """
+        result = dict.fromkeys(ids, 0)
+        for order in self.browse(cr, uid, ids, context=context):
+            result[order.id] = sum(order_line.product_id.price
+                                   for order_line in order.order_line_ids)
+        return result
+
+    def _fetch_orders_from_lines(self, cr, uid, ids, name, context=None):
+        """ 
+        return the list of lunch orders to which belong the order lines `ids´
+        """
+        result = set()
+        for order_line in self.browse(cr, uid, ids, context=context):
+            if order_line.order_id:
+                result.add(order_line.order_id.id)
+        return list(result)
+
+    def add_preference(self, cr, uid, ids, pref_id, context=None):
+        """ 
+        create a new order line based on the preference selected (pref_id)
+        """
+        assert len(ids) == 1
+        orderline_ref = self.pool.get('lunch.order.line')
+        prod_ref = self.pool.get('lunch.product')
+        order = self.browse(cr, uid, ids[0], context=context)
+        pref = orderline_ref.browse(cr, uid, pref_id, context=context)
+        new_order_line = {
+            'date': order.date,
+            'user_id': uid,
+            'product_id': pref.product_id.id,
+            'note': pref.note,
+            'order_id': order.id,
+            'price': pref.product_id.price,
+            'supplier': pref.product_id.supplier.id
+        }
+        return orderline_ref.create(cr, uid, new_order_line, context=context)
+
+    def _alerts_get(self, cr, uid, ids, name, arg, context=None):
+        """ 
+        get the alerts to display on the order form 
+        """
+        result = {}
+        alert_msg = self._default_alerts_get(cr, uid, context=context)
+        for order in self.browse(cr, uid, ids, context=context):
+            if order.state == 'new':
+                result[order.id] = alert_msg
+        return result
+
+    def check_day(self, alert):
+        """ 
+        This method is used by can_display_alert
+        to check if the alert day corresponds
+        to the current day 
+        """
+        today = datetime.now().isoweekday()
+        assert 1 <= today <= 7, "Should be between 1 and 7"
+        mapping = dict((idx, name) for idx, name in enumerate('monday tuestday wednesday thursday friday saturday sunday'.split()))
+        if today in mapping:
+            return mapping[today]
+
+    def can_display_alert(self, alert):
+        """ 
+        This method check if the alert can be displayed today
+        """
+        if alert.alter_type == 'specific':
+            #the alert is only activated on a specific day
+            return alert.specific_day == time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+        elif alert.alter_type == 'week':
+            #the alert is activated during some days of the week
+            return self.check_day(alert)
+
+    def _default_alerts_get(self, cr, uid, context=None):
+        """ 
+        get the alerts to display on the order form
+        """
+        alert_ref = self.pool.get('lunch.alert')
+        alert_ids = alert_ref.search(cr, uid, [], context=context)
+        alert_msg = []
+        for alert in alert_ref.browse(cr, uid, alert_ids, context=context):
+            #check if the address must be displayed today
+            if self.can_display_alert(alert):
+                #display the address only during its active time
+                mynow = fields.datetime.context_timestamp(cr, uid, datetime.now(), context=context)
+                hour_to = int(alert.active_to)
+                min_to = int((alert.active_to - hour_to) * 60)
+                to_alert = datetime.strptime(str(hour_to) + ":" + str(min_to), "%H:%M")
+                hour_from = int(alert.active_from)
+                min_from = int((alert.active_from - hour_from) * 60)
+                from_alert = datetime.strptime(str(hour_from) + ":" + str(min_from), "%H:%M")
+                if mynow.time() >= from_alert.time() and mynow.time() <= to_alert.time():
+                    alert_msg.append(alert.message)
+        return '\n'.join(alert_msg)
+
+    def onchange_price(self, cr, uid, ids, order_line_ids, context=None):
+        """
+        Onchange methode that refresh the total price of order
+        """
+        res = {'value': {'total': 0.0}}
+        order_line_ids = self.resolve_o2m_commands_to_record_dicts(cr, uid, "order_line_ids", order_line_ids, ["price"], context=context)
+        if order_line_ids:
+            tot = 0.0
+            product_ref = self.pool.get("lunch.product")
+            for prod in order_line_ids:
+                if 'product_id' in prod:
+                    tot += product_ref.browse(cr, uid, prod['product_id'], context=context).price
+                else:
+                    tot += prod['price']
+            res = {'value': {'total': tot}}
+        return res
 
-    _name = 'lunch.category'
-    _description = "Category"
+    def __getattr__(self, attr):
+        """ 
+        this method catch unexisting method call and if it starts with
+        add_preference_'n' we execute the add_preference method with 
+        'n' as parameter 
+        """
+        if attr.startswith('add_preference_'):
+            pref_id = int(attr[15:])
+            def specific_function(cr, uid, ids, context=None):
+                return self.add_preference(cr, uid, ids, pref_id, context=context)
+            return specific_function
+        return super(lunch_order,self).__getattr__(self,attr)
+
+    def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
+        """ 
+        Add preferences in the form view of order.line 
+        """
+        res = super(lunch_order,self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
+        line_ref = self.pool.get("lunch.order.line")
+        if view_type == 'form':
+            doc = etree.XML(res['arch'])
+            pref_ids = line_ref.search(cr, uid, [('user_id', '=', uid)], order='create_date desc', context=context)
+            xml_start = etree.Element("div")
+            #If there are no preference (it's the first time for the user)
+            if len(pref_ids)==0:
+                #create Elements
+                xml_no_pref_1 = etree.Element("div")
+                xml_no_pref_1.set('class','oe_inline oe_lunch_intro')
+                xml_no_pref_2 = etree.Element("h3")
+                xml_no_pref_2.text = _("This is the first time you order a meal")
+                xml_no_pref_3 = etree.Element("p")
+                xml_no_pref_3.set('class','oe_grey')
+                xml_no_pref_3.text = _("Select a product and put your order comments on the note.")
+                xml_no_pref_4 = etree.Element("p")
+                xml_no_pref_4.set('class','oe_grey')
+                xml_no_pref_4.text = _("Your favorite meals will be created based on your last orders.")
+                xml_no_pref_5 = etree.Element("p")
+                xml_no_pref_5.set('class','oe_grey')
+                xml_no_pref_5.text = _("Don't forget the alerts displayed in the reddish area")
+                #structure Elements
+                xml_start.append(xml_no_pref_1)
+                xml_no_pref_1.append(xml_no_pref_2)
+                xml_no_pref_1.append(xml_no_pref_3)
+                xml_no_pref_1.append(xml_no_pref_4)
+                xml_no_pref_1.append(xml_no_pref_5)
+            #Else: the user already have preferences so we display them
+            else:
+                preferences = line_ref.browse(cr, uid, pref_ids, context=context)
+                categories = {} #store the different categories of products in preference
+                count = 0
+                for pref in preferences:
+                    #For each preference
+                    categories.setdefault(pref.product_id.category_id.name, {})
+                    #if this product has already been added to the categories dictionnary
+                    if pref.product_id.id in categories[pref.product_id.category_id.name]:
+                        #we check if for the same product the note has already been added
+                        if pref.note not in categories[pref.product_id.category_id.name][pref.product_id.id]:
+                            #if it's not the case then we add this to preferences
+                            categories[pref.product_id.category_id.name][pref.product_id.id][pref.note] = pref
+                    #if this product is not in the dictionnay, we add it
+                    else:
+                        categories[pref.product_id.category_id.name][pref.product_id.id] = {}
+                        categories[pref.product_id.category_id.name][pref.product_id.id][pref.note] = pref
+
+                currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id
+
+                #For each preferences that we get, we will create the XML structure
+                for key,value in categories.items():
+                    xml_pref_1 = etree.Element("div")
+                    xml_pref_1.set('class','oe_lunch_30pc')
+                    xml_pref_2 = etree.Element("h2")
+                    xml_pref_2.text = key
+                    xml_pref_1.append(xml_pref_2)
+                    i = 0
+                    value = value.values()
+                    for val in value:
+                        for pref in val.values():
+                            #We only show 5 preferences per category (or it will be too long)
+                            if i==5: break
+                            i+=1
+                            xml_pref_3 = etree.Element("div")
+                            xml_pref_3.set('class','oe_lunch_vignette')
+                            xml_pref_1.append(xml_pref_3)
+
+                            xml_pref_4 = etree.Element("span")
+                            xml_pref_4.set('class','oe_lunch_button')
+                            xml_pref_3.append(xml_pref_4)
+
+                            xml_pref_5 = etree.Element("button")
+                            xml_pref_5.set('name',"add_preference_"+str(pref.id))
+                            xml_pref_5.set('class','oe_link oe_i oe_button_plus')
+                            xml_pref_5.set('type','object')
+                            xml_pref_5.set('string','+')
+                            xml_pref_4.append(xml_pref_5)
+
+                            xml_pref_6 = etree.Element("button")
+                            xml_pref_6.set('name',"add_preference_"+str(pref.id))
+                            xml_pref_6.set('class','oe_link oe_button_add')
+                            xml_pref_6.set('type','object')
+                            xml_pref_6.set('string',_("Add"))
+                            xml_pref_4.append(xml_pref_6)
+
+                            xml_pref_7 = etree.Element("div")
+                            xml_pref_7.set('class','oe_group_text_button')
+                            xml_pref_3.append(xml_pref_7)
+
+                            xml_pref_8 = etree.Element("div")
+                            xml_pref_8.set('class','oe_lunch_text')
+                            xml_pref_8.text = escape(pref.product_id.name)+str(" ")
+                            xml_pref_7.append(xml_pref_8)
+
+                            price = pref.product_id.price or 0.0
+                            cur = currency.name or ''
+                            xml_pref_9 = etree.Element("span")
+                            xml_pref_9.set('class','oe_tag')
+                            xml_pref_9.text = str(price)+str(" ")+cur
+                            xml_pref_8.append(xml_pref_9)
+
+                            xml_pref_10 = etree.Element("div")
+                            xml_pref_10.set('class','oe_grey')
+                            xml_pref_10.text = escape(pref.note or '')
+                            xml_pref_3.append(xml_pref_10)
+
+                            xml_start.append(xml_pref_1)
+
+            first_node = doc.xpath("//div[@name='preferences']")
+            if first_node and len(first_node)>0:
+                first_node[0].append(xml_start)
+            res['arch'] = etree.tostring(doc)
+        return res
 
     _columns = {
-        'name': fields.char('Name', required=True, size=50),
+        'user_id': fields.many2one('res.users', 'User Name', required=True, readonly=True, states={'new':[('readonly', False)]}),
+        'date': fields.date('Date', required=True, readonly=True, states={'new':[('readonly', False)]}),
+        'order_line_ids': fields.one2many('lunch.order.line', 'order_id', 'Products', ondelete="cascade", readonly=True, states={'new':[('readonly', False)]}),
+        'total': fields.function(_price_get, string="Total", store={
+                 'lunch.order.line': (_fetch_orders_from_lines, ['product_id','order_id'], 20),
+            }),
+        'state': fields.selection([('new', 'New'), \
+                                    ('confirmed','Confirmed'), \
+                                    ('cancelled','Cancelled'), \
+                                    ('partially','Partially Confirmed')] \
+                                ,'Status', readonly=True, select=True),
+        'alerts': fields.function(_alerts_get, string="Alerts", type='text'),
     }
-    _order = 'name'
 
-lunch_category()
+    _defaults = {
+        'user_id': lambda self, cr, uid, context: uid,
+        'date': fields.date.context_today,
+        'state': 'new',
+        'alerts': _default_alerts_get,
+    }
 
 
-class lunch_product(osv.osv):
-    """ Lunch Product """
+class lunch_order_line(osv.Model):
+    """ 
+    lunch order line: one lunch order can have many order lines
+    """
+    _name = 'lunch.order.line'
+    _description = 'lunch order line'
+
+    def onchange_price(self, cr, uid, ids, product_id, context=None):
+        if product_id:
+            price = self.pool.get('lunch.product').browse(cr, uid, product_id, context=context).price
+            return {'value': {'price': price}}
+        return {'value': {'price': 0.0}}
+
+    def order(self, cr, uid, ids, context=None):
+        """ 
+        The order_line is ordered to the supplier but isn't received yet
+        """
+        for order_line in self.browse(cr, uid, ids, context=context):
+            order_line.write({'state': 'ordered'}, context=context)
+        return self._update_order_lines(cr, uid, ids, context=context)
+
+    def confirm(self, cr, uid, ids, context=None):
+        """ 
+        confirm one or more order line, update order status and create new cashmove 
+        """
+        cashmove_ref = self.pool.get('lunch.cashmove')
+        for order_line in self.browse(cr, uid, ids, context=context):
+            if order_line.state != 'confirmed':
+                values = {
+                    'user_id': order_line.user_id.id,
+                    'amount': -order_line.price,
+                    'description': order_line.product_id.name,
+                    'order_id': order_line.id,
+                    'state': 'order',
+                    'date': order_line.date,
+                }
+                cashmove_ref.create(cr, uid, values, context=context)
+                order_line.write({'state': 'confirmed'}, context=context)
+        return self._update_order_lines(cr, uid, ids, context=context)
+
+    def _update_order_lines(self, cr, uid, ids, context=None):
+        """
+        Update the state of lunch.order based on its orderlines
+        """
+        orders_ref = self.pool.get('lunch.order')
+        orders = []
+        for order_line in self.browse(cr, uid, ids, context=context):
+            orders.append(order_line.order_id)
+        for order in set(orders):
+            isconfirmed = True
+            for orderline in order.order_line_ids:
+                if orderline.state == 'new':
+                    isconfirmed = False
+                if orderline.state == 'cancelled':
+                    isconfirmed = False
+                    orders_ref.write(cr, uid, [order.id], {'state': 'partially'}, context=context)
+            if isconfirmed:
+                orders_ref.write(cr, uid, [order.id], {'state': 'confirmed'}, context=context)
+        return {}
 
-    _name = 'lunch.product'
-    _description = "Lunch Product"
+    def cancel(self, cr, uid, ids, context=None):
+        """
+        cancel one or more order.line, update order status and unlink existing cashmoves
+        """
+        cashmove_ref = self.pool.get('lunch.cashmove')
+        for order_line in self.browse(cr, uid, ids, context=context):
+            order_line.write({'state':'cancelled'}, context=context)
+            cash_ids = [cash.id for cash in order_line.cashmove]
+            cashmove_ref.unlink(cr, uid, cash_ids, context=context)
+        return self._update_order_lines(cr, uid, ids, context=context)
 
     _columns = {
-        'name': fields.char('Name', size=50, required=True),
-        'category_id': fields.many2one('lunch.category', 'Category'),
-        'description': fields.text('Description', size=128, required=False),
-        'price': fields.float('Price', digits=(16,2)),
-        'active': fields.boolean('Active'),
-    }
+        'name': fields.related('product_id', 'name', readonly=True),
+        'order_id': fields.many2one('lunch.order', 'Order', ondelete='cascade'),
+        'product_id': fields.many2one('lunch.product', 'Product', required=True),
+        'date': fields.related('order_id', 'date', type='date', string="Date", readonly=True, store=True),
+        'supplier': fields.related('product_id', 'supplier', type='many2one', relation='res.partner', string="Supplier", readonly=True, store=True),
+        'user_id': fields.related('order_id', 'user_id', type='many2one', relation='res.users', string='User', readonly=True, store=True),
+        'note': fields.text('Note'),
+        'price': fields.float("Price"),
+        'state': fields.selection([('new', 'New'), \
+                                    ('confirmed', 'Received'), \
+                                    ('ordered', 'Ordered'),  \
+                                    ('cancelled', 'Cancelled')], \
+                                'Status', readonly=True, select=True),
+        'cashmove': fields.one2many('lunch.cashmove', 'order_id', 'Cash Move', ondelete='cascade'),
 
+    }
     _defaults = {
-        'active': lambda *a : True,
+        'state': 'new',
     }
 
-lunch_product()
-
-
-class lunch_cashbox(osv.osv):
-    """ cashbox for Lunch """
-
-    _name = 'lunch.cashbox'
-    _description = "Cashbox for Lunch "
-
-
-    def amount_available(self, cr, uid, ids, field_name, arg, context=None):
-
-        """ count available amount
-        @param cr: the current row, from the database cursor,
-        @param uid: the current user’s ID for security checks,
-        @param ids: List of create menu’s IDs
-        @param context: A standard dictionary for contextual values """
-
-        cr.execute("SELECT box,sum(amount) from lunch_cashmove where active = 't' group by box")
-        amount = dict(cr.fetchall())
-        for i in ids:
-            amount.setdefault(i, 0)
-        return amount
 
+class lunch_product(osv.Model):
+    """ 
+    lunch product 
+    """
+    _name = 'lunch.product'
+    _description = 'lunch product'
     _columns = {
-        'manager': fields.many2one('res.users', 'Manager'),
-        'name': fields.char('Name', size=30, required=True, unique = True),
-        'sum_remain': fields.function(amount_available, string='Total Remaining'),
+        'name': fields.char('Product', required=True, size=64),
+        'category_id': fields.many2one('lunch.product.category', 'Category', required=True),
+        'description': fields.text('Description', size=256),
+        'price': fields.float('Price', digits=(16,2)), #TODO: use decimal precision of 'Account', move it from product to decimal_precision
+        'supplier': fields.many2one('res.partner', 'Supplier'),
     }
 
-lunch_cashbox()
-
-
-class lunch_cashmove(osv.osv):
-    """ Move cash """
-
-    _name = 'lunch.cashmove'
-    _description = "Cash Move"
-
+class lunch_product_category(osv.Model):
+    """ 
+    lunch product category 
+    """
+    _name = 'lunch.product.category'
+    _description = 'lunch product category'
     _columns = {
-        'name': fields.char('Description', size=128),
-        'user_cashmove': fields.many2one('res.users', 'User Name', required=True),
-        'amount': fields.float('Amount', digits=(16, 2)),
-        'box': fields.many2one('lunch.cashbox', 'Box Name', size=30, required=True),
-        'active': fields.boolean('Active'),
-        'create_date': fields.datetime('Creation Date', readonly=True),
-    }
-
-    _defaults = {
-        'active': lambda *a: True,
+        'name': fields.char('Category', required=True), #such as PIZZA, SANDWICH, PASTA, CHINESE, BURGER, ...
     }
 
-lunch_cashmove()
-
-
-class lunch_order(osv.osv):
-    """ Apply lunch order """
-
-    _name = 'lunch.order'
-    _description = "Lunch Order"
-    _rec_name = "user_id"
-
-    def _price_get(self, cr, uid, ids, name, args, context=None):
-
-        """ Get Price of Product
-         @param cr: the current row, from the database cursor,
-         @param uid: the current user’s ID for security checks,
-         @param ids: List of Lunch order’s IDs
-         @param context: A standard dictionary for contextual values """
-
-        res = {}
-        for price in self.browse(cr, uid, ids, context=context):
-            res[price.id] = price.product.price
-        return res
-
+class lunch_cashmove(osv.Model):
+    """ 
+    lunch cashmove => order or payment 
+    """
+    _name = 'lunch.cashmove'
+    _description = 'lunch cashmove'
     _columns = {
-        'user_id': fields.many2one('res.users', 'User Name', required=True, \
-            readonly=True, states={'draft':[('readonly', False)]}),
-        'product': fields.many2one('lunch.product', 'Product', required=True, \
-            readonly=True, states={'draft':[('readonly', False)]}, change_default=True),
-        'date': fields.date('Date', readonly=True, states={'draft':[('readonly', False)]}),
-        'cashmove': fields.many2one('lunch.cashmove', 'Cash Move' , readonly=True),
-        'descript': fields.char('Comment', readonly=True, size=250, \
-            states = {'draft':[('readonly', False)]}),
-        'state': fields.selection([('draft', 'New'), ('confirmed', 'Confirmed'), ], \
-            'Status', readonly=True, select=True),
-        'price': fields.function(_price_get, string="Price"),
-        'category': fields.many2one('lunch.category','Category'),
+        'user_id': fields.many2one('res.users', 'User Name', required=True),
+        'date': fields.date('Date', required=True),
+        'amount': fields.float('Amount', required=True), #depending on the kind of cashmove, the amount will be positive or negative
+        'description': fields.text('Description'), #the description can be an order or a payment
+        'order_id': fields.many2one('lunch.order.line', 'Order', ondelete='cascade'),
+        'state': fields.selection([('order','Order'), ('payment','Payment')], 'Is an order or a Payment'),
     }
-
     _defaults = {
         'user_id': lambda self, cr, uid, context: uid,
         'date': fields.date.context_today,
-        'state': lambda self, cr, uid, context: 'draft',
+        'state': 'payment',
     }
 
-    def confirm(self, cr, uid, ids, box, context=None):
-
-        """ confirm order
-        @param cr: the current row, from the database cursor,
-        @param uid: the current user’s ID for security checks,
-        @param ids: List of confirm order’s IDs
-        @param context: A standard dictionary for contextual values """
-
-        cashmove_ref = self.pool.get('lunch.cashmove')
-        for order in self.browse(cr, uid, ids, context=context):
-            if order.state == 'confirmed':
-                continue
-            new_id = cashmove_ref.create(cr, uid, {'name': order.product.name+' order',
-                            'amount':-order.product.price,
-                            'user_cashmove':order.user_id.id,
-                            'box':box,
-                            'active':True,
-                            })
-            self.write(cr, uid, [order.id], {'cashmove': new_id, 'state': 'confirmed'})
-        return {}
-
-    def lunch_order_cancel(self, cr, uid, ids, context=None):
-
-        """" cancel order
-         @param cr: the current row, from the database cursor,
-         @param uid: the current user’s ID for security checks,
-         @param ids: List of create menu’s IDs
-         @param context: A standard dictionary for contextual values """
-
-        orders = self.browse(cr, uid, ids, context=context)
-        for order in orders:
-            if not order.cashmove:
-                continue
-        if order.cashmove.id:
-            self.pool.get('lunch.cashmove').unlink(cr, uid, [order.cashmove.id])
-        self.write(cr, uid, ids, {'state':'draft'})
-        return {}
-
-    def onchange_product(self, cr, uid, ids, product):
-
-        """ Get price for Product
-         @param cr: the current row, from the database cursor,
-         @param uid: the current user’s ID for security checks,
-         @param ids: List of create menu’s IDs
-         @product: Product To Ordered """
-
-        if not product:
-            return {'value': {'price': 0.0}}
-        price = self.pool.get('lunch.product').read(cr, uid, product, ['price'])['price']
-        categ_id = self.pool.get('lunch.product').browse(cr, uid, product).category_id.id
-        return {'value': {'price': price,'category':categ_id}}
-
-lunch_order()
-
-
-class report_lunch_amount(osv.osv):
-    """ Lunch Amount Report """
-
-    _name = 'report.lunch.amount'
-    _description = "Amount available by user and box"
-    _auto = False
-    _rec_name = "user_id"
-
+class lunch_alert(osv.Model):
+    """ 
+    lunch alert 
+    """
+    _name = 'lunch.alert'
+    _description = 'Lunch Alert'
     _columns = {
-        'user_id': fields.many2one('res.users', 'User Name', readonly=True),
-        'amount': fields.float('Amount', readonly=True, digits=(16, 2)),
-        'box': fields.many2one('lunch.cashbox', 'Box Name', size=30, readonly=True),
-        'year': fields.char('Year', size=4, readonly=True),
-        'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
-            ('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
-            ('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
-        'day': fields.char('Day', size=128, readonly=True),
-        'date': fields.date('Created Date', readonly=True),
+        'message': fields.text('Message', size=256, required=True),
+        'alter_type': fields.selection([('specific', 'Specific Day'), \
+                                    ('week', 'Every Week'), \
+                                    ('days', 'Every Day')], \
+                                string='Recurrency', required=True, select=True),
+        'specific_day': fields.date('Day'),
+        'monday': fields.boolean('Monday'),
+        'tuesday': fields.boolean('Tuesday'),
+        'wednesday': fields.boolean('Wednesday'),
+        'thursday': fields.boolean('Thursday'),
+        'friday': fields.boolean('Friday'),
+        'saturday': fields.boolean('Saturday'),
+        'sunday':  fields.boolean('Sunday'),
+        'active_from': fields.float('Between', required=True),
+        'active_to': fields.float('And', required=True),
+    }
+    _defaults = {
+        'alter_type': 'specific',
+        'specific_day': fields.date.context_today,
+        'active_from': 7,
+        'active_to': 23,
     }
-
-    def init(self, cr):
-
-        """ @param cr: the current row, from the database cursor"""
-
-        cr.execute("""
-            create or replace view report_lunch_amount as (
-                select
-                    min(lc.id) as id,
-                    to_date(to_char(lc.create_date, 'dd-MM-YYYY'),'dd-MM-YYYY') as date,
-                    to_char(lc.create_date, 'YYYY') as year,
-                    to_char(lc.create_date, 'MM') as month,
-                    to_char(lc.create_date, 'YYYY-MM-DD') as day,
-                    lc.user_cashmove as user_id,
-                    sum(amount) as amount,
-                    lc.box as box
-                from
-                    lunch_cashmove lc
-                where
-                    active = 't'
-                group by lc.user_cashmove, lc.box, lc.create_date
-                )""")
-
-report_lunch_amount()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
index 543086d..a9b0313 100644 (file)
 <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>
diff --git a/addons/lunch/lunch_installer_view.xml b/addons/lunch/lunch_installer_view.xml
deleted file mode 100644 (file)
index d63f44b..0000000
+++ /dev/null
@@ -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>
index c5e9338..942caad 100644 (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"
             />
index b560ada..32b978d 100644 (file)
 <?xml version="1.0"?>
 <openerp>
     <data>
-        <!-- Top menu item -->
-        <menuitem name="Tools" id="base.menu_tools" sequence="160"/>
-
-          <menuitem name="Lunch Order" parent="base.menu_tools"
-              id="menu_lunch" sequence="1" />
-
-          <menuitem name="Reporting" parent="base.menu_tools"
-              id="base.menu_lunch_reporting" sequence="6" groups="base.group_tool_manager"/>
-
-          <menuitem name="Lunch"
-              parent="base.menu_reporting"
-              id="menu_lunch_reporting_order" sequence="55" />
-
-          <menuitem name="Configuration" parent="base.menu_tools"
-              id="base.menu_lunch_survey_root" sequence="20" groups="base.group_tool_manager"/>
-
-          <menuitem name="Lunch" parent="base.menu_lunch_survey_root"
-              id="menu_lunch_category_root_configuration" sequence="1" />
-
-<!-- Lunch order Form view -->
-
-          <record model="ir.ui.view" id="view_lunch_order_form">
-            <field name="name">Order</field>
-            <field name="model">lunch.order</field>
+        <!--Menu and Title-->
+        <menuitem id='menu_lunch' name='Lunch' sequence="300"/>
+        <menuitem name="Lunch" parent="menu_lunch" id="menu_lunch_title" sequence="50" />
+        <menuitem name="Administrate Orders" parent="menu_lunch" id="menu_lunch_admin" sequence="51" groups="group_lunch_manager"/>
+        <menuitem name="Administrate Cash Moves" parent="menu_lunch" id="menu_lunch_cash" sequence="52" groups="group_lunch_manager"/>
+        <menuitem name="Configuration" parent="menu_lunch" id="menu_lunch_config" sequence="53" groups="group_lunch_manager"/>
+        
+         <!--View Search to group/filter by Supplier and time-->
+        <record model="ir.ui.view" id="lunch_order_line_search_view">
+            <field name="name">Search</field>
+            <field name="model">lunch.order.line</field>
+            <field name="type">search</field>
             <field name="arch" type="xml">
-                <form string="Lunch Order" version="7.0">
-                <header>
-                    <button name="%(action_lunch_order_confirm)d" string="Confirm Order" type="action" states="draft" class="oe_highlight"/>
-                    <button name="%(action_lunch_order_cancel)d" string="Cancel Order" type="action" states="confirmed" />
-                    <field name="state" widget="statusbar" statusbar_visible="draft,confirmed"/>
-                </header>
-                <sheet string="Order">
-                    <group>
-                        <group>
-                            <field name="product" on_change="onchange_product(product)"/>
-                            <field name="descript"/>
-                            <field name="price"/>
-                            <field name="category"/>
-                        </group>
-                        <group>
-                            <field name="user_id"/>
-                            <field name="cashmove"/>
-                            <field name="date"/>
-                        </group>
+                <search string="Search">
+                    <field name="name" filter_domain="['|', ('name', 'ilike', self), ('note', 'ilike', self)]"/>
+                    <filter name="not_confirmed" string="Not Received" domain="[('state','!=',('confirmed'))]"/>
+                    <filter name="comfirmed" string="Received" domain="[('state','=','confirmed')]"/>
+                    <filter name="cancelled" string="Cancelled" domain="[('state','=','cancelled')]"/>
+                    <separator/>
+                    <filter name="today" string="Today" domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]"/>
+                    <field name="user_id"/>
+                    <group expand="0" string="Group By...">
+                        <filter name="group_by_supplier" string="By Supplier" context="{'group_by':'supplier'}"/>
+                        <filter name="group_by_date" string="By Date" context="{'group_by':'date'}"/>
                     </group>
-                </sheet>
-                </form>
+                </search>
             </field>
         </record>
 
-<!-- Lunch order Tree view -->
-
-        <record model="ir.ui.view" id="view_lunch_order_tree">
-            <field name="name">Order</field>
-            <field name="model">lunch.order</field>
-            <field name="arch" type="xml">
-                <tree colors="blue:state == 'draft';black:state == 'confirmed'" string="Order">
-                    <field name="date"/>
+        <!--View Search to group by employee and input/output (cashmoves)-->
+        <record id="view_lunch_employee_payment_filter" model="ir.ui.view">
+            <field name='name'>lunch employee payment</field>
+            <field name='model'>lunch.cashmove</field>
+            <field name='type'>search</field>
+            <field name='arch' type='xml'>
+                <search string="lunch employee payment">
+                    <field name="description"/>
                     <field name="user_id"/>
-                    <field name="product"/>
-                    <field name="descript"/>
-                    <field name="category"/>
-                    <field name="price" sum="Total price"/>
-                    <field name="state"/>
-                </tree>
+                    <filter name='is_payment' string="Payment" domain="[('state','=','payment')]"/>
+                    <separator/>
+                    <filter name='is_mine' string="My Account" domain="[('user_id','=',uid)]"/>
+                </search>
             </field>
         </record>
 
-<!-- Lunch order Search view -->
-
-        <record id="view_lunch_order_filter" model="ir.ui.view">
-            <field name="name">lunch.order.list.select</field>
-            <field name="model">lunch.order</field>
-            <field name="arch" type="xml">
-                <search string="Search Lunch Order">
-                    <field name="date"/>
-                    <filter icon="terp-check" string="To Confirm" domain="[('state','=','draft')]"/>
-                    <filter icon="terp-camera_test" string="Confirmed" domain="[('state','=',('confirmed'))]"/>
+        <record id="view_lunch_cashmove_filter" model="ir.ui.view">
+            <field name='name'>lunch cashmove</field>
+            <field name='model'>lunch.cashmove</field>
+            <field name='type'>search</field>
+            <field name='arch' type='xml'>
+                <search string="lunch cashmove">
+                    <field name="description"/>
                     <field name="user_id"/>
                     <group expand="0" string="Group By...">
-                        <filter string="Category" icon="terp-stock_symbol-selection" domain="[]"  context="{'group_by':'category'}"/>
+                        <filter name='group_by_user' string="By Employee" context="{'group_by':'user_id'}"/>
                     </group>
                 </search>
             </field>
         </record>
 
-<!-- Lunch order Action -->
-
-        <record model="ir.actions.act_window" id="action_lunch_order_form">
-                <field name="name">Lunch Orders</field>
-                <field name="res_model">lunch.order</field>
-                <field name="view_mode">tree,form</field>
-                <field name="search_view_id" ref="view_lunch_order_filter"/>
-                <field name="context">{"search_default_Today":1}</field>
+        <!--View search for order-->
+        <record id="view_search_my_order" model="ir.ui.view">
+            <field name='name'>lunch orders</field>
+            <field name='model'>lunch.order</field>
+            <field name='type'>search</field>
+            <field name='arch' type='xml'>
+                <search string="lunch orders">
+                    <field name="date"/>
+                    <field name="order_line_ids"/>
+                    <filter name='is_mine' string="My Orders" domain="[('user_id','=',uid)]"/>
+                </search>
+            </field>
         </record>
 
-        <menuitem name="Lunch Orders" parent="menu_lunch"
-            id="menu_lunch_order_form" action="action_lunch_order_form" />
-
-<!--  Cash Box Form view  -->
 
-        <record model="ir.ui.view" id="view_lunch_cashbox_form">
-            <field name="name">Cashboxes</field>
-            <field name="model">lunch.cashbox</field>
+        <record model="ir.ui.view" id="alert_search_view">
+            <field name="name">Search</field>
+            <field name="model">lunch.alert</field>
+            <field name="type">search</field>
             <field name="arch" type="xml">
-                <form string="Cashboxes" version="7.0">
-                    <group colspan="4">
-                        <field name="name"/>
-                        <field name="manager"/>
-                    </group>
-                </form>
+                <search string="Search">
+                    <field name="message"/>
+                </search>
             </field>
         </record>
 
-<!--  Cash Box Tree view  -->
+        <!--Action for Your Orders-->
+        <record model="ir.actions.act_window" id="action_lunch_order_form">
+            <field name="name">New Order</field>
+            <field name="res_model">lunch.order</field>
+            <field name="view_mode">form</field>
+        </record>
+        <menuitem name="New Order" parent="menu_lunch_title" id="menu_lunch_order_form" action="action_lunch_order_form" sequence="1"/>
 
-        <record model="ir.ui.view" id="view_lunch_cashbox_tree">
-            <field name="name">Cashboxes</field>
-            <field name="model">lunch.cashbox</field>
-            <field name="arch" type="xml">
-                <tree string="Cashboxes" colors="red:sum_remain&lt;=0">
-                    <field name="name"/>
-                    <field name="manager"/>
-                    <field name="sum_remain"/>
-                </tree>
+        <record model="ir.actions.act_window" id="action_lunch_order_tree">
+            <field name="name">Your Orders</field>
+            <field name="res_model">lunch.order</field>
+            <field name="view_mode">tree,form</field>
+            <field name="search_view_id" ref="view_search_my_order"/>
+            <field name="context">{"search_default_is_mine":1}</field>
+            <field name="help" type="html">
+            <p class="oe_view_nocontent_create">
+                Click to create a lunch order. 
+            </p>
+            <p>
+                A lunch order is defined by its user, date and order lines.
+                Each order line corresponds to a product, an additional note and a price.
+                Before selecting your order lines, don't forget to read the warnings displayed in the reddish area.
+            </p>
             </field>
         </record>
+        <menuitem name="Previous Orders" parent="menu_lunch_title" id="menu_lunch_order_tree" action="action_lunch_order_tree" sequence="2"/>
 
-<!--  Cash Box Action  -->
-
-        <record model="ir.actions.act_window" id="action_lunch_cashbox_form">
-                <field name="name"> Cashboxes </field>
-                <field name="res_model">lunch.cashbox</field>
+        <!--Action for Lunch cashmoves-->
+        <record model="ir.actions.act_window" id="action_lunch_cashmove_form">
+            <field name="name">Your Account</field>
+            <field name="res_model">lunch.cashmove</field>
+            <field name="view_mode">tree</field>
+            <field name="search_view_id" ref="view_lunch_employee_payment_filter"/>
+            <field name="context">{"search_default_is_mine":1}</field>
+            <field name="help" type="html">
+              <p>
+                Here you can see your cash moves.<br/>A cash moves can be either an expense or a payment.
+                An expense is automatically created when an order is received while a payment is a reimbursement to the company encoded by the manager.
+              </p>
+            </field>
         </record>
-
-        <menuitem name="Cashboxes"
-            parent="menu_lunch_category_root_configuration"
-            id="menu_lunch_cashbox_form"
-            action="action_lunch_cashbox_form" />
-
-<!-- Cash Move Form view  -->
-
-        <record model="ir.ui.view" id="view_lunch_cashmove_form">
-            <field name="name">CashMove</field>
-            <field name="model">lunch.cashmove</field>
-            <field name="arch" type="xml">
-                <form string="CashMove" version="7.0">
-                    <sheet>
-                        <group col="4">
-                            <field name="name"/>
-                            <field name="user_cashmove"/>
-                            <field name="amount"/>
-                            <field name="box"/>
-                            <field name="create_date"/>
-                            <field name="active"/>
-                        </group>
-                    </sheet>
-                </form>
+        <menuitem name="Your Lunch Account" parent="menu_lunch_title" id="menu_lunch_cashmove_form" action="action_lunch_cashmove_form" sequence="3"/>
+
+        <!--Action for Administrate Orders group by supplier-->
+        <record model="ir.actions.act_window" id="action_lunch_order_by_supplier_form">
+            <field name="name">Orders by Supplier</field>
+            <field name="res_model">lunch.order.line</field>
+            <field name="view_mode">tree</field>
+            <field name="search_view_id" ref="lunch_order_line_search_view"/>
+            <field name="context">{"search_default_group_by_supplier":1, "search_default_today":1}</field>
+            <field name="help" type="html">
+              <p>
+                Here you can see today's orders grouped by suppliers.
+              </p>
+              <p>
+                - Click on the <img src="../../../web/static/src/img/icons/terp-call-start.png"/> to announce that the order is ordered <br/>
+                - Click on the <img src="../../../web/static/src/img/icons/gtk-apply.png"/> to announce that the order is received <br/>
+                - Click on the <img src="../../../web/static/src/img/icons/gtk-cancel.png"/> to announce that the order isn't available
+              </p>
             </field>
         </record>
-
-<!-- Cash Move Tree view  -->
-
-        <record model="ir.ui.view" id="view_lunch_cashmove_tree">
-            <field name="name">CashMove</field>
-            <field name="model">lunch.cashmove</field>
-            <field name="arch" type="xml">
-                <tree string="CashMove" editable="top">
-                    <field name="create_date"/>
-                    <field name="box"/>
-                    <field name="name" required="1"/>
-                    <field name="user_cashmove"/>
-                    <field name="amount" sum="Total amount"/>
-                </tree>
+        <menuitem name="Today's Orders by Supplier" parent="menu_lunch_admin" id="menu_lunch_order_by_supplier_form" action="action_lunch_order_by_supplier_form" />
+
+        <!--Action for control Supplier-->
+        <record model="ir.actions.act_window" id="action_lunch_control_suppliers">
+            <field name="name">Control Suppliers</field>
+            <field name="res_model">lunch.order.line</field>
+            <field name="view_mode">tree</field>
+            <field name="search_view_id" ref="lunch_order_line_search_view"/> 
+            <field name="context">{"search_default_group_by_date":1, "search_default_group_by_supplier":1}</field>
+            <field name="help" type="html">
+              <p>
+                Here you can see every orders grouped by suppliers and by date.
+              </p>
+              <p>
+                - Click on the <img src="../../../web/static/src/img/icons/terp-call-start.png"/> to announce that the order is ordered <br/>
+                - Click on the <img src="../../../web/static/src/img/icons/gtk-apply.png"/> to announce that the order is received <br/>
+                - Click on the <img src="../../../web/static/src/img/icons/gtk-cancel.png"/> red X to announce that the order isn't available
+              </p>
             </field>
         </record>
+        <menuitem name="Orders by Supplier" parent="menu_lunch_admin" id="menu_lunch_control_suppliers" action="action_lunch_control_suppliers" />
 
-<!--  Cash Move Search View  -->
-
-        <record id="view_lunch_cashmove_filter" model="ir.ui.view">
-            <field name="name">lunch.cashmove.list.select</field>
-            <field name="model">lunch.cashmove</field>
-            <field name="arch" type="xml">
-                <search string="Search CashMove">
-                    <field name="create_date"/>
-                    <field name="user_cashmove"/>
-                    <group expand="0" string="Group By...">
-                        <filter string="User" icon="terp-personal" domain="[]"  context="{'group_by':'user_cashmove'}"/>
-                        <filter string="Box" icon="terp-dolar" domain="[]"  context="{'group_by':'box'}"/>
-                        <filter string="Date" icon="terp-go-today" domain="[]"  context="{'group_by':'create_date'}"/>
-                    </group>
-                </search>
+        <!--Action for Control Accounts-->
+        <record model="ir.actions.act_window" id="action_lunch_control_accounts">
+            <field name="name">Control Accounts</field>
+            <field name="res_model">lunch.cashmove</field>
+            <field name="view_mode">tree,form</field>
+            <field name="search_view_id" ref="view_lunch_cashmove_filter"/>
+            <field name="context">{"search_default_group_by_user":1}</field>
+            <field name="help" type="html">
+                <p class="oe_view_nocontent_create">
+                Click to create a new payment. 
+            </p>
+              <p>
+                A cashmove can either be an expense or a payment.<br/>
+                An expense is automatically created at the order receipt.<br/>
+                A payment represents the employee reimbursement to the company.
+              </p>
             </field>
         </record>
+        <menuitem name="Control Accounts" parent="menu_lunch_cash" id="menu_lunch_control_accounts" action="action_lunch_control_accounts" />
 
-<!-- Cash Move Action  -->
 
-        <record model="ir.actions.act_window" id="action_lunch_cashmove_form">
-                <field name="name">Cash Moves</field>
-                <field name="res_model">lunch.cashmove</field>
-                <field name="search_view_id" ref="view_lunch_cashmove_filter"/>
-                <field name="context">{"search_default_Today":1}</field>
+        <!--Action for Payment cashmove-->
+        <record model="ir.actions.act_window" id="action_lunch_cashmove">
+            <field name="name">Register Cash Moves</field>
+            <field name="res_model">lunch.cashmove</field>
+            <field name="view_mode">tree,form</field>
+            <field name="search_view_id" ref="view_lunch_employee_payment_filter"/>
+            <field name="context">{"search_default_is_payment":1}</field>
+            <field name="help" type="html">
+                <p class="oe_view_nocontent_create">
+                Click to create a payment. 
+            </p>
+              <p>
+                Here you can see the employees' payment. A payment is a cash move from the employee to the company.
+              </p>
+            </field>
         </record>
+        <menuitem name="Employee's Payment" parent="menu_lunch_cash" id="menu_lunch_cashmove" action="action_lunch_cashmove" />
 
-        <menuitem name="Cash Moves" parent="menu_lunch"
-            id="menu_lunch_cashmove_form"
-            action="action_lunch_cashmove_form" />
+        <!--Action for Products-->
+        <record model="ir.actions.act_window" id="action_lunch_products">
+            <field name="name">Products</field>
+            <field name="res_model">lunch.product</field>
+            <field name="view_mode">tree,form</field>
+            <field name="help" type="html">
+                <p class="oe_view_nocontent_create">
+                Click to create a product for lunch. 
+            </p>
+              <p>
+                A product is defined by its name, category, price and supplier.
+              </p>
+            </field>
+        </record>
+        <menuitem name="Products" parent="menu_lunch_config" id="menu_lunch_products" action="action_lunch_products" />
 
-<!-- Lunch Category Form view  -->
+        <!--Action for Product categories-->
+        <record model="ir.actions.act_window" id="action_lunch_product_categories">
+            <field name="name">Product Categories</field>
+            <field name="res_model">lunch.product.category</field>
+            <field name="view_mode">tree,form</field>
+            <field name="help" type="html">
+                <p class="oe_view_nocontent_create">
+                Click to create a lunch category. 
+            </p>
+              <p>
+                Here you can find every lunch categories for products.
+              </p>
+            </field>
+        </record>
 
-        <record model="ir.ui.view" id="view_lunch_category_form">
-            <field name="name"> Category of product </field>
-            <field name="model">lunch.category</field>
+        <record model="ir.ui.view" id="product_category_form_view">
+            <field name="name">Product category Form</field>
+            <field name="model">lunch.product.category</field>
+            <field name="type">form</field>
             <field name="arch" type="xml">
-                <form string="Category" version="7.0">
+                <form string="Products Form" version="7.0">
+                    <sheet>
                     <group>
-                        <field name="name"/>
+                        <field name='name' string="Product Category: "/>
                     </group>
+                    </sheet>
                 </form>
             </field>
         </record>
 
-<!-- Lunch Category Tree view  -->
+        <menuitem name="Product Categories" parent="menu_lunch_config" id="menu_lunch_product_categories" action="action_lunch_product_categories" />
 
-        <record model="ir.ui.view" id="view_lunch_category_tree">
-            <field name="name">Category</field>
-            <field name="model">lunch.category</field>
+        <!--Action for Alert-->
+        <record model="ir.actions.act_window" id="action_lunch_alert">
+            <field name="name">Alerts</field>
+            <field name="res_model">lunch.alert</field>
+            <field name="view_mode">tree,form</field>
+            <field name="search_view_id" ref="alert_search_view"/>
+            <field name="help" type="html">
+                <p class="oe_view_nocontent_create">
+                Click to create a lunch alert. 
+            </p>
+              <p>
+                Alerts are used to warn employee from possible issues concerning the lunch orders.
+                To create a lunch alert you have to define its recurrency, the time interval during which the alert should be executed and the message to display.
+            </p>
+            <p>
+                Example: <br/>
+                - Recurency: Everyday<br/>
+                - Time interval: from 00h00 am to 11h59 pm<br/>
+                - Message: "You must order before 10h30 am"
+              </p>
+            </field>
+        </record>
+        <menuitem name="Alerts" parent="menu_lunch_config" id="menu_lunch_alert" action="action_lunch_alert" />
+
+        <!--View for Order lines-->
+        <record model="ir.ui.view" id="orders_order_lines_tree_view">
+            <field name="name">Order lines Tree</field>
+            <field name="model">lunch.order.line</field>
+            <field name="type">tree</field>
             <field name="arch" type="xml">
-                <tree string="Order">
-                    <field name="name"/>
+                <tree string="Order lines Tree"> 
+                    <field name='date'/>
+                    <field name='user_id'/>
+                    <field name='supplier' invisible='1'/> 
+                    <field name='product_id'/>                             
+                    <field name='note'/>
+                    <field name='state'/>
+                    <field name='price' sum="Total"/>
+                    <button name="order" string="Order" type="object" icon="terp-call-start" attrs="{'invisible': ['|',('state','=','confirmed'),('state','=','ordered')]}"/>
+                    <button name="confirm" string="Confirm" type="object" icon="gtk-apply" attrs="{'invisible': [('state','!=','ordered')]}"/>
+                    <button name="cancel" string="Cancel" type="object" icon="gtk-cancel" attrs="{'invisible': [('state','=','cancelled')]}"/>
                 </tree>
             </field>
         </record>
 
-<!-- Lunch Category Action  -->
-
-        <record model="ir.actions.act_window" id="action_lunch_category_form">
-            <field name="name"> Product Categories </field>
-            <field name="res_model">lunch.category</field>
+        <!--View for Your orders-->
+        <record model="ir.ui.view" id="orders_tree_view">
+            <field name="name">Orders Tree View</field>
+            <field name="model">lunch.order</field>
+            <field name="type">tree</field>
+            <field name="arch" type="xml">
+                <tree string="Orders Tree">
+                    <field name="date"/>
+                    <field name="order_line_ids"/>
+                    <field name="state" />
+                    <field name="total" sum="Total"/>
+                </tree>
+            </field>
         </record>
-
-<!-- Lunch Product Form view  -->
-
-        <record model="ir.ui.view" id="view_lunch_product_form">
-            <field name="name">Products</field>
-            <field name="model">lunch.product</field>
+       
+        <record model="ir.ui.view" id="orders_form_view">
+            <field name="name">Lunch Order</field>
+            <field name="model">lunch.order</field>
             <field name="arch" type="xml">
-                <form string="Products" version="7.0">
+                <form string='Orders Form' version='7.0' class="oe_lunch">
+                    <header>
+                        <field name='state' widget='statusbar' statusbar_visible='new,confirmed'/>
+                    </header>
                     <sheet>
                         <group>
                             <group>
-                                <field name="name"/>
-                                <field name="category_id"/>
-                                <field name="price" />
+                                <field name='user_id'/>
                             </group>
-                            <group>
-                                <field name="active"/>
+                            <group> 
+                                <field name='date'/>
                             </group>
-                            <field name="description" placeholder="Add a description" nolabel="1" colspan="4"/>
                         </group>
+                        <field name='alerts' attrs="{'invisible': ['|',('state','!=','new'),('alerts','=','')]}" class="oe_inline oe_lunch_alert"/> 
+                        <div name="preferences">
+                        </div>
+                        <separator string='Select your order'/>
+                        <field name='order_line_ids' nolabel='1' on_change='onchange_price(order_line_ids)'>
+                            <tree string='List' editable='bottom'>
+                                <field name='product_id' on_change='onchange_price(product_id)'/>
+                                <field name='note' />
+                                <field name='price' />
+                                <field name='supplier' invisible="1"/>
+                                <field name="state" invisible="1"/>
+                            </tree>
+                        </field> 
+                        <group class='oe_subtotal_footer oe_right'>
+                            <field name='total'/> 
+                        </group>
+                        <br/><br/>
                     </sheet>
                 </form>
             </field>
         </record>
 
-<!-- Lunch Product Tree view  -->
-
-        <record model="ir.ui.view" id="view_lunch_product_tree">
-            <field name="name">Products</field>
+        <!--View for Products-->
+        <record model="ir.ui.view" id="products_tree_view">
+            <field name="name">Products Tree</field>
             <field name="model">lunch.product</field>
+            <field name="type">tree</field>
             <field name="arch" type="xml">
-                <tree string="Products">
+                <tree string="Products Tree">
                     <field name="name"/>
                     <field name="category_id"/>
-                    <field name="price"/>
+                    <field name="supplier"/>
                     <field name="description"/>
+                    <field name="price"/>
                 </tree>
             </field>
         </record>
 
-<!-- Lunch Product Search view  -->
-
-        <record model="ir.ui.view" id="view_lunch_product_search">
-            <field name="name">Products</field>
+        <record model="ir.ui.view" id="products_form_view">
+            <field name="name">Products Form</field>
             <field name="model">lunch.product</field>
+            <field name="type">form</field>
             <field name="arch" type="xml">
-                <search string="Products">
-                    <field name="name" string="Product"/>
-                    <field name="price"/>
-                    <field name="category_id"/>
-                </search>
+                <form string="Products Form" version="7.0">
+                    <header>
+                    </header>
+                    <sheet>
+                        <group>
+                            <field name='name'/>
+                            <field name='category_id'/>
+                            <field name='supplier'/>
+                            <field name='price'/>
+                        </group>
+                        <label for='description'/>
+                        <field name='description'/>
+                    </sheet>
+                </form>
             </field>
         </record>
 
-<!-- Lunch Product Action  -->
-
-        <record model="ir.actions.act_window" id="action_lunch_product_form">
-            <field name="name">Products</field>
-            <field name="res_model">lunch.product</field>
-            <field name="view_type">form</field>
-            <field name="view_mode">tree,form</field>
-            <field name="view_id" ref="view_lunch_product_tree"/>
-            <field name="search_view_id" ref="view_lunch_product_search"/>
-        </record>
-
-        <menuitem name="Products"
-            parent="menu_lunch_category_root_configuration"
-            id="menu_lunch_product_form" action="action_lunch_product_form"
-            sequence="2" />
-
-        <menuitem name="Product Categories"
-            parent="menu_lunch_category_root_configuration"
-            id="menu_lunch_category_form"
-            action="action_lunch_category_form" sequence="1" />
-
-
-<!-- Lunch Amount Tree view -->
-
-        <record model="ir.ui.view" id="view_report_lunch_amount_tree">
-            <field name="name">Lunch amount</field>
-            <field name="model">report.lunch.amount</field>
+        <!--view for cashmove-->
+        <record model="ir.ui.view" id="casmove_tree_view">
+            <field name="name">cashmove tree</field>
+            <field name="model">lunch.cashmove</field>
+            <field name="type">tree</field>
             <field name="arch" type="xml">
-                <tree string="Box Amount by User">
-                    <field name="date" invisible="1"/>
-                    <field name="year" invisible="1"/>
-                    <field name="day" invisible="1"/>
-                    <field name="month" invisible="1"/>
-                    <field name="box"/>
+                <tree string="cashmove tree">
+                    <field name="date"/>
                     <field name="user_id"/>
-                    <field name="amount" sum="Total box" />
+                    <field name="description"/>
+                    <field name="amount" sum="Total"/>
                 </tree>
             </field>
         </record>
 
-<!-- Lunch Amount Form view -->
-
-        <record model="ir.ui.view" id="view_report_lunch_amount_form">
-            <field name="name">Lunch amount</field>
-            <field name="model">report.lunch.amount</field>
+        <record model="ir.ui.view" id="casmove_form_view">
+            <field name="name">cashmove form</field>
+            <field name="model">lunch.cashmove</field>
+            <field name="type">form</field>
             <field name="arch" type="xml">
-                <form string="Box Amount by User" version="7.0">
-                 <sheet>
-                    <group col="4">
-                        <field name="user_id"/>
-                        <field name="box"/>
-                        <field name="amount"/>
-                    </group>
-                 </sheet>   
+                <form string="cashmove form" version="7.0">
+                    <sheet>
+                        <group>
+                            <field name="user_id"/>
+                            <field name="date"/>
+                            <field name="amount"/>
+                        </group>
+                        <label for='description'/>
+                        <field name="description"/>
+                    </sheet>
                 </form>
             </field>
         </record>
 
-<!-- Lunch Amount Search view -->
-
-        <record model="ir.ui.view" id="view_report_lunch_amount_search">
-            <field name="name">Lunch amount</field>
-            <field name="model">report.lunch.amount</field>
+        <!--view for alerts-->
+        <record model="ir.ui.view" id="alert_tree_view">
+            <field name="name">alert tree</field>
+            <field name="model">lunch.alert</field>
+            <field name="type">tree</field>
             <field name="arch" type="xml">
-                <search string="Box Amount by User">
-                    <field name="date"/>
-                    <field name="box"/>
-                    <field name="amount"/>
-                    <field name="user_id"/>
-                    <group expand="0" string="Group By...">
-                        <filter string="Box" icon="terp-dolar" context="{'group_by':'box'}"/>
-                    </group>
-                </search>
+                <tree string="alert tree">
+                    <field name="message"/>
+                    <field name="alter_type"/>
+                    <field name='active_from' widget='float_time'/>
+                    <field name='active_to' widget='float_time'/>
+                </tree>
             </field>
         </record>
 
-<!-- Lunch Amount Action -->
+        <record model="ir.ui.view" id="alert_form_view">
+            <field name="name">alert form</field>
+            <field name="model">lunch.alert</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <form string="alert tree" version="7.0">
+                    <sheet>
+                        <group string="Schedule Date">
+                            <group>
+                                <field name="alter_type"/>
+                                <field name="specific_day" attrs="{'invisible': [('alter_type','!=','specific')], 'required':[('alter_type','=','specific')]}"/>
+                            </group>
+                        </group>
+                        <group attrs="{'invisible': [('alter_type','!=','week')]}">
+                            <group>
+                                <field name="monday"/>
+                                <field name="tuesday"/>
+                                <field name="wednesday"/>
+                                <field name="thursday"/>
+                            </group>
+                            <group>
+                                <field name="friday"/>
+                                <field name="saturday"/>
+                                <field name="sunday"/>
+                            </group>
+                        </group>
+                        <group string="Schedule Hour">
+                            <field name='active_from' widget='float_time'/>
+                            <field name='active_to' widget='float_time'/>
+                        </group>
+                        <group string='Message'>
+                            <field name='message' nolabel='1' placeholder="Write the message you want to display during the defined period..."/>
+                        </group>
 
-        <record model="ir.actions.act_window" id="action_report_lunch_amount_tree">
-            <field name="name">Cash Position by User</field>
-            <field name="res_model">report.lunch.amount</field>
-            <field name="view_type">form</field>
-            <field name="view_mode">tree,form</field>
-            <field name="context">{'search_default_year': 1,"search_default_month":1}</field>
-            <field name="search_view_id" ref="view_report_lunch_amount_search"/>
+                </sheet>
+                </form>
+            </field>
         </record>
 
-        <menuitem name="Cash Position by User"
-            parent="menu_lunch_reporting_order"
-            action="action_report_lunch_amount_tree"
-            id="menu_lunch_report_amount_tree" />
-
     </data>
 </openerp>
-
-
index b1745f7..abd5b27 100644 (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:
 
index 0a13beb..1ab52a8 100644 (file)
             </para>
           </td>
           <td>
-            <para style="terp_default_9_right_bold"><u>[[ formatLang(get_total(o,objects), currency_obj = o.company_id and o.company_id.currency_id) ]]</u></para>
+            <para style="terp_default_9_right_bold"><u>[[ formatLang(get_total(o,objects)) ]] [[ (o.company_id and o.company_id.currency_id and o.company_id.currency_id.symbol) or '' ]]</u></para>
           </td>
         </tr>
       </blockTable>
               <para style="terp_default_9_left9">[[ formatLang(lines.date,date='True') ]]</para>
             </td>
             <td>
-              <para style="terp_default_9">[[ (lines.product and lines.product.name) or '' ]]</para>
+              <para style="terp_default_9">[[ (lines.product_id and lines.product_id.name) or '' ]]</para>
             </td>
             <td>
-              <para style="terp_default_9">[[ lines.descript]]</para>
+              <para style="terp_default_9">[[ lines.note]]</para>
             </td>
             <td>
-              <para style="terp_default_9_right">[[ formatLang(lines.price , currency_obj = o.company_id and o.company_id.currency_id) ]]</para>
+              <para style="terp_default_9_right">[[ lines.price ]] [[ (o.company_id and o.company_id.currency_id and o.company_id.currency_id.symbol) or '' ]]</para>
             </td>
           </tr>
         </blockTable>
           <para style="terp_tbl_detail_header">Total :</para>
         </td>
         <td>
-          <para style="terp_default_9_right_bold">[[ formatLang(get_nettotal(), currency_obj = o.company_id and o.company_id.currency_id) ]]</para>
+          <para style="terp_default_9_right_bold">[[ formatLang(get_nettotal()) ]] [[ (o.company_id and o.company_id.currency_id and o.company_id.currency_id.symbol) or '' ]]</para>
         </td>
       </tr>
     </blockTable>
index 7e2b8de..3a0875c 100644 (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()
index e920075..f7bfdcd 100644 (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>
index 72c06cc..026a43e 100644 (file)
@@ -1,8 +1,13 @@
-id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink\r
-access_lunch_order_user,lunch.order user,model_lunch_order,base.group_tool_user,1,1,1,1\r
-access_lunch_cashmove_user,lunch.cashmove user,model_lunch_cashmove,base.group_tool_user,1,1,1,1\r
-access_report_lunch_amount_manager,report.lunch.amount manager,model_report_lunch_amount,base.group_tool_manager,1,1,1,1\r
-access_lunch_category_manager,lunch.category.user,model_lunch_category,base.group_tool_user,1,1,1,1\r
-access_report_lunch_order_manager,report.lunch.order manager,model_report_lunch_order,base.group_tool_manager,1,1,1,1\r
-access_lunch_product_user,lunch.product user,model_lunch_product,base.group_tool_user,1,1,1,1\r
-access_lunch_cashbox_user,lunch.cashbox user,model_lunch_cashbox,base.group_tool_user,1,1,1,1\r
+id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
+order_user,"Order user",model_lunch_order,group_lunch_manager,1,1,1,1
+order_line_user,"Order Line user",model_lunch_order_line,group_lunch_manager,1,1,1,1
+cashmove_user,"Cashmove user",model_lunch_cashmove,group_lunch_manager,1,1,1,1
+product_user,"Product user",model_lunch_product,group_lunch_manager,1,1,1,1
+product_category_user,"Product category user",model_lunch_product_category,group_lunch_manager,1,1,1,1
+alert_user,"Alert user",model_lunch_alert,group_lunch_manager,1,1,1,1
+order_user,"Order user",model_lunch_order,group_lunch_user,1,1,1,0
+order_line_user,"Order Line user",model_lunch_order_line,group_lunch_user,1,1,1,1
+cashmove_user,"Cashmove user",model_lunch_cashmove,group_lunch_user,1,0,0,0
+product_user,"Product user",model_lunch_product,group_lunch_user,1,0,0,0
+product_category_user,"Product category user",model_lunch_product_category,group_lunch_user,1,0,0,0
+alert_user,"Alert user",model_lunch_alert,group_lunch_user,1,0,0,0
\ No newline at end of file
index 46293a9..75ab083 100644 (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>
diff --git a/addons/lunch/static/src/css/Makefile b/addons/lunch/static/src/css/Makefile
new file mode 100644 (file)
index 0000000..941e8db
--- /dev/null
@@ -0,0 +1,3 @@
+lunch.css: lunch.sass
+       sass -t expanded lunch.sass lunch.css
+
diff --git a/addons/lunch/static/src/css/lunch.css b/addons/lunch/static/src/css/lunch.css
new file mode 100644 (file)
index 0000000..96e39c5
--- /dev/null
@@ -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;
+}
diff --git a/addons/lunch/static/src/css/lunch.sass b/addons/lunch/static/src/css/lunch.sass
new file mode 100644 (file)
index 0000000..9612b5f
--- /dev/null
@@ -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
index 7493a3c..0dda33e 100644 (file)
Binary files a/addons/lunch/static/src/img/icon.png and b/addons/lunch/static/src/img/icon.png differ
diff --git a/addons/lunch/test/lunch_report.yml b/addons/lunch/test/lunch_report.yml
deleted file mode 100644 (file)
index 2043afe..0000000
+++ /dev/null
@@ -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)
diff --git a/addons/lunch/test/test_lunch.yml b/addons/lunch/test/test_lunch.yml
deleted file mode 100644 (file)
index 7cb23f5..0000000
+++ /dev/null
@@ -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
-
diff --git a/addons/lunch/tests/__init__.py b/addons/lunch/tests/__init__.py
new file mode 100644 (file)
index 0000000..1948889
--- /dev/null
@@ -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:
diff --git a/addons/lunch/tests/test_lunch.py b/addons/lunch/tests/test_lunch.py
new file mode 100644 (file)
index 0000000..128e479
--- /dev/null
@@ -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==[])
\ No newline at end of file
index e6b34c2..9af98b6 100644 (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
 #    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
diff --git a/addons/lunch/wizard/lunch_cancel.py b/addons/lunch/wizard/lunch_cancel.py
new file mode 100644 (file)
index 0000000..648ab4e
--- /dev/null
@@ -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_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)
diff --git a/addons/lunch/wizard/lunch_cancel_view.xml b/addons/lunch/wizard/lunch_cancel_view.xml
new file mode 100644 (file)
index 0000000..4df5c87
--- /dev/null
@@ -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>
\ No newline at end of file
diff --git a/addons/lunch/wizard/lunch_cashbox_clean.py b/addons/lunch/wizard/lunch_cashbox_clean.py
deleted file mode 100644 (file)
index e95d058..0000000
+++ /dev/null
@@ -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 user’s ID for security checks,
-         @param ids: List  Lunch cashbox Clean’s IDs
-         @return:Dictionary {}.
-         """
-         #TOFIX: use orm methods
-         if context is None:
-            context = {}
-         data = context and context.get('active_ids', []) or []
-         cashmove_ref = self.pool.get('lunch.cashmove')
-         cr.execute("select user_cashmove, box,sum(amount) from lunch_cashmove \
-                 where active = 't' and box IN %s group by user_cashmove, \
-                     box"  , (tuple(data),))
-         res = cr.fetchall()
-
-         cr.execute("update lunch_cashmove set active = 'f' where active= 't' \
-             and box IN %s" , (tuple(data),))
-         #TOCHECK: Why need to create duplicate entry after clean box ?
-         #for (user_id, box_id, amount) in res:
-         #   cashmove_ref.create(cr, uid, {
-         #       'name': 'Summary for user' + str(user_id),
-         #       'amount': amount,
-         #       'user_cashmove': user_id,
-         #       'box': box_id,
-         #       'active': True,
-         #   })
-         return {'type': 'ir.actions.act_window_close'}
-
-lunch_cashbox_clean()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/lunch/wizard/lunch_cashbox_clean_view.xml b/addons/lunch/wizard/lunch_cashbox_clean_view.xml
deleted file mode 100644 (file)
index 5ba2a6f..0000000
+++ /dev/null
@@ -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>
diff --git a/addons/lunch/wizard/lunch_order.py b/addons/lunch/wizard/lunch_order.py
new file mode 100644 (file)
index 0000000..20de4ad
--- /dev/null
@@ -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)
diff --git a/addons/lunch/wizard/lunch_order_cancel.py b/addons/lunch/wizard/lunch_order_cancel.py
deleted file mode 100644 (file)
index a0c8779..0000000
+++ /dev/null
@@ -1,45 +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_cancel(osv.osv_memory):
-    """
-    Cancel Lunch Order
-    """
-    _name = "lunch.order.cancel"
-    _description = "Cancel Order"
-
-    def cancel(self, cr, uid, ids, context=None):
-        """
-        Cancel cashmove entry from cashmoves and update state to draft.
-        @param cr: the current row, from the database cursor,
-        @param uid: the current user’s ID for security checks,
-        @param ids: List  Lunch Order Cancel’s IDs
-        """
-        if context is None:
-            context = {}
-        data = context and context.get('active_ids', []) or []
-        return self.pool.get('lunch.order').lunch_order_cancel(cr, uid, data, context)
-
-lunch_order_cancel()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/lunch/wizard/lunch_order_cancel_view.xml b/addons/lunch/wizard/lunch_order_cancel_view.xml
deleted file mode 100644 (file)
index 91d6a95..0000000
+++ /dev/null
@@ -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>
diff --git a/addons/lunch/wizard/lunch_order_confirm.py b/addons/lunch/wizard/lunch_order_confirm.py
deleted file mode 100644 (file)
index 2792348..0000000
+++ /dev/null
@@ -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 user’s ID for security checks,
-        @param ids: List  Lunch Order confirm’s IDs
-        @return: Dictionary {}.
-        """
-        if context is None:
-            context = {}
-        data = context and context.get('active_ids', []) or []
-        order_ref = self.pool.get('lunch.order')
-
-        for confirm_obj in self.browse(cr, uid, ids, context=context):
-            order_ref.confirm(cr, uid, data, confirm_obj.confirm_cashbox.id, context)
-            return {'type': 'ir.actions.act_window_close'}
-
-lunch_order_confirm()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/lunch/wizard/lunch_order_confirm_view.xml b/addons/lunch/wizard/lunch_order_confirm_view.xml
deleted file mode 100644 (file)
index 022d17a..0000000
+++ /dev/null
@@ -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>
diff --git a/addons/lunch/wizard/lunch_order_view.xml b/addons/lunch/wizard/lunch_order_view.xml
new file mode 100644 (file)
index 0000000..990add2
--- /dev/null
@@ -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>
diff --git a/addons/lunch/wizard/lunch_validation.py b/addons/lunch/wizard/lunch_validation.py
new file mode 100644 (file)
index 0000000..f4b4b30
--- /dev/null
@@ -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)
diff --git a/addons/lunch/wizard/lunch_validation_view.xml b/addons/lunch/wizard/lunch_validation_view.xml
new file mode 100644 (file)
index 0000000..5e9fb92
--- /dev/null
@@ -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>