[MRG] from c2c l10n_ch
bzr revid: yannick.vaucher@camptocamp.com-20110916143255-7btktl8u1u23cwn0
This commit is contained in:
parent
e1012285a3
commit
2b142c0a31
|
@ -2,7 +2,7 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# Author: Nicolas Bessi. Copyright Camptocamp SA
|
# Author: Nicolas Bessi. Copyright Camptocamp SA
|
||||||
# Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
|
# Donors: Hasa SA, Open Net SA and Prisme Solutions Informatique SA
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
@ -22,9 +22,7 @@
|
||||||
{
|
{
|
||||||
"name" : "Switzerland - localization with 2011 taxes",
|
"name" : "Switzerland - localization with 2011 taxes",
|
||||||
"description" : """
|
"description" : """
|
||||||
Swiss localisation.
|
Swiss localisation :
|
||||||
===================
|
|
||||||
|
|
||||||
- DTA generation for a lot of payment types
|
- DTA generation for a lot of payment types
|
||||||
- BVR management (number generation, report, etc..)
|
- BVR management (number generation, report, etc..)
|
||||||
- Import account move from the bank file (like v11 etc..)
|
- Import account move from the bank file (like v11 etc..)
|
||||||
|
@ -34,8 +32,10 @@ You can also add ZIP and bank completion with:
|
||||||
- l10n_ch_zip
|
- l10n_ch_zip
|
||||||
- l10n_ch_bank
|
- l10n_ch_bank
|
||||||
|
|
||||||
Author: Camptocamp SA
|
Author: Camptocamp SA
|
||||||
Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
|
Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
Module incluant la localisation Suisse de TinyERP revu et corrigé par Camptocamp. Cette nouvelle version
|
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)
|
comprend la gestion et l'émissionde BVR, le paiement électronique via DTA (pour les banques, le système postal est en développement)
|
||||||
|
@ -51,6 +51,7 @@ Vous pouvez ajouter la completion des banques et des NPA avec with:
|
||||||
Auteur: Camptocamp SA
|
Auteur: Camptocamp SA
|
||||||
Donateurs: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
|
Donateurs: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
TODO :
|
TODO :
|
||||||
- Implement bvr import partial reconciliation
|
- Implement bvr import partial reconciliation
|
||||||
- Replace wizard by osv_memory when possible
|
- Replace wizard by osv_memory when possible
|
||||||
|
@ -60,8 +61,8 @@ TODO :
|
||||||
|
|
||||||
|
|
||||||
""",
|
""",
|
||||||
"version" : "6.0",
|
"version" : "6.1",
|
||||||
"author" : "Camptocamp SA",
|
"author" : "Camptocamp",
|
||||||
"category" : "Finance",
|
"category" : "Finance",
|
||||||
"website": "http://www.camptocamp.com",
|
"website": "http://www.camptocamp.com",
|
||||||
|
|
||||||
|
@ -83,10 +84,10 @@ TODO :
|
||||||
],
|
],
|
||||||
"demo_xml" : [
|
"demo_xml" : [
|
||||||
"demo/demo.xml",
|
"demo/demo.xml",
|
||||||
|
"demo/dta_demo.xml",
|
||||||
],
|
],
|
||||||
"update_xml" : [
|
"update_xml" : [
|
||||||
"wizard.xml",
|
"wizard.xml",
|
||||||
"dta_view.xml",
|
|
||||||
"wizard/bvr_import_view.xml",
|
"wizard/bvr_import_view.xml",
|
||||||
"wizard/create_dta_view.xml",
|
"wizard/create_dta_view.xml",
|
||||||
"company_view.xml",
|
"company_view.xml",
|
||||||
|
@ -97,6 +98,9 @@ TODO :
|
||||||
],
|
],
|
||||||
'test' : [
|
'test' : [
|
||||||
'test/l10n_ch_report.yml',
|
'test/l10n_ch_report.yml',
|
||||||
|
'test/l10n_ch_dta.yml',
|
||||||
|
'test/l10n_ch_v11.yml',
|
||||||
|
'test/l10n_ch_v11_part.yml',
|
||||||
],
|
],
|
||||||
"active": False,
|
"active": False,
|
||||||
"installable": True,
|
"installable": True,
|
||||||
|
|
|
@ -19,12 +19,15 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
from tools.translate import _
|
||||||
from osv import fields, osv
|
from osv import fields, osv
|
||||||
|
|
||||||
class Bank(osv.osv):
|
class Bank(osv.osv):
|
||||||
"""Inherit res.bank class in order to add swiss specific field"""
|
"""Inherit res.bank class in order to add swiss specific field"""
|
||||||
_inherit = 'res.bank'
|
_inherit = 'res.bank'
|
||||||
_columns = {
|
_columns = {
|
||||||
|
### Internal reference
|
||||||
|
'code': fields.char('Code', size=64),
|
||||||
###Swiss unik bank identifier also use in IBAN number
|
###Swiss unik bank identifier also use in IBAN number
|
||||||
'clearing': fields.char('Clearing number', size=64),
|
'clearing': fields.char('Clearing number', size=64),
|
||||||
### city of the bank
|
### city of the bank
|
||||||
|
@ -33,15 +36,113 @@ class Bank(osv.osv):
|
||||||
|
|
||||||
Bank()
|
Bank()
|
||||||
|
|
||||||
class bvr_checkbox(osv.osv):
|
|
||||||
""" Add function to generate function """
|
class ResPartnerBank(osv.osv):
|
||||||
_inherit = "res.partner.bank"
|
_inherit = "res.partner.bank"
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'print_bank' : fields.boolean('Print Bank on BVR'),
|
'name': fields.char('Description', size=128, required=True),
|
||||||
'print_account' : fields.boolean('Print Account Number on BVR'),
|
'post_number': fields.char('Post number', size=64),
|
||||||
|
'bvr_adherent_num': fields.char('BVR adherent number', size=11),
|
||||||
|
'dta_code': fields.char('DTA code', size=5),
|
||||||
|
'print_bank': fields.boolean('Print Bank on BVR'),
|
||||||
|
'print_account': fields.boolean('Print Account Number on BVR'),
|
||||||
|
'acc_number': fields.char('Account/IBAN Number', size=64),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bvr_checkbox()
|
def name_get(self, cursor, uid, ids, context=None):
|
||||||
|
if not len(ids):
|
||||||
|
return []
|
||||||
|
bank_type_obj = self.pool.get('res.partner.bank.type')
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
type_ids = bank_type_obj.search(cursor, uid, [])
|
||||||
|
bank_type_names = {}
|
||||||
|
for bank_type in bank_type_obj.browse(cursor, uid, type_ids,
|
||||||
|
context=context):
|
||||||
|
bank_type_names[bank_type.code] = bank_type.name
|
||||||
|
res = []
|
||||||
|
for r in self.read(cursor, uid, ids, ['name','state'], context):
|
||||||
|
res.append((r['id'], r['name']+' : '+bank_type_names.get(r['state'], '')))
|
||||||
|
return res
|
||||||
|
|
||||||
|
def post_write(self, cr, uid, ids, context={}):
|
||||||
|
""" Override of post_write method.
|
||||||
|
In Switzerland with post accounts you can either have a postal account
|
||||||
|
with a required bank number (BVR Bank) or a postal number alone (BV Post, BVR Post).
|
||||||
|
So acc_number is not always mandatory and postal and bank number are not the same field """
|
||||||
|
|
||||||
|
obj_acc = self.pool.get('account.account')
|
||||||
|
obj_data = self.pool.get('ir.model.data')
|
||||||
|
for bank in self.browse(cr, uid, ids, context):
|
||||||
|
if bank.company_id and not bank.journal_id:
|
||||||
|
# Find the code and parent of the bank account to create
|
||||||
|
dig = 6
|
||||||
|
current_num = 1
|
||||||
|
ids = obj_acc.search(cr, uid, [('type','=','liquidity')], context=context)
|
||||||
|
# No liquidity account exists, no template available
|
||||||
|
if not ids: continue
|
||||||
|
|
||||||
|
ref_acc_bank_temp = obj_acc.browse(cr, uid, ids[0], context=context)
|
||||||
|
ref_acc_bank = ref_acc_bank_temp.parent_id
|
||||||
|
while True:
|
||||||
|
new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)), '0')) + str(current_num)
|
||||||
|
ids = obj_acc.search(cr, uid, [('code', '=', new_code), ('company_id', '=', bank.company_id.id)])
|
||||||
|
if not ids:
|
||||||
|
break
|
||||||
|
current_num += 1
|
||||||
|
|
||||||
|
# Here is the test
|
||||||
|
if not bank.acc_number:
|
||||||
|
number = bank.post_number
|
||||||
|
else:
|
||||||
|
number = bank.acc_number
|
||||||
|
|
||||||
|
acc = {
|
||||||
|
'name': (bank.bank_name or '')+' '+ number,
|
||||||
|
'currency_id': bank.company_id.currency_id.id,
|
||||||
|
'code': new_code,
|
||||||
|
'type': 'liquidity',
|
||||||
|
'user_type': ref_acc_bank_temp.user_type.id,
|
||||||
|
'reconcile': False,
|
||||||
|
'parent_id': ref_acc_bank.id,
|
||||||
|
'company_id': bank.company_id.id,
|
||||||
|
}
|
||||||
|
acc_bank_id = obj_acc.create(cr,uid,acc,context=context)
|
||||||
|
|
||||||
|
# Get the journal view id
|
||||||
|
data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view')])
|
||||||
|
data = obj_data.browse(cr, uid, data_id[0], context=context)
|
||||||
|
view_id_cash = data.res_id
|
||||||
|
|
||||||
|
jour_obj = self.pool.get('account.journal')
|
||||||
|
new_code = 1
|
||||||
|
while True:
|
||||||
|
code = _('BNK')+str(new_code)
|
||||||
|
ids = jour_obj.search(cr, uid, [('code','=',code)], context=context)
|
||||||
|
if not ids:
|
||||||
|
break
|
||||||
|
new_code += 1
|
||||||
|
|
||||||
|
#create the bank journal
|
||||||
|
vals_journal = {
|
||||||
|
'name': (bank.bank_name or '')+' '+number,
|
||||||
|
'code': code,
|
||||||
|
'type': 'bank',
|
||||||
|
'company_id': bank.company_id.id,
|
||||||
|
'analytic_journal_id': False,
|
||||||
|
'currency_id': False,
|
||||||
|
'default_credit_account_id': acc_bank_id,
|
||||||
|
'default_debit_account_id': acc_bank_id,
|
||||||
|
'view_id': view_id_cash
|
||||||
|
}
|
||||||
|
journal_id = jour_obj.create(cr, uid, vals_journal, context=context)
|
||||||
|
|
||||||
|
self.write(cr, uid, [bank.id], {'journal_id': journal_id}, context=context)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
_sql_constraints = [('bvr_adherent_uniq', 'unique (bvr_adherent_num)',
|
||||||
|
'The BVR adherent number must be unique !')]
|
||||||
|
|
||||||
|
ResPartnerBank()
|
||||||
|
|
|
@ -1,54 +1,184 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data>
|
||||||
|
<!-- res.bank base form-->
|
||||||
<record model="ir.ui.view" id="view_res_bank_form">
|
<record model="ir.ui.view" id="view_res_bank_form">
|
||||||
<field name="name">res.bank.form</field>
|
<field name="name">res.bank.form</field>
|
||||||
<field name="model">res.bank</field>
|
<field name="model">res.bank</field>
|
||||||
<field name="type">form</field>
|
<field name="type">form</field>
|
||||||
|
<field name="sequence" eval="9" />
|
||||||
<field name="inherit_id" ref="base.view_res_bank_form"/>
|
<field name="inherit_id" ref="base.view_res_bank_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
|
<field name="name" position="after">
|
||||||
|
<field name="code"/>
|
||||||
|
</field>
|
||||||
<field name="bic" position="after">
|
<field name="bic" position="after">
|
||||||
<field name="clearing"/>
|
<field name="clearing"/>
|
||||||
</field>
|
</field>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<!-- res.bank base tree-->
|
||||||
<record model="ir.ui.view" id="l10nch_view_res_bank_tree">
|
<record model="ir.ui.view" id="l10nch_view_res_bank_tree">
|
||||||
<field name="name">res.bank.tree</field>
|
<field name="name">res.bank.tree</field>
|
||||||
<field name="model">res.bank</field>
|
<field name="model">res.bank</field>
|
||||||
<field name="type">tree</field>
|
<field name="type">tree</field>
|
||||||
|
<field name="sequence" eval="9" />
|
||||||
<field name="inherit_id" ref="base.view_res_bank_tree"/>
|
<field name="inherit_id" ref="base.view_res_bank_tree"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<field name="code" position="after">
|
<field name="name" position="after">
|
||||||
|
<field name="code" select="1"/>
|
||||||
<field name="clearing" select="1"/>
|
<field name="clearing" select="1"/>
|
||||||
</field>
|
</field>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="l10nch_view_res_partner_bank">
|
<!-- res.partner.bank in res partner form-->
|
||||||
<field name="name">res.partner_bank.form</field>
|
<!-- Partner -> Bank Details -->
|
||||||
<field name="model">res.partner.bank</field>
|
|
||||||
<field name="type">form</field>
|
<record model="ir.ui.view" id="l10nch_view_res_partner_bank_hide_f1">
|
||||||
<field name="inherit_id" ref="base.view_partner_bank_form"/>
|
<field name="name">res.partner_bank.form.hide.f1</field>
|
||||||
<field name="arch" type="xml">
|
|
||||||
<field name="country_id" position="after">
|
|
||||||
<field name="print_bank"/>
|
|
||||||
<field name="print_account"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record model="ir.ui.view" id="l10nch_view_res_partner_bank">
|
|
||||||
<field name="name">res.partner_partner_bank.form</field>
|
|
||||||
<field name="model">res.partner</field>
|
<field name="model">res.partner</field>
|
||||||
<field name="type">form</field>
|
<field name="type">form</field>
|
||||||
|
<field name="sequence" eval="9" />
|
||||||
<field name="inherit_id" ref="account.view_partner_property_form"/>
|
<field name="inherit_id" ref="account.view_partner_property_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<field name="bank" position="after">
|
<field name="acc_number" position="replace">
|
||||||
<newline />
|
|
||||||
<field name="print_bank"/>
|
|
||||||
<field name="print_account"/>
|
|
||||||
</field>
|
</field>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
<record model="ir.ui.view" id="l10nch_view_res_partner_bank_hide_f2">
|
||||||
|
<field name="name">res.partner_bank.form.hide.f2</field>
|
||||||
|
<field name="model">res.partner</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="sequence" eval="9" />
|
||||||
|
<field name="inherit_id" ref="account.view_partner_property_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="bank" position="replace">
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="l10nch_view_res_partner_bank_add_groups">
|
||||||
|
<field name="name">res.partner_bank.form.hide.f2</field>
|
||||||
|
<field name="model">res.partner</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="sequence" eval="10" />
|
||||||
|
<field name="inherit_id" ref="account.view_partner_property_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="state" position="after">
|
||||||
|
<newline/>
|
||||||
|
<separator colspan="4" string="Account infos"/>
|
||||||
|
<group string="Bank account info" colspan="4" attrs="{'invisible': [('state','in', ['bvpost','bvrpost'])]}" >
|
||||||
|
<field name="acc_number" string="Account/IBAN Number" attrs="{'required': [('state','not in',['bvpost','bvrpost'])]}"/>
|
||||||
|
<field name="dta_code"/>
|
||||||
|
<newline/>
|
||||||
|
</group>
|
||||||
|
<newline/>
|
||||||
|
<group string="Postal account info" colspan="4" attrs="{'invisible': [('state','not in', ['bvpost','bvrpost','bvbank','bvrbank'])]}" >
|
||||||
|
<field name="post_number" attrs="{'required': [('state','in',['bvpost','bvrpost','bvrbank'])]}"/>
|
||||||
|
<newline/>
|
||||||
|
</group>
|
||||||
|
<separator colspan="4" string="Financial institute infos"/>
|
||||||
|
<field name="bank" />
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- res.partner.bank base form-->
|
||||||
|
<!-- Sales -> Configuration -> Address Book -> Bank accounts -->
|
||||||
|
<!-- Invoice -> Bank account -->
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="l10nch_view_res_partner_bank_acc_number_hide_frominvoice">
|
||||||
|
<field name="name">res.partner_bank.form.hide.acc_number.frominvoice</field>
|
||||||
|
<field name="model">res.partner.bank</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="sequence" eval="9" />
|
||||||
|
<field name="inherit_id" ref="base.view_partner_bank_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="acc_number" position="replace">
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="l10nch_view_res_partner_bank_hide_bank_frominvoice2">
|
||||||
|
<field name="name">res.partner_bank.form.hide.bank.frominvoice</field>
|
||||||
|
<field name="model">res.partner.bank</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="sequence" eval="9" />
|
||||||
|
<field name="inherit_id" ref="base.view_partner_bank_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="bank" position="replace">
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="l10nch_view_res_partner_bank_from_invoice">
|
||||||
|
<field name="name">res.partner_bank.form.hide.frominvoice</field>
|
||||||
|
<field name="model">res.partner.bank</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="sequence" eval="10"/>
|
||||||
|
<field name="inherit_id" ref="base.view_partner_bank_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="state" position="after">
|
||||||
|
<newline/>
|
||||||
|
|
||||||
|
<separator colspan="4" string="Account infos"/>
|
||||||
|
<newline/>
|
||||||
|
<group string="Bank account info" colspan="4" attrs="{'invisible': [('state','in', ['bvpost','bvrpost'])]}" >
|
||||||
|
<field name="acc_number" string="Account/IBAN Number" attrs="{'required': [('state','not in',['bvpost','bvrpost'])]}"/>
|
||||||
|
<field name="dta_code"/>
|
||||||
|
<newline/>
|
||||||
|
</group>
|
||||||
|
<newline/>
|
||||||
|
<group string="Postal account info" colspan="4" attrs="{'invisible': [('state','not in', ['bvpost','bvrpost','bvbank','bvrbank'])]}" >
|
||||||
|
<field name="post_number" attrs="{'required': [('state','in',['bvpost','bvrpost','bvrbank'])]}"/>
|
||||||
|
<newline/>
|
||||||
|
</group>
|
||||||
|
<separator colspan="4" string="Financial institute infos"/>
|
||||||
|
<group string="BVR print options" colspan="4" attrs="{'invisible': [('company_id','=',False)]}" >
|
||||||
|
<field name="bvr_adherent_num"/>
|
||||||
|
<field name="print_bank"/>
|
||||||
|
<field name="print_account"/>
|
||||||
|
<newline/>
|
||||||
|
</group>
|
||||||
|
<newline/>
|
||||||
|
<field name="bank" />
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- res.partner form bank list-->
|
||||||
|
<!-- Adding Type and bank name -->
|
||||||
|
<record id="l10nch_view_partner_bank_details_list" model="ir.ui.view">
|
||||||
|
<field name="name">res.partner.form.bank_details.list</field>
|
||||||
|
<field name="model">res.partner</field>
|
||||||
|
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="/form/notebook/page/field[@name='bank_ids']/tree/field[@name='acc_number']" position="before">
|
||||||
|
<field name="state" />
|
||||||
|
<field name="bank" />
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- res.partner form bank list-->
|
||||||
|
<!-- Adding Type and bank name -->
|
||||||
|
<record id="l10nch_view_partner_bank_invoice_tree" model="ir.ui.view">
|
||||||
|
<field name="name">res.partner.bank.tree.from_invoice</field>
|
||||||
|
<field name="model">res.partner.bank</field>
|
||||||
|
<field name="inherit_id" ref="base.view_partner_bank_tree"/>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="acc_number" position="before">
|
||||||
|
<field name="state" />
|
||||||
|
<field name="bank" />
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -33,6 +33,16 @@ class res_company(osv.osv):
|
||||||
'bvr_delta_vert': fields.float('BVR Vert. Delta (mm)',
|
'bvr_delta_vert': fields.float('BVR Vert. Delta (mm)',
|
||||||
help='vert. delta in mm 1.2 will print the bvr 1.2mm lower, negative value is possible'),
|
help='vert. delta in mm 1.2 will print the bvr 1.2mm lower, negative value is possible'),
|
||||||
|
|
||||||
|
'bvr_scan_line_vert': fields.float('BVR vert. position for scan line (mm)',
|
||||||
|
help='Vert. position in mm for scan line'),
|
||||||
|
|
||||||
|
'bvr_scan_line_horz': fields.float('BVR horiz. position for scan line(mm)',
|
||||||
|
help='Horiz. position in mm for scan line'),
|
||||||
|
|
||||||
|
'bvr_scan_line_font_size': fields.float('BVR scan line font size (pt)'),
|
||||||
|
|
||||||
|
'bvr_scan_line_letter_spacing':fields.float('BVR scan line letter spacing'),
|
||||||
|
|
||||||
'bvr_background': fields.boolean('Insert BVR background ?'),
|
'bvr_background': fields.boolean('Insert BVR background ?'),
|
||||||
|
|
||||||
'bvr_only': fields.boolean('Separated BVR only ?',
|
'bvr_only': fields.boolean('Separated BVR only ?',
|
||||||
|
@ -42,6 +52,13 @@ class res_company(osv.osv):
|
||||||
help='Print only the invoice without BVR'),
|
help='Print only the invoice without BVR'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_defaults = {
|
||||||
|
'bvr_scan_line_vert': lambda *a: 232,
|
||||||
|
'bvr_scan_line_horz': lambda *a: 72,
|
||||||
|
'bvr_scan_line_font_size': lambda *a: 12,
|
||||||
|
'bvr_scan_line_letter_spacing': lambda *a: 0,
|
||||||
|
}
|
||||||
|
|
||||||
res_company()
|
res_company()
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -8,11 +8,19 @@
|
||||||
<field name="inherit_id" ref="base.view_company_form"/>
|
<field name="inherit_id" ref="base.view_company_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<field name="rml_footer2" position="after">
|
<field name="rml_footer2" position="after">
|
||||||
|
<newline/>
|
||||||
|
<group string="BVR data" colspan="4">
|
||||||
<field name="bvr_delta_horz"/>
|
<field name="bvr_delta_horz"/>
|
||||||
<field name="bvr_delta_vert"/>
|
<field name="bvr_delta_vert"/>
|
||||||
|
<field name="bvr_scan_line_vert"/>
|
||||||
|
<field name="bvr_scan_line_horz"/>
|
||||||
|
<field name="bvr_scan_line_font_size"/>
|
||||||
|
<field name="bvr_scan_line_letter_spacing"/>
|
||||||
<field name="bvr_background"/>
|
<field name="bvr_background"/>
|
||||||
<field name="bvr_only"/>
|
<field name="bvr_only"/>
|
||||||
<field name="invoice_only"/>
|
<field name="invoice_only"/>
|
||||||
|
</group>
|
||||||
|
<newline/>
|
||||||
</field>
|
</field>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
|
@ -13,10 +13,8 @@
|
||||||
<field name="state">bvrbank</field>
|
<field name="state">bvrbank</field>
|
||||||
<field name="post_number">11-1234-1</field>
|
<field name="post_number">11-1234-1</field>
|
||||||
<field name="bank" ref="main_bank"/>
|
<field name="bank" ref="main_bank"/>
|
||||||
<field name="iban">CH9100767000S00023455</field>
|
<!-- <field name="iban">CH9100767000S00023455</field> -->
|
||||||
<field name="bvr_adherent_num">0000000</field>
|
<field name="bvr_adherent_num">0000000</field>
|
||||||
|
|
||||||
|
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="bank" model="res.partner">
|
<record id="bank" model="res.partner">
|
||||||
|
@ -24,7 +22,6 @@
|
||||||
<field name="ref">banq</field>
|
<field name="ref">banq</field>
|
||||||
<field name="name">Banque</field>
|
<field name="name">Banque</field>
|
||||||
<field name="category_id" model="res.partner.category" search="[('name','=','Partenaire')]"/>
|
<field name="category_id" model="res.partner.category" search="[('name','=','Partenaire')]"/>
|
||||||
<field name="address" eval="[]"/>
|
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="res_partner_address_bank1" model="res.partner.address">
|
<record id="res_partner_address_bank1" model="res.partner.address">
|
||||||
|
@ -48,7 +45,6 @@
|
||||||
<field name="website">http://camptocamp.com</field>
|
<field name="website">http://camptocamp.com</field>
|
||||||
<field name="name">ProLibre</field>
|
<field name="name">ProLibre</field>
|
||||||
<field name="category_id" model="res.partner.category" search="[('name','=','Partenaire')]"/>
|
<field name="category_id" model="res.partner.category" search="[('name','=','Partenaire')]"/>
|
||||||
<field name="address" eval="[]"/>
|
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="camptocamp" model="res.partner">
|
<record id="camptocamp" model="res.partner">
|
||||||
|
@ -58,7 +54,6 @@
|
||||||
<field name="website">http://camptocamp.com</field>
|
<field name="website">http://camptocamp.com</field>
|
||||||
<field name="name">camptocamp SA</field>
|
<field name="name">camptocamp SA</field>
|
||||||
<field name="category_id" model="res.partner.category" search="[('name','=','Partenaire')]"/>
|
<field name="category_id" model="res.partner.category" search="[('name','=','Partenaire')]"/>
|
||||||
<field name="address" eval="[]"/>
|
|
||||||
</record>
|
</record>
|
||||||
<!--
|
<!--
|
||||||
Resource: res.partner.address
|
Resource: res.partner.address
|
||||||
|
|
|
@ -14,17 +14,18 @@
|
||||||
<field name="state">bvrbank</field>
|
<field name="state">bvrbank</field>
|
||||||
<field name="post_number">234567</field>
|
<field name="post_number">234567</field>
|
||||||
<field name="bank" ref="partner_bank"/>
|
<field name="bank" ref="partner_bank"/>
|
||||||
<field name="iban">CH9100767000S00023455</field>
|
<!-- <field name="iban">CH9100767000S00023455</field> -->
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="res.partner.bank" id="main_bank">
|
<record model="res.partner.bank" id="main_bank">
|
||||||
<field name="name">My bank</field>
|
<field name="name">My bank</field>
|
||||||
<field name="acc_number">123456</field>
|
<!-- <field name="acc_number">123456</field> -->
|
||||||
<field name="iban">123456</field>
|
<!-- <field name="iban">123456</field> -->
|
||||||
<field name="partner_id" ref="base.main_partner"/>
|
<field name="partner_id" ref="base.main_partner"/>
|
||||||
<field name="state">dta_company</field>
|
<field name="state">dta_company</field>
|
||||||
<field name="bank" ref="partner_bank"/>
|
<field name="bank" ref="partner_bank"/>
|
||||||
<field name="iban">CH9100767000S00023455</field>
|
<!-- <field name="iban">CH9100767000S00023455</field> -->
|
||||||
|
<field name="acc_number">CH9100767000S00023455</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="account.invoice" id="v11_invoice">
|
<record model="account.invoice" id="v11_invoice">
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
# -*- encoding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Author: Nicolas Bessi. Copyright Camptocamp SA
|
|
||||||
# Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as
|
|
||||||
# published by the Free Software Foundation, either version 3 of the
|
|
||||||
# License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
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="Displays 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 line 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()
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data noupdate="1">
|
||||||
|
|
||||||
|
|
||||||
<!-- Memo :
|
<!-- Memo :
|
||||||
|
@ -30,113 +30,25 @@
|
||||||
<field name="code">dta_company</field>
|
<field name="code">dta_company</field>
|
||||||
</record>
|
</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">
|
<record model="res.partner.bank.type" id="bvrbank">
|
||||||
<field name="name">DTA-BVRBANK</field>
|
<field name="name">BVR Bank</field>
|
||||||
<field name="code">bvrbank</field>
|
<field name="code">bvrbank</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="res.partner.bank.type" id="bvrpost">
|
<record model="res.partner.bank.type" id="bvrpost">
|
||||||
<field name="name">DTA-BVRPOST</field>
|
<field name="name">BVR Post</field>
|
||||||
<field name="code">bvrpost</field>
|
<field name="code">bvrpost</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="res.partner.bank.type" id="bvpost">
|
<record model="res.partner.bank.type" id="bvpost">
|
||||||
<field name="name">DTA-BVPOST</field>
|
<field name="name">BV Post</field>
|
||||||
<field name="code">bvpost</field>
|
<field name="code">bvpost</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="res.partner.bank.type" id="bvbank">
|
<record model="res.partner.bank.type" id="bvbank">
|
||||||
<field name="name">DTA-BVBANK</field>
|
<field name="name">BV Bank</field>
|
||||||
<field name="code">bvbank</field>
|
<field name="code">bvbank</field>
|
||||||
</record>
|
</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">post_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">post_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>
|
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
|
@ -1,37 +0,0 @@
|
||||||
<?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_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_adherent_num"/>
|
|
||||||
<field name="post_number"/>
|
|
||||||
<field name="dta_code"/>
|
|
||||||
</field>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
|
@ -73,7 +73,7 @@ class account_invoice(osv.osv):
|
||||||
help='The partner bank account to pay\nKeep empty to use the default'
|
help='The partner bank account to pay\nKeep empty to use the default'
|
||||||
),
|
),
|
||||||
### Amount to pay
|
### Amount to pay
|
||||||
'amount_to_pay': fields.function(_amount_to_pay,
|
'amount_to_pay': fields.function(_amount_to_pay, method=True,
|
||||||
type='float', string='Amount to be paid',
|
type='float', string='Amount to be paid',
|
||||||
help='The amount which should be paid at the current date\n' \
|
help='The amount which should be paid at the current date\n' \
|
||||||
'minus the amount which is already in payment order'),
|
'minus the amount which is already in payment order'),
|
||||||
|
@ -143,7 +143,7 @@ class account_invoice(osv.osv):
|
||||||
def onchange_partner_id(self, cr, uid, ids, type, partner_id,
|
def onchange_partner_id(self, cr, uid, ids, type, partner_id,
|
||||||
date_invoice=False, payment_term=False, partner_bank_id=False, company_id=False):
|
date_invoice=False, payment_term=False, partner_bank_id=False, company_id=False):
|
||||||
""" Function that is call when the partner of the invoice is changed
|
""" Function that is call when the partner of the invoice is changed
|
||||||
it will retriev and set the good bank partner bank"""
|
it will retrieve and set the good bank partner bank"""
|
||||||
res = super(account_invoice, self).onchange_partner_id(
|
res = super(account_invoice, self).onchange_partner_id(
|
||||||
cr,
|
cr,
|
||||||
uid,
|
uid,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data noupdate="1">
|
||||||
|
|
||||||
<record id="expenses_journal" model="account.journal">
|
<record id="expenses_journal" model="account.journal">
|
||||||
<field name="name">Journal de frais</field>
|
<field name="name">Journal de frais</field>
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
<record id="bank_journal" model="account.journal">
|
<record id="bank_journal" model="account.journal">
|
||||||
<field name="name">Banque CHF</field>
|
<field name="name">Banque CHF</field>
|
||||||
<field name="code">BCHF</field>
|
<field name="code">BCHF</field>
|
||||||
<field name="type">cash</field>
|
<field name="type">bank</field>
|
||||||
<field name="view_id" ref="account.account_journal_bank_view"/>
|
<field name="view_id" ref="account.account_journal_bank_view"/>
|
||||||
<field name="sequence_id" ref="account.sequence_journal"/>
|
<field name="sequence_id" ref="account.sequence_journal"/>
|
||||||
<field name="user_id" ref="base.user_root"/>
|
<field name="user_id" ref="base.user_root"/>
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
<record id="bank_euro_journal" model="account.journal">
|
<record id="bank_euro_journal" model="account.journal">
|
||||||
<field name="name">Banque EUR</field>
|
<field name="name">Banque EUR</field>
|
||||||
<field name="code">BEUR</field>
|
<field name="code">BEUR</field>
|
||||||
<field name="type">cash</field>
|
<field name="type">bank</field>
|
||||||
<field name="view_id" ref="account.account_journal_bank_view"/>
|
<field name="view_id" ref="account.account_journal_bank_view"/>
|
||||||
<field name="sequence_id" ref="account.sequence_journal"/>
|
<field name="sequence_id" ref="account.sequence_journal"/>
|
||||||
<field name="user_id" ref="base.user_root"/>
|
<field name="user_id" ref="base.user_root"/>
|
||||||
|
|
|
@ -30,35 +30,4 @@ class res_partner(osv.osv):
|
||||||
}
|
}
|
||||||
|
|
||||||
res_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_adherent_num': fields.char('BVR adherent number', size=11),
|
|
||||||
'dta_code': fields.char('DTA code', size=5),
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -7,6 +7,17 @@
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
src: url(${police_absolute_path('ocrbb.ttf')}) format("truetype");
|
src: url(${police_absolute_path('ocrbb.ttf')}) format("truetype");
|
||||||
}
|
}
|
||||||
|
.ocrbb{
|
||||||
|
text-align:right;
|
||||||
|
font-family:bvrocrb;
|
||||||
|
font-size:${str(company.bvr_scan_line_font_size or '0.0').replace(',','.')}pt;
|
||||||
|
position:absolute;top:${str(company.bvr_scan_line_vert or '0.0').replace(',','.')}mm;
|
||||||
|
left:${str(company.bvr_scan_line_horz or '0.0').replace(',','.')}mm;
|
||||||
|
z-index:4;
|
||||||
|
letter-spacing:str(company.bvr_scan_line_letter_spacing or '0.0').replace(',','.')
|
||||||
|
}
|
||||||
|
${css}
|
||||||
|
</style>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
@ -87,9 +98,41 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
${_check(objects)}
|
|
||||||
%for inv in objects :
|
%for inv in objects :
|
||||||
<% setLang(inv.partner_id.lang) %>
|
<% setLang(inv.partner_id.lang) %>
|
||||||
|
<!--adresses + info block -->
|
||||||
|
<table class="dest_address" style="position:absolute;top:6mm;left:15mm">
|
||||||
|
<tr><td ><b>${inv.partner_id.title.name or ''|entity} ${inv.partner_id.name |entity}</b></td></tr>
|
||||||
|
<tr><td>${inv.address_invoice_id.street or ''|entity}</td></tr>
|
||||||
|
<tr><td>${inv.address_invoice_id.street2 or ''|entity}</td></tr>
|
||||||
|
<tr><td>${inv.address_invoice_id.zip or ''|entity} ${inv.address_invoice_id.city or ''|entity}</td></tr>
|
||||||
|
%if inv.address_invoice_id.country_id :
|
||||||
|
<tr><td>${inv.address_invoice_id.country_id.name or ''|entity} </td></tr>
|
||||||
|
%endif
|
||||||
|
%if inv.address_invoice_id.phone :
|
||||||
|
<tr><td>${_("Tel") |entity}: ${inv.address_invoice_id.phone|entity}</td></tr>
|
||||||
|
%endif
|
||||||
|
%if inv.address_invoice_id.fax :
|
||||||
|
<tr><td>${_("Fax") |entity}: ${inv.address_invoice_id.fax|entity}</td></tr>
|
||||||
|
%endif
|
||||||
|
%if inv.address_invoice_id.email :
|
||||||
|
<tr><td>${_("E-mail") |entity}: ${inv.address_invoice_id.email|entity}</td></tr>
|
||||||
|
%endif
|
||||||
|
%if inv.partner_id.vat :
|
||||||
|
<tr><td>${_("VAT") |entity}: ${inv.partner_id.vat|entity}</td></tr>
|
||||||
|
%endif
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div style="position:absolute;top:60mm; left:20mm">
|
||||||
|
${_('Invoice')} - ${inv.number or ''|entity}
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
${_('Here is the BVR to allow you to pay the invoice %s - %s') % (inv.name or '', inv.number or '',)}
|
||||||
|
<br/>
|
||||||
|
${_('Regards')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div colspan="2" class="ocrbb">${mod10r('01'+str('%.2f' % inv.amount_total).replace('.','').rjust(10,'0'))}>${_get_ref(inv)}+${inv.partner_bank_id.post_number.split('-')[0]+(str(inv.partner_bank_id.post_number.split('-')[1])).rjust(6,'0')+inv.partner_bank_id.post_number.split('-')[2]}></div>
|
||||||
<div id="cont_${inv.id}" style="padding-left:20mm;padding-top:0;padding-bottom:10;height:180mm">
|
<div id="cont_${inv.id}" style="padding-left:20mm;padding-top:0;padding-bottom:10;height:180mm">
|
||||||
<!-- Your communication message here -->
|
<!-- Your communication message here -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -103,7 +146,7 @@
|
||||||
<tr style="height:8.4666667mm;vertical-align:bottom;padding-bottom:0"> <td><table style="width:100%" CELLPADDING="0" CELLSPACING="0"><td style="width:4mm"></td><td style="width:40mm;text-align: right" >${_space(('%.2f' % inv.amount_total)[:-3], 1)}</td><td style="width:6mm"></td><td style="width:10mm;text-align: right">${ _space(('%.2f' % inv.amount_total)[-2:], 1)}</td><td style="width:3mm;text-align: right"></td></table></td><td><table style="width:100%" CELLPADDING="0" CELLSPACING="0"><td style="width:4mm"></td><td style="width:40mm;text-align: right" >${_space(('%.2f' % inv.amount_total)[:-3], 1)}</td><td style="width:6mm"></td><td style="width:10mm;text-align: right">${ _space(('%.2f' % inv.amount_total)[-2:], 1)}</td><td style="width:3mm;text-align: right"></td></table></td><td></td></tr>
|
<tr style="height:8.4666667mm;vertical-align:bottom;padding-bottom:0"> <td><table style="width:100%" CELLPADDING="0" CELLSPACING="0"><td style="width:4mm"></td><td style="width:40mm;text-align: right" >${_space(('%.2f' % inv.amount_total)[:-3], 1)}</td><td style="width:6mm"></td><td style="width:10mm;text-align: right">${ _space(('%.2f' % inv.amount_total)[-2:], 1)}</td><td style="width:3mm;text-align: right"></td></table></td><td><table style="width:100%" CELLPADDING="0" CELLSPACING="0"><td style="width:4mm"></td><td style="width:40mm;text-align: right" >${_space(('%.2f' % inv.amount_total)[:-3], 1)}</td><td style="width:6mm"></td><td style="width:10mm;text-align: right">${ _space(('%.2f' % inv.amount_total)[-2:], 1)}</td><td style="width:3mm;text-align: right"></td></table></td><td></td></tr>
|
||||||
<tr style="height:21.166667mm"><td></td><td></td><td></td></tr>
|
<tr style="height:21.166667mm"><td></td><td></td><td></td></tr>
|
||||||
<tr style="height:8.4666667mm"> <td></td><td></td><td></td></tr>
|
<tr style="height:8.4666667mm"> <td></td><td></td><td></td></tr>
|
||||||
<tr style="height:21.166667mm;vertical-align:top"><td></td><td colspan="2" style="text-align:right;padding-right:0.3in;font-family:bvrocrb;font-size:12pt">${mod10r('01'+str('%.2f' % inv.amount_total).replace('.','').rjust(10,'0'))}>${_get_ref(inv)}+${inv.partner_bank_id.post_number.split('-')[0]+(str(inv.partner_bank_id.post_number.split('-')[1])).rjust(6,'0')+inv.partner_bank_id.post_number.split('-')[2]}></td></tr>
|
<tr style="height:21.166667mm;vertical-align:top"><td></td><td></td></tr>
|
||||||
</table>
|
</table>
|
||||||
%endfor
|
%endfor
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<% setLang(inv.partner_id.lang) %>
|
<% setLang(inv.partner_id.lang) %>
|
||||||
<div id="inv_cont_${inv.id}" style="padding-left:20mm;padding-top:0;padding-bottom:10;border-width:0px;border-style:solid">
|
<div id="inv_cont_${inv.id}" style="padding-left:20mm;padding-top:0;padding-bottom:10;border-width:0px;border-style:solid">
|
||||||
<table class="dest_address">
|
<table class="dest_address">
|
||||||
<tr><td ><b>${inv.partner_id.title or ''|entity} ${inv.partner_id.name |entity}</b></td></tr>
|
<tr><td ><b>${inv.partner_id.title.name or ''|entity} ${inv.partner_id.name |entity}</b></td></tr>
|
||||||
<tr><td>${inv.address_invoice_id.street or ''|entity}</td></tr>
|
<tr><td>${inv.address_invoice_id.street or ''|entity}</td></tr>
|
||||||
<tr><td>${inv.address_invoice_id.street2 or ''|entity}</td></tr>
|
<tr><td>${inv.address_invoice_id.street2 or ''|entity}</td></tr>
|
||||||
<tr><td>${inv.address_invoice_id.zip or ''|entity} ${inv.address_invoice_id.city or ''|entity}</td></tr>
|
<tr><td>${inv.address_invoice_id.zip or ''|entity} ${inv.address_invoice_id.city or ''|entity}</td></tr>
|
||||||
|
|
|
@ -33,7 +33,9 @@ import addons
|
||||||
import pooler
|
import pooler
|
||||||
from tools.config import config
|
from tools.config import config
|
||||||
from mako.template import Template
|
from mako.template import Template
|
||||||
|
from mako import exceptions
|
||||||
from tools.translate import _
|
from tools.translate import _
|
||||||
|
from osv.osv import except_osv
|
||||||
|
|
||||||
|
|
||||||
class l10n_ch_report_webkit_html(report_sxw.rml_parse):
|
class l10n_ch_report_webkit_html(report_sxw.rml_parse):
|
||||||
|
@ -41,16 +43,15 @@ class l10n_ch_report_webkit_html(report_sxw.rml_parse):
|
||||||
super(l10n_ch_report_webkit_html, self).__init__(cr, uid, name, context=context)
|
super(l10n_ch_report_webkit_html, self).__init__(cr, uid, name, context=context)
|
||||||
self.localcontext.update({
|
self.localcontext.update({
|
||||||
'time': time,
|
'time': time,
|
||||||
'cr':cr,
|
'cr': cr,
|
||||||
'uid': uid,
|
'uid': uid,
|
||||||
'user':self.pool.get("res.users").browse(cr, uid, uid),
|
'user':self.pool.get("res.users").browse(cr, uid, uid),
|
||||||
'mod10r': mod10r,
|
'mod10r': mod10r,
|
||||||
'_space': self._space,
|
'_space': self._space,
|
||||||
'_get_ref': self._get_ref,
|
'_get_ref': self._get_ref,
|
||||||
'comma_me': self.comma_me,
|
'comma_me': self.comma_me,
|
||||||
'police_absolute_path' : self.police_absolute_path,
|
'police_absolute_path': self.police_absolute_path,
|
||||||
'bvr_absolute_path':self.bvr_absolute_path,
|
'bvr_absolute_path': self.bvr_absolute_path,
|
||||||
'_check' : self._check,
|
|
||||||
'headheight': self.headheight
|
'headheight': self.headheight
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -59,14 +60,21 @@ class l10n_ch_report_webkit_html(report_sxw.rml_parse):
|
||||||
_compile_check_bvr = re.compile('[0-9][0-9]-[0-9]{3,6}-[0-9]')
|
_compile_check_bvr = re.compile('[0-9][0-9]-[0-9]{3,6}-[0-9]')
|
||||||
_compile_check_bvr_add_num = re.compile('[0-9]*$')
|
_compile_check_bvr_add_num = re.compile('[0-9]*$')
|
||||||
|
|
||||||
|
def set_context(self, objects, data, ids, report_type=None):
|
||||||
|
user = self.pool.get('res.users').browse(self.cr, self.uid, self.uid)
|
||||||
|
company = user.company_id
|
||||||
|
if not company.invoice_only:
|
||||||
|
self._check(ids)
|
||||||
|
return super(l10n_ch_report_webkit_html, self).set_context(objects, data, ids, report_type=report_type)
|
||||||
|
|
||||||
def police_absolute_path(self, inner_path) :
|
def police_absolute_path(self, inner_path) :
|
||||||
"""Will get the ocrb police absolute path"""
|
"""Will get the ocrb police absolute path"""
|
||||||
path = addons.get_module_resource(os.path.join('l10n_ch','report',inner_path))
|
path = addons.get_module_resource(os.path.join('l10n_ch', 'report', inner_path))
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def bvr_absolute_path(self) :
|
def bvr_absolute_path(self) :
|
||||||
"""Will get the ocrb police absolute path"""
|
"""Will get the ocrb police absolute path"""
|
||||||
path = addons.get_module_resource(os.path.join('l10n_ch','report','bvr1.jpg'))
|
path = addons.get_module_resource(os.path.join('l10n_ch', 'report', 'bvr1.jpg'))
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def headheight(self):
|
def headheight(self):
|
||||||
|
@ -76,7 +84,7 @@ class l10n_ch_report_webkit_html(report_sxw.rml_parse):
|
||||||
|
|
||||||
def comma_me(self, amount):
|
def comma_me(self, amount):
|
||||||
"""Fast swiss number formatting"""
|
"""Fast swiss number formatting"""
|
||||||
if type(amount) is float :
|
if isinstance(amount, float):
|
||||||
amount = str('%.2f'%amount)
|
amount = str('%.2f'%amount)
|
||||||
else :
|
else :
|
||||||
amount = str(amount)
|
amount = str(amount)
|
||||||
|
@ -88,13 +96,14 @@ class l10n_ch_report_webkit_html(report_sxw.rml_parse):
|
||||||
return self.comma_me(new)
|
return self.comma_me(new)
|
||||||
|
|
||||||
def _space(self, nbr, nbrspc=5):
|
def _space(self, nbr, nbrspc=5):
|
||||||
"""Spaces * 5"""
|
"""Spaces * 5.
|
||||||
res = ''
|
|
||||||
for i in range(len(nbr)):
|
Example:
|
||||||
res = res + nbr[i]
|
>>> self._space('123456789012345')
|
||||||
if not (i-1) % nbrspc:
|
'12 34567 89012 345'
|
||||||
res = res + ' '
|
"""
|
||||||
return res
|
return ''.join([' '[(i - 2) % nbrspc:] + c for i, c in enumerate(nbr)])
|
||||||
|
|
||||||
|
|
||||||
def _get_ref(self, inv):
|
def _get_ref(self, inv):
|
||||||
"""Retrieve ESR/BVR reference form invoice in order to print it"""
|
"""Retrieve ESR/BVR reference form invoice in order to print it"""
|
||||||
|
@ -106,22 +115,24 @@ class l10n_ch_report_webkit_html(report_sxw.rml_parse):
|
||||||
invoice_number = self._compile_get_ref.sub('', inv.number)
|
invoice_number = self._compile_get_ref.sub('', inv.number)
|
||||||
return mod10r(res + invoice_number.rjust(26-len(res), '0'))
|
return mod10r(res + invoice_number.rjust(26-len(res), '0'))
|
||||||
|
|
||||||
def _check(self, invoices):
|
def _check(self, invoice_ids):
|
||||||
"""Check if the invoice is ready to be printed"""
|
"""Check if the invoice is ready to be printed"""
|
||||||
|
if not invoice_ids:
|
||||||
|
invoice_ids = []
|
||||||
cursor = self.cr
|
cursor = self.cr
|
||||||
pool = self.pool
|
pool = self.pool
|
||||||
invoice_obj = pool.get('account.invoice')
|
invoice_obj = pool.get('account.invoice')
|
||||||
ids = [x.id for x in invoices]
|
ids = invoice_ids
|
||||||
for invoice in invoice_obj.browse(cursor, self.uid, ids):
|
for invoice in invoice_obj.browse(cursor, self.uid, ids):
|
||||||
if not invoice.partner_bank_id:
|
if not invoice.partner_bank_id:
|
||||||
raise wizard.except_wizard(_('UserError'),
|
raise except_osv(_('UserError'),
|
||||||
_('No bank specified on invoice:\n' + \
|
_('No bank specified on invoice:\n' + \
|
||||||
invoice_obj.name_get(cursor, self.uid, [invoice.id],
|
invoice_obj.name_get(cursor, self.uid, [invoice.id],
|
||||||
context={})[0][1]))
|
context={})[0][1]))
|
||||||
if not self._compile_check_bvr.match(
|
if not self._compile_check_bvr.match(
|
||||||
invoice.partner_bank_id.post_number or ''):
|
invoice.partner_bank_id.post_number or ''):
|
||||||
raise wizard.except_wizard(_('UserError'),
|
raise except_osv(_('UserError'),
|
||||||
_("Your bank BVR number should be of the form 0X-XXX-X! " +
|
_('Your bank BVR number should be of the form 0X-XXX-X! ' +
|
||||||
'Please check your company ' +
|
'Please check your company ' +
|
||||||
'information for the invoice:\n' +
|
'information for the invoice:\n' +
|
||||||
invoice_obj.name_get(cursor, self.uid, [invoice.id],
|
invoice_obj.name_get(cursor, self.uid, [invoice.id],
|
||||||
|
@ -129,16 +140,52 @@ class l10n_ch_report_webkit_html(report_sxw.rml_parse):
|
||||||
if invoice.partner_bank_id.bvr_adherent_num \
|
if invoice.partner_bank_id.bvr_adherent_num \
|
||||||
and not self._compile_check_bvr_add_num.match(
|
and not self._compile_check_bvr_add_num.match(
|
||||||
invoice.partner_bank_id.bvr_adherent_num):
|
invoice.partner_bank_id.bvr_adherent_num):
|
||||||
raise wizard.except_wizard('UserError',
|
raise except_osv(_('UserError'),
|
||||||
'Your bank BVR adherent number must contain exactly seven' +
|
_('Your bank BVR adherent number must contain exactly seven' +
|
||||||
'digits!\nPlease check your company ' +
|
'digits!\nPlease check your company ' +
|
||||||
'information for the invoice:\n' +
|
'information for the invoice:\n' +
|
||||||
invoice_obj.name_get(cursor, self.uid, [invoice.id],
|
invoice_obj.name_get(cursor, self.uid, [invoice.id],
|
||||||
context={})[0][1])
|
context={})[0][1]))
|
||||||
return ""
|
return ''
|
||||||
|
|
||||||
class BVRWebKitParser(webkit_report.WebKitParser):
|
class BVRWebKitParser(webkit_report.WebKitParser):
|
||||||
|
|
||||||
|
def setLang(self, lang):
|
||||||
|
if not lang:
|
||||||
|
lang = 'en_US'
|
||||||
|
self.localcontext['lang'] = lang
|
||||||
|
|
||||||
|
def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False):
|
||||||
|
"""format using the know cursor, language from localcontext"""
|
||||||
|
if digits is None:
|
||||||
|
digits = self.parser_instance.get_digits(value)
|
||||||
|
if isinstance(value, (str, unicode)) and not value:
|
||||||
|
return ''
|
||||||
|
pool_lang = self.pool.get('res.lang')
|
||||||
|
lang = self.localcontext['lang']
|
||||||
|
|
||||||
|
lang_ids = pool_lang.search(self.parser_instance.cr, self.parser_instance.uid, [('code','=',lang)])[0]
|
||||||
|
lang_obj = pool_lang.browse(self.parser_instance.cr, self.parser_instance.uid, lang_ids)
|
||||||
|
|
||||||
|
if date or date_time:
|
||||||
|
if not str(value):
|
||||||
|
return ''
|
||||||
|
|
||||||
|
date_format = lang_obj.date_format
|
||||||
|
parse_format = '%Y-%m-%d'
|
||||||
|
if date_time:
|
||||||
|
value=value.split('.')[0]
|
||||||
|
date_format = date_format + " " + lang_obj.time_format
|
||||||
|
parse_format = '%Y-%m-%d %H:%M:%S'
|
||||||
|
if not isinstance(value, time.struct_time):
|
||||||
|
return time.strftime(date_format, time.strptime(value, parse_format))
|
||||||
|
|
||||||
|
else:
|
||||||
|
date = datetime(*value.timetuple()[:6])
|
||||||
|
return date.strftime(date_format)
|
||||||
|
|
||||||
|
return lang_obj.format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
|
||||||
|
|
||||||
def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
|
def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
|
||||||
"""generate the PDF"""
|
"""generate the PDF"""
|
||||||
self.parser_instance = self.parser(
|
self.parser_instance = self.parser(
|
||||||
|
@ -190,74 +237,81 @@ class BVRWebKitParser(webkit_report.WebKitParser):
|
||||||
<body style="border:0; margin: 0;" onload="subst()">
|
<body style="border:0; margin: 0;" onload="subst()">
|
||||||
</body>
|
</body>
|
||||||
</html>"""
|
</html>"""
|
||||||
|
self.parser_instance.localcontext.update({'setLang':self.setLang})
|
||||||
|
self.parser_instance.localcontext.update({'formatLang':self.formatLang})
|
||||||
css = report_xml.webkit_header.css
|
css = report_xml.webkit_header.css
|
||||||
if not css :
|
if not css :
|
||||||
css = ''
|
css = ''
|
||||||
user = self.pool.get('res.users').browse(cursor, uid, uid)
|
user = self.pool.get('res.users').browse(cursor, uid, uid)
|
||||||
company= user.company_id
|
company = user.company_id
|
||||||
parse_template = template
|
parse_template = template
|
||||||
#default_filters=['unicode', 'entity'] can be used to set global filter
|
#default_filters=['unicode', 'entity'] can be used to set global filter
|
||||||
body_mako_tpl = Template(parse_template ,input_encoding='utf-8')
|
body_mako_tpl = Template(parse_template ,input_encoding='utf-8', output_encoding='utf-8')
|
||||||
#BVR specific
|
#BVR specific
|
||||||
bvr_path = addons.get_module_resource(os.path.join('l10n_ch','report','bvr.mako'))
|
bvr_path = addons.get_module_resource(os.path.join('l10n_ch','report','bvr.mako'))
|
||||||
body_bvr_tpl = Template(file(bvr_path).read(), input_encoding='utf-8')
|
body_bvr_tpl = Template(file(bvr_path).read(), input_encoding='utf-8', output_encoding='utf-8')
|
||||||
|
|
||||||
helper = report_helper.WebKitHelper(cursor, uid, report_xml.id, context)
|
helper = report_helper.WebKitHelper(cursor, uid, report_xml.id, context)
|
||||||
##BVR Specific
|
##BVR Specific
|
||||||
htmls = []
|
htmls = []
|
||||||
for obj in objs :
|
for obj in objs :
|
||||||
|
|
||||||
self.parser_instance.localcontext['objects'] = [obj]
|
self.parser_instance.localcontext['objects'] = [obj]
|
||||||
if not company.bvr_only:
|
if not company.bvr_only:
|
||||||
|
try:
|
||||||
html = body_mako_tpl.render(
|
html = body_mako_tpl.render(
|
||||||
helper=helper,
|
helper=helper,
|
||||||
css=css,
|
css=css,
|
||||||
_=self.translate_call,
|
_=self.translate_call,
|
||||||
**self.parser_instance.localcontext
|
**self.parser_instance.localcontext
|
||||||
)
|
)
|
||||||
|
except Exception, e:
|
||||||
|
raise Exception(exceptions.text_error_template().render())
|
||||||
htmls.append(html)
|
htmls.append(html)
|
||||||
if not company.invoice_only:
|
if not company.invoice_only:
|
||||||
|
try:
|
||||||
bvr = body_bvr_tpl.render(
|
bvr = body_bvr_tpl.render(
|
||||||
helper=helper,
|
helper=helper,
|
||||||
css=css,
|
css=css,
|
||||||
_=self.translate_call,
|
_=self.translate_call,
|
||||||
**self.parser_instance.localcontext
|
**self.parser_instance.localcontext
|
||||||
)
|
)
|
||||||
|
except Exception, e:
|
||||||
|
raise Exception(exceptions.text_error_template().render())
|
||||||
htmls.append(bvr)
|
htmls.append(bvr)
|
||||||
head_mako_tpl = Template(header, input_encoding='utf-8')
|
head_mako_tpl = Template(header, input_encoding='utf-8', output_encoding='utf-8')
|
||||||
|
try:
|
||||||
head = head_mako_tpl.render(
|
head = head_mako_tpl.render(
|
||||||
company=company,
|
|
||||||
time=time,
|
|
||||||
helper=helper,
|
helper=helper,
|
||||||
css=css,
|
css=css,
|
||||||
formatLang=self.parser_instance.formatLang,
|
_debug=False,
|
||||||
setLang=self.parser_instance.setLang,
|
_=self.translate_call,
|
||||||
_debug=False
|
**self.parser_instance.localcontext
|
||||||
)
|
)
|
||||||
|
except Exception, e:
|
||||||
|
raise Exception(exceptions.text_error_template().render())
|
||||||
foot = False
|
foot = False
|
||||||
if footer and company.invoice_only :
|
if footer and company.invoice_only :
|
||||||
foot_mako_tpl = Template(footer ,input_encoding='utf-8')
|
foot_mako_tpl = Template(footer, input_encoding='utf-8', output_encoding='utf-8')
|
||||||
|
try:
|
||||||
foot = foot_mako_tpl.render(
|
foot = foot_mako_tpl.render(
|
||||||
company=company,
|
|
||||||
time=time,
|
|
||||||
helper=helper,
|
helper=helper,
|
||||||
css=css,
|
css=css,
|
||||||
formatLang=self.parser_instance.formatLang,
|
|
||||||
setLang=self.parser_instance.setLang,
|
|
||||||
_=self.translate_call,
|
_=self.translate_call,
|
||||||
|
**self.parser_instance.localcontext
|
||||||
)
|
)
|
||||||
|
except Exception, e:
|
||||||
|
raise Exception(exceptions.text_error_template().render())
|
||||||
if report_xml.webkit_debug :
|
if report_xml.webkit_debug :
|
||||||
|
try:
|
||||||
deb = head_mako_tpl.render(
|
deb = head_mako_tpl.render(
|
||||||
company=company,
|
|
||||||
time=time,
|
|
||||||
helper=helper,
|
helper=helper,
|
||||||
css=css,
|
css=css,
|
||||||
_debug=html,
|
_debug=html,
|
||||||
formatLang=self.parser_instance.formatLang,
|
|
||||||
setLang=self.parser_instance.setLang,
|
|
||||||
_=self.translate_call,
|
_=self.translate_call,
|
||||||
|
**self.parser_instance.localcontext
|
||||||
)
|
)
|
||||||
|
except Exception, e:
|
||||||
|
raise Exception(exceptions.text_error_template().render())
|
||||||
return (deb, 'html')
|
return (deb, 'html')
|
||||||
bin = self.get_lib(cursor, uid, company.id)
|
bin = self.get_lib(cursor, uid, company.id)
|
||||||
pdf = self.generate_pdf(bin, report_xml, head, foot, htmls)
|
pdf = self.generate_pdf(bin, report_xml, head, foot, htmls)
|
||||||
|
|
|
@ -22,38 +22,40 @@
|
||||||
${css}
|
${css}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
<!-- <tr style="vertical-align:top">
|
||||||
|
<td style="text-align:right;font-size:12" ><span class="page"/></td><td style="text-align:left;font-size:12;"> / <span class="topage"/></td>
|
||||||
|
</tr> style="text-align:right"-->
|
||||||
<body style="border:0; margin: 0;" onload="subst()">
|
<body style="border:0; margin: 0;" onload="subst()">
|
||||||
<table class="header" style="border-bottom: 0px solid black; width: 100%;padding-left:20mm">
|
<table style="border-bottom: 1px solid black; width: 90%;padding-left:0mm;margin-left:5%">
|
||||||
<tr style="vertical-align:top" >
|
<tr style="vertical-align:top" >
|
||||||
<td>${helper.embed_logo_by_name('camptocamp_logo', width=64)}</td>
|
<td>${helper.embed_logo_by_name('camptocamp_logo', width=128)}</td>
|
||||||
<td style="text-align:right">
|
<td >
|
||||||
<table style="border-top: 0px solid black; width: 100%;height:100%">
|
|
||||||
<tr style="vertical-align:top">
|
<table style="border-top: 0px solid black; width: 100%;height:100%;;padding-left:4mm; margin-left:2%" class="dest_address">
|
||||||
<td style="text-align:right;font-size:12" width="80%"><span class="page"/></td><td style="text-align:left;font-size:12;"> / <span class="topage"/></td>
|
<tr>
|
||||||
</tr>
|
<td><b>${company.partner_id.name |entity}</b></td><td></td><td></td>
|
||||||
</table> </td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><br/></td>
|
<td>${company.partner_id.address and company.partner_id.address[0].street or ''|entity}</td><td>${_("phone")}:</td><td>${company.partner_id.address and company.partner_id.address[0].phone or ''|entity} </td><td></td>
|
||||||
<td style="text-align:right"> </td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>${company.partner_id.name |entity}</td>
|
<td>${company.partner_id.address and company.partner_id.address[0].street2 or ''|entity}</td><td>${_('Fax')}:</td><td>${company.partner_id.address and company.partner_id.address[0].fax or ''|entity} </td><td></td>
|
||||||
<td/>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td >${company.partner_id.address and company.partner_id.address[0].street or ''|entity}</td>
|
<td>${company.partner_id.address and company.partner_id.address[0].zip or ''|entity} ${company.partner_id.address and company.partner_id.address[0].city or ''|entity}</td><td>${_('e-mail')}:</td><td><a href="mailto:${company.partner_id.address and company.partner_id.address[0].email or ''|entity}">${company.partner_id.address and company.partner_id.address[0].email or ''|entity}</a></td><td></td>
|
||||||
<td/>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Phone: ${company.partner_id.address and company.partner_id.address[0].phone or ''|entity} </td>
|
<td>${company.partner_id.address and company.partner_id.address[0].country_id.name or ''|entity}</td><td></td><td style="text-align:right;font-size:12" ><span class="page"/></td><td style="text-align:left;font-size:12;"> / <span class="topage"/></td>
|
||||||
<td/>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
</table>
|
||||||
<td>Mail: <a href="mailto:${company.partner_id.address and company.partner_id.address[0].email or ''|entity}">${company.partner_id.address and company.partner_id.address[0].email or ''|entity}</a><br/></td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table> ${_debug or ''} <br/></body>
|
</table>
|
||||||
</html>]]>
|
<br/>
|
||||||
|
${_debug or ''}
|
||||||
|
<br/>
|
||||||
|
</body>
|
||||||
|
</html>]]>
|
||||||
</field>
|
</field>
|
||||||
<field eval="45" name="margin_top"/>
|
<field eval="45" name="margin_top"/>
|
||||||
<field eval="0.01" name="margin_bottom"/>
|
<field eval="0.01" name="margin_bottom"/>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data noupdate="1">
|
||||||
<!-- Fiscal Position Templates -->
|
<!-- Fiscal Position Templates -->
|
||||||
|
|
||||||
<record id="fiscal_position_template_import" model="account.fiscal.position.template">
|
<record id="fiscal_position_template_import" model="account.fiscal.position.template">
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
-
|
||||||
|
In order to test DTA generation I make an invoice and create the DTA from it.
|
||||||
|
-
|
||||||
|
I create an invoice on 1st January for 7000 EUR
|
||||||
|
###########################
|
||||||
|
# Creating 1 invoice #
|
||||||
|
###########################
|
||||||
|
-
|
||||||
|
!record {model: account.invoice, id: dta_account_invoice}:
|
||||||
|
company_id: base.main_company
|
||||||
|
journal_id: account.bank_journal
|
||||||
|
currency_id: base.EUR
|
||||||
|
account_id: account.a_pay
|
||||||
|
type : in_invoice
|
||||||
|
partner_id: base.res_partner_agrolait
|
||||||
|
address_contact_id: base.res_partner_address_8
|
||||||
|
address_invoice_id: base.res_partner_address_8
|
||||||
|
reference_type: bvr
|
||||||
|
reference: 111111111111111111111111111111
|
||||||
|
date_invoice: !eval "'%s-01-01' %(datetime.now().year)"
|
||||||
|
period_id: account.period_1
|
||||||
|
#invoice_line:
|
||||||
|
partner_bank_id: main_partner_bank
|
||||||
|
check_total : 7000
|
||||||
|
-
|
||||||
|
I add an invoice line
|
||||||
|
-
|
||||||
|
!record {model: account.invoice.line, id: dta_invoice_line}:
|
||||||
|
account_id: account.a_expense
|
||||||
|
name: '[PC1] Basic PC'
|
||||||
|
price_unit: 700.0
|
||||||
|
quantity: 10.0
|
||||||
|
product_id: product.product_product_pc1
|
||||||
|
uos_id: product.product_uom_unit
|
||||||
|
invoice_id: dta_account_invoice
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I Validate invoice by clicking on Validate button
|
||||||
|
-
|
||||||
|
!workflow {model: account.invoice, action: invoice_open, ref: dta_account_invoice}
|
||||||
|
|
||||||
|
-
|
||||||
|
I create my payment order to pay my invoice
|
||||||
|
###########################
|
||||||
|
# Doing payment order #
|
||||||
|
###########################
|
||||||
|
-
|
||||||
|
!record {model: payment.order, id: dta_payment_order}:
|
||||||
|
#date_created
|
||||||
|
#date_done
|
||||||
|
date_prefered: due
|
||||||
|
#date_scheduled
|
||||||
|
#line_ids:
|
||||||
|
mode: l10n_ch.payment_mode_dta
|
||||||
|
#reference
|
||||||
|
state: draft
|
||||||
|
total: 7000
|
||||||
|
#user_id
|
||||||
|
-
|
||||||
|
I add a payment line to my payment order
|
||||||
|
-
|
||||||
|
!record {model: payment.line, id: dta_pay_line}:
|
||||||
|
amount: 7000
|
||||||
|
amount_currency: 7000
|
||||||
|
bank_id: l10n_ch.agro_bank
|
||||||
|
#bank_statement_line_id
|
||||||
|
communication: "111111111111111111111111111111"
|
||||||
|
#communication2
|
||||||
|
company_currency: base.EUR
|
||||||
|
#create_date
|
||||||
|
currency: base.EUR
|
||||||
|
#date
|
||||||
|
#info_owner
|
||||||
|
#info_partner
|
||||||
|
#ml_date_created
|
||||||
|
#ml_inv_ref
|
||||||
|
#ml_maturity_date
|
||||||
|
move_line_id: !ref {model: account.move.line, search: "[('ref','=','111111111111111111111111111111')]"}
|
||||||
|
#name (reference)
|
||||||
|
order_id: dta_payment_order
|
||||||
|
partner_id: base.res_partner_agrolait
|
||||||
|
state: normal
|
||||||
|
|
||||||
|
-
|
||||||
|
I generate a DTA file by using the wizard "Create DTA" for my payment order
|
||||||
|
-
|
||||||
|
!python {model: create.dta.wizard}: |
|
||||||
|
import base64
|
||||||
|
wiz_id = self.create(cr,uid,[])
|
||||||
|
wiz = self.browse(cr, uid, wiz_id)
|
||||||
|
pay_order_id = ref("dta_payment_order")
|
||||||
|
#set the payment order as the active id
|
||||||
|
context['active_ids'] = [pay_order_id]
|
||||||
|
context['active_id'] = pay_order_id
|
||||||
|
result = wiz.create_dta(context=context)
|
||||||
|
assert result, "No result returned"
|
||||||
|
|
||||||
|
data = wiz.read(['dta_file'])
|
||||||
|
dta_file = base64.decodestring(data[0]['dta_file'] or '')
|
||||||
|
assert dta_file, "File is empty"
|
||||||
|
|
||||||
|
#check that file starts with 1st segment characters "01"
|
||||||
|
assert dta_file[:2] == "01", "File is not a DTA file"
|
||||||
|
|
||||||
|
payment_obj = self.pool.get('payment.order')
|
||||||
|
payment_obj.set_done(cr, uid, [ref('dta_payment_order')], context)
|
||||||
|
#force state in open state (confirmed)
|
||||||
|
payment_obj.write(cr, uid, [ref('dta_payment_order')], {'state': 'open'})
|
||||||
|
|
||||||
|
-
|
||||||
|
I check the execution date is today
|
||||||
|
-
|
||||||
|
!assert {model: payment.order, id: dta_payment_order}:
|
||||||
|
- date_done == datetime.now().date().strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
-
|
||||||
|
I check my payment order state is Confirmed
|
||||||
|
-
|
||||||
|
!assert {model: payment.order, id: dta_payment_order, string: state is done}:
|
||||||
|
- state == 'open'
|
||||||
|
|
||||||
|
-
|
||||||
|
I create a Bank Statment in order to confirm the payment line
|
||||||
|
-
|
||||||
|
!record {model: account.bank.statement, id: dta_bank_statement}:
|
||||||
|
#account_id:
|
||||||
|
#balance_end:
|
||||||
|
#balance_end_cash:
|
||||||
|
#balance_end_real:
|
||||||
|
#balance_start:
|
||||||
|
#closing_date:
|
||||||
|
#company_id:
|
||||||
|
#currency:
|
||||||
|
date: !eval "'%s-01-01' %(datetime.now().year)"
|
||||||
|
#ending_details_ids:
|
||||||
|
journal_id: account.bank_journal
|
||||||
|
#line_ids:
|
||||||
|
#move_line_ids
|
||||||
|
name: "/"
|
||||||
|
period_id: account.period_1
|
||||||
|
#starting_details_ids
|
||||||
|
state: draft
|
||||||
|
#total_entry_encoding
|
||||||
|
#user_id
|
||||||
|
|
||||||
|
-
|
||||||
|
I import the payment line
|
||||||
|
-
|
||||||
|
!python {model: account.payment.populate.statement}: |
|
||||||
|
wiz_id = self.create(cr,uid,[])
|
||||||
|
wiz = self.browse(cr, uid, wiz_id)
|
||||||
|
|
||||||
|
line_obj = self.pool.get('payment.line')
|
||||||
|
pay_line_ids = line_obj.search(cr, uid, [('communication','=','111111111111111111111111111111'),('amount','=','7000')])
|
||||||
|
|
||||||
|
data = { 'lines': [(6, 0, [pay_line_ids[0]])],}
|
||||||
|
wiz.write(data)
|
||||||
|
|
||||||
|
context['active_id'] = ref('dta_bank_statement')
|
||||||
|
context['active_ids'] = [ref('dta_bank_statement')]
|
||||||
|
|
||||||
|
self.populate_statement(cr, uid, [wiz_id], context=context)
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I check the statement line is created
|
||||||
|
-
|
||||||
|
!assert {model: account.bank.statement, id: dta_bank_statement, string: statement_line_ids is not empty}:
|
||||||
|
- line_ids
|
||||||
|
|
||||||
|
-
|
||||||
|
I check the voucher line is created
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('dta_bank_statement'))
|
||||||
|
|
||||||
|
assert statement.line_ids[0].voucher_id.line_ids, "Voucher line is missing"
|
||||||
|
assert len(statement.line_ids[0].voucher_id.line_ids) == 1, "There are too many voucher lines"
|
||||||
|
|
||||||
|
-
|
||||||
|
In order to confirm my bank statement, I enter the closing balance and press on compute button
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('dta_bank_statement'))
|
||||||
|
statement.write({'balance_end_real': -7000.0})
|
||||||
|
self.button_dummy(cr, uid, [ref('dta_bank_statement')], context=context)
|
||||||
|
statement = self.browse(cr, uid, ref('dta_bank_statement'))
|
||||||
|
|
||||||
|
-
|
||||||
|
I confirm my bank statement
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
self.button_confirm_bank(cr, uid, [ref('dta_bank_statement')], context=context)
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I check the move lines have been defined
|
||||||
|
-
|
||||||
|
!assert {model: account.bank.statement, id: dta_bank_statement, string: move_line_ids is not empty}:
|
||||||
|
- move_line_ids
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I check bank statement is Closed and balance is -7000
|
||||||
|
-
|
||||||
|
!assert {model: account.bank.statement, id: dta_bank_statement, string: state is Closed and balance is -7000}:
|
||||||
|
- state == 'confirm'
|
||||||
|
- balance_end == -7000.0
|
||||||
|
|
||||||
|
-
|
||||||
|
I check the residual amount of invoice, should be 0 in residual currency and 0 in amount_residual and paid
|
||||||
|
-
|
||||||
|
!python {model: account.invoice}: |
|
||||||
|
invoice_id = self.browse(cr, uid, ref("dta_account_invoice"))
|
||||||
|
move_line_obj = self.pool.get('account.move.line')
|
||||||
|
move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
|
||||||
|
move_line = move_line_obj.browse(cr, uid, move_lines[0])
|
||||||
|
assert move_line.amount_residual_currency == 0.0, "Residual amount currency is not correct : %.2f" % move_line.amount_residual_currency
|
||||||
|
assert move_line.amount_residual == 0.0 , "Residual amount of invoice is not correct : %.2f" % move_line.amount_residual
|
||||||
|
assert invoice_id.state == 'paid', "Invoice state is not Paid"
|
|
@ -1,5 +1,5 @@
|
||||||
-
|
-
|
||||||
In order to test BVR printing. I create Partner data.
|
In order to test BVR printing. I create Partner data .
|
||||||
-
|
-
|
||||||
!record {model: res.partner.category, id: res_partner_category_bvr}:
|
!record {model: res.partner.category, id: res_partner_category_bvr}:
|
||||||
name: Customers
|
name: Customers
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
-
|
||||||
|
In order to test the V11 import,
|
||||||
|
I will create an invoice with a specified reference that I will reconcile with the moves imported from a V11
|
||||||
|
-
|
||||||
|
I create an invoice ref 1234567
|
||||||
|
-
|
||||||
|
!record {model: account.invoice, id: v11_test_invoice}:
|
||||||
|
name: V11 YAML invoice
|
||||||
|
number: 1234567
|
||||||
|
company_id: base.main_company
|
||||||
|
journal_id: account.bank_journal
|
||||||
|
currency_id: base.EUR
|
||||||
|
account_id: account.a_recv
|
||||||
|
type : out_invoice
|
||||||
|
partner_id: base.res_partner_agrolait
|
||||||
|
address_contact_id: base.res_partner_address_8
|
||||||
|
address_invoice_id: base.res_partner_address_8
|
||||||
|
reference_type: bvr
|
||||||
|
reference: 12345676
|
||||||
|
date_invoice: !eval "'%s-01-01' %(datetime.now().year)"
|
||||||
|
period_id: account.period_1
|
||||||
|
#invoice_line:
|
||||||
|
partner_bank_id: main_partner_bank
|
||||||
|
check_total : 888.00
|
||||||
|
|
||||||
|
-
|
||||||
|
I create an invoice line
|
||||||
|
-
|
||||||
|
!record {model: account.invoice.line, id: v11_test_invoice_line}:
|
||||||
|
account_id: account.a_expense
|
||||||
|
name: '[PC1] Basic PC'
|
||||||
|
price_unit: 888.00
|
||||||
|
quantity: 1.0
|
||||||
|
product_id: product.product_product_pc1
|
||||||
|
uos_id: product.product_uom_unit
|
||||||
|
invoice_id: v11_test_invoice
|
||||||
|
|
||||||
|
-
|
||||||
|
I Validate invoice by clicking on Validate button
|
||||||
|
-
|
||||||
|
!workflow {model: account.invoice, action: invoice_open, ref: v11_test_invoice}
|
||||||
|
|
||||||
|
-
|
||||||
|
I specify the invoice number to fit with my v11
|
||||||
|
-
|
||||||
|
!python {model: account.invoice}: |
|
||||||
|
invoice = self.browse(cr, uid, ref('v11_test_invoice'))
|
||||||
|
invoice.write({'number': 1234567})
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I create a bank statement
|
||||||
|
-
|
||||||
|
!record {model: account.bank.statement, id: v11_test_bank_statement}:
|
||||||
|
#account_id:
|
||||||
|
#balance_end:
|
||||||
|
#balance_end_cash:
|
||||||
|
#balance_end_real:
|
||||||
|
#balance_start:
|
||||||
|
#closing_date:
|
||||||
|
#company_id:
|
||||||
|
#currency:
|
||||||
|
date: !eval "'%s-01-01' %(datetime.now().year)"
|
||||||
|
#ending_details_ids:
|
||||||
|
journal_id: account.bank_journal
|
||||||
|
#line_ids:
|
||||||
|
#move_line_ids
|
||||||
|
name: "/"
|
||||||
|
period_id: account.period_1
|
||||||
|
#starting_details_ids
|
||||||
|
state: draft
|
||||||
|
#total_entry_encoding
|
||||||
|
#user_id
|
||||||
|
|
||||||
|
-
|
||||||
|
I import the V11
|
||||||
|
-
|
||||||
|
!python {model: bvr.import.wizard}: |
|
||||||
|
import base64
|
||||||
|
import addons
|
||||||
|
import os
|
||||||
|
|
||||||
|
# create our wizard
|
||||||
|
wiz_id = self.create(cr,uid,[])
|
||||||
|
wiz = self.browse(cr, uid, wiz_id)
|
||||||
|
|
||||||
|
test_file_path = addons.get_module_resource(os.path.join('l10n_ch', 'test', 'test.v11'))
|
||||||
|
|
||||||
|
# get our test file to test it
|
||||||
|
f_v11 = open(test_file_path)
|
||||||
|
|
||||||
|
str64_v11 = base64.encodestring(f_v11.read())
|
||||||
|
|
||||||
|
wiz.write({'file': str64_v11})
|
||||||
|
|
||||||
|
# set the file in the wizard field
|
||||||
|
bank_statement_id = ref('v11_test_bank_statement')
|
||||||
|
|
||||||
|
context['active_id'] = bank_statement_id
|
||||||
|
context['active_ids'] = [bank_statement_id]
|
||||||
|
# launch the import
|
||||||
|
self.import_bvr(cr, uid, [wiz_id], context=context)
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I check my bank statement got a statement line
|
||||||
|
-
|
||||||
|
!assert {model: account.bank.statement, id: v11_test_bank_statement, string: statement has 1 and only 1 statement line id}:
|
||||||
|
- len(line_ids) == 1
|
||||||
|
|
||||||
|
-
|
||||||
|
I check the voucher linked to the statement line contains a line with an amount of 888.00
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('v11_test_bank_statement'))
|
||||||
|
|
||||||
|
voucher_line_ids = statement.line_ids[0].voucher_id.line_ids
|
||||||
|
|
||||||
|
assert voucher_line_ids, "No voucher line found"
|
||||||
|
|
||||||
|
voucher_line_amount = voucher_line_ids[0].amount
|
||||||
|
assert voucher_line_amount == 888.00, "Amount isn't correct : %d" %(voucher_line_amount)
|
||||||
|
|
||||||
|
-
|
||||||
|
I check amount of account voucher is equal to the bank statement line amount
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('v11_test_bank_statement'))
|
||||||
|
|
||||||
|
statement_line_amount = statement.line_ids[0].amount
|
||||||
|
voucher_amount = statement.line_ids[0].voucher_id.amount
|
||||||
|
|
||||||
|
assert statement_line_amount == voucher_amount, "Mismatch of amounts"
|
||||||
|
|
||||||
|
-
|
||||||
|
I enter the closing balance and press on compute button
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('v11_test_bank_statement'))
|
||||||
|
statement.write({'balance_end_real': 888.00})
|
||||||
|
self.button_dummy(cr, uid, [ref('v11_test_bank_statement')], context=context)
|
||||||
|
|
||||||
|
-
|
||||||
|
I check that the statement Balance is 888.00
|
||||||
|
-
|
||||||
|
!assert {model: account.bank.statement, id: v11_test_bank_statement, string: balance is 888.0}:
|
||||||
|
- balance_end == 888.0
|
||||||
|
|
||||||
|
-
|
||||||
|
I confirm my bank statement
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
self.button_confirm_bank(cr, uid, [ref('v11_test_bank_statement')], context=context)
|
||||||
|
|
||||||
|
-
|
||||||
|
I check my invoice is paid, reconciled and has no residual
|
||||||
|
-
|
||||||
|
!assert {model: account.invoice, id: v11_test_invoice, string: 'invoice is paid, reconciled and has no residual'}:
|
||||||
|
- state == "paid"
|
||||||
|
- reconciled
|
||||||
|
- residual == 0.0
|
|
@ -0,0 +1,292 @@
|
||||||
|
-
|
||||||
|
In order to test the V11 import,
|
||||||
|
I will create an invoice with a specified reference that I will partialy reconcile with a 1st V11
|
||||||
|
And then I will complete the reconcile with a second V11
|
||||||
|
-
|
||||||
|
I create an invoice ref 2000999 of EUR 250.00
|
||||||
|
-
|
||||||
|
!record {model: account.invoice, id: v11_part_test_invoice}:
|
||||||
|
name: V11 YAML invoice
|
||||||
|
number: 2000999
|
||||||
|
company_id: base.main_company
|
||||||
|
journal_id: account.bank_journal
|
||||||
|
currency_id: base.EUR
|
||||||
|
account_id: account.a_recv
|
||||||
|
type : out_invoice
|
||||||
|
partner_id: base.res_partner_agrolait
|
||||||
|
address_contact_id: base.res_partner_address_8
|
||||||
|
address_invoice_id: base.res_partner_address_8
|
||||||
|
reference_type: bvr
|
||||||
|
reference: 20009997
|
||||||
|
date_invoice: !eval "'%s-01-01' %(datetime.now().year)"
|
||||||
|
period_id: account.period_1
|
||||||
|
#invoice_line:
|
||||||
|
partner_bank_id: main_partner_bank
|
||||||
|
check_total : 250.00
|
||||||
|
|
||||||
|
-
|
||||||
|
I create an invoice line
|
||||||
|
-
|
||||||
|
!record {model: account.invoice.line, id: v11_part_test_invoice_line}:
|
||||||
|
account_id: account.a_expense
|
||||||
|
name: '[PC1] Basic PC'
|
||||||
|
price_unit: 250.00
|
||||||
|
quantity: 1.0
|
||||||
|
product_id: product.product_product_pc1
|
||||||
|
uos_id: product.product_uom_unit
|
||||||
|
invoice_id: v11_part_test_invoice
|
||||||
|
|
||||||
|
-
|
||||||
|
I Validate invoice by clicking on Validate button
|
||||||
|
-
|
||||||
|
!workflow {model: account.invoice, action: invoice_open, ref: v11_part_test_invoice}
|
||||||
|
|
||||||
|
-
|
||||||
|
I specify the invoice number to fit with my v11
|
||||||
|
-
|
||||||
|
!python {model: account.invoice}: |
|
||||||
|
invoice = self.browse(cr, uid, ref('v11_part_test_invoice'))
|
||||||
|
invoice.write({'number': 2000999})
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I create a 1st bank statement
|
||||||
|
#########################################
|
||||||
|
# Creating 1st bank statement #
|
||||||
|
#########################################
|
||||||
|
-
|
||||||
|
!record {model: account.bank.statement, id: v11_part_test_bank_statement_1}:
|
||||||
|
#account_id:
|
||||||
|
#balance_end:
|
||||||
|
#balance_end_cash:
|
||||||
|
#balance_end_real:
|
||||||
|
#balance_start:
|
||||||
|
#closing_date:
|
||||||
|
#company_id:
|
||||||
|
#currency:
|
||||||
|
date: !eval "'%s-01-01' %(datetime.now().year)"
|
||||||
|
#ending_details_ids:
|
||||||
|
journal_id: account.bank_journal
|
||||||
|
#line_ids:
|
||||||
|
#move_line_ids
|
||||||
|
name: "/"
|
||||||
|
period_id: account.period_1
|
||||||
|
#starting_details_ids
|
||||||
|
state: draft
|
||||||
|
#total_entry_encoding
|
||||||
|
#user_id
|
||||||
|
|
||||||
|
-
|
||||||
|
I import the 1st V11
|
||||||
|
-
|
||||||
|
!python {model: bvr.import.wizard}: |
|
||||||
|
import base64
|
||||||
|
import addons
|
||||||
|
import os
|
||||||
|
|
||||||
|
# create our wizard
|
||||||
|
wiz_id = self.create(cr,uid,[])
|
||||||
|
wiz = self.browse(cr, uid, wiz_id)
|
||||||
|
|
||||||
|
test_file_path = addons.get_module_resource(os.path.join('l10n_ch', 'test', 'test_part_1.v11'))
|
||||||
|
|
||||||
|
# get our test file to test it
|
||||||
|
f_v11 = open(test_file_path)
|
||||||
|
|
||||||
|
str64_v11 = base64.encodestring(f_v11.read())
|
||||||
|
|
||||||
|
wiz.write({'file': str64_v11})
|
||||||
|
|
||||||
|
# set the file in the wizard field
|
||||||
|
bank_statement_id = ref('v11_part_test_bank_statement_1')
|
||||||
|
|
||||||
|
context['active_id'] = bank_statement_id
|
||||||
|
context['active_ids'] = [bank_statement_id]
|
||||||
|
# launch the import
|
||||||
|
self.import_bvr(cr, uid, [wiz_id], context=context)
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I check my bank statement got a statement line
|
||||||
|
-
|
||||||
|
!assert {model: account.bank.statement, id: v11_part_test_bank_statement_1, string: statement has 1 and only 1 statement line id}:
|
||||||
|
- len(line_ids) == 1
|
||||||
|
|
||||||
|
-
|
||||||
|
I check the voucher linked to the statement line contains a line with an amount of EUR 150.00
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('v11_part_test_bank_statement_1'))
|
||||||
|
|
||||||
|
voucher_line_ids = statement.line_ids[0].voucher_id.line_ids
|
||||||
|
|
||||||
|
assert voucher_line_ids, "No voucher line found"
|
||||||
|
|
||||||
|
voucher_line_amount = voucher_line_ids[0].amount
|
||||||
|
assert voucher_line_amount == 150.00, "Amount isn't correct : %d" %(voucher_line_amount)
|
||||||
|
|
||||||
|
-
|
||||||
|
I check amount of account voucher is equal to the bank statement line amount
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('v11_part_test_bank_statement_1'))
|
||||||
|
|
||||||
|
statement_line_amount = statement.line_ids[0].amount
|
||||||
|
voucher_amount = statement.line_ids[0].voucher_id.amount
|
||||||
|
|
||||||
|
assert statement_line_amount == voucher_amount, "Mismatch of amounts"
|
||||||
|
|
||||||
|
-
|
||||||
|
I enter the closing balance and press on compute button
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('v11_part_test_bank_statement_1'))
|
||||||
|
statement.write({'balance_end_real': 150.00})
|
||||||
|
self.button_dummy(cr, uid, [ref('v11_part_test_bank_statement_1')], context=context)
|
||||||
|
|
||||||
|
-
|
||||||
|
I check that the statement Balance is EUR 150.00
|
||||||
|
-
|
||||||
|
!assert {model: account.bank.statement, id: v11_part_test_bank_statement_1, string: balance is 150.0}:
|
||||||
|
- balance_end == 150.0
|
||||||
|
|
||||||
|
-
|
||||||
|
I confirm my 1st bank statement
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
self.button_confirm_bank(cr, uid, [ref('v11_part_test_bank_statement_1')], context=context)
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I check that my invoice is partially paid in open state, not reconciled, with a residual amount of EUR 100.0
|
||||||
|
#########################################
|
||||||
|
# Checking partial result #
|
||||||
|
#########################################
|
||||||
|
-
|
||||||
|
!assert {model: account.invoice, id: v11_part_test_invoice, string: 'invoice is open, reconciled and has no residual'}:
|
||||||
|
- state == "open"
|
||||||
|
- not reconciled
|
||||||
|
- residual == 100.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I create a 2nd bank statement
|
||||||
|
#########################################
|
||||||
|
# Creating 2nd bank statement #
|
||||||
|
#########################################
|
||||||
|
-
|
||||||
|
!record {model: account.bank.statement, id: v11_part_test_bank_statement_2}:
|
||||||
|
#account_id:
|
||||||
|
#balance_end:
|
||||||
|
#balance_end_cash:
|
||||||
|
#balance_end_real:
|
||||||
|
#balance_start:
|
||||||
|
#closing_date:
|
||||||
|
#company_id:
|
||||||
|
#currency:
|
||||||
|
date: !eval "'%s-01-01' %(datetime.now().year)"
|
||||||
|
#ending_details_ids:
|
||||||
|
journal_id: account.bank_journal
|
||||||
|
#line_ids:
|
||||||
|
#move_line_ids
|
||||||
|
name: "/"
|
||||||
|
period_id: account.period_1
|
||||||
|
#starting_details_ids
|
||||||
|
state: draft
|
||||||
|
#total_entry_encoding
|
||||||
|
#user_id
|
||||||
|
|
||||||
|
-
|
||||||
|
I import the 2nd V11
|
||||||
|
-
|
||||||
|
!python {model: bvr.import.wizard}: |
|
||||||
|
import base64
|
||||||
|
import addons
|
||||||
|
import os
|
||||||
|
|
||||||
|
# create our wizard
|
||||||
|
wiz_id = self.create(cr,uid,[])
|
||||||
|
wiz = self.browse(cr, uid, wiz_id)
|
||||||
|
|
||||||
|
test_file_path = addons.get_module_resource(os.path.join('l10n_ch', 'test', 'test_part_2.v11'))
|
||||||
|
|
||||||
|
# get our test file to test it
|
||||||
|
f_v11 = open(test_file_path)
|
||||||
|
|
||||||
|
str64_v11 = base64.encodestring(f_v11.read())
|
||||||
|
|
||||||
|
wiz.write({'file': str64_v11})
|
||||||
|
|
||||||
|
# set the file in the wizard field
|
||||||
|
bank_statement_id = ref('v11_part_test_bank_statement_2')
|
||||||
|
|
||||||
|
context['active_id'] = bank_statement_id
|
||||||
|
context['active_ids'] = [bank_statement_id]
|
||||||
|
# launch the import
|
||||||
|
self.import_bvr(cr, uid, [wiz_id], context=context)
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I check my bank statement got a statement line
|
||||||
|
-
|
||||||
|
!assert {model: account.bank.statement, id: v11_part_test_bank_statement_2, string: statement has 1 and only 1 statement line id}:
|
||||||
|
- len(line_ids) == 1
|
||||||
|
|
||||||
|
-
|
||||||
|
I check the voucher linked to the statement line contains a line with an amount of EUR 100.00
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('v11_part_test_bank_statement_2'))
|
||||||
|
|
||||||
|
voucher_line_ids = statement.line_ids[0].voucher_id.line_ids
|
||||||
|
|
||||||
|
assert voucher_line_ids, "No voucher line found"
|
||||||
|
|
||||||
|
voucher_line_amount = voucher_line_ids[0].amount
|
||||||
|
assert voucher_line_amount == 100.00, "Amount isn't correct : %d" %(voucher_line_amount)
|
||||||
|
|
||||||
|
-
|
||||||
|
I check amount of account voucher is equal to the bank statement line amount
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('v11_part_test_bank_statement_2'))
|
||||||
|
|
||||||
|
statement_line_amount = statement.line_ids[0].amount
|
||||||
|
voucher_amount = statement.line_ids[0].voucher_id.amount
|
||||||
|
|
||||||
|
assert statement_line_amount == voucher_amount, "Mismatch of amounts"
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I enter the closing balance and press on compute button
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
statement = self.browse(cr, uid, ref('v11_part_test_bank_statement_2'))
|
||||||
|
statement.write({'balance_end_real': 100.00})
|
||||||
|
self.button_dummy(cr, uid, [ref('v11_part_test_bank_statement_2')], context=context)
|
||||||
|
|
||||||
|
-
|
||||||
|
I check that the statement Balance is EUR 100.00
|
||||||
|
-
|
||||||
|
!assert {model: account.bank.statement, id: v11_part_test_bank_statement_2, string: balance is 100.0}:
|
||||||
|
- balance_end == 100.0
|
||||||
|
|
||||||
|
-
|
||||||
|
I confirm my 2nd bank statement
|
||||||
|
-
|
||||||
|
!python {model: account.bank.statement}: |
|
||||||
|
self.button_confirm_bank(cr, uid, [ref('v11_part_test_bank_statement_2')], context=context)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
I check my invoice is paid, reconciled and has no residual
|
||||||
|
#########################################
|
||||||
|
# Checking finale state #
|
||||||
|
#########################################
|
||||||
|
-
|
||||||
|
!assert {model: account.invoice, id: v11_part_test_invoice, string: 'invoice is paid, reconciled and has no residual'}:
|
||||||
|
- state == "paid"
|
||||||
|
- reconciled
|
||||||
|
- residual == 0.0
|
|
@ -0,0 +1,2 @@
|
||||||
|
00201012162700000000000000000001234567600000888000001 000111010111010111010100000000010000000000000
|
||||||
|
999010121627999999999999999999999999999000000088800000000000001110102000000000000000000
|
|
@ -0,0 +1,2 @@
|
||||||
|
00201012162700000000000000000002000999700000150000001 000111010111010111010100000000010000000000000
|
||||||
|
999010121627999999999999999999999999999000000015000000000000001110102000000000000000000
|
|
@ -0,0 +1,2 @@
|
||||||
|
00201012162700000000000000000002000999700000100000001 000111010511010511010500000000010000000000000
|
||||||
|
999010121627999999999999999999999999999000000010000000000000001110106000000000000000000
|
|
@ -7,7 +7,6 @@
|
||||||
Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
Accounts/Generate Chart of Accounts from a Chart Template.</field>
|
||||||
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
<field name="action_id" ref="account.action_wizard_multi_chart"/>
|
||||||
<field name="sequence">4</field>
|
<field name="sequence">4</field>
|
||||||
<field name="category_id" ref="account.category_accounting_configuration"/>
|
|
||||||
<field name="type">automatic</field>
|
<field name="type">automatic</field>
|
||||||
</record>
|
</record>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import create_dta
|
from . import create_dta
|
||||||
import bvr_import
|
from . import bvr_import
|
||||||
|
from . import unicode2ascii
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -36,7 +36,9 @@ def _reconstruct_invoice_ref(cursor, user, reference, context=None):
|
||||||
user_current=user_obj.browse(cursor, user, user)
|
user_current=user_obj.browse(cursor, user, user)
|
||||||
|
|
||||||
##
|
##
|
||||||
cursor.execute("SELECT inv.id,inv.number from account_invoice AS inv where inv.company_id = %s" ,(user_current.company_id.id,))
|
cursor.execute("SELECT inv.id,inv.number from account_invoice "
|
||||||
|
"AS inv where inv.company_id = %s and type='out_invoice'",
|
||||||
|
(user_current.company_id.id,))
|
||||||
result_invoice = cursor.fetchall()
|
result_invoice = cursor.fetchall()
|
||||||
REF = re.compile('[^0-9]')
|
REF = re.compile('[^0-9]')
|
||||||
for inv_id,inv_name in result_invoice:
|
for inv_id,inv_name in result_invoice:
|
||||||
|
@ -60,7 +62,6 @@ def _reconstruct_invoice_ref(cursor, user, reference, context=None):
|
||||||
def _import(self, cursor, user, data, context=None):
|
def _import(self, cursor, user, data, context=None):
|
||||||
|
|
||||||
statement_line_obj = self.pool.get('account.bank.statement.line')
|
statement_line_obj = self.pool.get('account.bank.statement.line')
|
||||||
# statement_reconcile_obj = pool.get('account.bank.statement.reconcile')
|
|
||||||
voucher_obj = self.pool.get('account.voucher')
|
voucher_obj = self.pool.get('account.voucher')
|
||||||
voucher_line_obj = self.pool.get('account.voucher.line')
|
voucher_line_obj = self.pool.get('account.voucher.line')
|
||||||
move_line_obj = self.pool.get('account.move.line')
|
move_line_obj = self.pool.get('account.move.line')
|
||||||
|
@ -167,7 +168,7 @@ def _import(self, cursor, user, data, context=None):
|
||||||
# line2reconcile = line.id
|
# line2reconcile = line.id
|
||||||
account_id = line.account_id.id
|
account_id = line.account_id.id
|
||||||
break
|
break
|
||||||
result = voucher_obj.onchange_partner_id(cursor, user, [], partner_id, journal_id=statement.journal_id.id, price=abs(record['amount']), currency_id= statement.currency.id, ttype='receipt', date=statement.date ,context=context)
|
result = voucher_obj.onchange_partner_id(cursor, user, [], partner_id, journal_id=statement.journal_id.id, price=abs(record['amount']), voucher_currency_id= statement.currency.id, ttype='receipt', date=statement.date ,context=context)
|
||||||
voucher_res = { 'type': 'receipt' ,
|
voucher_res = { 'type': 'receipt' ,
|
||||||
|
|
||||||
'name': values['name'],
|
'name': values['name'],
|
||||||
|
@ -207,7 +208,7 @@ def _import(self, cursor, user, data, context=None):
|
||||||
cursor,
|
cursor,
|
||||||
user,
|
user,
|
||||||
[
|
[
|
||||||
('name','=','property_account_receivable'),
|
('name','=',name),
|
||||||
('company_id','=',statement.company_id.id),
|
('company_id','=',statement.company_id.id),
|
||||||
('res_id', '=', False)
|
('res_id', '=', False)
|
||||||
]
|
]
|
||||||
|
@ -226,9 +227,9 @@ def _import(self, cursor, user, data, context=None):
|
||||||
values['partner_id'] = partner_id
|
values['partner_id'] = partner_id
|
||||||
statement_line_obj.create(cursor, user, values, context=context)
|
statement_line_obj.create(cursor, user, values, context=context)
|
||||||
attachment_obj.create(cursor, user, {
|
attachment_obj.create(cursor, user, {
|
||||||
'name': 'BVR',
|
'name': 'BVR %s'%time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()),
|
||||||
'datas': file,
|
'datas': file,
|
||||||
'datas_fname': 'BVR.txt',
|
'datas_fname': 'BVR %s.txt'%time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()),
|
||||||
'res_model': 'account.bank.statement',
|
'res_model': 'account.bank.statement',
|
||||||
'res_id': statement_id,
|
'res_id': statement_id,
|
||||||
}, context=context)
|
}, context=context)
|
||||||
|
|
|
@ -26,6 +26,7 @@ import base64
|
||||||
from osv import osv, fields
|
from osv import osv, fields
|
||||||
import pooler
|
import pooler
|
||||||
from tools.translate import _
|
from tools.translate import _
|
||||||
|
import unicode2ascii
|
||||||
|
|
||||||
TRANS=[
|
TRANS=[
|
||||||
(u'é','e'),
|
(u'é','e'),
|
||||||
|
@ -38,6 +39,24 @@ TRANS=[
|
||||||
(u'ä','a'),
|
(u'ä','a'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def _u2a(text) :
|
||||||
|
"""Tries to convert unicode charactere to asci equivalence"""
|
||||||
|
if not text : return ""
|
||||||
|
txt = ""
|
||||||
|
for c in text:
|
||||||
|
if ord(c) < 128 :
|
||||||
|
txt += c
|
||||||
|
elif c in unicode2ascii.EXTRA_LATIN_NAMES :
|
||||||
|
txt += unicode2ascii.EXTRA_LATIN_NAMES[c]
|
||||||
|
elif c in unicode2ascii.UNI2ASCII_CONVERSIONS :
|
||||||
|
txt += unicode2ascii.UNI2ASCII_CONVERSIONS[c]
|
||||||
|
elif c in unicode2ascii.EXTRA_CHARACTERS :
|
||||||
|
txt += unicode2ascii.EXTRA_CHARACTERS[c]
|
||||||
|
elif c in unicode2ascii.FG_HACKS :
|
||||||
|
txt += unicode2ascii.FG_HACKS[c]
|
||||||
|
else : txt+= "_"
|
||||||
|
return txt
|
||||||
|
|
||||||
def tr(string_in):
|
def tr(string_in):
|
||||||
try:
|
try:
|
||||||
string_in= string_in.decode('utf-8')
|
string_in= string_in.decode('utf-8')
|
||||||
|
@ -339,7 +358,9 @@ def _create_dta(obj, cr, uid, data, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
payment = payment_obj.browse(cr, uid, data['id'], context=context)
|
payment = payment_obj.browse(cr, uid, data['id'], context=context)
|
||||||
|
# if payment.state != 'done':
|
||||||
|
# raise osv.except_osv(_('Order not confirmed'),
|
||||||
|
# _('Please confirm it'))
|
||||||
if not payment.mode:
|
if not payment.mode:
|
||||||
raise osv.except_osv(_('Error'),
|
raise osv.except_osv(_('Error'),
|
||||||
_('No payment mode'))
|
_('No payment mode'))
|
||||||
|
@ -365,11 +386,13 @@ def _create_dta(obj, cr, uid, data, context=None):
|
||||||
v['comp_name'] = co_addr.name
|
v['comp_name'] = co_addr.name
|
||||||
v['comp_dta'] = bank.dta_code or '' #XXX not mandatory in pratice
|
v['comp_dta'] = bank.dta_code or '' #XXX not mandatory in pratice
|
||||||
|
|
||||||
v['comp_bank_number'] = bank.acc_number or ''
|
# iban and account number are the same field and depends only on the type of account
|
||||||
if bank.iban:
|
v['comp_bank_iban'] = v['comp_bank_number'] = bank.acc_number or ''
|
||||||
v['comp_bank_iban'] = bank.iban.replace(' ','') or ''
|
|
||||||
else:
|
#if bank.iban:
|
||||||
v['comp_bank_iban'] = ''
|
# v['comp_bank_iban'] = bank.iban.replace(' ','') or ''
|
||||||
|
#else:
|
||||||
|
# v['comp_bank_iban'] = ''
|
||||||
if not v['comp_bank_iban']:
|
if not v['comp_bank_iban']:
|
||||||
raise osv.except_osv(_('Error'),
|
raise osv.except_osv(_('Error'),
|
||||||
_('No IBAN for the company bank account.'))
|
_('No IBAN for the company bank account.'))
|
||||||
|
@ -403,7 +426,7 @@ def _create_dta(obj, cr, uid, data, context=None):
|
||||||
'on the partner: %s\n' \
|
'on the partner: %s\n' \
|
||||||
'on line: %s') % (pline.bank_id.state, pline.partner_id.name, pline.name))
|
'on line: %s') % (pline.bank_id.state, pline.partner_id.name, pline.name))
|
||||||
|
|
||||||
v['partner_bank_iban'] = pline.bank_id.iban or False
|
v['partner_bank_iban'] = pline.bank_id.acc_number or False
|
||||||
v['partner_bank_number'] = pline.bank_id.acc_number \
|
v['partner_bank_number'] = pline.bank_id.acc_number \
|
||||||
and pline.bank_id.acc_number.replace('.','').replace('-','') \
|
and pline.bank_id.acc_number.replace('.','').replace('-','') \
|
||||||
or False
|
or False
|
||||||
|
@ -468,7 +491,7 @@ def _create_dta(obj, cr, uid, data, context=None):
|
||||||
# si payment structure -> bvr (826)
|
# si payment structure -> bvr (826)
|
||||||
# si non -> (827)
|
# si non -> (827)
|
||||||
|
|
||||||
if elec_pay == 'dta_iban':
|
if elec_pay == 'iban':
|
||||||
# If iban => country=country code for space reason
|
# If iban => country=country code for space reason
|
||||||
v['comp_country'] = co_addr.country_id and co_addr.country_id.code+'-' or ''
|
v['comp_country'] = co_addr.country_id and co_addr.country_id.code+'-' or ''
|
||||||
record_type = record_gt836
|
record_type = record_gt836
|
||||||
|
@ -512,9 +535,6 @@ def _create_dta(obj, cr, uid, data, context=None):
|
||||||
|
|
||||||
elif elec_pay == 'bvbank':
|
elif elec_pay == 'bvbank':
|
||||||
if not v['partner_bank_number'] :
|
if not v['partner_bank_number'] :
|
||||||
if v['partner_bank_iban'] :
|
|
||||||
v['partner_bank_number']= v['partner_bank_iban']
|
|
||||||
else:
|
|
||||||
raise osv.except_osv(_('Error'), _('You must provide ' \
|
raise osv.except_osv(_('Error'), _('You must provide ' \
|
||||||
'a bank number \n' \
|
'a bank number \n' \
|
||||||
'for the partner bank: %s\n' \
|
'for the partner bank: %s\n' \
|
||||||
|
@ -551,17 +571,17 @@ def _create_dta(obj, cr, uid, data, context=None):
|
||||||
v['sequence'] = str(seq).rjust(5).replace(' ','0')
|
v['sequence'] = str(seq).rjust(5).replace(' ','0')
|
||||||
if dta :
|
if dta :
|
||||||
dta = dta + record_gt890(v).generate()
|
dta = dta + record_gt890(v).generate()
|
||||||
|
dta_data = _u2a(dta)
|
||||||
dta_data = base64.encodestring(dta)
|
dta_data = base64.encodestring(dta)
|
||||||
payment_obj.set_done(cr, uid, [data['id']], context)
|
payment_obj.set_done(cr, uid, [data['id']], context)
|
||||||
attachment_obj.create(cr, uid, {
|
attachment_obj.create(cr, uid, {
|
||||||
'name': 'DTA',
|
'name': 'DTA%s'%time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()),
|
||||||
'datas': dta_data,
|
'datas': dta_data,
|
||||||
'datas_fname': 'DTA.txt',
|
'datas_fname': 'DTA%s.txt'%time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()),
|
||||||
'res_model': 'payment.order',
|
'res_model': 'payment.order',
|
||||||
'res_id': data['id'],
|
'res_id': data['id'],
|
||||||
}, context=context)
|
}, context=context)
|
||||||
return {'dta': dta_data}
|
return dta_data
|
||||||
|
|
||||||
class create_dta_wizard(osv.osv_memory):
|
class create_dta_wizard(osv.osv_memory):
|
||||||
_name="create.dta.wizard"
|
_name="create.dta.wizard"
|
||||||
|
@ -572,6 +592,11 @@ class create_dta_wizard(osv.osv_memory):
|
||||||
def create_dta(self, cr, uid, ids, context=None):
|
def create_dta(self, cr, uid, ids, context=None):
|
||||||
if not context:
|
if not context:
|
||||||
context = {}
|
context = {}
|
||||||
|
if isinstance(ids, list):
|
||||||
|
req_id = ids[0]
|
||||||
|
else:
|
||||||
|
req_id = ids
|
||||||
|
current = self.browse(cr, uid, req_id, context)
|
||||||
data = {}
|
data = {}
|
||||||
active_ids = context.get('active_ids', [])
|
active_ids = context.get('active_ids', [])
|
||||||
active_id = context.get('active_id', [])
|
active_id = context.get('active_id', [])
|
||||||
|
@ -579,25 +604,8 @@ class create_dta_wizard(osv.osv_memory):
|
||||||
data['ids'] = active_ids
|
data['ids'] = active_ids
|
||||||
data['id'] = active_id
|
data['id'] = active_id
|
||||||
dta_file = _create_dta(self, cr, uid, data, context)
|
dta_file = _create_dta(self, cr, uid, data, context)
|
||||||
context.update({'dta_file':dta_file})
|
current.write({'dta_file': dta_file})
|
||||||
return self.save_dta(cr, uid, ids, context)
|
return True
|
||||||
|
|
||||||
def save_dta(self, cr, uid, ids, context=None):
|
|
||||||
obj_model = self.pool.get('ir.model.data')
|
|
||||||
if context is None:
|
|
||||||
context = {}
|
|
||||||
model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'), ('name','=','dta_save_view')])
|
|
||||||
resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id']
|
|
||||||
return {
|
|
||||||
'view_type': 'form',
|
|
||||||
'view_mode': 'form',
|
|
||||||
'res_model': 'create.dta.wizard',
|
|
||||||
'views': [(resource_id, 'form')],
|
|
||||||
'type': 'ir.actions.act_window',
|
|
||||||
'target': 'new',
|
|
||||||
'context': context,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
create_dta_wizard()
|
create_dta_wizard()
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<form string="DTA file creation - Results">
|
<form string="DTA file creation - Results">
|
||||||
<group width="300" colspan="4">
|
<group width="300" colspan="4">
|
||||||
<separator string="Create DTA" colspan="4"/>
|
<separator string="Create DTA" colspan="4"/>
|
||||||
|
<field name="dta_file"/>
|
||||||
<group colspan="4">
|
<group colspan="4">
|
||||||
<button special="cancel" string="Cancel" icon="gtk-cancel" colspan="2"/>
|
<button special="cancel" string="Cancel" icon="gtk-cancel" colspan="2"/>
|
||||||
<button name="create_dta" string="Create DTA" type="object" icon="gtk-ok" colspan="2"/>
|
<button name="create_dta" string="Create DTA" type="object" icon="gtk-ok" colspan="2"/>
|
||||||
|
@ -38,21 +39,5 @@
|
||||||
<field name="key">action</field>
|
<field name="key">action</field>
|
||||||
<field name="model">payment.order</field>
|
<field name="model">payment.order</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Save DTA -->
|
|
||||||
<record id="dta_save_view" model="ir.ui.view">
|
|
||||||
<field name="name">Save DTA</field>
|
|
||||||
<field name="model">create.dta.wizard</field>
|
|
||||||
<field name="type">form</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<form string="DTA file creation - Results">
|
|
||||||
<group width="500" colspan="4">
|
|
||||||
<separator colspan="4" string="Click on 'Save as' to save the DTA file :" />
|
|
||||||
<field name="dta_file"/>
|
|
||||||
</group>
|
|
||||||
</form>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
|
@ -0,0 +1,592 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Convert many unicode characters to ascii characters that are like them.
|
||||||
|
|
||||||
|
I want to collate names, with the property that a last name starting with
|
||||||
|
O-umlaut will be in with the last name's starting with O. Horrors!
|
||||||
|
|
||||||
|
So I want that many Latin-1 characters have their umlaute's, etc., stripped.
|
||||||
|
Some of it can be done automatically but some needs to be done by hand, that
|
||||||
|
I can tell.
|
||||||
|
"""
|
||||||
|
__version__='1.0.1'
|
||||||
|
__author__='Jim Hefferon: ftpmaint at tug.ctan.org'
|
||||||
|
__date__='2008-July-15'
|
||||||
|
__notes__="""As sources, used effbot's web site, and
|
||||||
|
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/251871
|
||||||
|
and
|
||||||
|
man uni2ascii
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os, os.path, sys, re
|
||||||
|
import unicodedata
|
||||||
|
|
||||||
|
# These characters that are not done automatically by NFKD, and
|
||||||
|
# have a name starting with "LATIN". Some of these I found on the interwebs,
|
||||||
|
# but some I did by eye. Corrections or additions appreciated.
|
||||||
|
EXTRA_LATIN_NAMES={
|
||||||
|
# First are ones I got off the interweb
|
||||||
|
u"\N{LATIN CAPITAL LETTER O WITH STROKE}": u"O",
|
||||||
|
u"\N{LATIN SMALL LETTER A WITH GRAVE}": u"a",
|
||||||
|
u"\N{LATIN SMALL LETTER A WITH ACUTE}": u"a",
|
||||||
|
u"\N{LATIN SMALL LETTER A WITH CIRCUMFLEX}": u"a",
|
||||||
|
u"\N{LATIN SMALL LETTER A WITH TILDE}": u"a",
|
||||||
|
u"\N{LATIN SMALL LETTER A WITH DIAERESIS}": u"ae",
|
||||||
|
u"\N{LATIN SMALL LETTER A WITH RING ABOVE}": u"a",
|
||||||
|
u"\N{LATIN SMALL LETTER C WITH CEDILLA}": u"c",
|
||||||
|
u"\N{LATIN SMALL LETTER E WITH GRAVE}": u"e",
|
||||||
|
u"\N{LATIN SMALL LETTER E WITH ACUTE}": u"e",
|
||||||
|
u"\N{LATIN SMALL LETTER E WITH CIRCUMFLEX}": u"e",
|
||||||
|
u"\N{LATIN SMALL LETTER E WITH DIAERESIS}": u"e",
|
||||||
|
u"\N{LATIN SMALL LETTER I WITH GRAVE}": u"i",
|
||||||
|
u"\N{LATIN SMALL LETTER I WITH ACUTE}": u"i",
|
||||||
|
u"\N{LATIN SMALL LETTER I WITH CIRCUMFLEX}": u"i",
|
||||||
|
u"\N{LATIN SMALL LETTER I WITH DIAERESIS}": u"i",
|
||||||
|
u"\N{LATIN SMALL LETTER N WITH TILDE}": u"n",
|
||||||
|
u"\N{LATIN SMALL LETTER O WITH GRAVE}": u"o",
|
||||||
|
u"\N{LATIN SMALL LETTER O WITH ACUTE}": u"o",
|
||||||
|
u"\N{LATIN SMALL LETTER O WITH CIRCUMFLEX}": u"o",
|
||||||
|
u"\N{LATIN SMALL LETTER O WITH TILDE}": u"o",
|
||||||
|
u"\N{LATIN SMALL LETTER O WITH DIAERESIS}": u"oe",
|
||||||
|
u"\N{LATIN SMALL LETTER O WITH STROKE}": u"o",
|
||||||
|
u"\N{LATIN SMALL LETTER U WITH GRAVE}": u"u",
|
||||||
|
u"\N{LATIN SMALL LETTER U WITH ACUTE}": u"u",
|
||||||
|
u"\N{LATIN SMALL LETTER U WITH CIRCUMFLEX}": u"u",
|
||||||
|
u"\N{LATIN SMALL LETTER U WITH DIAERESIS}": u"ue",
|
||||||
|
u"\N{LATIN SMALL LETTER Y WITH ACUTE}": u"y",
|
||||||
|
u"\N{LATIN SMALL LETTER Y WITH DIAERESIS}": u"y",
|
||||||
|
u"\N{LATIN SMALL LETTER A WITH MACRON}": u"a",
|
||||||
|
u"\N{LATIN SMALL LETTER A WITH BREVE}": u"a",
|
||||||
|
u"\N{LATIN SMALL LETTER C WITH ACUTE}": u"c",
|
||||||
|
u"\N{LATIN SMALL LETTER C WITH CIRCUMFLEX}": u"c",
|
||||||
|
u"\N{LATIN SMALL LETTER E WITH MACRON}": u"e",
|
||||||
|
u"\N{LATIN SMALL LETTER E WITH BREVE}": u"e",
|
||||||
|
u"\N{LATIN SMALL LETTER G WITH CIRCUMFLEX}": u"g",
|
||||||
|
u"\N{LATIN SMALL LETTER G WITH BREVE}": u"g",
|
||||||
|
u"\N{LATIN SMALL LETTER G WITH CEDILLA}": u"g",
|
||||||
|
u"\N{LATIN SMALL LETTER H WITH CIRCUMFLEX}": u"h",
|
||||||
|
u"\N{LATIN SMALL LETTER I WITH TILDE}": u"i",
|
||||||
|
u"\N{LATIN SMALL LETTER I WITH MACRON}": u"i",
|
||||||
|
u"\N{LATIN SMALL LETTER I WITH BREVE}": u"i",
|
||||||
|
u"\N{LATIN SMALL LETTER J WITH CIRCUMFLEX}": u"j",
|
||||||
|
u"\N{LATIN SMALL LETTER K WITH CEDILLA}": u"k",
|
||||||
|
u"\N{LATIN SMALL LETTER L WITH ACUTE}": u"l",
|
||||||
|
u"\N{LATIN SMALL LETTER L WITH CEDILLA}": u"l",
|
||||||
|
u"\N{LATIN CAPITAL LETTER L WITH STROKE}": u"L",
|
||||||
|
u"\N{LATIN SMALL LETTER L WITH STROKE}": u"l",
|
||||||
|
u"\N{LATIN SMALL LETTER N WITH ACUTE}": u"n",
|
||||||
|
u"\N{LATIN SMALL LETTER N WITH CEDILLA}": u"n",
|
||||||
|
u"\N{LATIN SMALL LETTER O WITH MACRON}": u"o",
|
||||||
|
u"\N{LATIN SMALL LETTER O WITH BREVE}": u"o",
|
||||||
|
u"\N{LATIN SMALL LETTER R WITH ACUTE}": u"r",
|
||||||
|
u"\N{LATIN SMALL LETTER R WITH CEDILLA}": u"r",
|
||||||
|
u"\N{LATIN SMALL LETTER S WITH ACUTE}": u"s",
|
||||||
|
u"\N{LATIN SMALL LETTER S WITH CIRCUMFLEX}": u"s",
|
||||||
|
u"\N{LATIN SMALL LETTER S WITH CEDILLA}": u"s",
|
||||||
|
u"\N{LATIN SMALL LETTER T WITH CEDILLA}": u"t",
|
||||||
|
u"\N{LATIN SMALL LETTER U WITH TILDE}": u"u",
|
||||||
|
u"\N{LATIN SMALL LETTER U WITH MACRON}": u"u",
|
||||||
|
u"\N{LATIN SMALL LETTER U WITH BREVE}": u"u",
|
||||||
|
u"\N{LATIN SMALL LETTER U WITH RING ABOVE}": u"u",
|
||||||
|
u"\N{LATIN SMALL LETTER W WITH CIRCUMFLEX}": u"w",
|
||||||
|
u"\N{LATIN SMALL LETTER Y WITH CIRCUMFLEX}": u"y",
|
||||||
|
u"\N{LATIN SMALL LETTER Z WITH ACUTE}": u"z",
|
||||||
|
u"\N{LATIN SMALL LETTER W WITH GRAVE}": u"w",
|
||||||
|
u"\N{LATIN SMALL LETTER W WITH ACUTE}": u"w",
|
||||||
|
u"\N{LATIN SMALL LETTER W WITH DIAERESIS}": u"w",
|
||||||
|
u"\N{LATIN SMALL LETTER Y WITH GRAVE}": u"y",
|
||||||
|
# Below are the ones that failed automated conversion
|
||||||
|
u'\N{LATIN CAPITAL LETTER AE}': u'AE',
|
||||||
|
u'\N{LATIN CAPITAL LETTER ETH}': u'D',
|
||||||
|
u"\N{LATIN CAPITAL LETTER A WITH DIAERESIS}": u"Ae",
|
||||||
|
u"\N{LATIN CAPITAL LETTER O WITH DIAERESIS}": u"Oe",
|
||||||
|
u"\N{LATIN CAPITAL LETTER U WITH DIAERESIS}": u"Ue",
|
||||||
|
u'\N{LATIN CAPITAL LETTER O WITH STROKE}': u'O',
|
||||||
|
u'\N{LATIN CAPITAL LETTER THORN}': u'TH',
|
||||||
|
u'\N{LATIN SMALL LETTER SHARP S}': u'ss',
|
||||||
|
u'\N{LATIN SMALL LETTER AE}': u'ae',
|
||||||
|
u'\N{LATIN SMALL LETTER ETH}': u'd',
|
||||||
|
u'\N{LATIN SMALL LETTER O WITH STROKE}': u'o',
|
||||||
|
u'\N{LATIN SMALL LETTER THORN}': 'th',
|
||||||
|
u'\N{LATIN CAPITAL LETTER D WITH STROKE}': u'D',
|
||||||
|
u'\N{LATIN SMALL LETTER D WITH STROKE}': u'd',
|
||||||
|
u'\N{LATIN CAPITAL LETTER H WITH STROKE}': u'H',
|
||||||
|
u'\N{LATIN SMALL LETTER H WITH STROKE}': u'h',
|
||||||
|
u'\N{LATIN SMALL LETTER DOTLESS I}': u'i',
|
||||||
|
u'\N{LATIN SMALL LETTER KRA}': u'q',
|
||||||
|
u'\N{LATIN CAPITAL LETTER L WITH STROKE}': u'L',
|
||||||
|
u'\N{LATIN SMALL LETTER L WITH STROKE}': u'l',
|
||||||
|
u'\N{LATIN CAPITAL LETTER ENG}': u'N',
|
||||||
|
u'\N{LATIN SMALL LETTER ENG}': u'n',
|
||||||
|
u'\N{LATIN CAPITAL LIGATURE OE}': u'OE',
|
||||||
|
u'\N{LATIN SMALL LIGATURE OE}': u'oe',
|
||||||
|
u'\N{LATIN CAPITAL LETTER T WITH STROKE}': u'T',
|
||||||
|
u'\N{LATIN SMALL LETTER T WITH STROKE}': u't',
|
||||||
|
u'\N{LATIN SMALL LETTER B WITH STROKE}': u'b',
|
||||||
|
u'\N{LATIN CAPITAL LETTER B WITH HOOK}': u'B',
|
||||||
|
u'\N{LATIN CAPITAL LETTER B WITH TOPBAR}': u'B',
|
||||||
|
u'\N{LATIN SMALL LETTER B WITH TOPBAR}': u'b',
|
||||||
|
# u'\N{LATIN CAPITAL LETTER TONE SIX}': u'', # ?B
|
||||||
|
# u'\N{LATIN SMALL LETTER TONE SIX}': u'', # ?b
|
||||||
|
u'\N{LATIN CAPITAL LETTER OPEN O}': u'O',
|
||||||
|
u'\N{LATIN CAPITAL LETTER C WITH HOOK}': u'C',
|
||||||
|
u'\N{LATIN SMALL LETTER C WITH HOOK}': u'c',
|
||||||
|
u'\N{LATIN CAPITAL LETTER AFRICAN D}': u'D',
|
||||||
|
u'\N{LATIN CAPITAL LETTER D WITH HOOK}': u'D',
|
||||||
|
u'\N{LATIN CAPITAL LETTER D WITH TOPBAR}': u'D',
|
||||||
|
u'\N{LATIN SMALL LETTER D WITH TOPBAR}': u'd',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED DELTA}': u'',
|
||||||
|
u'\N{LATIN CAPITAL LETTER REVERSED E}': u'E',
|
||||||
|
# u'\N{LATIN CAPITAL LETTER SCHWA}': u'',
|
||||||
|
u'\N{LATIN CAPITAL LETTER OPEN E}': u'E',
|
||||||
|
u'\N{LATIN CAPITAL LETTER F WITH HOOK}': u'F',
|
||||||
|
u'\N{LATIN SMALL LETTER F WITH HOOK}': u'f',
|
||||||
|
u'\N{LATIN CAPITAL LETTER G WITH HOOK}': u'G',
|
||||||
|
# u'\N{LATIN CAPITAL LETTER GAMMA}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER HV}': u'hv',
|
||||||
|
u'\N{LATIN CAPITAL LETTER IOTA}': u'i',
|
||||||
|
u'\N{LATIN CAPITAL LETTER I WITH STROKE}': u'I',
|
||||||
|
u'\N{LATIN CAPITAL LETTER K WITH HOOK}': u'K',
|
||||||
|
u'\N{LATIN SMALL LETTER K WITH HOOK}': u'k',
|
||||||
|
u'\N{LATIN SMALL LETTER L WITH BAR}': u'l',
|
||||||
|
# u'\N{LATIN SMALL LETTER LAMBDA WITH STROKE}': u'',
|
||||||
|
# u'\N{LATIN CAPITAL LETTER TURNED M}': u'',
|
||||||
|
u'\N{LATIN CAPITAL LETTER N WITH LEFT HOOK}': u'N',
|
||||||
|
u'\N{LATIN SMALL LETTER N WITH LONG RIGHT LEG}': u'N',
|
||||||
|
u'\N{LATIN CAPITAL LETTER O WITH MIDDLE TILDE}': u'O',
|
||||||
|
u'\N{LATIN CAPITAL LETTER OI}': u'OI',
|
||||||
|
u'\N{LATIN SMALL LETTER OI}': u'oi',
|
||||||
|
u'\N{LATIN CAPITAL LETTER P WITH HOOK}': u'P',
|
||||||
|
u'\N{LATIN SMALL LETTER P WITH HOOK}': u'p',
|
||||||
|
# u'\N{LATIN LETTER YR}': u'',
|
||||||
|
# u'\N{LATIN CAPITAL LETTER TONE TWO}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TONE TWO}': u'',
|
||||||
|
u'\N{LATIN CAPITAL LETTER ESH}': u'SH',
|
||||||
|
# u'\N{LATIN LETTER REVERSED ESH LOOP}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER T WITH PALATAL HOOK}': u't',
|
||||||
|
u'\N{LATIN CAPITAL LETTER T WITH HOOK}': u'T',
|
||||||
|
u'\N{LATIN SMALL LETTER T WITH HOOK}': u't',
|
||||||
|
u'\N{LATIN CAPITAL LETTER T WITH RETROFLEX HOOK}': u'T',
|
||||||
|
# u'\N{LATIN CAPITAL LETTER UPSILON}': u'',
|
||||||
|
u'\N{LATIN CAPITAL LETTER V WITH HOOK}': u'V',
|
||||||
|
u'\N{LATIN CAPITAL LETTER Y WITH HOOK}': u'Y',
|
||||||
|
u'\N{LATIN SMALL LETTER Y WITH HOOK}': u'y',
|
||||||
|
u'\N{LATIN CAPITAL LETTER Z WITH STROKE}': u'Z',
|
||||||
|
u'\N{LATIN SMALL LETTER Z WITH STROKE}': u'z',
|
||||||
|
u'\N{LATIN CAPITAL LETTER EZH}': u'S',
|
||||||
|
# u'\N{LATIN CAPITAL LETTER EZH REVERSED}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER EZH REVERSED}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER EZH WITH TAIL}': u's',
|
||||||
|
# u'\N{LATIN LETTER TWO WITH STROKE}': u'',
|
||||||
|
# u'\N{LATIN CAPITAL LETTER TONE FIVE}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TONE FIVE}': u'',
|
||||||
|
# u'\N{LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE}': u'',
|
||||||
|
u'\N{LATIN LETTER WYNN}': u'w',
|
||||||
|
# u'\N{LATIN LETTER DENTAL CLICK}': u'',
|
||||||
|
# u'\N{LATIN LETTER LATERAL CLICK}': u'',
|
||||||
|
# u'\N{LATIN LETTER ALVEOLAR CLICK}': u'',
|
||||||
|
# u'\N{LATIN LETTER RETROFLEX CLICK}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED E}': u'',
|
||||||
|
u'\N{LATIN CAPITAL LETTER AE WITH MACRON}': u'AE',
|
||||||
|
u'\N{LATIN SMALL LETTER AE WITH MACRON}': u'ae',
|
||||||
|
u'\N{LATIN CAPITAL LETTER G WITH STROKE}': u'G',
|
||||||
|
u'\N{LATIN SMALL LETTER G WITH STROKE}': u'g',
|
||||||
|
u'\N{LATIN CAPITAL LETTER EZH WITH CARON}': u'S',
|
||||||
|
u'\N{LATIN SMALL LETTER EZH WITH CARON}': u's',
|
||||||
|
u'\N{LATIN CAPITAL LETTER HWAIR}': u'HW',
|
||||||
|
u'\N{LATIN CAPITAL LETTER WYNN}': u'W',
|
||||||
|
u'\N{LATIN CAPITAL LETTER AE WITH ACUTE}': u'AE',
|
||||||
|
u'\N{LATIN SMALL LETTER AE WITH ACUTE}': u'AE',
|
||||||
|
u'\N{LATIN CAPITAL LETTER O WITH STROKE AND ACUTE}': u'O',
|
||||||
|
u'\N{LATIN SMALL LETTER O WITH STROKE AND ACUTE}': u'o',
|
||||||
|
u'\N{LATIN CAPITAL LETTER YOGH}': u'J',
|
||||||
|
u'\N{LATIN SMALL LETTER YOGH}': u'j',
|
||||||
|
u'\N{LATIN CAPITAL LETTER N WITH LONG RIGHT LEG}': u'N',
|
||||||
|
u'\N{LATIN SMALL LETTER D WITH CURL}': u'd',
|
||||||
|
u'\N{LATIN CAPITAL LETTER OU}': u'OU',
|
||||||
|
u'\N{LATIN SMALL LETTER OU}': u'ou',
|
||||||
|
u'\N{LATIN CAPITAL LETTER Z WITH HOOK}': u'Z',
|
||||||
|
u'\N{LATIN SMALL LETTER Z WITH HOOK}': u'z',
|
||||||
|
u'\N{LATIN SMALL LETTER L WITH CURL}': u'l',
|
||||||
|
u'\N{LATIN SMALL LETTER N WITH CURL}': u'n',
|
||||||
|
u'\N{LATIN SMALL LETTER T WITH CURL}': u't',
|
||||||
|
u'\N{LATIN SMALL LETTER DOTLESS J}': u'j',
|
||||||
|
u'\N{LATIN SMALL LETTER DB DIGRAPH}': u'db',
|
||||||
|
u'\N{LATIN SMALL LETTER QP DIGRAPH}': u'qp',
|
||||||
|
u'\N{LATIN CAPITAL LETTER A WITH STROKE}': u'A',
|
||||||
|
u'\N{LATIN CAPITAL LETTER C WITH STROKE}': u'C',
|
||||||
|
u'\N{LATIN SMALL LETTER C WITH STROKE}': u'C',
|
||||||
|
u'\N{LATIN CAPITAL LETTER L WITH BAR}': u'L',
|
||||||
|
u'\N{LATIN CAPITAL LETTER T WITH DIAGONAL STROKE}': u'T',
|
||||||
|
u'\N{LATIN SMALL LETTER S WITH SWASH TAIL}': u'S',
|
||||||
|
u'\N{LATIN SMALL LETTER Z WITH SWASH TAIL}': u'Z',
|
||||||
|
# u'\N{LATIN CAPITAL LETTER GLOTTAL STOP}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED A}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER ALPHA}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED ALPHA}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER B WITH HOOK}': u'b',
|
||||||
|
u'\N{LATIN SMALL LETTER OPEN O}': u'o',
|
||||||
|
u'\N{LATIN SMALL LETTER C WITH CURL}': u'c',
|
||||||
|
u'\N{LATIN SMALL LETTER D WITH TAIL}': u'd',
|
||||||
|
u'\N{LATIN SMALL LETTER D WITH HOOK}': u'd',
|
||||||
|
# u'\N{LATIN SMALL LETTER REVERSED E}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER SCHWA}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER SCHWA WITH HOOK}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER OPEN E}': u'e',
|
||||||
|
# u'\N{LATIN SMALL LETTER REVERSED OPEN E}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER REVERSED OPEN E WITH HOOK}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER CLOSED REVERSED OPEN E}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER DOTLESS J WITH STROKE}': u'j',
|
||||||
|
u'\N{LATIN SMALL LETTER G WITH HOOK}': u'g',
|
||||||
|
u'\N{LATIN SMALL LETTER SCRIPT G}': u'g',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL G}': u'G',
|
||||||
|
# u'\N{LATIN SMALL LETTER GAMMA}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER RAMS HORN}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED H}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER H WITH HOOK}': u'h',
|
||||||
|
u'\N{LATIN SMALL LETTER HENG WITH HOOK}': u'h',
|
||||||
|
u'\N{LATIN SMALL LETTER I WITH STROKE}': u'i',
|
||||||
|
# u'\N{LATIN SMALL LETTER IOTA}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL I}': u'I',
|
||||||
|
u'\N{LATIN SMALL LETTER L WITH MIDDLE TILDE}': u'L',
|
||||||
|
u'\N{LATIN SMALL LETTER L WITH BELT}': u'L',
|
||||||
|
u'\N{LATIN SMALL LETTER L WITH RETROFLEX HOOK}': u'L',
|
||||||
|
# u'\N{LATIN SMALL LETTER LEZH}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED M}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED M WITH LONG LEG}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER M WITH HOOK}': u'm',
|
||||||
|
u'\N{LATIN SMALL LETTER N WITH LEFT HOOK}': u'n',
|
||||||
|
u'\N{LATIN SMALL LETTER N WITH RETROFLEX HOOK}': u'n',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL N}': u'N',
|
||||||
|
u'\N{LATIN SMALL LETTER BARRED O}': u'o',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL OE}': u'OE',
|
||||||
|
# u'\N{LATIN SMALL LETTER CLOSED OMEGA}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER PHI}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED R}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED R WITH LONG LEG}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED R WITH HOOK}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER R WITH LONG LEG}': u'r',
|
||||||
|
u'\N{LATIN SMALL LETTER R WITH TAIL}': u'r',
|
||||||
|
u'\N{LATIN SMALL LETTER R WITH FISHHOOK}': u'r',
|
||||||
|
# u'\N{LATIN SMALL LETTER REVERSED R WITH FISHHOOK}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL R}': u'R',
|
||||||
|
# u'\N{LATIN LETTER SMALL CAPITAL INVERTED R}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER S WITH HOOK}': u's',
|
||||||
|
u'\N{LATIN SMALL LETTER ESH}': u'sh',
|
||||||
|
u'\N{LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK}': u'j',
|
||||||
|
# u'\N{LATIN SMALL LETTER SQUAT REVERSED ESH}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER ESH WITH CURL}': u'sh',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED T}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER T WITH RETROFLEX HOOK}': u't',
|
||||||
|
u'\N{LATIN SMALL LETTER U BAR}': u'u',
|
||||||
|
# u'\N{LATIN SMALL LETTER UPSILON}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER V WITH HOOK}': u'v',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED V}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED W}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED Y}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL Y}': u'Y',
|
||||||
|
u'\N{LATIN SMALL LETTER Z WITH RETROFLEX HOOK}': u'z',
|
||||||
|
u'\N{LATIN SMALL LETTER Z WITH CURL}': u'z',
|
||||||
|
u'\N{LATIN SMALL LETTER EZH}': u's',
|
||||||
|
u'\N{LATIN SMALL LETTER EZH WITH CURL}': u's',
|
||||||
|
# u'\N{LATIN LETTER GLOTTAL STOP}': u'',
|
||||||
|
# u'\N{LATIN LETTER PHARYNGEAL VOICED FRICATIVE}': u'',
|
||||||
|
# u'\N{LATIN LETTER INVERTED GLOTTAL STOP}': u'',
|
||||||
|
u'\N{LATIN LETTER STRETCHED C}': u'c',
|
||||||
|
# u'\N{LATIN LETTER BILABIAL CLICK}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL B}': u'B',
|
||||||
|
u'\N{LATIN SMALL LETTER CLOSED OPEN E}': u'e',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL G WITH HOOK}': u'G',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL H}': u'H',
|
||||||
|
u'\N{LATIN SMALL LETTER J WITH CROSSED-TAIL}': u'j',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED K}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL L}': u'L',
|
||||||
|
u'\N{LATIN SMALL LETTER Q WITH HOOK}': u'q',
|
||||||
|
# u'\N{LATIN LETTER GLOTTAL STOP WITH STROKE}': u'',
|
||||||
|
# u'\N{LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER DZ DIGRAPH}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER DEZH DIGRAPH}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER DZ DIGRAPH WITH CURL}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TS DIGRAPH}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TESH DIGRAPH}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TC DIGRAPH WITH CURL}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER FENG DIGRAPH}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER LS DIGRAPH}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER LZ DIGRAPH}': u'',
|
||||||
|
# u'\N{LATIN LETTER BILABIAL PERCUSSIVE}': u'',
|
||||||
|
# u'\N{LATIN LETTER BIDENTAL PERCUSSIVE}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED H WITH FISHHOOK}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL A}': u'A',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL AE}': u'AE',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED AE}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL BARRED B}': u'B',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL C}': u'C',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL D}': u'D',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL ETH}': u'D',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL E}': u'E',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED OPEN E}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED I}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL J}': u'J',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL K}': u'K',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL L WITH STROKE}': u'L',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL M}': u'M',
|
||||||
|
# u'\N{LATIN LETTER SMALL CAPITAL REVERSED N}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL O}': u'O',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL OPEN O}': u'O',
|
||||||
|
# u'\N{LATIN SMALL LETTER SIDEWAYS O}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER SIDEWAYS OPEN O}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER SIDEWAYS O WITH STROKE}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED OE}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL OU}': u'OU',
|
||||||
|
# u'\N{LATIN SMALL LETTER TOP HALF O}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER BOTTOM HALF O}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL P}': u'P',
|
||||||
|
# u'\N{LATIN LETTER SMALL CAPITAL REVERSED R}': u'',
|
||||||
|
# u'\N{LATIN LETTER SMALL CAPITAL TURNED R}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL T}': u'T',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL U}': u'U',
|
||||||
|
# u'\N{LATIN SMALL LETTER SIDEWAYS U}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER SIDEWAYS DIAERESIZED U}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER SIDEWAYS TURNED M}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL V}': u'V',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL W}': u'W',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL Z}': u'',
|
||||||
|
u'\N{LATIN LETTER SMALL CAPITAL EZH}': u'S',
|
||||||
|
# u'\N{LATIN LETTER VOICED LARYNGEAL SPIRANT}': u'',
|
||||||
|
# u'\N{LATIN LETTER AIN}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER UE}': u'ue',
|
||||||
|
u'\N{LATIN SMALL LETTER B WITH MIDDLE TILDE}': u'b',
|
||||||
|
u'\N{LATIN SMALL LETTER D WITH MIDDLE TILDE}': u'd',
|
||||||
|
u'\N{LATIN SMALL LETTER F WITH MIDDLE TILDE}': u'f',
|
||||||
|
u'\N{LATIN SMALL LETTER M WITH MIDDLE TILDE}': u'm',
|
||||||
|
u'\N{LATIN SMALL LETTER N WITH MIDDLE TILDE}': u'n',
|
||||||
|
u'\N{LATIN SMALL LETTER P WITH MIDDLE TILDE}': u'p',
|
||||||
|
u'\N{LATIN SMALL LETTER R WITH MIDDLE TILDE}': u'r',
|
||||||
|
u'\N{LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE}': u'r',
|
||||||
|
u'\N{LATIN SMALL LETTER S WITH MIDDLE TILDE}': u's',
|
||||||
|
u'\N{LATIN SMALL LETTER T WITH MIDDLE TILDE}': u't',
|
||||||
|
u'\N{LATIN SMALL LETTER Z WITH MIDDLE TILDE}': u'z',
|
||||||
|
# u'\N{LATIN SMALL LETTER TURNED G}': u'',
|
||||||
|
# u'\N{LATIN SMALL LETTER INSULAR G}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER TH WITH STRIKETHROUGH}': u'th',
|
||||||
|
u'\N{LATIN SMALL CAPITAL LETTER I WITH STROKE}': u'I',
|
||||||
|
# u'\N{LATIN SMALL LETTER IOTA WITH STROKE}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER P WITH STROKE}': u'p',
|
||||||
|
u'\N{LATIN SMALL CAPITAL LETTER U WITH STROKE}': u'U',
|
||||||
|
# u'\N{LATIN SMALL LETTER UPSILON WITH STROKE}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER B WITH PALATAL HOOK}': u'b',
|
||||||
|
u'\N{LATIN SMALL LETTER D WITH PALATAL HOOK}': u'd',
|
||||||
|
u'\N{LATIN SMALL LETTER F WITH PALATAL HOOK}': u'f',
|
||||||
|
u'\N{LATIN SMALL LETTER G WITH PALATAL HOOK}': u'g',
|
||||||
|
u'\N{LATIN SMALL LETTER K WITH PALATAL HOOK}': u'k',
|
||||||
|
u'\N{LATIN SMALL LETTER L WITH PALATAL HOOK}': u'l',
|
||||||
|
u'\N{LATIN SMALL LETTER M WITH PALATAL HOOK}': u'm',
|
||||||
|
u'\N{LATIN SMALL LETTER N WITH PALATAL HOOK}': u'n',
|
||||||
|
u'\N{LATIN SMALL LETTER P WITH PALATAL HOOK}': u'p',
|
||||||
|
u'\N{LATIN SMALL LETTER R WITH PALATAL HOOK}': u'r',
|
||||||
|
u'\N{LATIN SMALL LETTER S WITH PALATAL HOOK}': u's',
|
||||||
|
u'\N{LATIN SMALL LETTER ESH WITH PALATAL HOOK}': u'sh',
|
||||||
|
u'\N{LATIN SMALL LETTER V WITH PALATAL HOOK}': u'v',
|
||||||
|
u'\N{LATIN SMALL LETTER X WITH PALATAL HOOK}': u'x',
|
||||||
|
u'\N{LATIN SMALL LETTER Z WITH PALATAL HOOK}': u'z',
|
||||||
|
u'\N{LATIN SMALL LETTER A WITH RETROFLEX HOOK}': u'a',
|
||||||
|
# u'\N{LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER D WITH HOOK AND TAIL}': u'd',
|
||||||
|
u'\N{LATIN SMALL LETTER E WITH RETROFLEX HOOK}': u'e',
|
||||||
|
u'\N{LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK}': u'e',
|
||||||
|
u'\N{LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK}': u'e',
|
||||||
|
# u'\N{LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK}': u'',
|
||||||
|
u'\N{LATIN SMALL LETTER I WITH RETROFLEX HOOK}': u'i',
|
||||||
|
u'\N{LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK}': u'o',
|
||||||
|
u'\N{LATIN SMALL LETTER ESH WITH RETROFLEX HOOK}': u'sh',
|
||||||
|
u'\N{LATIN SMALL LETTER U WITH RETROFLEX HOOK}': u'u',
|
||||||
|
u'\N{LATIN SMALL LETTER EZH WITH RETROFLEX HOOK}': u's',
|
||||||
|
# u'\N{LATIN SUBSCRIPT SMALL LETTER SCHWA}': u'',
|
||||||
|
# u'\N{LATIN CROSS}': u''
|
||||||
|
}
|
||||||
|
|
||||||
|
# Additional ones; see "man uni2ascii"
|
||||||
|
UNI2ASCII_CONVERSIONS={
|
||||||
|
u'\N{NO-BREAK SPACE}': u' ',
|
||||||
|
u'\N{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}': u'"',
|
||||||
|
u'\N{SOFT HYPHEN}': u'', # Controversial: see http://www.cs.tut.fi/~jkorpela/shy.html
|
||||||
|
u'\N{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}': u'"',
|
||||||
|
u'\N{ETHIOPIC WORDSPACE}': u' ',
|
||||||
|
u'\N{OGHAM SPACE MARK}': u' ',
|
||||||
|
u'\N{EN QUAD}': u' ',
|
||||||
|
u'\N{EM QUAD}': u' ',
|
||||||
|
u'\N{EN SPACE}': u' ',
|
||||||
|
u'\N{EM SPACE}': u' ',
|
||||||
|
u'\N{THREE-PER-EM SPACE}': u' ',
|
||||||
|
u'\N{FOUR-PER-EM SPACE}': u' ',
|
||||||
|
u'\N{SIX-PER-EM SPACE}': u' ',
|
||||||
|
u'\N{FIGURE SPACE}': u' ',
|
||||||
|
u'\N{PUNCTUATION SPACE}': u' ',
|
||||||
|
u'\N{THIN SPACE}': u' ',
|
||||||
|
u'\N{HAIR SPACE}': u' ',
|
||||||
|
u'\N{ZERO WIDTH SPACE}': u' ',
|
||||||
|
u'\N{ZERO WIDTH NO-BREAK SPACE}': u' ',
|
||||||
|
u'\N{HYPHEN}': u'-',
|
||||||
|
u'\N{NON-BREAKING HYPHEN}': u'-',
|
||||||
|
u'\N{FIGURE DASH}': u'-',
|
||||||
|
u'\N{EN DASH}': u'-',
|
||||||
|
u'\N{EM DASH}': u'-',
|
||||||
|
u'\N{LEFT SINGLE QUOTATION MARK}': u'`',
|
||||||
|
u'\N{RIGHT SINGLE QUOTATION MARK}': u"'",
|
||||||
|
u'\N{SINGLE LOW-9 QUOTATION MARK}': u'`',
|
||||||
|
u'\N{SINGLE HIGH-REVERSED-9 QUOTATION MARK}': u'`',
|
||||||
|
u'\N{LEFT DOUBLE QUOTATION MARK}': u'"',
|
||||||
|
u'\N{RIGHT DOUBLE QUOTATION MARK}': u'"',
|
||||||
|
u'\N{DOUBLE LOW-9 QUOTATION MARK}': u'"',
|
||||||
|
u'\N{DOUBLE HIGH-REVERSED-9 QUOTATION MARK}': u'"',
|
||||||
|
u'\N{SINGLE LEFT-POINTING ANGLE QUOTATION MARK}': u'`',
|
||||||
|
u'\N{SINGLE RIGHT-POINTING ANGLE QUOTATION MARK}': u"'",
|
||||||
|
u'\N{LOW ASTERISK}': u'*',
|
||||||
|
u'\N{MINUS SIGN}': u'-',
|
||||||
|
u'\N{ASTERISK OPERATOR}': u'*',
|
||||||
|
u'\N{BOX DRAWINGS LIGHT HORIZONTAL}': u'-',
|
||||||
|
u'\N{BOX DRAWINGS HEAVY HORIZONTAL}': u'-',
|
||||||
|
u'\N{BOX DRAWINGS LIGHT VERTICAL}': u'|',
|
||||||
|
u'\N{BOX DRAWINGS HEAVY VERTICAL}': u'|',
|
||||||
|
u'\N{HEAVY ASTERISK}': u'*',
|
||||||
|
u'\N{HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT}': u'"',
|
||||||
|
u'\N{HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT}': u'"',
|
||||||
|
u'\N{IDEOGRAPHIC SPACE}': u' ',
|
||||||
|
u'\N{SMALL AMPERSAND}': u'&',
|
||||||
|
u'\N{SMALL ASTERISK}': u'*',
|
||||||
|
u'\N{SMALL PLUS SIGN}': u'+',
|
||||||
|
u'\N{CENT SIGN}': u'cent',
|
||||||
|
u'\N{POUND SIGN}': u'pound',
|
||||||
|
u'\N{YEN SIGN}': u'yen',
|
||||||
|
u'\N{COPYRIGHT SIGN}': u'(c)',
|
||||||
|
u'\N{REGISTERED SIGN}': u'(R)',
|
||||||
|
u'\N{VULGAR FRACTION ONE QUARTER}': u'1/4',
|
||||||
|
u'\N{VULGAR FRACTION ONE HALF}': u'1/2',
|
||||||
|
u'\N{VULGAR FRACTION THREE QUARTERS}': u'3/4',
|
||||||
|
# u'\N{CAPITAL LETTER ASH}': u'AE',
|
||||||
|
u'\N{LATIN SMALL LETTER SHARP S}': u'ss',
|
||||||
|
# u'\N{SMALL LETTER ASH}': u'ae',
|
||||||
|
u'\N{LATIN CAPITAL LIGATURE IJ}': u'IJ',
|
||||||
|
u'\N{LATIN SMALL LIGATURE IJ}': u'ij',
|
||||||
|
u'\N{LATIN CAPITAL LIGATURE OE}': u'OE',
|
||||||
|
u'\N{LATIN SMALL LIGATURE oe}': u'oe',
|
||||||
|
u'\N{LATIN CAPITAL LETTER DZ}': u'DZ',
|
||||||
|
u'\N{LATIN CAPITAL LETTER DZ WITH CARON}': u'DZ',
|
||||||
|
u'\N{LATIN CAPITAL LETTER D WITH SMALL LETTER Z}': u'Dz',
|
||||||
|
u'\N{LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON}': u'Dz',
|
||||||
|
u'\N{LATIN SMALL LETTER DZ}': u'dz',
|
||||||
|
u'\N{LATIN SMALL LETTER TS DIGRAPH}': u'ts',
|
||||||
|
u'\N{HORIZONTAL ELLIPSIS}': u'...',
|
||||||
|
u'\N{MIDLINE HORIZONTAL ELLIPSIS}': u'...',
|
||||||
|
u'\N{LEFTWARDS ARROW}': u'<-',
|
||||||
|
u'\N{RIGHTWARDS ARROW}': u'->',
|
||||||
|
u'\N{LEFTWARDS DOUBLE ARROW}': u'<=',
|
||||||
|
u'\N{RIGHTWARDS DOUBLE ARROW}': u'=>',
|
||||||
|
}
|
||||||
|
|
||||||
|
# More from "man uni2ascii", in a different category.
|
||||||
|
EXTRA_CHARACTERS={
|
||||||
|
u'\N{ACUTE ACCENT}': u"'",
|
||||||
|
u'\N{BROKEN BAR}': u'|',
|
||||||
|
# u'\N{CEDILLA}': u'{cedilla}',
|
||||||
|
u'\N{CENT SIGN}': u' cents ',
|
||||||
|
u'\N{COPYRIGHT SIGN}': u'(C)',
|
||||||
|
u'\N{CURRENCY SIGN}': u' currency ',
|
||||||
|
u'\N{DEGREE SIGN}': u' degrees ',
|
||||||
|
# u'\N{DIAERESIS}': u'{umlaut}',
|
||||||
|
u'\N{DIVISION SIGN}': u'/',
|
||||||
|
# u'\N{FEMININE ORDINAL INDICATOR}': u'{^a}',
|
||||||
|
u'\N{INVERTED EXCLAMATION MARK}': u'!',
|
||||||
|
u'\N{INVERTED QUESTION MARK}': u'?',
|
||||||
|
# wrong? u'\N{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}': u'<<',
|
||||||
|
u'\N{MACRON}': u'_',
|
||||||
|
# u'\N{MASCULINE ORDINAL INDICATOR}': u'{^o}',
|
||||||
|
u'\N{MICRO SIGN}': u'micro',
|
||||||
|
u'\N{MIDDLE DOT}': u'*',
|
||||||
|
u'\N{MULTIPLICATION SIGN}': u'*',
|
||||||
|
u'\N{NOT SIGN}': u'not',
|
||||||
|
u'\N{PILCROW SIGN}': u'paragraph',
|
||||||
|
u'\N{PLUS-MINUS SIGN}': u'+/-',
|
||||||
|
u'\N{POUND SIGN}': u'pound',
|
||||||
|
u'\N{REGISTERED SIGN}': u'(R)',
|
||||||
|
# wrong? u'\N{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}': u'>>',
|
||||||
|
u'\N{SECTION SIGN}': u'section',
|
||||||
|
u'\N{SOFT HYPHEN}': u'',
|
||||||
|
u'\N{SUPERSCRIPT ONE}': u'^1',
|
||||||
|
u'\N{SUPERSCRIPT THREE}': u'^3',
|
||||||
|
u'\N{SUPERSCRIPT TWO}': u'^2',
|
||||||
|
u'\N{VULGAR FRACTION ONE HALF}': u'1/2',
|
||||||
|
u'\N{VULGAR FRACTION ONE QUARTER}': u'1/4',
|
||||||
|
u'\N{VULGAR FRACTION THREE QUARTERS}': u'3/4',
|
||||||
|
u'\N{YEN SIGN}': u'yen'
|
||||||
|
}
|
||||||
|
FG_HACKS={
|
||||||
|
u'\u0082': u'', # "break permitted here" symbol
|
||||||
|
u'\u2022': u'*', # Bullet
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def build_dictionary():
|
||||||
|
'Return the translation dictionary.'
|
||||||
|
d = dict()
|
||||||
|
# First do what can be done automatically
|
||||||
|
for i in range(0xffff):
|
||||||
|
u=unichr(i)
|
||||||
|
try:
|
||||||
|
n=unicodedata.name(u)
|
||||||
|
if n.startswith('LATIN '):
|
||||||
|
k=unicodedata.normalize('NFKD', u).encode('ASCII', 'ignore')
|
||||||
|
if k: d[i]=unicode(k) # i=ord(u)
|
||||||
|
except ValueError: pass
|
||||||
|
# Next, add some by-hand ones (overlap possible, so order matters)
|
||||||
|
for m in [EXTRA_LATIN_NAMES,EXTRA_CHARACTERS,UNI2ASCII_CONVERSIONS,FG_HACKS]:
|
||||||
|
for i in m:
|
||||||
|
try: d[ord(i)]=unicode(m[i])
|
||||||
|
except Exception, err: pass
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
udict = build_dictionary()
|
||||||
|
convert = lambda s: s.translate(udict)
|
||||||
|
|
||||||
|
def coroutine(func):
|
||||||
|
def start(*argz, **kwz):
|
||||||
|
cr = func(*argz, **kwz)
|
||||||
|
cr.next()
|
||||||
|
return cr
|
||||||
|
return start
|
||||||
|
|
||||||
|
@coroutine
|
||||||
|
def co_filter(drain, in_enc='utf-8', out_enc='ascii'):
|
||||||
|
bs = None
|
||||||
|
while True:
|
||||||
|
chunk = (yield bs)
|
||||||
|
bs = drain(convert(unicode(chunk)).encode('utf-8'))
|
||||||
|
|
||||||
|
def uc_filter(sin, sout, bs=8192, in_enc='utf-8', out_enc='ascii'):
|
||||||
|
sout = co_filter(sout.write, in_enc, out_enc)
|
||||||
|
while True:
|
||||||
|
dta = sin.read(bs)
|
||||||
|
if not dta: break
|
||||||
|
else: sout.send(dta)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
from optparse import OptionParser
|
||||||
|
parser = OptionParser(usage='%prog [options]',
|
||||||
|
description='utf8 stdin -> ascii stdout')
|
||||||
|
parser.add_option('-s', '--src-enc',
|
||||||
|
action='store', type='str', dest='src_enc', metavar='ENC', default='utf-8',
|
||||||
|
help='source encoding (utf-8)')
|
||||||
|
parser.add_option('-d', '--dst-enc',
|
||||||
|
action='store', type='str', dest='dst_enc', metavar='ENC', default='ascii',
|
||||||
|
help='destination encoding (ascii)')
|
||||||
|
parser.add_option('-c', '--chunk',
|
||||||
|
action='store', type='int', dest='bs', metavar='BYTES', default=8192,
|
||||||
|
help='read/write in chunks of a given size (8192)')
|
||||||
|
optz, argz = parser.parse_args()
|
||||||
|
if argz: parser.error('Only stdin -> stdout conversion suported')
|
||||||
|
|
||||||
|
uc_filter(sys.stdin, sys.stdout, bs=optz.bs, in_enc=optz.src_enc, out_enc=optz.dst_enc)
|
Loading…
Reference in New Issue