74 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
# -*- coding: utf-8 -*-
 | 
						|
# copyright 2016 Camptocamp
 | 
						|
# license agpl-3.0 or later (http://www.gnu.org/licenses/agpl.html)
 | 
						|
 | 
						|
import json
 | 
						|
from datetime import datetime, date
 | 
						|
 | 
						|
import dateutil
 | 
						|
 | 
						|
from odoo import fields, models
 | 
						|
 | 
						|
 | 
						|
class JobSerialized(fields.Field):
 | 
						|
    """ Serialized fields provide the storage for sparse fields. """
 | 
						|
    type = 'job_serialized'
 | 
						|
    column_type = ('text', 'text')
 | 
						|
 | 
						|
    def convert_to_column(self, value, record, values=None):
 | 
						|
        return json.dumps(value, cls=JobEncoder)
 | 
						|
 | 
						|
    def convert_to_cache(self, value, record, validate=True):
 | 
						|
        # cache format: dict
 | 
						|
        value = value or {}
 | 
						|
        if isinstance(value, dict):
 | 
						|
            return value
 | 
						|
        else:
 | 
						|
            return json.loads(value, cls=JobDecoder, env=record.env)
 | 
						|
 | 
						|
 | 
						|
class JobEncoder(json.JSONEncoder):
 | 
						|
    """ Encode Odoo recordsets so that we can later recompose them """
 | 
						|
 | 
						|
    def default(self, obj):
 | 
						|
        if isinstance(obj, models.BaseModel):
 | 
						|
            return {'_type': 'odoo_recordset',
 | 
						|
                    'model': obj._name,
 | 
						|
                    'ids': obj.ids,
 | 
						|
                    'uid': obj.env.uid,
 | 
						|
                    }
 | 
						|
        elif isinstance(obj, datetime):
 | 
						|
            return {'_type': 'datetime_isoformat',
 | 
						|
                    'value': obj.isoformat()}
 | 
						|
        elif isinstance(obj, date):
 | 
						|
            return {'_type': 'date_isoformat',
 | 
						|
                    'value': obj.isoformat()}
 | 
						|
        return json.JSONEncoder.default(self, obj)
 | 
						|
 | 
						|
 | 
						|
class JobDecoder(json.JSONDecoder):
 | 
						|
    """ Decode json, recomposing recordsets """
 | 
						|
 | 
						|
    def __init__(self, *args, **kwargs):
 | 
						|
        env = kwargs.pop('env')
 | 
						|
        super(JobDecoder, self).__init__(
 | 
						|
            object_hook=self.object_hook, *args, **kwargs
 | 
						|
        )
 | 
						|
        assert env
 | 
						|
        self.env = env
 | 
						|
 | 
						|
    def object_hook(self, obj):
 | 
						|
        if '_type' not in obj:
 | 
						|
            return obj
 | 
						|
        type_ = obj['_type']
 | 
						|
        if type_ == 'odoo_recordset':
 | 
						|
            model = self.env[obj['model']]
 | 
						|
            if obj.get('uid'):
 | 
						|
                model = model.sudo(obj['uid'])
 | 
						|
            return model.browse(obj['ids'])
 | 
						|
        elif type_ == 'datetime_isoformat':
 | 
						|
            return dateutil.parser.parse(obj['value'])
 | 
						|
        elif type_ == 'date_isoformat':
 | 
						|
            return dateutil.parser.parse(obj['value']).date()
 | 
						|
        return obj
 |