mirror of
https://github.com/bringout/oca-ocb-vertical-industry.git
synced 2026-04-23 06:32:00 +02:00
19.0 vanilla
This commit is contained in:
parent
4607ccbd2e
commit
825ff6514e
487 changed files with 184979 additions and 195262 deletions
|
|
@ -1,8 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
from odoo.fields import Domain
|
||||
|
||||
|
||||
class LunchOrder(models.Model):
|
||||
|
|
@ -11,23 +12,22 @@ class LunchOrder(models.Model):
|
|||
_order = 'id desc'
|
||||
_display_name = 'product_id'
|
||||
|
||||
name = fields.Char(related='product_id.name', string="Product Name", store=True, readonly=True)
|
||||
name = fields.Char(related='product_id.name', string="Product Name", readonly=True)
|
||||
topping_ids_1 = fields.Many2many('lunch.topping', 'lunch_order_topping', 'order_id', 'topping_id', string='Extras 1', domain=[('topping_category', '=', 1)])
|
||||
topping_ids_2 = fields.Many2many('lunch.topping', 'lunch_order_topping', 'order_id', 'topping_id', string='Extras 2', domain=[('topping_category', '=', 2)])
|
||||
topping_ids_3 = fields.Many2many('lunch.topping', 'lunch_order_topping', 'order_id', 'topping_id', string='Extras 3', domain=[('topping_category', '=', 3)])
|
||||
product_id = fields.Many2one('lunch.product', string="Product", required=True)
|
||||
category_id = fields.Many2one(
|
||||
string='Product Category', related='product_id.category_id', store=True)
|
||||
date = fields.Date('Order Date', required=True, readonly=True,
|
||||
states={'new': [('readonly', False)]},
|
||||
date = fields.Date('Order Date', required=True, readonly=False,
|
||||
default=fields.Date.context_today)
|
||||
supplier_id = fields.Many2one(
|
||||
string='Vendor', related='product_id.supplier_id', store=True, index=True)
|
||||
available_today = fields.Boolean(related='supplier_id.available_today')
|
||||
order_deadline_passed = fields.Boolean(related='supplier_id.order_deadline_passed')
|
||||
user_id = fields.Many2one('res.users', 'User', readonly=True,
|
||||
states={'new': [('readonly', False)]},
|
||||
default=lambda self: self.env.uid)
|
||||
|
||||
available_on_date = fields.Boolean(compute='_compute_available_on_date')
|
||||
order_deadline_passed = fields.Boolean(compute='_compute_order_deadline_passed')
|
||||
user_id = fields.Many2one('res.users', 'User', default=lambda self: self.env.uid)
|
||||
lunch_location_id = fields.Many2one('lunch.location', default=lambda self: self.env.user.last_lunch_location_id)
|
||||
note = fields.Text('Notes')
|
||||
price = fields.Monetary('Total Price', compute='_compute_total_price', readonly=True, store=True)
|
||||
|
|
@ -59,6 +59,9 @@ class LunchOrder(models.Model):
|
|||
available_toppings_2 = fields.Boolean(help='Are extras available for this product', compute='_compute_available_toppings')
|
||||
available_toppings_3 = fields.Boolean(help='Are extras available for this product', compute='_compute_available_toppings')
|
||||
display_reorder_button = fields.Boolean(compute='_compute_display_reorder_button')
|
||||
display_add_button = fields.Boolean(compute='_compute_display_add_button')
|
||||
|
||||
_user_product_date = models.Index("(user_id, product_id, date)")
|
||||
|
||||
@api.depends('product_id')
|
||||
def _compute_product_images(self):
|
||||
|
|
@ -73,6 +76,22 @@ class LunchOrder(models.Model):
|
|||
order.available_toppings_2 = bool(order.env['lunch.topping'].search_count([('supplier_id', '=', order.supplier_id.id), ('topping_category', '=', 2)]))
|
||||
order.available_toppings_3 = bool(order.env['lunch.topping'].search_count([('supplier_id', '=', order.supplier_id.id), ('topping_category', '=', 3)]))
|
||||
|
||||
@api.depends('name')
|
||||
def _compute_display_add_button(self):
|
||||
new_orders = dict(self.env["lunch.order"]._read_group([
|
||||
("date", "in", self.mapped("date")),
|
||||
("user_id", "in", self.user_id.ids),
|
||||
("state", "=", "new"),
|
||||
], ['user_id'], ['id:recordset']))
|
||||
for order in self:
|
||||
user_new_orders = new_orders.get(order.user_id)
|
||||
price = 0
|
||||
if user_new_orders:
|
||||
user_new_orders = user_new_orders.filtered(lambda lunch_order: lunch_order.date == order.date)
|
||||
price = sum(order.price for order in user_new_orders)
|
||||
wallet_amount = self.env['lunch.cashmove'].get_wallet_balance(order.user_id) - price
|
||||
order.display_add_button = wallet_amount >= order.price
|
||||
|
||||
@api.depends_context('show_reorder_button')
|
||||
@api.depends('state')
|
||||
def _compute_display_reorder_button(self):
|
||||
|
|
@ -80,26 +99,44 @@ class LunchOrder(models.Model):
|
|||
for order in self:
|
||||
order.display_reorder_button = show_button and order.state == 'confirmed' and order.supplier_id.available_today
|
||||
|
||||
def init(self):
|
||||
self._cr.execute("""CREATE INDEX IF NOT EXISTS lunch_order_user_product_date ON %s (user_id, product_id, date)"""
|
||||
% self._table)
|
||||
@api.depends('date', 'supplier_id')
|
||||
def _compute_available_on_date(self):
|
||||
for order in self:
|
||||
order.available_on_date = order.supplier_id._available_on_date(order.date)
|
||||
|
||||
@api.depends('supplier_id', 'date')
|
||||
def _compute_order_deadline_passed(self):
|
||||
today = fields.Date.context_today(self)
|
||||
for order in self:
|
||||
if order.date < today:
|
||||
order.order_deadline_passed = True
|
||||
elif order.date == today:
|
||||
order.order_deadline_passed = order.supplier_id.order_deadline_passed
|
||||
else:
|
||||
order.order_deadline_passed = False
|
||||
|
||||
def _get_topping_ids(self, field, values):
|
||||
return list(self._fields[field].convert_to_cache(values, self))
|
||||
|
||||
def _extract_toppings(self, values):
|
||||
"""
|
||||
If called in api.multi then it will pop topping_ids_1,2,3 from values
|
||||
"""
|
||||
if self.ids:
|
||||
# TODO This is not taking into account all the toppings for each individual order, this is usually not a problem
|
||||
# since in the interface you usually don't update more than one order at a time but this is a bug nonetheless
|
||||
topping_1 = values.pop('topping_ids_1')[0][2] if 'topping_ids_1' in values else self[:1].topping_ids_1.ids
|
||||
topping_2 = values.pop('topping_ids_2')[0][2] if 'topping_ids_2' in values else self[:1].topping_ids_2.ids
|
||||
topping_3 = values.pop('topping_ids_3')[0][2] if 'topping_ids_3' in values else self[:1].topping_ids_3.ids
|
||||
else:
|
||||
topping_1 = values['topping_ids_1'][0][2] if 'topping_ids_1' in values else []
|
||||
topping_2 = values['topping_ids_2'][0][2] if 'topping_ids_2' in values else []
|
||||
topping_3 = values['topping_ids_3'][0][2] if 'topping_ids_3' in values else []
|
||||
topping_ids = []
|
||||
|
||||
return topping_1 + topping_2 + topping_3
|
||||
for i in range(1, 4):
|
||||
topping_field = f'topping_ids_{i}'
|
||||
topping_values = values.get(topping_field, False)
|
||||
|
||||
if self.ids:
|
||||
# TODO This is not taking into account all the toppings for each individual order, this is usually not a problem
|
||||
# since in the interface you usually don't update more than one order at a time but this is a bug nonetheless
|
||||
topping_ids += self._get_topping_ids(topping_field, values.pop(topping_field)) \
|
||||
if topping_values else self[:1][topping_field].ids
|
||||
else:
|
||||
topping_ids += self._get_topping_ids(topping_field, topping_values) if topping_values else []
|
||||
|
||||
return topping_ids
|
||||
|
||||
@api.constrains('topping_ids_1', 'topping_ids_2', 'topping_ids_3')
|
||||
def _check_topping_quantity(self):
|
||||
|
|
@ -126,8 +163,9 @@ class LunchOrder(models.Model):
|
|||
lines = self._find_matching_lines({
|
||||
**vals,
|
||||
'toppings': self._extract_toppings(vals),
|
||||
'state': 'new',
|
||||
})
|
||||
if lines.filtered(lambda l: l.state not in ['sent', 'confirmed']):
|
||||
if lines:
|
||||
# YTI FIXME This will update multiple lines in the case there are multiple
|
||||
# matching lines which should not happen through the interface
|
||||
lines.update_quantity(1)
|
||||
|
|
@ -136,8 +174,10 @@ class LunchOrder(models.Model):
|
|||
orders |= super().create(vals)
|
||||
return orders
|
||||
|
||||
def write(self, values):
|
||||
merge_needed = 'note' in values or 'topping_ids_1' in values or 'topping_ids_2' in values or 'topping_ids_3' in values
|
||||
def write(self, vals):
|
||||
values = vals
|
||||
change_topping = 'topping_ids_1' in values or 'topping_ids_2' in values or 'topping_ids_3' in values
|
||||
merge_needed = 'note' in values or change_topping or 'state' in values
|
||||
default_location_id = self.env.user.last_lunch_location_id and self.env.user.last_lunch_location_id.id or False
|
||||
|
||||
if merge_needed:
|
||||
|
|
@ -149,14 +189,16 @@ class LunchOrder(models.Model):
|
|||
# This also forces us to invalidate the cache for topping_ids_2 and topping_ids_3 that
|
||||
# could have changed through topping_ids_1 without the cache knowing about it
|
||||
toppings = self._extract_toppings(values)
|
||||
self.invalidate_model(['topping_ids_2', 'topping_ids_3'])
|
||||
values['topping_ids_1'] = [(6, 0, toppings)]
|
||||
if change_topping:
|
||||
self.invalidate_model(['topping_ids_2', 'topping_ids_3'])
|
||||
values['topping_ids_1'] = [(6, 0, toppings)]
|
||||
matching_lines = self._find_matching_lines({
|
||||
'user_id': values.get('user_id', line.user_id.id),
|
||||
'product_id': values.get('product_id', line.product_id.id),
|
||||
'note': values.get('note', line.note or False),
|
||||
'toppings': toppings,
|
||||
'lunch_location_id': values.get('lunch_location_id', default_location_id),
|
||||
'state': values.get('state'),
|
||||
})
|
||||
if matching_lines:
|
||||
lines_to_deactivate |= line
|
||||
|
|
@ -171,10 +213,12 @@ class LunchOrder(models.Model):
|
|||
domain = [
|
||||
('user_id', '=', values.get('user_id', self.default_get(['user_id'])['user_id'])),
|
||||
('product_id', '=', values.get('product_id', False)),
|
||||
('date', '=', fields.Date.today()),
|
||||
('date', '=', values.get('date', fields.Date.today())),
|
||||
('note', '=', values.get('note', False)),
|
||||
('lunch_location_id', '=', values.get('lunch_location_id', default_location_id)),
|
||||
]
|
||||
if values.get('state'):
|
||||
domain = Domain.AND([domain, [('state', '=', values['state'])]])
|
||||
toppings = values.get('toppings', [])
|
||||
return self.search(domain).filtered(lambda line: (line.topping_ids_1 | line.topping_ids_2 | line.topping_ids_3).ids == toppings)
|
||||
|
||||
|
|
@ -210,19 +254,17 @@ class LunchOrder(models.Model):
|
|||
self.env.flush_all()
|
||||
for line in self:
|
||||
if self.env['lunch.cashmove'].get_wallet_balance(line.user_id) < 0:
|
||||
raise ValidationError(_('Your wallet does not contain enough money to order that. To add some money to your wallet, please contact your lunch manager.'))
|
||||
raise ValidationError(_('Oh no! You don’t have enough money in your wallet to order your selected lunch! Contact your lunch manager to add some money to your wallet.'))
|
||||
|
||||
def action_order(self):
|
||||
for order in self:
|
||||
if not order.supplier_id.available_today:
|
||||
raise UserError(_('The vendor related to this order is not available today.'))
|
||||
if not order.available_on_date:
|
||||
raise UserError(_('The vendor related to this order is not available at the selected date.'))
|
||||
if self.filtered(lambda line: not line.product_id.active):
|
||||
raise ValidationError(_('Product is no longer available.'))
|
||||
self.write({
|
||||
'state': 'ordered',
|
||||
})
|
||||
for order in self:
|
||||
order.lunch_location_id = order.user_id.last_lunch_location_id
|
||||
self._check_wallet()
|
||||
|
||||
def action_reorder(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue