[Merge] with lp:banking-addons/6.1 revno 167

This commit is contained in:
Alexis de Lattre
2013-05-15 16:46:04 +02:00
33 changed files with 1483 additions and 620 deletions

View File

@@ -81,6 +81,10 @@ class account_banking_account_settings(osv.osv):
select=True, required=True),
'journal_id': fields.many2one('account.journal', 'Journal',
required=True),
'partner_id': fields.related(
'company_id', 'partner_id',
type='many2one', relation='res.partner',
string='Partner'),
'default_credit_account_id': fields.many2one(
'account.account', 'Default credit account', select=True,
help=('The account to use when an unexpected payment was signaled. '
@@ -127,44 +131,59 @@ class account_banking_account_settings(osv.osv):
#),
}
def _default_company(self, cursor, uid, context=None):
user = self.pool.get('res.users').browse(cursor, uid, uid, context=context)
if user.company_id:
return user.company_id.id
company_ids = self.pool.get('res.company').search(
cursor, uid, [('parent_id', '=', False)])
return len(company_ids) == 1 and company_ids[0] or False
def _default_journal(self, cr, uid, context=None):
domain = [('type', '=', 'bank')]
def _default_company(self, cr, uid, context=None):
"""
Return the user's company or the first company found
in the database
"""
user = self.pool.get('res.users').read(
cr, uid, uid, ['company_id'], context=context)
if user['company_id']:
domain.append(('company_id', '=', user['company_id'][0]))
return user['company_id'][0]
return self.pool.get('res.company').search(
cr, uid, [('parent_id', '=', False)])[0]
def _default_partner_id(self, cr, uid, context=None, company_id=False):
if not company_id:
company_id = self._default_company(cr, uid, context=context)
return self.pool.get('res.company').read(
cr, uid, company_id, ['partner_id'],
context=context)['partner_id'][0]
def _default_journal(self, cr, uid, context=None, company_id=False):
if not company_id:
company_id = self._default_company(cr, uid, context=context)
journal_ids = self.pool.get('account.journal').search(
cr, uid, domain)
return len(journal_ids) == 1 and journal_ids[0] or False
cr, uid, [('type', '=', 'bank'), ('company_id', '=', company_id)])
return journal_ids and journal_ids[0] or False
def _default_partner_bank_id(self, cr, uid, context=None):
user = self.pool.get('res.users').read(
cr, uid, uid, ['company_id'], context=context)
if user['company_id']:
bank_ids = self.pool.get('res.partner.bank').search(
cr, uid, [('company_id', '=', user['company_id'][0])])
if len(bank_ids) == 1:
return bank_ids[0]
return False
def _default_partner_bank_id(
self, cr, uid, context=None, company_id=False):
if not company_id:
company_id = self._default_company(cr, uid, context=context)
partner_id = self.pool.get('res.company').read(
cr, uid, company_id, ['partner_id'], context=context)['partner_id'][0]
bank_ids = self.pool.get('res.partner.bank').search(
cr, uid, [('partner_id', '=', partner_id)], context=context)
return bank_ids and bank_ids[0] or False
def _default_debit_account_id(self, cr, uid, context=None):
def _default_debit_account_id(
self, cr, uid, context=None, company_id=False):
localcontext = context and context.copy() or {}
localcontext['force_company'] = (
company_id or self._default_company(cr, uid, context=context))
account_def = self.pool.get('ir.property').get(
cr, uid, 'property_account_receivable',
'res.partner', context=context)
'res.partner', context=localcontext)
return account_def and account_def.id or False
def _default_credit_account_id(self, cr, uid, context=None):
def _default_credit_account_id(self, cr, uid, context=None, company_id=False):
localcontext = context and context.copy() or {}
localcontext['force_company'] = (
company_id or self._default_company(cr, uid, context=context))
account_def = self.pool.get('ir.property').get(
cr, uid, 'property_account_payable',
'res.partner', context=context)
'res.partner', context=localcontext)
return account_def and account_def.id or False
def find(self, cr, uid, journal_id, partner_bank_id=False, context=None):
@@ -173,8 +192,35 @@ class account_banking_account_settings(osv.osv):
domain.append(('partner_bank_id','=',partner_bank_id))
return self.search(cr, uid, domain, context=context)
def onchange_partner_bank_id(
self, cr, uid, ids, partner_bank_id, context=None):
values = {}
if partner_bank_id:
bank = self.pool.get('res.partner.bank').read(
cr, uid, partner_bank_id, ['journal_id'], context=context)
if bank['journal_id']:
values['journal_id'] = bank['journal_id'][0]
return {'value': values}
def onchange_company_id (
self, cr, uid, ids, company_id=False, context=None):
if not company_id:
return {}
result = {
'partner_id': self._default_partner_id(
cr, uid, company_id=company_id, context=context),
'journal_id': self._default_journal(
cr, uid, company_id=company_id, context=context),
'default_debit_account_id': self._default_debit_account_id(
cr, uid, company_id=company_id, context=context),
'default_credit_account_id': self._default_credit_account_id(
cr, uid, company_id=company_id, context=context),
}
return {'value': result}
_defaults = {
'company_id': _default_company,
'partner_id': _default_partner_id,
'journal_id': _default_journal,
'default_debit_account_id': _default_debit_account_id,
'default_credit_account_id': _default_credit_account_id,
@@ -410,13 +456,19 @@ class account_bank_statement(osv.osv):
'account.bank.statement.line')
st_line = account_bank_statement_line_obj.browse(
cr, uid, st_line_id, context=context)
period_id = self._get_period(
cr, uid, st_line.date, context=context) # AB
# Start account voucher
# Post the voucher and update links between statement and moves
if st_line.voucher_id:
voucher_pool = self.pool.get('account.voucher')
wf_service = netsvc.LocalService("workflow")
voucher_pool.write(
cr, uid, [st_line.voucher_id.id], {'number': st_line_number}, context=context)
cr, uid, [st_line.voucher_id.id], {
'number': st_line_number,
'date': st_line.date,
'period_id': period_id, # AB
}, context=context)
if st_line.voucher_id.state == 'cancel':
voucher_pool.action_cancel_draft(
cr, uid, [st_line.voucher_id.id], context=context)
@@ -443,8 +495,6 @@ class account_bank_statement(osv.osv):
context.update({'date': st_line.date})
ctxt = context.copy() # AB
ctxt['company_id'] = st_line.company_id.id # AB
period_id = self._get_period(
cr, uid, st_line.date, context=ctxt) # AB
move_id = account_move_obj.create(cr, uid, {
'journal_id': st.journal_id.id,
@@ -1470,16 +1520,13 @@ class res_partner_bank(osv.osv):
if country.code in sepa.IBAN.countries:
acc_number_fmt = sepa.BBAN(acc_number, country.code)
if acc_number_fmt.valid:
values['acc_number'] = str(acc_number_fmt)
values['acc_number_domestic'] = str(acc_number_fmt)
else:
values['acc_number'] = acc_number
result.update(warning(
_('Invalid format'),
_('The account number has the wrong format for %(country)s')
% {'country': country.name}
))
else:
values['acc_number'] = acc_number
return result
def onchange_iban(

View File

@@ -39,17 +39,31 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Default Import Settings for Bank Account">
<field name="company_id" />
<field name="company_id"
widget='selection'
groups="base.group_multi_company"
on_change="onchange_company_id(company_id)" />
<separator string="Bank Account Details" colspan="4" />
<field name="partner_bank_id" /> <!-- Needs domain for used companies /-->
<field name="journal_id" domain="[('type','=','bank')]" />
<field name="partner_id" invisible="1"/>
<field name="partner_bank_id"
domain="[('partner_id', '=', partner_id)]"
on_change="onchange_partner_bank_id(partner_bank_id)" />
<field name="journal_id"
domain="[('type','=','bank'),
('company_id', '=', company_id)]" />
<separator string="Default Accounts for Unknown Movements" colspan="4" />
<field name="default_credit_account_id" />
<field name="default_debit_account_id" />
<field name="default_credit_account_id"
domain="[('company_id', '=', company_id)]" />
<field name="default_debit_account_id"
domain="[('company_id', '=', company_id)]" />
<separator string="Generation of Bank Costs Invoices" colspan="4" />
<field name="bank_partner_id" />
<field name="costs_account_id" attrs="{'required': [('bank_partner_id', '&lt;&gt;', False)]}" />
<field name="invoice_journal_id" attrs="{'required': [('bank_partner_id', '&lt;&gt;', False)]}" />
<field name="costs_account_id"
attrs="{'required': [('bank_partner_id', '!=', False)]}"
domain="[('company_id', '=', company_id)]" />
<field name="invoice_journal_id"
attrs="{'required': [('bank_partner_id', '!=', False)]}"
domain="[('company_id', '=', company_id)]" />
</form>
</field>
</record>
@@ -60,8 +74,8 @@
<field name="arch" type="xml">
<tree string="Default Import Settings for Bank Account">
<field name="company_id" />
<field name="partner_bank_id" /> <!-- Needs domain for used companies /-->
<field name="journal_id" domain="[('type','=','bank')]" />
<field name="partner_bank_id" />
<field name="journal_id" />
</tree>
</field>
</record>
@@ -328,12 +342,8 @@
<field name="arch" type="xml">
<data>
<xpath expr="/form/group/button[@string='Select Invoices to Pay']"
position="replace">
<button colspan="2" name="%(account_payment.action_create_payment_order)s"
string="Select Invoices to Pay" type="action"
attrs="{'invisible':[('state','!=','draft')]}"
icon="gtk-find"
/>
position="attributes">
<attribute name="attrs">{'invisible':[('state','!=','draft')]}</attribute>
</xpath>
<xpath expr="/form/group/button[@string='Make Payments']"
position="replace">

View File

@@ -25,7 +25,6 @@
##############################################################################
from osv import osv, fields
import time
import netsvc
import base64
import datetime
@@ -141,7 +140,8 @@ class banking_import_transaction(osv.osv):
limit=0, context=context)
orders = payment_order_obj.browse(cr, uid, order_ids, context)
candidates = [x for x in orders if
is_zero(x.total - trans.transferred_amount)]
is_zero(x.total - trans.transferred_amount) and
x.line_ids and x.line_ids[0].debit_move_line_id]
if len(candidates) > 0:
# retrieve the common account_id, if any
account_id = False
@@ -222,7 +222,7 @@ class banking_import_transaction(osv.osv):
Match on ID of invoice (reference, name or number, whatever
available and sensible)
'''
if invoice.reference:
if invoice.reference and len(invoice.reference) > 2:
# Reference always comes first, as it is manually set for a
# reason.
iref = invoice.reference.upper()
@@ -230,7 +230,7 @@ class banking_import_transaction(osv.osv):
return True
if invoice.type.startswith('in_'):
# Internal numbering, no likely match on number
if invoice.name:
if invoice.name and len(invoice.name) > 2:
iname = invoice.name.upper()
if iname in ref or iname in msg:
return True
@@ -375,7 +375,7 @@ class banking_import_transaction(osv.osv):
move_line = False
partial = False
elif len(candidates) == 1:
elif len(candidates) == 1 and candidates[0].invoice:
# Mismatch in amounts
move_line = candidates[0]
invoice = move_line.invoice
@@ -423,10 +423,10 @@ class banking_import_transaction(osv.osv):
if x.partner_id.id == move_line.partner_id.id
]
return (trans, self._get_move_info(
cr, uid, [move_line.id],
account_ids and account_ids[0] or False),
trans2)
return (trans, self._get_move_info(
cr, uid, [move_line.id],
account_ids and account_ids[0] or False),
trans2)
return trans, False, False
@@ -494,7 +494,7 @@ class banking_import_transaction(osv.osv):
if from_curr_id != to_curr_id:
amount_currency = statement_line_pool._convert_currency(
cr, uid, from_curr_id, to_curr_id, move_line_amount,
round=True, date=time.strftime('%Y-%m-%d'),
round=True, date=transaction.move_line_id.date,
context=context)
else:
amount_currency = move_line_amount
@@ -606,7 +606,7 @@ class banking_import_transaction(osv.osv):
payment_line_obj.write(
cr, uid, transaction.payment_line_id.id, {
'export_state': 'done',
'date_done': transaction.effective_date,
'date_done': transaction.statement_line_id.date,
}
)
self._confirm_move(cr, uid, transaction_id, context=context)
@@ -961,9 +961,14 @@ class banking_import_transaction(osv.osv):
]
def create(self, cr, uid, vals, context=None):
"""
Search for duplicates of the newly created transaction
and mark them as such unless a context key
'transaction_no_duplicate_search' is defined and true.
"""
res = super(banking_import_transaction, self).create(
cr, uid, vals, context)
if res:
if res and not context.get('transaction_no_duplicate_search'):
me = self.browse(cr, uid, res, context)
search_vals = [(key, '=', me[key])
for key in self.signal_duplicate_keys]
@@ -1052,7 +1057,7 @@ class banking_import_transaction(osv.osv):
if move_lines and len(move_lines) == 1:
retval['reference'] = move_lines[0].ref
if retval['match_type'] == 'invoice':
retval['invoice_ids'] = [x.invoice.id for x in move_lines]
retval['invoice_ids'] = list(set([x.invoice.id for x in move_lines]))
retval['type'] = type_map[move_lines[0].invoice.type]
return retval
@@ -1310,8 +1315,7 @@ class banking_import_transaction(osv.osv):
transaction.remote_owner_address,
transaction.remote_owner_postalcode,
transaction.remote_owner_city,
country_code, results['log']
)
country_code, results['log'], context=context)
if transaction.remote_account:
partner_bank_id = create_bank_account(
self.pool, cr, uid, partner_id,
@@ -1319,7 +1323,8 @@ class banking_import_transaction(osv.osv):
transaction.remote_owner,
transaction.remote_owner_address,
transaction.remote_owner_city,
country_code, results['log']
country_code, results['log'],
bic=transaction.remote_bank_bic
)
partner_banks = partner_bank_obj.browse(
cr, uid, [partner_bank_id]
@@ -1556,11 +1561,19 @@ class banking_import_transaction(osv.osv):
if transaction.move_line_id:
move_line_amount = transaction.move_line_id.amount_residual_currency
to_curr_id = transaction.statement_id.journal_id.currency and transaction.statement_id.journal_id.currency.id or transaction.statement_line_id.statement_id.company_id.currency_id.id
from_curr_id = transaction.move_line_id.currency_id and transaction.move_line_id.currency_id.id or transaction.statement_id.company_id.currency_id.id
to_curr_id = (
transaction.statement_line_id.statement_id.journal_id.currency
and transaction.statement_line_id.statement_id.journal_id.currency.id
or transaction.statement_line_id.statement_id.company_id.currency_id.id
)
from_curr_id = (
transaction.move_line_id.currency_id
and transaction.move_line_id.currency_id.id
or transaction.statement_line_id.statement_id.company_id.currency_id.id
)
if from_curr_id != to_curr_id:
amount_currency = stline_pool._convert_currency(cr, uid, from_curr_id, to_curr_id, move_line_amount, round=True,
date=time.strftime('%Y-%m-%d'), context=context)
date=transaction.statement_line_id.date, context=context)
else:
amount_currency = move_line_amount
sign = 1
@@ -1871,6 +1884,42 @@ class account_bank_statement_line(osv.osv):
return super(account_bank_statement_line, self).unlink(
cr, uid, ids, context=context)
def create_instant_transaction(
self, cr, uid, ids, context=None):
"""
Check for existance of import transaction on the
bank statement lines. Create instant items if appropriate.
This way, the matching wizard works on manually
encoded statements.
The transaction is only filled with the most basic
information. The use of the transaction at this point
is rather to store matching data rather than to
provide data about the transaction which have all been
transferred to the bank statement line.
"""
import_transaction_pool = self.pool.get('banking.import.transaction')
if ids and isinstance(ids, (int, long)):
ids = [ids]
if context is None:
context = {}
localcontext = context.copy()
localcontext['transaction_no_duplicate_search'] = True
for line in self.browse(
cr, uid, ids, context=context):
if line.state != 'confirmed' and not line.import_transaction_id:
res = import_transaction_pool.create(
cr, uid, {
'company_id': line.statement_id.company_id.id,
'statement_line_id': line.id,
},
context=localcontext)
self.write(
cr, uid, line.id, {
'import_transaction_id': res},
context=context)
account_bank_statement_line()
class account_bank_statement(osv.osv):
@@ -1919,6 +1968,7 @@ class account_bank_statement(osv.osv):
_('The account entries lines are not in valid state.'))
line_obj.confirm(cr, uid, [line.id for line in st.line_ids], context)
st.refresh()
self.log(cr, uid, st.id, _('Statement %s is confirmed, journal '
'items are created.') % (st.name,))
return self.write(cr, uid, ids, {'state':'confirm'}, context=context)

View File

@@ -85,12 +85,20 @@ class payment_order_create(osv.osv_memory):
state = communication2 = False
communication = line.ref or '/'
if line.invoice:
if line.invoice.reference_type == 'structured':
state = 'structured'
communication = line.invoice.reference
if line.invoice.type in ('in_invoice', 'in_refund'):
if line.invoice.reference_type == 'structured':
state = 'structured'
communication = line.invoice.reference
else:
state = 'normal'
communication2 = line.invoice.reference
else:
state = 'normal'
communication2 = line.invoice.reference
# Make sure that the communication includes the
# customer invoice number (in the case of debit order)
communication = line.invoice.number.replace('/', '')
state = 'structured'
if communication != line.ref:
communication2 = line.ref
# support debit orders when enabled
if (payment.payment_order_type == 'debit' and
'amount_to_receive' in line):
@@ -112,7 +120,7 @@ class payment_order_create(osv.osv_memory):
'state': state,
### end account banking
'date': date_to_pay,
'currency': line.invoice and line.invoice.currency_id.id or False,
'currency': line.invoice and line.invoice.currency_id.id or line.journal_id.currency.id or line.journal_id.company_id.currency_id.id,
}, context=context)
return {'type': 'ir.actions.act_window_close'}

View File

@@ -260,7 +260,18 @@ class banking_import(osv.osv_memory):
# Get the period for the statement (as bank statement object checks this)
period_ids = period_obj.search(cursor, uid, [('company_id','=',company.id),
('date_start','<=',statement.date),
('date_stop','>=',statement.date)])
('date_stop','>=',statement.date),
('special', '=', False)])
if not period_ids:
results.log.append(
_('No period found covering statement date %(date)s, '
'statement %(id)s skipped') % {
'date': statement.date,
'id': statement.id,
}
)
continue
# Create the bank statement record
statement_id = statement_obj.create(cursor, uid, dict(

View File

@@ -35,6 +35,18 @@ class banking_transaction_wizard(osv.osv_memory):
_name = 'banking.transaction.wizard'
_description = 'Match transaction'
def create(self, cr, uid, vals, context=None):
"""
Make sure that the statement line has an import transaction
"""
res = super(banking_transaction_wizard, self).create(
cr, uid, vals, context=context)
if res and vals.get('statement_line_id'):
line_pool = self.pool.get('account.bank.statement.line')
line_pool.create_instant_transaction(
cr, uid, vals['statement_line_id'], context=context)
return res
def create_act_window(self, cr, uid, ids, nodestroy=True, context=None):
"""
Return a popup window for this model

View File

@@ -93,7 +93,21 @@
</page>
<page string="Manual match">
<field name="manual_invoice_id"/>
<field name="manual_move_line_id"/>
<!--
Specify alternative tree_view_ref as a
workaround for lp:1073521 in OpenERP 6.1
Need to also define 'view_mode' to prevent
an instant editable tree view
reconstruction by account.move.line's
fields_view_get().
Both are not needed in OpenERP 6.0 or 7.0.
-->
<field name="manual_move_line_id"
context="{
'tree_view_ref': 'account.view_move_line_tax_tree',
'view_mode': 'yes'
}"
/>
<newline/>
<button colspan="1"
name="trigger_write"

View File

@@ -19,14 +19,11 @@
#
##############################################################################
import sys
import datetime
import re
from tools.translate import _
from account_banking.parsers import convert
from account_banking import sepa
from account_banking.struct import struct
import unicodedata
__all__ = [
'get_period',
@@ -71,7 +68,8 @@ def get_period(pool, cursor, uid, date, company, log):
fiscalyear_id = fiscalyear_ids[0]
period_ids = period_obj.search(cursor, uid, [
('date_start','<=',search_date), ('date_stop','>=',search_date),
('fiscalyear_id','=',fiscalyear_id), ('state','=','draft')
('fiscalyear_id','=',fiscalyear_id), ('state','=','draft'),
('special', '=', False),
])
if not period_ids:
log.append(_('No suitable period found for date %(date)s and company %(company_name)s')
@@ -120,69 +118,67 @@ def _has_attr(obj, attr):
except KeyError:
return False
def get_or_create_partner(pool, cursor, uid, name, address, postal_code, city,
country_code, log):
def get_or_create_partner(pool, cr, uid, name, address, postal_code, city,
country_code, log, context=None):
'''
Get or create the partner belonging to the account holders name <name>
If multiple partners are found with the same name, select the first and
add a warning to the import log.
TODO: revive the search by lines from the address argument
'''
partner_obj = pool.get('res.partner')
partner_ids = partner_obj.search(cursor, uid, [('name', 'ilike', name)])
partner_ids = partner_obj.search(cr, uid, [('name', 'ilike', name)],
context=context)
country_id = False
if not partner_ids:
# Try brute search on address and then match reverse
address_obj = pool.get('res.partner.address')
filter = [('partner_id', '<>', None)]
criteria = []
if country_code:
country_obj = pool.get('res.country')
country_ids = country_obj.search(
cursor, uid, [('code','=',country_code.upper())]
)
cr, uid, [('code', '=', country_code.upper())],
context=context)
country_id = country_ids and country_ids[0] or False
filter.append(('country_id', '=', country_id))
# disable for now. Apparently, address is an array of lines.
if address and False:
if len(address) >= 1:
filter.append(('street', 'ilike', address[0]))
if len(address) > 1:
filter.append(('street2', 'ilike', address[1]))
criteria.append(('address.country_id', '=', country_id))
if city:
filter.append(('city', 'ilike', city))
criteria.append(('address.city', 'ilike', city))
if postal_code:
filter.append(('zip', 'ilike', postal_code))
address_ids = address_obj.search(cursor, uid, filter)
criteria.append(('address.zip', 'ilike', postal_code))
partner_search_ids = partner_obj.search(
cr, uid, criteria, context=context)
key = name.lower()
# Make sure to get a unique list
partner_ids = list(set([x.partner_id.id
for x in address_obj.browse(cursor, uid, address_ids)
# Beware for dangling addresses
if _has_attr(x.partner_id, 'name') and
x.partner_id.name.lower() in key
]))
partners = []
for partner in partner_obj.read(
cr, uid, partner_search_ids, ['name'], context=context):
if (len(partner['name']) > 3 and partner['name'].lower() in key):
partners.append(partner)
partners.sort(key=lambda x: len(x['name']), reverse=True)
partner_ids = [x['id'] for x in partners]
if not partner_ids:
if (not country_code) or not country_id:
user = pool.get('res.user').browse(cursor, uid, uid)
if not country_id:
user = pool.get('res.user').browse(cr, uid, uid, context=context)
country_id = (
user.company_id.partner_id.country and
user.company_id.partner_id.country.id or
False
)
partner_id = partner_obj.create(cursor, uid, dict(
name=name, active=True, comment='Generated from Bank Statements Import',
partner_id = partner_obj.create(cr, uid, dict(
name=name, active=True,
comment='Generated from Bank Statements Import',
address=[(0,0,{
'street': address and address[0] or '',
'street2': len(address) > 1 and address[1] or '',
'city': city,
'zip': postal_code or '',
'country_id': country_id,
})],
))
elif len(partner_ids) > 1:
log.append(
_('More then one possible match found for partner with name %(name)s')
% {'name': name}
)
return False
})]), context=context)
else:
if len(partner_ids) > 1:
log.append(
_('More than one possible match found for partner with '
'name %(name)s') % {'name': name})
partner_id = partner_ids[0]
return partner_id
@@ -317,7 +313,7 @@ def get_or_create_bank(pool, cursor, uid, bic, online=False, code=None,
def create_bank_account(pool, cursor, uid, partner_id,
account_number, holder_name, address, city,
country_code, log
country_code, log, bic=False,
):
'''
Create a matching bank account with this holder for this partner.
@@ -327,7 +323,6 @@ def create_bank_account(pool, cursor, uid, partner_id,
owner_name = holder_name,
)
bankcode = None
bic = None
country_obj = pool.get('res.country')
# Are we dealing with IBAN?

View File

@@ -88,6 +88,7 @@ class transaction(models.mem_bank_transaction):
'GIRO': bt.ORDER,
'INTL': bt.ORDER, # international order
'UNKN': bt.ORDER, # everything else
'SEPA': bt.ORDER,
}
def __init__(self, line, *args, **kwargs):
@@ -134,24 +135,97 @@ class transaction(models.mem_bank_transaction):
size = 33
res = []
while(len(line) > col * size):
if line[col * size : (col + 1) * size - 1].strip():
res.append(line[col * size : (col + 1) * size - 1])
separation = (col + 1) * size - 1
if line[col * size : separation].strip():
part = line[col * size : separation]
# If the separation character is not a space, add it anyway
# presumably for sepa feedback strings only
if (len(line) > separation
and line[separation] != ' '):
part += line[separation]
res.append(part)
col += 1
return res
def get_sepa_dict(field):
"""
Parses a subset of SEPA feedback strings as occur
in this non-SEPA csv format.
The string consists of slash separated KEY/VALUE pairs,
but the slash is allowed to and known to occur in VALUE as well!
"""
def _sepa_message(field, reason):
return _(
'unable to parse SEPA string: %s - %s' % (field, reason))
def _get_next_key(items, start):
'''Find next key, starting from start, returns the key found,
the start position in the array and the end position + 1'''
known_keys = [
'TRTP', 'IBAN', 'BIC', 'NAME', 'RTRN', 'EREF', 'SWOC',
'REMI', 'ADDR', 'CPRP', 'CREF', 'CSID', 'ISDT', 'MARF',
'NRTX', 'NRTXR', 'PREF', 'PURP', 'REFOB', 'RREF', 'RTYP',
'SVCL', 'SWOD', 'BENM//ID', 'ORDP//ID', 'ORDP//RID',
'ORIG//CSID', 'ORIG//MARF', 'ULTD//NAME', 'ULTD//ID',
'ULTB//NAME', 'ULTB//ID'
]
items_len = len(items)
start_index = start
# Search until start after end of items
while start_index < items_len:
end_index = start_index + 1
while end_index < items_len:
key = '/'.join(items[start_index:end_index])
if key in known_keys:
return (key, start_index, end_index)
end_index += 1
start_index += 1
return False
items = field[1:].split('/')
assert len(items) > 1, _sepa_message(field, _('too few items'))
sepa_dict = {}
item_index = 0
items_len = len(items)
key_info = _get_next_key(items, item_index)
assert key_info, _sepa_message(
field, _('no key found for start %d') % item_index)
assert key_info[1] == 0, _sepa_message(
field, _('invalid data found before key %s') % key_info[0])
while key_info:
sepa_key = key_info[0]
item_index = key_info[2]
# Find where next key - if any - starts
key_info = _get_next_key(items, item_index)
value_end_index = (key_info and key_info[1]) or items_len
sepa_value = (
((value_end_index > item_index)
and '/'.join(items[item_index:value_end_index]))
or '')
sepa_dict[sepa_key] = sepa_value
return sepa_dict
def parse_type(field):
# here we process the first field, which identifies the statement type
# and in case of certain types contains additional information
transfer_type = 'UNKN'
remote_account = False
remote_owner = False
if field.startswith('GIRO '):
if field.startswith('/TRTP/'):
transfer_type = 'SEPA'
elif field.startswith('GIRO '):
transfer_type = 'GIRO'
# columns 6 to 14 contain the left or right aligned account number
remote_account = field[:15].strip().zfill(10)
# column 15 contains a space
# columns 16 to 31 contain remote owner
remote_owner = field[16:32].strip() or False
# field has markup 'GIRO ACCOUNT OWNER'
# separated by clusters of space of varying size
account_match = re.match('\s*([0-9]+)\s(.*)$', field[5:])
if account_match:
remote_account = account_match.group(1).zfill(10)
remote_owner = account_match.group(2).strip() or ''
else:
raise osv.except_osv(
_('Error !'),
_('unable to parse GIRO string: %s') % field)
elif field.startswith('BEA '):
transfer_type = 'BEA'
# columns 6 to 16 contain the terminal identifier
@@ -176,8 +250,22 @@ class transaction(models.mem_bank_transaction):
fields = split_blob(self.blob)
(self.transfer_type, self.remote_account, self.remote_owner) = parse_type(fields[0])
if self.transfer_type == 'SEPA':
sepa_dict = get_sepa_dict(''.join(fields))
sepa_type = sepa_dict.get('TRTP')
if sepa_type != 'SEPA OVERBOEKING':
raise ValueError,_('Sepa transaction type %s not handled yet')
self.remote_account = sepa_dict.get('IBAN',False)
self.remote_bank_bic = sepa_dict.get('BIC', False)
self.remote_owner = sepa_dict.get('NAME', False)
self.reference = sepa_dict.get('REMI', '')
# extract other information depending on type
if self.transfer_type == 'GIRO':
elif self.transfer_type == 'GIRO':
if not self.remote_owner and len(fields) > 1:
# OWNER is listed in the second field if not in the first
self.remote_owner = fields[1].strip() or False
fields = [fields[0]] + fields[2:]
self.message = ' '.join(field.strip() for field in fields[1:])
elif self.transfer_type == 'BEA':
@@ -206,7 +294,7 @@ class transaction(models.mem_bank_transaction):
if fields[2].startswith('/'):
self.remote_account = fields[2][1:].strip()
else:
self.message += ' ' + fields[2].strip()
self.remote_account = fields[2].strip()
# fourth column contains remote owner
self.remote_owner = (len(fields) > 3 and fields[3].strip() or
False)
@@ -219,11 +307,12 @@ class transaction(models.mem_bank_transaction):
if not self.reference:
# the reference is sometimes flagged by the prefix "BETALINGSKENM."
# but can be any numeric line really
refexpr = re.compile("^\s*(BETALINGSKENM\.)?\s*([0-9]+ ?)+\s*$")
for field in fields[1:]:
m = refexpr.match(field)
m = re.match(
"^\s*((BETALINGSKENM\.)|(ACCEPTGIRO))?\s*([0-9]+([ /][0-9]+)*)\s*$",
field)
if m:
self.reference = m.group(2)
self.reference = m.group(4)
break
class statement(models.mem_bank_statement):

View File

@@ -61,7 +61,10 @@ class clieop_export(osv.osv):
'date_generated':
fields.date('Generation Date', readonly=True, select=True),
'file':
fields.binary('ClieOp File', readonly=True),
fields.binary('ClieOp File', readonly=True,),
'filename': fields.char(
'File Name', size=32,
),
'state':
fields.selection([
('draft', 'Draft'),
@@ -69,6 +72,7 @@ class clieop_export(osv.osv):
('done', 'Reconciled'),
], 'State', readonly=True),
}
def get_daynr(self, cr, uid, context=None):
'''
Return highest day number

View File

@@ -14,33 +14,34 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Client Opdrachten Export">
<notebook>
<page string="General Information">
<field name="filetype" />
<field name="identification" />
<separator string="ClieOp Information" colspan="4" />
<field name="total_amount" />
<field name="check_no_accounts" />
<field name="no_transactions" />
<separator string="Processing Information" colspan="4" />
<field name="prefered_date" />
<field name="date_generated" />
<field name="testcode" />
<newline />
<field name="file" colspan="4" />
</page>
<page string="Payment Orders">
<field name="payment_order_ids" colspan="4" nolabel="1">
<tree colors="blue:state in ('draft');gray:state in ('cancel','done');black:state in ('open')" string="Payment order">
<field name="reference"/>
<field name="date_created"/>
<field name="date_done"/>
<field name="total"/>
<field name="state"/>
</tree>
</field>
</page>
</notebook>
<notebook>
<page string="General Information">
<field name="filetype" />
<field name="identification" />
<separator string="ClieOp Information" colspan="4" />
<field name="total_amount" />
<field name="check_no_accounts" />
<field name="no_transactions" />
<separator string="Processing Information" colspan="4" />
<field name="prefered_date" />
<field name="date_generated" />
<field name="testcode" />
<newline />
<field name="filename" invisible="True"/>
<field name="file" colspan="4" filename="filename"/>
</page>
<page string="Payment Orders">
<field name="payment_order_ids" colspan="4" nolabel="1">
<tree colors="blue:state in ('draft');gray:state in ('cancel','done');black:state in ('open')" string="Payment order">
<field name="reference"/>
<field name="date_created"/>
<field name="date_done"/>
<field name="total"/>
<field name="state"/>
</tree>
</field>
</page>
</notebook>
</form>
</field>
</record>

View File

@@ -0,0 +1,345 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_nl_clieop
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-11-01 16:23+0000\n"
"PO-Revision-Date: 2012-11-01 18:11+0100\n"
"Last-Translator: Erwin van der Ploeg | Endian Solutions "
"<erwin@endiansolutions.nl>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.4\n"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop.wizard,batchtype:0
msgid "Direct Debits"
msgstr "Incasso opdrachten"
#. module: account_banking_nl_clieop
#: code:addons\account_banking_nl_clieop\account_banking_nl_clieop.py:39
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:94
#: selection:banking.export.clieop,testcode:0
#: selection:banking.export.clieop.wizard,testcode:0
#, python-format
msgid "No"
msgstr "Nee"
#. module: account_banking_nl_clieop
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:290
#, python-format
msgid "There is insufficient information"
msgstr "Er is onvoldoende informatie"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
#: selection:banking.export.clieop.wizard,state:0
msgid "Create"
msgstr "Aanmaken"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,no_transactions:0
#: field:banking.export.clieop.wizard,no_transactions:0
msgid "Number of Transactions"
msgstr "Aantal transacties"
#. module: account_banking_nl_clieop
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:211
#, python-format
msgid "You can't create ClieOp orders more than 30 days in advance."
msgstr ""
"Het is niet mogelijk een ClieOp betaalopdracht te maken, 30 dagen van te "
"voren."
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,state:0
#: field:banking.export.clieop.wizard,state:0
msgid "State"
msgstr "Status"
#. module: account_banking_nl_clieop
#: help:banking.export.clieop.wizard,test:0
msgid ""
"Select this if you want your bank to run a test process rather then execute "
"your orders for real."
msgstr ""
"Selecteer dit indien u wilt dat uw bank een test uitvoert in plaats van een "
"werkelijke verwerking."
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,identification:0
#: field:banking.export.clieop.wizard,identification:0
msgid "Identification"
msgstr "Identificatie"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "Processing Information"
msgstr "Verwerkingsinformatie"
#. module: account_banking_nl_clieop
#: help:banking.export.clieop.wizard,fixed_message:0
msgid ""
"A fixed message to apply to all transactions in addition to the individual "
"messages."
msgstr ""
"Een vast bericht dat alle transacties betreft, als toevoeging op de "
"Individuele berichten."
#. module: account_banking_nl_clieop
#: model:ir.model,name:account_banking_nl_clieop.model_banking_export_clieop
msgid "banking.export.clieop"
msgstr "banking.export.clieop"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,check_no_accounts:0
#: field:banking.export.clieop.wizard,check_no_accounts:0
msgid "Check Number Accounts"
msgstr "Controlegetal rekeningen"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,batchtype:0
msgid "Type"
msgstr "Type"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Sent"
msgstr "Verzonden"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "ClieOp Information"
msgstr "ClieOp-informatie"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
#: selection:banking.export.clieop.wizard,state:0
msgid "Finish"
msgstr "Gereed"
#. module: account_banking_nl_clieop
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:216
#, python-format
msgid "You can only combine payment orders of the same type"
msgstr "U kunt alleen maar betaalopdrachten van hetzelfde type combineren."
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,filetype:0
#: selection:banking.export.clieop.wizard,filetype:0
msgid "Salary Payment Batch"
msgstr "Salarisbetalingsbatch"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Reconciled"
msgstr "Afgeletterd"
#. module: account_banking_nl_clieop
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:252
#, python-format
msgid "Your bank account has to have a valid account number"
msgstr "Uw bankrekening moet een geldig rekeningnummer hebben."
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
msgid "Reference for further communication"
msgstr "Referentie voor verdere communicatie"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,duplicates:0
msgid "Number of Duplicates"
msgstr "Aantal duplicaten"
#. module: account_banking_nl_clieop
#: help:banking.export.clieop.wizard,reference:0
msgid ""
"The bank will use this reference in feedback communication to refer to this "
"run. Only five characters are available."
msgstr ""
"De bank zal deze referentie gebruiken in de teruggekoppelde communicatie "
"betreffende deze batch. Er zijn maar 5 karakters beschikbaar."
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
msgid "Processing Details"
msgstr "Verwerking details"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,testcode:0
#: field:banking.export.clieop.wizard,test:0
#: field:banking.export.clieop.wizard,testcode:0
msgid "Test Run"
msgstr "Testverwerking"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,filetype:0
#: selection:banking.export.clieop.wizard,filetype:0
msgid "Direct Debit Batch"
msgstr "Incassobatch"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,prefered_date:0
#: field:banking.export.clieop.wizard,prefered_date:0
msgid "Prefered Processing Date"
msgstr "Gewenste verwerkingsdatum"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,file:0
#: field:banking.export.clieop.wizard,file_id:0
msgid "ClieOp File"
msgstr "ClieOp-bestand"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,file:0
msgid "File"
msgstr "Bestand"
#. module: account_banking_nl_clieop
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:312
#, python-format
msgid "You cannot send international bank transfers through ClieOp3!"
msgstr ""
"Het is niet mogelijk om een internationale betaling te doen met behulp van "
"ClieOp3!"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,execution_date:0
msgid "Execution Date"
msgstr "Uitvoeringsdatum"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,fixed_message:0
msgid "Fixed Message"
msgstr "Vast bericht"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,filetype:0
#: field:banking.export.clieop.wizard,filetype:0
msgid "File Type"
msgstr "Bestandsformaat"
#. module: account_banking_nl_clieop
#: model:ir.actions.act_window,name:account_banking_nl_clieop.act_banking_export_clieop_payment_order
#: model:ir.actions.act_window,name:account_banking_nl_clieop.action_account_banking_clieops
#: model:ir.ui.menu,name:account_banking_nl_clieop.menu_action_account_banking_exported_clieop_files
msgid "Generated ClieOp3 Files"
msgstr "Gegenereerde ClieOp3-bestanden"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop.wizard,batchtype:0
msgid "Payments"
msgstr "Betalingen"
#. module: account_banking_nl_clieop
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:210
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:215
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:251
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:289
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:311
#, python-format
msgid "Error"
msgstr "Fout"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop.wizard,batchtype:0
msgid "Salary Payments"
msgstr "Salaris betalingen"
#. module: account_banking_nl_clieop
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:348
#: view:banking.export.clieop:0 view:banking.export.clieop.wizard:0
#: model:ir.model,name:account_banking_nl_clieop.model_banking_export_clieop_wizard
#, python-format
msgid "Client Opdrachten Export"
msgstr "Betaalopdrachten export"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
msgid "Additional message for all transactions"
msgstr "Additionele berichten voor alle transacties"
#. module: account_banking_nl_clieop
#: help:banking.export.clieop.wizard,execution_date:0
msgid ""
"This is the date the file should be processed by the bank. Don't choose a "
"date beyond the nearest date in your payments. The latest allowed date is 30 "
"days from now.\n"
"Please keep in mind that banks only execute on working days and typically "
"use a delay of two days between execution date and effective transfer date."
msgstr ""
"Dit si de datum waarop het bestand moet worden verwerkt door de bank. Kies "
"geen datum verder dan de dichtsbijzijnde datum in uw betalingen. De laatst "
"toegestane datum is 30 fagen vanaf nu. \n"
"Houd u er rekening mee dat banken alleen bestanden verwerken op werkdagen en "
"normaliter een vertraging hanteren van twee dagen tussen de uitvoeringsdatum "
"en de effectieve overboekingsdatum."
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,total_amount:0
#: field:banking.export.clieop.wizard,total_amount:0
msgid "Total Amount"
msgstr "Totaalbedrag"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,reference:0
msgid "Reference"
msgstr "Referentie"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "Payment order"
msgstr "Betaalopdracht"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
#: field:banking.export.clieop,payment_order_ids:0
#: field:banking.export.clieop.wizard,payment_order_ids:0
msgid "Payment Orders"
msgstr "Betalingsopdrachten"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "General Information"
msgstr "Algemene informatie"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,daynumber:0
msgid "ClieOp Transaction nr of the Day"
msgstr "ClieOp dagtransactienummer"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
msgid "Cancel"
msgstr "Annuleren"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Draft"
msgstr "Concept"
#. module: account_banking_nl_clieop
#: code:addons\account_banking_nl_clieop\account_banking_nl_clieop.py:39
#: code:addons\account_banking_nl_clieop\wizard\export_clieop.py:94
#: selection:banking.export.clieop,testcode:0
#: selection:banking.export.clieop.wizard,testcode:0
#, python-format
msgid "Yes"
msgstr "Ja"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,filetype:0
#: selection:banking.export.clieop.wizard,filetype:0
msgid "Payment Batch"
msgstr "Betalingsbatch"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,date_generated:0
msgid "Generation Date"
msgstr "Aanmaakdatum"

View File

@@ -1,395 +0,0 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_nl_clieop
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 5.0.7\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-02-12 13:29:33+0000\n"
"PO-Revision-Date: 2010-01-07 22:22:23+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_nl_clieop
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
msgstr ""
"De objectnaam moet beginnen met x_ en mag geen speciale karakters bevatten !"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Direct Debits"
msgstr "Incasso-batch"
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid ""
"There is insufficient information.\r\n"
"'\n"
" 'Both destination address and account '\n"
" 'number must be provided"
msgstr ""
"Er is onvoldoende informatie.\r\n"
"'\n"
" 'Zowel begunstigde als extern rekeningnummer '\n"
" 'dienen bekende te zijn"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,testcode:0
#: code:addons/account_banking_nl_clieop/account_banking_nl_clieop.py:0
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#: selection:banking.export.clieop,testcode:0
#, python-format
msgid "No"
msgstr "Nee"
#. module: account_banking_nl_clieop
#: model:ir.module.module,shortdesc:account_banking_nl_clieop.module_meta_information
msgid "Account Banking NL ClieOp"
msgstr "Account Banking NL ClieOp"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,no_transactions:0
#: field:banking.export.clieop,no_transactions:0
msgid "Number of Transactions"
msgstr "Aantal transacties"
#. module: account_banking_nl_clieop
#: model:ir.actions.wizard,name:account_banking_nl_clieop.wizard_account_banking_export_clieop
msgid "Export ClieOp File"
msgstr "Exporteer ClieOp-bestand"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,prefered_date:0
#: field:banking.export.clieop,prefered_date:0
msgid "Prefered Processing Date"
msgstr "Gewenste verwerkingsdatum"
#. module: account_banking_nl_clieop
#: model:payment.type,name:account_banking_nl_clieop.export_clieop_pay
msgid "ClieOp3 Payment Batch"
msgstr "ClieOp3 betalingsbatch"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,state:0
msgid "State"
msgstr "Status"
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,test:0
msgid ""
"Select this if you want your bank to run a test process rather then execute "
"your orders for real."
msgstr ""
"Kies dit als u wilt dat de bank een testrun draait in plaats van uw "
"opdrachten te verwerken."
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Draft"
msgstr "Concept"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "Processing Information"
msgstr "Verwerkingsinformatie"
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,fixed_message:0
msgid ""
"A fixed message to apply to all transactions in addition to the individual "
"messages."
msgstr ""
"Een vast bericht om toe te voegen aan alle transacties in toevoeging op de "
"individuele berichten."
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,check_no_accounts:0
#: field:banking.export.clieop,check_no_accounts:0
msgid "Check Number Accounts"
msgstr "Controlegetal rekeningen"
#. module: account_banking_nl_clieop
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
msgstr "Ongeldige naam in actie-definitie."
#. module: account_banking_nl_clieop
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,create,save:0
msgid "Save"
msgstr "Opslaan"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Type"
msgstr "Soort"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Sent"
msgstr "Verzonden"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,log:0
msgid "Log"
msgstr "Log"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "ClieOp Information"
msgstr "ClieOp-informatie"
#. module: account_banking_nl_clieop
#: model:ir.model,name:account_banking_nl_clieop.model_banking_export_clieop
msgid "ClieOp3 Export"
msgstr "ClieOp3-export"
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "You can only combine payment orders of the same type"
msgstr "U kunt alleen betalingsopdrachten van dezelfde soort combineren"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: selection:banking.export.clieop,filetype:0
msgid "Salary Payment Batch"
msgstr "Salarisbetalingsbatch"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Reconciled"
msgstr "Afgeletterd"
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "Your bank account has to have a valid account number"
msgstr "Uw bankrekening dient een geldig rekeningnummer te hebben"
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
msgid "Reference for further communication"
msgstr "Referentie voor verdere communicatie"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,duplicates:0
msgid "Number of Duplicates"
msgstr "Aantal duplicaten"
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,reference:0
msgid ""
"The bank will use this reference in feedback communication to refer to this "
"run. Only five characters are available."
msgstr ""
"De bank zal dit gebruiken in terugkoppelingsberichten om te referen aan deze "
"verwerking. Slechts vijf tekens zijn beschikbaar."
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
msgid "Processing Details"
msgstr "Verwerkingsdetails"
#. module: account_banking_nl_clieop
#: model:payment.type,name:account_banking_nl_clieop.export_clieop_sal
msgid "ClieOp3 Salary Payment Batch"
msgstr "ClieOp3 salarisverwerking"
#. module: account_banking_nl_clieop
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,init,create:0
msgid "Create"
msgstr "Maak"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: selection:banking.export.clieop,filetype:0
msgid "Direct Debit Batch"
msgstr "Incassobatch"
#. module: account_banking_nl_clieop
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
msgstr "Ongeldige XML voor overzicht"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,file:0
#: field:banking.export.clieop,file:0
msgid "ClieOp File"
msgstr "ClieOp-bestand"
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid ""
"You cannot send international bank transfers '\n"
" 'through ClieOp3!"
msgstr ""
"U kunt geen internationale betalingen met ClieOp3'\n"
" ' insturen!"
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "You can\'t create ClieOp orders more than 30 days in advance."
msgstr "U kunt geen ClieOp opdrachten aanmaken voor meer dan 30 dagen vooruit."
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,execution_date:0
msgid "Execution Date"
msgstr "Uitvoeringsdatum"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,fixed_message:0
msgid "Fixed Message"
msgstr "Vast bericht"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: field:banking.export.clieop,filetype:0
msgid "File Type"
msgstr "Bestandsformaat"
#. module: account_banking_nl_clieop
#: model:payment.type,name:account_banking_nl_clieop.export_clieop_inc
msgid "ClieOp3 Direct Debit Batch"
msgstr "ClieOp3 incassoverwerking"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,testcode:0
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,test:0
#: field:banking.export.clieop,testcode:0
msgid "Test Run"
msgstr "Testverwerking"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Payments"
msgstr "Betalingen"
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "Error"
msgstr "Fout"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Salary Payments"
msgstr "Salarisbetalingen"
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,create:0
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
#: view:banking.export.clieop:0
msgid "Client Opdrachten Export"
msgstr "Client Opdrachten Export"
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
msgid "Additional message for all transactions"
msgstr "Toegevoegd bericht voor alle transacties"
#. module: account_banking_nl_clieop
#: model:ir.actions.act_window,name:account_banking_nl_clieop.action_account_banking_clieops
#: model:ir.ui.menu,name:account_banking_nl_clieop.menu_action_account_banking_exported_clieop_files
msgid "Generated ClieOp3 Files"
msgstr "Gegenereerde ClieOp3-bestanden"
#. module: account_banking_nl_clieop
#: model:ir.module.module,description:account_banking_nl_clieop.module_meta_information
msgid ""
"\n"
" Module to export payment orders in ClieOp format.\n"
"\n"
" ClieOp format is used by Dutch banks to batch national bank transfers.\n"
" This module uses the account_banking logic.\n"
" "
msgstr ""
"\n"
" Module voor het exporteren van betalingsopdrachten in ClieOp-formaat.\n"
"\n"
" ClieOp-formaat wordt gebruikt door Nederlandse banks voor "
"batchverwerking van national banktransacties.\n"
" Deze module gebruikt de account_banking logica.\n"
" "
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,reference:0
msgid "Reference"
msgstr "Referentie"
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,execution_date:0
msgid ""
"This is the date the file should be processed by the bank. Don't choose a "
"date beyond the nearest date in your payments. The latest allowed date is 30 "
"days from now.\n"
"Please keep in mind that banks only execute on working days and typically "
"use a delay of two days between execution date and effective transfer date."
msgstr ""
"Dit is de datum dat het bestand verwerkt dient te worden door de bank. Kies "
"geen datum verder dan 30 dagen vooruit.\n"
"Onthoud dat veel banken in alleen verwerken op werkdagen en dat er doorgaans "
"twee dagen vertraging zit tussen verwerkingsdatum en effectieve datum.\n"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,payment_order_ids:0
msgid "Payment Orders"
msgstr "Betalingsopdrachten"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "General Information"
msgstr "Algemene informatie"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,total_amount:0
#: field:banking.export.clieop,total_amount:0
msgid "Total Amount"
msgstr "Totaalbedrag"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,daynumber:0
msgid "ClieOp Transaction nr of the Day"
msgstr "ClieOp dagtransactienummer"
#. module: account_banking_nl_clieop
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,create,cancel:0
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,init,end:0
msgid "Cancel"
msgstr "Annuleren"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,identification:0
#: field:banking.export.clieop,identification:0
msgid "Identification"
msgstr "Identificatie"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,testcode:0
#: code:addons/account_banking_nl_clieop/account_banking_nl_clieop.py:0
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#: selection:banking.export.clieop,testcode:0
#, python-format
msgid "Yes"
msgstr "Ja"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: selection:banking.export.clieop,filetype:0
msgid "Payment Batch"
msgstr "Betalingsbatch"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,date_generated:0
msgid "Generation Date"
msgstr "Aanmaakdatum"

View File

@@ -43,6 +43,11 @@ class SWIFTField(record.Field):
#def format(self, value):
# return convert.to_swift(super(SWIFTField, self).format(value))
class SWIFTFieldNoLeadingWhitespace(SWIFTField):
def format(self, value):
return super(SWIFTFieldNoLeadingWhitespace, self).format(
self.cast(value).lstrip())
def eleven_test(s):
'''
Dutch eleven-test for validating 9-long local bank account numbers.
@@ -161,7 +166,7 @@ class PaymentReferenceRecord(record.Record):
_fields = [
record.Filler('recordcode', 4, '0150'),
record.Filler('variantcode', 1, 'A'),
SWIFTField('paymentreference', 16),
SWIFTFieldNoLeadingWhitespace('paymentreference', 16),
record.Filler('filler', 29),
]
@@ -276,9 +281,10 @@ class Transaction(object):
self.paymentreference = Optional(PaymentReferenceRecord)
self.description = Optional(DescriptionRecord, 4)
self.transaction.transactiontype = type_
self.transaction.accountno_beneficiary = accountno_beneficiary
self.transaction.accountno_payer = accountno_payer
self.transaction.amount = int(amount * 100)
# Remove Postbank account marker 'P'
self.transaction.accountno_beneficiary = accountno_beneficiary.replace('P', '0')
self.transaction.accountno_payer = accountno_payer.replace('P', '0')
self.transaction.amount = int(round(amount * 100))
if reference:
self.paymentreference.paymentreference = reference
# Allow long message lines to redistribute over multiple message

View File

@@ -138,13 +138,19 @@ class banking_export_clieop_wizard(osv.osv_memory):
readonly=True,
string='File',
),
'filename': fields.related(
'file_id', 'filename',
type='char', size=32,
readonly=True,
string='Filename',
),
'payment_order_ids': fields.many2many(
'payment.order', 'rel_wiz_payorders', 'wizard_id',
'payment_order_id', 'Payment Orders',
readonly=True,
),
}
_defaults = {
'test': True,
}
@@ -334,6 +340,7 @@ class banking_export_clieop_wizard(osv.osv_memory):
no_transactions = order.nr_posts,
testcode = order.testcode,
file = base64.encodestring(clieopfile.rawdata),
filename = 'Clieop03-{0}.txt'.format(order.identification),
daynumber = int(clieopfile.header.file_id[2:]),
payment_order_ids = [
[6, 0, [x.id for x in clieop_export['payment_order_ids']]]
@@ -375,7 +382,7 @@ class banking_export_clieop_wizard(osv.osv_memory):
clieop_obj = self.pool.get('banking.export.clieop')
payment_order_obj = self.pool.get('payment.order')
clieop_file = clieop_obj.write(
cursor, uid, clieop_export['file_id'].id, {'state':'sent'}
cursor, uid, clieop_export['file_id'].id, {'state': 'sent'}
)
wf_service = netsvc.LocalService('workflow')
for order in clieop_export['payment_order_ids']:

View File

@@ -6,53 +6,54 @@
<field name="model">banking.export.clieop.wizard</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Client Opdrachten Export">
<field name="state" invisible="True"/>
<group states="create">
<separator colspan="4" string="Processing Details" />
<field name="batchtype" />
<field name="execution_date" />
<field name="test" />
<separator colspan="4" string="Reference for further communication" />
<field name="reference" colspan="2" />
<separator colspan="4" string="Additional message for all transactions" />
<field name="fixed_message" />
<newline/>
<button icon="gtk-close"
special="cancel"
string="Cancel"
/>
<button icon="gtk-ok"
string="Create"
name="create_clieop"
type="object"
/>
</group>
<group states="finish">
<field name="filetype" />
<field name="identification" />
<field name="total_amount" />
<field name="check_no_accounts" />
<field name="no_transactions" />
<field name="prefered_date" />
<field name="testcode" />
<newline/>
<field name="file_id" />
<field name="file" />
<newline/>
<button icon="gtk-close"
string="Cancel"
name="cancel_clieop"
type="object"
/>
<button icon="gtk-ok"
string="Finish"
name="save_clieop"
type="object"
/>
</group>
</form>
</field>
</record>
<form string="Client Opdrachten Export">
<field name="state" invisible="True"/>
<group states="create">
<separator colspan="4" string="Processing Details" />
<field name="batchtype" />
<field name="execution_date" />
<field name="test" />
<separator colspan="4" string="Reference for further communication" />
<field name="reference" colspan="2" />
<separator colspan="4" string="Additional message for all transactions" />
<field name="fixed_message" />
<newline/>
<button icon="gtk-close"
special="cancel"
string="Cancel"
/>
<button icon="gtk-ok"
string="Create"
name="create_clieop"
type="object"
/>
</group>
<group states="finish">
<field name="filetype" />
<field name="identification" />
<field name="total_amount" />
<field name="check_no_accounts" />
<field name="no_transactions" />
<field name="prefered_date" />
<field name="testcode" />
<newline/>
<field name="filename" invisible="True"/>
<field name="file_id" />
<field name="file" filename="filename"/>
<newline/>
<button icon="gtk-close"
string="Cancel"
name="cancel_clieop"
type="object"
/>
<button icon="gtk-ok"
string="Finish"
name="save_clieop"
type="object"
/>
</group>
</form>
</field>
</record>
</data>
</openerp>

View File

@@ -194,7 +194,7 @@ class transaction(models.mem_bank_transaction):
'''
if self.transfer_type == 'VZ':
# Credit bank costs (interest) gets a special treatment.
if self.remote_owner.starswith('RC AFREK. REK. '):
if self.remote_owner.startswith('RC AFREK. REK. '):
self.transfer_type = 'DV'
if self.transfer_type == 'DV':

View File

@@ -31,9 +31,9 @@
##############################################################################
{
'name': 'ING (NL) Bank Statements Import',
'version': '0.1.105',
'version': '0.1.140',
'license': 'GPL-3',
'author': 'Smile / Therp BV / EduSense BV',
'author': ['Smile', 'Therp BV', 'EduSense BV'],
'website': 'https://launchpad.net/banking-addons',
'category': 'Banking addons',
'depends': ['account_banking'],
@@ -43,7 +43,7 @@
'demo_xml': [],
'description': '''
Module to import Dutch ING bank format transaction files. The format covered
is the CSV format with 'ddmmyy' date syntax.
is the CSV format with either 'dd-mm-yyyy' or 'yyyymmdd' date syntax.
As the ING bank does not provide detailed specification concerning possible
values and their meaning for the fields in the CSV file format, the statements

View File

@@ -24,7 +24,7 @@ msgstr "ING (NL) Bankafschriften importeren "
#: model:ir.module.module,description:account_banking_nl_ing.module_meta_information
msgid "Module to import Dutch ING bank format transaction files. The format covered is the CSV format with 'ddmmyy' date syntax.As the ING bank does not provide detailed specification concerning possiblevalues and their meaning for the fields in the CSV file format, the statementsare parsed according to an educated guess based on incomplete information.You can contact the banking-addons developers through their launchpad page andhelp improve the performance of this import filter onhttps://launchpad.net/banking-addons.Note that imported bank transfers are organized in statements covering periodsof one week, even if the imported files cover a different period.This modules contains no logic, just an import filter for account_banking. "
msgstr "Module voor het importeren van bankafschriften van de Nederlandse ING bank.\n"
"Bestanden in het CSV-formaat met datumindeling 'ddmmjj' kunnen worden verwerkt.\n\n"
"Bestanden in het CSV-formaat met datumindeling 'dd-mm-jjjj' of 'jjjjmmdd' kunnen worden verwerkt.\n\n"
"Gezien het feit dat de ING geen enkele vorm van specificaties\n"
"beschikbaar stelt, is de importroutine samengesteld op basis van \n"
"voorbeeldbestanden, en kan volledige dekking niet worden gegarandeerd. U\n"

View File

@@ -67,7 +67,10 @@ class transaction_message(object):
re.sub(',', '.', self.transferred_amount))
if self.debcred == 'Af':
self.transferred_amount = -self.transferred_amount
self.execution_date = self.effective_date = str2date(self.date, '%Y%m%d')
try:
self.execution_date = self.effective_date = str2date(self.date, '%Y%m%d')
except ValueError:
self.execution_date = self.effective_date = str2date(self.date, '%d-%m-%Y')
self.statement_id = '' #self.effective_date.strftime('%Yw%W')
self.id = str(subno).zfill(4)
self.reference = ''
@@ -178,7 +181,10 @@ class statement(models.mem_bank_statement):
super(statement, self).__init__(*args, **kwargs)
self.id = msg.statement_id
self.local_account = msg.local_account
self.date = str2date(msg.date, '%Y%m%d')
try:
self.date = str2date(msg.date, '%Y%m%d')
except ValueError:
self.date = str2date(msg.date, '%d-%m-%Y')
self.start_balance = self.end_balance = 0 # msg.start_balance
self.import_transaction(msg)

View File

@@ -58,7 +58,7 @@ msgstr "Incasso geweigerd"
#. module: account_direct_debit
#: help:payment.mode,transfer_account_id:0
msgid "Pay off lines in sent orders with a move on this account. For debit type modes only. You can only select accounts of type regular that are marked for reconciliation"
msgstr "Betaal op het moment van versturen de openstaande posten met een boeking op deze rekening. Alleen van toepassing op een incassomodus. Alleen rekeningen van type 'normaal' kunnen hier worden geselecteerd, die ook voorzien zijn van kemnerk 'afletteren'.
msgstr "Betaal op het moment van versturen de openstaande posten met een boeking op deze rekening. Alleen van toepassing op een incassomodus. Alleen rekeningen van type 'normaal' kunnen hier worden geselecteerd, die ook voorzien zijn van kenmerk 'afletteren'.
#. module: account_direct_debit
#: field:account.move.line,invoice_state:0

View File

@@ -89,7 +89,7 @@ class account_move_line(osv.osv):
def _dummy(self, cr, user, ids, name, arg, context=None):
res = {}
if ids:
res = dict([(x.id, False) for x in ids])
res = dict([(x, False) for x in ids])
return res
def _invoice_payment_term_id_search(

View File

@@ -447,6 +447,7 @@ class payment_order_create(osv.osv_memory):
('account_id.type', '=', 'payable'),
('amount_to_pay', '>', 0)
]
domain.append(('company_id', '=', payment.mode.company_id.id))
# apply payment term filter
if payment.mode.payment_term_ids:
domain = domain + [

View File

@@ -63,8 +63,14 @@
<field name="type">form</field>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="transfer_account_id"/>
<field name="transfer_journal_id"/>
<field name="transfer_account_id"
domain="[('type', '=', 'other'),
('reconcile', '=', True),
('company_id', '=', company_id)]"
/>
<field name="transfer_journal_id"
domain="[('company_id', '=', company_id)]"
/>
<field name="payment_term_ids"/>
</field>
</field>

View File

@@ -12,7 +12,7 @@
another state, 'sent_wait' between sent and done.
-->
<record id="account_payment.act_done" model="workflow.activity">
<field name="flow_stop">False</field>
<field name="flow_stop" eval="False"/>
</record>
<record id="trans_done_sent" model="workflow.transition">

View File

@@ -0,0 +1 @@
import model

View File

@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2012 Therp BV (<http://therp.nl>).
#
# 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/>.
#
##############################################################################
{
"name": "Bank statement instant voucher",
"version": "1.0r028",
"author": "Therp BV",
"category": 'Base',
'complexity': "normal",
"description": """
This module adds a new button on the bank statement line that allows the
accountant to instantly create a sales or purchase voucher based on the
values of the bank statement line.
This module does not depend on account_banking, but if this module is
installed, the bank statement line will be reconciled automatically
in the confirmation step of the wizard.
If account_banking is not installed, the accountant will still have to
reconcile the associated move line with the move line from the bank
statement line manually.
If the wizard is cancelled,the created voucher will be deleted again.
Known limitations:
Currency conversion and payment difference writeoff are not yet
supported.
""",
'website': 'http://therp.nl',
'images': [],
'depends': ['account_voucher'],
'data': [
'view/account_voucher_instant.xml',
'view/account_bank_statement_line.xml',
],
"license": 'AGPL-3',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,158 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * bank_statement_instant_voucher
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-11-12 10:42+0000\n"
"PO-Revision-Date: 2012-11-12 10:42+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: bank_statement_instant_voucher
#: view:account.voucher.instant:0
msgid "Confirm"
msgstr "Bevestig"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:71
#, python-format
msgid "Voucher for statement line %s.%s"
msgstr "Journaalbon voor bankafschrift %s.%s"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,state:0
msgid "State"
msgstr "Status"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:201
#, python-format
msgid "The voucher could not be posted."
msgstr "De journaalbon kon niet worden bevestigd."
#. module: bank_statement_instant_voucher
#: selection:account.voucher.instant,state:0
msgid "ready"
msgstr "ready"
#. module: bank_statement_instant_voucher
#: model:ir.model,name:bank_statement_instant_voucher.model_account_voucher_instant
msgid "Instant Voucher"
msgstr "Instant journaalbon"
#. module: bank_statement_instant_voucher
#: selection:account.voucher.instant,state:0
msgid "confirm"
msgstr "confirm"
#. module: bank_statement_instant_voucher
#: view:account.bank.statement:0
#: model:ir.actions.act_window,name:bank_statement_instant_voucher.act_instant_voucher
msgid "Create matching voucher"
msgstr "Bijpassende journaalbon aanmaken"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:137
#, python-format
msgid "Cannot determine statement line"
msgstr "Kan de bankafschriftregel niet afleiden"
#. module: bank_statement_instant_voucher
#: selection:account.voucher.instant,state:0
msgid "init"
msgstr "init"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:209
#, python-format
msgid "The voucher's move line could not be posted."
msgstr "De journaalposten van de journaalbon konden niet geboekt worden"
#. module: bank_statement_instant_voucher
#: model:ir.model,name:bank_statement_instant_voucher.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr "Bankafschriftregel"
#. module: bank_statement_instant_voucher
#: view:account.voucher.instant:0
msgid "Create voucher"
msgstr "Journaalbon aanmaken"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:214
#, python-format
msgid "The amount on the bank statement line needs to be the same as on the voucher. Write-off is not yet supported."
msgstr "Het bedrag op het bankafschrift dient gelijk te zijn aan het bedrag op de journaalbon. Afschrijven is nog niet ondersteund."
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:59
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:136
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:190
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:200
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:208
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:213
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:224
#, python-format
msgid "Error"
msgstr "Fout"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:60
#, python-format
msgid "No %s journal defined"
msgstr "Geen %s-dagboek ingesteld"
#. module: bank_statement_instant_voucher
#: constraint:account.bank.statement.line:0
msgid "The amount of the voucher must be the same amount as the one on the statement line"
msgstr "Het bedrag op de bon moet hetzelfde bedrag zijn dat vermeld staat op de afschriftregel"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,balance:0
msgid "Balance"
msgstr "Balans"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,statement_line_id:0
msgid "Bank statement line"
msgstr "Bankafschriftregel"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,ref:0
msgid "Reference"
msgstr "Referentie"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:191
#, python-format
msgid "Currency on the bank statement line needs to be the same as on the voucher. Currency conversion is not yet supported."
msgstr "De valuta van de bankafschriftregel dient gelijk te zijn aan die op de journaalbon. Omrekenen tussen valuta is nog niet ondersteund."
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:225
#, python-format
msgid "Cannot match a confirmed statement line"
msgstr "Kan een bevestigde bankafschriftregel niet afletteren"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,voucher_id:0
msgid "Voucher"
msgstr "Journaalbon"
#. module: bank_statement_instant_voucher
#: view:account.voucher.instant:0
msgid "Cancel"
msgstr "Annuleer"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,partner_id:0
msgid "Partner"
msgstr "Relatie"

View File

@@ -0,0 +1,2 @@
import account_voucher_instant
import account_bank_statement_line

View File

@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2012 Therp BV (<http://therp.nl>).
#
# 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/>.
#
##############################################################################
from openerp.osv import osv, fields
class account_bank_statement_line(osv.Model):
_inherit = 'account.bank.statement.line'
def create_instant_voucher(self, cr, uid, ids, context=None):
res = False
if ids:
if isinstance(ids, (int, float)):
ids = [ids]
if context is None:
context = {}
local_context = context.copy()
local_context['active_id'] = ids[0]
wizard_obj = self.pool.get('account.voucher.instant')
res = {
'name': wizard_obj._description,
'view_type': 'form',
'view_mode': 'form',
'res_model': wizard_obj._name,
'domain': [],
'context': local_context,
'type': 'ir.actions.act_window',
'target': 'new',
'res_id': False,
'nodestroy': False,
}
return res

View File

@@ -0,0 +1,306 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2012 Therp BV (<http://therp.nl>).
#
# 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/>.
#
##############################################################################
from openerp.osv import osv, fields
from openerp.tools.translate import _
from openerp.addons.decimal_precision import decimal_precision as dp
class instant_voucher(osv.TransientModel):
_name = 'account.voucher.instant'
_description = 'Instant Voucher'
def cancel(self, cr, uid, ids, context=None):
"""
Delete the voucher and close window
"""
assert len(ids) == 1, "Will only take one resource id"
instant = self.browse(cr, uid, ids[0], context=context)
if instant.voucher_id:
self.pool.get('account.voucher').cancel_voucher(
cr, uid, [instant.voucher_id.id], context=context)
self.pool.get('account.voucher').unlink(
cr, uid, [instant.voucher_id.id], context=context)
return {'type': 'ir.actions.act_window_close'}
def get_voucher_defaults(
self, cr, uid, vals, context=None):
"""
Gather conditional defaults based on given key, value pairs
:param vals: dictionary of key, value pairs
:returns: dictionary of default values for fields not in vals
"""
values_pool = self.pool.get('ir.values')
voucher_pool = self.pool.get('account.voucher')
res = {}
for (key, val) in vals.iteritems():
if val and voucher_pool._all_columns[key].column.change_default:
for default in values_pool.get_defaults(
cr, uid, 'account.voucher', '%s=%s' % (key, val)):
if default[1] not in vals:
res[default[1]] = default[2]
return res
def create_voucher(self, cr, uid, ids, context=None):
"""
Create a fully fledged voucher counterpart for the
statement line. User only needs to process taxes and may
adapt cost/income account.
"""
assert len(ids) == 1, "Will only take one resource id"
voucher_pool = self.pool.get('account.voucher')
period_pool = self.pool.get('account.period')
instant = self.browse(cr, uid, ids[0], context=context)
line = instant.statement_line_id
voucher_type = line.amount < 0 and 'purchase' or 'sale'
journal_ids = self.pool.get('account.journal').search(
cr, uid, [('company_id', '=', line.company_id.id),
('type', '=', voucher_type)])
if not journal_ids:
osv.exept_osv(
_('Error'),
_('No %s journal defined') % voucher_type)
journal = self.pool.get('account.journal').browse(
cr, uid, journal_ids[0], context=context)
if journal.type in ('sale', 'sale_refund'):
line_account_id = (journal.default_credit_account_id and
journal.default_credit_account_id.id or False)
elif journal.type in ('purchase', 'expense', 'purchase_refund'):
line_account_id = (journal.default_debit_account_id and
journal.default_debit_account_id.id or False)
vals = {
'name': _('Voucher for statement line %s.%s') % (line.statement_id.name, line.name),
'reference': line.ref or False,
'company_id': line.company_id.id,
'partner_id': instant.partner_id.id,
'date': line.date or res.get('line.date', False),
'account_id': line.account_id.id,
'type': voucher_type,
'line_ids': [(0, 0, {'amount': abs(line.amount),
'account_id': line_account_id,
'type': line.amount < 0 and 'dr' or 'cr',
'name': line.ref or False,
})],
'amount': line.amount and abs(line.amount) or res.get('amount', False),
'journal_id': journal_ids[0],
}
if vals['date']:
period_ids = period_pool.find(cr, uid, vals['date'], context=context)
if period_ids:
vals['period_id'] = period_ids[0]
vals.update(self.get_voucher_defaults(cr, uid, vals, context=context))
voucher_id = voucher_pool.create(
cr, uid, vals, context=context)
self.write(
cr, uid, ids[0],
{'voucher_id': voucher_id,
'state': 'ready',
'type': voucher_type,
}, context=context)
return {
'name': self._description,
'view_type': 'form',
'view_mode': 'form',
'res_model': self._name,
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
'res_id': ids[0],
'nodestroy': False,
}
def dummy(self, cr, uid, ids, context=None):
return {
'name': self._description,
'view_type': 'form',
'view_mode': 'form',
'res_model': self._name,
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
'res_id': ids[0],
'nodestroy': False,
}
def default_get(self, cr, uid, fields_list, context=None):
"""
Gather sane default values from the originating statement line
"""
res = super(instant_voucher, self).default_get(
cr, uid, fields_list, context=context)
if 'statement_line_id' in fields_list:
res['statement_line_id'] = (
context.get('active_id') or
context.get('active_ids') and context.get('active_ids')[0])
if not res['statement_line_id']:
raise osv.except_osv(
_('Error'),
_('Cannot determine statement line'))
line = self.pool.get('account.bank.statement.line').browse(
cr, uid, res['statement_line_id'], context=context)
if 'balance' in fields_list:
res['balance'] = line.amount
if 'ref' in fields_list:
res['ref'] = line.ref
if 'partner_id' in fields_list:
if line.partner_id:
res['partner_id'] = line.partner_id.id
return res
def _get_balance(self, cr, uid, ids, field_name, args, context=None):
"""
Compute the expected residual
TODO: currency conversion
"""
res = {}
for instant in self.browse(cr, uid, ids, context=context):
if instant.voucher_id and instant.voucher_id.state == 'posted':
amount = instant.statement_line_id.amount
counteramount = 0.0
for line in instant.voucher_id.move_ids:
if line.account_id.id == instant.statement_line_id.account_id.id:
counteramount = line.debit - line.credit
for line in instant.voucher_id.move_ids:
if line.account_id.id == instant.statement_line_id.account_id.id:
counteramount = line.debit - line.credit
else:
amount = abs(instant.statement_line_id.amount)
counteramount = abs(instant.voucher_id and instant.voucher_id.amount or 0.0)
res[instant.id] = amount - counteramount
return res
def confirm(self, cr, uid, ids, context=None):
"""
Post the voucher if necessary
Post the voucher's move lines if necessary
Sanity checks on currency and residual = 0.0
If the account_banking module is installed, perform matching
and reconciliation. If not, the user is left to manual
reconciliation of OpenERP.
"""
assert len(ids) == 1, "Will only take one resource id"
statement_line_obj = self.pool.get('account.bank.statement.line')
voucher_obj = self.pool.get('account.voucher')
move_obj = self.pool.get('account.move')
instant = self.browse(cr, uid, ids[0], context=context)
voucher_currency = (instant.voucher_id.currency_id and
instant.voucher_id.currency_id or
instant.voucher_id.company_id.currency_id)
if (instant.statement_line_id.statement_id.currency.id !=
voucher_currency.id):
raise osv.except_osv(
_("Error"),
_("Currency on the bank statement line needs to be the "
"same as on the voucher. Currency conversion is not yet "
"supported."))
if instant.voucher_id.state != 'posted':
voucher_obj.proforma_voucher(
cr, uid, [instant.voucher_id.id], context=context)
instant.refresh()
if instant.voucher_id.state != 'posted':
raise osv.except_osv(
_("Error"),
_("The voucher could not be posted."))
if instant.voucher_id.move_id.state != 'posted':
move_obj.post(
cr, uid, [instant.voucher_id.move_id.id], context=context)
instant.refresh()
if instant.voucher_id.move_id.state != 'posted':
raise osv.except_osv(
_("Error"),
_("The voucher's move line could not be posted."))
if not self.pool.get('res.currency').is_zero(
cr, uid, voucher_currency, instant.balance):
raise osv.except_osv(
_("Error"),
_("The amount on the bank statement line needs to be the "
"same as on the voucher. Write-off is not yet "
"supported."))
# Banking Addons integration:
# Gather the info needed to match the bank statement line
# and trigger its posting and reconciliation.
if 'import_transaction_id' in statement_line_obj._columns:
if instant.statement_line_id.state == 'confirmed':
raise osv.except_osv(
_("Error"),
_("Cannot match a confirmed statement line"))
if not instant.statement_line_id.import_transaction_id:
statement_line_obj.create_instant_transaction(
cr, uid, instant.statement_line_id.id, context=context)
instant.statement_line_id.refresh()
for line in instant.voucher_id.move_ids:
if line.account_id.id == instant.statement_line_id.account_id.id:
self.pool.get('banking.import.transaction').write(
cr, uid, instant.statement_line_id.import_transaction_id.id,
{
'move_line_id': line.id,
'move_line_ids': [(6, 0, [line.id])],
'match_type': 'move',
'invoice_id': False,
'invoice_ids': [(6, 0, [])],
}, context=context)
statement_line_obj.confirm(
cr, uid, [instant.statement_line_id.id], context=context)
break
return {'type': 'ir.actions.act_window_close'}
_columns = {
'balance': fields.function(
_get_balance,
type='float',
digits_compute=dp.get_precision('Account'),
string="Balance",),
'partner_id': fields.many2one(
'res.partner',
'Partner',
required=True),
'statement_line_id': fields.many2one(
'account.bank.statement.line',
'Bank statement line',
readonly=True),
'ref': fields.related(
'statement_line_id', 'ref',
type="char", size="48",
readonly=True,
string="Reference"),
'voucher_id': fields.many2one(
'account.voucher',
'Voucher',
readonly=True),
'state': fields.selection(
[('init', 'init'),
('ready', 'ready'),
('confirm', 'confirm')],
'State'),
'type': fields.selection(
[('sale', 'Sale'),
('purchase', 'Purchase')],
'Voucher type'),
}
_defaults = {'state': 'init'}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_banking_bank_statement_form" model="ir.ui.view">
<field name="name">Add instant voucher button to bank statement line on statement form</field>
<field name="inherit_id" ref="account.view_bank_statement_form" />
<field name="model">account.bank.statement</field>
<field name="type">form</field>
<field name="priority" eval="30"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='voucher_id']"
position="before">
<button name="create_instant_voucher" states="draft"
string="Create matching voucher"
icon="STOCK_COPY"
type="object"/>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="instant_voucher_form" model="ir.ui.view">
<field name="name">Instant voucher form view</field>
<field name="model">account.voucher.instant</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form>
<field name="state" invisible="1" readonly="1"/>
<field name="statement_line_id"/>
<field name="ref"/>
<newline/>
<field name="partner_id"/>
<field name="balance"/>
<newline/>
<field name="type" invisible="1"/>
<field name="voucher_id"
context="{'statement_line_id': statement_line_id,
'form_view_ref': (
type == 'sale' and 'account_voucher.view_sale_receipt_form'
or 'account_voucher.view_purchase_receipt_form')
}"
/>
<newline/>
<newline/>
<button icon="gtk-cancel"
string="Cancel"
name="cancel"
type="object"/>
<button icon="gtk-ok" string="Confirm"
states="ready"
name="confirm"
type="object"
/>
<button icon="gtk-ok" string="Create voucher"
states="init"
name="create_voucher"
type="object"
/>
</form>
</field>
</record>
<act_window name="Create matching voucher"
res_model="account.voucher.instant"
src_model="account.bank.statement.line"
view_mode="form"
target="new"
key2="client_action_multi"
id="act_instant_voucher"/>
</data>
</openerp>