We would like to automatize lunch as currently all orders are manually ordered and validated, and a cash move has to be manually created each time you want to credit the wallet of some user. 1/ In this commit we add a new widget that comes with the kanban view and will allow to take orders in a friendly manner. 2/ We also add a lunch.supplier model this also allows you to configure an automatic ordering via email. 3/ Introduces new lunch.location model to replace res.partner on suppliers 4/ New mail template for automatic ordering 5/ Add the concept of new products (mark a product as new until some date) 6/ The toppings are now defined by product category 7/ Lunch.order removed, lunch.order.line renamed into lunch.order 8/ New SQL report to get the wallet content (aggregate of lunch.cashmove and lunch.order) 9/ New setting to allow negative wallet (aka overdraft) 10/ Application now remembers what notes and toppings you last ordered with your product 11/ You can change your location using the widget on the kanban view 12/ Edition of the order can be done until the order is arrived TaskID: 1856876 TaskID: 1916105 closes odoo/odoo#30028
120 lines
4.8 KiB
Python
120 lines
4.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo import http, fields
|
|
from odoo.http import request
|
|
from odoo.osv import expression
|
|
from odoo.tools import float_round, float_repr
|
|
|
|
|
|
class LunchController(http.Controller):
|
|
@http.route('/lunch/infos', type='json', auth='user')
|
|
def infos(self, user_id=None):
|
|
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
|
|
|
|
infos = self._make_infos(user, order=False)
|
|
|
|
lines = self._get_current_lines(user.id)
|
|
if lines:
|
|
lines = [{'id': line.id,
|
|
'product': (line.product_id.id, line.product_id.name, float_repr(float_round(line.product_id.price, 2), 2)),
|
|
'toppings': [(topping.name, float_repr(float_round(topping.price, 2), 2))
|
|
for topping in line.topping_ids_1 | line.topping_ids_2 | line.topping_ids_3],
|
|
'quantity': line.quantity,
|
|
'price': line.price,
|
|
'state': line.state, # Only used for _get_state
|
|
'note': line.note} for line in lines]
|
|
raw_state, state = self._get_state(lines)
|
|
infos.update({
|
|
'total': float_repr(float_round(sum(line['price'] for line in lines), 2), 2),
|
|
'raw_state': raw_state,
|
|
'state': state,
|
|
'lines': lines,
|
|
})
|
|
return infos
|
|
|
|
@http.route('/lunch/trash', type='json', auth='user')
|
|
def trash(self, user_id=None):
|
|
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
|
|
|
|
lines = self._get_current_lines(user.id)
|
|
lines.action_cancel()
|
|
lines.unlink()
|
|
|
|
@http.route('/lunch/pay', type='json', auth='user')
|
|
def pay(self, user_id=None):
|
|
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
|
|
|
|
lines = self._get_current_lines(user.id)
|
|
if lines:
|
|
lines = lines.filtered(lambda line: line.state == 'new')
|
|
|
|
lines.action_order()
|
|
return True
|
|
|
|
return False
|
|
|
|
@http.route('/lunch/payment_message', type='json', auth='user')
|
|
def payment_message(self):
|
|
return {'message': request.env['ir.qweb'].render('lunch.lunch_payment_dialog', {})}
|
|
|
|
@http.route('/lunch/user_location_set', type='json', auth='user')
|
|
def set_user_location(self, location_id, user_id=None):
|
|
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
|
|
|
|
user.last_lunch_location_id = request.env['lunch.location'].browse(location_id)
|
|
return True
|
|
|
|
@http.route('/lunch/user_location_get', type='json', auth='user')
|
|
def get_user_location(self, user_id=None):
|
|
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
|
|
|
|
return user.last_lunch_location_id.id
|
|
|
|
def _make_infos(self, user, **kwargs):
|
|
res = dict(kwargs)
|
|
|
|
is_manager = request.env.user.has_group('lunch.group_lunch_manager')
|
|
|
|
currency = user.company_id.currency_id
|
|
|
|
res.update({
|
|
'username': user.sudo().name,
|
|
'userimage': '/web/image?model=res.users&id=%s&field=image_small' % user.id,
|
|
'wallet': request.env['lunch.cashmove'].get_wallet_balance(user, False),
|
|
'is_manager': is_manager,
|
|
'locations': request.env['lunch.location'].search_read([], ['name']),
|
|
'currency': {'symbol': currency.symbol, 'position': currency.position},
|
|
})
|
|
|
|
user_location = user.last_lunch_location_id if user.last_lunch_location_id else request.env['lunch.location'].search([], limit=1)
|
|
|
|
alert_domain = expression.AND([
|
|
[('available_today', '=', True)],
|
|
[('location_ids', 'in', user_location.id)],
|
|
])
|
|
|
|
res.update({
|
|
'user_location': (user_location.id, user_location.name),
|
|
'alerts': request.env['lunch.alert'].search_read(alert_domain, ['message']),
|
|
})
|
|
|
|
return res
|
|
|
|
def _get_current_lines(self, user_id):
|
|
return request.env['lunch.order'].search([('user_id', '=', user_id), ('date', '=', fields.Date.today()), ('state', '!=', 'cancelled')])
|
|
|
|
def _get_state(self, lines):
|
|
"""
|
|
This method returns the lowest state of the list of lines
|
|
|
|
eg: [confirmed, confirmed, new] will return ('new', 'To Order')
|
|
"""
|
|
states_to_int = {'new': 0, 'ordered': 1, 'confirmed': 2, 'cancelled': 3}
|
|
int_to_states = ['new', 'ordered', 'confirmed', 'cancelled']
|
|
translated_states = dict(request.env['lunch.order']._fields['state']._description_selection(request.env))
|
|
|
|
state = int_to_states[min(states_to_int[line['state']] for line in lines)]
|
|
|
|
return (state, translated_states[state])
|