Files
odoo_source/addons/pos_cache/models/pos_cache.py
T
Ivan Yelizariev 0eb30d3fee [FIX] pos_cache: fix error on opening POS
STEP:
* install pos_cache
* create some products (this step is not needed in demo database)
* open POS

BEFORE: error "TypeError: Object of type 'datetime' is not JSON serializable"

AFTER: no errors

WHY:
* Since Odoo 12 date fields are not strings: https://github.com/odoo/odoo/commit/960360afe478a8f7b9c456721b5591154952a37d
* Since Odoo 14 fields lists to read contains write_date:
https://github.com/odoo/odoo/commit/c6397ab3b3654da336a4269a81d5d91016baf520 --
see models.js

---

opw-2410334

closes odoo/odoo#62960

X-original-commit: fd477f3f6d331355b5667a12b43d1c4a110b7e21
Signed-off-by: Ivan Yelizariev // IEL <yelizariev@users.noreply.github.com>
2020-12-07 13:44:53 +00:00

97 lines
3.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import json
from ast import literal_eval
from odoo import models, fields, api
from odoo.tools import date_utils
class pos_cache(models.Model):
_name = 'pos.cache'
_description = 'Point of Sale Cache'
cache = fields.Binary(attachment=True)
product_domain = fields.Text(required=True)
product_fields = fields.Text(required=True)
config_id = fields.Many2one('pos.config', ondelete='cascade', required=True)
compute_user_id = fields.Many2one('res.users', 'Cache compute user', required=True)
@api.model
def refresh_all_caches(self):
self.env['pos.cache'].search([]).refresh_cache()
def refresh_cache(self):
for cache in self:
Product = self.env['product.product'].with_user(cache.compute_user_id.id)
products = Product.search(cache.get_product_domain())
prod_ctx = products.with_context(pricelist=cache.config_id.pricelist_id.id,
display_default_code=False, lang=cache.compute_user_id.lang)
res = prod_ctx.read(cache.get_product_fields())
cache.write({
'cache': base64.encodebytes(json.dumps(res, default=date_utils.json_default).encode('utf-8')),
})
@api.model
def get_product_domain(self):
return literal_eval(self.product_domain)
@api.model
def get_product_fields(self):
return literal_eval(self.product_fields)
@api.model
def get_cache(self, domain, fields):
if not self.cache or domain != self.get_product_domain() or fields != self.get_product_fields():
self.product_domain = str(domain)
self.product_fields = str(fields)
self.refresh_cache()
return json.loads(base64.decodebytes(self.cache).decode('utf-8'))
class pos_config(models.Model):
_inherit = 'pos.config'
@api.depends('cache_ids')
def _get_oldest_cache_time(self):
for cache in self:
pos_cache = self.env['pos.cache']
oldest_cache = pos_cache.search([('config_id', '=', cache.id)], order='write_date', limit=1)
cache.oldest_cache_time = oldest_cache.write_date
# Use a related model to avoid the load of the cache when the pos load his config
cache_ids = fields.One2many('pos.cache', 'config_id')
oldest_cache_time = fields.Datetime(compute='_get_oldest_cache_time', string='Oldest cache time', readonly=True)
def _get_cache_for_user(self):
pos_cache = self.env['pos.cache']
cache_for_user = pos_cache.search([('id', 'in', self.cache_ids.ids), ('compute_user_id', '=', self.env.uid)])
if cache_for_user:
return cache_for_user[0]
else:
return None
def get_products_from_cache(self, fields, domain):
cache_for_user = self._get_cache_for_user()
if cache_for_user:
return cache_for_user.get_cache(domain, fields)
else:
pos_cache = self.env['pos.cache']
pos_cache.create({
'config_id': self.id,
'product_domain': str(domain),
'product_fields': str(fields),
'compute_user_id': self.env.uid
})
new_cache = self._get_cache_for_user()
return new_cache.get_cache(domain, fields)
def delete_cache(self):
# throw away the old caches
self.cache_ids.unlink()