mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
[REF] Payment wizards are now new style (osv_memory) wizards
[FIX] Allow for ClieOp export with empty reference
This commit is contained in:
@@ -35,8 +35,6 @@
|
||||
'update_xml': [
|
||||
'security/ir.model.access.csv',
|
||||
'data/account_banking_data.xml',
|
||||
'account_banking_import_wizard.xml',
|
||||
'account_banking_payment_wizard.xml',
|
||||
'wizard/bank_import_view.xml',
|
||||
'account_banking_view.xml',
|
||||
'account_banking_workflow.xml',
|
||||
|
||||
@@ -203,58 +203,16 @@ class payment_mode_type(osv.osv):
|
||||
'bank_type_payment_type_rel',
|
||||
'pay_type_id','bank_type_id',
|
||||
'Suitable bank types', required=True),
|
||||
'ir_model_id': fields.many2one(
|
||||
'ir.model', 'Payment wizard',
|
||||
help=('Select the Payment Wizard for payments of this type. '
|
||||
'Leave empty for manual processing'),
|
||||
domain=[('osv_memory', '=', True)],
|
||||
),
|
||||
}
|
||||
|
||||
payment_mode_type()
|
||||
|
||||
class payment_order_create(osv.osv_memory):
|
||||
_inherit = "payment.order.create"
|
||||
|
||||
def create_payment(self, cr, uid, ids, context=None):
|
||||
""" This method is equal to the one in
|
||||
account_payment/wizard/account_payment_order.py
|
||||
except for a fix in passing the payment mode to line2bank()
|
||||
"""
|
||||
order_obj = self.pool.get('payment.order')
|
||||
line_obj = self.pool.get('account.move.line')
|
||||
payment_obj = self.pool.get('payment.line')
|
||||
if context is None:
|
||||
context = {}
|
||||
data = self.read(cr, uid, ids, [], context=context)[0]
|
||||
line_ids = data['entries']
|
||||
if not line_ids:
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
payment = order_obj.browse(cr, uid, context['active_id'], context=context)
|
||||
### account banking
|
||||
# t = None
|
||||
# line2bank = line_obj.line2bank(cr, uid, line_ids, t, context)
|
||||
line2bank = line_obj.line2bank(cr, uid, line_ids, payment.mode.id, context)
|
||||
### end account banking
|
||||
|
||||
## Finally populate the current payment with new lines:
|
||||
for line in line_obj.browse(cr, uid, line_ids, context=context):
|
||||
if payment.date_prefered == "now":
|
||||
#no payment date => immediate payment
|
||||
date_to_pay = False
|
||||
elif payment.date_prefered == 'due':
|
||||
date_to_pay = line.date_maturity
|
||||
elif payment.date_prefered == 'fixed':
|
||||
date_to_pay = payment.date_scheduled
|
||||
payment_obj.create(cr, uid,{
|
||||
'move_line_id': line.id,
|
||||
'amount_currency': line.amount_to_pay,
|
||||
'bank_id': line2bank.get(line.id),
|
||||
'order_id': payment.id,
|
||||
'partner_id': line.partner_id and line.partner_id.id or False,
|
||||
'communication': line.ref or '/',
|
||||
'date': date_to_pay,
|
||||
'currency': line.invoice and line.invoice.currency_id.id or False,
|
||||
}, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
payment_order_create()
|
||||
|
||||
class payment_mode(osv.osv):
|
||||
''' Restoring the payment type from version 5,
|
||||
used to select the export wizard (if any) '''
|
||||
@@ -794,41 +752,7 @@ class payment_order(osv.osv):
|
||||
'''
|
||||
_inherit = 'payment.order'
|
||||
|
||||
def _get_id_proxy(self, cr, uid, ids, name, args, context=None):
|
||||
return dict([(id, id) for id in ids])
|
||||
|
||||
_columns = {
|
||||
#
|
||||
# 'id_proxy' is simply a reference to the resource's id
|
||||
# for the following reason:
|
||||
#
|
||||
# The GTK client 6.0 lacks necessary support for old style wizards.
|
||||
# It does not pass the resource's id if the wizard is called from
|
||||
# a button on a form.
|
||||
#
|
||||
# As a workaround, we pass the payment order id in the context
|
||||
# Evaluating 'id' in the context in the webclient on a form
|
||||
# in readonly mode dies with an error "Invalid Syntax", because 'id'
|
||||
# evaluates to "<built-in function id>" and the resource's field
|
||||
# values are not passed to eval in readonly mode at all.
|
||||
# See /addons/openerp/static/javascript/form.js line 308
|
||||
#
|
||||
# Evaluating any other variable in the webclient on a form in
|
||||
# readonly mode fails silently. That is actually ok, because the
|
||||
# webclient still supports passing the resource id when an old style
|
||||
# wizard is called.
|
||||
#
|
||||
# Therefore, if we want to pass the id in the context safely we have to
|
||||
# pass it under a different name.
|
||||
#
|
||||
# TODO: migrate old style wizards to osv_memory
|
||||
#
|
||||
'id_proxy': fields.function(
|
||||
_get_id_proxy, method=True, string='Copy ID', type='integer',
|
||||
# Would have used store={}, but the system does not seem to
|
||||
# generate triggers on the field 'id'.
|
||||
store=False,
|
||||
),
|
||||
'date_scheduled': fields.date(
|
||||
'Scheduled date if fixed',
|
||||
states={
|
||||
@@ -904,25 +828,39 @@ class payment_order(osv.osv):
|
||||
If type is manual. just confirm the order.
|
||||
Previously (pre-v6) in account_payment/wizard/wizard_pay.py
|
||||
"""
|
||||
if context == None:
|
||||
context={}
|
||||
result = {}
|
||||
obj_model = self.pool.get('ir.model.data')
|
||||
order = self.browse(cr, uid, ids[0], context)
|
||||
t = order.mode and order.mode.type.code or 'manual'
|
||||
res_id = False
|
||||
if t != 'manual':
|
||||
gw = self.get_wizard(t)
|
||||
if gw:
|
||||
module, wizard = gw
|
||||
wiz_id = obj_model._get_id(cr, uid, module, wizard)
|
||||
if wiz_id:
|
||||
res_id = obj_model.read(
|
||||
cr, uid, [wiz_id], ['res_id'])[0]['res_id']
|
||||
if res_id:
|
||||
result = self.pool.get('ir.actions.wizard').read(
|
||||
cr, uid, [res_id])[0]
|
||||
orders = self.browse(cr, uid, ids, context)
|
||||
order = orders[0]
|
||||
# check if a wizard is defined for the first order
|
||||
if order.mode.type and order.mode.type.ir_model_id:
|
||||
context['active_ids'] = ids
|
||||
wizard_model = order.mode.type.ir_model_id.model
|
||||
wizard_obj = self.pool.get(wizard_model)
|
||||
wizard_id = wizard_obj.create(cr, uid, {}, context)
|
||||
result = {
|
||||
'name': wizard_obj._description or 'Payment Order Export',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': wizard_model,
|
||||
'domain': [],
|
||||
'context': context,
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
'res_id': wizard_id,
|
||||
'nodestroy': True,
|
||||
}
|
||||
else:
|
||||
# should all be manual orders without type or wizard model
|
||||
for order in orders[1:]:
|
||||
if order.mode.type and order.mode.type.ir_model_id:
|
||||
raise osv.except_osv(
|
||||
_('Error'),
|
||||
_('You can only combine payment orders of the same type')
|
||||
)
|
||||
# process manual payments
|
||||
self.action_sent(cr, uid, ids, context)
|
||||
result['nodestroy'] = True
|
||||
return result
|
||||
|
||||
def _write_payment_lines(self, cursor, uid, ids, **kwargs):
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) EduSense BV <http://www.edusense.nl>
|
||||
All rights reserved.
|
||||
The licence is in the file __terp__.py
|
||||
-->
|
||||
<openerp>
|
||||
<data>
|
||||
<wizard id="wizard_account_banking_import_file"
|
||||
string="Import Bank Statements File"
|
||||
model="account.bank.statement"
|
||||
name="account_banking.banking_import"
|
||||
/>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) EduSense BV <http://www.edusense.nl>
|
||||
All rights reserved.
|
||||
The licence is in the file __terp__.py
|
||||
-->
|
||||
<openerp>
|
||||
<data>
|
||||
<wizard id="wizard_account_banking_payment_manual"
|
||||
menu="False"
|
||||
string="Manual Bank Payment"
|
||||
model="account_payment.payment.order"
|
||||
name="account_banking.payment_manual"
|
||||
/>
|
||||
<wizard id="account_payment.wizard_populate_payment"
|
||||
menu="False"
|
||||
string="Populate payment"
|
||||
model="payment.order"
|
||||
name="account_payment.populate_payment"
|
||||
/>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -143,6 +143,15 @@
|
||||
action="wizard_account_banking_import_file"
|
||||
sequence="15"/>
|
||||
|
||||
<!-- Add the import wizard to the statement's right menu -->
|
||||
<act_window name="Import Bank Statements File"
|
||||
res_model="account.banking.bank.import"
|
||||
src_model="account.bank.statement"
|
||||
view_mode="form"
|
||||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="act_account_banking_import_wizard"/>
|
||||
|
||||
<!-- Create right menu entry to see statements -->
|
||||
<act_window name="Bank Statements File"
|
||||
domain="[('id','=',banking_id)]"
|
||||
@@ -283,19 +292,30 @@
|
||||
<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" states="draft,open"
|
||||
string="Select Invoices to Pay" type="action"
|
||||
attrs="{'invisible':[('state','!=','draft')]}"
|
||||
icon="gtk-find"
|
||||
/>
|
||||
</xpath>
|
||||
<xpath expr="/form/group/button[@string='Make Payments']"
|
||||
position="replace">
|
||||
<field name="id_proxy" invisible="1"/>
|
||||
<button name="launch_wizard" states="open" string="Make Payments" type="object" icon="gtk-execute" context="{'payment_order_id': id_proxy}"/>
|
||||
<button name="launch_wizard" states="open" string="Make Payments" type="object" icon="gtk-execute"/>
|
||||
<newline/>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_banking_payment_order_tree_1" model="ir.ui.view">
|
||||
<field name="name">account.payment.order.tree.banking-1</field>
|
||||
<field name="inherit_id" ref="account_payment.view_payment_order_tree" />
|
||||
<field name="model">payment.order</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<button string="Make Payments" position="replace">
|
||||
<button name="launch_wizard" states="open" string="Make Payments" type="object" icon="gtk-execute"/>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Set trigger on IBAN and acc_number fields in res_partner_bank form -->
|
||||
<record id="view_partner_bank_account_banking_form_1" model="ir.ui.view">
|
||||
@@ -403,6 +423,7 @@
|
||||
<field name="name" />
|
||||
<field name="code" />
|
||||
<field name="suitable_bank_types"/>
|
||||
<field name="ir_model_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -17,11 +17,18 @@
|
||||
Ratio: one can have bank accounts in foreign banks. Foreign
|
||||
addresses not automatically involve international banking.
|
||||
-->
|
||||
<record id="bank_normal_field_contry" model="res.partner.bank.type.field">
|
||||
<record id="base.bank_normal_field_contry" model="res.partner.bank.type.field">
|
||||
<field name="name">country_id</field>
|
||||
<field name="bank_type_id" ref="base.bank_normal"/>
|
||||
<field eval="False" name="required"/>
|
||||
<field eval="False" name="readonly"/>
|
||||
</record>
|
||||
<!-- Add manual bank transfer as default payment option -->
|
||||
<record model="payment.mode.type" id="account_banking.manual_bank_tranfer">
|
||||
<field name="name">Manual Bank Transfer</field>
|
||||
<field name="code">BANKMAN</field>
|
||||
<field name="suitable_bank_types"
|
||||
eval="[(6,0,[ref('base.bank_normal'),ref('base_iban.bank_iban'),])]" />
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
"access_account_banking_settings","account.banking.account.settings","model_account_banking_account_settings","account.group_account_manager",1,1,1,1
|
||||
"access_account_banking_settings_user","account.banking.account.settings user","model_account_banking_account_settings","account.group_account_user",1,0,0,0
|
||||
"access_account_banking_import","account.bankimport","model_account_banking_imported_file","account.group_account_user",1,1,1,1
|
||||
"access_payment_mode_type","payment.mode.type","model_payment_mode_type","account_payment.group_account_payment",1,1,1,1
|
||||
|
||||
|
@@ -20,6 +20,6 @@
|
||||
##############################################################################
|
||||
import bank_import
|
||||
import bank_payment_manual
|
||||
import wizard_payment_order
|
||||
import account_payment_order
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
113
account_banking/wizard/account_payment_order.py
Normal file
113
account_banking/wizard/account_payment_order.py
Normal file
@@ -0,0 +1,113 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
|
||||
# All Rights Reserved
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import datetime
|
||||
from osv import osv
|
||||
from account_banking.struct import struct
|
||||
from account_banking.parsers import convert
|
||||
|
||||
today = datetime.date.today
|
||||
|
||||
def str2date(str):
|
||||
dt = convert.str2date(str, '%Y-%m-%d')
|
||||
return datetime.date(dt.year, dt.month, dt.day)
|
||||
|
||||
class payment_order_create(osv.osv_memory):
|
||||
_inherit = 'payment.order.create'
|
||||
|
||||
def create_payment(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
This method is a slightly modified version of the existing method on this
|
||||
model in account_payment.
|
||||
- pass the payment mode to line2bank()
|
||||
- allow invoices to create influence on the payment process: not only 'Free'
|
||||
references are allowed, but others as well
|
||||
- check date_to_pay is not in the past.
|
||||
'''
|
||||
|
||||
order_obj = self.pool.get('payment.order')
|
||||
line_obj = self.pool.get('account.move.line')
|
||||
payment_obj = self.pool.get('payment.line')
|
||||
if context is None:
|
||||
context = {}
|
||||
data = self.read(cr, uid, ids, [], context=context)[0]
|
||||
line_ids = data['entries']
|
||||
if not line_ids:
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
payment = order_obj.browse(cr, uid, context['active_id'], context=context)
|
||||
### account banking
|
||||
# t = None
|
||||
# line2bank = line_obj.line2bank(cr, uid, line_ids, t, context)
|
||||
line2bank = line_obj.line2bank(cr, uid, line_ids, payment.mode.id, context)
|
||||
_today = today()
|
||||
### end account banking
|
||||
|
||||
## Finally populate the current payment with new lines:
|
||||
for line in line_obj.browse(cr, uid, line_ids, context=context):
|
||||
if payment.date_prefered == "now":
|
||||
#no payment date => immediate payment
|
||||
date_to_pay = False
|
||||
elif payment.date_prefered == 'due':
|
||||
### account_banking
|
||||
# date_to_pay = line.date_maturity
|
||||
date_to_pay = line.date_maturity and \
|
||||
str2date(line.date_maturity) > _today\
|
||||
and line.date_maturity or False
|
||||
### end account banking
|
||||
elif payment.date_prefered == 'fixed':
|
||||
### account_banking
|
||||
# date_to_pay = payment.date_planned
|
||||
date_to_pay = payment.date_planned and \
|
||||
str2date(payment.date_planned) > _today\
|
||||
and payment.date_planned or False
|
||||
### end account banking
|
||||
|
||||
### account_banking
|
||||
state = communication2 = False
|
||||
communication = line.ref or '/'
|
||||
if line.invoice:
|
||||
if line.invoice.reference_type == 'structured':
|
||||
state = 'structured'
|
||||
communication = line.invoice.reference
|
||||
else:
|
||||
state = 'normal'
|
||||
communication2 = line.invoice.reference
|
||||
### end account_banking
|
||||
|
||||
payment_obj.create(cr, uid,{
|
||||
'move_line_id': line.id,
|
||||
'amount_currency': line.amount_to_pay,
|
||||
'bank_id': line2bank.get(line.id),
|
||||
'order_id': payment.id,
|
||||
'partner_id': line.partner_id and line.partner_id.id or False,
|
||||
### account banking
|
||||
# 'communication': line.ref or '/'
|
||||
'communication': communication,
|
||||
'communication2': communication2,
|
||||
'state': state,
|
||||
### end account banking
|
||||
'date': date_to_pay,
|
||||
'currency': line.invoice and line.invoice.currency_id.id or False,
|
||||
}, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
payment_order_create()
|
||||
@@ -974,6 +974,7 @@ class banking_import(osv.osv_memory):
|
||||
'State', readonly=True),
|
||||
'import_id': fields.many2one(
|
||||
'account.banking.imported.file', 'Import File'),
|
||||
# osv_memory does not seem to support one2many
|
||||
'statement_ids': fields.many2many(
|
||||
'account.bank.statement', 'rel_wiz_statements', 'wizard_id',
|
||||
'statement_id', 'Imported Bank Statements'),
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (C) EduSense BV (<http://www.edusense.nl>).
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
import datetime
|
||||
import wizard
|
||||
import pooler
|
||||
from tools.misc import UpdateableStr
|
||||
from tools.translate import _
|
||||
from account_banking.struct import struct
|
||||
from account_banking.parsers import convert
|
||||
|
||||
__doc__ = '''
|
||||
This module is a slightly modified version of the identical named payment
|
||||
order wizard in account_payment. The rationale for this bulk copy is the
|
||||
inability to inherit wizards in OpenERP versions prior to version 6.
|
||||
The modifications in this wizard allows invoices to create influence on the
|
||||
payment process: not only 'Free' references are allowed, but others as well.
|
||||
|
||||
In order to allow further projects based on account_banking to inherit from
|
||||
this wizard, the complete wizard is made object oriented, as is should have
|
||||
been from the start.
|
||||
'''
|
||||
|
||||
today = datetime.date.today
|
||||
|
||||
def str2date(str):
|
||||
dt = convert.str2date(str, '%Y-%m-%d')
|
||||
return datetime.date(dt.year, dt.month, dt.day)
|
||||
|
||||
class wizard_payment_order(wizard.interface):
|
||||
'''
|
||||
Create a payment object with lines corresponding to the account move line
|
||||
to pay according to the date and the mode provided by the user.
|
||||
Hypothesis:
|
||||
- Small number of non-reconcilied move line , payment mode and bank account type,
|
||||
- Big number of partner and bank account.
|
||||
|
||||
If a type is given, unsuitable account move lines are ignored.
|
||||
'''
|
||||
|
||||
FORM = UpdateableStr()
|
||||
FIELDS = {
|
||||
'entries': {
|
||||
'string':'Entries',
|
||||
'type':'many2many',
|
||||
'relation': 'account.move.line',
|
||||
},
|
||||
}
|
||||
field_duedate = {
|
||||
'duedate': {
|
||||
'string': 'Due Date',
|
||||
'type': 'date',
|
||||
'required': True,
|
||||
'default': lambda *a: convert.date2str(today()),
|
||||
},
|
||||
}
|
||||
arch_duedate='''<?xml version="1.0"?>
|
||||
<form string="Search Payment lines">
|
||||
<field name="duedate" />
|
||||
</form>'''
|
||||
|
||||
|
||||
def search_entries(self, cursor, uid, data, context):
|
||||
'''
|
||||
Search for invoices that can be paid
|
||||
'''
|
||||
search_due_date = data['form']['duedate']
|
||||
|
||||
pool = pooler.get_pool(cursor.dbname)
|
||||
order_obj = pool.get('payment.order')
|
||||
move_line_obj = pool.get('account.move.line')
|
||||
|
||||
payment = order_obj.browse(cursor, uid, data['id'], context=context)
|
||||
if payment.mode:
|
||||
ctx = '''context="{'journal_id': %d}"''' % payment.mode.journal.id
|
||||
else:
|
||||
ctx = ''
|
||||
|
||||
# Search account.move.line to pay:
|
||||
domain = [
|
||||
('reconcile_id', '=', False),
|
||||
('account_id.type', '=', 'payable'),
|
||||
('amount_to_pay', '>', 0),
|
||||
'|', ('date_maturity','<=',search_due_date),
|
||||
('date_maturity','=',False)
|
||||
]
|
||||
line_ids = move_line_obj.search(cursor, uid, domain, context=context)
|
||||
self.FORM.string = '''<?xml version="1.0"?>
|
||||
<form string="Populate Payment:">
|
||||
<field name="entries" colspan="4" height="300" width="800" nolabel="1"
|
||||
domain="[('id', 'in', [%s])]" %s
|
||||
/>
|
||||
</form>''' % (','.join([str(x) for x in line_ids]), ctx)
|
||||
return {}
|
||||
|
||||
def get_communication(self, line):
|
||||
'''
|
||||
Method to fill the communication and communication2 lines of a payment
|
||||
line. Returns (state, comm1, comm2).
|
||||
'''
|
||||
if line.invoice.reference_type == 'structured':
|
||||
return ('structured', line.invoice.reference, '')
|
||||
return ('normal', '', line.invoice.reference)
|
||||
|
||||
def create_payment(self, cursor, uid, data, context):
|
||||
'''
|
||||
Create payment lines from the data of previously created payable
|
||||
invoices
|
||||
'''
|
||||
ids = data['form']['entries'][0][2]
|
||||
if not ids:
|
||||
return {}
|
||||
|
||||
pool = pooler.get_pool(cursor.dbname)
|
||||
order_obj = pool.get('payment.order')
|
||||
move_line_obj = pool.get('account.move.line')
|
||||
payment_line_obj = pool.get('payment.line')
|
||||
|
||||
payment = order_obj.browse(cursor, uid, data['id'], context=context)
|
||||
ptype = payment.mode and payment.mode.type.id or None
|
||||
line2bank = move_line_obj.line2bank(cursor, uid, ids, ptype, context)
|
||||
_today = today()
|
||||
retval = struct()
|
||||
|
||||
# Populate the current payment with new lines
|
||||
for line in move_line_obj.browse(cursor, uid, ids, context=context):
|
||||
if payment.date_prefered == 'now':
|
||||
# no payment date means immediate payment
|
||||
date_to_pay = False
|
||||
elif payment.date_prefered == 'due':
|
||||
date_to_pay = line.date_maturity and \
|
||||
str2date(line.date_maturity) > _today\
|
||||
and line.date_maturity or False
|
||||
elif payment.date_prefered == 'fixed':
|
||||
date_to_pay = payment.date_planned and \
|
||||
str2date(payment.date_planned) > _today\
|
||||
and payment.date_planned or False
|
||||
values = struct(
|
||||
move_line_id = line.id,
|
||||
amount_currency = line.amount_to_pay,
|
||||
bank_id = line2bank.get(line.id),
|
||||
order_id = payment.id,
|
||||
partner_id = line.partner_id and line.partner_id.id or False,
|
||||
date = date_to_pay,
|
||||
currency = False,
|
||||
)
|
||||
if line.invoice:
|
||||
values.state, values.communication, values.communication2 = \
|
||||
self.get_communication(line)
|
||||
values.currency = line.invoice.currency_id.id,
|
||||
payment_line_obj.create(cursor, uid, values, context=context)
|
||||
|
||||
return {}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': arch_duedate,
|
||||
'fields': field_duedate,
|
||||
'state': [
|
||||
('end','_Cancel'),
|
||||
('search','_Search', '', True)
|
||||
]
|
||||
},
|
||||
},
|
||||
'search': {
|
||||
'actions': [search_entries],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': FORM,
|
||||
'fields': FIELDS,
|
||||
'state': [
|
||||
('end','_Cancel'),
|
||||
('create','_Add to payment order', '', True)
|
||||
]
|
||||
},
|
||||
},
|
||||
'create': {
|
||||
'actions': [],
|
||||
'result': {
|
||||
'type': 'action',
|
||||
'action': create_payment,
|
||||
'state': 'end'
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
wizard_payment_order('account_payment.populate_payment')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -33,10 +33,10 @@
|
||||
'depends': ['account_banking'],
|
||||
'init_xml': [],
|
||||
'update_xml': [
|
||||
#'security/ir.model.access.csv',
|
||||
'account_banking_nl_clieop.xml',
|
||||
'account_banking_export_wizard.xml',
|
||||
'wizard/export_clieop_view.xml',
|
||||
'data/banking_export_clieop.xml',
|
||||
'security/ir.model.access.csv',
|
||||
],
|
||||
'demo_xml': [],
|
||||
'description': '''
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) EduSense BV <http://www.edusense.nl>
|
||||
All rights reserved.
|
||||
The licence is in the file __terp__.py
|
||||
-->
|
||||
<openerp>
|
||||
<data>
|
||||
<wizard id="wizard_account_banking_export_clieop"
|
||||
string="Export ClieOp File"
|
||||
model="payment.order"
|
||||
name="account_banking_nl_clieop.banking_export_clieop"
|
||||
/>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -22,25 +22,19 @@ from osv import osv, fields
|
||||
from datetime import date
|
||||
from tools.translate import _
|
||||
|
||||
class payment_order(osv.osv):
|
||||
'''
|
||||
Attach export_clieop wizard to payment order and allow traceability
|
||||
'''
|
||||
_inherit = 'payment.order'
|
||||
def get_wizard(self, type):
|
||||
if type in ['CLIEOPPAY', 'CLIEOPINC', 'CLIEOPSAL']:
|
||||
return self._module, 'wizard_account_banking_export_clieop'
|
||||
return super(payment_order, self).get_wizard(type)
|
||||
payment_order()
|
||||
|
||||
class clieop_export(osv.osv):
|
||||
'''ClieOp3 Export'''
|
||||
_name = 'banking.export.clieop'
|
||||
_description = __doc__
|
||||
_rec_name = 'identification'
|
||||
|
||||
_columns = {
|
||||
'payment_order_ids':
|
||||
fields.text('Payment Orders'),
|
||||
'payment_order_ids': fields.many2many(
|
||||
'payment.order',
|
||||
'account_payment_order_clieop_rel',
|
||||
'banking_export_clieop_id', 'account_order_id',
|
||||
'Payment Orders',
|
||||
readonly=True),
|
||||
'testcode':
|
||||
fields.selection([('T', _('Yes')), ('P', _('No'))],
|
||||
'Test Run', readonly=True),
|
||||
|
||||
@@ -14,19 +14,33 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Client Opdrachten Export">
|
||||
<separator string="General Information" colspan="4" />
|
||||
<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" />
|
||||
<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>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
@@ -59,5 +73,14 @@
|
||||
sequence="12"
|
||||
/>
|
||||
|
||||
<!-- Create right menu entry to see generated files -->
|
||||
<act_window name="Generated ClieOp3 Files"
|
||||
domain="[('payment_order_ids', '=', active_id)]"
|
||||
res_model="banking.export.clieop"
|
||||
src_model="payment.order"
|
||||
view_type="form"
|
||||
view_mode="tree,form"
|
||||
id="act_banking_export_clieop_payment_order"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
<field name="code">CLIEOPINC</field>
|
||||
<field name="suitable_bank_types"
|
||||
eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
|
||||
<field name="ir_model_id"
|
||||
ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
|
||||
</record>
|
||||
|
||||
<record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_pay">
|
||||
@@ -13,6 +15,8 @@
|
||||
<field name="code">CLIEOPPAY</field>
|
||||
<field name="suitable_bank_types"
|
||||
eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
|
||||
<field name="ir_model_id"
|
||||
ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
|
||||
</record>
|
||||
|
||||
<record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_sal">
|
||||
@@ -20,6 +24,8 @@
|
||||
<field name="code">CLIEOPSAL</field>
|
||||
<field name="suitable_bank_types"
|
||||
eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
|
||||
<field name="ir_model_id"
|
||||
ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
2
account_banking_nl_clieop/security/ir.model.access.csv
Normal file
2
account_banking_nl_clieop/security/ir.model.access.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
"access_banking_export_clieop","banking.export.clieop","model_banking_export_clieop","account_payment.group_account_payment",1,1,1,1
|
||||
|
@@ -76,7 +76,7 @@ class HeaderRecord(record.Record): #{{{
|
||||
|
||||
def __init__(self, id='1', seqno=1, duplicate=False):
|
||||
super(HeaderRecord, self).__init__()
|
||||
self.sender_id = id
|
||||
self.sender_id = id or ''
|
||||
self.file_id = '%02d%02d' % (self.creation_date.day, seqno)
|
||||
self.duplicatecode = duplicate and '2' or '1'
|
||||
#}}}
|
||||
@@ -362,7 +362,7 @@ class Batch(object):
|
||||
self.header.variantcode = batch_id and 'C' or 'B'
|
||||
self.header.transactiongroup = transactiongroup
|
||||
self.header.batch_tracer = batch_tracer
|
||||
self.header.batch_id = batch_id
|
||||
self.header.batch_id = batch_id or ''
|
||||
self.header.accountno_sender = rekeningnr
|
||||
self.sender.name_sender = sender
|
||||
self.sender.preferred_execution_date = execution_date
|
||||
|
||||
@@ -19,12 +19,11 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import pooler
|
||||
import base64
|
||||
from datetime import datetime, date, timedelta
|
||||
from account_banking import sepa
|
||||
from osv import osv, fields
|
||||
from tools.translate import _
|
||||
from account_banking import sepa
|
||||
import clieop
|
||||
|
||||
def strpdate(arg, format='%Y-%m-%d'):
|
||||
@@ -35,151 +34,131 @@ def strfdate(arg, format='%Y-%m-%d'):
|
||||
'''shortcut'''
|
||||
return arg.strftime(format)
|
||||
|
||||
class wizard_banking_export_clieop(wizard.interface):
|
||||
form = '''<?xml version="1.0"?>
|
||||
<form string="Client Opdrachten Export">
|
||||
<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" />
|
||||
</form>'''
|
||||
|
||||
fields = {
|
||||
'reference' : {
|
||||
'string': 'Reference',
|
||||
'type': 'char',
|
||||
'size': 5,
|
||||
'required': False,
|
||||
'help': ('The bank will use this reference in feedback communication '
|
||||
'to refer to this run. Only five characters are available.'
|
||||
)
|
||||
},
|
||||
'batchtype': {
|
||||
'string': 'Type',
|
||||
'type': 'selection',
|
||||
'selection': [
|
||||
class banking_export_clieop_wizard(osv.osv_memory):
|
||||
_name = 'banking.export.clieop.wizard'
|
||||
_description = 'Client Opdrachten Export'
|
||||
_columns = {
|
||||
'state': fields.selection(
|
||||
[
|
||||
('create', 'Create'),
|
||||
('finish', 'Finish')
|
||||
],
|
||||
'State',
|
||||
readonly=True,
|
||||
),
|
||||
'reference': fields.char(
|
||||
'Reference', size=5,
|
||||
help=('The bank will use this reference in feedback communication '
|
||||
'to refer to this run. Only five characters are available.'
|
||||
),
|
||||
),
|
||||
'batchtype': fields.selection(
|
||||
[
|
||||
('CLIEOPPAY', 'Payments'),
|
||||
('CLIEOPSAL', 'Salary Payments'),
|
||||
('CLIEOPINC', 'Direct Debits'),
|
||||
],
|
||||
'readonly': True,
|
||||
},
|
||||
'execution_date': {
|
||||
'string': 'Execution Date',
|
||||
'type': 'date',
|
||||
'required': False,
|
||||
'help': ('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.'
|
||||
),
|
||||
},
|
||||
'test': {
|
||||
'string': 'Test Run',
|
||||
'type': 'boolean',
|
||||
'required': True,
|
||||
'default': True,
|
||||
'help': ('Select this if you want your bank to run a test process '
|
||||
'rather then execute your orders for real.'
|
||||
)
|
||||
},
|
||||
'fixed_message': {
|
||||
'string': 'Fixed Message',
|
||||
'type': 'char',
|
||||
'size': 32,
|
||||
'required': False,
|
||||
'default': '',
|
||||
'help': ('A fixed message to apply to all transactions in addition to '
|
||||
'the individual messages.'
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
file_form = '''<?xml version="1.0"?>
|
||||
<form string="Client Opdrachten Export">
|
||||
<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" />
|
||||
<field name="log" colspan="4" nolabel="1" />
|
||||
</form>'''
|
||||
|
||||
file_fields = {
|
||||
'testcode': {
|
||||
'string': 'Test Run',
|
||||
'type': 'selection',
|
||||
'selection': [('T', _('Yes')), ('P', _('No'))],
|
||||
'required': False,
|
||||
'readonly': True,
|
||||
},
|
||||
'prefered_date': {
|
||||
'string': 'Prefered Processing Date',
|
||||
'type': 'date',
|
||||
'required': False,
|
||||
'readonly': True,
|
||||
},
|
||||
'no_transactions': {
|
||||
'string': 'Number of Transactions',
|
||||
'type': 'int',
|
||||
'required': False,
|
||||
'readonly': True,
|
||||
},
|
||||
'check_no_accounts': {
|
||||
'string': 'Check Number Accounts',
|
||||
'type': 'char',
|
||||
'size': 5,
|
||||
'required': False,
|
||||
'readonly': True,
|
||||
},
|
||||
'total_amount': {
|
||||
'string': 'Total Amount',
|
||||
'type': 'float',
|
||||
'required': False,
|
||||
'readonly': True,
|
||||
},
|
||||
'identification': {
|
||||
'string': 'Identification',
|
||||
'type': 'char',
|
||||
'size': 6,
|
||||
'required': False,
|
||||
'readonly': True,
|
||||
},
|
||||
'filetype': {
|
||||
'string': 'File Type',
|
||||
'type': 'selection',
|
||||
'selection': [
|
||||
], 'Type', readonly=True,
|
||||
),
|
||||
'execution_date': fields.date(
|
||||
'Execution Date',
|
||||
help=('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.'
|
||||
),
|
||||
),
|
||||
'test': fields.boolean(
|
||||
'Test Run',
|
||||
help=('Select this if you want your bank to run a test process '
|
||||
'rather then execute your orders for real.'
|
||||
),
|
||||
),
|
||||
'fixed_message': fields.char(
|
||||
'Fixed Message', size=32,
|
||||
help=('A fixed message to apply to all transactions in addition to '
|
||||
'the individual messages.'
|
||||
),
|
||||
),
|
||||
# file fields
|
||||
'file_id': fields.many2one(
|
||||
'banking.export.clieop',
|
||||
'ClieOp File',
|
||||
readonly=True
|
||||
),
|
||||
# fields.related does not seem to support
|
||||
# fields of type selection
|
||||
'testcode': fields.selection(
|
||||
[('T', _('Yes')), ('P', _('No'))],
|
||||
'Test Run', readonly=True,
|
||||
),
|
||||
'filetype': fields.selection(
|
||||
[
|
||||
('CREDBET', 'Payment Batch'),
|
||||
('SALARIS', 'Salary Payment Batch'),
|
||||
('INCASSO', 'Direct Debit Batch'),
|
||||
],
|
||||
'required': False,
|
||||
'readonly': True,
|
||||
},
|
||||
'file': {
|
||||
'string': 'ClieOp File',
|
||||
'type': 'binary',
|
||||
'required': False,
|
||||
'readonly': True,
|
||||
},
|
||||
'log': {
|
||||
'string': 'Log',
|
||||
'type': 'text',
|
||||
'readonly': True,
|
||||
},
|
||||
}
|
||||
],
|
||||
'File Type',
|
||||
readonly=True,
|
||||
),
|
||||
'prefered_date': fields.related(
|
||||
'file_id', 'prefered_date',
|
||||
type='date',
|
||||
string='Prefered Processing Date',
|
||||
readonly=True,
|
||||
),
|
||||
'no_transactions': fields.related(
|
||||
'file_id', 'no_transactions',
|
||||
type ='integer',
|
||||
string='Number of Transactions',
|
||||
readonly=True,
|
||||
),
|
||||
'check_no_accounts': fields.related(
|
||||
'file_id', 'check_no_accounts',
|
||||
type='char', size=5,
|
||||
string='Check Number Accounts',
|
||||
readonly=True,
|
||||
),
|
||||
'total_amount': fields.related(
|
||||
'file_id', 'total_amount',
|
||||
type='float',
|
||||
string='Total Amount',
|
||||
readonly=True,
|
||||
),
|
||||
'identification': fields.related(
|
||||
'file_id', 'identification',
|
||||
type='char', size=6,
|
||||
string='Identification',
|
||||
readonly=True,
|
||||
),
|
||||
'file': fields.related(
|
||||
'file_id', 'file', type='binary',
|
||||
readonly=True,
|
||||
string='File',
|
||||
),
|
||||
'payment_order_ids': fields.many2many(
|
||||
'payment.order', 'rel_wiz_payorders', 'wizard_id',
|
||||
'payment_order_id', 'Payment Orders',
|
||||
readonly=True,
|
||||
),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'test': True,
|
||||
}
|
||||
|
||||
def _check_orders(self, cursor, uid, data, context):
|
||||
def create(self, cursor, uid, vals, context=None):
|
||||
'''
|
||||
Retrieve a sane set of default values based on the payment orders
|
||||
from the context.
|
||||
'''
|
||||
if 'batchtype' not in vals:
|
||||
self.check_orders(cursor, uid, vals, context)
|
||||
return super(banking_export_clieop_wizard, self).create(
|
||||
cursor, uid, vals, context)
|
||||
|
||||
def check_orders(self, cursor, uid, vals, context):
|
||||
'''
|
||||
Check payment type for all orders.
|
||||
|
||||
@@ -191,19 +170,14 @@ class wizard_banking_export_clieop(wizard.interface):
|
||||
Also mind that rates for batches are way higher than those for
|
||||
transactions. It pays to limit the number of batches.
|
||||
'''
|
||||
form = data['form']
|
||||
today = date.today()
|
||||
pool = pooler.get_pool(cursor.dbname)
|
||||
payment_order_obj = pool.get('payment.order')
|
||||
|
||||
# Can get id from context. Seems necessary due to lack of support for
|
||||
# old style wizards in the GTK client
|
||||
if 'ids' not in data and context.get('payment_order_id', False):
|
||||
data['ids'] = [context['payment_order_id']]
|
||||
payment_order_obj = self.pool.get('payment.order')
|
||||
|
||||
# Payment order ids are provided in the context
|
||||
payment_order_ids = context.get('active_ids', [])
|
||||
runs = {}
|
||||
# Only orders of same type can be combined
|
||||
payment_orders = payment_order_obj.browse(cursor, uid, data['ids'])
|
||||
payment_orders = payment_order_obj.browse(cursor, uid, payment_order_ids)
|
||||
for payment_order in payment_orders:
|
||||
|
||||
payment_type = payment_order.mode.type.code
|
||||
@@ -231,34 +205,33 @@ class wizard_banking_export_clieop(wizard.interface):
|
||||
else:
|
||||
execution_date = today
|
||||
if execution_date and execution_date >= max_date:
|
||||
raise wizard.except_wizard(
|
||||
raise osv.except_osv(
|
||||
_('Error'),
|
||||
_('You can\'t create ClieOp orders more than 30 days in advance.')
|
||||
)
|
||||
# Sanity check: can't process in the past
|
||||
form['execution_date'] = strfdate(max(execution_date, today))
|
||||
|
||||
if len(runs) != 1:
|
||||
raise wizard.except_wizard(
|
||||
raise osv.except_osv(
|
||||
_('Error'),
|
||||
_('You can only combine payment orders of the same type')
|
||||
)
|
||||
|
||||
form['batchtype'] = type = runs.keys()[0]
|
||||
form['reference'] = runs[type][0].reference[-5:]
|
||||
return form
|
||||
type = runs.keys()[0]
|
||||
vals.update({
|
||||
'execution_date': strfdate(max(execution_date, today)),
|
||||
'batchtype': type,
|
||||
'reference': runs[type][0].reference[-5:],
|
||||
'payment_order_ids': [[6, 0, payment_order_ids]],
|
||||
'state': 'create',
|
||||
})
|
||||
|
||||
def _create_clieop(self, cursor, uid, data, context):
|
||||
def create_clieop(self, cursor, uid, ids, context):
|
||||
'''
|
||||
Wizard to actually create the ClieOp3 file
|
||||
'''
|
||||
pool = pooler.get_pool(cursor.dbname)
|
||||
payment_order_obj = pool.get('payment.order')
|
||||
form = data['form']
|
||||
|
||||
payment_order_obj = self.pool.get('payment.order')
|
||||
clieop_export = self.browse(cursor, uid, ids, context)[0]
|
||||
clieopfile = None
|
||||
payment_orders = payment_order_obj.browse(cursor, uid, data['ids'])
|
||||
for payment_order in payment_orders:
|
||||
for payment_order in clieop_export.payment_order_ids:
|
||||
if not clieopfile:
|
||||
# Just once: create clieop file
|
||||
our_account_owner = payment_order.mode.bank_id.owner_name \
|
||||
@@ -269,19 +242,19 @@ class wizard_banking_export_clieop(wizard.interface):
|
||||
payment_order.mode.bank_id.iban
|
||||
).localized_BBAN
|
||||
if not our_account_nr:
|
||||
raise wizard.except_wizard(
|
||||
raise osv.except_osv(
|
||||
_('Error'),
|
||||
_('Your bank account has to have a valid account number')
|
||||
)
|
||||
clieopfile = {'CLIEOPPAY': clieop.PaymentsFile,
|
||||
'CLIEOPINC': clieop.DirectDebitFile,
|
||||
'CLIEOPSAL': clieop.SalaryPaymentsFile,
|
||||
}[form['batchtype']](
|
||||
identification = form['reference'],
|
||||
execution_date = form['execution_date'],
|
||||
}[clieop_export['batchtype']](
|
||||
identification = clieop_export['reference'],
|
||||
execution_date = clieop_export['execution_date'],
|
||||
name_sender = our_account_owner,
|
||||
accountno_sender = our_account_nr,
|
||||
test = form['test']
|
||||
test = clieop_export['test']
|
||||
)
|
||||
|
||||
# ClieOp3 files can contain multiple batches, but we put all
|
||||
@@ -290,21 +263,21 @@ class wizard_banking_export_clieop(wizard.interface):
|
||||
# cheaper to combine than it is to split. As we split out all
|
||||
# reported errors afterwards, there is no additional gain in
|
||||
# using multiple batches.
|
||||
if form['fixed_message']:
|
||||
messages = [form['fixed_message']]
|
||||
if clieop_export['fixed_message']:
|
||||
messages = [clieop_export['fixed_message']]
|
||||
else:
|
||||
messages = []
|
||||
# The first payment order processed sets the reference of the
|
||||
# batch.
|
||||
batch = clieopfile.batch(
|
||||
messages = messages,
|
||||
batch_id = payment_order.reference
|
||||
batch_id = clieop_export['reference']
|
||||
)
|
||||
|
||||
for line in payment_order.line_ids:
|
||||
# Check on missing partner of bank account (this can happen!)
|
||||
if not line.bank_id or not line.bank_id.partner_id:
|
||||
raise wizard.except_wizard(
|
||||
raise osv.except_osv(
|
||||
_('Error'),
|
||||
_('There is insufficient information.\r\n'
|
||||
'Both destination address and account '
|
||||
@@ -323,13 +296,13 @@ class wizard_banking_export_clieop(wizard.interface):
|
||||
# Is this an IBAN account?
|
||||
if iban.valid:
|
||||
if iban.countrycode != 'NL':
|
||||
raise wizard.except_wizard(
|
||||
raise osv.except_osv(
|
||||
_('Error'),
|
||||
_('You cannot send international bank transfers '
|
||||
'through ClieOp3!')
|
||||
)
|
||||
other_account_nr = iban.localized_BBAN
|
||||
if form['batchtype'] == 'CLIEOPINC':
|
||||
if clieop_export['batchtype'] == 'CLIEOPINC':
|
||||
kwargs['accountno_beneficiary'] = our_account_nr
|
||||
kwargs['accountno_payer'] = other_account_nr
|
||||
else:
|
||||
@@ -339,87 +312,63 @@ class wizard_banking_export_clieop(wizard.interface):
|
||||
|
||||
# Generate the specifics of this clieopfile
|
||||
order = clieopfile.order
|
||||
values = dict(
|
||||
filetype = order.name_transactioncode,
|
||||
identification = order.identification,
|
||||
prefered_date = strfdate(order.preferred_execution_date),
|
||||
total_amount = int(order.total_amount) / 100.0,
|
||||
check_no_accounts = order.total_accountnos,
|
||||
no_transactions = order.nr_posts,
|
||||
testcode = order.testcode,
|
||||
file = base64.encodestring(clieopfile.rawdata),
|
||||
)
|
||||
form.update(values)
|
||||
values['daynumber'] = int(clieopfile.header.file_id[2:])
|
||||
values['payment_order_ids'] = ','.join(map(str, data['ids']))
|
||||
data['file_id'] = pool.get('banking.export.clieop').create(cursor, uid, values)
|
||||
data['clieop'] = clieopfile
|
||||
form['log'] = ''
|
||||
return form
|
||||
file_id = self.pool.get('banking.export.clieop').create(
|
||||
cursor, uid, dict(
|
||||
filetype = order.name_transactioncode,
|
||||
identification = order.identification,
|
||||
prefered_date = strfdate(order.preferred_execution_date),
|
||||
total_amount = int(order.total_amount) / 100.0,
|
||||
check_no_accounts = order.total_accountnos,
|
||||
no_transactions = order.nr_posts,
|
||||
testcode = order.testcode,
|
||||
file = base64.encodestring(clieopfile.rawdata),
|
||||
daynumber = int(clieopfile.header.file_id[2:]),
|
||||
payment_order_ids = [
|
||||
[6, 0, [x.id for x in clieop_export['payment_order_ids']]]
|
||||
],
|
||||
), context)
|
||||
self.write(cursor, uid, [ids[0]], dict(
|
||||
filetype = order.name_transactioncode,
|
||||
testcode = order.testcode,
|
||||
file_id = file_id,
|
||||
state = 'finish',
|
||||
), context)
|
||||
return {
|
||||
'name': _('Client Opdrachten Export'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': self._name,
|
||||
'domain': [],
|
||||
'context': dict(context, active_ids=ids),
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
'res_id': ids[0] or False,
|
||||
}
|
||||
|
||||
def _cancel_clieop(self, cursor, uid, data, context):
|
||||
def cancel_clieop(self, cursor, uid, ids, context):
|
||||
'''
|
||||
Cancel the ClieOp: just drop the file
|
||||
'''
|
||||
pool = pooler.get_pool(cursor.dbname)
|
||||
pool.get('banking.export.clieop').unlink(cursor, uid, data['file_id'])
|
||||
return {'state': 'end'}
|
||||
clieop_export = self.read(cursor, uid, ids, ['file_id'], context)[0]
|
||||
self.pool.get('banking.export.clieop').unlink(cursor, uid, clieop_export['file_id'])
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
def _save_clieop(self, cursor, uid, data, context):
|
||||
def save_clieop(self, cursor, uid, ids, context):
|
||||
'''
|
||||
Save the ClieOp: mark all payments in the file as 'sent', if not a test
|
||||
'''
|
||||
if 'test' not in data['form'] or not data['form']['test']:
|
||||
pool = pooler.get_pool(cursor.dbname)
|
||||
clieop_obj = pool.get('banking.export.clieop')
|
||||
payment_order_obj = pool.get('payment.order')
|
||||
clieop_export = self.browse(
|
||||
cursor, uid, ids, context)[0]
|
||||
if not clieop_export['test']:
|
||||
clieop_obj = self.pool.get('banking.export.clieop')
|
||||
payment_order_obj = self.pool.get('payment.order')
|
||||
clieop_file = clieop_obj.write(
|
||||
cursor, uid, data['file_id'], {'state':'sent'}
|
||||
cursor, uid, clieop_export['file_id'].id, {'state':'sent'}
|
||||
)
|
||||
payment_order_obj.action_sent(cursor, uid, data['ids'])
|
||||
return {'state': 'end'}
|
||||
payment_order_obj.action_sent(
|
||||
cursor, uid, [x.id for x in clieop_export['payment_order_ids']])
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_check_orders],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': form,
|
||||
'fields' : fields,
|
||||
'state': [
|
||||
('end', 'Cancel', 'gtk-cancel'),
|
||||
('create', 'Create', 'gtk-ok'),
|
||||
]
|
||||
}
|
||||
},
|
||||
'create': {
|
||||
'actions': [_create_clieop],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': file_form,
|
||||
'fields': file_fields,
|
||||
'state': [
|
||||
('cancel', 'Cancel', 'gtk-cancel'),
|
||||
('save', 'Finish', 'gtk-ok'),
|
||||
]
|
||||
},
|
||||
},
|
||||
'cancel': {
|
||||
'actions': [_cancel_clieop],
|
||||
'result': {
|
||||
'type': 'state',
|
||||
'state': 'end'
|
||||
}
|
||||
},
|
||||
'save': {
|
||||
'actions': [_save_clieop],
|
||||
'result': {
|
||||
'type': 'state',
|
||||
'state': 'end'
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
wizard_banking_export_clieop('account_banking_nl_clieop.banking_export_clieop')
|
||||
banking_export_clieop_wizard()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
58
account_banking_nl_clieop/wizard/export_clieop_view.xml
Normal file
58
account_banking_nl_clieop/wizard/export_clieop_view.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="banking_export_clieop_wizard_view" model="ir.ui.view">
|
||||
<field name="name">banking.export.clieop.wizard.view</field>
|
||||
<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>
|
||||
</data>
|
||||
</openerp>
|
||||
Reference in New Issue
Block a user