summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/lunch/__manifest__.py4
-rw-r--r--addons/lunch/models/__init__.py5
-rw-r--r--addons/lunch/models/lunch_alert.py85
-rw-r--r--addons/lunch/models/lunch_cashmove.py23
-rw-r--r--addons/lunch/models/lunch_order.py (renamed from addons/lunch/models/lunch.py)156
-rw-r--r--addons/lunch/models/lunch_product.py63
-rw-r--r--addons/lunch/views/lunch_alert_views.xml134
-rw-r--r--addons/lunch/views/lunch_cashmove_views.xml165
-rw-r--r--addons/lunch/views/lunch_orders_views.xml237
-rw-r--r--addons/lunch/views/lunch_product_views.xml140
-rw-r--r--addons/lunch/views/lunch_views.xml683
11 files changed, 855 insertions, 840 deletions
diff --git a/addons/lunch/__manifest__.py b/addons/lunch/__manifest__.py
index ef5bc49a52f..e28b88a82f2 100644
--- a/addons/lunch/__manifest__.py
+++ b/addons/lunch/__manifest__.py
@@ -28,6 +28,10 @@ If you want to save your employees' time and avoid them to always have coins in
'report/lunch_order_templates.xml',
'views/lunch_templates.xml',
'wizard/lucky_order_view.xml',
+ 'views/lunch_alert_views.xml',
+ 'views/lunch_cashmove_views.xml',
+ 'views/lunch_orders_views.xml',
+ 'views/lunch_product_views.xml',
'views/lunch_views.xml',
'data/lunch_data.xml',
],
diff --git a/addons/lunch/models/__init__.py b/addons/lunch/models/__init__.py
index 9824b4ad3b0..f99750c87d0 100644
--- a/addons/lunch/models/__init__.py
+++ b/addons/lunch/models/__init__.py
@@ -1,3 +1,6 @@
# -*- coding: utf-8 -*-
-from . import lunch
+from . import lunch_alert
+from . import lunch_cashmove
+from . import lunch_order
+from . import lunch_product
diff --git a/addons/lunch/models/lunch_alert.py b/addons/lunch/models/lunch_alert.py
new file mode 100644
index 00000000000..325a64f4385
--- /dev/null
+++ b/addons/lunch/models/lunch_alert.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import datetime
+
+from odoo import api, fields, models, _
+
+
+class LunchAlert(models.Model):
+ """ Alerts to display during a lunch order. An alert can be specific to a
+ given day, weekly or daily. The alert is displayed from start to end hour. """
+ _name = 'lunch.alert'
+ _description = 'Lunch Alert'
+ _rec_name = 'message'
+
+ display = fields.Boolean(compute='_compute_display_get')
+ message = fields.Text('Message', required=True)
+ alert_type = fields.Selection([('specific', 'Specific Day'),
+ ('week', 'Every Week'),
+ ('days', 'Every Day')],
+ string='Recurrence', required=True, index=True, default='specific')
+ partner_id = fields.Many2one('res.partner', string="Vendor",
+ help="If specified, the selected vendor can be ordered only on selected days")
+ specific_day = fields.Date('Day', default=fields.Date.context_today)
+ 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')
+ start_hour = fields.Float('Between', oldname='active_from', required=True, default=7)
+ end_hour = fields.Float('And', oldname='active_to', required=True, default=23)
+ active = fields.Boolean(default=True)
+
+ @api.multi
+ def name_get(self):
+ return [(alert.id, '%s %s' % (_('Alert'), '#%d' % alert.id)) for alert in self]
+
+ @api.depends('alert_type', 'specific_day', 'monday', 'tuesday', 'thursday',
+ 'friday', 'saturday', 'sunday', 'start_hour', 'end_hour')
+ def _compute_display_get(self):
+ """
+ This method check if the alert can be displayed today
+ if alert type is specific : compare specific_day(date) with today's date
+ if alert type is week : check today is set as alert (checkbox true) eg. self['monday']
+ if alert type is day : True
+ return : Message if can_display_alert is True else False
+ """
+ days_codes = {'0': 'sunday',
+ '1': 'monday',
+ '2': 'tuesday',
+ '3': 'wednesday',
+ '4': 'thursday',
+ '5': 'friday',
+ '6': 'saturday'}
+ fullday = False
+ now = datetime.datetime.now()
+ if self.env.context.get('lunch_date'):
+ # lunch_date is a fields.Date -> 00:00:00
+ lunch_date = fields.Datetime.from_string(self.env.context['lunch_date'])
+ # if lunch_date is in the future, planned lunch, ignore hours
+ fullday = lunch_date > now
+ now = max(lunch_date, now)
+ mynow = fields.Datetime.context_timestamp(self, now)
+
+ for alert in self:
+ can_display_alert = {
+ 'specific': (str(alert.specific_day) == fields.Date.to_string(mynow)),
+ 'week': alert[days_codes[mynow.strftime('%w')]],
+ 'days': True
+ }
+
+ if can_display_alert[alert.alert_type]:
+ hour_to = int(alert.end_hour)
+ min_to = int((alert.end_hour - hour_to) * 60)
+ to_alert = datetime.time(hour_to, min_to)
+ hour_from = int(alert.start_hour)
+ min_from = int((alert.start_hour - hour_from) * 60)
+ from_alert = datetime.time(hour_from, min_from)
+
+ if fullday or (from_alert <= mynow.time() <= to_alert):
+ alert.display = True
+ else:
+ alert.display = False
diff --git a/addons/lunch/models/lunch_cashmove.py b/addons/lunch/models/lunch_cashmove.py
new file mode 100644
index 00000000000..7d4a6b56ae4
--- /dev/null
+++ b/addons/lunch/models/lunch_cashmove.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, fields, models, _
+
+
+class LunchCashMove(models.Model):
+ """ Two types of cashmoves: payment (credit) or order (debit) """
+ _name = 'lunch.cashmove'
+ _description = 'Lunch Cashmove'
+
+ user_id = fields.Many2one('res.users', 'User',
+ default=lambda self: self.env.uid)
+ date = fields.Date('Date', required=True, default=fields.Date.context_today)
+ amount = fields.Float('Amount', required=True, help='Can be positive (payment) or negative (order or payment if user wants to get his money back)')
+ description = fields.Text('Description', help='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', default='payment')
+
+ @api.multi
+ def name_get(self):
+ return [(cashmove.id, '%s %s' % (_('Lunch Cashmove'), '#%d' % cashmove.id)) for cashmove in self]
diff --git a/addons/lunch/models/lunch.py b/addons/lunch/models/lunch_order.py
index 19aad72ef22..f4354913db8 100644
--- a/addons/lunch/models/lunch.py
+++ b/addons/lunch/models/lunch_order.py
@@ -4,12 +4,10 @@
from collections import OrderedDict
import json
-import datetime
from odoo import api, fields, models, _
from odoo.exceptions import AccessError, ValidationError
from odoo.addons import decimal_precision as dp
-from odoo.osv import expression
class LunchOrder(models.Model):
@@ -315,157 +313,3 @@ class LunchOrderLine(models.Model):
self.cashmove.unlink()
else:
raise AccessError(_("Only your lunch manager cancels the orders."))
-
-
-class LunchProduct(models.Model):
- """ Products available to order. A product is linked to a specific vendor. """
- _name = 'lunch.product'
- _description = 'Lunch Product'
-
- name = fields.Char('Product', required=True)
- category_id = fields.Many2one('lunch.product.category', 'Product Category', required=True)
- description = fields.Text('Description')
- price = fields.Float('Price', digits=dp.get_precision('Account'))
- supplier = fields.Many2one('res.partner', 'Vendor')
- active = fields.Boolean(default=True)
- available = fields.Boolean(compute='_get_available_product', search='_search_available_products')
-
- @api.depends('supplier')
- def _get_available_product(self):
- for product in self:
- if not product.supplier:
- product.available = True
- else:
- alerts = self.env['lunch.alert'].search([
- ('partner_id', '=', self.supplier.id)
- ])
- if alerts and not any(alert.display for alert in alerts):
- # every alert is not available
- product.available = False
- else:
- # no alert for the supplier or at least one is not available
- product.available = True
-
- def _search_available_products(self, operator, value):
- alerts = self.env['lunch.alert'].search([])
- supplier_w_alerts = alerts.mapped('partner_id')
- available_suppliers = alerts.filtered(lambda a: a.display).mapped('partner_id')
- available_products = self.search([
- '|',
- ('supplier', 'not in', supplier_w_alerts.ids),
- ('supplier', 'in', available_suppliers.ids)
- ])
-
- if (operator in expression.NEGATIVE_TERM_OPERATORS and value) or \
- (operator not in expression.NEGATIVE_TERM_OPERATORS and not value):
- # e.g. (available = False) or (available != True)
- return [('id', 'not in', available_products.ids)]
- else:
- # e.g. (available = True) or (available != False)
- return [('id', 'in', available_products.ids)]
-
-
-class LunchProductCategory(models.Model):
- """ Category of the product such as pizza, sandwich, pasta, chinese, burger... """
- _name = 'lunch.product.category'
- _description = 'Lunch Product Category'
-
- name = fields.Char('Product Category', required=True)
-
-
-class LunchCashMove(models.Model):
- """ Two types of cashmoves: payment (credit) or order (debit) """
- _name = 'lunch.cashmove'
- _description = 'Lunch Cashmove'
-
- user_id = fields.Many2one('res.users', 'User',
- default=lambda self: self.env.uid)
- date = fields.Date('Date', required=True, default=fields.Date.context_today)
- amount = fields.Float('Amount', required=True, help='Can be positive (payment) or negative (order or payment if user wants to get his money back)')
- description = fields.Text('Description', help='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', default='payment')
-
- @api.multi
- def name_get(self):
- return [(cashmove.id, '%s %s' % (_('Lunch Cashmove'), '#%d' % cashmove.id)) for cashmove in self]
-
-
-class LunchAlert(models.Model):
- """ Alerts to display during a lunch order. An alert can be specific to a
- given day, weekly or daily. The alert is displayed from start to end hour. """
- _name = 'lunch.alert'
- _description = 'Lunch Alert'
- _rec_name = 'message'
-
- display = fields.Boolean(compute='_compute_display_get')
- message = fields.Text('Message', required=True)
- alert_type = fields.Selection([('specific', 'Specific Day'),
- ('week', 'Every Week'),
- ('days', 'Every Day')],
- string='Recurrence', required=True, index=True, default='specific')
- partner_id = fields.Many2one('res.partner', string="Vendor",
- help="If specified, the selected vendor can be ordered only on selected days")
- specific_day = fields.Date('Day', default=fields.Date.context_today)
- 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')
- start_hour = fields.Float('Between', oldname='active_from', required=True, default=7)
- end_hour = fields.Float('And', oldname='active_to', required=True, default=23)
- active = fields.Boolean(default=True)
-
- @api.multi
- def name_get(self):
- return [(alert.id, '%s %s' % (_('Alert'), '#%d' % alert.id)) for alert in self]
-
- @api.depends('alert_type', 'specific_day', 'monday', 'tuesday', 'thursday',
- 'friday', 'saturday', 'sunday', 'start_hour', 'end_hour')
- def _compute_display_get(self):
- """
- This method check if the alert can be displayed today
- if alert type is specific : compare specific_day(date) with today's date
- if alert type is week : check today is set as alert (checkbox true) eg. self['monday']
- if alert type is day : True
- return : Message if can_display_alert is True else False
- """
- days_codes = {'0': 'sunday',
- '1': 'monday',
- '2': 'tuesday',
- '3': 'wednesday',
- '4': 'thursday',
- '5': 'friday',
- '6': 'saturday'}
- fullday = False
- now = datetime.datetime.now()
- if self.env.context.get('lunch_date'):
- # lunch_date is a fields.Date -> 00:00:00
- lunch_date = fields.Datetime.from_string(self.env.context['lunch_date'])
- # if lunch_date is in the future, planned lunch, ignore hours
- fullday = lunch_date > now
- now = max(lunch_date, now)
- mynow = fields.Datetime.context_timestamp(self, now)
-
- for alert in self:
- can_display_alert = {
- 'specific': (str(alert.specific_day) == fields.Date.to_string(mynow)),
- 'week': alert[days_codes[mynow.strftime('%w')]],
- 'days': True
- }
-
- if can_display_alert[alert.alert_type]:
- hour_to = int(alert.end_hour)
- min_to = int((alert.end_hour - hour_to) * 60)
- to_alert = datetime.time(hour_to, min_to)
- hour_from = int(alert.start_hour)
- min_from = int((alert.start_hour - hour_from) * 60)
- from_alert = datetime.time(hour_from, min_from)
-
- if fullday or (from_alert <= mynow.time() <= to_alert):
- alert.display = True
- else:
- alert.display = False
diff --git a/addons/lunch/models/lunch_product.py b/addons/lunch/models/lunch_product.py
new file mode 100644
index 00000000000..8ded108fc81
--- /dev/null
+++ b/addons/lunch/models/lunch_product.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, fields, models, _
+
+from odoo.addons import decimal_precision as dp
+from odoo.osv import expression
+
+
+class LunchProductCategory(models.Model):
+ """ Category of the product such as pizza, sandwich, pasta, chinese, burger... """
+ _name = 'lunch.product.category'
+ _description = 'Lunch Product Category'
+
+ name = fields.Char('Product Category', required=True)
+
+
+class LunchProduct(models.Model):
+ """ Products available to order. A product is linked to a specific vendor. """
+ _name = 'lunch.product'
+ _description = 'Lunch Product'
+
+ name = fields.Char('Product', required=True)
+ category_id = fields.Many2one('lunch.product.category', 'Product Category', required=True)
+ description = fields.Text('Description')
+ price = fields.Float('Price', digits=dp.get_precision('Account'))
+ supplier = fields.Many2one('res.partner', 'Vendor')
+ active = fields.Boolean(default=True)
+ available = fields.Boolean(compute='_get_available_product', search='_search_available_products')
+
+ @api.depends('supplier')
+ def _get_available_product(self):
+ for product in self:
+ if not product.supplier:
+ product.available = True
+ else:
+ alerts = self.env['lunch.alert'].search([
+ ('partner_id', '=', self.supplier.id)
+ ])
+ if alerts and not any(alert.display for alert in alerts):
+ # every alert is not available
+ product.available = False
+ else:
+ # no alert for the supplier or at least one is not available
+ product.available = True
+
+ def _search_available_products(self, operator, value):
+ alerts = self.env['lunch.alert'].search([])
+ supplier_w_alerts = alerts.mapped('partner_id')
+ available_suppliers = alerts.filtered(lambda a: a.display).mapped('partner_id')
+ available_products = self.search([
+ '|',
+ ('supplier', 'not in', supplier_w_alerts.ids),
+ ('supplier', 'in', available_suppliers.ids)
+ ])
+
+ if (operator in expression.NEGATIVE_TERM_OPERATORS and value) or \
+ (operator not in expression.NEGATIVE_TERM_OPERATORS and not value):
+ # e.g. (available = False) or (available != True)
+ return [('id', 'not in', available_products.ids)]
+ else:
+ # e.g. (available = True) or (available != False)
+ return [('id', 'in', available_products.ids)]
diff --git a/addons/lunch/views/lunch_alert_views.xml b/addons/lunch/views/lunch_alert_views.xml
new file mode 100644
index 00000000000..bb6d807a9ff
--- /dev/null
+++ b/addons/lunch/views/lunch_alert_views.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="lunch_alert_view_search" model="ir.ui.view">
+ <field name="name">lunch.alert.search</field>
+ <field name="model">lunch.alert</field>
+ <field name="arch" type="xml">
+ <search string="Search">
+ <field name="message"/>
+ <filter name="inactive" string="Archived" domain="[('active','=',False)]"/>
+ </search>
+ </field>
+ </record>
+
+ <record id="lunch_alert_view_tree" model="ir.ui.view">
+ <field name="name">lunch.alert.tree</field>
+ <field name="model">lunch.alert</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="message"/>
+ <field name="alert_type"/>
+ <field name='start_hour' widget='float_time'/>
+ <field name='end_hour' widget='float_time'/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="lunch_alert_view_form" model="ir.ui.view">
+ <field name="name">lunch.alert.form</field>
+ <field name="model">lunch.alert</field>
+ <field name="arch" type="xml">
+ <form>
+ <sheet>
+ <div class="oe_button_box" name="button_box">
+ <button name="toggle_active" type="object"
+ class="oe_stat_button" icon="fa-archive">
+ <field name="active" widget="boolean_button"
+ options='{"terminology": "archive"}'/>
+ </button>
+ </div>
+ <group>
+ <group name="schedule" string="Schedule">
+ <group colspan="4">
+ <field name="alert_type"/>
+ <field name="specific_day"
+ attrs="{'invisible': [('alert_type','!=','specific')], 'required':[('alert_type','=','specific')]}"/>
+ <field name='start_hour' widget='float_time' />
+ <field name='end_hour' widget='float_time' />
+ </group>
+ <group name="weekdays" col="4" attrs="{'invisible': [('alert_type','!=','week')]}">
+ <field name="monday"/>
+ <field name="tuesday"/>
+ <field name="wednesday"/>
+ <field name="thursday"/>
+ <field name="friday"/>
+ <field name="saturday"/>
+ <field name="sunday"/>
+ </group>
+ </group>
+ <group name="vendor" string="Vendor">
+ <group name="partner" colspan="4">
+ <field name="partner_id"/>
+ <field name="display" invisible="True"/>
+ </group>
+ <div class="oe_grey" colspan="4"
+ attrs="{'invisible': ['|', ('partner_id', '=', False), ('display', '=', True)]}">
+ Products from this vendor can <strong>not</strong> be ordered at that moment.
+ </div>
+ <div class="oe_grey" colspan="4"
+ attrs="{'invisible': ['|', ('partner_id', '=', False), ('display', '=', False)]}">
+ Products from this vendor can be ordered at that moment.
+ </div>
+ </group>
+ </group>
+ <group string='Message'>
+ <field name='message' nolabel='1' placeholder="Write the message you want to display during the defined period..."/>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="view_lunch_alert_kanban" model="ir.ui.view">
+ <field name="name">lunch.alert.kanban</field>
+ <field name="model">lunch.alert</field>
+ <field name="arch" type="xml">
+ <kanban class="o_kanban_mobile">
+ <field name="message"/>
+ <field name="alert_type"/>
+ <field name='start_hour'/>
+ <field name='end_hour'/>
+ <templates>
+ <t t-name="kanban-box">
+ <div t-attf-class="oe_kanban_global_click">
+ <div class="o_kanban_record_top">
+ <strong class="o_kanban_record_title"><t t-esc="record.message.value"/></strong>
+ </div>
+ <div class="row mb4">
+ <div class="col-6">
+ Between: <t t-esc="record.start_hour.value"/> -
+ <t t-esc="record.end_hour.value"/>
+ </div>
+ <div class="col-6">
+ <span class="badge badge-pill float-right">
+ <t t-esc="record.alert_type.value"/>
+ </span>
+ </div>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+
+ <record id="lunch_alert_action" model="ir.actions.act_window">
+ <field name="name">Alerts</field>
+ <field name="res_model">lunch.alert</field>
+ <field name="view_mode">tree,kanban,form</field>
+ <field name="search_view_id" ref="lunch_alert_view_search"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Create a new 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 recurrence, 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>
+</odoo>
diff --git a/addons/lunch/views/lunch_cashmove_views.xml b/addons/lunch/views/lunch_cashmove_views.xml
new file mode 100644
index 00000000000..b714205587a
--- /dev/null
+++ b/addons/lunch/views/lunch_cashmove_views.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="lunch_cashmove_view_search" model="ir.ui.view">
+ <field name='name'>lunch.cashmove.search</field>
+ <field name='model'>lunch.cashmove</field>
+ <field name='arch' type='xml'>
+ <search string="lunch employee payment">
+ <field name="description"/>
+ <field name="user_id"/>
+ <filter name='is_payment' string="Payment" domain="[('state','=','payment')]"/>
+ <separator/>
+ <filter name='is_mine_group' string="My Account grouped" domain="[('user_id','=',uid)]" context="{'group_by':'user_id'}"/>
+ <filter name="group_by_user" string="By User" context="{'group_by':'user_id'}"/>
+ </search>
+ </field>
+ </record>
+
+ <record id="lunch_cashmove_view_search_2" model="ir.ui.view">
+ <field name='name'>lunch.cashmove.search</field>
+ <field name='model'>lunch.cashmove</field>
+ <field name='arch' type='xml'>
+ <search string="lunch cashmove">
+ <field name="description"/>
+ <field name="user_id"/>
+ <group expand="0" string="Group By">
+ <filter name='group_by_user' string="By Employee" context="{'group_by':'user_id'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record id="lunch_cashmove_view_tree" model="ir.ui.view">
+ <field name="name">lunch.cashmove.tree</field>
+ <field name="model">lunch.cashmove</field>
+ <field name="arch" type="xml">
+ <tree string="cashmove tree">
+ <field name="date"/>
+ <field name="user_id"/>
+ <field name="description"/>
+ <field name="amount" sum="Total"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="lunch_cashmove_view_tree_2" model="ir.ui.view">
+ <field name="name">lunch.cashmove.tree</field>
+ <field name="model">lunch.cashmove</field>
+ <field name="arch" type="xml">
+ <tree string="cashmove tree" create='false'>
+ <field name="date"/>
+ <field name="description"/>
+ <field name="amount" sum="Total"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="lunch_cashmove_view_form" model="ir.ui.view">
+ <field name="name">lunch.cashmove.form</field>
+ <field name="model">lunch.cashmove</field>
+ <field name="arch" type="xml">
+ <form string="cashmove form">
+ <sheet>
+ <group>
+ <field name="user_id" required="1"/>
+ <field name="date"/>
+ <field name="amount"/>
+ </group>
+ <label for='description'/>
+ <field name="description"/>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="view_lunch_cashmove_kanban" model="ir.ui.view">
+ <field name="name">lunch.cashmove.kanban</field>
+ <field name="model">lunch.cashmove</field>
+ <field name="arch" type="xml">
+ <kanban class="o_kanban_mobile">
+ <field name="date"/>
+ <field name="user_id"/>
+ <field name="description"/>
+ <field name="amount"/>
+ <templates>
+ <t t-name="kanban-box">
+ <div t-attf-class="oe_kanban_global_click">
+ <div class="row mb4">
+ <div class="col-8">
+ <span>
+ <strong class="o_kanban_record_title"><t t-esc="record.description.value"/></strong>
+ </span>
+ </div>
+ <div class="col-4 text-right">
+ <span class="badge badge-pill">
+ <strong><i class="fa fa-money" role="img" aria-label="Amount" title="Amount"/> <field name="amount"/></strong>
+ </span>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-6">
+ <i class="fa fa-clock-o" role="img" aria-label="Date" title="Date"/>
+ <t t-esc="record.date.value"/>
+ </div>
+ <div class="col-6">
+ <img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" t-att-alt="record.user_id.value" width="24" height="24" class="oe_kanban_avatar float-right"/>
+ </div>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+
+ <record id="lunch_cashmove_action_account" model="ir.actions.act_window">
+ <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="lunch_cashmove_view_search"/>
+ <field name="context">{"search_default_is_mine_group":1}</field>
+ <field name="view_id" ref="lunch_cashmove_view_tree_2"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ No cash move yet
+ </p><p>
+ Here you can see your cash moves.<br/>A cash move can either be 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>
+
+ <record id="lunch_cashmove_action_control_accounts" model="ir.actions.act_window">
+ <field name="name">Control Accounts</field>
+ <field name="res_model">lunch.cashmove</field>
+ <field name="view_mode">tree,kanban,form</field>
+ <field name="search_view_id" ref="lunch_cashmove_view_search_2"/>
+ <field name="context">{"search_default_group_by_user":1}</field>
+ <field name="view_id" ref="lunch_cashmove_view_tree"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ 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>
+
+ <record id="lunch_cashmove_action_payment" model="ir.actions.act_window">
+ <field name="name">Register Cash Moves</field>
+ <field name="res_model">lunch.cashmove</field>
+ <field name="view_mode">tree,kanban,form</field>
+ <field name="search_view_id" ref="lunch_cashmove_view_search"/>
+ <field name="context">{"search_default_is_payment":1}</field>
+ <field name="view_id" ref="lunch_cashmove_view_tree"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Register a payment
+ </p><p>
+ Payments are used to register liquidity movements. You can process those payments by your own means or by using installed facilities.
+ </p>
+ </field>
+ </record>
+</odoo>
diff --git a/addons/lunch/views/lunch_orders_views.xml b/addons/lunch/views/lunch_orders_views.xml
new file mode 100644
index 00000000000..8cd4658a8cb
--- /dev/null
+++ b/addons/lunch/views/lunch_orders_views.xml
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="lunch_order_view_tree" model="ir.ui.view">
+ <field name="name">lunch.order.tree</field>
+ <field name="model">lunch.order</field>
+ <field name="arch" type="xml">
+ <tree string="Orders Tree">
+ <field name="date"/>
+ <field name="order_line_ids"/>
+ <field name="state"/>
+ <field name="total" sum="Total"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="lunch_order_view_form" model="ir.ui.view">
+ <field name="name">lunch.order.form</field>
+ <field name="model">lunch.order</field>
+ <field name="arch" type="xml">
+ <form string='Orders Form' class="o_lunch">
+ <header>
+ <button name="%(action_lunch_order_line_lucky)d" type="action" string="Feeling Lucky" class="oe_highlight"/>
+ <field name='state' widget='statusbar' statusbar_visible='new,confirmed'/>
+ </header>
+ <sheet>
+ <field name="balance_visible" invisible="1"/>
+
+ <div class="oe_button_box" name="button_box">
+ <button class="oe_stat_button"
+ attrs="{'invisible': [('balance_visible', '=', False)]}"
+ name="%(lunch_cashmove_action_account)d"
+ icon="fa-money"
+ type="action">
+ <div class="o_field_widget o_stat_info">
+ <span class="o_stat_value"><field name="cash_move_balance" widget="monetary"/></span>
+ <span class="o_stat_text">Balance</span>
+ </div>
+ </button>
+ </div>
+
+ <group>
+ <group>
+ <field name='user_id' class="oe_inline" required='1'/>
+ <field name='date'/>
+ </group>
+ <div>
+ <div attrs="{'invisible': ['|',('state','!=','new'),('alerts','=',False)]}" class="alert alert-danger oe_edit_only" role="alert">
+ <field name='alerts'/>
+ </div>
+ </div>
+ </group>
+
+ <div>
+ <field name='previous_order_widget' widget='previous_order' class='o_lunch_last_orders'/>
+ </div>
+
+ <separator string='Select your order'/>
+ <field name='order_line_ids'>
+ <tree string='List' editable='bottom'>
+ <field name='product_id' context="{'lunch_date': parent.date}"/>
+ <field name='note' />
+ <field name='price'/>
+ <field name='supplier' invisible="1"/>
+ <field name="state" invisible="1"/>
+ </tree>
+ <form string='Lunch Order Form'>
+ <group>
+ <field name='product_id' context="{'lunch_date': parent.date}"/>
+ <field name='note' />
+ <field name='price'/>
+ </group>
+ </form>
+ </field>
+ <group class='oe_subtotal_footer oe_right'>
+ <field name='total' widget='monetary' options="{'currency_field': 'currency_id'}"/>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="lunch_order_line_view_search" model="ir.ui.view">
+ <field name="name">lunch.order.line.search</field>
+ <field name="model">lunch.order.line</field>
+ <field name="arch" type="xml">
+ <search string="Search">
+ <filter name='is_mine' string="My Orders" domain="[('user_id','=',uid)]"/>
+ <separator/>
+ <field name="name" string="Product" filter_domain="['|', ('name', 'ilike', self), ('note', 'ilike', self)]"/>
+ <filter name="not_confirmed" string="Not Received" domain="[('state','!=',('confirmed'))]"/>
+ <filter name="confirmed" string="Received" domain="[('state','=','confirmed')]"/>
+ <filter name="cancelled" string="Cancelled" domain="[('state','=','cancelled')]"/>
+ <separator/>
+ <filter name="date_filter" string="Date" date="date" default_period="today"/>
+ <field name="user_id"/>
+ <group expand="0" string="Group By">
+ <filter name="group_by_order_id" string="By Order" context="{'group_by':'order_id'}"/>
+ <filter name="group_by_supplier" string="By Vendor" context="{'group_by':'supplier'}"/>
+ <filter name="group_by_date" string="Order Date" context="{'group_by':'date'}" help="Vendor Orders by Date"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record id="lunch_order_line_view_tree" model="ir.ui.view">
+ <field name="name">lunch.order.line.tree</field>
+ <field name="model">lunch.order.line</field>
+ <field name="arch" type="xml">
+ <tree string="Order lines Tree" create="false" edit="false">
+ <field name='date'/>
+ <field name='supplier' invisible='1'/>
+ <field name='product_id'/>
+ <field name='note'/>
+ <field name='state'/>
+ <field name='user_id'/>
+ <field name='price' sum="Total" string="Price"/>
+ <button name="order" string="Order" type="object" icon="fa-phone text-success" attrs="{'invisible': ['|',('state','=','confirmed'),('state','=','ordered')]}" groups="lunch.group_lunch_manager"/>
+ <button name="confirm" string="Receive" type="object" icon="fa-check text-success" attrs="{'invisible': [('state','!=','ordered')]}" groups="lunch.group_lunch_manager"/>
+ <button name="cancel" string="Cancel" type="object" icon="fa-times-circle text-danger" attrs="{'invisible': [('state','=','cancelled')]}" groups="lunch.group_lunch_manager"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id='lunch_order_line_view_kanban' model='ir.ui.view'>
+ <field name="name">lunch.order.line.kanban</field>
+ <field name="model">lunch.order.line</field>
+ <field name="arch" type="xml">
+ <kanban>
+ <field name='product_id'/>
+ <field name='note'/>
+ <field name='state'/>
+ <field name='user_id'/>
+ <field name='date'/>
+ <field name="price"/>
+ <templates>
+ <t t-name="kanban-box">
+ <div class="oe_kanban_global_click">
+ <div class="o_kanban_record_top">
+ <div class="o_kanban_record_headings">
+ <strong class="o_kanban_record_title"><field name="product_id"/></strong>
+ </div>
+ <field name="state" widget="kanban_label_selection" options="{'classes': {'new': 'default', 'confirmed': 'success', 'cancelled':'danger'}}"/>
+ </div>
+ <div>
+ <field name="note"/>
+ </div>
+ <div class="row">
+ <div class="col-6">
+ <i class="fa fa-money" role="img" aria-label="Money" title="Money"/> <field name="price"/>
+ </div>
+ <div class="col-6 text-right">
+ <i class="fa fa-clock-o" role="img" aria-label="Date" title="Date"/> <field name="date"/>
+ </div>
+ </div>
+ <div class="row mt4">
+ <div class="col-6">
+ <a class="btn btn-sm btn-success" role="button" name="order" string="Order" type="object" attrs="{'invisible': ['|',('state','=','confirmed'),('state','=','ordered')]}" groups="lunch.group_lunch_manager">
+ <i class="fa fa-phone" role="img" aria-label="Order button" title="Order button"/>
+ </a>
+ <a class="btn btn-sm btn-info" role="button" name="confirm" string="Receive" type="object" attrs="{'invisible': [('state','!=','ordered')]}" groups="lunch.group_lunch_manager">
+ <i class="fa fa-check" role="img" aria-label="Receive button" title="Receive button"/>
+ </a>
+ <a class="btn btn-sm btn-danger" role="button" name="cancel" string="Cancel" type="object" attrs="{'invisible': [('state','=','cancelled')]}" groups="lunch.group_lunch_manager">
+ <i class="fa fa-times" role="img" aria-label="Cancel button" title="Cancel button"/>
+ </a>
+ </div>
+ <div class="col-6">
+ <img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" t-att-alt="record.user_id.value" width="24" height="24" class="oe_kanban_avatar float-right"/>
+ </div>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+
+ <record id="lunch_order_action_form" model="ir.actions.act_window">
+ <field name="name">New Order</field>
+ <field name="res_model">lunch.order</field>
+ <field name="view_mode">form</field>
+ </record>
+
+ <record id="lunch_order_line_action" model="ir.actions.act_window">
+ <field name="name">Your Orders</field>
+ <field name="res_model">lunch.order.line</field>
+ <field name="view_mode">tree,kanban,form</field>
+ <field name="search_view_id" ref="lunch_order_line_view_search"/>
+ <field name="context">{"search_default_is_mine":1}</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ No previous order found
+ </p><p>
+ There is no previous order recorded. Click on "My Lunch" and then create a new lunch order.
+ </p>
+ </field>
+ </record>
+
+ <record id="lunch_order_line_action_by_supplier" model="ir.actions.act_window">
+ <field name="name">Orders by Vendor</field>
+ <field name="res_model">lunch.order.line</field>
+ <field name="view_mode">tree,kanban</field>
+ <field name="search_view_id" ref="lunch_order_line_view_search"/>
+ <field name="context">{"search_default_group_by_supplier":1, "search_default_date_filter":1}</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ Nothing to order today
+ </p><p>
+ Here you can see today's orders grouped by vendors.
+ </p><p>
+ Click on the <span class="fa fa-phone text-success" role="img" aria-label="Order button" title="Order button"/> to announce that the order is ordered.<br/>
+ Click on the <span class="fa fa-check text-success" role="img" aria-label="Receive button" title="Receive button"/> to announce that the order is received.<br/>
+ Click on the <span class="fa fa-times-circle text-danger" role="img" aria-label="Cancel button" title="Cancel button"/> to announce that the order isn't available.
+ </p>
+ </field>
+ </record>
+
+ <record id="lunch_order_line_action_control_suppliers" model="ir.actions.act_window">
+ <field name="name">Control Vendors</field>
+ <field name="res_model">lunch.order.line</field>
+ <field name="view_mode">tree,kanban</field>
+ <field name="search_view_id" ref="lunch_order_line_view_search"/>
+ <field name="context">{"search_default_group_by_date":1, "search_default_group_by_supplier":1}</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ No lunch order yet
+ </p><p>
+ Summary of all lunch orders, grouped by vendor and by date.
+ </p><p>
+ Click on the <span class="fa fa-phone text-success" role="img" aria-label="Order button" title="Order button"/> to announce that the order is ordered.<br/>
+ Click on the <span class="fa fa-check text-success" role="img" aria-label="Receive button" title="Receive button"/> to announce that the order is received.<br/>
+ Click on the <span class="fa fa-times-circle text-danger" role="img" aria-label="Cancel button" title="Cancel button"/> red X to announce that the order isn't available.
+ </p>
+ </field>
+ </record>
+
+</odoo>
diff --git a/addons/lunch/views/lunch_product_views.xml b/addons/lunch/views/lunch_product_views.xml
new file mode 100644
index 00000000000..e7647207d6d
--- /dev/null
+++ b/addons/lunch/views/lunch_product_views.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="lunch_product_view_search" model="ir.ui.view">
+ <field name="name">lunch.product.search</field>
+ <field name="model">lunch.product</field>
+ <field name="arch" type="xml">
+ <search string="Product Search">
+ <field name="name"/>
+ <field name="category_id"/>
+ <field name="supplier"/>
+ <field name="description"/>
+ <group expand="0" string="Group By">
+ <filter name="supplier" string="Vendor" context="{'group_by': 'supplier'}"/>
+ <filter name="category" string="Product Category" context="{'group_by': 'category_id'}"/>
+ <filter name="inactive" string="Archived" domain="[('active','=',False)]"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record id="lunch_product_view_tree" model="ir.ui.view">
+ <field name="name">lunch.product.tree</field>
+ <field name="model">lunch.product</field>
+ <field name="arch" type="xml">
+ <tree string="Products Tree">
+ <field name="name"/>
+ <field name="category_id"/>
+ <field name="supplier"/>
+ <field name="description"/>
+ <field name="price"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="lunch_product_view_form" model="ir.ui.view">
+ <field name="name">lunch.product.form</field>
+ <field name="model">lunch.product</field>
+ <field name="arch" type="xml">
+ <form string="Products Form">
+ <header>
+ </header>
+ <sheet>
+ <div class="oe_button_box" name="button_box">
+ <button name="toggle_active" type="object"
+ class="oe_stat_button" icon="fa-archive">
+ <field name="active" widget="boolean_button"
+ options='{"terminology": "archive"}'/>
+ </button>
+ </div>
+ <group>
+ <group>
+ <field name='name'/>
+ <field name='category_id'/>
+ </group>
+ <group>
+ <field name='supplier'/>
+ <field name='price'/>
+ </group>
+ </group>
+ <label for='description'/>
+ <field name='description'/>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="view_lunch_product_kanban" model="ir.ui.view">
+ <field name="name">lunch.product.kanban</field>
+ <field name="model">lunch.product</field>
+ <field name="arch" type="xml">
+ <kanban class="o_kanban_mobile">
+ <field name="name"/>
+ <field name="category_id"/>
+ <field name="supplier"/>
+ <field name="description"/>
+ <field name="price"/>
+ <templates>
+ <t t-name="kanban-box">
+ <div t-attf-class="oe_kanban_global_click">
+ <div class="o_kanban_record_top">
+ <div class="o_kanban_record_headings">
+ <strong class="o_kanban_record_title"><t t-esc="record.name.value"/></strong>
+ </div>
+ <span class="badge badge-pill float-right">
+ Price: <t t-esc="record.price.value"/>
+ </span>
+ </div>
+ <div>
+ <t t-esc="record.supplier.value"/>
+ </div>
+ <div>
+ <t t-esc="record.description.value"/>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+
+ <record id="lunch_product_category_view_form" model="ir.ui.view">
+ <field name="name">Product category Form</field>
+ <field name="model">lunch.product.category</field>
+ <field name="arch" type="xml">
+ <form string="Products Form">
+ <sheet>
+ <group>
+ <field name='name' string="Product Category: "/>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="lunch_product_action" model="ir.actions.act_window">
+ <field name="name">Products</field>
+ <field name="res_model">lunch.product</field>
+ <field name="view_mode">tree,kanban,form</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Create a new product for lunch
+ </p><p>
+ A product is defined by its name, category, price and vendor.
+ </p>
+ </field>
+ </record>
+
+ <record id="lunch_product_category_action" model="ir.actions.act_window">
+ <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="o_view_nocontent_smiling_face">
+ Create a new lunch category
+ </p><p>
+ Here you can access all categories for the lunch products.
+ </p>
+ </field>
+ </record>
+</odoo>
diff --git a/addons/lunch/views/lunch_views.xml b/addons/lunch/views/lunch_views.xml
index bdb16983772..454085fb92b 100644
--- a/addons/lunch/views/lunch_views.xml
+++ b/addons/lunch/views/lunch_views.xml
@@ -6,549 +6,19 @@
<menuitem name="Manager" parent="menu_lunch" id="menu_lunch_admin" sequence="51" 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 id="lunch_order_line_view_search" model="ir.ui.view">
- <field name="name">lunch.order.line.search</field>
- <field name="model">lunch.order.line</field>
- <field name="arch" type="xml">
- <search string="Search">
- <filter name='is_mine' string="My Orders" domain="[('user_id','=',uid)]"/>
- <separator/>
- <field name="name" string="Product" filter_domain="['|', ('name', 'ilike', self), ('note', 'ilike', self)]"/>
- <filter name="not_confirmed" string="Not Received" domain="[('state','!=',('confirmed'))]"/>
- <filter name="confirmed" string="Received" domain="[('state','=','confirmed')]"/>
- <filter name="cancelled" string="Cancelled" domain="[('state','=','cancelled')]"/>
- <separator/>
- <filter name="date_filter" string="Date" date="date" default_period="today"/>
- <field name="user_id"/>
- <group expand="0" string="Group By">
- <filter name="group_by_order_id" string="By Order" context="{'group_by':'order_id'}"/>
- <filter name="group_by_supplier" string="By Vendor" context="{'group_by':'supplier'}"/>
- <filter name="group_by_date" string="Order Date" context="{'group_by':'date'}" help="Vendor Orders by Date"/>
- </group>
- </search>
- </field>
- </record>
-
- <!--View Search to group by employee and input/output (cashmoves)-->
- <record id="lunch_cashmove_view_search" model="ir.ui.view">
- <field name='name'>lunch.cashmove.search</field>
- <field name='model'>lunch.cashmove</field>
- <field name='arch' type='xml'>
- <search string="lunch employee payment">
- <field name="description"/>
- <field name="user_id"/>
- <filter name='is_payment' string="Payment" domain="[('state','=','payment')]"/>
- <separator/>
- <filter name='is_mine_group' string="My Account grouped" domain="[('user_id','=',uid)]" context="{'group_by':'user_id'}"/>
- <filter name="group_by_user" string="By User" context="{'group_by':'user_id'}"/>
- </search>
- </field>
- </record>
-
- <record id="lunch_cashmove_view_search_2" model="ir.ui.view">
- <field name='name'>lunch.cashmove.search</field>
- <field name='model'>lunch.cashmove</field>
- <field name='arch' type='xml'>
- <search string="lunch cashmove">
- <field name="description"/>
- <field name="user_id"/>
- <group expand="0" string="Group By">
- <filter name='group_by_user' string="By Employee" context="{'group_by':'user_id'}"/>
- </group>
- </search>
- </field>
- </record>
-
- <record id="lunch_alert_view_search" model="ir.ui.view">
- <field name="name">lunch.alert.search</field>
- <field name="model">lunch.alert</field>
- <field name="arch" type="xml">
- <search string="Search">
- <field name="message"/>
- <filter name="inactive" string="Archived" domain="[('active','=',False)]"/>
- </search>
- </field>
- </record>
-
- <!--view for cashmove-->
- <record id="lunch_cashmove_view_tree" model="ir.ui.view">
- <field name="name">lunch.cashmove.tree</field>
- <field name="model">lunch.cashmove</field>
- <field name="arch" type="xml">
- <tree string="cashmove tree">
- <field name="date"/>
- <field name="user_id"/>
- <field name="description"/>
- <field name="amount" sum="Total"/>
- </tree>
- </field>
- </record>
-
- <record id="view_lunch_cashmove_kanban" model="ir.ui.view">
- <field name="name">lunch.cashmove.kanban</field>
- <field name="model">lunch.cashmove</field>
- <field name="arch" type="xml">
- <kanban class="o_kanban_mobile">
- <field name="date"/>
- <field name="user_id"/>
- <field name="description"/>
- <field name="amount"/>
- <templates>
- <t t-name="kanban-box">
- <div t-attf-class="oe_kanban_global_click">
- <div class="row mb4">
- <div class="col-8">
- <span>
- <strong class="o_kanban_record_title"><t t-esc="record.description.value"/></strong>
- </span>
- </div>
- <div class="col-4 text-right">
- <span class="badge badge-pill">
- <strong><i class="fa fa-money" role="img" aria-label="Amount" title="Amount"/> <field name="amount"/></strong>
- </span>
- </div>
- </div>
- <div class="row">
- <div class="col-6">
- <i class="fa fa-clock-o" role="img" aria-label="Date" title="Date"/>
- <t t-esc="record.date.value"/>
- </div>
- <div class="col-6">
- <img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" t-att-alt="record.user_id.value" width="24" height="24" class="oe_kanban_avatar float-right"/>
- </div>
- </div>
- </div>
- </t>
- </templates>
- </kanban>
- </field>
- </record>
-
- <record id="lunch_cashmove_view_form" model="ir.ui.view">
- <field name="name">lunch.cashmove.form</field>
- <field name="model">lunch.cashmove</field>
- <field name="arch" type="xml">
- <form string="cashmove form">
- <sheet>
- <group>
- <field name="user_id" required="1"/>
- <field name="date"/>
- <field name="amount"/>
- </group>
- <label for='description'/>
- <field name="description"/>
- </sheet>
- </form>
- </field>
- </record>
-
-
- <!--Action for Your Orders-->
- <record id="lunch_order_action_form" model="ir.actions.act_window">
- <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="lunch_order_menu_form" action="lunch_order_action_form" sequence="1"/>
-
- <record id="lunch_order_line_action" model="ir.actions.act_window">
- <field name="name">Your Orders</field>
- <field name="res_model">lunch.order.line</field>
- <field name="view_mode">tree,kanban,form</field>
- <field name="search_view_id" ref="lunch_order_line_view_search"/>
- <field name="context">{"search_default_is_mine":1}</field>
- <field name="help" type="html">
- <p class="o_view_nocontent_empty_folder">
- No previous order found
- </p><p>
- There is no previous order recorded. Click on "My Lunch" and then create a new lunch order.
- </p>
- </field>
- </record>
<menuitem name="Previous Orders" parent="menu_lunch_title" id="lunch_order_menu_tree" action="lunch_order_line_action" sequence="2"/>
-
- <record id="lunch_cashmove_view_tree_2" model="ir.ui.view">
- <field name="name">lunch.cashmove.tree</field>
- <field name="model">lunch.cashmove</field>
- <field name="arch" type="xml">
- <tree string="cashmove tree" create='false'>
- <field name="date"/>
- <field name="description"/>
- <field name="amount" sum="Total"/>
- </tree>
- </field>
- </record>
-
- <!--Action for Lunch cashmoves-->
- <record id="lunch_cashmove_action_account" model="ir.actions.act_window">
- <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="lunch_cashmove_view_search"/>
- <field name="context">{"search_default_is_mine_group":1}</field>
- <field name="view_id" ref="lunch_cashmove_view_tree_2"/>
- <field name="help" type="html">
- <p class="o_view_nocontent_empty_folder">
- No cash move yet
- </p><p>
- Here you can see your cash moves.<br/>A cash move can either be an expense or a payment.
- An expense is automatically created when an order is received while a payment is a reimbursement to the company encoded by the manager.
- </p>
- </field>
- </record>
-
<menuitem name="Your Lunch Account" parent="menu_lunch_title" id="lunch_cashmove_menu_form" action="lunch_cashmove_action_account" sequence="3"/>
- <!--Action for Administrate Orders group by supplier-->
- <record id="lunch_order_line_action_by_supplier" model="ir.actions.act_window">
- <field name="name">Orders by Vendor</field>
- <field name="res_model">lunch.order.line</field>
- <field name="view_mode">tree,kanban</field>
- <field name="search_view_id" ref="lunch_order_line_view_search"/>
- <field name="context">{"search_default_group_by_supplier":1, "search_default_date_filter":1}</field>
- <field name="help" type="html">
- <p class="o_view_nocontent_empty_folder">
- Nothing to order today
- </p><p>
- Here you can see today's orders grouped by vendors.
- </p><p>
- Click on the <span class="fa fa-phone text-success" role="img" aria-label="Order button" title="Order button"/> to announce that the order is ordered.<br/>
- Click on the <span class="fa fa-check text-success" role="img" aria-label="Receive button" title="Receive button"/> to announce that the order is received.<br/>
- Click on the <span class="fa fa-times-circle text-danger" role="img" aria-label="Cancel button" title="Cancel button"/> to announce that the order isn't available.
- </p>
- </field>
- </record>
<menuitem name="Today's Orders" parent="menu_lunch_admin" id="lunch_order_line_menu_by_supplier" action="lunch_order_line_action_by_supplier" />
-
- <!--Action for control Vendor -->
- <record id="lunch_order_line_action_control_suppliers" model="ir.actions.act_window">
- <field name="name">Control Vendors</field>
- <field name="res_model">lunch.order.line</field>
- <field name="view_mode">tree,kanban</field>
- <field name="search_view_id" ref="lunch_order_line_view_search"/>
- <field name="context">{"search_default_group_by_date":1, "search_default_group_by_supplier":1}</field>
- <field name="help" type="html">
- <p class="o_view_nocontent_empty_folder">
- No lunch order yet
- </p><p>
- Summary of all lunch orders, grouped by vendor and by date.
- </p><p>
- Click on the <span class="fa fa-phone text-success" role="img" aria-label="Order button" title="Order button"/> to announce that the order is ordered.<br/>
- Click on the <span class="fa fa-check text-success" role="img" aria-label="Receive button" title="Receive button"/> to announce that the order is received.<br/>
- Click on the <span class="fa fa-times-circle text-danger" role="img" aria-label="Cancel button" title="Cancel button"/> red X to announce that the order isn't available.
- </p>
- </field>
- </record>
<menuitem name="Orders by Vendor" parent="menu_lunch_admin" id="lunch_order_line_menu_control_suppliers" action="lunch_order_line_action_control_suppliers" />
-
- <!--Action for Control Accounts-->
- <record id="lunch_cashmove_action_control_accounts" model="ir.actions.act_window">
- <field name="name">Control Accounts</field>
- <field name="res_model">lunch.cashmove</field>
- <field name="view_mode">tree,kanban,form</field>
- <field name="search_view_id" ref="lunch_cashmove_view_search_2"/>
- <field name="context">{"search_default_group_by_user":1}</field>
- <field name="view_id" ref="lunch_cashmove_view_tree"/>
- <field name="help" type="html">
- <p class="o_view_nocontent_smiling_face">
- 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_admin" id="lunch_cashmove_menu_control_accounts" action="lunch_cashmove_action_control_accounts"/>
-
- <!--Action for Payment cashmove-->
- <record id="lunch_cashmove_action_payment" model="ir.actions.act_window">
- <field name="name">Register Cash Moves</field>
- <field name="res_model">lunch.cashmove</field>
- <field name="view_mode">tree,kanban,form</field>
- <field name="search_view_id" ref="lunch_cashmove_view_search"/>
- <field name="context">{"search_default_is_payment":1}</field>
- <field name="view_id" ref="lunch_cashmove_view_tree"/>
- <field name="help" type="html">
- <p class="o_view_nocontent_smiling_face">
- Register a payment
- </p><p>
- Payments are used to register liquidity movements. You can process those payments by your own means or by using installed facilities.
- </p>
- </field>
- </record>
<menuitem name="Employee Payments" parent="menu_lunch_admin" id="lunch_cashmove_menu_payment" action="lunch_cashmove_action_payment"/>
- <!--Action for Products-->
- <record id="lunch_product_action" model="ir.actions.act_window">
- <field name="name">Products</field>
- <field name="res_model">lunch.product</field>
- <field name="view_mode">tree,kanban,form</field>
- <field name="help" type="html">
- <p class="o_view_nocontent_smiling_face">
- Create a new product for lunch
- </p><p>
- A product is defined by its name, category, price and vendor.
- </p>
- </field>
- </record>
<menuitem name="Products" parent="menu_lunch_config" id="lunch_product_menu" action="lunch_product_action"/>
-
- <!--Action for Product categories-->
- <record id="lunch_product_category_action" model="ir.actions.act_window">
- <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="o_view_nocontent_smiling_face">
- Create a new lunch category
- </p><p>
- Here you can access all categories for the lunch products.
- </p>
- </field>
- </record>
-
- <record id="lunch_product_category_view_form" model="ir.ui.view">
- <field name="name">Product category Form</field>
- <field name="model">lunch.product.category</field>
- <field name="arch" type="xml">
- <form string="Products Form">
- <sheet>
- <group>
- <field name='name' string="Product Category: "/>
- </group>
- </sheet>
- </form>
- </field>
- </record>
-
<menuitem name="Product Categories" parent="menu_lunch_config" id="lunch_product_category_menu" action="lunch_product_category_action" />
-
- <!--Action for Alert-->
- <record id="lunch_alert_action" model="ir.actions.act_window">
- <field name="name">Alerts</field>
- <field name="res_model">lunch.alert</field>
- <field name="view_mode">tree,kanban,form</field>
- <field name="search_view_id" ref="lunch_alert_view_search"/>
- <field name="help" type="html">
- <p class="o_view_nocontent_smiling_face">
- Create a new 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 recurrence, 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="lunch_alert_menu" action="lunch_alert_action" />
- <!--View for Order lines-->
- <record id="lunch_order_line_view_tree" model="ir.ui.view">
- <field name="name">lunch.order.line.tree</field>
- <field name="model">lunch.order.line</field>
- <field name="arch" type="xml">
- <tree string="Order lines Tree" create="false" edit="false">
- <field name='date'/>
- <field name='supplier' invisible='1'/>
- <field name='product_id'/>
- <field name='note'/>
- <field name='state'/>
- <field name='user_id'/>
- <field name='price' sum="Total" string="Price"/>
- <button name="order" string="Order" type="object" icon="fa-phone text-success" attrs="{'invisible': ['|',('state','=','confirmed'),('state','=','ordered')]}" groups="lunch.group_lunch_manager"/>
- <button name="confirm" string="Receive" type="object" icon="fa-check text-success" attrs="{'invisible': [('state','!=','ordered')]}" groups="lunch.group_lunch_manager"/>
- <button name="cancel" string="Cancel" type="object" icon="fa-times-circle text-danger" attrs="{'invisible': [('state','=','cancelled')]}" groups="lunch.group_lunch_manager"/>
- </tree>
- </field>
- </record>
-
- <record id='lunch_order_line_view_kanban' model='ir.ui.view'>
- <field name="name">lunch.order.line.kanban</field>
- <field name="model">lunch.order.line</field>
- <field name="arch" type="xml">
- <kanban>
- <field name='product_id'/>
- <field name='note'/>
- <field name='state'/>
- <field name='user_id'/>
- <field name='date'/>
- <field name="price"/>
- <templates>
- <t t-name="kanban-box">
- <div class="oe_kanban_global_click">
- <div class="o_kanban_record_top">
- <div class="o_kanban_record_headings">
- <strong class="o_kanban_record_title"><field name="product_id"/></strong>
- </div>
- <field name="state" widget="kanban_label_selection" options="{'classes': {'new': 'default', 'confirmed': 'success', 'cancelled':'danger'}}"/>
- </div>
- <div>
- <field name="note"/>
- </div>
- <div class="row">
- <div class="col-6">
- <i class="fa fa-money" role="img" aria-label="Money" title="Money"/> <field name="price"/>
- </div>
- <div class="col-6 text-right">
- <i class="fa fa-clock-o" role="img" aria-label="Date" title="Date"/> <field name="date"/>
- </div>
- </div>
- <div class="row mt4">
- <div class="col-6">
- <a class="btn btn-sm btn-success" role="button" name="order" string="Order" type="object" attrs="{'invisible': ['|',('state','=','confirmed'),('state','=','ordered')]}" groups="lunch.group_lunch_manager">
- <i class="fa fa-phone" role="img" aria-label="Order button" title="Order button"/>
- </a>
- <a class="btn btn-sm btn-info" role="button" name="confirm" string="Receive" type="object" attrs="{'invisible': [('state','!=','ordered')]}" groups="lunch.group_lunch_manager">
- <i class="fa fa-check" role="img" aria-label="Receive button" title="Receive button"/>
- </a>
- <a class="btn btn-sm btn-danger" role="button" name="cancel" string="Cancel" type="object" attrs="{'invisible': [('state','=','cancelled')]}" groups="lunch.group_lunch_manager">
- <i class="fa fa-times" role="img" aria-label="Cancel button" title="Cancel button"/>
- </a>
- </div>
- <div class="col-6">
- <img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" t-att-alt="record.user_id.value" width="24" height="24" class="oe_kanban_avatar float-right"/>
- </div>
- </div>
- </div>
- </t>
- </templates>
- </kanban>
- </field>
- </record>
-
- <!--View for Your orders-->
- <record id="lunch_order_view_tree" model="ir.ui.view">
- <field name="name">lunch.order.tree</field>
- <field name="model">lunch.order</field>
- <field name="arch" type="xml">
- <tree string="Orders Tree">
- <field name="date"/>
- <field name="order_line_ids"/>
- <field name="state"/>
- <field name="total" sum="Total"/>
- </tree>
- </field>
- </record>
-
- <record id="lunch_order_view_form" model="ir.ui.view">
- <field name="name">lunch.order.form</field>
- <field name="model">lunch.order</field>
- <field name="arch" type="xml">
- <form string='Orders Form' class="o_lunch">
- <header>
- <button name="%(action_lunch_order_line_lucky)d" type="action" string="Feeling Lucky" class="oe_highlight"/>
- <field name='state' widget='statusbar' statusbar_visible='new,confirmed'/>
- </header>
- <sheet>
- <field name="balance_visible" invisible="1"/>
-
- <div class="oe_button_box" name="button_box">
- <button class="oe_stat_button"
- attrs="{'invisible': [('balance_visible', '=', False)]}"
- name="%(lunch_cashmove_action_account)d"
- icon="fa-money"
- type="action">
- <div class="o_field_widget o_stat_info">
- <span class="o_stat_value"><field name="cash_move_balance" widget="monetary"/></span>
- <span class="o_stat_text">Balance</span>
- </div>
- </button>
- </div>
-
- <group>
- <group>
- <field name='user_id' class="oe_inline" required='1'/>
- <field name='date'/>
- </group>
- <div>
- <div attrs="{'invisible': ['|',('state','!=','new'),('alerts','=',False)]}" class="alert alert-danger oe_edit_only" role="alert">
- <field name='alerts'/>
- </div>
- </div>
- </group>
-
- <div>
- <field name='previous_order_widget' widget='previous_order' class='o_lunch_last_orders'/>
- </div>
-
- <separator string='Select your order'/>
- <field name='order_line_ids'>
- <tree string='List' editable='bottom'>
- <field name='product_id' context="{'lunch_date': parent.date}"/>
- <field name='note' />
- <field name='price'/>
- <field name='supplier' invisible="1"/>
- <field name="state" invisible="1"/>
- </tree>
- <form string='Lunch Order Form'>
- <group>
- <field name='product_id' context="{'lunch_date': parent.date}"/>
- <field name='note' />
- <field name='price'/>
- </group>
- </form>
- </field>
- <group class='oe_subtotal_footer oe_right'>
- <field name='total' widget='monetary' options="{'currency_field': 'currency_id'}"/>
- </group>
- </sheet>
- </form>
- </field>
- </record>
-
- <!--View for Products-->
- <record id="lunch_product_view_tree" model="ir.ui.view">
- <field name="name">lunch.product.tree</field>
- <field name="model">lunch.product</field>
- <field name="arch" type="xml">
- <tree string="Products Tree">
- <field name="name"/>
- <field name="category_id"/>
- <field name="supplier"/>
- <field name="description"/>
- <field name="price"/>
- </tree>
- </field>
- </record>
-
- <record id="view_lunch_product_kanban" model="ir.ui.view">
- <field name="name">lunch.product.kanban</field>
- <field name="model">lunch.product</field>
- <field name="arch" type="xml">
- <kanban class="o_kanban_mobile">
- <field name="name"/>
- <field name="category_id"/>
- <field name="supplier"/>
- <field name="description"/>
- <field name="price"/>
- <templates>
- <t t-name="kanban-box">
- <div t-attf-class="oe_kanban_global_click">
- <div class="o_kanban_record_top">
- <div class="o_kanban_record_headings">
- <strong class="o_kanban_record_title"><t t-esc="record.name.value"/></strong>
- </div>
- <span class="badge badge-pill float-right">
- Price: <t t-esc="record.price.value"/>
- </span>
- </div>
- <div>
- <t t-esc="record.supplier.value"/>
- </div>
- <div>
- <t t-esc="record.description.value"/>
- </div>
- </div>
- </t>
- </templates>
- </kanban>
- </field>
- </record>
<record id="action_server_lunch_archive_product" model="ir.actions.server">
<field name="name">Lunch: Archive/Restore products</field>
@@ -558,157 +28,4 @@
<field name="state">code</field>
<field name="code">records.toggle_active()</field>
</record>
-
- <!-- Search for product -->
- <record id="lunch_product_view_search" model="ir.ui.view">
- <field name="name">lunch.product.search</field>
- <field name="model">lunch.product</field>
- <field name="arch" type="xml">
- <search string="Product Search">
- <field name="name"/>
- <field name="category_id"/>
- <field name="supplier"/>
- <field name="description"/>
- <group expand="0" string="Group By">
- <filter name="supplier" string="Vendor" context="{'group_by': 'supplier'}"/>
- <filter name="category" string="Product Category" context="{'group_by': 'category_id'}"/>
- <filter name="inactive" string="Archived" domain="[('active','=',False)]"/>
- </group>
- </search>
- </field>
- </record>
-
- <record id="lunch_product_view_form" model="ir.ui.view">
- <field name="name">lunch.product.form</field>
- <field name="model">lunch.product</field>
- <field name="arch" type="xml">
- <form string="Products Form">
- <header>
- </header>
- <sheet>
- <div class="oe_button_box" name="button_box">
- <button name="toggle_active" type="object"
- class="oe_stat_button" icon="fa-archive">
- <field name="active" widget="boolean_button"
- options='{"terminology": "archive"}'/>
- </button>
- </div>
- <group>
- <group>
- <field name='name'/>
- <field name='category_id'/>
- </group>
- <group>
- <field name='supplier'/>
- <field name='price'/>
- </group>
- </group>
- <label for='description'/>
- <field name='description'/>
- </sheet>
- </form>
- </field>
- </record>
-
- <!--view for alerts-->
- <record id="lunch_alert_view_tree" model="ir.ui.view">
- <field name="name">lunch.alert.tree</field>
- <field name="model">lunch.alert</field>
- <field name="arch" type="xml">
- <tree>
- <field name="message"/>
- <field name="alert_type"/>
- <field name='start_hour' widget='float_time'/>
- <field name='end_hour' widget='float_time'/>
- </tree>
- </field>
- </record>
-
- <record id="view_lunch_alert_kanban" model="ir.ui.view">
- <field name="name">lunch.alert.kanban</field>
- <field name="model">lunch.alert</field>
- <field name="arch" type="xml">
- <kanban class="o_kanban_mobile">
- <field name="message"/>
- <field name="alert_type"/>
- <field name='start_hour'/>
- <field name='end_hour'/>
- <templates>
- <t t-name="kanban-box">
- <div t-attf-class="oe_kanban_global_click">
- <div class="o_kanban_record_top">
- <strong class="o_kanban_record_title"><t t-esc="record.message.value"/></strong>
- </div>
- <div class="row mb4">
- <div class="col-6">
- Between: <t t-esc="record.start_hour.value"/> -
- <t t-esc="record.end_hour.value"/>
- </div>
- <div class="col-6">
- <span class="badge badge-pill float-right">
- <t t-esc="record.alert_type.value"/>
- </span>
- </div>
- </div>
- </div>
- </t>
- </templates>
- </kanban>
- </field>
- </record>
-
- <record id="lunch_alert_view_form" model="ir.ui.view">
- <field name="name">lunch.alert.form</field>
- <field name="model">lunch.alert</field>
- <field name="arch" type="xml">
- <form>
- <sheet>
- <div class="oe_button_box" name="button_box">
- <button name="toggle_active" type="object"
- class="oe_stat_button" icon="fa-archive">
- <field name="active" widget="boolean_button"
- options='{"terminology": "archive"}'/>
- </button>
- </div>
- <group>
- <group name="schedule" string="Schedule">
- <group colspan="4">
- <field name="alert_type"/>
- <field name="specific_day"
- attrs="{'invisible': [('alert_type','!=','specific')], 'required':[('alert_type','=','specific')]}"/>
- <field name='start_hour' widget='float_time' />
- <field name='end_hour' widget='float_time' />
- </group>
- <group name="weekdays" col="4" attrs="{'invisible': [('alert_type','!=','week')]}">
- <field name="monday"/>
- <field name="tuesday"/>
- <field name="wednesday"/>
- <field name="thursday"/>
- <field name="friday"/>
- <field name="saturday"/>
- <field name="sunday"/>
- </group>
- </group>
- <group name="vendor" string="Vendor">
- <group name="partner" colspan="4">
- <field name="partner_id"/>
- <field name="display" invisible="True"/>
- </group>
- <div class="oe_grey" colspan="4"
- attrs="{'invisible': ['|', ('partner_id', '=', False), ('display', '=', True)]}">
- Products from this vendor can <strong>not</strong> be ordered at that moment.
- </div>
- <div class="oe_grey" colspan="4"
- attrs="{'invisible': ['|', ('partner_id', '=', False), ('display', '=', False)]}">
- Products from this vendor can be ordered at that moment.
- </div>
- </group>
- </group>
- <group string='Message'>
- <field name='message' nolabel='1' placeholder="Write the message you want to display during the defined period..."/>
- </group>
- </sheet>
- </form>
- </field>
- </record>
</odoo>