diff --git a/addons/l10n_ch/account_wizard.py b/addons/l10n_ch/account_wizard.py
new file mode 100644
index 00000000000..b2e1ab00924
--- /dev/null
+++ b/addons/l10n_ch/account_wizard.py
@@ -0,0 +1,43 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Author: Nicolas Bessi. Copyright Camptocamp SA
+# Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+import tools
+from osv import osv
+import addons
+
+class WizardMultiChartsAccounts(osv.osv_memory):
+
+ _inherit ='wizard.multi.charts.accounts'
+ _defaults = {
+ 'bank_accounts_id': False,
+ 'code_digits': 0,
+ 'sale_tax': False,
+ 'purchase_tax':False
+ }
+
+ def execute(self, cr, uid, ids, context=None):
+ """Override of code in order to be able to link journal with account in XML"""
+ res = super(WizardMultiChartsAccounts, self).execute(cr, uid, ids, context)
+ path = addons.get_module_resource('l10n_ch/sterchi_chart/account_journal_rel.xml')
+ tools.convert_xml_import(cr, 'l10n_ch', path, idref=None, mode='init', noupdate=True, report=None)
+ return res
+
+WizardMultiChartsAccounts()
+
diff --git a/addons/l10n_ch/demo/demo.xml b/addons/l10n_ch/demo/demo.xml
new file mode 100644
index 00000000000..7782669d995
--- /dev/null
+++ b/addons/l10n_ch/demo/demo.xml
@@ -0,0 +1,84 @@
+
+
+
+
+ My bank !
+ banq
+ Banque
+
+
+
+ +41 31 622 13 00
+ Marc Dufour
+ 1015
+ Lausanne
+
+
+ openerp@bank.com
+ +41 24 620 10 12
+ PSE-C
+ 1
+ default
+
+
+
+ Very good company!
+ They provides a very high quality service.
+ ProL
+ http://camptocamp.com
+ ProLibre
+
+
+
+
+ Very good company!
+ They provides a very high quality service.
+ c2c
+ http://camptocamp.com
+ camptocamp SA
+
+
+
+
+
+ +41 21 619 10 00
+ Luc Maurer
+ 1015
+ Lausanne
+
+
+ openerp@camptocamp.com
+ +41 21 619 10 12
+ PSE-A, EPFL
+ 1
+ default
+
+
+ Ferdinand Gassauer
+ 1015
+ Lausanne
+
+
+ info@camptocamp.com
+ +41 21 619 10 11
+ 18, rue des Moraines
+ 1
+ default
+
+
+ +41 21 619 10 00
+ Claude Philipona
+ 1015
+ Lausanne
+
+
+ openerp@camptocamp.com
+ +41 21 619 10 12
+ PSE-A, EPFL
+ 1
+ default
+
+
+
diff --git a/addons/l10n_ch/journal_data.xml b/addons/l10n_ch/journal_data.xml
new file mode 100644
index 00000000000..ac8c714fbca
--- /dev/null
+++ b/addons/l10n_ch/journal_data.xml
@@ -0,0 +1,71 @@
+
+
+
+
+ Journal de frais
+ EXPF
+ purchase
+
+
+
+
+
+
+
+
+ Banque CHF
+ BCHF
+ cash
+
+
+
+
+
+
+
+
+ Banque EUR
+ BEUR
+ cash
+
+
+
+
+
+
+
+
+
+ Caisse
+ CAI
+ cash
+
+
+
+
+
+
+
+
+ Opérations Diverses
+ OD
+ general
+
+
+
+
+
+
+
+
+ Journal d'ouverture
+ JO
+ situation
+ True
+
+
+
+
+
+
+
diff --git a/addons/l10n_ch/report/bvr.jpg b/addons/l10n_ch/report/bvr.jpg
new file mode 100644
index 00000000000..fd63debd47c
Binary files /dev/null and b/addons/l10n_ch/report/bvr.jpg differ
diff --git a/addons/l10n_ch/report/bvr.mako b/addons/l10n_ch/report/bvr.mako
new file mode 100644
index 00000000000..bebf943e11b
--- /dev/null
+++ b/addons/l10n_ch/report/bvr.mako
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+ ${_check(objects)}
+ %for inv in objects :
+ <% setLang(inv.partner_id.lang) %>
+
+
+
+ %if company.bvr_background:
+
+ %endif
+
+ ${inv.partner_bank_id and inv.partner_bank_id.print_bank and inv.partner_bank_id.bank and inv.partner_bank_id.bank.name or ''} | ${inv.partner_bank_id and inv.partner_bank_id.print_bank and inv.partner_bank_id.bank and inv.partner_bank_id.bank.name or ''} | |
+ ${user.company_id.partner_id.name} | ${user.company_id.partner_id.name} | |
+ ${user.company_id.partner_id.address[0].street} ${user.company_id.partner_id.address[0].zip} ${user.company_id.partner_id.address[0].city} | ${inv.partner_bank_id.print_account and inv.partner_bank_id.bvr_number or ''} |
| ${user.company_id.partner_id.address[0].street} ${user.company_id.partner_id.address[0].zip} ${user.company_id.partner_id.address[0].city} | ${inv.partner_bank_id.print_account and inv.partner_bank_id.bvr_number or ''} |
| ${_space(_get_ref(inv))} |
+ | ${_space(('%.2f' % inv.amount_total)[:-3], 1)} | | ${ _space(('%.2f' % inv.amount_total)[-2:], 1)} | |
| | ${_space(('%.2f' % inv.amount_total)[:-3], 1)} | | ${ _space(('%.2f' % inv.amount_total)[-2:], 1)} | |
| |
+ | | |
+ | | |
+ | ${mod10r('01'+str('%.2f' % inv.amount_total).replace('.','').rjust(10,'0'))}>${_get_ref(inv)}+${inv.partner_bank_id.bvr_number.split('-')[0]+(str(inv.partner_bank_id.bvr_number.split('-')[1])).rjust(6,'0')+inv.partner_bank_id.bvr_number.split('-')[2]}> |
+
+ %endfor
+
+
\ No newline at end of file
diff --git a/addons/l10n_ch/report/bvr1.jpg b/addons/l10n_ch/report/bvr1.jpg
new file mode 100644
index 00000000000..3882f86776a
Binary files /dev/null and b/addons/l10n_ch/report/bvr1.jpg differ
diff --git a/addons/l10n_ch/report/report_webkit_html.mako b/addons/l10n_ch/report/report_webkit_html.mako
new file mode 100644
index 00000000000..1cb2c7fe091
--- /dev/null
+++ b/addons/l10n_ch/report/report_webkit_html.mako
@@ -0,0 +1,84 @@
+
+
+
+
+
+ %for inv in objects :
+ <% setLang(inv.partner_id.lang) %>
+
+
+ | ${inv.partner_id.title or ''|entity} ${inv.partner_id.name |entity} |
+ | ${inv.address_invoice_id.street or ''|entity} |
+ | ${inv.address_invoice_id.street2 or ''|entity} |
+ | ${inv.address_invoice_id.zip or ''|entity} ${inv.address_invoice_id.city or ''|entity} |
+ %if inv.address_invoice_id.country_id :
+ | ${inv.address_invoice_id.country_id.name or ''|entity} |
+ %endif
+ %if inv.address_invoice_id.phone :
+ | ${_("Tel")}: ${inv.address_invoice_id.phone|entity} |
+ %endif
+ %if inv.address_invoice_id.fax :
+ | ${_("Fax")}: ${inv.address_invoice_id.fax|entity} |
+ %endif
+ %if inv.address_invoice_id.email :
+ | ${_("E-mail")}: ${inv.address_invoice_id.email|entity} |
+ %endif
+ %if inv.partner_id.vat :
+ | ${_("VAT")}: ${inv.partner_id.vat|entity} |
+ %endif
+
+
+ %if inv.type == 'out_invoice' :
+
${_("Invoice")} ${inv.number or ''|entity}
+ %elif inv.type == 'in_invoice' :
+
${_("Supplier Invoice")} ${inv.number or ''|entity}
+ %elif inv.type == 'out_refund' :
+
${_("Refund")} ${inv.number or ''|entity}
+ %elif inv.type == 'in_refund' :
+
${_("Supplier Refund")} ${inv.number or ''|entity}
+ %endif
+
+
+
+ | ${_("Document")} | ${_("Invoice Date")} | ${_("Partner Ref.")} |
+ | ${inv.name} | ${formatLang(inv.date_invoice, date=True)|entity} | |
+
+
+
+ | ${_("Description")} | ${_("Taxes")} | ${_("QTY")} | ${_("Unit Price")} | ${_("Disc.(%)")} | ${_("Price")} |
+ %for line in inv.invoice_line :
+
+ | ${line.name|entity} | ${ ', '.join([ tax.name or '' for tax in line.invoice_line_tax_id ])|entity} | ${line.quantity} | ${formatLang(line.price_unit)} | ${line.discount or 0.00} | ${formatLang(line.price_subtotal)} |
+ %if line.note :
+ ${line.note |entity} |
+ %endif
+ %endfor
+ | | | | Net Total: | ${formatLang(inv.amount_untaxed)} |
+ | | | | Taxes: | ${formatLang(inv.amount_tax)} |
+ | | | | Total: | ${formatLang(inv.amount_total)} |
+
+
+
+
+ | Tax | ${_("Base")} | ${_("Amount")} |
+ %if inv.tax_line :
+ %for t in inv.tax_line :
+
+ | ${ t.name|entity } |
+ ${ t.base|entity} |
+ ${ formatLang(t.amount) } |
+
+ %endfor
+ %endif
+
+ |
+ ${_("Total")} |
+ ${ formatLang(inv.amount_tax) } |
+
+
+
+ %endfor
+
+
\ No newline at end of file
diff --git a/addons/l10n_ch/report/report_webkit_html.py b/addons/l10n_ch/report/report_webkit_html.py
new file mode 100644
index 00000000000..ed7d4bbf60c
--- /dev/null
+++ b/addons/l10n_ch/report/report_webkit_html.py
@@ -0,0 +1,265 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Author: Nicolas Bessi. Copyright Camptocamp SA
+# Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+import time
+from report import report_sxw
+from report_webkit import webkit_report
+from report_webkit import report_helper
+from osv import osv
+from tools import mod10r
+import sys
+import os
+import re
+import wizard
+import addons
+import pooler
+from tools.config import config
+from mako.template import Template
+
+
+class l10n_ch_report_webkit_html(report_sxw.rml_parse):
+ def __init__(self, cr, uid, name, context):
+ super(l10n_ch_report_webkit_html, self).__init__(cr, uid, name, context=context)
+ self.localcontext.update({
+ 'time': time,
+ 'cr':cr,
+ 'uid': uid,
+ 'user':self.pool.get("res.users").browse(cr, uid, uid),
+ 'mod10r': mod10r,
+ '_space': self._space,
+ '_get_ref': self._get_ref,
+ 'comma_me': self.comma_me,
+ 'police_absolute_path' : self.police_absolute_path,
+ 'bvr_absolute_path':self.bvr_absolute_path,
+ '_check' : self._check,
+ 'headheight': self.headheight
+ })
+
+ #will be fixed in 5.0.10
+ def police_absolute_path(self, inner_path) :
+ """Will get the ocrb police absolute path"""
+ path = addons.get_module_resource('l10n_ch/report/'+inner_path)
+ return path
+
+ def bvr_absolute_path(self) :
+ """Will get the ocrb police absolute path"""
+ path = addons.get_module_resource('l10n_ch/report/bvr1.jpg')
+ return path
+
+ def headheight(self):
+ report_id = self.pool.get('ir.actions.report.xml').search(self.cr, self.uid, [('name','=', 'BVR invoice')])[0]
+ report = self.pool.get('ir.actions.report.xml').browse(self.cr, self.uid, report_id)
+ return report.webkit_header.margin_top
+
+ def comma_me(self, amount):
+ """Fast swiss number formatting"""
+ if type(amount) is float :
+ amount = str('%.2f'%amount)
+ else :
+ amount = str(amount)
+ orig = amount
+ new = re.sub("^(-?\d+)(\d{3})", "\g<1>'\g<2>", amount)
+ if orig == new:
+ return new
+ else:
+ return self.comma_me(new)
+
+ def _space(self, nbr, nbrspc=5):
+ """Spaces * 5"""
+ res = ''
+ for i in range(len(nbr)):
+ res = res + nbr[i]
+ if not (i-1) % nbrspc:
+ res = res + ' '
+ return res
+
+ def _get_ref(self, inv):
+ """Retrieve ESR/BVR reference form invoice in order to print it"""
+ res = ''
+ if inv.partner_bank_id.bvr_adherent_num:
+ res = inv.partner_bank_id.bvr_adherent_num
+ invoice_number = ''
+ if inv.number:
+ invoice_number = re.sub('[^0-9]', '', inv.number)
+ return mod10r(res + invoice_number.rjust(26-len(res), '0'))
+
+ def _check(self, invoices):
+ """Check if the invoice is ready to be printed"""
+ cursor = self.cr
+ pool = self.pool
+ invoice_obj = pool.get('account.invoice')
+ ids = [x.id for x in invoices]
+ for invoice in invoice_obj.browse(cursor, self.uid, ids):
+ if not invoice.partner_bank_id:
+ raise wizard.except_wizard('UserError',
+ 'No bank specified on invoice:\n' + \
+ invoice_obj.name_get(cursor, self.uid, [invoice.id],
+ context={})[0][1])
+ if not re.compile('[0-9][0-9]-[0-9]{3,6}-[0-9]').match(
+ invoice.partner_bank_id.bvr_number or ''):
+ raise wizard.except_wizard('UserError',
+ "Your bank BVR number should be of the form 0X-XXX-X! " +
+ 'Please check your company ' +
+ 'information for the invoice:\n' +
+ invoice_obj.name_get(cursor, self.uid, [invoice.id],
+ context={})[0][1])
+ if invoice.partner_bank_id.bvr_adherent_num \
+ and not re.compile('[0-9]*$').match(
+ invoice.partner_bank_id.bvr_adherent_num):
+ raise wizard.except_wizard('UserError',
+ 'Your bank BVR adherent number must contain exactly seven' +
+ 'digits!\nPlease check your company ' +
+ 'information for the invoice:\n' +
+ invoice_obj.name_get(cursor, self.uid, [invoice.id],
+ context={})[0][1])
+ return ""
+
+class BVRWebKitParser(webkit_report.WebKitParser):
+
+ def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
+ """generate the PDF"""
+ self.parser_instance = self.parser(
+ cursor,
+ uid,
+ self.name2,
+ context=context
+ )
+ self.pool = pooler.get_pool(cursor.dbname)
+ objs = self.getObjects(cursor, uid, ids, context)
+ self.parser_instance.set_context(objs, data, ids, report_xml.report_type)
+ template = False
+ if report_xml.report_file :
+ path = addons.get_module_resource(report_xml.report_file)
+ if os.path.exists(path) :
+ template = file(path).read()
+ if not template and report_xml.report_webkit_data :
+ template = report_xml.report_webkit_data
+ if not template :
+ raise except_osv(_('Webkit Report template not found !'), _(''))
+ header = report_xml.webkit_header.html
+ footer = report_xml.webkit_header.footer_html
+ if not header and report_xml.header:
+ raise except_osv(
+ _('No header defined for this Webkit report!'),
+ _('Please set a header in company settings')
+ )
+ if not report_xml.header :
+ #I know it could be cleaner ...
+ header = u"""
+
+
+
+
+
+
+
+"""
+ css = report_xml.webkit_header.css
+ if not css :
+ css = ''
+ user = self.pool.get('res.users').browse(cursor, uid, uid)
+ company= user.company_id
+ parse_template = template
+ #default_filters=['unicode', 'entity'] can be used to set global filter
+ body_mako_tpl = Template(parse_template ,input_encoding='utf-8')
+ #BVR specific
+ bvr_path = addons.get_module_resource('l10n_ch/report/bvr.mako')
+ body_bvr_tpl = Template(file(bvr_path).read(), input_encoding='utf-8')
+
+ helper = report_helper.WebKitHelper(cursor, uid, report_xml.id, context)
+ ##BVR Specific
+ htmls = []
+ for obj in objs :
+
+ self.parser_instance.localcontext['objects'] = [obj]
+ if not company.bvr_only:
+ html = body_mako_tpl.render(
+ helper=helper,
+ css=css,
+ _=self.translate_call,
+ **self.parser_instance.localcontext
+ )
+ htmls.append(html)
+ if not company.invoice_only:
+ bvr = body_bvr_tpl.render(
+ helper=helper,
+ css=css,
+ _=self.translate_call,
+ **self.parser_instance.localcontext
+ )
+ htmls.append(bvr)
+ head_mako_tpl = Template(header, input_encoding='utf-8')
+ head = head_mako_tpl.render(
+ company=company,
+ time=time,
+ helper=helper,
+ css=css,
+ formatLang=self.parser_instance.formatLang,
+ setLang=self.parser_instance.setLang,
+ _debug=False
+ )
+ foot = False
+ if footer and company.invoice_only :
+ foot_mako_tpl = Template(footer ,input_encoding='utf-8')
+ foot = foot_mako_tpl.render(
+ company=company,
+ time=time,
+ helper=helper,
+ css=css,
+ formatLang=self.parser_instance.formatLang,
+ setLang=self.parser_instance.setLang,
+ _=self.translate_call,
+
+ )
+ if report_xml.webkit_debug :
+ deb = head_mako_tpl.render(
+ company=company,
+ time=time,
+ helper=helper,
+ css=css,
+ _debug=html,
+ formatLang=self.parser_instance.formatLang,
+ setLang=self.parser_instance.setLang,
+ _=self.translate_call,
+ )
+ return (deb, 'html')
+ bin = self.get_lib(cursor, uid, company.id)
+ pdf = self.generate_pdf(bin, report_xml, head, foot, htmls)
+ return (pdf, 'pdf')
+
+
+BVRWebKitParser('report.invoice_web_bvr',
+ 'account.invoice',
+ 'addons/l10n_ch/report/report_webkit_html.mako',
+ parser=l10n_ch_report_webkit_html)
diff --git a/addons/l10n_ch/report/report_webkit_html_view.xml b/addons/l10n_ch/report/report_webkit_html_view.xml
new file mode 100644
index 00000000000..8c66b1038c8
--- /dev/null
+++ b/addons/l10n_ch/report/report_webkit_html_view.xml
@@ -0,0 +1,162 @@
+
+
+
+