def startElement(self, name, attributes):

        # Manage the top level tag
        if name == "record":
            self.model = self.mh.pool.get(attributes["model"])
            assert self.model, "The model %s does not exist !" % \
                    (attributes["model"],)

            self.xml_id = attributes["id"]
            self.update = bool(int(attributes.get('update', '0')))

            # create/update a dict containing fields values
            self.values = {}

            self.current_field = None
            self.cdata = False

            return self.xml_id

        # Manage included tags:
        elif name == "field":

            field_name = attributes['name']
            field_type = attributes.get('type', '')
            # Create a new entry in the values
            self.values[field_name] = ""
            # Remind the current name (see characters)
            self.current_field = field_name
            # Put a flag to escape cdata tags
            if field_type == "xml":
                self.cdata = "start"

            # Catch the known attributes
            search_attr = attributes.get('search', '')
            ref_attr = attributes.get('ref', '')
            eval_attr = attributes.get('eval', '')

            if search_attr:
                search_model = self.model._columns[field_name].model_name
                f_obj = self.mh.pool.get(search_model)
                with Transaction().set_context(active_test=False):
                    self.values[field_name], = \
                            f_obj.search(safe_eval(search_attr))

            elif ref_attr:
                self.values[field_name] = self.mh.get_id(ref_attr)

            elif eval_attr:
                context = {}
                context['time'] = time
                context['version'] = VERSION.rsplit('.', 1)[0]
                context['ref'] = self.mh.get_id
                context['obj'] = lambda *a: 1
                self.values[field_name] = safe_eval(eval_attr, context)

        else:
            raise Exception("Tags '%s' not supported inside tag record." %
                    (name,))
    def _clean_value(key, browse_record, object_ref):
        """
        Take a field name, a browse_record, and a reference to the
        corresponding object.  Return a raw value has it must look on the
        db.
        """

        # search the field type in the object or in a parent
        if key in object_ref._columns:
            field_type = object_ref._columns[key]._type
        else:
            field_type = object_ref._inherit_fields[key][2]._type

        # handle the value regarding to the type
        if field_type == 'many2one':
            return browse_record[key] and browse_record[key].id or None
        elif field_type == 'reference':
            if not browse_record[key]:
                return None
            ref_mode, ref_id = browse_record[key].split(',', 1)
            try:
                ref_id = safe_eval(ref_id)
            except Exception:
                pass
            if isinstance(ref_id, (list, tuple)):
                ref_id = ref_id[0]
            return ref_mode + ',' + str(ref_id)
        elif field_type in ['one2many', 'many2many']:
            raise Unhandled_field("Unhandled field %s" % key)
        else:
            return browse_record[key]
Example #3
0
    def _clean_value(key, record):
        """
        Take a field name, a browse_record, and a reference to the
        corresponding object.  Return a raw value has it must look on the
        db.
        """
        Model = record.__class__
        # search the field type in the object or in a parent
        field_type = Model._fields[key]._type

        # handle the value regarding to the type
        if field_type == 'many2one':
            return getattr(record, key).id if getattr(record, key) else None
        elif field_type == 'reference':
            if not getattr(record, key):
                return None
            elif not isinstance(getattr(record, key), basestring):
                return str(getattr(record, key))
            ref_mode, ref_id = getattr(record, key).split(',', 1)
            try:
                ref_id = safe_eval(ref_id)
            except Exception:
                pass
            if isinstance(ref_id, (list, tuple)):
                ref_id = ref_id[0]
            return ref_mode + ',' + str(ref_id)
        elif field_type in ['one2many', 'many2many']:
            raise Unhandled_field("Unhandled field %s" % key)
        else:
            return getattr(record, key)
 def get_unit_price(self):
     '''
     Return unit price (as Decimal)
     '''
     context = Transaction().context.copy()
     context['Decimal'] = Decimal
     return safe_eval(decistmt(self.formula), context)
    def init(cursor):
        from trytond.tools import safe_eval
        sql_file = os.path.join(os.path.dirname(__file__), 'init.sql')
        with open(sql_file) as fp:
            for line in fp.read().split(';'):
                if (len(line) > 0) and (not line.isspace()):
                    cursor.execute(line)

        for i in ('ir', 'res', 'webdav'):
            root_path = os.path.join(os.path.dirname(__file__), '..', '..')
            tryton_file = os.path.join(root_path, i, '__tryton__.py')
            with open(tryton_file) as fp:
                info = safe_eval(fp.read())
            active = info.get('active', False)
            if active:
                state = 'to install'
            else:
                state = 'uninstalled'
            cursor.execute('INSERT INTO ir_module_module ' \
                    '(create_uid, create_date, author, website, name, ' \
                    'shortdesc, description, state) ' \
                    'VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
                    (0, datetime.datetime.now(), info.get('author', ''),
                info.get('website', ''), i, info.get('name', False),
                info.get('description', ''), state))
            cursor.execute('SELECT last_insert_rowid()')
            module_id = cursor.fetchone()[0]
            dependencies = info.get('depends', [])
            for dependency in dependencies:
                cursor.execute('INSERT INTO ir_module_module_dependency ' \
                        '(create_uid, create_date, module, name) ' \
                        'VALUES (%s, %s, %s, %s) ',
                        (0, datetime.datetime.now(), module_id, dependency))
def create_graph(module_list):
    graph = Graph()
    packages = []

    for module in module_list:
        tryton_file = OPJ(MODULES_PATH, module, '__tryton__.py')
        mod_path = OPJ(MODULES_PATH, module)
        if module in ('ir', 'res', 'webdav', 'test'):
            root_path = os.path.abspath(os.path.dirname(
                    os.path.dirname(__file__)))
            tryton_file = OPJ(root_path, module, '__tryton__.py')
            mod_path = OPJ(root_path, module)
        elif module in EGG_MODULES:
            ep = EGG_MODULES[module]
            tryton_file = OPJ(ep.dist.location, 'trytond', 'modules', module,
                    '__tryton__.py')
            mod_path = OPJ(ep.dist.location, 'trytond', 'modules', module)
            if not os.path.isfile(tryton_file) or not os.path.isdir(mod_path):
                # When testing modules from setuptools location is the module
                # directory
                tryton_file = OPJ(ep.dist.location, '__tryton__.py')
                mod_path = os.path.dirname(ep.dist.location)
        if os.path.isfile(tryton_file):
            with tools.file_open(tryton_file, subdir='') as fp:
                info = tools.safe_eval(fp.read())
            packages.append((module, info.get('depends', []),
                    info.get('extras_depend', []), info))
        elif module != 'all':
            raise Exception('Module %s not found' % module)

    current, later = set([x[0] for x in packages]), set()
    all_packages = set(current)
    while packages and current > later:
        package, deps, xdep, info = packages[0]

        # if all dependencies of 'package' are already in the graph,
        # add 'package' in the graph
        all_deps = deps + [x for x in xdep if x in all_packages]
        if reduce(lambda x, y: x and y in graph, all_deps, True):
            if not package in current:
                packages.pop(0)
                continue
            later.clear()
            current.remove(package)
            graph.add_node(package, all_deps)
            node = Node(package, graph)
            node.info = info
        else:
            later.add(package)
            packages.append((package, deps, xdep, info))
        packages.pop(0)

    for package, deps, xdep, info in packages:
        if package not in later:
            continue
        missings = [x for x in deps if x not in graph]
        raise Exception('%s unmet dependencies: %s' % (package, missings))
    return graph, packages, later
    def _engine_python(self, expression, record):
        '''Evaluate the pythonic expression and return its value
        '''
        if expression is None:
            return u''

        assert record is not None, 'Record is undefined'
        template_context = self.template_context(record)
        return safe_eval(expression, template_context)
    def _engine_python(self, expression, record):
        '''Evaluate the pythonic expression and return its value
        '''
        if expression is None:
            return u''

        assert record is not None, 'Record is undefined'
        template_context = self.template_context(record)
        return safe_eval(expression, template_context)
Example #9
0
 def get_fields(self, ids, names):
     if not ids:
         return {}
     res={}
     for line in self.browse(ids):
         all_add_options = False
         if line.add_options:
             all_add_options = safe_eval(line.add_options,{
                 'Decimal': Decimal,
                 'datetime': datetime})
         for name in names:
             res.setdefault(name, {})
             res[name].setdefault(line.id, False)
             if name == 'number_doc':
                 if name == 'number_doc':
                     if line.type_transaction in ('expense', 'expense_tax') :
                         res[name][line.id] = line.number_our
                     else:
                         res[name][line.id] = line.number_in
             elif name == 'state_doc':
                 res[name][line.id] = line.state
             elif name == 'from_party_doc':
                 res[name][line.id] = line.from_party.id
             elif name == 'to_party_doc':
                 res[name][line.id] = line.to_party.id
             elif name == 'template_bank':
                 res[name][line.id] = line.template.id
             elif name == 'content':
                 res[name][line.id] = line.note
             elif all_add_options and name == 'pole_order':
                 res[name][line.id] = all_add_options.get('pole_order')
             elif all_add_options and name == 'pole_type':
                 res[name][line.id] = all_add_options.get('pole_type')
             elif all_add_options and name == 'pole_maturity':
                 res[name][line.id] = all_add_options.get('pole_maturity')
             elif all_add_options and name == 'pole_detail':
                 res[name][line.id] = all_add_options.get('pole_detail')
             elif all_add_options and name == 'pole_code':
                 res[name][line.id] = all_add_options.get('pole_code')
             elif all_add_options and name == 'pole_reserve':
                 res[name][line.id] = all_add_options.get('pole_reserve')
             elif all_add_options and name == 'kind_payment_tax':
                 res[name][line.id] = all_add_options.get('kind_payment_tax')
             elif all_add_options and name == 'status_payer_tax':
                 res[name][line.id] = all_add_options.get('status_payer_tax')
             elif all_add_options and name == 'kbk_indicator':
                 res[name][line.id] = all_add_options.get('kbk_indicator')
             elif all_add_options and name == 'okato_indicator':
                 res[name][line.id] = all_add_options.get('okato_indicator')
             elif all_add_options and name == 'payment_details_tax':
                 res[name][line.id] = all_add_options.get('payment_details_tax')
             elif all_add_options and name == 'number_doc_base_tax':
                 res[name][line.id] = all_add_options.get('number_doc_base_tax')
             elif all_add_options and name == 'tax_period':
                 res[name][line.id] = all_add_options.get('tax_period')
     return res
Example #10
0
 def _search_quantity_eval_domain(line, domain):
     field, operator, operand = domain
     value = line.get(field)
     if value is None:
         return False
     if operator not in ("=", ">=", "<=", ">", "<", "!="):
         return False
     if operator == "=":
         operator = "=="
     return (safe_eval(str(value) + operator + str(operand)))
Example #11
0
 def encode(element):
     for attr in ('states', 'domain', 'spell', 'colors'):
         if element.get(attr):
             try:
                 value = safe_eval(element.get(attr), CONTEXT)
                 validates.get(attr, lambda a: True)(value)
             except Exception, e:
                 cls.logger.error('Invalid pyson view element "%s:%s":'
                     '\n%s\n%s'
                     % (element.get('id') or element.get('name'),
                         attr, str(e), xml))
                 return False
Example #12
0
 def get_module_info(name):
     "Return the content of the __tryton__.py"
     try:
         if name in ['ir', 'res', 'webdav']:
             file_p = tools.file_open(os.path.join(name, '__tryton__.py'))
         else:
             file_p = tools.file_open(os.path.join(name, '__tryton__.py'))
         with file_p:
             data = file_p.read()
         info = tools.safe_eval(data)
     except Exception:
         return {}
     return info
Example #13
0
 def encode(element):
     for attr in ("states", "domain", "context", "digits", "add_remove", "spell", "colors"):
         if element.get(attr):
             try:
                 value = safe_eval(element.get(attr), CONTEXT)
                 validates.get(attr, lambda a: True)(value)
             except Exception, e:
                 logger = logging.getLogger("ir")
                 logger.error(
                     'Invalid pyson view element "%s:%s":'
                     "\n%s\n%s" % (element.get("id") or element.get("name"), attr, str(e), xml)
                 )
                 return False
Example #14
0
 def check_mon_grouping(self):
     '''
     Check if mon_grouping is list of numbers
     '''
     try:
         grouping = safe_eval(self.mon_grouping)
         for i in grouping:
             if not isinstance(i, int):
                 raise ValueError
     except Exception:
         self.raise_user_error('invalid_mon_grouping', {
                 'grouping': self.mon_grouping,
                 'currency': self.rec_name,
                 })
    def compute_formula(self, id, formula, values={}):
        minus = 1
        if formula[:1] == '-':
            minus = -1
            formula = formula[1:]
        if formula == 'AmountDoc':
            return values['AmountDoc'] * minus
        elif formula == 'AmountLine':
            return values['AmountLine'] * minus
        elif formula == 'AmountAnalytic':
            return values['AmountAnalytic'] * minus
        elif formula == 'AmountTax':
            return values['AmountTax'] * minus
        #raise Exception(str(values))

        context = Transaction().context
        line_obj = self.pool.get('ekd.account.move.line.template')
        line = line_obj.browse(id)

        return safe_eval(
            formula, {
                'turnover': self.turnover,
                'balance': self.balance,
                'Period': self.period,
                'Date': self.date,
                'FromParty': line.ct_analytic,
                'ToParty': line.dt_analytic,
                'AccountDt': line.dt_account.id,
                'AccountCt': line.ct_account.id,
                'Debit': 1,
                'Credit': -1,
                'AmountDoc': Decimal('0.0'),
                'AmountDocTax': Decimal('0.0'),
                'AmountLine': Decimal('0.0'),
                'AmountLineTax': Decimal('0.0'),
                'AmountAnalytic': Decimal('0.0'),
                'AmountFixed': Decimal('0.0'),
                'AmountIntagible': Decimal('0.0'),
                'AmountMaterial': Decimal('0.0'),
                'AmountGoods': Decimal('0.0'),
                'AmountSupplier': Decimal('0.0'),
                'AmountCustomer': Decimal('0.0'),
                'AmountEmployee': Decimal('0.0'),
                'CurrentPeriod': context.get('current_period'),
                'FiscalYear': context.get('fiscalyear'),
                'StartDate': context.get('start_period'),
                'EndDate': context.get('end_period'),
                'CurrentDate': context.get('current_date'),
            }.update(values))
    def compute_formula(self, id, formula, values={}):
        minus = 1
        if formula[:1] == '-':
            minus = -1
            formula = formula[1:]
        if formula == 'AmountDoc':
            return values['AmountDoc']*minus
        elif formula == 'AmountLine':
            return values['AmountLine']*minus
        elif formula == 'AmountAnalytic':
            return values['AmountAnalytic']*minus
        elif formula == 'AmountTax':
            return values['AmountTax']*minus
        #raise Exception(str(values))
       
        context = Transaction().context
        line_obj = self.pool.get('ekd.account.move.line.template')
        line = line_obj.browse(id)

        return safe_eval(formula, {
                    'turnover': self.turnover,
                    'balance': self.balance,
                    'Period': self.period,
                    'Date': self.date,
                    'FromParty': line.ct_analytic,
                    'ToParty': line.dt_analytic,
                    'AccountDt': line.dt_account.id,
                    'AccountCt': line.ct_account.id,
                    'Debit': 1,
                    'Credit': -1,
                    'AmountDoc': Decimal('0.0'),
                    'AmountDocTax': Decimal('0.0'),
                    'AmountLine': Decimal('0.0'),
                    'AmountLineTax': Decimal('0.0'),
                    'AmountAnalytic': Decimal('0.0'),
                    'AmountFixed': Decimal('0.0'),
                    'AmountIntagible': Decimal('0.0'),
                    'AmountMaterial': Decimal('0.0'),
                    'AmountGoods': Decimal('0.0'),
                    'AmountSupplier': Decimal('0.0'),
                    'AmountCustomer': Decimal('0.0'),
                    'AmountEmployee': Decimal('0.0'),
                    'CurrentPeriod': context.get('current_period'),
                    'FiscalYear': context.get('fiscalyear'),
                    'StartDate': context.get('start_period'),
                    'EndDate': context.get('end_period'),
                    'CurrentDate': context.get('current_date'),
                    }.update(values))
    def check_xml_record(self, ids, values):
        """
        Check if a list of records and their corresponding fields are
        originating from xml data. This is used by write and delete
        functions: if the return value is True the records can be
        written/deleted, False otherwise. The default behaviour is to
        forbid any modification on records/fields originating from
        xml. Values is the dictionary of written values. If values is
        equal to None, no field by field check is performed, False is
        returned as soon as one of the record comes from the xml.

        :param ids: a list of ids or an id
        :param values: a dictionary with field names as key and
            written values as value
        :return: True or False
        """
        model_data_obj = Pool().get('ir.model.data')
        # Allow root user to update/delete
        if Transaction().user == 0:
            return True
        if isinstance(ids, (int, long)):
            ids = [ids]
        with Transaction().set_user(0):
            model_data_ids = model_data_obj.search([
                ('model', '=', self._name),
                ('db_id', 'in', ids),
                ])
            if not model_data_ids:
                return True
            if values == None:
                return False
            for line in model_data_obj.browse(model_data_ids):
                if not line.values:
                    continue
                xml_values = safe_eval(line.values, {
                    'Decimal': Decimal,
                    'datetime': datetime,
                    })
                for key, val in values.iteritems():
                    if key in xml_values and val != xml_values[key]:
                        return False
        return True
Example #18
0
    def set_fields_add(self, ids, name, value):
        if isinstance(ids, list):
            ids = ids[0]
        if not value:
            return
        all_add_options = {}
        document = self.browse(ids)
        if document.add_options:
            all_add_options = safe_eval(document.add_options, {
                'Decimal': Decimal,
                'datetime': datetime
            })

        if name == 'pole_order':
            all_add_options['pole_order'] = value
        elif name == 'pole_type':
            all_add_options['pole_type'] = value
        elif name == 'pole_maturity':
            all_add_options['pole_maturity'] = value
        elif name == 'pole_detail':
            all_add_options['pole_detail'] = value
        elif name == 'pole_code':
            all_add_options['pole_code'] = value
        elif name == 'pole_reserve':
            all_add_options['pole_reserve'] = value
        elif name == 'kind_payment_tax':
            all_add_options['kind_payment_tax'] = value
        elif name == 'status_payer_tax':
            all_add_options['status_payer_tax'] = value
        elif name == 'kbk_indicator':
            all_add_options['kbk_indicator'] = value
        elif name == 'okato_indicator':
            all_add_options['okato_indicator'] = value
        elif name == 'payment_details_tax':
            all_add_options['payment_details_tax'] = value
        elif name == 'number_doc_base_tax':
            all_add_options['number_doc_base_tax'] = value
        elif name == 'tax_period':
            all_add_options['tax_period'] = value

        self.write(ids, {'add_options': str(all_add_options)})
Example #19
0
    def set_fields_add(self, ids, name, value):
        if isinstance(ids, list):
            ids = ids[0]
        if not value:
            return
        all_add_options = {}
        document = self.browse(ids)
        if document.add_options:
            all_add_options = safe_eval(document.add_options, {
                    'Decimal': Decimal,
                    'datetime': datetime})

        if name == 'pole_order':
            all_add_options['pole_order'] = value
        elif name == 'pole_type':
            all_add_options['pole_type'] = value
        elif name == 'pole_maturity':
            all_add_options['pole_maturity'] = value
        elif name == 'pole_detail':
            all_add_options['pole_detail'] = value
        elif name == 'pole_code':
            all_add_options['pole_code'] = value
        elif name == 'pole_reserve':
            all_add_options['pole_reserve'] = value
        elif name == 'kind_payment_tax':
            all_add_options['kind_payment_tax'] = value
        elif name == 'status_payer_tax':
            all_add_options['status_payer_tax'] = value
        elif name == 'kbk_indicator':
            all_add_options['kbk_indicator'] = value
        elif name == 'okato_indicator':
            all_add_options['okato_indicator'] = value
        elif name == 'payment_details_tax':
            all_add_options['payment_details_tax'] = value
        elif name == 'number_doc_base_tax':
            all_add_options['number_doc_base_tax'] = value
        elif name == 'tax_period':
            all_add_options['tax_period'] = value

        self.write(ids, {'add_options': str(all_add_options)})
Example #20
0
    def get_path(cls, attachments, name):
        pool = Pool()
        Collection = pool.get('webdav.collection')
        paths = dict((a.id, None) for a in attachments)

        resources = {}
        resource2attachments = {}
        for attachment in attachments:
            if not attachment.resource:
                paths[attachment.id] = None
                continue
            model_name = attachment.resource.__name__
            record_id = attachment.resource.id
            resources.setdefault(model_name, set()).add(record_id)
            resource2attachments.setdefault((model_name, record_id),
                []).append(attachment)
        collections = Collection.search([
                ('model.model', 'in', resources.keys()),
                ])
        for collection in collections:
            model_name = collection.model.model
            Model = pool.get(model_name)
            ids = list(resources[model_name])
            domain = safe_eval(collection.domain or '[]')
            domain = [domain, ('id', 'in', ids)]
            records = Model.search(domain)
            for record in records:
                for attachment in resource2attachments[
                        (model_name, record.id)]:
                    paths[attachment.id] = '/'.join((collection.rec_name,
                            record.rec_name + '-' + str(record.id),
                            attachment.name))
        if 'webdav.collection' in resources:
            collection_ids = list(resources['webdav.collection'])
            for collection in Collection.browse(collection_ids):
                for attachment in resource2attachments[
                        ('webdav.collection', collection.id)]:
                    paths[attachment.id] = '/'.join((collection.rec_name,
                            attachment.name))
        return paths
Example #21
0
    def get_path(self, ids, name):
        pool = Pool()
        collection_obj = pool.get('webdav.collection')
        paths = dict((x, None) for x in ids)

        attachments = self.browse(ids)
        resources = {}
        resource2attachments = {}
        for attachment in attachments:
            if not attachment.resource:
                paths[attachment.id] = None
            model_name, record_id = attachment.resource.split(',')
            record_id = int(record_id)
            resources.setdefault(model_name, set()).add(record_id)
            resource2attachments.setdefault((model_name, record_id),
                []).append(attachment)
        collection_ids = collection_obj.search([
                ('model.model', 'in', resources.keys()),
                ])
        for collection in collection_obj.browse(collection_ids):
            model_name = collection.model.model
            model_obj = pool.get(model_name)
            ids = list(resources[model_name])
            domain = safe_eval(collection.domain or '[]')
            domain = [domain, ('id', 'in', ids)]
            record_ids = model_obj.search(domain)
            for record in model_obj.browse(record_ids):
                for attachment in resource2attachments[
                        (model_name, record.id)]:
                    paths[attachment.id] = '/'.join((collection.rec_name,
                            record.rec_name + '-' + str(record.id),
                            attachment.name))
        if 'webdav.collection' in resources:
            collection_ids = list(resources['webdav.collection'])
            for collection in collection_obj.browse(collection_ids):
                for attachment in resource2attachments[
                        ('webdav.collection', collection.id)]:
                    paths[attachment.id] = '/'.join((collection.rec_name,
                            attachment.name))
        return paths
Example #22
0
    def __view_look_dom(cls, element, type, fields_width=None,
            fields_attrs=None):
        pool = Pool()
        Translation = pool.get('ir.translation')
        ModelData = pool.get('ir.model.data')
        Button = pool.get('ir.model.button')
        User = pool.get('res.user')

        if fields_width is None:
            fields_width = {}
        if not fields_attrs:
            fields_attrs = {}
        else:
            fields_attrs = copy.deepcopy(fields_attrs)
        childs = True

        if element.tag in ('field', 'label', 'separator', 'group', 'suffix',
                'prefix'):
            for attr in ('name', 'icon', 'geometry'):
                if element.get(attr):
                    fields_attrs.setdefault(element.get(attr), {})
                    try:
                        field = cls._fields[element.get(attr)]
                        if hasattr(field, 'model_name'):
                            relation = field.model_name
                        else:
                            relation = field.get_target().__name__
                    except Exception:
                        relation = False
                    if relation and element.tag == 'field':
                        childs = False
                        views = {}
                        mode = (element.attrib.pop('mode', None)
                            or 'tree,form').split(',')
                        view_ids = []
                        if element.get('view_ids'):
                            for view_id in element.get('view_ids').split(','):
                                try:
                                    view_ids.append(int(view_id))
                                except ValueError:
                                    view_ids.append(ModelData.get_id(
                                            *view_id.split('.')))
                        Relation = pool.get(relation)
                        if (not len(element)
                                and type == 'form'
                                and field._type in ('one2many', 'many2many')):
                            # Prefetch only the first view to prevent infinite
                            # loop
                            if view_ids:
                                for view_id in view_ids:
                                    view = Relation.fields_view_get(
                                        view_id=view_id)
                                    views[str(view_id)] = view
                                    break
                            else:
                                for view_type in mode:
                                    views[view_type] = \
                                        Relation.fields_view_get(
                                            view_type=view_type)
                                    break
                        element.attrib['mode'] = ','.join(mode)
                        element.attrib['view_ids'] = ','.join(
                            map(str, view_ids))
                        fields_attrs[element.get(attr)].setdefault('views', {}
                            ).update(views)
            if element.get('name') in fields_width:
                element.set('width', str(fields_width[element.get('name')]))

        # convert attributes into pyson
        encoder = PYSONEncoder()
        for attr in ('states', 'domain', 'spell', 'colors'):
            if element.get(attr):
                element.set(attr, encoder.encode(safe_eval(element.get(attr),
                    CONTEXT)))

        if element.tag == 'button':
            button_name = element.attrib['name']
            if button_name in cls._buttons:
                states = cls._buttons[button_name]
            else:
                states = {}
            groups = set(User.get_groups())
            button_groups = Button.get_groups(cls.__name__, button_name)
            if button_groups and not groups & button_groups:
                states = states.copy()
                states['readonly'] = True
            element.set('states', encoder.encode(states))

        # translate view
        if Transaction().language != 'en_US':
            for attr in ('string', 'sum', 'confirm', 'help'):
                if element.get(attr):
                    trans = Translation.get_source(cls.__name__, 'view',
                            Transaction().language, element.get(attr))
                    if trans:
                        element.set(attr, trans)

        # Set header string
        if element.tag in ('form', 'tree', 'graph'):
            element.set('string', cls.view_header_get(
                element.get('string') or '', view_type=element.tag))

        if element.tag == 'tree' and element.get('sequence'):
            fields_attrs.setdefault(element.get('sequence'), {})

        if childs:
            for field in element:
                fields_attrs = cls.__view_look_dom(field, type,
                    fields_width=fields_width, fields_attrs=fields_attrs)
        return fields_attrs
Example #23
0
    def fields_view_get(cls, view_id=None, view_type='form'):
        '''
        Return a view definition.
        If view_id is None the first one will be used of view_type.
        The definition is a dictionary with keys:
           - model: the model name
           - arch: the xml description of the view
           - fields: a dictionary with the definition of each field in the view
        '''
        key = (cls.__name__, view_id, view_type)
        result = cls._fields_view_get_cache.get(key)
        if result:
            return result
        result = {'model': cls.__name__}
        pool = Pool()
        View = pool.get('ir.ui.view')

        test = True
        model = True
        view = None
        inherit_view_id = False
        while test:
            if view_id:
                domain = [('id', '=', view_id)]
                if model:
                    domain.append(('model', '=', cls.__name__))
                views = View.search(domain, order=[])
            else:
                domain = [
                    ('model', '=', cls.__name__),
                    ('type', '=', view_type),
                    ]
                order = [
                    ('inherit', 'DESC'),
                    ('priority', 'ASC'),
                    ('id', 'ASC'),
                    ]
                views = View.search(domain, order=order)
            if not views:
                break
            view = views[0]
            test = view.inherit
            if test:
                inherit_view_id = view.id
            view_id = test.id if test else view.id
            model = False

        # if a view was found
        if view:
            result['type'] = view.type
            result['view_id'] = view_id
            result['arch'] = view.arch
            result['field_childs'] = view.field_childs

            # Check if view is not from an inherited model
            if view.model != cls.__name__:
                Inherit = pool.get(view.model)
                result['arch'] = Inherit.fields_view_get(
                        result['view_id'])['arch']
                view_id = inherit_view_id

            # get all views which inherit from (ie modify) this view
            views = View.search([
                    'OR', [
                        ('inherit', '=', view_id),
                        ('model', '=', cls.__name__),
                        ], [
                        ('id', '=', view_id),
                        ('inherit', '!=', None),
                        ],
                    ],
                order=[
                    ('priority', 'ASC'),
                    ('id', 'ASC'),
                    ])
            raise_p = False
            while True:
                try:
                    views.sort(key=lambda x:
                        cls._modules_list.index(x.module or None))
                    break
                except ValueError:
                    if raise_p:
                        raise
                    # There is perhaps a new module in the directory
                    ModelView._reset_modules_list()
                    raise_p = True
            for view in views:
                if view.domain:
                    if not safe_eval(view.domain,
                            {'context': Transaction().context}):
                        continue
                if not view.arch or not view.arch.strip():
                    continue
                result['arch'] = _inherit_apply(result['arch'], view.arch)

        # otherwise, build some kind of default view
        else:
            if view_type == 'form':
                res = cls.fields_get()
                xml = '''<?xml version="1.0"?>''' \
                    '''<form string="%s" col="4">''' % (cls.__doc__,)
                for i in res:
                    if i in ('create_uid', 'create_date',
                            'write_uid', 'write_date', 'id', 'rec_name'):
                        continue
                    if res[i]['type'] not in ('one2many', 'many2many'):
                        xml += '<label name="%s"/>' % (i,)
                        xml += '<field name="%s"/>' % (i,)
                        if res[i]['type'] == 'text':
                            xml += "<newline/>"
                    else:
                        xml += '<field name="%s" colspan="4"/>' % (i,)
                xml += "</form>"
            elif view_type == 'tree':
                field = 'id'
                if cls._rec_name in cls._fields:
                    field = cls._rec_name
                xml = '''<?xml version="1.0"?>''' \
                    '''<tree string="%s"><field name="%s"/></tree>''' \
                    % (cls.__doc__, field)
            else:
                xml = ''
            result['type'] = view_type
            result['arch'] = xml
            result['field_childs'] = False
            result['view_id'] = 0

        # Update arch and compute fields from arch
        parser = etree.XMLParser(remove_blank_text=True)
        tree = etree.fromstring(result['arch'], parser)
        xarch, xfields = cls._view_look_dom_arch(tree, result['type'],
                result['field_childs'])
        result['arch'] = xarch
        result['fields'] = xfields

        cls._fields_view_get_cache.set(key, result)
        return result
    def startElement(self, name, attributes):
        cursor = Transaction().cursor

        values = {}

        self.xml_id = attributes['id']

        for attr in ('name', 'icon', 'sequence', 'parent', 'action', 'groups'):
            if attributes.get(attr):
                values[attr] = attributes.get(attr)

        if attributes.get('active'):
            values['active'] = bool(safe_eval(attributes['active']))

        if values.get('parent'):
            values['parent'] = self.mh.get_id(values['parent'])

        action_name = None
        if values.get('action'):
            action_id = self.mh.get_id(values['action'])

            # TODO maybe use a prefetch for this:
            cursor.execute(cursor.limit_clause(
            "SELECT a.name, a.type, v.type, v.field_childs, icon.name " \
            "FROM ir_action a " \
                "LEFT JOIN ir_action_report report ON (a.id = report.action) "\
                "LEFT JOIN ir_action_act_window act ON (a.id = act.action) " \
                "LEFT JOIN ir_action_wizard wizard ON (a.id = wizard.action) "\
                "LEFT JOIN ir_action_url url ON (a.id = url.action) " \
                "LEFT JOIN ir_action_act_window_view wv ON " \
                    "(act.id = wv.act_window) " \
                "LEFT JOIN ir_ui_view v ON (v.id = wv.view) " \
                "LEFT JOIN ir_ui_icon icon ON (a.icon = icon.id) " \
            "WHERE report.id = %s " \
                "OR act.id = %s " \
                "OR wizard.id = %s " \
                "OR url.id = %s " \
            "ORDER by wv.sequence", 1),
            (action_id, action_id, action_id, action_id))
            action_name, action_type, view_type, field_childs, icon_name = \
                    cursor.fetchone()

            values['action'] = '%s,%s' % (action_type, action_id)

            icon = attributes.get('icon', '')
            if icon:
                values['icon'] = icon
            elif icon_name:
                values['icon'] = icon_name
            elif action_type == 'ir.action.wizard':
                values['icon'] = 'tryton-executable'
            elif action_type == 'ir.action.report':
                values['icon'] = 'tryton-print'
            elif action_type == 'ir.action.act_window':
                if view_type == 'tree':
                    if field_childs:
                        values['icon'] = 'tryton-tree'
                    else:
                        values['icon'] = 'tryton-list'
                elif view_type == 'form':
                    values['icon'] = 'tryton-new'
                elif view_type == 'graph':
                    values['icon'] = 'tryton-graph'
                elif view_type == 'calendar':
                    values['icon'] = 'tryton-calendar'
            elif action_type == 'ir.action.url':
                values['icon'] = 'tryton-web-browser'
            else:
                values['icon'] = 'tryton-new'

        if values.get('groups'):
            raise Exception("Please use separate records for groups")

        if not values.get('name'):
            if not action_name:
                raise Exception("Please provide at least a 'name' attributes "
                        "or a 'action' attributes on the menuitem tags.")
            else:
                values['name'] = action_name

        self.values = values
    def __view_look_dom(self, element, type, fields_width=None):
        pool = Pool()
        translation_obj = pool.get("ir.translation")
        model_data_obj = pool.get("ir.model.data")
        button_obj = pool.get("ir.model.button")
        user_obj = pool.get("res.user")

        if fields_width is None:
            fields_width = {}
        fields_attrs = {}
        childs = True

        if element.tag in ("field", "label", "separator", "group"):
            for attr in ("name", "icon"):
                if element.get(attr):
                    attrs = {}
                    try:
                        if element.get(attr) in self._columns:
                            field = self._columns[element.get(attr)]
                        else:
                            field = self._inherit_fields[element.get(attr)][2]
                        if hasattr(field, "model_name"):
                            relation = field.model_name
                        else:
                            relation = field.get_target()._name
                    except Exception:
                        relation = False
                    if relation and element.tag == "field":
                        childs = False
                        views = {}
                        mode = (element.attrib.pop("mode", None) or "tree,form").split(",")
                        view_ids = []
                        if element.get("view_ids"):
                            for view_id in element.get("view_ids").split(","):
                                try:
                                    view_ids.append(int(view_id))
                                except ValueError:
                                    view_ids.append(model_data_obj.get_id(*view_id.split(".")))
                        relation_obj = pool.get(relation)
                        if not len(element) and type == "form" and field._type in ("one2many", "many2many"):
                            # Prefetch only the first view to prevent infinite
                            # loop
                            if view_ids:
                                for view_id in view_ids:
                                    view = relation_obj.fields_view_get(view_id=view_id)
                                    views[view["type"]] = view
                                    break
                            else:
                                for view_type in mode:
                                    views[view_type] = relation_obj.fields_view_get(view_type=view_type)
                                    break
                        element.attrib["mode"] = ",".join(mode)
                        element.attrib["view_ids"] = ",".join(map(str, view_ids))
                        attrs = {"views": views}
                    fields_attrs[element.get(attr)] = attrs
            if element.get("name") in fields_width:
                element.set("width", str(fields_width[element.get("name")]))

        # convert attributes into pyson
        encoder = PYSONEncoder()
        for attr in ("states", "domain", "context", "digits", "add_remove", "spell", "colors"):
            if element.get(attr):
                element.set(attr, encoder.encode(safe_eval(element.get(attr), CONTEXT)))

        if element.tag == "button":
            if element.get("type", "object") == "object":
                assert not element.get("states")
                button_name = element.attrib["name"]
                if button_name in self._buttons:
                    states = self._buttons[button_name]
                else:
                    states = {}
                groups = set(user_obj.get_groups())
                button_groups = button_obj.get_groups(self._name, button_name)
                if button_groups and not groups & button_groups:
                    states = states.copy()
                    states["readonly"] = True
                element.set("states", encoder.encode(states))

        # translate view
        if Transaction().language != "en_US":
            for attr in ("string", "sum", "confirm", "help"):
                if element.get(attr):
                    trans = translation_obj.get_source(self._name, "view", Transaction().language, element.get(attr))
                    if trans:
                        element.set(attr, trans)

        # Set header string
        if element.tag in ("form", "tree", "graph"):
            element.set("string", self.view_header_get(element.get("string") or "", view_type=element.tag))

        if element.tag == "tree" and element.get("sequence"):
            fields_attrs.setdefault(element.get("sequence"), {})

        if childs:
            for field in element:
                fields_attrs.update(self.__view_look_dom(field, type, fields_width=fields_width))
        return fields_attrs
    def fields_view_get(self, view_id=None, view_type="form", hexmd5=None):
        """
        Return a view definition.

        :param view_id: the id of the view, if None the first one will be used
        :param view_type: the type of the view if view_id is None
        :param hexmd5: if filled, the function will return True if the result
            has the same md5
        :return: a dictionary with keys:
           - model: the model name
           - arch: the xml description of the view
           - fields: a dictionary with the definition of each field in the view
           - md5: the check sum of the dictionary without this checksum
        """
        result = {"model": self._name}
        pool = Pool()

        test = True
        model = True
        sql_res = False
        inherit_view_id = False
        cursor = Transaction().cursor
        while test:
            if view_id:
                where = (model and (" and model='%s'" % (self._name,))) or ""
                cursor.execute(
                    "SELECT arch, field_childs, id, type, " "inherit, model " "FROM ir_ui_view WHERE id = %s " + where,
                    (view_id,),
                )
            else:
                cursor.execute(
                    "SELECT arch, field_childs, id, type, "
                    "inherit, model "
                    "FROM ir_ui_view "
                    "WHERE model = %s AND type = %s "
                    "ORDER BY inherit DESC, priority ASC, id ASC",
                    (self._name, view_type),
                )
            sql_res = cursor.fetchone()
            if not sql_res:
                break
            test = sql_res[4]
            if test:
                inherit_view_id = sql_res[2]
            view_id = test or sql_res[2]
            model = False

        # if a view was found
        if sql_res:
            result["type"] = sql_res[3]
            result["view_id"] = view_id
            result["arch"] = sql_res[0]
            result["field_childs"] = sql_res[1] or False

            # Check if view is not from an inherited model
            if sql_res[5] != self._name:
                inherit_obj = pool.get(sql_res[5])
                result["arch"] = inherit_obj.fields_view_get(result["view_id"])["arch"]
                view_id = inherit_view_id

            # get all views which inherit from (ie modify) this view
            cursor.execute(
                "SELECT arch, domain, module FROM ir_ui_view "
                "WHERE (inherit = %s AND model = %s) OR "
                " (id = %s AND inherit IS NOT NULL) "
                "ORDER BY priority ASC, id ASC",
                (view_id, self._name, view_id),
            )
            sql_inherit = cursor.fetchall()
            raise_p = False
            while True:
                try:
                    sql_inherit.sort(key=lambda x: self._modules_list.index(x[2] or None))
                    break
                except ValueError:
                    if raise_p:
                        raise
                    # There is perhaps a new module in the directory
                    ModelView._reset_modules_list()
                    raise_p = True
            for arch, domain, _ in sql_inherit:
                if domain:
                    if not safe_eval(domain, {"context": Transaction().context}):
                        continue
                if not arch or not arch.strip():
                    continue
                result["arch"] = _inherit_apply(result["arch"], arch)

        # otherwise, build some kind of default view
        else:
            if view_type == "form":
                res = self.fields_get()
                xml = """<?xml version="1.0" encoding="utf-8"?>""" """<form string="%s">""" % (self._description,)
                for i in res:
                    if i in ("create_uid", "create_date", "write_uid", "write_date", "id", "rec_name"):
                        continue
                    if res[i]["type"] not in ("one2many", "many2many"):
                        xml += '<label name="%s"/>' % (i,)
                        xml += '<field name="%s"/>' % (i,)
                        if res[i]["type"] == "text":
                            xml += "<newline/>"
                xml += "</form>"
            elif view_type == "tree":
                field = "id"
                if self._rec_name in self._columns:
                    field = self._rec_name
                xml = """<?xml version="1.0" encoding="utf-8"?>""" """<tree string="%s"><field name="%s"/></tree>""" % (
                    self._description,
                    field,
                )
            else:
                xml = ""
            result["type"] = view_type
            result["arch"] = xml
            result["field_childs"] = False
            result["view_id"] = 0

        # Update arch and compute fields from arch
        parser = etree.XMLParser(remove_blank_text=True)
        tree = etree.fromstring(result["arch"], parser)
        xarch, xfields = self._view_look_dom_arch(tree, result["type"], result["field_childs"])
        result["arch"] = xarch
        result["fields"] = xfields

        # Compute md5
        if hashlib:
            result["md5"] = hashlib.md5(str(result)).hexdigest()
        else:
            result["md5"] = md5.new(str(result)).hexdigest()
        if hexmd5 == result["md5"]:
            return True
        return result
Example #27
0
    def __view_look_dom(cls, element, type, fields_width=None, fields_attrs=None):
        pool = Pool()
        Translation = pool.get("ir.translation")
        ModelData = pool.get("ir.model.data")
        Button = pool.get("ir.model.button")
        User = pool.get("res.user")

        if fields_width is None:
            fields_width = {}
        if not fields_attrs:
            fields_attrs = {}
        else:
            fields_attrs = copy.deepcopy(fields_attrs)
        childs = True

        if element.tag in ("field", "label", "separator", "group", "suffix", "prefix"):
            for attr in ("name", "icon"):
                if element.get(attr):
                    fields_attrs.setdefault(element.get(attr), {})
                    try:
                        field = cls._fields[element.get(attr)]
                        if hasattr(field, "model_name"):
                            relation = field.model_name
                        else:
                            relation = field.get_target().__name__
                    except Exception:
                        relation = False
                    if relation and element.tag == "field":
                        childs = False
                        views = {}
                        mode = (element.attrib.pop("mode", None) or "tree,form").split(",")
                        view_ids = []
                        if element.get("view_ids"):
                            for view_id in element.get("view_ids").split(","):
                                try:
                                    view_ids.append(int(view_id))
                                except ValueError:
                                    view_ids.append(ModelData.get_id(*view_id.split(".")))
                        Relation = pool.get(relation)
                        if not len(element) and type == "form" and field._type in ("one2many", "many2many"):
                            # Prefetch only the first view to prevent infinite
                            # loop
                            if view_ids:
                                for view_id in view_ids:
                                    view = Relation.fields_view_get(view_id=view_id)
                                    views[str(view_id)] = view
                                    break
                            else:
                                for view_type in mode:
                                    views[view_type] = Relation.fields_view_get(view_type=view_type)
                                    break
                        element.attrib["mode"] = ",".join(mode)
                        element.attrib["view_ids"] = ",".join(map(str, view_ids))
                        fields_attrs[element.get(attr)].setdefault("views", {}).update(views)
            if element.get("name") in fields_width:
                element.set("width", str(fields_width[element.get("name")]))

        # convert attributes into pyson
        encoder = PYSONEncoder()
        for attr in ("states", "domain", "context", "digits", "add_remove", "spell", "colors"):
            if element.get(attr):
                element.set(attr, encoder.encode(safe_eval(element.get(attr), CONTEXT)))

        if element.tag == "button":
            button_name = element.attrib["name"]
            if button_name in cls._buttons:
                states = cls._buttons[button_name]
            else:
                states = {}
            groups = set(User.get_groups())
            button_groups = Button.get_groups(cls.__name__, button_name)
            if button_groups and not groups & button_groups:
                states = states.copy()
                states["readonly"] = True
            element.set("states", encoder.encode(states))

        # translate view
        if Transaction().language != "en_US":
            for attr in ("string", "sum", "confirm", "help"):
                if element.get(attr):
                    trans = Translation.get_source(cls.__name__, "view", Transaction().language, element.get(attr))
                    if trans:
                        element.set(attr, trans)

        # Set header string
        if element.tag in ("form", "tree", "graph"):
            element.set("string", cls.view_header_get(element.get("string") or "", view_type=element.tag))

        if element.tag == "tree" and element.get("sequence"):
            fields_attrs.setdefault(element.get("sequence"), {})

        if childs:
            for field in element:
                fields_attrs = cls.__view_look_dom(field, type, fields_width=fields_width, fields_attrs=fields_attrs)
        return fields_attrs
Example #28
0
    def get_childs(self, uri, filter=None, cache=None):
        pool = Pool()
        report_obj = pool.get('ir.action.report')
        res = []
        if filter:
            return []
        if not uri:
            collection_ids = self.search([
                ('parent', '=', None),
                ])
            for collection in self.browse(collection_ids):
                if '/' in collection.name:
                    continue
                res.append(collection.name)
                if cache is not None:
                    cache.setdefault(self._name, {})
                    cache[self._name][collection.id] = {}
            return res
        object_name, object_id = self._uri2object(uri, cache=cache)
        if object_name == self._name and object_id:
            collection = self.browse(object_id)
            if collection.model:
                model_obj = pool.get(collection.model.model)
                if not model_obj:
                    return res
                model_ids = model_obj.search(
                        safe_eval(collection.domain or "[]"))
                for child in model_obj.browse(model_ids):
                    if '/' in child.rec_name:
                        continue
                    res.append(child.rec_name + '-' + str(child.id))
                    if cache is not None:
                        cache.setdefault(model_obj._name, {})
                        cache[model_obj._name][child.id] = {}
                return res
            else:
                for child in collection.childs:
                    if '/' in child.name:
                        continue
                    res.append(child.name)
                    if cache is not None:
                        cache.setdefault(self._name, {})
                        cache[self._name][child.id] = {}
        if object_name not in ('ir.attachment', 'ir.action.report'):
            report_ids = report_obj.search([
                ('model', '=', object_name),
                ])
            reports = report_obj.browse(report_ids)
            for report in reports:
                report_name = report.name + '-' + str(report.id) \
                        + '.' + report.extension
                if '/' in report_name:
                    continue
                res.append(report_name)
                if cache is not None:
                    cache.setdefault(report_obj._name, {})
                    cache[report_obj._name][report.id] = {}

            attachment_obj = pool.get('ir.attachment')
            attachment_ids = attachment_obj.search([
                ('resource', '=', '%s,%s' % (object_name, object_id)),
                ])
            for attachment in attachment_obj.browse(attachment_ids):
                if attachment.name and not attachment.link:
                    if '/' in attachment.name:
                        continue
                    res.append(attachment.name)
                    if cache is not None:
                        cache.setdefault(attachment_obj._name, {})
                        cache[attachment_obj._name][attachment.id] = {}
        return res
    def import_record(self, model, values, fs_id):
        module = self.module

        if not fs_id:
            raise Exception('import_record : Argument fs_id is mandatory')

        if '.' in fs_id:
            assert len(fs_id.split('.')) == 2, '"%s" contains too many dots. '\
                    'file system ids should contain ot most one dot ! ' \
                    'These are used to refer to other modules data, ' \
                    'as in module.reference_id' % (fs_id)

            module, fs_id = fs_id.split('.')
            if not self.fs2db.get(module, fs_id):
                raise Exception('Reference to %s.%s not found' % \
                        (module, fs_id))

        object_ref = self.pool.get(model)

        if self.fs2db.get(module, fs_id):

            # Remove this record from the to_delete list. This means that
            # the corresponding record have been found.
            if module == self.module and fs_id in self.to_delete:
                self.to_delete.remove(fs_id)

            if self.noupdate:
                return

            # this record is already in the db:
            # XXX maybe use only one call to get()
            db_id, db_model, mdata_id, old_values = \
                    [self.fs2db.get(module, fs_id)[x] for x in \
                    ["db_id", "model", "id", "values"]]
            inherit_db_ids = {}
            inherit_mdata_ids = []

            if not old_values:
                old_values = {}
            else:
                old_values = safe_eval(old_values, {
                    'Decimal': Decimal,
                    'datetime': datetime,
                    })

            for key in old_values:
                if isinstance(old_values[key], str):
                    # Fix for migration to unicode
                    old_values[key] = old_values[key].decode('utf-8')

            if model != db_model:
                raise Exception("This record try to overwrite " \
                "data with the wrong model: %s (module: %s)" % (fs_id, module))

            #Re-create record if it was deleted
            if not self.fs2db.get_browserecord(
                    module, object_ref._name, db_id):
                with Transaction().set_context(
                        module=module, language='en_US'):
                    db_id = object_ref.create(values)

                # reset_browsercord
                self.fs2db.reset_browsercord(module, object_ref._name, db_id)

                record = self.fs2db.get_browserecord(module, object_ref._name,
                        db_id)
                for table, field_name, field in \
                        object_ref._inherit_fields.values():
                    inherit_db_ids[table] = record[field_name].id

                for table in inherit_db_ids.keys():
                    data_id = self.modeldata_obj.search([
                        ('fs_id', '=', fs_id),
                        ('module', '=', module),
                        ('model', '=', table),
                        ], limit=1)
                    if data_id:
                        self.modeldata_obj.write(data_id, {
                            'db_id': inherit_db_ids[table],
                            'inherit': True,
                            })
                    else:
                        data_id = self.modeldata_obj.create({
                            'fs_id': fs_id,
                            'module': module,
                            'model': table,
                            'db_id': inherit_db_ids[table],
                            'inherit': True,
                            })
                    inherit_mdata_ids.append((table, data_id))

                data_id = self.modeldata_obj.search([
                    ('fs_id', '=', fs_id),
                    ('module', '=', module),
                    ('model', '=', object_ref._name),
                    ], limit=1)[0]
                self.modeldata_obj.write(data_id, {
                    'db_id': db_id,
                    })
                self.fs2db.get(module, fs_id)["db_id"] = db_id

            db_val = self.fs2db.get_browserecord(module, object_ref._name,
                    db_id)
            if not db_val:
                db_val = object_ref.browse(db_id)

            to_update = {}
            for key in values:

                db_field = self._clean_value(key, db_val, object_ref)

                # if the fs value is the same has in the db, whe ignore it
                val = values[key]
                if isinstance(values[key], str):
                    # Fix for migration to unicode
                    val = values[key].decode('utf-8')
                if db_field == val:
                    continue

                # we cannot update a field if it was changed by a user...
                if key not in old_values:
                    if key in object_ref._columns:
                        expected_value = object_ref._defaults.get(
                            key, lambda *a: None)()
                    else:
                        inherit_obj = self.pool.get(
                            object_ref._inherit_fields[key][0])
                        expected_value = inherit_obj._defaults.get(
                            key, lambda *a: None)()
                else:
                    expected_value = old_values[key]

                # Migration from 2.0: Reference field change value
                if key in object_ref._columns:
                    field_type = object_ref._columns[key]._type
                else:
                    field_type = object_ref._inherit_fields[key][2]._type
                if field_type == 'reference':
                    if (expected_value and expected_value.endswith(',0')
                            and not db_field):
                        db_field = expected_value

                # ... and we consider that there is an update if the
                # expected value differs from the actual value, _and_
                # if they are not false in a boolean context (ie None,
                # False, {} or [])
                if db_field != expected_value and (db_field or expected_value):
                    logging.getLogger("convert").warning(
                        "Field %s of %s@%s not updated (id: %s), because "\
                        "it has changed since the last update" % \
                        (key, db_id, model, fs_id))
                    continue

                # so, the field in the fs and in the db are different,
                # and no user changed the value in the db:
                to_update[key] = values[key]

            # if there is values to update:
            if to_update:
                # write the values in the db:
                with Transaction().set_context(
                        module=module, language='en_US'):
                    object_ref.write(db_id, to_update)
                self.fs2db.reset_browsercord(module, object_ref._name, db_id)

            if not inherit_db_ids:
                record = object_ref.browse(db_id)
                for table, field_name, field in \
                        object_ref._inherit_fields.values():
                    inherit_db_ids[table] = record[field_name].id
            if not inherit_mdata_ids:
                for table in inherit_db_ids.keys():
                    data_id = self.modeldata_obj.search([
                        ('fs_id', '=', fs_id),
                        ('module', '=', module),
                        ('model', '=', table),
                        ], limit=1)
                    inherit_mdata_ids.append((table, data_id))

            if to_update:
                # re-read it: this ensure that we store the real value
                # in the model_data table:
                db_val = self.fs2db.get_browserecord(module, object_ref._name,
                        db_id)
                if not db_val:
                    db_val = object_ref.browse(db_id)
                for key in to_update:
                    values[key] = self._clean_value(key, db_val, object_ref)

            if module != self.module:
                temp_values = old_values.copy()
                temp_values.update(values)
                values = temp_values

            if values != old_values:
                self.modeldata_obj.write(mdata_id, {
                    'fs_id': fs_id,
                    'model': model,
                    'module': module,
                    'db_id': db_id,
                    'values': str(values),
                    'date_update': datetime.datetime.now(),
                    })
                for table, inherit_mdata_id in inherit_mdata_ids:
                    self.modeldata_obj.write(inherit_mdata_id, {
                        'fs_id': fs_id,
                        'model': table,
                        'module': module,
                        'db_id': inherit_db_ids[table],
                        'values': str(values),
                        'date_update': datetime.datetime.now(),
                        })
            # reset_browsercord to keep cache memory low
            self.fs2db.reset_browsercord(module, object_ref._name, db_id)

        else:
            # this record is new, create it in the db:
            with Transaction().set_context(module=module, language='en_US'):
                db_id = object_ref.create(values)
            inherit_db_ids = {}

            record = object_ref.browse(db_id)
            for table, field_name, field in (
                    object_ref._inherit_fields.values()):
                inherit_db_ids[table] = record[field_name].id

            # re-read it: this ensure that we store the real value
            # in the model_data table:
            db_val = object_ref.browse(db_id)
            for key in values:
                values[key] = self._clean_value(key, db_val, object_ref)

            for table in inherit_db_ids.keys():
                self.modeldata_obj.create({
                    'fs_id': fs_id,
                    'model': table,
                    'module': module,
                    'db_id': inherit_db_ids[table],
                    'values': str(values),
                    'inherit': True,
                    'noupdate': self.noupdate,
                    })

            mdata_id = self.modeldata_obj.create({
                'fs_id': fs_id,
                'model': model,
                'module': module,
                'db_id': db_id,
                'values': str(values),
                'noupdate': self.noupdate,
                })

            # update fs2db:
            self.fs2db.set(module, fs_id, {
                    "db_id": db_id, "model": model,
                    "id": mdata_id, "values": str(values)})
            self.fs2db.reset_browsercord(module, model, db_id)
Example #30
0
)
JSONDecoder.register(
    'time',
    lambda dct: datetime.time(
        dct['hour'], dct['minute'], dct['second'], dct['microsecond']
    )
)
JSONDecoder.register(
    'buffer', lambda dct:
    buffer(base64.decodestring(dct['base64']))
)
JSONDecoder.register(
    'Decimal', lambda dct: Decimal(dct['decimal'])
)
JSONDecoder.register(
    'Model', lambda dct: safe_eval(dct['repr'], {'Pool': Pool})
)


class JSONEncoder(json.JSONEncoder):

    serializers = {}

    def __init__(self, *args, **kwargs):
        super(JSONEncoder, self).__init__(*args, **kwargs)
        # Force to use our custom decimal with simplejson
        self.use_decimal = False

    @classmethod
    def register(cls, klass, encoder):
        assert klass not in cls.serializers
        return dct


JSONDecoder.register(
    'datetime', lambda dct: datetime.datetime(dct['year'], dct['month'], dct[
        'day'], dct['hour'], dct['minute'], dct['second'], dct['microsecond']))
JSONDecoder.register(
    'date', lambda dct: datetime.date(dct['year'], dct['month'], dct['day']))
JSONDecoder.register(
    'time', lambda dct: datetime.time(dct['hour'], dct['minute'], dct[
        'second'], dct['microsecond']))
JSONDecoder.register('buffer',
                     lambda dct: buffer(base64.decodestring(dct['base64'])))
JSONDecoder.register('Decimal', lambda dct: Decimal(dct['decimal']))
JSONDecoder.register('Model',
                     lambda dct: safe_eval(dct['repr'], {'Pool': Pool}))


class JSONEncoder(json.JSONEncoder):

    serializers = {}

    def __init__(self, *args, **kwargs):
        super(JSONEncoder, self).__init__(*args, **kwargs)
        # Force to use our custom decimal with simplejson
        self.use_decimal = False

    @classmethod
    def register(cls, klass, encoder):
        assert klass not in cls.serializers
        cls.serializers[klass] = encoder
Example #32
0
    def fields_view_get(cls, view_id=None, view_type="form"):
        """
        Return a view definition.
        If view_id is None the first one will be used of view_type.
        The definition is a dictionary with keys:
           - model: the model name
           - arch: the xml description of the view
           - fields: a dictionary with the definition of each field in the view
        """
        key = (cls.__name__, view_id, view_type)
        result = cls._fields_view_get_cache.get(key)
        if result:
            return result
        result = {"model": cls.__name__}
        pool = Pool()
        View = pool.get("ir.ui.view")

        test = True
        model = True
        view = None
        inherit_view_id = False
        while test:
            if view_id:
                domain = [("id", "=", view_id)]
                if model:
                    domain.append(("model", "=", cls.__name__))
                views = View.search(domain, order=[])
            else:
                domain = [("model", "=", cls.__name__), ("type", "=", view_type)]
                order = [("inherit", "DESC"), ("priority", "ASC"), ("id", "ASC")]
                views = View.search(domain, order=order)
            if not views:
                break
            view = views[0]
            test = view.inherit
            if test:
                inherit_view_id = view.id
            view_id = test.id if test else view.id
            model = False

        # if a view was found
        if view:
            result["type"] = view.type
            result["view_id"] = view_id
            result["arch"] = view.arch
            result["field_childs"] = view.field_childs

            # Check if view is not from an inherited model
            if view.model != cls.__name__:
                Inherit = pool.get(view.model)
                result["arch"] = Inherit.fields_view_get(result["view_id"])["arch"]
                view_id = inherit_view_id

            # get all views which inherit from (ie modify) this view
            views = View.search(
                [
                    "OR",
                    [("inherit", "=", view_id), ("model", "=", cls.__name__)],
                    [("id", "=", view_id), ("inherit", "!=", None)],
                ],
                order=[("priority", "ASC"), ("id", "ASC")],
            )
            raise_p = False
            while True:
                try:
                    views.sort(key=lambda x: cls._modules_list.index(x.module or None))
                    break
                except ValueError:
                    if raise_p:
                        raise
                    # There is perhaps a new module in the directory
                    ModelView._reset_modules_list()
                    raise_p = True
            for view in views:
                if view.domain:
                    if not safe_eval(view.domain, {"context": Transaction().context}):
                        continue
                if not view.arch or not view.arch.strip():
                    continue
                result["arch"] = _inherit_apply(result["arch"], view.arch)

        # otherwise, build some kind of default view
        else:
            if view_type == "form":
                res = cls.fields_get()
                xml = """<?xml version="1.0"?>""" """<form string="%s" col="4">""" % (cls.__doc__,)
                for i in res:
                    if i in ("create_uid", "create_date", "write_uid", "write_date", "id", "rec_name"):
                        continue
                    if res[i]["type"] not in ("one2many", "many2many"):
                        xml += '<label name="%s"/>' % (i,)
                        xml += '<field name="%s"/>' % (i,)
                        if res[i]["type"] == "text":
                            xml += "<newline/>"
                    else:
                        xml += '<field name="%s" colspan="4"/>' % (i,)
                xml += "</form>"
            elif view_type == "tree":
                field = "id"
                if cls._rec_name in cls._fields:
                    field = cls._rec_name
                xml = """<?xml version="1.0"?>""" """<tree string="%s"><field name="%s"/></tree>""" % (
                    cls.__doc__,
                    field,
                )
            else:
                xml = ""
            result["type"] = view_type
            result["arch"] = xml
            result["field_childs"] = False
            result["view_id"] = 0

        # Update arch and compute fields from arch
        parser = etree.XMLParser(remove_blank_text=True)
        tree = etree.fromstring(result["arch"], parser)
        xarch, xfields = cls._view_look_dom_arch(tree, result["type"], result["field_childs"])
        result["arch"] = xarch
        result["fields"] = xfields

        cls._fields_view_get_cache.set(key, result)
        return result
Example #33
0
    def get_childs(cls, uri, filter=None, cache=None):
        pool = Pool()
        Report = pool.get('ir.action.report')
        res = []
        if filter:
            return []
        if not uri:
            collections = cls.search([
                ('parent', '=', None),
                ])
            for collection in collections:
                if '/' in collection.name:
                    continue
                res.append(collection.name)
                if cache is not None:
                    cache.setdefault(cls.__name__, {})
                    cache[cls.__name__][collection.id] = {}
            return res
        object_name, object_id = cls._uri2object(uri, cache=cache)
        if object_name == cls.__name__ and object_id:
            collection = cls(object_id)
            if collection.model:
                Model = pool.get(collection.model.model)
                if not Model:
                    return res
                models = Model.search(
                        safe_eval(collection.domain or "[]"))
                for child in models:
                    if '/' in child.rec_name:
                        continue
                    res.append(child.rec_name + '-' + str(child.id))
                    if cache is not None:
                        cache.setdefault(Model.__name__, {})
                        cache[Model.__name__][child.id] = {}
                return res
            else:
                for child in collection.childs:
                    if '/' in child.name:
                        continue
                    res.append(child.name)
                    if cache is not None:
                        cache.setdefault(cls.__name__, {})
                        cache[cls.__name__][child.id] = {}
        if object_name not in ('ir.attachment', 'ir.action.report'):
            reports = Report.search([
                ('model', '=', object_name),
                ])
            for report in reports:
                report_name = (report.name + '-' + str(report.id)
                    + '.' + report.extension)
                if '/' in report_name:
                    continue
                res.append(report_name)
                if cache is not None:
                    cache.setdefault(Report.__name__, {})
                    cache[Report.__name__][report.id] = {}

            Attachment = pool.get('ir.attachment')
            attachments = Attachment.search([
                    ('resource', '=', '%s,%s' % (object_name, object_id)),
                    ])
            for attachment in attachments:
                if attachment.name and not attachment.link:
                    if '/' in attachment.name:
                        continue
                    res.append(attachment.name)
                    if cache is not None:
                        cache.setdefault(Attachment.__name__, {})
                        cache[Attachment.__name__][attachment.id] = {}
        return res
Example #34
0
 def get_fields(self, ids, names):
     if not ids:
         return {}
     res = {}
     for line in self.browse(ids):
         all_add_options = False
         if line.add_options:
             all_add_options = safe_eval(line.add_options, {
                 'Decimal': Decimal,
                 'datetime': datetime
             })
         for name in names:
             res.setdefault(name, {})
             res[name].setdefault(line.id, False)
             if name == 'number_doc':
                 if name == 'number_doc':
                     if line.type_transaction in ('expense', 'expense_tax'):
                         res[name][line.id] = line.number_our
                     else:
                         res[name][line.id] = line.number_in
             elif name == 'state_doc':
                 res[name][line.id] = line.state
             elif name == 'from_party_doc':
                 res[name][line.id] = line.from_party.id
             elif name == 'to_party_doc':
                 res[name][line.id] = line.to_party.id
             elif name == 'template_bank':
                 res[name][line.id] = line.template.id
             elif name == 'content':
                 res[name][line.id] = line.note
             elif all_add_options and name == 'pole_order':
                 res[name][line.id] = all_add_options.get('pole_order')
             elif all_add_options and name == 'pole_type':
                 res[name][line.id] = all_add_options.get('pole_type')
             elif all_add_options and name == 'pole_maturity':
                 res[name][line.id] = all_add_options.get('pole_maturity')
             elif all_add_options and name == 'pole_detail':
                 res[name][line.id] = all_add_options.get('pole_detail')
             elif all_add_options and name == 'pole_code':
                 res[name][line.id] = all_add_options.get('pole_code')
             elif all_add_options and name == 'pole_reserve':
                 res[name][line.id] = all_add_options.get('pole_reserve')
             elif all_add_options and name == 'kind_payment_tax':
                 res[name][line.id] = all_add_options.get(
                     'kind_payment_tax')
             elif all_add_options and name == 'status_payer_tax':
                 res[name][line.id] = all_add_options.get(
                     'status_payer_tax')
             elif all_add_options and name == 'kbk_indicator':
                 res[name][line.id] = all_add_options.get('kbk_indicator')
             elif all_add_options and name == 'okato_indicator':
                 res[name][line.id] = all_add_options.get('okato_indicator')
             elif all_add_options and name == 'payment_details_tax':
                 res[name][line.id] = all_add_options.get(
                     'payment_details_tax')
             elif all_add_options and name == 'number_doc_base_tax':
                 res[name][line.id] = all_add_options.get(
                     'number_doc_base_tax')
             elif all_add_options and name == 'tax_period':
                 res[name][line.id] = all_add_options.get('tax_period')
     return res