1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from odoo.modules.module import get_module_resource
from odoo.tools import formatLang
class LunchProductCategory(models.Model):
""" Category of the product such as pizza, sandwich, pasta, chinese, burger... """
_name = 'lunch.product.category'
_inherit = 'image.mixin'
_description = 'Lunch Product Category'
@api.model
def _default_image(self):
image_path = get_module_resource('lunch', 'static/img', 'lunch.png')
return base64.b64encode(open(image_path, 'rb').read())
name = fields.Char('Product Category', required=True, translate=True)
company_id = fields.Many2one('res.company')
currency_id = fields.Many2one('res.currency', related='company_id.currency_id')
topping_label_1 = fields.Char('Extra 1 Label', required=True, default='Extras')
topping_label_2 = fields.Char('Extra 2 Label', required=True, default='Beverages')
topping_label_3 = fields.Char('Extra 3 Label', required=True, default='Extra Label 3')
topping_ids_1 = fields.One2many('lunch.topping', 'category_id', domain=[('topping_category', '=', 1)])
topping_ids_2 = fields.One2many('lunch.topping', 'category_id', domain=[('topping_category', '=', 2)])
topping_ids_3 = fields.One2many('lunch.topping', 'category_id', domain=[('topping_category', '=', 3)])
topping_quantity_1 = fields.Selection([
('0_more', 'None or More'),
('1_more', 'One or More'),
('1', 'Only One')], 'Extra 1 Quantity', default='0_more', required=True)
topping_quantity_2 = fields.Selection([
('0_more', 'None or More'),
('1_more', 'One or More'),
('1', 'Only One')], 'Extra 2 Quantity', default='0_more', required=True)
topping_quantity_3 = fields.Selection([
('0_more', 'None or More'),
('1_more', 'One or More'),
('1', 'Only One')], 'Extra 3 Quantity', default='0_more', required=True)
product_count = fields.Integer(compute='_compute_product_count', help="The number of products related to this category")
active = fields.Boolean(string='Active', default=True)
image_1920 = fields.Image(default=_default_image)
def _compute_product_count(self):
product_data = self.env['lunch.product'].read_group([('category_id', 'in', self.ids)], ['category_id'], ['category_id'])
data = {product['category_id'][0]: product['category_id_count'] for product in product_data}
for category in self:
category.product_count = data.get(category.id, 0)
@api.model
def create(self, vals):
for topping in vals.get('topping_ids_2', []):
topping[2].update({'topping_category': 2})
for topping in vals.get('topping_ids_3', []):
topping[2].update({'topping_category': 3})
return super(LunchProductCategory, self).create(vals)
def write(self, vals):
for topping in vals.get('topping_ids_2', []):
topping_values = topping[2]
if topping_values:
topping_values.update({'topping_category': 2})
for topping in vals.get('topping_ids_3', []):
topping_values = topping[2]
if topping_values:
topping_values.update({'topping_category': 3})
return super(LunchProductCategory, self).write(vals)
def toggle_active(self):
""" Archiving related lunch product """
res = super().toggle_active()
Product = self.env['lunch.product'].with_context(active_test=False)
all_products = Product.search([('category_id', 'in', self.ids)])
all_products._sync_active_from_related()
return res
class LunchTopping(models.Model):
""""""
_name = 'lunch.topping'
_description = 'Lunch Extras'
name = fields.Char('Name', required=True)
company_id = fields.Many2one('res.company', default=lambda self: self.env.company)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id')
price = fields.Float('Price', digits='Account', required=True)
category_id = fields.Many2one('lunch.product.category', ondelete='cascade')
topping_category = fields.Integer('Topping Category', help="This field is a technical field", required=True, default=1)
def name_get(self):
currency_id = self.env.company.currency_id
res = dict(super(LunchTopping, self).name_get())
for topping in self:
price = formatLang(self.env, topping.price, currency_obj=currency_id)
res[topping.id] = '%s %s' % (topping.name, price)
return list(res.items())
class LunchProduct(models.Model):
""" Products available to order. A product is linked to a specific vendor. """
_name = 'lunch.product'
_description = 'Lunch Product'
_inherit = 'image.mixin'
_order = 'name'
_check_company_auto = True
name = fields.Char('Product Name', required=True, translate=True)
category_id = fields.Many2one('lunch.product.category', 'Product Category', check_company=True, required=True)
description = fields.Text('Description', translate=True)
price = fields.Float('Price', digits='Account', required=True)
supplier_id = fields.Many2one('lunch.supplier', 'Vendor', check_company=True, required=True)
active = fields.Boolean(default=True)
company_id = fields.Many2one('res.company', related='supplier_id.company_id', readonly=False, store=True)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id')
new_until = fields.Date('New Until')
favorite_user_ids = fields.Many2many('res.users', 'lunch_product_favorite_user_rel', 'product_id', 'user_id', check_company=True)
def _sync_active_from_related(self):
""" Archive/unarchive product after related field is archived/unarchived """
return self.filtered(lambda p: (p.category_id.active and p.supplier_id.active) != p.active).toggle_active()
def toggle_active(self):
if self.filtered(lambda product: not product.active and not product.category_id.active):
raise UserError(_("The product category is archived. The user have to unarchive the category or change the category of the product."))
if self.filtered(lambda product: not product.active and not product.supplier_id.active):
raise UserError(_("The product supplier is archived. The user have to unarchive the supplier or change the supplier of the product."))
return super().toggle_active()
|