summaryrefslogtreecommitdiff
path: root/addons/l10n_lu/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'addons/l10n_lu/scripts')
-rw-r--r--addons/l10n_lu/scripts/tax.xlsbin0 -> 259072 bytes
-rw-r--r--addons/l10n_lu/scripts/tax2csv.py183
2 files changed, 183 insertions, 0 deletions
diff --git a/addons/l10n_lu/scripts/tax.xls b/addons/l10n_lu/scripts/tax.xls
new file mode 100644
index 00000000..0a3a0182
--- /dev/null
+++ b/addons/l10n_lu/scripts/tax.xls
Binary files differ
diff --git a/addons/l10n_lu/scripts/tax2csv.py b/addons/l10n_lu/scripts/tax2csv.py
new file mode 100644
index 00000000..2a2da358
--- /dev/null
+++ b/addons/l10n_lu/scripts/tax2csv.py
@@ -0,0 +1,183 @@
+from collections import OrderedDict
+
+import xlrd
+from odoo.tools import pycompat
+
+def _is_true(s):
+ return s not in ('F', 'False', 0, '', None, False)
+
+
+class LuxTaxGenerator:
+
+ def __init__(self, filename):
+ self.workbook = xlrd.open_workbook('tax.xls')
+ self.sheet_info = \
+ self.workbook.sheet_by_name('INFO')
+ self.sheet_taxes = \
+ self.workbook.sheet_by_name('TAXES')
+ self.sheet_tax_codes = \
+ self.workbook.sheet_by_name('TAX.CODES')
+ self.sheet_fiscal_pos_map = \
+ self.workbook.sheet_by_name('FISCAL.POSITION.MAPPINGS')
+ self.suffix = self.sheet_info.cell_value(4, 2)
+
+ def iter_tax_codes(self):
+ keys = [c.value for c in self.sheet_tax_codes.row(0)]
+ yield keys
+ for i in range(1, self.sheet_tax_codes.nrows):
+ row = (c.value for c in self.sheet_tax_codes.row(i))
+ d = OrderedDict(zip(keys, row))
+ d['sign'] = int(d['sign'])
+ d['sequence'] = int(d['sequence'])
+ yield d
+
+ def iter_taxes(self):
+ keys = [c.value for c in self.sheet_taxes.row(0)]
+ yield keys
+ for i in range(1, self.sheet_taxes.nrows):
+ row = (c.value for c in self.sheet_taxes.row(i))
+ yield OrderedDict(zip(keys, row))
+
+ def iter_fiscal_pos_map(self):
+ keys = [c.value for c in self.sheet_fiscal_pos_map.row(0)]
+ yield keys
+ for i in range(1, self.sheet_fiscal_pos_map.nrows):
+ row = (c.value for c in self.sheet_fiscal_pos_map.row(i))
+ yield OrderedDict(zip(keys, row))
+
+ def tax_codes_to_csv(self):
+ writer = pycompat.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.to_text(v) for v in row.values()])
+
+ # 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,
+ u'lu_tct_m' + parent_code,
+ tax_code_id.replace('lu_tax_code_template_', u''),
+ u'1',
+ u'',
+ pycompat.to_text(name),
+ u''
+ ])
+
+ def taxes_to_csv(self):
+ writer = pycompat.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([
+ pycompat.to_text(v)
+ for v in list(row.values())[3:]
+ ] + [cur_seq])
+
+ def fiscal_pos_map_to_csv(self):
+ writer = pycompat.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.to_text(s) for s in row.values()])
+
+
+if __name__ == '__main__':
+ o = LuxTaxGenerator('tax.xls')
+ o.tax_codes_to_csv()
+ o.taxes_to_csv()
+ o.fiscal_pos_map_to_csv()