adding swiss localisation modules

bzr revid: nicolas.bessi@camptocamp.com-20090213155346-dm090u6oqpvb3ujw
This commit is contained in:
nicolas.bessi@camptocamp.com
2009-02-13 16:53:46 +01:00
parent a86a89517e
commit 9f8a426388
47 changed files with 125093 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
# -*- encoding: utf-8 -*-
#
# __init__.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import invoice
import company
import partner
import company
import wizard
import payment
import report
import bank
import account_move_line
+108
View File
@@ -0,0 +1,108 @@
# -*- encoding: utf-8 -*-
#
# __terp__.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
{
"name" : "Switzerland localisation corrected by Camptocamp",
"description" : """
Swiss localisation :
- DTA generation for a lot of paiment types
- BVR management (number generation, report, etc..)
- Import account move from the bank file (like v11 etc..)
- Simplify the way you handle the bank statement for reconciliation
You can also add with this module one of the following account plan:
- l10n_ch_c2c_pcg
------------------------------------------------------------------------
Module incluant la localisation Suisse de TinyERP revu et corrigé par Camptocamp. Cette nouvelle version
comprend la gestion et l'émissionde BVR, le paiement électronique via DTA (pour les banques, le système postal est en développement)
et l'import du relevé de compte depuis la banque de manière automatisée.
De plus, nous avons intégré la définition de toutes les banques Suisses(adresse, swift et clearing).
Par ailleurs, conjointement à ce module, nous proposons 1 plan comptables issus de l'USAM :
- l10n_ch_c2c_pcg
--------------------------------------------------------------------------
TODO :
- Implement bvr import partial reconciliation
- Replace wizard by osv_memory when possible
- Add mising HELP
- Finish code comment
- Improve demo data
""",
"version" : "5.0",
"author" : "Camptocamp SA",
"category" : "Localisation/Europe",
"website": "http://www.camptocamp.com",
"depends" : [
"base",
"account",
"base_vat",
"base_iban",
"account_payment",
"account_tax_include",
],
"init_xml" : [
"dta_data.xml",
"vaudtax_data.xml",
#these data will soon be part of an other modules but if you want
#them now uncomment the two lines
#"zip_code_default.xml",
#"bank_ch.xml",
],
"demo_xml" : [
"demo/vaudtax_data_demo.xml",
],
"update_xml" : [
"dta_view.xml",
"dta_wizard.xml",
"account_vat.xml",
"bvr_report.xml",
"bvr_wizard.xml",
"bvr_view.xml",
"company_view.xml",
"account_invoice.xml",
"bank_view.xml",
"account_journal_view.xml",
"security/ir.model.access.csv",
],
"active": False,
"installable": True,
}
+45
View File
@@ -0,0 +1,45 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="ir.ui.view" id="invoice_supplier_form6">
<field name="name">account.invoice.supplier.form.inherit</field>
<field name="model">account.invoice</field>
<field name="type">form</field>
<field name="inherit_id" ref="account.invoice_supplier_form"/>
<field name="arch" type="xml">
<field name="partner_id" position="replace">
<field name="partner_id"
on_change="onchange_partner_id(type,partner_id,date_invoice,payment_term, partner_bank)"
select="1"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="invoice_supplier_form8">
<field name="name">account.invoice.supplier.form.inherit</field>
<field name="model">account.invoice</field>
<field name="type">form</field>
<field name="inherit_id" ref="account.invoice_supplier_form"/>
<field name="priority" eval="18"/>
<field name="arch" type="xml">
<field name="partner_bank" position="replace">
<field name="partner_bank" select="2"
domain="[('partner_id', '=', partner_id)]"
on_change="onchange_partner_bank(partner_bank)"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="invoice_form">
<field name="name">account.invoice.form.inherit</field>
<field name="model">account.invoice</field>
<field name="type">form</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<field name="partner_bank" position="replace">
<field name="partner_bank" select="2"
domain="[('partner_id.ref_companies', 'in', [company_id])]"/>
</field>
</field>
</record>
</data>
</openerp>
+44
View File
@@ -0,0 +1,44 @@
<openerp>
<data>
<record id="view_account_journal_form_todo" model="ir.ui.view">
<field name="name">account.journal.todo.form</field>
<field name="model">account.journal.todo</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Account Journal">
<group colspan="4" col="6">
<field name="name" select="1"/>
</group>
<separator colspan="4" string="The accounts linked to the account journals"/>
<field name="default_credit_account_id"
on_change="on_change_credit(name, default_credit_account_id)" select="1"/>
<field name="default_debit_account_id"
on_change="on_change_debit(name, default_debit_account_id)" select="1"/>
<group col="4" colspan="4">
<button icon="gtk-cancel" name="action_cancel" string="Cancel" type="object"/>
<button icon="gtk-ok" name="action_new" string="Next" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_config_journal" model="ir.actions.act_window">
<field name="name">Configure Journal</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.journal.todo</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_account_journal_form_todo"/>
<field name="target">new</field>
</record>
<record id="action_config_journal_todo" model="ir.actions.todo">
<field name="name">Finalize your journal</field>
<field name="note">Set accounts on financial journals defined by
Camptocamp l10n_ch module</field>
<field name="action_id" ref="action_config_journal"/>
<field name="sequence">5</field>
</record>
</data>
</openerp>
+70
View File
@@ -0,0 +1,70 @@
#
# account_move_line.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from osv import fields, osv
class AccountMoveLine(osv.osv):
""" Inherit account.move.line in order to add a custom link
between supplier invoice line and bank. The original link
was defined in account_payment between line """
_inherit = 'account.move.line'
## @param self The object pointer.
## @param cr a psycopg cursor
## @param uid res.user.id that is currently loged
## @param payment_type manual
## @parma context a standard dict
## @return a dict who has the account move line id as key and the bank id as value
def line2bank(self, cr, uid, ids, payment_type='manual', context=None):
"""add a link to account.move.line in order to link
supplier invoice line and bank. The original link
was defined in account_payment"""
payment_mode_obj = self.pool.get('payment.mode')
line2bank = {}
if not ids:
return {}
bank_type = payment_mode_obj.suitable_bank_types(cr, uid, payment_type,
context=context)
for line in self.browse(cr, uid, ids, context=context):
if line.invoice and line.invoice.partner_bank:
line2bank[line.id] = line.invoice.partner_bank.id
elif line.partner:
for bank in line.partner.bank_ids:
if bank.state in bank_type:
line2bank[line.id] = bank.id
break
if line.id not in line2bank and line.partner.bank_ids:
line2bank[line.id] = line.partner.bank_ids[0].id
return line2bank
AccountMoveLine()
+45
View File
@@ -0,0 +1,45 @@
#
# bank.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from osv import fields, osv
class Bank(osv.osv):
"""Inherit res.bank class in order to add swiss specific field"""
_inherit = 'res.bank'
_columns = {
###Swiss unik bank identifier also use in IBAN number
'clearing': fields.char('Clearing number', size=64),
### city of the bank
'city': fields.char('City', size=128, select=1),
}
Bank()
+42507
View File
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="view_res_bank_form">
<field name="name">res.bank.form</field>
<field name="model">res.bank</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_res_bank_form"/>
<field name="arch" type="xml">
<field name="bic" position="after">
<field name="clearing" select="2"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="l10nch_view_res_bank_tree">
<field name="name">res.bank.tree</field>
<field name="model">res.bank</field>
<field name="type">tree</field>
<field name="inherit_id" ref="base.view_res_bank_tree"/>
<field name="arch" type="xml">
<field name="code" position="after">
<field name="clearing" select="1"/>
</field>
</field>
</record>
</data>
</openerp>
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<openerp>
<data>
<report
id="account_invoice_bvr"
string="BVR A4 Sheet"
model="account.invoice"
name="l10n_ch.bvr"
rml="l10n_ch/report/bvr.rml"
auto="False"
menu="False"
header="False"
/>
<report
id="invoice_bvr"
string="Invoice with BVR"
model="account.invoice"
name="l10n_ch.invoice.bvr"
rml="l10n_ch/report/invoice.rml"
auto="False"
menu="False"
header="False"
/>
</data>
</openerp>
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="ir.ui.view" id="view_bank_statement_form">
<field name="name">account.bank.statement.form.inherit</field>
<field name="model">account.bank.statement</field>
<field name="type">form</field>
<field name="inherit_id" ref="account.view_bank_statement_form"/>
<field name="arch" type="xml">
<field name="balance_end_real" position="after">
<button name="%(wizard_bvr_import)d" string="Import BVR" type="action" colspan="2"/>
</field>
</field>
</record>
</data>
</openerp>
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0"?>
<openerp>
<data>
<wizard
string="BVR"
model="account.invoice"
name="l10n_ch.bvr.check"
id="wizard_bvr_check_report"
keyword="client_print_multi"/>
<wizard
string="Invoices BVR"
model="account.invoice"
name="l10n_ch.invoice.bvr.check"
id="wizard_invoice_bvr_check_report"
keyword="client_print_multi"/>
<wizard
string="BVR Import"
model="account.bank.statement"
name="l10n_ch.bvr_import"
id="wizard_bvr_import"
menu="False"/>
</data>
</openerp>
+49
View File
@@ -0,0 +1,49 @@
# -*- encoding: utf-8 -*-
#
# company.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import netsvc
from osv import fields, osv
class res_company(osv.osv):
"""override company in order to add bvr vertical and
Horizontal print delta"""
_inherit = "res.company"
_columns = {
### horiz. delta in mm 1.2 will print the bvz 1.2mm lefter
'bvr_delta_horz': fields.float('BVR Horz. Delta (mm)',
help='horiz. delta in mm 1.2 will print the bvz 1.2mm lefter'),
### vert. delta in mm 1.2 will print the bvz 1.2mm lefter
'bvr_delta_vert': fields.float('BVR Vert. Delta (mm)',
help='vert. delta in mm 1.2 will print the bvz 1.2mm lefter'),
}
res_company()
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="ir.ui.view" id="company_form_view">
<field name="name">res.company.form.inherit.bvr</field>
<field name="model">res.company</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="arch" type="xml">
<field name="rml_footer2" position="after">
<field name="bvr_delta_horz"/>
<field name="bvr_delta_vert"/>
</field>
</field>
</record>
</data>
</openerp>
+66
View File
@@ -0,0 +1,66 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="res.bank" id="partner_bank">
<field name="name">Fortis s.a.</field>
<field name="clearing">123456</field>
</record>
<record model="res.partner.bank" id="agro_bank">
<field name="name">Fortis account</field>
<field name="acc_number">123456</field>
<field name="partner_id" ref="base.res_partner_agrolait"/>
<field name="state">bvrbank</field>
<field name="bvr_number">234567</field>
<field name="bank" ref="partner_bank"/>
<field name="iban">CH9100767000S00023455</field>
</record>
<record model="res.partner.bank" id="main_bank">
<field name="name">My bank</field>
<field name="acc_number">123456</field>
<field name="iban">123456</field>
<field name="partner_id" ref="base.main_partner"/>
<field name="state">dta_company</field>
<field name="bank" ref="partner_bank"/>
<field name="iban">CH9100767000S00023455</field>
</record>
<record model="account.invoice" id="v11_invoice">
<field name="name">V11 invoice</field>
<field name="amount_total">54150</field>
<field name="number">1</field>
<field name="partner_id" ref="base.res_partner_agrolait"/>
<field name="address_invoice_id" ref="base.res_partner_address_8"/>
<field name="account_id" ref="account.a_recv"/>
<field name="currency_id" ref="base.EUR"/>
<field name="company_id" ref="base.main_partner"/>
</record>
<record model="account.invoice.line" id="v11_invoice_line">
<field name="name">Dummy product</field>
<field name="price_unit">54150</field>
<field name="quantity">1</field>
<field name="account_id" ref="account.a_sale"/>
<field name="invoice_id" ref="v11_invoice"/>
</record>
<record model="account.journal" id="account.sales_journal">
<field name="default_debit_account_id" ref="account.a_recv"/>
</record>
<!-- Define a payment mode -->
<record model="payment.mode" id="payment_mode_dta">
<field name="name">DTA</field>
<field name="type" ref="payment_type_dta"/>
<field name="bank_id" ref="main_bank"/>
<field name="journal" model="account.journal" search="[('type','=','cash')]"/>
</record>
</data>
</openerp>
+88
View File
@@ -0,0 +1,88 @@
<openerp>
<data noupdate="1">
<record id="bank" model="res.partner">
<field name="comment">My bank !</field>
<field name="ref">banq</field>
<field name="name">Banque</field>
<field name="category_id" model="res.partner.category" search="[('name','=','Partenaire')]"/>
</record>
<record id="res_partner_address_bank1" model="res.partner.address">
<field name="fax">+41 31 622 13 00</field>
<field name="name">Marc Dufour</field>
<field name="zip">1015</field>
<field name="city">Lausanne</field>
<field name="partner_id" ref="bank"/>
<field name="country_id" model="res.country" search="[('code','=','ch')]"/>
<field name="title">M.</field>
<field name="email">tinyerp@bank.com</field>
<field name="phone">+41 24 620 10 12</field>
<field name="street">PSE-C</field>
<field name="active">1</field>
<field name="type">default</field>
</record>
<record id="prolibre" model="res.partner">
<field name="comment">Very good company!
They provides a very high quality service.</field>
<field name="ref">ProL</field>
<field name="website">http://camptocamp.com</field>
<field name="name">ProLibre</field>
<field name="category_id" model="res.partner.category" search="[('name','=','Partenaire')]"/>
</record>
<record id="camptocamp" model="res.partner">
<field name="comment">Very good company!
They provides a very high quality service.</field>
<field name="ref">c2c</field>
<field name="website">http://camptocamp.com</field>
<field name="name">camptocamp SA</field>
<field name="category_id" model="res.partner.category" search="[('name','=','Partenaire')]"/>
</record>
<!--
Resource: res.partner.address
-->
<record id="res_partner_address_1" model="res.partner.address">
<field name="fax">+41 21 619 10 00</field>
<field name="name">Luc Maurer</field>
<field name="zip">1015</field>
<field name="city">Lausanne</field>
<field name="partner_id" ref="camptocamp"/>
<field name="country_id" model="res.country" search="[('code','=','ch')]"/>
<field name="title">M.</field>
<field name="email">tinyerp@camptocamp.com</field>
<field name="phone">+41 21 619 10 12</field>
<field name="street">PSE-A, EPFL</field>
<field name="active">1</field>
<field name="type">default</field>
</record>
<record id="res_partner_address_2" model="res.partner.address">
<field name="name">Gilbert Robert</field>
<field name="zip">1227</field>
<field name="city">Carouge</field>
<field name="partner_id" ref="prolibre"/>
<field name="country_id" model="res.country" search="[('code','=','ch')]"/>
<field name="title">M.</field>
<field name="email">info@prolibre.com</field>
<field name="phone">+41 22 3015383</field>
<field name="street">18, rue des Moraines </field>
<field name="active">1</field>
<field name="type">default</field>
</record>
<record id="res_partner_address_3" model="res.partner.address">
<field name="fax">+41 21 619 10 00</field>
<field name="name">Claude Philipona</field>
<field name="zip">1015</field>
<field name="city">Lausanne</field>
<field name="partner_id" ref="camptocamp"/>
<field name="country_id" model="res.country" search="[('name','=','Switzerland')]"/>
<field name="title">M.</field>
<field name="email">tinyerp@camptocamp.com</field>
<field name="phone">+41 21 619 10 12 </field>
<field name="street">PSE-A, EPFL</field>
<field name="active">1</field>
<field name="type">default</field>
</record>
</data>
</openerp>
+95
View File
@@ -0,0 +1,95 @@
# -*- encoding: utf-8 -*-
# dat.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import time
from osv import osv,fields
class account_dta(osv.osv):
"""class that implements bank DTA File format,
used to transfert bulk batch payment instruction to a bank"""
_name = "account.dta"
_description = "DTA History"
_columns = {
### name of the file
'name': fields.binary('DTA file', readonly=True),
### list of dta line linked to the dta order
'dta_line_ids': fields.one2many('account.dta.line','dta_id','DTA lines', readonly=True),
## textual notes
'note': fields.text('Creation log', readonly=True,
help="display the problem during dta generation"),
### bank how will execute DTA order
'bank': fields.many2one('res.partner.bank','Bank', readonly=True,select=True,
help="bank how will execute DTA order"),
### date of DTA order generation
'date': fields.date('Creation Date', readonly=True,select=True,
help="date of DTA order generation"),
### user how generate the DTA order
'user_id': fields.many2one('res.users','User', readonly=True, select=True),
}
account_dta()
class account_dta_line(osv.osv):
"""Class that represent a DTA order line,
each lin corressponds to a payment instruction"""
_name = "account.dta.line"
_description = "DTA line"
_columns = {
### name of the line
'name' : fields.many2one('account.invoice','Invoice', required=True, size=256),
### partner how will receive payments
'partner_id' : fields.many2one('res.partner','Partner',
help="Partenr to pay"),
### due date of the payment
'due_date' : fields.date('Due date'),
### date of the supplier invoice to pay
'invoice_date' : fields.date('Invoice date'),
### cash discount date
'cashdisc_date' : fields.date('Cash Discount date'),
### amount effectively paied on this line
'amount_to_pay' : fields.float('Amount to pay',
help="amount effectively paid"),
### amount that was on the supplier invoice
'amount_invoice': fields.float('Invoiced Amount',
help="amount to pay base on the supplier invoice"),
### Cash discount amount
'amount_cashdisc': fields.float('Cash Discount Amount'),
### Linke to the main dta order
'dta_id': fields.many2one('account.dta','Associated DTA', required=True, ondelete='cascade'),
### state of the invoice Drat, Cancel, Done
'state' : fields.selection([('draft','Draft'),('cancel','Error'),('done','Paid')],'State')
}
_defaults = {
'state' : lambda *a :'draft',
}
account_dta_line()
+152
View File
@@ -0,0 +1,152 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- Memo :
Mandatory for all kind of dta payment:
* for the partner bank:
- a bank name
* for the company:
- iban
Mandatory for iban payment:
* for the partner:
- iban
- BIC / iban or a city
Mandatory for bvrpost/bvrbank payment:
* for the partner:
- bvr ref number on the partner bank
Mandatory for bvbank payment:
* for the partner:
- bank number
Mandatory for bvpost payment:
* for the partner:
- post number
-->
<!-- Define new types -->
<record model="res.partner.bank.type" id="bank_dta">
<field name="name">Ordering party DTA</field>
<field name="code">dta_company</field>
</record>
<record model="res.partner.bank.type" id="dta_iban">
<field name="name">DTA-IBAN</field>
<field name="code">dta_iban</field>
</record>
<record model="res.partner.bank.type" id="bvrbank">
<field name="name">DTA-BVRBANK</field>
<field name="code">bvrbank</field>
</record>
<record model="res.partner.bank.type" id="bvrpost">
<field name="name">DTA-BVRPOST</field>
<field name="code">bvrpost</field>
</record>
<record model="res.partner.bank.type" id="bvpost">
<field name="name">DTA-BVPOST</field>
<field name="code">bvpost</field>
</record>
<record model="res.partner.bank.type" id="bvbank">
<field name="name">DTA-BVBANK</field>
<field name="code">bvbank</field>
</record>
<!-- Adjust the fields attributes for dta_company-->
<record model="res.partner.bank.type.field" id="iban_field">
<field name="name">iban</field>
<field name="bank_type_id" ref="bank_dta"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<!-- Adjust the fields attributes for dta_iban-->
<record model="res.partner.bank.type.field" id="iban_field_iban">
<field name="name">iban</field>
<field name="bank_type_id" ref="dta_iban"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<record model="res.partner.bank.type.field" id="bank_field_iban">
<field name="name">bank</field>
<field name="bank_type_id" ref="dta_iban"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<!-- Adjust the fields attributes for bvrbank-->
<record model="res.partner.bank.type.field" id="bank_field_bvrbank">
<field name="name">bank</field>
<field name="bank_type_id" ref="bvrbank"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<record model="res.partner.bank.type.field" id="bvr_num_field_bvrbank">
<field name="name">bvr_number</field>
<field name="bank_type_id" ref="bvrbank"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<!-- Adjust the fields attributes for bvrpost-->
<record model="res.partner.bank.type.field" id="bank_field_bvrpost">
<field name="name">bank</field>
<field name="bank_type_id" ref="bvrpost"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<record model="res.partner.bank.type.field" id="bvr_num_field_bvrpost">
<field name="name">bvr_number</field>
<field name="bank_type_id" ref="bvrpost"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<!-- Adjust the fields attributes for bvpost -->
<record model="res.partner.bank.type.field" id="bank_field_bvpost">
<field name="name">bank</field>
<field name="bank_type_id" ref="bvpost"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<record model="res.partner.bank.type.field" id="post_field_bvpost">
<field name="name">post_number</field>
<field name="bank_type_id" ref="bvpost"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<!-- Adjust the fields attributes for bvbank -->
<record model="res.partner.bank.type.field" id="bank_field_bvbank">
<field name="name">bank</field>
<field name="bank_type_id" ref="bvbank"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<record model="res.partner.bank.type.field" id="acc_num_field_bvbank">
<field name="name">acc_number</field>
<field name="bank_type_id" ref="bvbank"/>
<field name="required" eval="True"/>
<field name="readonly" eval="False"/>
</record>
<!-- Define a payment type -->
<record model="payment.type" id="payment_type_dta">
<field name="name">DTA</field>
<field name="code">dta</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('dta_iban'),ref('bvrbank'),ref('bvrpost'),ref('bvbank'),ref('bvpost')])]"/>
</record>
</data>
</openerp>
+39
View File
@@ -0,0 +1,39 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- Inherit both bank view -->
<record model="ir.ui.view" id="view_partner_bank_form">
<field name="name">partner - bank inherit</field>
<field name="model">res.partner</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<field name="acc_number" position="after">
<newline/>
<field name="bvr_number"/>
<field name="bvr_adherent_num"/>
<field name="post_number"/>
<field name="dta_code"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_partner_bank_form2">
<field name="name">partner - bank inherit</field>
<field name="model">res.partner.bank</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_bank_form"/>
<field name="arch" type="xml">
<field name="acc_number" position="after">
<newline/>
<field name="bvr_number"/>
<field name="bvr_adherent_num"/>
<field name="post_number"/>
<field name="dta_code"/>
</field>
</field>
</record>
</data>
</openerp>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<openerp>
<data>
<wizard
string="Create DTA"
model="payment.order"
name="account.dta_create"
menu= "False"
id="wizard_account_dta_create"/>
</data>
</openerp>
+210
View File
@@ -0,0 +1,210 @@
# -*- encoding: utf-8 -*-
#
# bank.py
# invoice.py
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import time
from osv import fields, osv
from tools import mod10r
from mx import DateTime
class account_invoice(osv.osv):
"""Inherit account.invoice in order to add bvr
printing functionnalites. BVR is a Swiss payment vector"""
_inherit = "account.invoice"
## @param self The object pointer.
## @param cursor a psycopg cursor
## @param user res.user.id that is currently loged
## @parma context a standard dict
## @return a list of tuple (name,value)
def _get_reference_type(self, cursor, user, context=None):
"""Function use by the function field reference_type in order to initalise available
BVR Reference Types"""
res = super(account_invoice, self)._get_reference_type(cursor, user,
context=context)
res.append(('bvr', 'BVR'))
return res
## @param self The object pointer.
## @param cursor a psycopg cursor
## @param user res.user.id that is currently loged
## @parma context a standard dict
## @param name of the files
## @param args a list of diverse argument
## @parma context a standard dict
## @return a dict (invoice id,amount to pay)
def _amount_to_pay(self, cursor, user, ids, name, args, context=None):
'''Return the amount still to pay regarding all the payment orders'''
if not ids:
return {}
res = {}
for invoice in self.browse(cursor, user, ids, context=context):
res[invoice.id] = 0.0
if invoice.move_id:
for line in invoice.move_id.line_id:
if not line.date_maturity or \
DateTime.strptime(line.date_maturity, '%Y-%m-%d') \
< DateTime.now():
res[invoice.id] += line.amount_to_pay
return res
_columns = {
### BVR reference type BVR or FREE
'reference_type': fields.selection(_get_reference_type,
'Reference Type', required=True),
### Partner bank link between bank and partner id
'partner_bank': fields.many2one('res.partner.bank', 'Bank Account',
help='The partner bank account to pay\nKeep empty to use the default'
),
### Amount to pay
'amount_to_pay': fields.function(_amount_to_pay, method=True,
type='float', string='Amount to be paid',
help='The amount which should be paid at the current date\n' \
'minus the amount which is already in payment order'),
}
## @param self The object pointer.
## @param cursor a psycopg cursor
## @param user res.user.id that is currently loged
## @parma ids invoices id
## @return a boolean True if valid False if invalid
def _check_bvr(self, cr, uid, ids):
"""
Function to validate a bvr reference like :
0100054150009>132000000000000000000000014+ 1300132412>
The validation is based on l10n_ch
"""
invoices = self.browse(cr,uid,ids)
for invoice in invoices:
if invoice.reference_type == 'bvr':
if not invoice.reference:
return False
## I need help for this bug because in this case
# <010001000060190> 052550152684006+ 43435>
# the reference 052550152684006 do not match modulo 10
#
if mod10r(invoice.reference[:-1]) != invoice.reference and \
len(invoice.reference) == 15:
return True
#
if mod10r(invoice.reference[:-1]) != invoice.reference:
return False
return True
## @param self The object pointer.
## @param cursor a psycopg cursor
## @param user res.user.id that is currently loged
## @parma ids invoices id
## @return a boolean True if valid False if invalid
def _check_reference_type(self, cursor, user, ids):
"""Check the customer invoice reference type depending
on the BVR reference type and the invoice partner bank type"""
for invoice in self.browse(cursor, user, ids):
if invoice.type in 'in_invoice':
if invoice.partner_bank and \
invoice.partner_bank.state in \
('bvrbank', 'bvrpost') and \
invoice.reference_type != 'bvr':
return False
return True
_constraints = [
(_check_bvr, 'Error: Invalid Bvr Number (wrong checksum).',
['reference']),
(_check_reference_type, 'Error: BVR reference is required.',
['reference_type']),
]
## @param self The object pointer.
## @param cr a psycopg cursor
## @param uid res.user.id that is currently loged
## @parma ids invoices id
## @parma type the invoice type
## @param partner_id the partner linked to the invoice
## @parma date_invoice date of the invoice
## @parma payment_term inoice payment term
## @param partner_bank_id the partner linked invoice bank
## @return the dict of values with the partner_bank value updated
def onchange_partner_id(self, cr, uid, ids, type, partner_id,
date_invoice=False, payment_term=False, partner_bank_id=False):
""" Function that is call when the partner of the invoice is changed
it will retriev and set the good bank partner bank"""
res = super(account_invoice, self).onchange_partner_id(
cr,
uid,
ids,
type,
partner_id,
date_invoice,
payment_term
)
bank_id = False
if partner_id:
p = self.pool.get('res.partner').browse(cr, uid, partner_id)
if p.bank_ids:
bank_id = p.bank_ids[0].id
if type in ('in_invoice', 'in_refund'):
res['value']['partner_bank'] = bank_id
if partner_bank_id != bank_id:
to_update = self.onchange_partner_bank(cr, uid, ids, bank_id)
res['value'].update(to_update['value'])
return res
## @param self The object pointer.
## @param cursor a psycopg cursor
## @param user res.user.id that is currently loged
## @parma ids invoices id
## @param partner_bank_id the partner linked invoice bank
## @return the dict of values with the reference type value updated
def onchange_partner_bank(self, cursor, user, ids, partner_bank_id):
"""update the reference type depending of the partner bank"""
res = {'value': {}}
partner_bank_obj = self.pool.get('res.partner.bank')
if partner_bank_id:
partner_bank = partner_bank_obj.browse(cursor, user, partner_bank_id)
if partner_bank.state in ('bvrbank', 'bvrpost'):
res['value']['reference_type'] = 'bvr'
return res
account_invoice()
class account_tax_code(osv.osv):
"""Inherit account tax code in order
to add a Case code"""
_name = 'account.tax.code'
_inherit = "account.tax.code"
_columns = {
### The case code of the taxt code
'code': fields.char('Case Code', size=512),
}
account_tax_code()
+98
View File
@@ -0,0 +1,98 @@
# -*- encoding: utf-8 -*-
#
# bank.py
# partner.py
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import netsvc
from osv import fields, osv
class res_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'ref_companies': fields.one2many('res.company', 'partner_id',
'Companies that refers to partner'),
}
res_partner()
class res_partner_bank(osv.osv):
_inherit = "res.partner.bank"
_columns = {
'name': fields.char('Description', size=128, required=True),
'post_number': fields.char('Post number', size=64),
'bvr_number': fields.char('BVR account number', size=11),
'bvr_adherent_num': fields.char('BVR adherent number', size=11),
'dta_code': fields.char('DTA code', size=5),
}
def _default_value(self, cursor, user, field, context=None):
if field in ('country_id', 'state_id'):
value = False
else:
value = ''
if not context.get('address', False):
return value
for ham, spam, address in context['address']:
if 'type' in address.keys() :
if address['type'] == 'default':
return address[field]
elif not address['type']:
value = address[field]
else :
value = False
return value
def name_get(self, cr, uid, ids, context=None):
if not len(ids):
return []
bank_type_obj = self.pool.get('res.partner.bank.type')
type_ids = bank_type_obj.search(cr, uid, [])
bank_type_names = {}
for bank_type in bank_type_obj.browse(cr, uid, type_ids,
context=context):
bank_type_names[bank_type.code] = bank_type.name
res = []
for r in self.read(cr, uid, ids, ['name','state'], context):
res.append((r['id'], r['name']+' : '+bank_type_names[r['state']]))
return res
_sql_constraints = [
('bvr_adherent_uniq', 'unique (bvr_adherent_num)', 'The BVR adherent number must be unique !')
]
res_partner_bank()
+43
View File
@@ -0,0 +1,43 @@
# -*- encoding: utf-8 -*-
#
# payment.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from osv import fields
from osv import osv
class payment_order(osv.osv):
_inherit = 'payment.order'
def get_wizard(self,mode):
if mode == 'dta':
return 'l10n_ch','wizard_account_dta_create'
return super(payment_order,self).get_wizard(mode)
payment_order()
+29
View File
@@ -0,0 +1,29 @@
# -*- encoding: utf-8 -*-
#
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
+33
View File
@@ -0,0 +1,33 @@
# -*- encoding: utf-8 -*-
#
# __init__.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import bvr
+102
View File
@@ -0,0 +1,102 @@
# -*- encoding: utf-8 -*-
#
# bvr.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import time
from report import report_sxw
from tools import mod10r
import re
from mx.DateTime import *
class account_invoice_bvr(report_sxw.rml_parse):
"""Report class that Allows to print BVR payement vector"""
def __init__(self, cr, uid, name, context):
super(account_invoice_bvr, self).__init__(cr, uid, name, context)
self.localcontext.update({
'time': time,
'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,
'format_date': self._get_and_change_date_format_for_swiss,
#'date_invoice':
})
def _get_and_change_date_format_for_swiss (self,date_to_format):
date_formatted=''
print date_to_format
if date_to_format:
date_formatted = strptime(date_to_format,'%Y-%m-%d').strftime('%d.%m.%Y')
return date_formatted
def comma_me(self,amount):
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):
res = ''
for i in range(len(nbr)):
res = res + nbr[i]
if not (i-1) % nbrspc:
res = res + ' '
return res
def _get_ref(self, o):
res = ''
if o.partner_bank.bvr_adherent_num:
res = o.partner_bank.bvr_adherent_num
invoice_number = ''
if o.number:
invoice_number = re.sub('[^0-9]', '0', o.number)
return mod10r(res + invoice_number.rjust(26-len(res), '0'))
report_sxw.report_sxw(
'report.l10n_ch.bvr',
'account.invoice',
'addons/l10n_ch/report/bvr.rml',
parser=account_invoice_bvr,
header=False)
report_sxw.report_sxw(
'report.l10n_ch.invoice.bvr',
'account.invoice',
'addons/l10n_ch/report/invoice.rml',
parser=account_invoice_bvr,
header=False)
+164
View File
@@ -0,0 +1,164 @@
<?xml version="1.0"?>
<document filename="test.pdf">
<docinit>
<registerFont fontName="ocrb" fontFile="addons/l10n_ch/report/ocrbb.ttf"/>
</docinit>
<template pageSize="(210.0mm,297.0mm)" title="Test" author="Martin Simon" allowSplitting="20">
<pageTemplate id="first">
<pageGraphics>
<setFont name="Helvetica" size="30"/>
<fill color="darkblue"/>
<stroke color="darkblue"/>
<drawString x="1cm" y="27.8cm">[[ company.partner_id.name ]]</drawString>
<lines>1cm 27.7cm 20cm 27.7cm</lines>
<setFont name="Helvetica" size="10"/>
<drawRightString x="20cm" y="27.8cm">[[ company.rml_header1 ]]</drawRightString>
<drawString x="1cm" y="27.1cm">[[ company.partner_id.address[0].street ]]</drawString>
<drawString x="1cm" y="26.7cm">[[ company.partner_id.address[0].zip ]] [[ company.partner_id.address[0].city ]]</drawString>
<drawString x="17cm" y="27.1cm">TVA:</drawString>
<drawString x="18cm" y="27.1cm">[[ company.partner_id.vat ]]</drawString>
<drawString x="1cm" y="26.2cm">Phone:</drawString>
<drawRightString x="7cm" y="26.2cm">[[ company.partner_id.address[0].phone ]]</drawRightString>
<drawString x="1cm" y="25.8cm">Mail:</drawString>
<drawRightString x="7cm" y="25.8cm">[[ company.partner_id.address[0].email ]]</drawRightString>
<lines>1cm 25.7cm 7cm 25.7cm</lines>
</pageGraphics>
<frame id="first" x1="24.0" y1="111.5mm" width="190mm" height="142mm" last="1"/>
<frame id="Frame1"
expr="{'height':str(111+(company.bvr_delta_vert or 0.0))+'mm', 'x1': str((company.bvr_delta_horz or 0.0))+'mm'}"
x1="0mm"
y1="0mm"
width="210mm"
height="106mm"/>
</pageTemplate>
</template>
<stylesheet>
<blockTableStyle id="Standard_Outline">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<blockTableStyle id="Table1">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<blockTableStyle id="Table2">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<initialize>
<paraStyle name="all" alignment="justify"/>
</initialize>
<paraStyle name="P1" fontName="Times-Roman" fontSize="11.0" leading="14"/>
<paraStyle name="P2" fontName="Times-Roman" fontSize="11.0" leading="14" alignment="LEFT"/>
<paraStyle name="PBVR" fontName="ocrb" fontSize="11.0" leading="14" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P4" fontName="Times-Roman" fontSize="11.0" leading="14" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P5" fontName="Times-Roman" fontSize="11.0" leading="14" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P6" fontName="ocrb" fontSize="11.0" leading="14" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P7" fontName="Courier-Bold" fontSize="12.0" leading="15" alignment="LEFT"/>
<paraStyle name="P8" fontName="Times-Roman" fontSize="6.0" leading="8" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P9" fontName="Times-Roman" fontSize="12.0" leading="15" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P10" fontName="Times-Roman" fontSize="11.0" leading="14"/>
<paraStyle name="P11" fontName="Times-Roman" fontSize="11.0" leading="14" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="Standard" fontName="Times-Roman"/>
<paraStyle name="Text body" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="List" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="Table Contents" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="Table Heading" fontName="Times-Roman" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="Caption" fontName="Times-Roman" fontSize="10.0" leading="13" spaceBefore="6.0" spaceAfter="6.0"/>
<paraStyle name="Frame contents" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="Index" fontName="Times-Roman"/>
</stylesheet>
<story>
<para style="P8">[[ repeatIn(objects,'o') ]]<font face="Times-Roman">[[ setLang(o.partner_id.lang) ]]</font></para>
<blockTable colWidths="264.0,264.0" style="Table2">
<tr>
<td>
<para style="P9">
<font color="white"> </font>
</para>
</td>
<td>
<para style="P10">[[ o.partner_id.title or '' ]] [[ o.partner_id.name ]]</para>
<para style="P10">[[ o.address_invoice_id.title or '' ]] [[ o.address_invoice_id.name ]]</para>
<para style="P10">[[ o.address_invoice_id.street ]]</para>
<para style="P10">[[ o.address_invoice_id.street2 or '' ]]</para>
<para style="P10">[[ o.address_invoice_id.zip or '' ]] [[ o.address_invoice_id.city or '' ]]</para>
<para style="P10">[[ o.address_invoice_id.state_id and o.address_invoice_id.state_id.name or '' ]]</para>
<para style="P10">[[ o.address_invoice_id.country_id and o.address_invoice_id.country_id.name or '' ]]</para>
</td>
</tr>
</blockTable>
<para style="P11">
<font color="white"> </font>
</para>
<para style="P11"><font face="Helvetica-Bold">Subject: </font>Invoice - [[ o.number ]]</para>
<para style="P11">
<font color="white"> </font>
</para>
<para style="P11">Dear customer,</para>
<para style="P11">Here is the BVR to allow you to pay the invoice ' <font face="Times-Roman">[[ o.name ]]</font>', reference:<font face="Times-Roman"> [[ o.number ]].</font></para>
<para style="P11">Thanks,</para>
<para style="P11">
<font color="white"> </font>
</para>
<para style="P11">[[ user.signature ]]</para>
<currentFrame name="Frame1"/>
<!--
Width: 2.3inch, 5.9inch
Height: 4*1/6 inch
-->
<illustration width="210mm" height="106mm">
<setFont name="Helvetica" size="11"/>
<drawString x="2mm" y="78mm"> [[ user.company_id.partner_id.name ]]</drawString>
<drawString x="2mm" y="73mm"> [[ user.company_id.partner_id.address[0].street ]]</drawString>
<drawString x="2mm" y="68mm"> [[ (user.company_id.partner_id.address[0].street2 or '')]]</drawString>
<drawString x="2mm" y="63mm"> [[ user.company_id.partner_id.address[0].zip ]] [[ user.company_id.partner_id.address[0].city ]]</drawString>
<drawString x="62mm" y="78mm">[[ user.company_id.partner_id.name ]]</drawString>
<drawString x="62mm" y="73mm">[[ user.company_id.partner_id.address[0].street ]]</drawString>
<drawString x="62mm" y="68mm">[[ (user.company_id.partner_id.address[0].street2 or '')]]</drawString>
<drawString x="62mm" y="63mm">[[ user.company_id.partner_id.address[0].zip ]] [[ user.company_id.partner_id.address[0].city ]]</drawString>
<setFont name="ocrb" size="9"/>
<drawString x="2mm" y="35mm"> [[ o.partner_id.name ]]</drawString>
<drawString x="2mm" y="30mm"> [[ o.address_invoice_id.street ]]</drawString>
<drawString x="2mm" y="25mm"> [[ (o.address_invoice_id.street2 or '')]]</drawString>
<drawString x="2mm" y="20mm"> [[ o.address_invoice_id.zip ]] [[ o.address_invoice_id.city ]]</drawString>
<drawString x="2mm" y="40mm"> [[ _get_ref(o) ]]</drawString>
<drawString x="126mm" y="50mm">[[ o.partner_id.name ]]</drawString>
<drawString x="126mm" y="45mm">[[ o.address_invoice_id.street ]]</drawString>
<drawString x="126mm" y="40mm">[[ (o.address_invoice_id.street2 or '')]]</drawString>
<drawString x="126mm" y="35mm">[[ o.address_invoice_id.zip ]] [[ o.address_invoice_id.city ]]</drawString>
<setFont name="ocrb" size="11"/>
<drawString x="124mm" y="67mm">[[ _space(_get_ref(o)) ]]</drawString>
<setFont name="ocrb" size="12"/>
<drawRightString x="42mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[:-3], 1) + ' ' ]]</drawRightString>
<drawRightString x="104mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[:-3], 1) + ' ' ]]</drawRightString>
<drawRightString x="58mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[-2:], 1) + ' ' ]]</drawRightString>
<drawRightString x="119mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[-2:], 1) + ' ' ]]</drawRightString>
<!--
Exact value: y=17.6mm
-->
<setFont name="ocrb" size="11.5"/>
<drawRightString x="195mm" y="15mm">[[mod10r('01'+str('%.2f' % o.amount_total).replace('.','').rjust(10,'0'))]]&gt;[[ _get_ref(o) ]]+ [[o.partner_bank.bvr_number.split('-')[0]+(str(o.partner_bank.bvr_number.split('-')[1])).rjust(6,'0')+o.partner_bank.bvr_number.split('-')[2] ]]&gt;</drawRightString>
</illustration>
</story>
</document>
+378
View File
@@ -0,0 +1,378 @@
<?xml version="1.0"?>
<document filename="test.pdf">
<docinit>
<registerFont fontName="ocrb" fontFile="addons/l10n_ch/report/ocrbb.ttf"/>
</docinit>
<template pageSize="(210.0mm,297.0mm)" title="Test" author="Martin Simon" allowSplitting="20">
<pageTemplate id="first">
<pageGraphics>
<!--logo-->
<setFont name="Helvetica" size="30"/>
<fill color="darkblue"/>
<stroke color="darkblue"/>
<drawString x="1cm" y="27.8cm">[[ company.partner_id.name ]]</drawString>
<lines>1cm 27.7cm 20cm 27.7cm</lines>
<setFont name="Helvetica" size="10"/>
<drawRightString x="20cm" y="27.8cm">[[ company.rml_header1 ]]</drawRightString>
<drawString x="1cm" y="27.1cm">[[ company.partner_id.address and company.partner_id.address[0].street ]]</drawString>
<drawString x="1cm" y="26.7cm">[[ company.partner_id.address and company.partner_id.address[0].zip ]] [[ company.partner_id.address and company.partner_id.address[0].city ]] - [[ company.partner_id.address and company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name ]]</drawString>
<drawString x="17cm" y="27.1cm">TVA:</drawString>
<drawString x="18cm" y="27.1cm">[[ company.partner_id.vat ]]</drawString>
<drawString x="1cm" y="26.2cm">Phone:</drawString>
<drawRightString x="7cm" y="26.2cm">[[ company.partner_id.address and company.partner_id.address[0].phone ]]</drawRightString>
<drawString x="1cm" y="25.8cm">Mail:</drawString>
<drawRightString x="7cm" y="25.8cm">[[ company.partner_id.address and company.partner_id.address[0].email ]]</drawRightString>
<lines>1cm 25.7cm 7cm 25.7cm</lines>
</pageGraphics>
<!-- end of header -->
<frame id="first" x1="24.0" y1="111.5mm" width="190mm" height="142mm" last="1"/>
<frame id="Frame1"
expr="{'height':str(111+(company.bvr_delta_vert or 0.0))+'mm', 'x1': str((company.bvr_delta_horz or 0.0))+'mm'}"
x1="0mm"
y1="0mm"
width="210mm"
height="106mm"/>
</pageTemplate>
</template>
<!-- begin of core -->
<stylesheet>
<blockTableStyle id="Standard_Outline">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<blockTableStyle id="Table1">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<blockTableStyle id="Table2">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
<lineStyle kind="GRID" colorName="black"/>
<blockBackground colorName="#e6e6e6" start="0,0" stop="0,0"/>
<blockBackground colorName="#e6e6e6" start="1,0" stop="1,0"/>
<blockBackground colorName="#e6e6e6" start="2,0" stop="2,0"/>
<blockBackground colorName="#e6e6e6" start="3,0" stop="3,0"/>
<blockBackground colorName="#e6e6e6" start="4,0" stop="4,0"/>
<blockBackground colorName="#e6e6e6" start="5,0" stop="5,0"/>
</blockTableStyle>
<blockTableStyle id="Table3">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<blockTableStyle id="Table4">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<blockTableStyle id="Table5">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
<blockBackground colorName="#e6e6e6" start="0,1" stop="0,1"/>
<blockBackground colorName="#e6e6e6" start="1,1" stop="1,1"/>
<blockBackground colorName="#e6e6e6" start="2,1" stop="2,1"/>
</blockTableStyle>
<blockTableStyle id="Table6">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
<blockBackground colorName="#e6e6e6" start="0,0" stop="0,0"/>
<blockBackground colorName="#e6e6e6" start="1,0" stop="1,0"/>
<blockBackground colorName="#e6e6e6" start="2,0" stop="2,0"/>
</blockTableStyle>
<blockTableStyle id="Table7">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<initialize>
<paraStyle name="all" alignment="justify"/>
</initialize>
<paraStyle name="P1" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P2" fontName="Helvetica-BoldOblique" fontSize="6.0" leading="8" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P3" fontName="Helvetica" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P4" fontName="Helvetica-BoldOblique" fontSize="11.0" leading="14" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P5" fontName="Helvetica-BoldOblique" fontSize="11.0" leading="14" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P6" fontName="Helvetica" fontSize="10.0" leading="13" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P7" fontName="Helvetica" fontSize="10.0" leading="13" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P8" fontName="Helvetica" fontSize="10.0" leading="13" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P9" fontName="Helvetica-Oblique" fontSize="8.0" leading="10" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P10" fontName="Helvetica" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P11" fontName="Helvetica" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P12" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P13" fontName="Helvetica" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P14" fontName="Helvetica-Bold" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P15" fontName="Helvetica-Bold" fontSize="5.0" leading="6" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P16" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P17" fontName="Helvetica-Bold" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P18" fontName="Helvetica"/>
<paraStyle name="P19" fontName="Helvetica-Bold" fontSize="20.0" leading="25" alignment="LEFT"/>
<paraStyle name="P20" fontName="Helvetica-BoldOblique" fontSize="14.0" leading="17" alignment="CENTER"/>
<paraStyle name="P21" fontName="Helvetica" fontSize="11.0" leading="14"/>
<paraStyle name="P22" fontName="Helvetica-Bold" fontSize="11.0" leading="14"/>
<paraStyle name="P23" fontName="Helvetica" fontSize="11.0" leading="14" alignment="LEFT"/>
<paraStyle name="P24" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="LEFT"/>
<paraStyle name="P25" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P26" fontName="Helvetica-BoldOblique" fontSize="6.0" leading="8" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P27" fontName="Helvetica" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P28" fontName="Helvetica-BoldOblique" fontSize="11.0" leading="14" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P29" fontName="Helvetica-BoldOblique" fontSize="11.0" leading="14" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P30" fontName="Helvetica" fontSize="10.0" leading="13" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P31" fontName="Helvetica" fontSize="10.0" leading="13" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P32" fontName="Helvetica" fontSize="10.0" leading="13" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P33" fontName="Helvetica-Oblique" fontSize="8.0" leading="10" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P34" fontName="Helvetica" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P35" fontName="Helvetica" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P36" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P37" fontName="Helvetica" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P38" fontName="Helvetica-Bold" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P39" fontName="Helvetica-Bold" fontSize="6.0" leading="8" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P40" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P41" fontName="Helvetica-Bold" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P42" fontName="Helvetica"/>
<paraStyle name="P43" fontName="Helvetica" fontSize="11.0" leading="14" alignment="LEFT"/>
<paraStyle name="P44" fontName="Helvetica-Bold" fontSize="20.0" leading="25" alignment="LEFT"/>
<paraStyle name="P45" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="LEFT"/>
<paraStyle name="P46" fontName="Helvetica-BoldOblique" fontSize="14.0" leading="17" alignment="CENTER"/>
<paraStyle name="P47" fontName="Helvetica" fontSize="11.0" leading="14"/>
<paraStyle name="P48" fontName="Helvetica-Bold" fontSize="11.0" leading="14"/>
<paraStyle name="Standard" fontName="Helvetica"/>
<paraStyle name="Text body" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="List" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="Table Contents" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="Table Heading" fontName="Helvetica" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="Caption" fontName="Helvetica" fontSize="10.0" leading="13" spaceBefore="6.0" spaceAfter="6.0"/>
<paraStyle name="Index" fontName="Helvetica"/>
</stylesheet>
<story>
<para style="P2">[[ repeatIn(objects,'o') ]]</para>
<para style="P2">[[ setLang(o.partner_id.lang) ]]</para>
<blockTable colWidths="295.0,232.0" style="Table1">
<tr>
<td>
<para style="P3">
<font color="white"> </font>
</para>
</td>
<td>
<para style="P18">[[ o.partner_id.title or '' ]] [[ o.partner_id.name ]]</para>
<para style="P18">[[ o.address_invoice_id.title or '' ]] [[ o.address_invoice_id.name ]]</para>
<para style="P18">[[ o.address_invoice_id.street ]]</para>
<para style="P18">[[ o.address_invoice_id.street2 or '' ]]</para>
<para style="P18">[[ o.address_invoice_id.zip or '' ]] [[ o.address_invoice_id.city or '' ]]</para>
<para style="P18">[[ o.address_invoice_id.state_id and o.address_invoice_id.state_id.name or '' ]]</para>
<para style="P18">[[ o.address_invoice_id.country_id and o.address_invoice_id.country_id.name or '' ]]</para>
<para style="P18">
<font color="white"> </font>
</para>
<para style="P18">VAT : [[ o.partner_id.vat or removeParentNode('para') ]]</para>
</td>
</tr>
</blockTable>
<para style="P19">
<font color="white"> </font>
</para>
<para style="P24">Invoice [[ ((o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')) or removeParentNode('para')) and '' ]] [[ o.number ]]</para>
<para style="P24">PRO-FORMA [[ ((o.type == 'out_invoice' and o.state == 'proforma') or removeParentNode('para')) and '' ]]</para>
<para style="P24">Draft Invoice [[ ((o.type == 'out_invoice' and o.state == 'draft') or removeParentNode('para')) and '' ]]</para>
<para style="P24">Canceled Invoice [[ ((o.type == 'out_invoice' and o.state == 'cancel') or removeParentNode('para')) and '' ]]</para>
<para style="P24">Refund [[ (o.type=='out_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]</para>
<para style="P24">Supplier Refund [[ (o.type=='in_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]</para>
<para style="P24">Supplier Invoice [[ (o.type=='in_invoice' or removeParentNode('para')) and '' ]] [[ o.number ]]</para>
<para style="P20">
<font color="white"> </font>
</para>
<para style="P21">
<font face="Helvetica">Concerne:</font>
<font face="Helvetica">[[o.name]]</font>
</para>
<para style="P21">
<font face="Helvetica">Invoice Date: </font>
<font face="Helvetica">[[format_date(o.date_invoice)]]</font>
</para>
<para style="P21">
<font face="Helvetica">Remarque:</font>
<font face="Helvetica"> [[o.comment]]</font>
</para>
<para style="P22">
<font face="Helvetica">Condition</font>
<font face="Helvetica"> : [[o.payment_term and o.payment_term.name or '']]</font>
</para>
<para style="P18">
<font color="white"> </font>
</para>
<blockTable colWidths="216.0, 62.0, 62.0, 63.0, 40.0, 84.0" style="Table2">
<tr>
<td>
<para style="P4">Description</para>
</td>
<td>
<para style="P5">TVA (%)</para>
</td>
<td>
<para style="P5">Quantity</para>
</td>
<td>
<para style="P5">Unit Price</para>
</td>
<td>
<para style="P5">Disc. (%)</para>
</td>
<td>
<para style="P5">Price </para>
</td>
</tr>
</blockTable>
<section>
<para style="P15">[[repeatIn(o.invoice_line,'l') ]]</para>
<blockTable colWidths="216.0, 62.0, 62.0, 63.0, 40.0, 84.0" style="Table3">
<tr>
<td>
<para style="P6">[[ l.name ]]</para>
</td>
<td>
<para style="P8">[[ ', '.join([str((float(lt.amount) * 100)) for lt in l.invoice_line_tax_id]) ]]</para>
</td>
<td>
<para style="P7">[[ l.quantity ]] </para>
</td>
<td>
<para style="P7">[[ comma_me( l.price_unit) ]]</para>
</td>
<td>
<para style="P7">[[ round(l.discount) ]]</para>
</td>
<td>
<para style="P7">[[ comma_me(l.price_subtotal) ]] [[o.currency_id.code ]]</para>
</td>
</tr>
</blockTable>
<blockTable colWidths="28.0,499.0" style="Table4">
<tr>
<td>
<para style="P16">[[ repeatIn((l.note and l.note.splitlines()) or [], 'note') ]]</para>
</td>
<td>
<para style="P9">[[ note or removeParentNode('table') ]]</para>
</td>
</tr>
</blockTable>
</section>
<para style="P18">
<font color="white"> </font>
</para>
<blockTable colWidths="215.0,313.0" style="Table5">
<tr>
<td>
<blockTable colWidths="81.0,73.0,60.0" style="Table6">
<tr>
<td>
<para style="P10">Tax</para>
</td>
<td>
<para style="P11">Base</para>
</td>
<td>
<para style="P11">Amount</para>
</td>
</tr>
<tr>
<td>
<para style="P12"><font face="Helvetica">[[ repeatIn(o.tax_line,'t') ]]</font> [[ t.name ]]</para>
</td>
<td>
<para style="P14">[[ comma_me( t.base )]]</para>
</td>
<td>
<para style="P14">[[ comma_me( t.amount)]]</para>
</td>
</tr>
</blockTable>
</td>
<td>
<blockTable colWidths="214.0,95.0" style="Table7">
<tr>
<td>
<para style="P13">Total (excl. taxes):</para>
</td>
<td>
<para style="P13">[[ comma_me(o.amount_untaxed) ]] [[o.currency_id.code ]]</para>
</td>
</tr>
<tr>
<td>
<para style="P13">Taxes:</para>
</td>
<td>
<para style="P13">[[ comma_me(o.amount_tax) ]] [[o.currency_id.code ]]</para>
</td>
</tr>
<tr>
<td>
<para style="P14">Total <font face="Helvetica">(incl. taxes):</font></para>
</td>
<td>
<para style="P17">[[ comma_me(o.amount_total) ]] [[o.currency_id.code ]]</para>
</td>
</tr>
</blockTable>
</td>
</tr>
</blockTable>
<!-- end of core -->
<currentFrame name="Frame1"/>
<!--
Width: 2.3inch, 5.9inch
Height: 4*1/6 inch
-->
<illustration width="210mm" height="106mm">
<setFont name="Helvetica" size="11"/>
<drawString x="2mm" y="78mm"> [[user.company_id.name]]</drawString>
<drawString x="2mm" y="73mm"> [[ user.company_id.partner_id.address[0].street ]]</drawString>
<drawString x="2mm" y="68mm"> [[ (user.company_id.partner_id.address[0].street2 or '')]]</drawString>
<drawString x="2mm" y="63mm"> [[ user.company_id.partner_id.address[0].zip ]] [[ user.company_id.partner_id.address[0].city ]]</drawString>
<drawString x="62mm" y="78mm">[[user.company_id.name]]</drawString>
<drawString x="62mm" y="73mm">[[ user.company_id.partner_id.address[0].street ]]</drawString>
<drawString x="62mm" y="68mm">[[ (user.company_id.partner_id.address[0].street2 or '')]]</drawString>
<drawString x="62mm" y="63mm">[[ user.company_id.partner_id.address[0].zip ]] [[ user.company_id.partner_id.address[0].city ]]</drawString>
<setFont name="ocrb" size="9"/>
<drawString x="2mm" y="35mm"> [[ o.partner_id.name ]]</drawString>
<drawString x="2mm" y="30mm"> [[ o.address_invoice_id.street ]]</drawString>
<drawString x="2mm" y="25mm"> [[ (o.address_invoice_id.street2 or '')]]</drawString>
<drawString x="2mm" y="20mm"> [[ o.address_invoice_id.zip ]] [[ o.address_invoice_id.city ]]</drawString>
<drawString x="2mm" y="40mm"> [[ _get_ref(o) ]]</drawString>
<drawString x="126mm" y="50mm">[[ o.partner_id.name ]]</drawString>
<drawString x="126mm" y="45mm">[[ o.address_invoice_id.street ]]</drawString>
<drawString x="126mm" y="40mm">[[ (o.address_invoice_id.street2 or '')]]</drawString>
<drawString x="126mm" y="35mm">[[ o.address_invoice_id.zip ]] [[ o.address_invoice_id.city ]]</drawString>
<setFont name="ocrb" size="11"/>
<drawString x="124mm" y="67mm">[[ _space(_get_ref(o)) ]]</drawString>
<setFont name="ocrb" size="12"/>
<drawRightString x="42mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[:-3], 1) + ' ' ]]</drawRightString>
<drawRightString x="104mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[:-3], 1) + ' ' ]]</drawRightString>
<drawRightString x="58mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[-2:], 1) + ' ' ]]</drawRightString>
<drawRightString x="119mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[-2:], 1) + ' ' ]]</drawRightString>
<!--
Exact value: y=17.6mm
-->
<setFont name="ocrb" size="11.5"/>
<drawRightString x="195mm" y="15mm">[[mod10r('01'+str('%.2f' % o.amount_total).replace('.','').rjust(10,'0'))]]&gt;[[ _get_ref(o) ]]+ [[o.partner_bank.bvr_number.split('-')[0]+(str(o.partner_bank.bvr_number.split('-')[1])).rjust(6,'0')+o.partner_bank.bvr_number.split('-')[2] ]]&gt;</drawRightString>
</illustration>
</story>
</document>
+610
View File
@@ -0,0 +1,610 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:office="http://openoffice.org/2000/office"
xmlns:style="http://openoffice.org/2000/style"
xmlns:text="http://openoffice.org/2000/text"
xmlns:table="http://openoffice.org/2000/table"
xmlns:draw="http://openoffice.org/2000/drawing"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:number="http://openoffice.org/2000/datastyle"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:chart="http://openoffice.org/2000/chart"
xmlns:dr3d="http://openoffice.org/2000/dr3d"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:form="http://openoffice.org/2000/form"
xmlns:script="http://openoffice.org/2000/script"
office:class="text" office:version="1.0"
exclude-result-prefixes = "xsl fo office style text table draw xlink number svg chart dr3d math form script">
<!--TODO's: indent, picture cache (trml2pdf) -->
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="text_style" match="style:style[@style:family='text']" use="@style:name" />
<xsl:key name="page_break_before" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-before='page']" use="@style:name" />
<xsl:key name="page_break_after" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-after='page']" use="@style:name" />
<xsl:key name="table_column_style" match="style:style[@style:family='table-column']" use="@style:name" />
<xsl:key name="table_cell_style" match="style:style[@style:family='table-cell']" use="@style:name" />
<xsl:key name="paragraph_style" match="style:style[@style:family='paragraph']" use="@style:name" />
<xsl:template match="office:document-content">
<document filename="test.pdf">
<xsl:apply-templates select="office:automatic-styles" />
<xsl:apply-templates select="office:body" />
</document>
</xsl:template>
<xsl:template name="page_size">
<xsl:attribute name="pageSize">
<xsl:text>(</xsl:text>
<xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
<xsl:text>,</xsl:text>
<xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
<xsl:text>)</xsl:text>
</xsl:attribute>
</xsl:template>
<xsl:template name="margin_sizes">
<xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
<xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
<xsl:variable name="margin_top" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-top" />
<xsl:variable name="margin_bottom" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-bottom" />
<xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
<xsl:variable name="page_height" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
<xsl:attribute name="x1"><xsl:value-of select="$margin_left" /></xsl:attribute>
<xsl:attribute name="y1"><xsl:value-of select="$margin_bottom" /></xsl:attribute>
<xsl:attribute name="width"><xsl:value-of select="$page_width - $margin_left - $margin_right"/></xsl:attribute>
<xsl:attribute name="height"><xsl:value-of select="$page_height - $margin_bottom - $margin_top"/></xsl:attribute>
</xsl:template>
<xsl:template name="text_width">
<!-- You need this for the workaround to make primitive outlines-->
<xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
<xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
<xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
<xsl:value-of select="$page_width - $margin_left - $margin_right - 18"/>
</xsl:template>
<xsl:template match="office:automatic-styles">
<!--<template pageSize="(21cm, 29.7cm)" leftMargin="1.0cm" rightMargin="2.0cm" topMargin="1.0cm" bottomMargin="1.0cm" title="Test" author="Martin Simon" allowSplitting="20">-->
<template pageSize="(21cm, 29.7cm)" title="Test" author="Martin Simon" allowSplitting="20">
<xsl:call-template name="page_size" />
<pageTemplate id="first">
<frame id="first" x1="2cm" y1="2cm" width="17cm" height="26cm">
<xsl:call-template name="margin_sizes" />
</frame>
</pageTemplate>
</template>
<stylesheet>
<!--A table style to simulate primitive outlines -till the <addOutline> tag is implemented in trml2pdf -->
<blockTableStyle id="Standard_Outline">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<!--use two standard table grid styles like PyOpenOffice "Old Way": with and without a grid-->
<!--TODO insert table cell colors here, not within the <td> tag - otherwise
it will not work with flowables as cell content-->
<xsl:call-template name="make_blocktablestyle" />
<initialize>
<paraStyle name="all" alignment="justify" />
</initialize>
<xsl:apply-templates select="style:style" />
</stylesheet>
</xsl:template>
<xsl:template name="make_blocktablestyle">
<xsl:for-each select="//table:table">
<xsl:variable name="test">
<xsl:value-of select="./@table:name" />
</xsl:variable>
<xsl:if test="not(boolean(count(preceding-sibling::table:table[@table:name=$test])))">
<!--Test if this is the first table with this style, nested tables not counted-->
<blockTableStyle id="{@table:name}">
<xsl:if test=".//draw:image">
<blockTopPadding value="0"/>
<blockBottomPadding value="0"/>
</xsl:if>
<blockAlignment value="LEFT" />
<blockValign value="TOP" />
<xsl:call-template name="make_tablegrid" />
<xsl:call-template name="make_tablebackground" />
</blockTableStyle>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="make_tablegrid">
<xsl:variable name="test_grid">
<xsl:call-template name="test_grid" />
</xsl:variable>
<xsl:if test="contains($test_grid,'has_grid')">
<lineStyle kind="GRID" colorName="black" />
</xsl:if>
</xsl:template>
<!-- Was needed to simulate bulleted lists:
<xsl:template match="text:ordered-list|text:unordered-list">
<xsl:variable name = "text_width">
<xsl:call-template name="text_width" />
</xsl:variable>
<blockTable style="Standard_Outline" colWidths="18,{$text_width}">
<xsl:apply-templates match="text:list-item" />
</blockTable>
</xsl:template>
<xsl:template match="text:list-item">
<tr>
<td><para><font face="Helvetica-Bold" size="10">*</font></para></td>
<td>
<xsl:apply-templates />
</td>
</tr>
</xsl:template>
-->
<xsl:template match="office:body">
<story>
<xsl:apply-templates />
</story>
</xsl:template>
<xsl:template match="table:table">
<blockTable>
<xsl:attribute name="colWidths">
<xsl:call-template name="make_columns" />
</xsl:attribute>
<xsl:call-template name="make_tableheaders" />
<xsl:attribute name="style">
<xsl:value-of select="@table:name" />
</xsl:attribute>
<xsl:apply-templates />
</blockTable>
</xsl:template>
<xsl:template name="make_tableheaders">
<xsl:if test="boolean(count(table:table-header-rows))">
<xsl:attribute name="repeatRows">1</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template name="make_tablebackground">
<xsl:for-each select=".//table:table-row">
<!--Be careful when there are table:table-header-rows as
parent node of table:table-row -->
<xsl:variable name="row" select="position() - 1" />
<xsl:for-each select="./table:table-cell">
<xsl:variable name="col" select="position() - 1" />
<xsl:variable name="background">
<xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:background-color" />
</xsl:variable>
<xsl:if test="not($background='') and boolean(key('table_cell_style',@table:style-name)/style:properties/@fo:background-color) and starts-with($background,'#')">
<!--only RGB hexcolors are accepted -->
<blockBackground colorName="{$background}" start="{$col},{$row}" stop="{$col},{$row}" />
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="test_grid">
<!--very primitive: if at last one cell has a border,
the whole table style is set to GRID.-->
<xsl:for-each select=".//table:table-cell">
<xsl:for-each select="key('table_cell_style',@table:style-name)/style:properties" >
<!--Test all table cell styles if there is at least one border line -->
<xsl:variable name="border">
<xsl:value-of select="@fo:border" />
</xsl:variable>
<xsl:if test="not($border='none') and not($border='') and boolean(@fo:border)">
<xsl:text>has_grid</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="make_columns">
<xsl:variable name="columns" >
<xsl:for-each select="table:table-column">
<xsl:value-of select="key('table_column_style',@table:style-name)/style:properties/@style:column-width" />
<xsl:text>,</xsl:text>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="substring($columns,1,string-length($columns) - 1)" />
<!--strip the last comma-->
</xsl:template>
<xsl:template match="table:table-row">
<tr>
<xsl:apply-templates />
</tr>
</xsl:template>
<xsl:template match="table:table-cell">
<td>
<xsl:apply-templates />
</td>
</xsl:template>
<xsl:template match="text:section">
<section>
<xsl:apply-templates />
</section>
</xsl:template>
<xsl:template match="text:span">
<font>
<xsl:call-template name="make_fontnames_span" />
<xsl:call-template name="make_fontsize_span" />
<xsl:apply-templates />
</font>
</xsl:template>
<xsl:template name="make_fontsize_span">
<xsl:variable name ="fontsize">
<xsl:value-of select="key('text_style',@text:style-name)/style:properties/@fo:font-size" />
</xsl:variable>
<xsl:if test="not($fontsize='') and boolean(key('text_style',@text:style-name)/style:properties/@fo:font-size)" >
<xsl:attribute name="size">
<xsl:value-of select="$fontsize" />
</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template name="make_fontnames_span">
<xsl:attribute name="face">
<xsl:call-template name="make_fontnames">
<xsl:with-param name="fontName" select="key('text_style',@text:style-name)/style:properties/@style:font-name" />
<xsl:with-param name="fontWeight" select="key('text_style',@text:style-name)/style:properties/@fo:font-weight" />
<xsl:with-param name="fontStyle" select="key('text_style',@text:style-name)/style:properties/@fo:font-style" />
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<xsl:template name="make_image">
<illustration height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}">
<image x="0" y="0" file="{substring-after(.//draw:image/@xlink:href,'#Pictures/')}" height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}" />
</illustration>
</xsl:template>
<xsl:template name="empty_paragraph">
<xsl:if test="not(boolean(count(descendant::node())))">
<xsl:call-template name="distance_point">
<xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="distance_point">
<xsl:param name="background" />
<xsl:param name="tab_stop"></xsl:param>
<xsl:variable name="local_back">
<xsl:choose>
<xsl:when test="not(boolean($background)) or not(contains($background,'#'))">
<!-- Do not accept OO colors like "transparent", only hex-colors -->
<xsl:text>white</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$background" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<font color="{$local_back}">
<xsl:text> </xsl:text>
<xsl:if test="boolean($tab_stop)">
<!-- simulate a tabstop with white/background-color points -->
<xsl:text>.........</xsl:text>
</xsl:if>
</font>
</xsl:template>
<xsl:template match="text:ordered-list">
<xsl:apply-templates />
<para><seqreset id="ordered_list" /></para>
<!-- Reset the counter. seqreset is not a trml2pdf tag, but a Platypus Intra Paragraph Markup,
so it needs a dummy paragraph to enclose it -->
</xsl:template>
<xsl:template name="make_listitem">
<xsl:if test="(name(..)='text:list-item')">
<xsl:attribute name="leftIndent">15</xsl:attribute>
<xsl:attribute name="bulletIndent">0</xsl:attribute>
<xsl:choose>
<xsl:when test="(name(../..)='text:unordered-list')">
<xsl:variable name="fontsize">
<xsl:value-of select="number(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)" />
</xsl:variable>
<xsl:choose>
<xsl:when test="$fontsize='NaN'">
<!-- you should exclude non-numerical values for bulletFontSize. <== Sometimes the preprocessing went wrong.-->
<!--use a default bullet font size-->
<xsl:attribute name="bulletFontSize">6</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="bulletFontSize"><xsl:value-of select="floor(($fontsize div 2) + 1)" /></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:attribute name="bulletFontName">ZapfDingbats</xsl:attribute>
<xsl:attribute name="bulletText">l</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- Generate the numbers for an ordered list -->
<xsl:variable name="size">
<xsl:value-of select="key('paragraph_style',@text:style-name)/style:properties/@fo:font-size" />
</xsl:variable>
<!-- For ordered lists we use the bullet tag from Platypus Intra Paragraph Markup -->
<bullet>
<xsl:if test="not($size='') and boolean(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)">
<xsl:attribute name="size">
<!-- adapt the fontsize to the fontsize of the current paragraph -->
<xsl:value-of select="$size" />
</xsl:attribute>
</xsl:if>
<seq id="ordered_list" />.</bullet>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template match="text:p|text:h">
<xsl:if test="boolean(key('page_break_before',@text:style-name))" >
<pageBreak />
</xsl:if>
<xsl:choose>
<xsl:when test="boolean(.//draw:image)">
<xsl:call-template name="make_image" />
</xsl:when>
<xsl:otherwise>
<para>
<xsl:attribute name="style">
<xsl:value-of select="@text:style-name" />
</xsl:attribute>
<xsl:call-template name="make_listitem" />
<xsl:apply-templates />
<xsl:call-template name="empty_paragraph" />
</para>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="boolean(key('page_break_after',@text:style-name))" >
<pageBreak />
</xsl:if>
</xsl:template>
<xsl:template match="text:p/text:tab-stop">
<!-- simulate a tabstop -->
<xsl:call-template name="distance_point">
<xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
<xsl:with-param name="tab_stop">yes</xsl:with-param>
</xsl:call-template>
</xsl:template>
<!-- experimental - switched off
<xsl:template match="text:h">
<para>
<xsl:attribute name="style">
<xsl:value-of select="@text:style-name" />
</xsl:attribute>
<xsl:call-template name="make_number" />
<xsl:apply-templates />
<xsl:call-template name="empty_paragraph" />
</para>
</xsl:template>
<xsl:template name="make_number">
<xsl:choose>
<xsl:when test="@text:level='1'">
<xsl:number format="1. " />
</xsl:when>
<xsl:when test="@text:level='2'">
<xsl:number count="text:h[@text:level='1']|text:h[text:level='2']" level="any" format="1.1." />
</xsl:when>
</xsl:choose>
</xsl:template>
-->
<xsl:template match="style:style[@style:family='paragraph']">
<paraStyle>
<xsl:attribute name="name">
<xsl:value-of select="@style:name" />
</xsl:attribute>
<xsl:call-template name="make_indent_paragraph" />
<xsl:call-template name="make_fontnames_paragraph" />
<xsl:call-template name="make_fontsize" />
<!--<xsl:call-template name="make_parent" /> not necessary -
parent styles processed by PyOpenOffice -->
<xsl:call-template name="make_alignment" />
<xsl:call-template name="make_background" />
<xsl:call-template name="make_space_beforeafter" />
</paraStyle>
</xsl:template>
<xsl:template name="make_indent_paragraph">
<xsl:variable name="right_indent"><xsl:value-of select="style:properties/@fo:margin-right" /></xsl:variable>
<xsl:variable name="left_indent"><xsl:value-of select="style:properties/@fo:margin-left" /></xsl:variable>
<xsl:if test="not($right_indent='') and boolean(style:properties/@fo:margin-right)">
<xsl:attribute name="rightIndent">
<xsl:value-of select="$right_indent" />
</xsl:attribute>
</xsl:if>
<xsl:if test="not($left_indent='') and boolean(style:properties/@fo:margin-left)">
<xsl:attribute name="leftIndent">
<xsl:value-of select="$left_indent" />
</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template name="make_background">
<xsl:variable name="background">
<xsl:value-of select="style:properties/@fo:background-color" />
</xsl:variable>
<xsl:if test="not($background='') and boolean(style:properties/@fo:background-color) and starts-with($background,'#')" >
<xsl:attribute name="backColor">
<xsl:value-of select="$background" />
</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template name="make_space_beforeafter">
<xsl:variable name="before">
<xsl:value-of select="style:properties/@fo:margin-top" />
</xsl:variable>
<xsl:variable name="after">
<xsl:value-of select="style:properties/@fo:margin-bottom" />
</xsl:variable>
<xsl:if test="not($before='') and boolean(style:properties/@fo:margin-top)" >
<xsl:attribute name="spaceBefore">
<xsl:value-of select="$before" />
</xsl:attribute>
</xsl:if>
<xsl:if test="not($after='') and boolean(style:properties/@fo:margin-bottom)" >
<xsl:attribute name="spaceAfter">
<xsl:value-of select="$after" />
</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template name="make_fontsize">
<xsl:variable name="fontSize">
<xsl:value-of select="style:properties/@fo:font-size" />
</xsl:variable>
<xsl:if test="not($fontSize='') and boolean(style:properties/@fo:font-size)">
<xsl:attribute name="fontSize">
<xsl:value-of select="$fontSize" />
</xsl:attribute>
<xsl:attribute name="leading">
<xsl:value-of select="$fontSize + floor($fontSize div 5) + 1" />
<!--use a standard leading related to the font size -->
</xsl:attribute>
</xsl:if>
</xsl:template>
<!--this template is not needed anymore for "normalized" sxw files -->
<xsl:template name="make_parent">
<xsl:variable name="parent">
<xsl:value-of select="@style:parent-style-name" />
</xsl:variable>
<xsl:if test="not($parent='') and boolean(@style:parent-style-name)">
<xsl:attribute name="parent">
<xsl:value-of select="$parent" />
</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template name="make_alignment">
<xsl:variable name="alignment">
<xsl:value-of select="style:properties/@fo:text-align" />
</xsl:variable>
<xsl:if test="not($alignment='') and boolean(style:properties/@fo:text-align)">
<xsl:choose>
<xsl:when test="$alignment='start'">
<xsl:attribute name="alignment">LEFT</xsl:attribute>
</xsl:when>
<xsl:when test="$alignment='center'">
<xsl:attribute name="alignment">CENTER</xsl:attribute>
</xsl:when>
<xsl:when test="$alignment='end'">
<xsl:attribute name="alignment">RIGHT</xsl:attribute>
</xsl:when>
<xsl:when test="$alignment='justify'">
<xsl:attribute name="alignment">JUSTIFY</xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name="make_fontnames_paragraph">
<xsl:attribute name="fontName">
<xsl:call-template name="make_fontnames">
<xsl:with-param name="fontName" select="style:properties/@style:font-name" />
<xsl:with-param name="fontWeight" select="style:properties/@fo:font-weight" />
<xsl:with-param name="fontStyle" select="style:properties/@fo:font-style" />
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<xsl:template name="make_fontnames">
<!--much too verbose, needs improvement-->
<xsl:param name="fontName" />
<xsl:param name="fontWeight" />
<xsl:param name="fontStyle" />
<xsl:choose>
<xsl:when test="not($fontName='') and boolean($fontName)">
<xsl:choose>
<xsl:when test="contains($fontName,'Courier')">
<xsl:choose>
<xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
<xsl:text>Courier-BoldOblique</xsl:text>
</xsl:when>
<xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
<xsl:text>Courier-Bold</xsl:text>
</xsl:when>
<xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
<xsl:text>Courier-Oblique</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Courier</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="contains($fontName,'Helvetica') or contains($fontName,'Arial') or contains($fontName,'Sans')">
<xsl:choose>
<xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
<xsl:text>Helvetica-BoldOblique</xsl:text>
</xsl:when>
<xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
<xsl:text>Helvetica-Bold</xsl:text>
</xsl:when>
<xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
<xsl:text>Helvetica-Oblique</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Helvetica</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
<xsl:text>Helvetica-BoldOblique</xsl:text>
</xsl:when>
<xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
<xsl:text>Helvetica-Bold</xsl:text>
</xsl:when>
<xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
<xsl:text>Helvetica-Oblique</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Helvetica</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!--Use this as default -->
<xsl:text>Helvetica</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
This stylesheet is part of:
PyOpenOffice Version 0.4
Copyright (C) 2005: Martin Simon
Homepage: www.bezirksreiter.de
GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999
-->
</xsl:stylesheet>
BIN
View File
Binary file not shown.
+341
View File
@@ -0,0 +1,341 @@
#!/usr/bin/python
#coding: latin-1
##############################################################################
#
# Copyright (c):
#
# 2005 pyopenoffice.py Martin Simon (http://www.bezirksreiter.de)
# 2005 Fabien Pinckaers, TINY SPRL. (http://tiny.be)
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contact a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""
Tiny SXW2RML - The Tiny ERP's report engine
Tiny SXW2RMLis part of the Tiny report project.
Tiny Report is a module that allows you to render high quality PDF document
from an OpenOffice template (.sxw) and any relationnal database.
The whole source code is distributed under the terms of the
GNU Public Licence.
(c) 2005 pyopenoffice.py Martin Simon (http://www.bezirksreiter.de)
(c) 2005-TODAY, Fabien Pinckaers - Tiny sprl
"""
__version__ = '0.9'
import re
import string
import os
import time
import zipfile
import xml.dom.minidom
from reportlab.lib.units import toLength
import optparse
parser = optparse.OptionParser(
version="Tiny Report v%s" % __version__,
usage = 'tiny_sxw2rml.py [options] file.sxw')
parser.add_option("-v", "--verbose", default=False, dest="verbose", help="enable basic debugging")
parser.add_option("-o", "--output", dest="output", default='.', help="directory of image output")
(opt, args) = parser.parse_args()
if len(args) != 1:
parser.error("incorrect number of arguments")
class DomApiGeneral:
"""General DOM API utilities."""
def __init__(self,content_string="",file=""):
self.content_string = content_string
self.re_digits = re.compile(r"(.*?\d)(pt|cm|mm|inch|in)")
def _unitTuple(self,string):
"""Split values and units to a tuple."""
temp = self.re_digits.findall(string)
if not temp:
return (string,"")
else:
return (temp[0])
def stringPercentToFloat(self,string):
temp = string.replace("""%""","")
return float(temp)/100
def findChildrenByName(self,parent,name,attr_dict={}):
"""Helper functions. Does not work recursively.
Optional: also test for certain attribute/value pairs."""
children = []
for c in parent.childNodes:
if c.nodeType == c.ELEMENT_NODE and c.nodeName == name:
children.append(c)
if attr_dict == {}:
return children
else:
return self._selectForAttributes(nodelist=children,attr_dict=attr_dict)
def _selectForAttributes(self,nodelist,attr_dict):
"Helper function."""
selected_nodes = []
for n in nodelist:
check = 1
for a in attr_dict.keys():
if n.getAttribute(a) != attr_dict[a]:
# at least one incorrect attribute value?
check = 0
if check:
selected_nodes.append(n)
return selected_nodes
def _stringToTuple(self,s):
"""Helper function."""
try:
temp = string.split(s,",")
return int(temp[0]),int(temp[1])
except:
return None
def _tupleToString(self,t):
try:
return self.openOfficeStringUtf8("%s,%s" % (t[0],t[1]))
except:
return None
def _lengthToFloat(self,value):
v = value
if not self.re_digits.search(v):
return v
try:
if v[-4:] == "inch":
# OO files use "inch" instead of "in" in Reportlab units
v = v[:-2]
except:
pass
try:
c = round(toLength(v))
return c
except:
return v
def openOfficeStringUtf8(self,string):
if type(string) == unicode:
return string.encode("utf-8")
tempstring = unicode(string,"cp1252").encode("utf-8")
return tempstring
class DomApi(DomApiGeneral):
"""This class provides a DOM-API for XML-Files from an SXW-Archive."""
def __init__(self,xml_content,xml_styles):
DomApiGeneral.__init__(self)
self.content_dom = xml.dom.minidom.parseString(xml_content)
self.styles_dom = xml.dom.minidom.parseString(xml_styles)
body = self.content_dom.getElementsByTagName("office:body")
self.body = body and body[0]
# TODO:
self.style_dict = {}
self.style_properties_dict = {}
# ******** always use the following order:
self.buildStyleDict()
self.buildStylePropertiesDict()
self.page_master = self.styles_dom.getElementsByTagName("style:page-master")[0]
self.document = self.content_dom.getElementsByTagName("office:document-content")[0]
def buildStylePropertiesDict(self):
for s in self.style_dict.keys():
self.style_properties_dict[s] = self.getStylePropertiesDict(s)
def updateWithPercents(self,dict,updatedict):
"""Sometimes you find values like "115%" in the style hierarchy."""
if not updatedict:
# no style hierarchies for this style? =>
return
new_updatedict = copy.copy(updatedict)
for u in new_updatedict.keys():
try:
if new_updatedict[u].find("""%""") != -1 and dict.has_key(u):
number = float(self.re_digits.search(dict[u]).group(1))
unit = self.re_digits.search(dict[u]).group(2)
new_number = self.stringPercentToFloat(new_updatedict[u]) * number
if unit == "pt":
new_number = int(new_number)
# no floats allowed for "pt"
# OOo just takes the int, does not round (try it out!)
new_updatedict[u] = "%s%s" % (new_number,unit)
else:
dict[u] = new_updatedict[u]
except:
dict[u] = new_updatedict[u]
dict.update(new_updatedict)
def normalizeStyleProperties(self):
"""Transfer all style:style-properties attributes from the
self.style_properties_hierarchical dict to the automatic-styles
from content.xml. Use this function to preprocess content.xml for
XSLT transformations etc.Do not try to implement this function
with XSlT - believe me, it's a terrible task..."""
styles_styles = self.styles_dom.getElementsByTagName("style:style")
automatic_styles = self.content_dom.getElementsByTagName("office:automatic-styles")[0]
for s in styles_styles:
automatic_styles.appendChild(s.cloneNode(deep=1))
content_styles = self.content_dom.getElementsByTagName("style:style")
# these are the content_styles with styles_styles added!!!
for s in content_styles:
c = self.findChildrenByName(s,"style:properties")
if c == []:
# some derived automatic styles do not have "style:properties":
temp = self.content_dom.createElement("style:properties")
s.appendChild(temp)
c = self.findChildrenByName(s,"style:properties")
c = c[0]
dict = self.style_properties_dict[(s.getAttribute("style:name")).encode("latin-1")] or {}
for attribute in dict.keys():
c.setAttribute(self.openOfficeStringUtf8(attribute),self.openOfficeStringUtf8(dict[attribute]))
def transferStylesXml(self):
"""Transfer certain sub-trees from styles.xml to the normalized content.xml
(see above). It is not necessary to do this - for example - with paragraph styles.
the "normalized" style properties contain all information needed for
further processing."""
# TODO: What about table styles etc.?
page_master = self.page_master
outline_styles = self.styles_dom.getElementsByTagName("text:outline-style")
t = self.content_dom.createElement("transferredfromstylesxml")
self.document.insertBefore(t,self.body)
t_new = self.body.previousSibling
try:
t_new.appendChild(page_master.cloneNode(deep=1))
t_new.appendChild(outline_styles[0].cloneNode(deep=1))
except:
pass
def normalizeLength(self):
"""Normalize all lengthes to floats (i.e: 1 inch = 72).
Always use this after "normalizeContent" and "transferStyles"!"""
# TODO: The complex attributes of table cell styles are not transferred yet.
#all_styles = self.content_dom.getElementsByTagName("style:properties")
#all_styles += self.content_dom.getElementsByTagName("draw:image")
all_styles = self.content_dom.getElementsByTagName("*")
for s in all_styles:
for x in s._attrs.keys():
v = s.getAttribute(x)
s.setAttribute(x,"%s" % self._lengthToFloat(v))
# convert float to string first!
def normalizeTableColumns(self):
"""Handle this strange table:number-columns-repeated attribute."""
columns = self.content_dom.getElementsByTagName("table:table-column")
for c in columns:
if c.hasAttribute("table:number-columns-repeated"):
number = int(c.getAttribute("table:number-columns-repeated"))
c.removeAttribute("table:number-columns-repeated")
for i in range(number-1):
(c.parentNode).insertBefore(c.cloneNode(deep=1),c)
def buildStyleDict(self):
"""Store all style:style-nodes from content.xml and styles.xml in self.style_dict.
Caution: in this dict the nodes from two dom apis are merged!"""
for st in (self.styles_dom,self.content_dom):
for s in st.getElementsByTagName("style:style"):
name = s.getAttribute("style:name").encode("latin-1")
self.style_dict[name] = s
return True
def toxml(self):
return self.content_dom.toxml(encoding="utf-8")
def getStylePropertiesDict(self,style_name):
res = {}
if self.style_dict[style_name].hasAttribute("style:parent-style-name"):
parent = self.style_dict[style_name].getAttribute("style:parent-style-name").encode("latin-1")
res = self.getStylePropertiesDict(parent)
childs = self.style_dict[style_name].childNodes
for c in childs:
if c.nodeType == c.ELEMENT_NODE and c.nodeName == "style:properties":
for attr in c._attrs.keys():
res[attr] = c.getAttribute(attr).encode("latin-1")
return res
class PyOpenOffice(object):
"""This is the main class which provides all functionality."""
def __init__(self, path='.'):
self.path = path
def oo_read(self,fname):
z = zipfile.ZipFile(fname,"r")
content = z.read('content.xml')
style = z.read('styles.xml')
all = z.namelist()
for a in all:
if a[:9]=='Pictures/' and len(a)>10:
pic_content = z.read(a)
f=open(os.path.join(self.path, os.path.basename(a)),"wb")
f.write(pic_content)
f.close()
z.close()
return content,style
def oo_replace(self,content):
regex = [
(r"<para[^>]*/>", ""),
#(r"<text:ordered-list.*?>(.*?)</text:ordered-list>", "$1"),
#(r"<text:unordered-list.*?>(.*?)</text:unordered-list>", "$1"),
(r"<para(.*)>(.*?)<text:line-break[^>]*/>", "<para$1>$2</para><para$1>"),
]
for key,val in regex:
content = re.sub(key, val, content)
return content
def unpackNormalize(self,sourcefile):
c,s = self.oo_read(sourcefile)
c = self.oo_replace(c)
dom = DomApi(c,s)
dom.normalizeStyleProperties()
dom.transferStylesXml()
dom.normalizeLength()
dom.normalizeTableColumns()
new_c = dom.toxml()
return new_c
if __name__ == "__main__":
import sys
import libxslt
import libxml2
f = sys.argv[1]
tool = PyOpenOffice(opt.output)
res = tool.unpackNormalize(f)
styledoc = libxml2.parseFile('normalized_oo2rml.xsl')
style = libxslt.parseStylesheetDoc(styledoc)
doc = libxml2.parseMemory(res,len(res))
result = style.applyStylesheet(doc, None)
xml = style.saveResultToString(result)
print xml
@@ -0,0 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"account_journal_todo","account.journal.todo","model_account_journal_todo","base.group_system",1,1,1,1
"account_journal_todo_erp","account.journa.todo","model_account_journal_todo","base.group_erp_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 account_journal_todo account.journal.todo model_account_journal_todo base.group_system 1 1 1 1
3 account_journal_todo_erp account.journa.todo model_account_journal_todo base.group_erp_manager 1 1 1 1
+104
View File
@@ -0,0 +1,104 @@
<openerp>
<data>
<!--
Title contact
-->
<record id="res_c_partner_title_madame" model="res.partner.title">
<field name="domain">contact</field>
<field name="name">Madame</field>
<field name="shortcut">Mme.</field>
</record>
<record id="res_c_partner_title_sir" model="res.partner.title">
<field name="domain">contact</field>
<field name="name">Monsieur</field>
<field name="shortcut">M. </field>
</record>
<record id="res_c_partner_title_societe" model="res.partner.title">
<field name="domain">contact</field>
<field name="name">Société</field>
<field name="shortcut">sc</field>
</record>
<record id="res_c_partner_title_mlle" model="res.partner.title">
<field name="domain">contact</field>
<field name="name">Mademoiselle</field>
<field name="shortcut">Mlle</field>
</record>
<record id="res_c_partner_title_mme_m" model="res.partner.title">
<field name="domain">contact</field>
<field name="name">Madame, Monsieur,</field>
<field name="shortcut">Mme,m</field>
</record>
<!--
Title partner
-->
<record id="res_partner_title_madame" model="res.partner.title">
<field name="domain">partner</field>
<field name="name">Madame</field>
<field name="shortcut">Mme.</field>
</record>
<record id="res_partner_title_sir" model="res.partner.title">
<field name="domain">partner</field>
<field name="name">Monsieur</field>
<field name="shortcut">M. </field>
</record>
<record id="res_partner_title_societe" model="res.partner.title">
<field name="domain">partner</field>
<field name="name">Société</field>
<field name="shortcut">sc</field>
</record>
<record id="res_partner_title_mlle" model="res.partner.title">
<field name="domain">partner</field>
<field name="name">Mademoiselle</field>
<field name="shortcut">Mlle</field>
</record>
<record id="res_partner_title_mme_m" model="res.partner.title">
<field name="domain">partner</field>
<field name="name">Madame, Monsieur,</field>
<field name="shortcut">Mme,m</field>
</record>
<!--
Account Journal we define the swiss base journal
-->
<record id="account.sales_journal" model="account.journal">
<field name="name">Journal de vente</field>
<field name="code">JV</field>
<field name="type">sale</field>
<field name="view_id" ref="account.account_journal_view"/>
<field name="sequence_id" ref="account.sequence_journal"/>
<field name="user_id" ref="base.user_root"/>
</record>
<record id="account.refund_sales_journal" model="account.journal">
<field name="name">Journal d'extourne</field>
<field name="code">JVE</field>
<field name="type">sale</field>
<field name="refund_journal">True</field>
<field name="view_id" ref="account.account_journal_view"/>
<field name="sequence_id" ref="account.sequence_journal"/>
<field name="user_id" ref="base.user_root"/>
</record>
<record id="account.expenses_journal" model="account.journal">
<field name="name">Journal de frais</field>
<field name="code">EXJ</field>
<field name="type">purchase</field>
<field name="view_id" ref="account.account_journal_view"/>
<field name="sequence_id" ref="account.sequence_journal"/>
<field name="user_id" ref="base.user_root"/>
</record>
<record id="account.bank_journal" model="account.journal">
<field name="name">Journal de Banque CHF</field>
<field name="code">BNK</field>
<field name="type">cash</field>
<field name="view_id" ref="account.account_journal_bank_view"/>
<field name="sequence_id" ref="account.sequence_journal"/>
<field name="user_id" ref="base.user_root"/>
</record>
<record model="account.journal" id="account.bilan_journal">
<field name="name">Journal d'ouverture</field>
<field name="code">JO</field>
<field name="type">situation</field>
<field name="centralisation">True</field>
<field name="view_id" ref="account.account_journal_view"/>
<field name="sequence_id" ref="account.sequence_journal"/>
</record>
</data>
</openerp>
+36
View File
@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
#
# __init__.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import dta_wizard
import wizard_bvr
import bvr_import
import journal_config
+250
View File
@@ -0,0 +1,250 @@
# -*- encoding: utf-8 -*-
#
# bvr_import.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import wizard
import pooler
import base64
import time
from tools import mod10r
import re
ASK_FORM = """<?xml version="1.0"?>
<form string="BVR Import">
<field name="file"/>
</form>"""
ASK_FIELDS = {
'file': {
'string': 'BVR file',
'type': 'binary',
'required': True,
},
}
def _reconstruct_invoice_ref(cursor, user, reference, context):
###
id_invoice = False
# On fait d'abord une recherche sur toutes les factures
# we now searhc for company
user_obj=pooler.get_pool(cursor.dbname).get('res.users')
user_current=user_obj.browse(cursor, user, user)
##
cursor.execute("SELECT inv.id,inv.number from account_invoice AS inv where inv.company_id = " + str(user_current.company_id.id))
result_invoice = cursor.fetchall()
for inv_id,inv_name in result_invoice:
inv_name = re.sub('[^0-9]', '0', str(inv_name))
if inv_name == reference:
id_invoice = inv_id
break
if id_invoice:
cursor.execute('SELECT l.id ' \
'FROM account_move_line l, account_invoice i ' \
'WHERE l.move_id = i.move_id AND l.reconcile_id is NULL ' \
'AND i.id in (' + ','.join([str(x) for x in [id_invoice]]) + ')')
inv_line = []
for id_line in cursor.fetchall():
inv_line.append(id_line[0])
return inv_line
else:
return []
return True
def _import(obj, cursor, user, data, context):
pool = pooler.get_pool(cursor.dbname)
statement_line_obj = pool.get('account.bank.statement.line')
statement_reconcile_obj = pool.get('account.bank.statement.reconcile')
move_line_obj = pool.get('account.move.line')
property_obj = pool.get('ir.property')
model_fields_obj = pool.get('ir.model.fields')
attachment_obj = pool.get('ir.attachment')
file = data['form']['file']
statement_id = data['id']
records = []
total_amount = 0
total_cost = 0
find_total = False
for lines in base64.decodestring(file).split("\n"):
# Manage files without carriage return
while lines:
(line, lines) = (lines[:128], lines[128:])
record = {}
if line[0:3] in ('999', '995'):
if find_total:
raise wizard.except_wizard('Error',
'Too much total record found!')
find_total = True
if lines:
raise wizard.except_wizard('Error',
'Record found after total record!')
amount = float(line[39:49]) + (float(line[49:51]) / 100)
cost = float(line[69:76]) + (float(line[76:78]) / 100)
if line[2] == '5':
amount *= -1
cost *= -1
if round(amount - total_amount, 2) >= 0.01 \
or round(cost - total_cost, 2) >= 0.01:
raise wizard.except_wizard('Error',
'Total record different from the computed!')
if int(line[51:63]) != len(records):
raise wizard.except_wizard('Error',
'Number record different from the computed!')
else:
record = {
'reference': line[12:39],
'amount': float(line[39:47]) + (float(line[47:49]) / 100),
'date': time.strftime('%Y-%m-%d',
time.strptime(line[65:71], '%y%m%d')),
'cost': float(line[96:98]) + (float(line[98:100]) / 100),
}
if record['reference'] != mod10r(record['reference'][:-1]):
raise wizard.except_wizard('Error',
'Recursive mod10 is invalid for reference: %s' % \
record['reference'])
if line[2] == '5':
record['amount'] *= -1
record['cost'] *= -1
total_amount += record['amount']
total_cost += record['cost']
records.append(record)
model_fields_ids = model_fields_obj.search(cursor, user, [
('name', 'in', ['property_account_receivable', 'property_account_payable']),
('model', '=', 'res.partner'),
], context=context)
property_ids = property_obj.search(cursor, user, [
('fields_id', 'in', model_fields_ids),
('res_id', '=', False),
], context=context)
account_receivable = False
account_payable = False
for property in property_obj.browse(cursor, user, property_ids, context=context):
if property.fields_id.name == 'property_account_receivable':
account_receivable = int(property.value.split(',')[1])
elif property.fields_id.name == 'property_account_payable':
account_payable = int(property.value.split(',')[1])
for record in records:
# Remove the 11 first char because it can be adherent number
# TODO check if 11 is the right number
reference = record['reference'][11:-1].lstrip('0')
values = {
'name': 'IN '+ reference,
'date': record['date'],
'amount': record['amount'],
'ref': reference,
'type': (record['amount'] >= 0 and 'customer') or 'supplier',
'statement_id': statement_id,
}
line_ids = move_line_obj.search(cursor, user, [
('ref', 'like', reference),
('reconcile_id', '=', False),
('account_id.type', 'in', ['receivable', 'payable']),
], order='date desc', context=context)
if not line_ids:
line_ids = _reconstruct_invoice_ref(cursor,user,reference,None)
line2reconcile = False
partner_id = False
account_id = False
for line in move_line_obj.browse(cursor, user, line_ids, context=context):
if line.partner_id.id:
partner_id = line.partner_id.id
if record['amount'] >= 0:
if round(record['amount'] - line.debit, 2) < 0.01:
line2reconcile = line.id
account_id = line.account_id.id
break
else:
if round(line.credit + record['amount'], 2) < 0.01:
line2reconcile = line.id
account_id = line.account_id.id
break
if not account_id:
if record['amount'] >= 0:
account_id = account_receivable
else:
account_id = account_payable
if not account_id :
raise wizard.except_wizard('Error',
'The properties account payable account receivable')
values['account_id'] = account_id
values['partner_id'] = partner_id
if line2reconcile:
values['reconcile_id'] = statement_reconcile_obj.create(cursor, user, {
'line_ids': [(6, 0, [line2reconcile])],
}, context=context)
statement_line_obj.create(cursor, user, values, context=context)
attachment_obj.create(cursor, user, {
'name': 'BVR',
'datas': file,
'datas_fname': 'BVR.txt',
'res_model': 'account.bank.statement',
'res_id': statement_id,
}, context=context)
return {}
class BVRImport(wizard.interface):
states = {
'init': {
'actions': [],
'result': {
'type': 'form',
'arch': ASK_FORM,
'fields': ASK_FIELDS,
'state': [
('end', 'Cancel', 'gtk-cancel'),
('import', 'Import', 'gtk-ok', True),
],
},
},
'import': {
'actions': [],
'result': {
'type': 'action',
'action': _import,
'state': 'end',
},
},
}
BVRImport('l10n_ch.bvr_import')
+611
View File
@@ -0,0 +1,611 @@
# -*- encoding: utf-8 -*-
#
# dta_wizard.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import pooler
import wizard
import base64
import time
import pooler
import mx.DateTime
FORM = """<?xml version="1.0"?>
<form string="DTA file creation - Results">
<separator colspan="4" string="Clic on 'Save as' to save the DTA file :" />
<field name="dta"/>
</form>"""
FIELDS = {
'dta': {
'string': 'DTA File',
'type': 'binary',
'readonly': True,
},
}
TRANS=[
(u'é','e'),
(u'è','e'),
(u'à','a'),
(u'ê','e'),
(u'î','i'),
(u'ï','i'),
(u'â','a'),
(u'ä','a'),
]
def tr(s):
s= s.decode('utf-8')
for k in TRANS:
s = s.replace(k[0],k[1])
try:
res= s.encode('ascii','replace')
except:
res = s
return res
class record:
def __init__(self, global_context_dict):
for i in global_context_dict:
global_context_dict[i] = global_context_dict[i] \
and tr(global_context_dict[i])
self.fields = []
self.global_values = global_context_dict
self.pre = {
'padding': '',
'seg_num1': '01',
'seg_num2': '02',
'seg_num3': '03',
'seg_num4': '04',
'seg_num5': '05',
'flag': '0',
'zero5': '00000'
}
self.post={'date_value_hdr': '000000', 'type_paiement': '0'}
self.init_local_context()
def init_local_context(self):
"""
Must instanciate a fields list, field = (name,size)
and update a local_values dict.
"""
raise "not implemented"
def generate(self):
res=''
for field in self.fields :
if self.pre.has_key(field[0]):
value = self.pre[field[0]]
elif self.global_values.has_key(field[0]):
value = self.global_values[field[0]]
elif self.post.has_key(field[0]):
value = self.post[field[0]]
else :
pass
#raise Exception(field[0]+' not found !')
try:
res = res + c_ljust(value, field[1])
except :
pass
return res
class record_gt826(record):
"""
bvr
"""
def init_local_context(self):
self.fields=[
('seg_num1', 2),
#header
('date_value_hdr', 6),
('partner_bank_clearing', 12),
('zero5', 5),
('creation_date', 6),
('comp_bank_clearing', 7),
('uid', 5),
('sequence', 5),
('genre_trans', 3),
('type_paiement', 1),
('flag', 1),
#seg1
('comp_dta', 5),
('number', 11),
('comp_bank_iban', 24),
('date_value', 6),
('currency', 3),
('amount_to_pay', 12),
('padding', 14),
#seg2
('seg_num2', 2),
('comp_name', 20),
('comp_street', 20),
('comp_zip', 10),
('comp_city', 10),
('comp_country', 20),
('padding', 46),
#seg3
('seg_num3', 2),
('partner_bvr', 12),#numero d'adherent bvr
('partner_name', 20),
('partner_street', 20),
('partner_zip', 10),
('partner_city', 10),
('partner_country', 20),
('reference', 27),#communication structuree
('padding', 2),#cle de controle
('padding', 5)
]
self.pre.update({
'date_value_hdr': self.global_values['date_value'],
'date_value': '',
'partner_bank_clearing': '',
'partner_cpt_benef': '',
'genre_trans': '826',
'conv_cours': '',
'option_id_bank': 'D',
'partner_bvr': '/C/'+ self.global_values['partner_bvr'],
'ref2': '',
'ref3': '',
'format': '0',
})
class record_gt827(record):
"""
interne suisse (bvpost et bvbank)
"""
def init_local_context(self):
self.fields = [
('seg_num1', 2),
#header
('date_value_hdr', 6),
('partner_bank_clearing', 12),
('zero5', 5),
('creation_date', 6),
('comp_bank_clearing', 7),
('uid', 5),
('sequence', 5),
('genre_trans', 3),
('type_paiement', 1),
('flag', 1),
#seg1
('comp_dta', 5),
('number', 11),
('comp_bank_iban', 24),
('date_value', 6),
('currency', 3),
('amount_to_pay', 12),
('padding', 14),
#seg2
('seg_num2', 2),
('comp_name', 20),
('comp_street', 20),
('comp_zip', 10),
('comp_city', 10),
('comp_country', 20),
('padding', 46),
#seg3
('seg_num3', 2),
('partner_bank_number', 30),
('partner_name', 24),
('partner_street', 24),
('partner_zip', 12),
('partner_city', 12),
('partner_country', 24),
#seg4
('seg_num4', 2),
('reference', 112),
('padding', 14),
#seg5
#('padding',128)
]
self.pre.update({
'date_value_hdr': self.global_values['date_value'],
'date_value': '',
'partner_cpt_benef': '',
'type_paiement': '0',
'genre_trans': '827',
'conv_cours': '',
'option_id_bank': 'D',
'ref2': '',
'ref3': '',
'format': '0'
})
class record_gt836(record):
"""
iban
"""
def init_local_context(self):
self.fields = [
('seg_num1', 2),
#header
('date_value_hdr', 6),
('partner_bank_clearing', 12),
('zero5', 5),
('creation_date', 6),
('comp_bank_clearing', 7),
('uid', 5),
('sequence', 5),
('genre_trans', 3),
('type_paiement', 1),
('flag', 1),
#seg1
('comp_dta', 5),
('number', 11),
('comp_bank_iban', 24),
('date_value', 6),
('currency', 3),
('amount_to_pay', 15),
('padding', 11),
#seg2
('seg_num2', 2),
('conv_cours', 12),
('comp_name', 35),
('comp_street', 35),
('comp_country', 3),
('comp_zip', 10),
('comp_city', 22),
('padding', 9),
#seg3
('seg_num3', 2),
('option_id_bank', 1),
('partner_bank_ident', 70),
('partner_bank_iban', 34),
('padding', 21),
#seg4
('seg_num4', 2),
('partner_name', 35),
('partner_street', 35),
('partner_country', 3),
('partner_zip', 10),
('partner_city', 22),
('padding', 21),
#seg5
('seg_num5', 2),
('option_motif', 1),
('reference', 105),
('format', 1),
('padding', 19)
]
self.pre.update( {
'partner_bank_clearing': '',
'partner_cpt_benef': '',
'type_paiement': '0',
'genre_trans': '836',
'conv_cours': '',
'reference': self.global_values['reference'],
'ref2': '',
'ref3': '',
'format': '2'
})
self.post.update({'option_motif': 'U'})
class record_gt890(record):
"""
Total
"""
def init_local_context(self):
self.fields = [
('seg_num1', 2),
#header
('date_value_hdr', 6),
('partner_bank_clearing', 12),
('zero5', 5),
('creation_date', 6),
('comp_bank_clearing', 7),
('uid', 5),
('sequence', 5),
('genre_trans', 3),
('type_paiement', 1),
('flag', 1),
#total
('amount_total', 16),
('padding', 59)
]
self.pre.update({'partner_bank_clearing': '', 'partner_cpt_benef': '',
'company_bank_clearing': '', 'genre_trans': '890'})
def c_ljust(s, size):
"""
check before calling ljust
"""
s= s or ''
if len(s) > size:
s= s[:size]
s = s.decode('utf-8').encode('latin1','replace').ljust(size)
return s
def _create_dta(obj, cr, uid, data, context):
v={}
v['uid'] = str(uid)
v['creation_date']= time.strftime('%y%m%d')
dta=''
pool = pooler.get_pool(cr.dbname)
payment_obj = pool.get('payment.order')
attachment_obj = pool.get('ir.attachment')
payment = payment_obj.browse(cr, uid, data['id'], context=context)
if not payment.mode or payment.mode.type.code != 'dta':
raise wizard.except_wizard('Error',
'No payment mode or payment type code invalid.')
bank = payment.mode.bank_id
if not bank:
raise wizard.except_wizard('Error', 'No bank account for the company.')
v['comp_bank_name']= bank.bank and bank.bank.name or False
v['comp_bank_clearing'] = bank.bank.clearing
if not v['comp_bank_clearing']:
raise wizard.except_wizard('Error',
'You must provide a Clearing Number for your bank account.')
user = pool.get('res.users').browse(cr,uid,[uid])[0]
company= user.company_id
#XXX dirty code use get_addr
co_addr= company.partner_id.address[0]
v['comp_country'] = co_addr.country_id and co_addr.country_id.name or ''
v['comp_street'] = co_addr.street or ''
v['comp_zip'] = co_addr.zip
v['comp_city'] = co_addr.city
v['comp_name'] = co_addr.name
v['comp_dta'] = bank.dta_code or '' #XXX not mandatory in pratice
v['comp_bank_number'] = bank.acc_number or ''
if bank.iban:
v['comp_bank_iban'] = bank.iban.replace(' ','') or ''
else:
v['comp_bank_iban'] = ''
if not v['comp_bank_iban']:
raise wizard.except_wizard('Error',
'No IBAN for the company bank account.')
dta_line_obj = pool.get('account.dta.line')
res_partner_bank_obj = pool.get('res.partner.bank')
seq= 1
amount_tot = 0
amount_currency_tot = 0
for pline in payment.line_ids:
if not pline.bank_id:
raise wizard.except_wizard('Error', 'No bank account defined\n' \
'on line: ' + pline.name)
if not pline.bank_id.bank:
raise wizard.except_wizard('Error', 'No bank defined\n' \
'for the bank account: ' + pline.bank_id.state + '\n' \
'on the partner: ' + pline.partner_id.name + '\n' \
'on line: ' + pline.name)
v['sequence'] = str(seq).rjust(5).replace(' ', '0')
v['amount_to_pay']= str(pline.amount_currency).replace('.', ',')
v['number'] = pline.name
v['currency'] = pline.currency.code
v['partner_bank_name'] = pline.bank_id.bank.name or False
v['partner_bank_clearing'] = pline.bank_id.bank.clearing or False
if not v['partner_bank_name'] :
raise wizard.except_wizard('Error', 'No bank name defined\n' \
'for the bank account: ' + pline.bank_id.state + '\n' \
'on the partner: ' + pline.partner_id.name + '\n' \
'on line: ' + pline.name)
v['partner_bank_iban']= pline.bank_id.iban or False
v['partner_bank_number']= pline.bank_id.acc_number \
and pline.bank_id.acc_number.replace('.','').replace('-','') \
or False
v['partner_post_number']= pline.bank_id.post_number \
and pline.bank_id.post_number.replace('.', '').replace('-', '') \
or False
v['partner_bvr'] = pline.bank_id.bvr_number or ''
if v['partner_bvr']:
v['partner_bvr'] = v['partner_bvr'].replace('-','')
if len(v['partner_bvr']) < 9:
v['partner_bvr'] = v['partner_bvr'][:2] + '0' * \
(9 - len(v['partner_bvr'])) + v['partner_bvr'][2:]
if pline.bank_id.bank:
v['partner_bank_city'] = pline.bank_id.bank.city or False
v['partner_bank_street'] = pline.bank_id.bank.street or ''
v['partner_bank_zip'] = pline.bank_id.bank.zip or ''
v['partner_bank_country'] = pline.bank_id.bank.country and \
pline.bank_id.bank.country.name or ''
v['partner_bank_code'] = pline.bank_id.bank.bic
v['reference'] = pline.move_line_id.ref
v['partner_name'] = pline.partner_id and pline.partner_id.name or ''
if pline.partner_id and pline.partner_id.address \
and pline.partner_id.address[0]:
v['partner_street'] = pline.partner_id.address[0].street
v['partner_city']= pline.partner_id.address[0].city
v['partner_zip']= pline.partner_id.address[0].zip
# If iban => country=country code for space reason
elec_pay = pline.bank_id.state #Bank type
if elec_pay == 'iban':
v['partner_country']= pline.partner_id.address[0].country_id \
and pline.partner_id.address[0].country_id.code+'-' \
or ''
else:
v['partner_country']= pline.partner_id.address[0].country_id \
and pline.partner_id.address[0].country_id.name \
or ''
else:
v['partner_street'] =''
v['partner_city']= ''
v['partner_zip']= ''
v['partner_country']= ''
raise wizard.except_wizard('Error', 'No address defined \n' \
'for the partner: ' + pline.partner_id.name + '\n' \
'on line: ' + pline.name)
if pline.order_id.date_planned :
date_value = mx.DateTime.strptime(pline.order_id.date_planned, '%Y-%m-%d')
elif pline.date :
date_value = mx.DateTime.strptime(pline.date, '%Y-%m-%d')
else :
date_value = mx.DateTime.now()
v['date_value'] = date_value.strftime("%y%m%d")
# si compte iban -> iban (836)
# si payment structure -> bvr (826)
# si non -> (827)
if elec_pay == 'dta_iban':
# If iban => country=country code for space reason
v['comp_country'] = co_addr.country_id and co_addr.country_id.code+'-' or ''
record_type = record_gt836
if not v['partner_bank_iban']:
raise wizard.except_wizard('Error', 'No IBAN defined \n' \
'for the bank account: ' + \
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
context)[0][1] + '\n' \
'on line: ' + pline.name)
if v['partner_bank_code'] : # bank code is swift (BIC address)
v['option_id_bank']= 'A'
v['partner_bank_ident']= v['partner_bank_code']
elif v['partner_bank_city']:
v['option_id_bank']= 'D'
v['partner_bank_ident']= v['partner_bank_name'] \
+ ' ' + v['partner_bank_street'] \
+ ' ' + v['partner_bank_zip'] \
+ ' ' + v['partner_bank_city'] \
+ ' ' + v['partner_bank_country']
else:
raise wizard.except_wizard('Error', 'You must provide the bank city '
'or the bic code for the partner bank: \n' + \
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
context)[0][1] + '\n' \
'on line: ' + pline.name)
elif elec_pay == 'bvrbank' or elec_pay == 'bvrpost':
from tools import mod10r
if v['reference']:
v['reference'] = v['reference'].replace(' ',
'').rjust(27).replace(' ', '0')
if not v['reference'] \
or mod10r(v['reference'][:-1]) != v['reference']:
raise wizard.except_wizard('Error', 'You must provide ' \
'a valid BVR reference number \n' +
'for the line: ' + pline.name)
if not v['partner_bvr']:
raise wizard.except_wizard('Error', 'You must provide a BVR number\n'
'for the bank account: ' + \
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
context)[0][1] + '\n' \
'on line: ' + pline.name)
record_type = record_gt826
elif elec_pay == 'bvbank':
if not v['partner_bank_number'] :
if v['partner_bank_iban'] :
v['partner_bank_number']= v['partner_bank_iban']
else:
raise wizard.except_wizard('Error', 'You must provide ' \
'a bank number \n' \
'for the partner bank: ' + \
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
context)[0][1] + '\n' \
'on line: ' + pline.name)
if not v['partner_bank_clearing']:
raise wizard.except_wizard('Error', 'You must provide ' \
'a Clearing Number\n' \
'for the partner bank: ' + \
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
context)[0][1] + '\n' \
'on line '+ pline.name)
v['partner_bank_number'] = '/C/'+v['partner_bank_number']
record_type = record_gt827
elif elec_pay == 'bvpost':
if not v['partner_post_number']:
raise wizard.except_wizard('Error', 'You must provide ' \
'a post number \n' \
'for the partner bank: ' + \
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
context)[0][1] + '\n' \
'on line: ' + pline.name)
v['partner_bank_clearing']= ''
v['partner_bank_number'] = '/C/'+v['partner_post_number']
record_type = record_gt827
else:
raise wizard.except_wizard('Error', 'The Bank type ' + elec_pay + \
'of the bank account: ' + \
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
context)[0][1] + ' '\
'is not supported')
dta_line = record_type(v).generate()
dta = dta + dta_line
amount_tot += pline.amount
amount_currency_tot += pline.amount_currency
seq += 1
# segment total
v['amount_total'] = str(amount_currency_tot).replace('.',',')
v['sequence'] = str(seq).rjust(5).replace(' ','0')
if dta :
dta = dta + record_gt890(v).generate()
dta_data= base64.encodestring(dta)
payment_obj.set_done(cr, uid, data['id'], context)
attachment_obj.create(cr, uid, {
'name': 'DTA',
'datas': dta_data,
'datas_fname': 'DTA.txt',
'res_model': 'payment.order',
'res_id': data['id'],
}, context=context)
return {'dta': dta_data}
class wizard_dta_create(wizard.interface):
states = {
'init' : {
'actions' : [_create_dta],
'result' : {'type' : 'form',
'arch' : FORM,
'fields' : FIELDS,
'state' : [('end', 'OK', 'gtk-ok', True)]
}
},
}
wizard_dta_create('account.dta_create')
+165
View File
@@ -0,0 +1,165 @@
# -*- encoding: utf-8 -*-
#
# journal_config.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from osv import fields, osv
class Journal(osv.osv):
"""Create account.journal.todo in order to add configuration wizzard"""
_name ="account.journal.todo"
def _get_journal(self, cr, uid, ctx):
if not self.__dict__.has_key('_inner_steps') :
self._inner_steps = 0
ids = self.pool.get('account.journal').search(cr,uid,[])
if self._inner_steps == 'done' :
return False
return ids[self._inner_steps]
def _get_debit(self, cr, uid, ctx):
if not self.__dict__.has_key('_inner_steps') :
self._inner_steps = 0
if self._inner_steps == 'done' :
return False
ids = self.pool.get('account.journal').search(cr,uid,[])
id = self.pool.get('account.journal').browse(
cr,
uid,
ids[self._inner_steps]
).default_debit_account_id.id
return id
def _get_credit(self, cr, uid, ctx):
if not self.__dict__.has_key('_inner_steps') :
self._inner_steps = 0
if self._inner_steps == 'done' :
return False
ids = self.pool.get('account.journal').search(cr,uid,[])
id = self.pool.get('account.journal').browse(
cr,
uid,
ids[self._inner_steps]
).default_credit_account_id.id
return id
_columns={
'name': fields.many2one(
'account.journal',
'Journal to set',
readonly=True,
help="the currenty edited account journal"
),
'default_credit_account_id': fields.many2one(
'account.account', 'Default Credit Account',
domain="[('type','!=','view')]",
help="The Default Credit Account of the account journal"
),
'default_debit_account_id': fields.many2one(
'account.account',
'Default Debit Account',
domain="[('type','!=','view')]",
help="The Default Debit Account of the account journal"
),
}
_defaults = {
'name': _get_journal,
'default_debit_account_id':_get_debit,
'default_credit_account_id':_get_credit,
}
def on_change_debit(self, cr, uid, id, journal, account) :
if account :
self.pool.get('account.journal').write(
cr,
uid,
journal,
vals={
'default_debit_account_id': account,
}
)
return {}
def on_change_credit(self, cr, uid, id, journal, account) :
if account :
self.pool.get('account.journal').write(
cr,
uid,
journal,
vals={
'default_credit_account_id': account,
}
)
return {}
def action_cancel(self,cr,uid,ids,context=None):
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'ir.actions.configuration.wizard',
'type': 'ir.actions.act_window',
'target':'new',
}
def action_new(self,cr,uid,ids,context={}):
jids = self.pool.get('account.journal').search(cr, uid, [])
if self._inner_steps < len(jids)-1 :
self._inner_steps += 1
else :
print 'DONE'
self._inner_steps = 'done'
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'account.journal.todo',
'view_id':self.pool.get('ir.ui.view').search(
cr,
uid,
[('name','=','view_account_journal_form_todo')]
),
'type': 'ir.actions.act_window',
'target':'new',
}
Journal()
+82
View File
@@ -0,0 +1,82 @@
# -*- encoding: utf-8 -*-
#
# wizzard_bvr.py
# l10n_ch
#
# Created by Nicolas Bessi based on Credric Krier contribution
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import wizard
import pooler
import re
def _check(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
invoice_obj = pool.get('account.invoice')
for invoice in invoice_obj.browse(cr, uid, data['ids'], context):
if not invoice.partner_bank:
raise wizard.except_wizard('UserError',
'No bank specified on invoice:\n' + \
invoice_obj.name_get(cr, uid, [invoice.id],
context=context)[0][1])
if not re.compile('[0-9][0-9]-[0-9]{3,6}-[0-9]').match(
invoice.partner_bank.bvr_number or ''):
raise wizard.except_wizard('UserError',
'Your bank BVR number should be of the form 0X-XXX-X!\n' \
'Please check your company ' \
'information for the invoice:\n' + \
invoice_obj.name_get(cr, uid, [invoice.id],
context=context)[0][1])
if invoice.partner_bank.bvr_adherent_num \
and not re.compile('[0-9]*$').match(
invoice.partner_bank.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(cr, uid, [invoice.id],
context=context)[0][1])
return {}
class wizard_report(wizard.interface):
states = {
'init': {
'actions': [_check],
'result': {'type':'print', 'report':'l10n_ch.bvr', 'state':'end'}
}
}
wizard_report('l10n_ch.bvr.check')
class ReportInvoiceBVRCheck(wizard.interface):
states = {
'init': {
'actions': [_check],
'result': {'type':'print', 'report':'l10n_ch.invoice.bvr', 'state':'end'}
}
}
ReportInvoiceBVRCheck('l10n_ch.invoice.bvr.check')
+58513
View File
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
#
# __init__.py
#
# Created by Nicolas Bessi on 12.02.09.
# Copyright (c) 2009 CamptoCamp. All rights reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import wizard
+52
View File
@@ -0,0 +1,52 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2008 CamptoCamp SA
#
# __init__.py
#
# Created by Vincent Renaville on 12.02.09.
# Copyright (c) 2009 CamptoCamp. All rights reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
{
"name" : "Suisse - Plan comptable general pour PME STERCHI",
"version" : "1.0",
"depends" : [
"account",
"account_chart",
"l10n_ch"
],
"author" : "Camptocamp",
"description": "Swiws account chart that add also tax template definition",
"website" : "camptocamp.com",
"category" : "Localisation/Account Charts",
"init_xml" : [
'account.xml',
'vat.xml'
],
"demo_xml" : [ ],
"update_xml" : [
'wizard.xml',
'tax_template_view.xml',
'security/ir.model.access.csv',
],
"active": False,
"installable": True
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"account_tax_todo","account.tax.template.todo","model_account_tax_template_todo","base.group_system",1,1,1,1
"account_tax_todo_erp","account.tax.template.todo","model_account_tax_template_todo","base.group_erp_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 account_tax_todo account.tax.template.todo model_account_tax_template_todo base.group_system 1 1 1 1
3 account_tax_todo_erp account.tax.template.todo model_account_tax_template_todo base.group_erp_manager 1 1 1 1
+50
View File
@@ -0,0 +1,50 @@
<!-- #!/usr/bin/env python2.3
#
# tax_template_view.xml
#
# Created by Nicolas Bessi on 12.02.09.
# Copyright (c) 2009 CamptoCamp. All rights reserved.
# -->
<openerp>
<data>
<record id="view_tax_template_form_todo" model="ir.ui.view">
<field name="name">account.tax.template.todo</field>
<field name="model">account.tax.template.todo</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Account tax template">
<group colspan="4" col="6">
<field name="name" select="1"/>
</group>
<separator colspan="4" string="The accounts linked to the tax template"/>
<field name="account_collected_id"
on_change="on_change_collected(name, account_collected_id)" select="1"/>
<field name="account_paid_id"
on_change="on_change_paid(name, account_paid_id)" select="1"/>
<group col="4" colspan="4">
<button icon="gtk-cancel" name="action_cancel" string="Cancel" type="object"/>
<button icon="gtk-ok" name="action_new" string="Next" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_config_tax" model="ir.actions.act_window">
<field name="name">Configure Journal</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.tax.template.todo</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_tax_template_form_todo"/>
<field name="target">new</field>
</record>
<record id="action_config_tax_todo" model="ir.actions.todo">
<field name="name">Finalize your tax configuration</field>
<field name="note">Set account on financial taxes defined by
Camptocamp l10n_ch_c2c_pcg module</field>
<field name="action_id" ref="action_config_tax"/>
<field name="sequence">5</field>
</record>
</data>
</openerp>
+533
View File
@@ -0,0 +1,533 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<!--
# Tax Code Configuration
-->
<record model="account.tax.code.template" id="vat_code_balance_net">
<field name="name">Solde de TVA a payer a l'AFC</field>
<field name="code">150 Solde de TVA a payer a l'AFC</field>
</record>
<record model="account.tax.code.template" id="vat_code_due_tva">
<field name="name">TVA Due (TVA a payer)</field>
<field name="code">100 TVA Due (TVA a payer)</field>
<field name="parent_id" ref="vat_code_balance_net"/>
</record>
<record model="account.tax.code.template" id="vat_code_due_tva76">
<field name="name">TVA due sur base a 7.6%</field>
<field name="code">070b TVA due sur base a 7.6%</field>
<field name="parent_id" ref="vat_code_due_tva"/>
</record>
<record model="account.tax.code.template" id="vat_code_due_tva24">
<field name="name">TVA due sur base a 2.4%</field>
<field name="code">071b TVA due sur base a 2.4%</field>
<field name="parent_id" ref="vat_code_due_tva"/>
</record>
<record model="account.tax.code.template" id="vat_code_due_tva36">
<field name="name">TVA due sur base a 3.6%</field>
<field name="code">074b TVA due sur base a 3.6%</field>
<field name="parent_id" ref="vat_code_due_tva"/>
</record>
<record model="account.tax.code.template" id="vat_code_due_tva0">
<field name="name">TVA due sur base a 0%</field>
<field name="code">074b TVA due sur base a 0%</field>
<field name="parent_id" ref="vat_code_due_tva"/>
</record>
<record model="account.tax.code.template" id="vat_code_payable">
<field name="name">Impot préalable sur acquisitions (TVA a récupérer)</field>
<field name="code">Impot préalable sur acquisitions (TVA a récupérer)</field>
<field name="parent_id" ref="vat_code_balance_net"/>
</record>
<record model="account.tax.code.template" id="vat_code_payable_bs">
<field name="name">Impot préalable sur biens et services</field>
<field name="code">100 Impot préalable sur biens et services</field>
<field name="parent_id" ref="vat_code_payable"/>
</record>
<record model="account.tax.code.template" id="vat_code_payable_invest">
<field name="name">Impot préalable sur invest. et autres ch.</field>
<field name="code">111 Impot préalable sur invest. et autres ch.</field>
<field name="parent_id" ref="vat_code_payable"/>
</record>
<record model="account.tax.code.template" id="vat_code_base_net">
<field name="name">Base de calcul de TVA</field>
<field name="code"/>
</record>
<record model="account.tax.code.template" id="vat_code_base_due">
<field name="name">Chiffre d'affaires imposable</field>
<field name="code">080 Chiffre d'affaires imposable</field>
<field name="parent_id" ref="vat_code_base_net"/>
</record>
<record model="account.tax.code.template" id="vat_code_due_76">
<field name="name">Chiffre d'affaires imposable a 7.6% (taux normal)</field>
<field name="code">070 Chiffre d'affaires imposable a 7.6% (taux normal)</field>
<field name="parent_id" ref="vat_code_base_due"/>
</record>
<record model="account.tax.code.template" id="vat_code_due_24">
<field name="name">Chiffre d'affaires imposable a 2.4% (taux réduit)</field>
<field name="code">071 Chiffre d'affaires imposable a 2.4% (taux réduit)</field>
<field name="parent_id" ref="vat_code_base_due"/>
</record>
<record model="account.tax.code.template" id="vat_code_due_36">
<field name="name">Chiffre d'affaires imposable a 3.6% (taux spécial)</field>
<field name="code">074 Chiffre d'affaires imposable a 3.6% (taux spécial)</field>
<field name="parent_id" ref="vat_code_base_due"/>
</record>
<record model="account.tax.code.template" id="vat_code_due_0">
<field name="name">Chiffre d'affaires imposable a 0% (exportation)</field>
<field name="code">040 Chiffre d'affaires imposable a 0% (exportation)</field>
<field name="parent_id" ref="vat_code_base_due"/>
</record>
<record model="account.tax.code.template" id="vat_code_due_0_exclu">
<field name="name">Chiffre d'affaires imposable a 0% (exclu)</field>
<field name="code">043 Chiffre d'affaires imposable a 0% (exclu)</field>
<field name="parent_id" ref="vat_code_base_due"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_net">
<field name="name">Acquisition</field>
<field name="code">Acquisition</field>
<field name="parent_id" ref="vat_code_base_net"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base">
<field name="name">Acquisition de biens et services</field>
<field name="code">Acquisition de biens et services</field>
<field name="parent_id" ref="vat_code_receivable_net"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_0">
<field name="name">Acquisition de biens et services a 0%</field>
<field name="code">Acquisition de biens et services a 0%</field>
<field name="parent_id" ref="vat_code_receivable_base"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_76">
<field name="name">Acquisition de biens et services a 7.6%</field>
<field name="code">Acquisition de biens et services a 7.6%</field>
<field name="parent_id" ref="vat_code_receivable_base"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_24">
<field name="name">Acquisition de biens et services a 2.4%</field>
<field name="code">Acquisition de biens et services a 2.4%</field>
<field name="parent_id" ref="vat_code_receivable_base"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_36">
<field name="name">Acquisition de biens et services a 3.6%</field>
<field name="code">Acquisition de biens et services a 3.6%</field>
<field name="parent_id" ref="vat_code_receivable_base"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_24_50%">
<field name="name">Acquisition de biens et services a 2.4% récup. à 50%</field>
<field name="code">Acquisition de biens et services a 2.4% récup. à 50%</field>
<field name="parent_id" ref="vat_code_receivable_base"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_76_50%">
<field name="name">Acquisition de biens et services a 7.6% récup. à 50%</field>
<field name="code">Acquisition de biens et services a 7.6% récup. à 50%</field>
<field name="parent_id" ref="vat_code_receivable_base"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_36_50%">
<field name="name">Acquisition de biens et services a 3.6% récup. à 50%</field>
<field name="code">Acquisition de biens et services a 3.6% récup. à 50%</field>
<field name="parent_id" ref="vat_code_receivable_base"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_invest">
<field name="name">Acquisition de biens d'invest. et autres charges</field>
<field name="code">Acquisition de biens d'invest. et autres charges</field>
<field name="parent_id" ref="vat_code_receivable_net"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_invest76">
<field name="name">Acquisition de biens d'invest. et autres charges a 7.6%</field>
<field name="code">Acquisition de biens d'invest. et autres charges a 7.6%</field>
<field name="parent_id" ref="vat_code_receivable_base_invest"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_invest24">
<field name="name">Acquisition de biens d'invest. et autres charges a 2.4%</field>
<field name="code">Acquisition de biens d'invest. et autres charges a 2.4%</field>
<field name="parent_id" ref="vat_code_receivable_base_invest"/>
</record>
<record model="account.tax.code.template" id="vat_code_receivable_base_invest36">
<field name="name">Acquisition de biens d'invest. et autres charges a 3.6%</field>
<field name="code">Acquisition de biens d'invest. et autres charges a 3.6%</field>
<field name="parent_id" ref="vat_code_receivable_base_invest"/>
</record>
<!--
# TVA - Taxe sur la Valeur Ajoutée
-->
<record model="account.tax.template" id="vat_24">
<field name="name">2.4%</field>
<field name="amount" eval="0.024"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_due_24"/>
<field name="tax_code_id" ref="vat_code_due_tva24"/>
<field name="ref_base_code_id" ref="vat_code_due_24"/>
<field name="ref_tax_code_id" ref="vat_code_due_tva24"/>
<field name="base_sign" eval="1.0"/>
<field name="tax_sign" eval="1.0"/>
<field name="ref_base_sign" eval="-1.0"/>
<field name="ref_tax_sign" eval="-1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">sale</field>
</record>
<record model="account.tax.template" id="vat_24_purchase">
<field name="name">TVA 2.4% sur achat B&amp;S</field>
<field name="amount" eval="0.024"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_24"/>
<field name="tax_code_id" ref="vat_code_payable_bs"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_24"/>
<field name="ref_tax_code_id" ref="vat_code_payable_bs"/>
<field name="python_compute">result = round((price_unit * 0.024) / 0.05) * 0.05</field>
<field name="python_compute_inv">result = round((price_unit * ( 1 - (1 / 1.024))) /
0.05) * 0.05</field>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<record model="account.tax.template" id="vat_24_invest">
<field name="name">TVA 2.4% sur invest. et autres ch.</field>
<field name="amount" eval="0.024"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_invest24"/>
<field name="tax_code_id" ref="vat_code_payable_invest"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_invest24"/>
<field name="ref_tax_code_id" ref="vat_code_payable_invest"/>
<field name="python_compute">result = round((price_unit * 0.024) / 0.05) * 0.05</field>
<field name="python_compute_inv">result = round((price_unit * ( 1 - (1 / 1.024))) /
0.05) * 0.05</field>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<record model="account.tax.template" id="vat_36">
<field name="name">3.6%</field>
<field name="amount" eval="0.036"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_due_36"/>
<field name="tax_code_id" ref="vat_code_due_tva36"/>
<field name="ref_base_code_id" ref="vat_code_due_36"/>
<field name="ref_tax_code_id" ref="vat_code_due_tva36"/>
<field name="python_compute">result = round((price_unit * 0.036) / 0.05) * 0.05</field>
<field name="python_compute_inv">result = round((price_unit * ( 1 - (1 / 1.036))) /
0.05) * 0.05</field>
<field name="base_sign" eval="1.0"/>
<field name="tax_sign" eval="1.0"/>
<field name="ref_base_sign" eval="-1.0"/>
<field name="ref_tax_sign" eval="-1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">sale</field>
</record>
<record model="account.tax.template" id="vat_36_purchase">
<field name="name">TVA 3.6% sur achat B&amp;S</field>
<field name="amount" eval="0.036"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_36"/>
<field name="tax_code_id" ref="vat_code_payable_bs"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_36"/>
<field name="ref_tax_code_id" ref="vat_code_payable_bs"/>
<field name="python_compute">result = round((price_unit * 0.036) / 0.05) * 0.05</field>
<field name="python_compute_inv">result = round((price_unit * ( 1 - (1 / 1.036))) /
0.05) * 0.05</field>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<record model="account.tax.template" id="vat_36_invest">
<field name="name">TVA 3.6% sur invest. et autres ch.</field>
<field name="amount" eval="0.036"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_invest36"/>
<field name="tax_code_id" ref="vat_code_payable_invest"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_invest36"/>
<field name="ref_tax_code_id" ref="vat_code_payable_invest"/>
<field name="python_compute">result = round((price_unit * 0.036) / 0.05) * 0.05</field>
<field name="python_compute_inv">result = round((price_unit * ( 1 - (1 / 1.036))) /
0.05) * 0.05</field>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<record model="account.tax.template" id="vat_76">
<field name="name">7.6%</field>
<field name="amount" eval="0.076"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_due_76"/>
<field name="tax_code_id" ref="vat_code_due_tva76"/>
<field name="ref_base_code_id" ref="vat_code_due_76"/>
<field name="ref_tax_code_id" ref="vat_code_due_tva76"/>
<field name="python_compute">result = round((price_unit * 0.076) / 0.05) * 0.05</field>
<field name="python_compute_inv">result = round((price_unit * ( 1 - (1 / 1.076))) /
0.05) * 0.05</field>
<field name="base_sign" eval="1.0"/>
<field name="tax_sign" eval="1.0"/>
<field name="ref_base_sign" eval="-1.0"/>
<field name="ref_tax_sign" eval="-1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">sale</field>
</record>
<record model="account.tax.template" id="vat_76_purchase">
<field name="name">TVA 7.6% sur achat B&amp;S</field>
<field name="amount" eval="0.076"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_76"/>
<field name="tax_code_id" ref="vat_code_payable_bs"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_76"/>
<field name="ref_tax_code_id" ref="vat_code_payable_bs"/>
<field name="python_compute">result = round((price_unit * 0.076) / 0.05) * 0.05</field>
<field name="python_compute_inv">result = round((price_unit * ( 1 - (1 / 1.076))) /
0.05) * 0.05</field>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<record model="account.tax.template" id="vat_76_invest">
<field name="name">TVA 7.6% sur invest. et autres ch.</field>
<field name="amount" eval="0.076"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_invest76"/>
<field name="tax_code_id" ref="vat_code_payable_invest"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_invest76"/>
<field name="ref_tax_code_id" ref="vat_code_payable_invest"/>
<field name="python_compute">result = round((price_unit * 0.076) / 0.05) * 0.05</field>
<field name="python_compute_inv">result = round((price_unit * ( 1 - (1 / 1.076))) /
0.05) * 0.05</field>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<record model="account.tax.template" id="vat_XO">
<field name="name">TVA 0% Exportations</field>
<field name="amount" eval="0.00"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_due_0"/>
<field name="tax_code_id" ref="vat_code_due_tva0"/>
<field name="ref_base_code_id" ref="vat_code_due_0"/>
<field name="ref_tax_code_id" ref="vat_code_due_tva0"/>
<field name="base_sign" eval="1.0"/>
<field name="tax_sign" eval="1.0"/>
<field name="ref_base_sign" eval="-1.0"/>
<field name="ref_tax_sign" eval="-1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">sale</field>
</record>
<record model="account.tax.template" id="vat_O_exclude">
<field name="name">TVA 0% exclue</field>
<field name="amount" eval="0.00"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_due_0_exclu"/>
<field name="tax_code_id" ref="vat_code_due_tva0"/>
<field name="ref_base_code_id" ref="vat_code_due_0_exclu"/>
<field name="ref_tax_code_id" ref="vat_code_due_tva0"/>
<field name="base_sign" eval="1.0"/>
<field name="tax_sign" eval="1.0"/>
<field name="ref_base_sign" eval="-1.0"/>
<field name="ref_tax_sign" eval="-1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">sale</field>
</record>
<record model="account.tax.template" id="vat_O_import">
<field name="name">TVA 0% Importations de biens et services</field>
<field name="amount" eval="0.00"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_0"/>
<field name="tax_code_id" ref="vat_code_payable_bs"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_0"/>
<field name="ref_tax_code_id" ref="vat_code_payable_bs"/>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!-- TVA 50% -->
<!-- 50% 0f 7.6% base purchase -->
<record model="account.tax.template" id="vat_76_50">
<field name="name">TVA 50% sur 7.6% achat B&amp;S</field>
<field name="amount" eval="1.0"/>
<field name="child_depend" eval="True"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_76_50%"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_76_50%"/>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!--# 50% 0f 7.6% child 1-->
<record model="account.tax.template" id="vat_76_50_child_1">
<field name="name">TVA 50% sur 7.6% achat B&amp;S (récupérable)</field>
<field name="amount" eval="0.0380"/>
<field name="child_depend" eval="False"/>
<field name="type">percent</field>
<field name="tax_code_id" ref="vat_code_payable_bs"/>
<field name="ref_tax_code_id" ref="vat_code_payable_bs"/>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="parent_id" ref="vat_76_50"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!--# 50% 0f 7.6% child 2-->
<record model="account.tax.template" id="vat_76_50_child_2">
<field name="name">TVA 50% sur 7.6% achat B&amp;S (non récupérable)</field>
<field name="amount" eval="0.0380"/>
<field name="child_depend" eval="False"/>
<field name="type">percent</field>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="parent_id" ref="vat_76_50"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!--# 50% 0f 3.6% base purchase-->
<record model="account.tax.template" id="vat_36_50">
<field name="name">TVA 50% sur 3.6% achat B&amp;S</field>
<field name="amount" eval="1.0"/>
<field name="child_depend" eval="True"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_36_50%"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_36_50%"/>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!--# 50% 0f 3.6% child 1-->
<record model="account.tax.template" id="vat_36_50_child_1">
<field name="name">TVA 50% sur 3.6% achat B&amp;S (récupérable)</field>
<field name="amount" eval="0.0180"/>
<field name="child_depend" eval="False"/>
<field name="type">percent</field>
<field name="tax_code_id" ref="vat_code_payable_bs"/>
<field name="ref_tax_code_id" ref="vat_code_payable_bs"/>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="parent_id" ref="vat_36_50"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!--# 50% 0f 3.6% child 2-->
<record model="account.tax.template" id="vat_36_50_child_2">
<field name="name">TVA 50% sur 3.6% achat B&amp;S (non récupérable)</field>
<field name="amount" eval="0.018"/>
<field name="child_depend" eval="False"/>
<field name="type">percent</field>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="parent_id" ref="vat_36_50"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!-- # 50% 0f 2.4% base purchase -->
<record model="account.tax.template" id="vat_24_50">
<field name="name">TVA 50% sur 2.4% achat B&amp;S</field>
<field name="amount" eval="1.0"/>
<field name="child_depend" eval="True"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_receivable_base_24_50%"/>
<field name="ref_base_code_id" ref="vat_code_receivable_base_24_50%"/>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!-- 50% 0f 2.4% child 1 -->
<record model="account.tax.template" id="vat_24_50_child_1">
<field name="name">TVA 50% sur 2.4% achat B&amp;S (récupérable)</field>
<field name="amount" eval="0.012"/>
<field name="child_depend" eval="False"/>
<field name="type">percent</field>
<field name="tax_code_id" ref="vat_code_payable_bs"/>
<field name="ref_tax_code_id" ref="vat_code_payable_bs"/>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="parent_id" ref="vat_24_50"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!--# 50% 0f 2.4% child 2-->
<record model="account.tax.template" id="vat_24_50_child_2">
<field name="name">TVA 50% sur 2.4% achat B&amp;S (non récupérable)</field>
<field name="amount" eval="0.012"/>
<field name="child_depend" eval="False"/>
<field name="type">percent</field>
<field name="base_sign" eval="-1.0"/>
<field name="tax_sign" eval="-1.0"/>
<field name="ref_base_sign" eval="1.0"/>
<field name="ref_tax_sign" eval="1.0"/>
<field name="parent_id" ref="vat_24_50"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
<!--# 100% omn import !! the tax percentage is 00-->
<record model="account.tax.template" id="vat_100_import">
<field name="name">100% sur import</field>
<field name="amount" eval="0.0"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_payable_bs"/>
<field name="ref_base_code_id" ref="vat_code_payable_bs"/>
<field name="base_sign" eval="1.0"/>
<field name="tax_sign" eval="1.0"/>
<field name="ref_base_sign" eval="-1.0"/>
<field name="ref_tax_sign" eval="-1.0"/>
<field name="chart_template_id" ref="vat_code_chart_root"/>
<field name="type_tax_use">purchase</field>
</record>
</data>
</openerp>
+12
View File
@@ -0,0 +1,12 @@
<openerp>
<data>
<record id="config_call_account_template_l10n_ch" model="ir.actions.todo">
<field name="name">Generate Chart of Accounts from the L10n_ch_c2c_pcg Chart Template</field>
<field name="note">Generate Chart of Accounts from a Chart Template. You will be asked to pass the name of the company, the chart template to follow, the no. of digits to generate the code for your accounts and Bank account, currency to create Journals. Thus,the pure copy of chart Template is generated.
This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template.</field>
<field name="action_id" ref="account.action_wizard_multi_chart"/>
<field name="sequence">4</field>
</record>
</data>
</openerp>
+7
View File
@@ -0,0 +1,7 @@
#
# config.py
#
# Created by Nicolas Bessi on 12.02.09.
# Copyright (c) 2009 CamptoCamp. All rights reserved.
#
import config
+143
View File
@@ -0,0 +1,143 @@
#!/usr/bin/env python2.3
#
# config.py
#
# Created by Nicolas Bessi on 12.02.09.
# Copyright (c) 2009 CamptoCamp. All rights reserved.
#
from osv import fields, osv
class Tax_template(osv.osv):
"""Creat account.journal.todo class in order
to add configuration wizzard"""
_name ="account.tax.template.todo"
def _get_tax(self, cr, uid, ctx):
if not self.__dict__.has_key('_inner_steps') :
self._inner_steps = 0
ids = self.pool.get('account.tax.template').search(cr,uid,[])
if self._inner_steps == 'done' :
return False
return ids[self._inner_steps]
def _get_collected(self, cr, uid, ctx):
if not self.__dict__.has_key('_inner_steps') :
self._inner_steps = 0
if self._inner_steps == 'done' :
return False
ids = self.pool.get('account.tax.template').search(cr,uid,[])
id = self.pool.get('account.tax.template').browse(
cr,
uid,
ids[self._inner_steps]
).account_collected_id.id
return id
def _get_paid(self, cr, uid, ctx):
if not self.__dict__.has_key('_inner_steps') :
self._inner_steps = 0
if self._inner_steps == 'done' :
return False
ids = self.pool.get('account.tax.template').search(cr,uid,[])
id = self.pool.get('account.tax.template').browse(
cr,
uid,
ids[self._inner_steps]
).account_paid_id.id
return id
_columns={
'name': fields.many2one(
'account.tax.template',
'Tax to set',
readonly=True,
help="The tax template you are currently editing"
),
'account_collected_id':fields.many2one(
'account.account.template',
'Invoice Tax Account',
help="You can set \
here the invoice tax account"
),
'account_paid_id':fields.many2one(
'account.account.template',
'Refund Tax Account',
help="You can set \
here the refund tax account"
),
}
_defaults = {
'name': _get_tax,
'account_collected_id':_get_collected,
'account_paid_id':_get_paid,
}
def on_change_collected(self, cr, uid, id, tax, account) :
if account :
self.pool.get('account.tax.template').write(
cr,
uid,
tax,
vals={
'account_collected_id': account,
}
)
return {}
def on_change_paid(self, cr, uid, id, tax, account) :
if account :
self.pool.get('account.tax.template').write(
cr,
uid,
tax,
vals={
'account_paid_id': account,
}
)
return {}
def action_cancel(self,cr,uid,ids,context=None):
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'ir.actions.configuration.wizard',
'type': 'ir.actions.act_window',
'target':'new',
}
def action_new(self,cr,uid,ids,context={}):
jids = self.pool.get('account.tax.template').search(cr, uid, [])
if self._inner_steps < len(jids)-1 :
self._inner_steps += 1
else :
self._inner_steps = 'done'
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'account.tax.template.todo',
'view_id':self.pool.get('ir.ui.view').search(
cr,
uid,
[('name','=','view_account_journal_form_todo')]
),
'type': 'ir.actions.act_window',
'target':'new',
}
Tax_template()