diff options
| author | RomainLibert <rli@odoo.com> | 2018-10-19 10:09:56 +0200 |
|---|---|---|
| committer | Yannick Tivisse <yti@odoo.com> | 2018-12-04 11:55:07 +0100 |
| commit | ad99f09a062cd190c9863d49486e60899daed2a6 (patch) | |
| tree | 9902ae2601dd1bcefc1a0b7b1a4439a93b06e7e4 | |
| parent | a2c5b44df8c538b0a43b86502849e72c55c2d2ff (diff) | |
[REF] lunch: split lunch.py into smaller files
We should basically have one model per file, as this will facilitate the
reading and maintenance of the code
| -rw-r--r-- | addons/lunch/__manifest__.py | 4 | ||||
| -rw-r--r-- | addons/lunch/models/__init__.py | 5 | ||||
| -rw-r--r-- | addons/lunch/models/lunch_alert.py | 85 | ||||
| -rw-r--r-- | addons/lunch/models/lunch_cashmove.py | 23 | ||||
| -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.py | 63 | ||||
| -rw-r--r-- | addons/lunch/views/lunch_alert_views.xml | 134 | ||||
| -rw-r--r-- | addons/lunch/views/lunch_cashmove_views.xml | 165 | ||||
| -rw-r--r-- | addons/lunch/views/lunch_orders_views.xml | 237 | ||||
| -rw-r--r-- | addons/lunch/views/lunch_product_views.xml | 140 | ||||
| -rw-r--r-- | addons/lunch/views/lunch_views.xml | 683 |
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> |
