Ejemplo n.º 1
0
 def _read_xls_book(self, book):
     sheet = book.sheet_by_index(0)
     # emulate Sheet.get_rows for pre-0.9.4
     for row in pycompat.imap(sheet.row, range(sheet.nrows)):
         values = []
         for cell in row:
             if cell.ctype is xlrd.XL_CELL_NUMBER:
                 is_float = cell.value % 1 != 0.0
                 values.append(
                     pycompat.text_type(cell.value)
                     if is_float
                     else pycompat.text_type(int(cell.value))
                 )
             elif cell.ctype is xlrd.XL_CELL_DATE:
                 is_datetime = cell.value % 1 != 0.0
                 # emulate xldate_as_datetime for pre-0.9.3
                 dt = datetime.datetime(*xlrd.xldate.xldate_as_tuple(cell.value, book.datemode))
                 values.append(
                     dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
                     if is_datetime
                     else dt.strftime(DEFAULT_SERVER_DATE_FORMAT)
                 )
             elif cell.ctype is xlrd.XL_CELL_BOOLEAN:
                 values.append(u'True' if cell.value else u'False')
             elif cell.ctype is xlrd.XL_CELL_ERROR:
                 raise ValueError(
                     _("Error cell found while reading XLS/XLSX file: %s") %
                     xlrd.error_text_from_code.get(
                         cell.value, "unknown error code %s" % cell.value)
                 )
             else:
                 values.append(cell.value)
         if any(x for x in values if x.strip()):
             yield values
Ejemplo n.º 2
0
    def _convert_import_data(self, fields, options):
        """ Extracts the input BaseModel and fields list (with
            ``False``-y placeholders for fields to *not* import) into a
            format Model.import_data can use: a fields list without holes
            and the precisely matching data matrix

            :param list(str|bool): fields
            :returns: (data, fields)
            :rtype: (list(list(str)), list(str))
            :raises ValueError: in case the import data could not be converted
        """
        # Get indices for non-empty fields
        indices = [index for index, field in enumerate(fields) if field]
        if not indices:
            raise ValueError(_("You must configure at least one field to import"))
        # If only one index, itemgetter will return an atom rather
        # than a 1-tuple
        if len(indices) == 1:
            mapper = lambda row: [row[indices[0]]]
        else:
            mapper = operator.itemgetter(*indices)
        # Get only list of actually imported fields
        import_fields = [f for f in fields if f]

        rows_to_import = self._read_file(options)
        if options.get('headers'):
            rows_to_import = itertools.islice(rows_to_import, 1, None)
        data = [
            list(row) for row in pycompat.imap(mapper, rows_to_import)
            # don't try inserting completely empty rows (e.g. from
            # filtering out o2m fields)
            if any(row)
        ]

        return data, import_fields
Ejemplo n.º 3
0
    def record_to_html(self, record, field_name, options):
        assert options['tagName'] != 'img',\
            "Oddly enough, the root tag of an image field can not be img. " \
            "That is because the image goes into the tag, or it gets the " \
            "hose again."

        if options.get('qweb_img_raw_data', False):
            return super(Image, self).record_to_html(record, field_name, options)

        aclasses = ['img', 'img-fluid'] if options.get('qweb_img_responsive', True) else ['img']
        aclasses += options.get('class', '').split()
        classes = ' '.join(pycompat.imap(escape, aclasses))

        max_size = None
        if options.get('resize'):
            max_size = options.get('resize')
        else:
            max_width, max_height = options.get('max_width', 0), options.get('max_height', 0)
            if max_width or max_height:
                max_size = '%sx%s' % (max_width, max_height)

        sha = hashlib.sha1(str(getattr(record, '__last_update')).encode('utf-8')).hexdigest()[0:7]
        max_size = '' if max_size is None else '/%s' % max_size
        avoid_if_small = '&avoid_if_small=true' if options.get('avoid_if_small') else ''
        src = '/web/image/%s/%s/%s%s?unique=%s%s' % (record._name, record.id, field_name, max_size, sha, avoid_if_small)

        alt = None
        if options.get('alt-field') and getattr(record, options['alt-field'], None):
            alt = escape(record[options['alt-field']])
        elif options.get('alt'):
            alt = options['alt']

        src_zoom = None
        if options.get('zoom') and getattr(record, options['zoom'], None):
            src_zoom = '/web/image/%s/%s/%s%s?unique=%s' % (record._name, record.id, options['zoom'], max_size, sha)
        elif options.get('zoom'):
            src_zoom = options['zoom']

        atts = OrderedDict()
        atts["src"] = src
        atts["class"] = classes
        atts["style"] = options.get('style')
        atts["alt"] = alt
        atts["data-zoom"] = src_zoom and u'1' or None
        atts["data-zoom-image"] = src_zoom
        atts["data-no-post-process"] = options.get('data-no-post-process')

        atts = self.env['ir.qweb']._post_processing_att('img', atts, options.get('template_options'))

        img = ['<img']
        for name, value in atts.items():
            if value:
                img.append(' ')
                img.append(escape(pycompat.to_text(name)))
                img.append('="')
                img.append(escape(pycompat.to_text(value)))
                img.append('"')
        img.append('/>')

        return u''.join(img)
Ejemplo n.º 4
0
 def fiscal_pos_map_to_csv(self):
     writer = csv.writer(open('account.fiscal.'
                              'position.tax.template-%s.csv' %
                              self.suffix, 'wb'))
     fiscal_pos_map_iterator = self.iter_fiscal_pos_map()
     keys = next(fiscal_pos_map_iterator)
     writer.writerow(keys)
     for row in fiscal_pos_map_iterator:
         writer.writerow(pycompat.imap(_e, pycompat.values(row)))
Ejemplo n.º 5
0
 def taxes_to_csv(self):
     writer = csv.writer(open('account.tax.template-%s.csv' %
                              self.suffix, 'wb'))
     taxes_iterator = self.iter_taxes()
     keys = next(taxes_iterator)
     writer.writerow(keys[3:] + ['sequence'])
     seq = 100
     for row in sorted(taxes_iterator, key=lambda r: r['description']):
         if not _is_true(row['active']):
             continue
         seq += 1
         if row['parent_id:id']:
             cur_seq = seq + 1000
         else:
             cur_seq = seq
         writer.writerow(list(pycompat.imap(_e, list(pycompat.values(row))[3:])) + [cur_seq])
Ejemplo n.º 6
0
    def record_to_html(self, record, field_name, options):
        assert options['tagName'] != 'img',\
            "Oddly enough, the root tag of an image field can not be img. " \
            "That is because the image goes into the tag, or it gets the " \
            "hose again."

        if options.get('qweb_img_raw_data', False):
            return super(Image, self).record_to_html(record, field_name, options)

        aclasses = ['img', 'img-responsive'] if options.get('qweb_img_responsive', True) else ['img']
        aclasses += options.get('class', '').split()
        classes = ' '.join(pycompat.imap(escape, aclasses))

        max_size = None
        if options.get('resize'):
            max_size = options.get('resize')
        else:
            max_width, max_height = options.get('max_width', 0), options.get('max_height', 0)
            if max_width or max_height:
                max_size = '%sx%s' % (max_width, max_height)

        sha = hashlib.sha1(getattr(record, '__last_update').encode('utf-8')).hexdigest()[0:7]
        max_size = '' if max_size is None else '/%s' % max_size
        avoid_if_small = '&avoid_if_small=true' if options.get('avoid_if_small') else ''
        src = '/web/image/%s/%s/%s%s?unique=%s%s' % (record._name, record.id, field_name, max_size, sha, avoid_if_small)

        alt = None
        if options.get('alt-field') and getattr(record, options['alt-field'], None):
            alt = escape(record[options['alt-field']])
        elif options.get('alt'):
            alt = options['alt']

        src_zoom = None
        if options.get('zoom') and getattr(record, options['zoom'], None):
            src_zoom = '/web/image/%s/%s/%s%s?unique=%s' % (record._name, record.id, options['zoom'], max_size, sha)
        elif options.get('zoom'):
            src_zoom = options['zoom']

        img = '<img class="%s" src="%s" style="%s"%s%s/>' % \
            (classes, src, options.get('style', ''), ' alt="%s"' % alt if alt else '', ' data-zoom="1" data-zoom-image="%s"' % src_zoom if src_zoom else '')
        return pycompat.to_text(img)
Ejemplo n.º 7
0
    def _convert_import_data(self, fields, options):
        """ Extracts the input BaseModel and fields list (with
            ``False``-y placeholders for fields to *not* import) into a
            format Model.import_data can use: a fields list without holes
            and the precisely matching data matrix

            :param list(str|bool): fields
            :returns: (data, fields)
            :rtype: (list(list(str)), list(str))
            :raises ValueError: in case the import data could not be converted
        """
        # Get indices for non-empty fields
        indices = [index for index, field in enumerate(fields) if field]
        if not indices:
            raise ValueError(
                _("You must configure at least one field to import"))
        # If only one index, itemgetter will return an atom rather
        # than a 1-tuple
        if len(indices) == 1:
            mapper = lambda row: [row[indices[0]]]
        else:
            mapper = operator.itemgetter(*indices)
        # Get only list of actually imported fields
        import_fields = [f for f in fields if f]

        rows_to_import = self._read_file(options)
        if options.get('headers'):
            rows_to_import = itertools.islice(rows_to_import, 1, None)
        data = [
            list(row) for row in pycompat.imap(mapper, rows_to_import)
            # don't try inserting completely empty rows (e.g. from
            # filtering out o2m fields)
            if any(row)
        ]

        return data, import_fields
Ejemplo n.º 8
0
    def record_to_html(self, record, field_name, options):
        assert options['tagName'] != 'img',\
            "Oddly enough, the root tag of an image field can not be img. " \
            "That is because the image goes into the tag, or it gets the " \
            "hose again."

        if options.get('qweb_img_raw_data', False):
            return super(Image, self).record_to_html(record, field_name,
                                                     options)

        aclasses = ['img', 'img-fluid'] if options.get('qweb_img_responsive',
                                                       True) else ['img']
        aclasses += options.get('class', '').split()
        classes = ' '.join(pycompat.imap(escape, aclasses))

        max_size = None
        if options.get('resize'):
            max_size = options.get('resize')
        else:
            max_width, max_height = options.get('max_width', 0), options.get(
                'max_height', 0)
            if max_width or max_height:
                max_size = '%sx%s' % (max_width, max_height)

        sha = hashlib.sha1(
            str(getattr(record,
                        '__last_update')).encode('utf-8')).hexdigest()[0:7]
        max_size = '' if max_size is None else '/%s' % max_size
        avoid_if_small = '&avoid_if_small=true' if options.get(
            'avoid_if_small') else ''
        src = '/web/image/%s/%s/%s%s?unique=%s%s' % (
            record._name, record.id, field_name, max_size, sha, avoid_if_small)

        alt = None
        if options.get('alt-field') and getattr(record, options['alt-field'],
                                                None):
            alt = escape(record[options['alt-field']])
        elif options.get('alt'):
            alt = options['alt']

        src_zoom = None
        if options.get('zoom') and getattr(record, options['zoom'], None):
            src_zoom = '/web/image/%s/%s/%s%s?unique=%s' % (
                record._name, record.id, options['zoom'], max_size, sha)
        elif options.get('zoom'):
            src_zoom = options['zoom']

        atts = OrderedDict()
        atts["src"] = src
        atts["class"] = classes
        atts["style"] = options.get('style')
        atts["alt"] = alt
        atts["data-zoom"] = src_zoom and u'1' or None
        atts["data-zoom-image"] = src_zoom
        atts["data-no-post-process"] = options.get('data-no-post-process')

        atts = self.env['ir.qweb']._post_processing_att(
            'img', atts, options.get('template_options'))

        img = ['<img']
        for name, value in atts.items():
            if value:
                img.append(' ')
                img.append(escape(pycompat.to_text(name)))
                img.append('="')
                img.append(escape(pycompat.to_text(value)))
                img.append('"')
        img.append('/>')

        return u''.join(img)
Ejemplo n.º 9
0
    def tax_codes_to_csv(self):
        writer = csv.writer(open('account.tax.code.template-%s.csv' %
                                 self.suffix, 'wb'))
        tax_codes_iterator = self.iter_tax_codes
        keys = next(tax_codes_iterator)
        writer.writerow(keys)

        # write structure tax codes
        tax_codes = {}  # code: id
        for row in tax_codes_iterator:
            tax_code = row['code']
            if tax_code in tax_codes:
                raise RuntimeError('duplicate tax code %s' % tax_code)
            tax_codes[tax_code] = row['id']
            writer.writerow(pycompat.imap(_e, pycompat.values(row)))

        # read taxes and add leaf tax codes
        new_tax_codes = {}  # id: parent_code

        def add_new_tax_code(tax_code_id, new_name, new_parent_code):
            if not tax_code_id:
                return
            name, parent_code = new_tax_codes.get(tax_code_id, (None, None))
            if parent_code and parent_code != new_parent_code:
                raise RuntimeError('tax code "%s" already exist with '
                                   'parent %s while trying to add it with '
                                   'parent %s' %
                                   (tax_code_id, parent_code, new_parent_code))
            else:
                new_tax_codes[tax_code_id] = (new_name, new_parent_code)

        taxes_iterator = self.iter_taxes()
        next(taxes_iterator)
        for row in taxes_iterator:
            if not _is_true(row['active']):
                continue
            if row['child_depend'] and row['amount'] != 1:
                raise RuntimeError('amount must be one if child_depend '
                                   'for %s' % row['id'])
            # base parent
            base_code = row['BASE_CODE']
            if not base_code or base_code == '/':
                base_code = 'NA'
            if base_code not in tax_codes:
                raise RuntimeError('undefined tax code %s' % base_code)
            if base_code != 'NA':
                if row['child_depend']:
                    raise RuntimeError('base code specified '
                                       'with child_depend for %s' % row['id'])
            if not row['child_depend']:
                # ... in lux, we have the same code for invoice and refund
                if base_code != 'NA':
                    assert row['base_code_id:id'], 'missing base_code_id for %s' % row['id']
                assert row['ref_base_code_id:id'] == row['base_code_id:id']
                add_new_tax_code(row['base_code_id:id'],
                                 'Base - ' + row['name'],
                                 base_code)
            # tax parent
            tax_code = row['TAX_CODE']
            if not tax_code or tax_code == '/':
                tax_code = 'NA'
            if tax_code not in tax_codes:
                raise RuntimeError('undefined tax code %s' % tax_code)
            if tax_code == 'NA':
                if row['amount'] and not row['child_depend']:
                    raise RuntimeError('TAX_CODE not specified '
                                       'for non-zero tax %s' % row['id'])
                if row['tax_code_id:id']:
                    raise RuntimeError('tax_code_id specified '
                                       'for tax %s' % row['id'])
            else:
                if row['child_depend']:
                    raise RuntimeError('TAX_CODE specified '
                                       'with child_depend for %s' % row['id'])
                if not row['amount']:
                    raise RuntimeError('TAX_CODE specified '
                                       'for zero tax %s' % row['id'])
                if not row['tax_code_id:id']:
                    raise RuntimeError('tax_code_id not specified '
                                       'for tax %s' % row['id'])
            if not row['child_depend'] and row['amount']:
                # ... in lux, we have the same code for invoice and refund
                assert row['tax_code_id:id'], 'missing tax_code_id for %s' % row['id']
                assert row['ref_tax_code_id:id'] == row['tax_code_id:id']
                add_new_tax_code(row['tax_code_id:id'],
                                 'Taxe - ' + row['name'],
                                 tax_code)

        for tax_code_id in sorted(new_tax_codes):
            name, parent_code = new_tax_codes[tax_code_id]
            writer.writerow((tax_code_id,
                             'lu_tct_m' + parent_code,
                             tax_code_id.replace('lu_tax_code_template_', ''),
                             '1',
                             '',
                             _e(name),
                             ''))
Ejemplo n.º 10
0
 def _groups_branding(self, specs_tree, view_id):
     groups_id = self.browse(view_id).groups_id
     if groups_id:
         attr_value = ','.join(pycompat.imap(str, groups_id.ids))
         for node in specs_tree.iter(tag=etree.Element):
             node.set('studio-view-group-ids', attr_value)
Ejemplo n.º 11
0
    def read_xls(self, map1):
        # import ipdb; ipdb.set_trace()

        file1 = base64.b64decode(self.file1)
        try:
            book = xlrd.open_workbook(file_contents=file1 or b'')
        except:
            return []

        sheet = book.sheet_by_index(0)

        cols = []
        vals = []
        x = -1
        for row in pycompat.imap(sheet.row, range(sheet.nrows)):
            x += 1
            val_one = {}
            c = -1
            for cell in row:
                c += 1
                if x == 0:
                    col = str(cell.value).lower()
                    get_map = map1.get(col, '')
                    # if type(get_map) is list:
                    #     col_to_save = get_map[0]
                    # else:
                    #     col_to_save = get_map
                    # cols.append(col_to_save)
                    cols.append(get_map)
                else:
                    get_map = cols[c]
                    if not get_map:
                        continue

                    val = ''
                    if cell.ctype is xlrd.XL_CELL_NUMBER:
                        is_float = cell.value % 1 != 0.0
                        val = pycompat.text_type(
                            cell.value) if is_float else pycompat.text_type(
                                int(cell.value))
                    elif cell.ctype is xlrd.XL_CELL_DATE:
                        is_datetime = cell.value % 1 != 0.0
                        # emulate xldate_as_datetime for pre-0.9.3
                        dt = datetime.datetime(*xlrd.xldate.xldate_as_tuple(
                            cell.value, book.datemode))
                        val = dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT
                                          ) if is_datetime else dt.strftime(
                                              DEFAULT_SERVER_DATE_FORMAT)
                    elif cell.ctype is xlrd.XL_CELL_BOOLEAN:
                        val = u'True' if cell.value else u'False'
                    elif cell.ctype is xlrd.XL_CELL_ERROR:
                        # raise ValueError(
                        #     _("Error cell found while reading XLS/XLSX file: %s") %
                        #     xlrd.error_text_from_code.get(
                        #         cell.value, "unknown error code %s" % cell.value)
                        # )
                        val = ''
                    else:
                        # import ipdb; ipdb.set_trace()
                        # print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", cell)
                        val = cell.value
                    # val_one[field] = val

                    value = val
                    if type(get_map) is list:
                        col_to_save = get_map[0]
                        col = get_map[3]
                        if col_to_save:
                            val_to_save = False
                            tipe = get_map[1]
                            model = get_map[2]

                            if tipe == 'many2one':
                                model = self.env[model]
                                rec = model.search([('name', '=', value)])
                                if not rec:
                                    # create first
                                    # rec = model.create({'name': value})
                                    raise ValidationError(
                                        _('{} : "{}" is not known'.format(
                                            col, value)))

                                val_to_save = rec.id

                            val_one[col_to_save] = val_to_save
                    else:
                        col_to_save = get_map
                        if col_to_save:
                            val_one[col_to_save] = value

            if val_one:
                vals.append((0, 0, val_one))
        return vals