Merge lp:~luc-demeyer/account-financial-tools/7.0-account_pain into lp:~account-core-editors/account-financial-tools/7.0

Proposed by Luc De Meyer (Noviat) on 2013-10-22
Status: Work in progress
Proposed branch: lp:~luc-demeyer/account-financial-tools/7.0-account_pain
Merge into: lp:~account-core-editors/account-financial-tools/7.0
Diff against target: 2229 lines (+2153/-0)
13 files modified
account_pain/README.txt (+3/-0)
account_pain/__init__.py (+25/-0)
account_pain/__openerp__.py (+65/-0)
account_pain/account_move_line.py (+104/-0)
account_pain/account_pain_wizard.xml (+36/-0)
account_pain/account_payment.py (+233/-0)
account_pain/account_payment_view.xml (+143/-0)
account_pain/i18n/fr.po (+78/-0)
account_pain/i18n/nl.po (+78/-0)
account_pain/wizard/__init__.py (+24/-0)
account_pain/wizard/pain_wizard.py (+303/-0)
account_pain/wizard/payment_order_create.py (+140/-0)
account_pain/xsd/pain.001.001.03.xsd (+921/-0)
To merge this branch: bzr merge lp:~luc-demeyer/account-financial-tools/7.0-account_pain
Reviewer Review Type Date Requested Status
Stefan Rijnhart (Opener) Disapprove on 2013-10-23
Raphaël Valyi - http://www.akretion.com Needs Fixing on 2013-10-23
Pedro Manuel Baeza 2013-10-22 Needs Information on 2013-10-22
Review via email: mp+192256@code.launchpad.net

Description of the Change

add support for SEPA payments (ISO 20022)

To post a comment you must log in.
Pedro Manuel Baeza (pedro.baeza) wrote :

Hi, Luc, maybe account-payment repository is better for this module?

Regards.

review: Needs Information
Alexis de Lattre (alexis-via) wrote :

@Pedro

I think SEPA-related stuff belongs to the banking-addons https://launchpad.net/banking-addons

By the way, there is already a module for SEPA Credit Transfer in the banking-addons (account_banking_sepa_credit_transfer), so it would be interesting to see if there are some features that are in this module but are not in the module account_banking_sepa_credit_transfer and merge the features of the 2 modules.

Hello Luc,

cool to see Noviat joining the OCA effort. I won't comment functionally but certainly the remarks of Alexis and Pedro are valid.

Technically, there a few caveats that the watchdogs will remind you if I don't, so let's do it:

* please use orm.Model instead of osv.osv which is deprecated now
* also use orm.TransientModel instead of osv.memory
* also you use context={} in methods definitions at lines 309, 324, 327 and 458. You better use the ugly context=None + test against None plumbing instead. Indeed the mutable {} would eventually remain from a method call to another, see http://effbot.org/zone/default-values.htm eventually (Hey but I guess you knew it already).

Regards.

review: Needs Fixing

Hi Luc,

I gladly welcome the initiative of Noviat of bringing their great modules under the umbrella of the community projects!

With regards to this particular module, I must agree with Alexis that his module overlaps greatly with this module. Now before Stéphane Bidoul made a great effort to decouple the banking addons export modules from the whole bank statement import and reconciliation bit, there would have been a legitimate place for a standalone module like this. But since Alexis' SEPA export module can now also be used with only a very thin boilerplate architecture (account_banking_payment_export), I have to disagree with adopting this module too.

Looking at what this module adds is as announced, heavily biased for Belgium. This is awkward in a module that has potential use in all of Europe, but it would be perfectly alright to refactor them out into a module on top of account_banking_sepa_credit_transfer. Additionally, I see that you allow sale refunds to be selected in the payment order. Given its general usefulness, this should probably be adopted in account_banking_payment_export. Same for improving support for multi-currency environments.

I hope that my review is not discouraging you. Your input is much appreciated, but the point of the community repositories is also to combine focus and avoid double work.

Cheers,
Stefan.

review: Disapprove
Pedro Manuel Baeza (pedro.baeza) wrote :

Hi, I told about account-payment repository because I see that this feature is developed following account-payment approach instead of banking-payment, the same as, for example, spanish bank formats export.

Maybe the two approaches can coexist?

Regards.

Hello Pedro,

just to mention: in Brazil we are also account-payment biased so far (we
were inspired by NaN module like 4 years ago now). And we still have to
develop SEPA like format but for Brazil (CNAB). So we have more or less the
same problem as you. I'm not sure yet what approach is the best, but we
should definitely keep convergence in mind with account-payment and
banking-payment. I also mention that it looks that NaN and Ziakzak recently
ported the account-payment approach to Tryton (so they stick we it).

Regards.

On Wed, Oct 23, 2013 at 6:25 AM, Pedro Manuel Baeza
<email address hidden>wrote:

> Hi, I told about account-payment repository because I see that this
> feature is developed following account-payment approach instead of
> banking-payment, the same as, for example, spanish bank formats export.
>
> Maybe the two approaches can coexist?
>
> Regards.
> --
>
> https://code.launchpad.net/~luc-demeyer/account-financial-tools/7.0-account_pain/+merge/192256
> You are reviewing the proposed merge of
> lp:~luc-demeyer/account-financial-tools/7.0-account_pain into
> lp:account-financial-tools.
>

124. By Luc De Meyer on 2013-10-31

technical update

Luc De Meyer (Noviat) (luc-demeyer) wrote :

I updated the https://code.launchpad.net/~luc-demeyer/account-financial-tools/7.0-account_pain branch with the technical changes documented below.

Luc

-----Original Message-----
From: <email address hidden> [mailto:<email address hidden>] On Behalf Of Raphaël Valyi - http://www.akretion.com
Sent: woensdag 23 oktober 2013 6:05
To: <email address hidden>
Subject: Re: [Merge] lp:~luc-demeyer/account-financial-tools/7.0-account_pain into lp:account-financial-tools

Review: Needs Fixing

Hello Luc,

cool to see Noviat joining the OCA effort. I won't comment functionally but certainly the remarks of Alexis and Pedro are valid.

Technically, there a few caveats that the watchdogs will remind you if I don't, so let's do it:

* please use orm.Model instead of osv.osv which is deprecated now
* also use orm.TransientModel instead of osv.memory
* also you use context={} in methods definitions at lines 309, 324, 327 and 458. You better use the ugly context=None + test against None plumbing instead. Indeed the mutable {} would eventually remain from a method call to another, see http://effbot.org/zone/default-values.htm eventually (Hey but I guess you knew it already).

Regards.

--
https://code.launchpad.net/~luc-demeyer/account-financial-tools/7.0-account_pain/+merge/192256
You are the owner of lp:~luc-demeyer/account-financial-tools/7.0-account_pain.

Luc De Meyer (Noviat) (luc-demeyer) wrote :

I am in favor of one SEPA community module in stead of multiple.

Hence the best approach would be to merge the functionality.
After a quick comparison module from Alexis I think it's no too hard to do.
We should merge the functionality which will require some changes to both the 'account_banking_sepa_credit_transfer' as the underlying 'account_banking_payment_export' and allow for SEPA localisation modules on top of the 'account_banking_sepa_credit_transfer'.
Once this is done, we can migrate our 'account_pain' install base to the new module. We are also working on new functionalities and these would than become more widely available.

Alexis, Stefan,

What about a physical meeting where we run through the requirements and after this produce a new version that can be used as well as the basis for other country specific SEPA extensions.
We can host such a session in our Brussels offices (centrally located between France and Holland, I'll pay dinner, lunch, drinks, ... to compensate for your travel costs).

Regards,
Luc

-----Original Message-----
From: <email address hidden> [mailto:<email address hidden>] On Behalf Of Raphaël Valyi - http://www.akretion.com
Sent: woensdag 23 oktober 2013 15:24
To: Pedro Manuel Baeza
Subject: Re: [Merge] lp:~luc-demeyer/account-financial-tools/7.0-account_pain into lp:account-financial-tools

Hello Pedro,

just to mention: in Brazil we are also account-payment biased so far (we were inspired by NaN module like 4 years ago now). And we still have to develop SEPA like format but for Brazil (CNAB). So we have more or less the same problem as you. I'm not sure yet what approach is the best, but we should definitely keep convergence in mind with account-payment and banking-payment. I also mention that it looks that NaN and Ziakzak recently ported the account-payment approach to Tryton (so they stick we it).

Regards.

On Wed, Oct 23, 2013 at 6:25 AM, Pedro Manuel Baeza
<email address hidden>wrote:

> Hi, I told about account-payment repository because I see that this
> feature is developed following account-payment approach instead of
> banking-payment, the same as, for example, spanish bank formats export.
>
> Maybe the two approaches can coexist?
>
> Regards.
> --
>
> https://code.launchpad.net/~luc-demeyer/account-financial-tools/7.0-ac
> count_pain/+merge/192256 You are reviewing the proposed merge of
> lp:~luc-demeyer/account-financial-tools/7.0-account_pain into
> lp:account-financial-tools.
>

--
https://code.launchpad.net/~luc-demeyer/account-financial-tools/7.0-account_pain/+merge/192256
You are the owner of lp:~luc-demeyer/account-financial-tools/7.0-account_pain.

125. By Luc De Meyer on 2013-10-31

technical update

Alexis de Lattre (alexis-via) wrote :

Here is result of the Akretion-Noviat code sprint on SEPA credit transfer to add the additionnal features of the module account_pain inside the module account_banking_sepa_credit_transfer :

https://code.launchpad.net/~akretion-team/banking-addons/70-akretion-noviat-sepa-sprint

But before I propose this branch for a merge on lp:banking-addons, I will need to have the following MP approved : https://code.launchpad.net/~akretion-team/banking-addons/70-sepa-credit-transfer-update/+merge/194948

Unmerged revisions

125. By Luc De Meyer on 2013-10-31

technical update

124. By Luc De Meyer on 2013-10-31

technical update

123. By Luc De Meyer on 2013-10-22

add account_pain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'account_pain'
2=== added file 'account_pain/README.txt'
3--- account_pain/README.txt 1970-01-01 00:00:00 +0000
4+++ account_pain/README.txt 2013-10-31 17:26:11 +0000
5@@ -0,0 +1,3 @@
6+Installation tips
7+=================
8+
9
10=== added file 'account_pain/__init__.py'
11--- account_pain/__init__.py 1970-01-01 00:00:00 +0000
12+++ account_pain/__init__.py 2013-10-31 17:26:11 +0000
13@@ -0,0 +1,25 @@
14+# -*- encoding: utf-8 -*-
15+##############################################################################
16+#
17+# OpenERP, Open Source Management Solution
18+#
19+# Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
20+#
21+# This program is free software: you can redistribute it and/or modify
22+# it under the terms of the GNU Affero General Public License as
23+# published by the Free Software Foundation, either version 3 of the
24+# License, or (at your option) any later version.
25+#
26+# This program is distributed in the hope that it will be useful,
27+# but WITHOUT ANY WARRANTY; without even the implied warranty of
28+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29+# GNU Affero General Public License for more details.
30+#
31+# You should have received a copy of the GNU Affero General Public License
32+# along with this program. If not, see <http://www.gnu.org/licenses/>.
33+#
34+##############################################################################
35+
36+from . import account_payment
37+from . import account_move_line
38+from . import wizard
39
40=== added file 'account_pain/__openerp__.py'
41--- account_pain/__openerp__.py 1970-01-01 00:00:00 +0000
42+++ account_pain/__openerp__.py 2013-10-31 17:26:11 +0000
43@@ -0,0 +1,65 @@
44+# -*- encoding: utf-8 -*-
45+##############################################################################
46+#
47+# OpenERP, Open Source Management Solution
48+#
49+# Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
50+#
51+# This program is free software: you can redistribute it and/or modify
52+# it under the terms of the GNU Affero General Public License as
53+# published by the Free Software Foundation, either version 3 of the
54+# License, or (at your option) any later version.
55+#
56+# This program is distributed in the hope that it will be useful,
57+# but WITHOUT ANY WARRANTY; without even the implied warranty of
58+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59+# GNU Affero General Public License for more details.
60+#
61+# You should have received a copy of the GNU Affero General Public License
62+# along with this program. If not, see <http://www.gnu.org/licenses/>.
63+#
64+##############################################################################
65+{
66+ 'name': 'ISO 20022 XML payment files',
67+ 'version': '0.1',
68+ 'license': 'AGPL-3',
69+ 'author': 'Noviat',
70+ 'category': 'Generic Modules/Accounting',
71+ 'description': """
72+
73+ISO 20022 XML payment files
74+===========================
75+
76+Module to generate Customer Credit Transfer Initiation message ISO 20022 XML - pain.001.001.03.
77+
78+This module implements the following subset of the ISO 20022 specifications:
79+
80+European Credit Transfers:
81+--------------------------
82+* debtor and creditor account in SEPA countries
83+* debtor account in Company currency
84+* creditor account in Company currency
85+* creditor account identified by BIC & IBAN
86+* support for single payments
87+
88+The module also prohibits the removal of a confirmed Payment Order.
89+Such a removal is still possible via the 'Undo Payment' button available to users of the 'Accounting / Manager' group.
90+
91+Features targeted for the Belgian market (cf. febelfin guidelines):
92+
93+* creditor account identified by IBAN (without BIC) for BE IBAN accounts
94+* support for belgian structured communication format
95+* by default, the right part of the VAT number (KBO/BCE number) is used to identify the Initiating Party
96+
97+ """,
98+ 'depends': ['account','base_iban', 'account_payment'],
99+ 'demo_xml': [],
100+ 'init_xml': [],
101+ 'update_xml' : [
102+# 'security/ir.model.access.csv',
103+ 'account_pain_wizard.xml',
104+ 'account_payment_view.xml',
105+ ],
106+ 'active': False,
107+ 'installable': True,
108+}
109
110=== added file 'account_pain/account_move_line.py'
111--- account_pain/account_move_line.py 1970-01-01 00:00:00 +0000
112+++ account_pain/account_move_line.py 2013-10-31 17:26:11 +0000
113@@ -0,0 +1,104 @@
114+# -*- encoding: utf-8 -*-
115+##############################################################################
116+#
117+# OpenERP, Open Source Management Solution
118+#
119+# Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
120+#
121+# This program is free software: you can redistribute it and/or modify
122+# it under the terms of the GNU Affero General Public License as
123+# published by the Free Software Foundation, either version 3 of the
124+# License, or (at your option) any later version.
125+#
126+# This program is distributed in the hope that it will be useful,
127+# but WITHOUT ANY WARRANTY; without even the implied warranty of
128+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
129+# GNU Affero General Public License for more details.
130+#
131+# You should have received a copy of the GNU Affero General Public License
132+# along with this program. If not, see <http://www.gnu.org/licenses/>.
133+#
134+##############################################################################
135+
136+from openerp.tools.translate import _
137+from openerp.osv import fields, orm
138+from operator import itemgetter
139+import logging
140+_logger = logging.getLogger(__name__)
141+
142+class account_move_line(orm.Model):
143+ _inherit = "account.move.line"
144+
145+ def amount_to_pay(self, cr, uid, ids, name, arg={}, context=None):
146+ """ Return the amount still to pay regarding all the payment orders
147+ (excepting cancelled orders)"""
148+ if not ids:
149+ return {}
150+ amounts_residual = self.read(cr, uid, ids, ['amount_residual'], context=context)
151+ cr.execute("""SELECT ml.id,
152+ (SELECT coalesce(sum(amount_currency),0)
153+ FROM payment_line pl
154+ INNER JOIN payment_order po
155+ ON (pl.order_id = po.id)
156+ WHERE move_line_id = ml.id
157+ AND po.state != 'cancel') AS pl_amount
158+ FROM account_move_line ml
159+ WHERE id IN %s""", (tuple(ids),))
160+ amounts_paylines = dict(cr.fetchall())
161+ amounts_to_pay = {}
162+ for entry in amounts_residual:
163+ k = entry['id']
164+ v = entry['amount_residual'] - amounts_paylines[k]
165+ amounts_to_pay[k] = v
166+ return amounts_to_pay
167+
168+ def _to_pay_search(self, cr, uid, obj, name, args, context=None):
169+ if not args:
170+ return []
171+ if not context: context={}
172+ context['all_fiscalyear'] = True
173+ line_obj = self.pool.get('account.move.line')
174+ query = line_obj._query_get(cr, uid, context={})
175+ query += 'AND l.blocked = False '
176+ where = ' and '.join(map(lambda x: '''(SELECT
177+ CASE WHEN l.amount_currency < 0
178+ THEN - l.amount_currency
179+ ELSE l.credit
180+ END - coalesce(sum(pl.amount_currency), 0)
181+ FROM payment_line pl
182+ INNER JOIN payment_order po ON (pl.order_id = po.id)
183+ WHERE move_line_id = l.id
184+ AND po.state != 'cancel'
185+ ) %(operator)s %%s ''' % {'operator': x[1]}, args))
186+ sql_args = tuple(map(itemgetter(2), args))
187+
188+ cr.execute(('''SELECT id
189+ FROM account_move_line l
190+ WHERE account_id IN (select id
191+ FROM account_account
192+ WHERE type in %s AND active)
193+ AND reconcile_id IS null
194+ AND credit > 0
195+ AND ''' + where + ' AND ' + query), (('payable','receivable'),)+sql_args ) # fix Noviat to include sale refunds
196+
197+ res = cr.fetchall()
198+ if not res:
199+ return [('id', '=', '0')]
200+ return [('id', 'in', map(lambda x:x[0], res))]
201+
202+ _columns = {
203+ 'amount_to_pay': fields.function(amount_to_pay, method=True,
204+ type='float', string='Amount to pay', fnct_search=_to_pay_search),
205+ }
206+
207+ def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
208+ if view_type == 'tree':
209+ mod_obj = self.pool.get('ir.model.data')
210+ if context is None:
211+ context = {}
212+ if context.get('account_payment', False):
213+ model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'view_move_line_tree_account_pain')], context=context)
214+ view_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
215+ return super(account_move_line, self).fields_view_get(cr, uid, view_id, view_type, context=context, toolbar=toolbar, submenu=submenu)
216+
217+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
218
219=== added file 'account_pain/account_pain_wizard.xml'
220--- account_pain/account_pain_wizard.xml 1970-01-01 00:00:00 +0000
221+++ account_pain/account_pain_wizard.xml 2013-10-31 17:26:11 +0000
222@@ -0,0 +1,36 @@
223+<?xml version="1.0" ?>
224+<openerp>
225+ <data>
226+
227+ <record id="account_pain_save_view" model="ir.ui.view">
228+ <field name="name">ISO 20022 payment file</field>
229+ <field name="model">account.pain.create</field>
230+ <field name="priority">1</field>
231+ <field name="arch" type="xml">
232+ <form string="The ISO 20022 payment file has been created" version="7.0">
233+ <p>Click on link below to download the XML File</p>
234+ <p>
235+ <b>
236+ <field name="pain_data" readonly="1" filename="pain_fname"/>
237+ <field name="pain_fname" invisible="1"/>
238+ </b>
239+ </p>
240+ <separator colspan="4"/>
241+ <field name="note" colspan="4" attrs="{'invisible':[('note','=',False)]}"/>
242+ <separator colspan="4"/>
243+ </form>
244+ </field>
245+ </record>
246+
247+ <record id="action_account_pain_create" model="ir.actions.act_window">
248+ <field name="name">The ISO 20022 payment file has been created</field>
249+ <field name="type">ir.actions.act_window</field>
250+ <field name="res_model">account.pain.create</field>
251+ <field name="view_type">form</field>
252+ <field name="view_mode">form</field>
253+ <field name="view_id" ref="account_pain_save_view"/>
254+ <field name="target">new</field>
255+ </record>
256+
257+ </data>
258+</openerp>
259
260=== added file 'account_pain/account_payment.py'
261--- account_pain/account_payment.py 1970-01-01 00:00:00 +0000
262+++ account_pain/account_payment.py 2013-10-31 17:26:11 +0000
263@@ -0,0 +1,233 @@
264+# -*- encoding: utf-8 -*-
265+##############################################################################
266+#
267+# OpenERP, Open Source Management Solution
268+#
269+# Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
270+#
271+# This program is free software: you can redistribute it and/or modify
272+# it under the terms of the GNU Affero General Public License as
273+# published by the Free Software Foundation, either version 3 of the
274+# License, or (at your option) any later version.
275+#
276+# This program is distributed in the hope that it will be useful,
277+# but WITHOUT ANY WARRANTY; without even the implied warranty of
278+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
279+# GNU Affero General Public License for more details.
280+#
281+# You should have received a copy of the GNU Affero General Public License
282+# along with this program. If not, see <http://www.gnu.org/licenses/>.
283+#
284+##############################################################################
285+
286+from openerp.tools.translate import _
287+from openerp.osv import fields, orm
288+
289+from openerp import netsvc
290+import re
291+import logging
292+_logger = logging.getLogger(__name__)
293+
294+def check_bba_comm(val):
295+ supported_chars = '0-9+*/ '
296+ pattern = re.compile('[^' + supported_chars + ']')
297+ if pattern.findall(val or ''):
298+ return False
299+ bbacomm = re.sub('\D', '', val or '')
300+ if len(bbacomm) == 12:
301+ base = int(bbacomm[:10])
302+ mod = base % 97 or 97
303+ if mod == int(bbacomm[-2:]):
304+ return True
305+ return False
306+
307+class payment_mode(orm.Model):
308+ _inherit= 'payment.mode'
309+
310+ def _initiatingparty_default(self, cr, uid, field, context=None):
311+ #_logger.warn('_initiatingparty_default, field=%s, context=%s', field, context)
312+ company = self.pool.get('res.users').browse(cr, uid, uid).company_id
313+ vat = company.partner_id.vat
314+ # Belgium, febelfin specs
315+ if vat and vat[0:2].upper() == 'BE':
316+ kbo_nr = vat[2:].replace(' ','')
317+ if field == 'id':
318+ return kbo_nr
319+ else:
320+ return 'KBO-BCE'
321+ else:
322+ # complete for other countries
323+ return False
324+
325+ def _initiatingparty_id_default(self, cr, uid, context=None):
326+ return self._initiatingparty_default(cr, uid, 'id', context=context)
327+
328+ def _initiatingparty_issr_default(self, cr, uid, context=None):
329+ return self._initiatingparty_default(cr, uid, 'issr', context=context)
330+
331+ _columns = {
332+ 'type': fields.selection([
333+ ('manual', 'Manual'),
334+ ('iso20022', 'ISO 20022')],
335+ 'Type', select=1,
336+ help='Select the Payment Type for the Payment Mode.'),
337+ 'bank_id': fields.many2one('res.partner.bank', "Bank account",
338+ required=False, help='Bank Account for the Payment Mode'),
339+ 'initgpty_id': fields.char('Initiating Party Id', size=35,
340+ help="Identifier of the Initiating Party."
341+ "\nSpecify KBO-BCE number for Belgium."
342+ "\n(Field: InitgPty.Id.OrgId.Othr.Id)"),
343+ 'initgpty_issr': fields.char('Initiating Party Id Issuer', size=35,
344+ help="Issuer of the Identifier of the Initiating Party."
345+ "\nSpecify 'KBO-BCE' for Belgium."
346+ "\n(Field: InitgPty.Id.OrgId.Othr.Issr)"),
347+ }
348+ _defaults = {
349+ 'initgpty_id': _initiatingparty_id_default,
350+ 'initgpty_issr': _initiatingparty_issr_default,
351+ }
352+
353+ def _check_initiatingparty_id(self, cr, uid, ids, context=None):
354+ pm = self.browse(cr, uid, ids[0], context=context)
355+ if pm.initgpty_issr and not pm.initgpty_id:
356+ return False
357+ return True
358+
359+ _constraints = [
360+ (_check_initiatingparty_id, "Configuration Error! Please complete the 'Initiating Party Id' field.", ['initgpty_id'])
361+ ]
362+
363+class payment_order(orm.Model):
364+ _inherit = 'payment.order'
365+
366+ def get_wizard(self, type):
367+ if type == 'iso20022':
368+ return 'account_pain','action_account_pain_create'
369+ else:
370+ return super(payment_order, self).get_wizard(type)
371+
372+ def action_open(self, cr, uid, ids, *args):
373+ for payment in self.browse(cr, uid, ids):
374+ for line in payment.line_ids:
375+ if line.amount_currency <= 0:
376+ raise orm.except_orm(_('Payment Instruction Error!'),
377+ _("Unsupported Payment Instruction in Payment Line %s.\n" \
378+ "The value '%s' is less than the minimum value allowed.")
379+ % (line.name, line.amount_currency))
380+ return super(payment_order, self).action_open(cr, uid, ids, *args)
381+
382+ def unlink(self, cr, uid, ids, context=None):
383+ for order in self.browse(cr, uid, ids, context=context):
384+ if order.state == 'done':
385+ raise orm.except_orm(_('Error'),
386+ _("You can not remove a Payment Order that has already been processed !" \
387+ "\nIf such an action is required, you should first cancel the Order."))
388+ return super(payment_order, self).unlink(cr, uid, ids, context=context)
389+
390+ def button_undo_payment(self, cr, uid, ids, context=None):
391+ att_obj = self.pool.get('ir.attachment')
392+ for order in self.browse(cr, uid, ids, context=context):
393+ att_ids = att_obj.search(cr, uid, [('res_model', '=', 'payment.order'), ('res_id', '=', order.id)])
394+ if att_ids:
395+ att_obj.unlink(cr, uid, att_ids)
396+ self.write(cr, uid, order.id, {'state': 'draft'})
397+ wf_service = netsvc.LocalService("workflow")
398+ wf_service.trg_delete(uid, 'payment.order', order.id, cr)
399+ wf_service.trg_create(uid, 'payment.order', order.id, cr)
400+ return True
401+
402+class payment_line(orm.Model):
403+ _inherit = 'payment.line'
404+
405+ def _get_struct_comm_types(self, cr, uid, context=None):
406+ res = self.pool.get('account.invoice').fields_get(cr, uid, ['reference_type'], context)['reference_type']['selection']
407+ res.pop([i for i,x in enumerate(res) if x[0] == 'none'][0])
408+ bba_list = [i for i,x in enumerate(res) if x[0] == 'bba']
409+ if not bba_list:
410+ res.append(('bba', 'BBA Structured Communication'))
411+ return res
412+
413+ def _check_communication(self, cr, uid, ids):
414+ for line in self.browse(cr, uid, ids):
415+ if line.state == 'structured':
416+ if line.struct_comm_type == 'bba':
417+ return check_bba_comm(line.communication)
418+ return True
419+
420+ def fields_get(self, cr, uid, fields=None, context=None):
421+ fields = super(payment_line,self).fields_get(cr, uid, fields, context)
422+ if context is None:
423+ context = {}
424+ if context.get('payment_line_readonly'):
425+ for field in fields:
426+ fields[field]['readonly'] = True
427+ return fields
428+
429+ def unlink(self, cr, uid, ids, context=None):
430+ if context is None:
431+ context = {}
432+ if context.get('payment_line_readonly'):
433+ raise orm.except_orm(_('Warning'), _('Delete operation not allowed !' \
434+ '\nPlease go to the associated Payment Order in order to delete this payment line'))
435+ return super(payment_line, self).unlink(cr, uid, ids, context=context)
436+
437+ def create(self, cr, uid, vals, context=None):
438+ # copy structured communication of payment line is created by referencing an invoice
439+ if vals.has_key('move_line_id') and vals['move_line_id']:
440+ move_line = self.pool.get('account.move.line').browse(cr, uid, vals['move_line_id'], context)
441+ inv = move_line.invoice
442+ if inv and inv.reference_type != 'none':
443+ vals['state'] = 'structured'
444+ vals['struct_comm_type'] = inv.reference_type
445+ vals['communication'] = inv.reference
446+ # verify correctness of bba structured communication when created via the payment line form
447+ if vals.has_key('state') and (vals['state'] == 'structured'):
448+ if vals.has_key('struct_comm_type') and (vals['struct_comm_type'] == 'bba'):
449+ if vals.has_key('communication'):
450+ bbacomm = vals['communication']
451+ if check_bba_comm(bbacomm):
452+ bbacomm = re.sub('\D', '', bbacomm)
453+ vals['communication'] = '+++' + bbacomm[0:3] + '/' + bbacomm[3:7] + '/' + bbacomm[7:] + '+++'
454+ else:
455+ raise orm.except_orm(_('Payment Instruction Error!'),
456+ _('Invalid BBA Structured Communication in Payment Line %s , please correct !') % vals['name'])
457+ return super(payment_line, self).create(cr, uid, vals, context=context)
458+
459+ def write(self, cr, uid, ids, vals, context=None):
460+ if type(ids) is int:
461+ ids = [ids]
462+ for line in self.browse(cr, uid, ids, context):
463+ vals2 = vals.copy()
464+ if vals.has_key('state'):
465+ line_state = vals['state']
466+ else:
467+ line_state = line.state
468+ if line_state == 'structured':
469+ if vals.has_key('struct_comm_type'):
470+ struct_comm_type = vals['struct_comm_type']
471+ else:
472+ struct_comm_type = line.struct_comm_type or ''
473+ if struct_comm_type == 'bba':
474+ if vals.has_key('communication'):
475+ bbacomm = vals['communication']
476+ else:
477+ bbacomm = line.communication or ''
478+ if check_bba_comm(bbacomm):
479+ bbacomm = re.sub('\D', '', bbacomm)
480+ vals2['communication'] = '+++' + bbacomm[0:3] + '/' + bbacomm[3:7] + '/' + bbacomm[7:] + '+++'
481+ else:
482+ raise orm.except_orm(_('Payment Instruction Error!'),
483+ _('Invalid BBA Structured Communication in Payment Line %s , please correct !') % line.name)
484+ super(payment_line, self).write(cr, uid, [line.id], vals2, context)
485+ return True
486+
487+ _columns = {
488+ 'name': fields.char('Payment Line Ref.', size=64, required=True),
489+ 'state': fields.selection([('normal','Free Communication'), ('structured','Structured Communication')], 'Communication Type', required=True),
490+ 'struct_comm_type': fields.selection(_get_struct_comm_types, 'Structured Communication Type'),
491+ }
492+ _constraints = [
493+ (_check_communication, 'Invalid BBA Structured Communication !', ['Communication']),
494+ ]
495+
496+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
497\ No newline at end of file
498
499=== added file 'account_pain/account_payment_view.xml'
500--- account_pain/account_payment_view.xml 1970-01-01 00:00:00 +0000
501+++ account_pain/account_payment_view.xml 2013-10-31 17:26:11 +0000
502@@ -0,0 +1,143 @@
503+<?xml version="1.0" encoding="utf-8"?>
504+<openerp>
505+ <data>
506+
507+ <record id="view_payment_line_search" model="ir.ui.view">
508+ <field name="name">payment.line.tree.search</field>
509+ <field name="model">payment.line</field>
510+ <field name="arch" type="xml">
511+ <search string="Search Payment Lines">
512+ <group>
513+ <field name="order_id"/>
514+ <field name="ml_inv_ref"/>
515+ <field name="ml_maturity_date"/>
516+ <field name="partner_id" select="1"/>
517+ <field name="communication"/>
518+ <field name="amount"/>
519+ <field name="bank_id" domain="[('partner_id', '=', partner_id)]"/>
520+ <field name="move_line_id" on_change="onchange_move_line(move_line_id,parent.mode)"/>
521+ <field name="create_date"/>
522+ <field name="name"/>
523+ </group>
524+ <newline/>
525+ <group expand="0" string="Group By...">
526+ <filter string="Payment Mode" context="{'group_by': 'bank_id'}" icon="terp-dolar"/>
527+ </group>
528+ </search>
529+ </field>
530+ </record>
531+
532+ <record id="action_payment_line_tree" model="ir.actions.act_window">
533+ <field name="name">Payment Lines</field>
534+ <field name="res_model">payment.line</field>
535+ <field name="view_type">form</field>
536+ <field name="view_mode">tree,form</field>
537+ <field name="search_view_id" ref="view_payment_line_search"/>
538+ <field name="view_id" ref="account_payment.view_payment_line_tree"/>
539+ <field name="context">{'payment_line_readonly':1}</field>
540+ </record>
541+ <menuitem action="action_payment_line_tree" id="menu_action_payment_line" parent="account_payment.menu_main_payment" sequence="4"/>
542+
543+ <act_window domain="[('move_line_id.move_id.id', '=', move_id)]"
544+ id="act_account_invoice_2_payment_line"
545+ name="Payment Lines"
546+ view_type="form"
547+ context="{'payment_line_readonly':1}"
548+ res_model="payment.line" src_model="account.invoice"/>
549+
550+
551+ <record id="account_payment.action_create_payment_order" model="ir.actions.act_window">
552+ <field name="view_id" ref="account_payment.view_create_payment_order"/>
553+ </record>
554+
555+ <!-- change compared to view in account payment : 'name'-field replaced by 'invoice'-field -->
556+ <record model="ir.ui.view" id="view_move_line_tree_account_pain">
557+ <field name="name">account.pain.move.line.tree</field>
558+ <field name="model">account.move.line</field>
559+ <field name="priority" eval="1"/>
560+ <field name="arch" type="xml">
561+ <tree string="Account Entry Line">
562+ <field name="partner_id"/>
563+ <field name="ref"/>
564+ <field name="invoice"/>
565+ <field name="journal_id"/>
566+ <field name="account_id"/>
567+ <field name="date_maturity"/>
568+ <field name="date"/>
569+ <field name="debit" sum="Total debit"/>
570+ <field name="credit" sum="Total credit"/>
571+ <field name="amount_to_pay"/>
572+ <field name="amount_currency"/>
573+ <field name="currency_id"/>
574+ <field name="period_id" invisible="1"/>
575+ </tree>
576+ </field>
577+ </record>
578+
579+ <record id="view_payment_order_form_inherit" model="ir.ui.view">
580+ <field name="name">payment.order.form.inherit</field>
581+ <field name="model">payment.order</field>
582+ <field name="inherit_id" ref="account_payment.view_payment_order_form"/>
583+ <field name="arch" type="xml">
584+ <data>
585+ <xpath expr="//field[@name='line_ids']//page[@string='Payment']//field[@name='state']" position="after">
586+ <group colspan="4" attrs="{'invisible':[('state','=','normal')]}">
587+ <field name="struct_comm_type" attrs="{'required':[('state','=','structured')]}"/>
588+ </group>
589+ </xpath>
590+ <button name="cancel" position="after">
591+ <button name="button_undo_payment" states="done" string="Undo Payment" type="object" groups="account.group_account_manager" icon="gtk-cancel"/>
592+ </button>
593+ <button name="set_done" position="replace">
594+ <button name="%(account_payment.action_account_payment_make_payment)d" states="open" string="Make Payments" type="action" icon="gtk-execute"/>
595+ </button>
596+ </data>
597+ </field>
598+ </record>
599+
600+ <record id="view_payment_mode_search_inherit" model="ir.ui.view">
601+ <field name="name">payment.mode.search.inherit</field>
602+ <field name="model">payment.mode</field>
603+ <field name="inherit_id" ref="account_payment.view_payment_mode_search"/>
604+ <field name="arch" type="xml">
605+ <field name="journal" position="after">
606+ <field name="type"/>
607+ </field>
608+ </field>
609+ </record>
610+
611+ <record id="view_payment_mode_tree_inherit" model="ir.ui.view">
612+ <field name="name">payment.mode.tree.inherit</field>
613+ <field name="model">payment.mode</field>
614+ <field name="inherit_id" ref="account_payment.view_payment_mode_tree"/>
615+ <field name="arch" type="xml">
616+ <field name="journal" position="after">
617+ <field name="type"/>
618+ </field>
619+ </field>
620+ </record>
621+
622+ <record id="view_payment_mode_form_inherit" model="ir.ui.view">
623+ <field name="name">payment.mode.form.inherit</field>
624+ <field name="model">payment.mode</field>
625+ <field name="inherit_id" ref="account_payment.view_payment_mode_form"/>
626+ <field name="arch" type="xml">
627+ <field name="journal" position="after">
628+ <field name="type"/>
629+ </field>
630+ <field name="bank_id" position="attributes">
631+ <attribute name="attrs">{'required':[('type','=','iso20022')]}</attribute>
632+ </field>
633+ <field name="bank_id" position="after">
634+ <field name="initgpty_id" attrs="{'invisible':[('type','!=','iso20022')]}"/>
635+ <field name="initgpty_issr" attrs="{'invisible':[('type','!=','iso20022')]}"/>
636+ </field>
637+ <!--correct partner_id field for GTK client -->
638+ <field name="partner_id" position="replace">
639+ <field name="partner_id" invisible="1"/>
640+ </field>
641+ </field>
642+ </record>
643+
644+ </data>
645+</openerp>
646
647=== added directory 'account_pain/i18n'
648=== added file 'account_pain/i18n/fr.po'
649--- account_pain/i18n/fr.po 1970-01-01 00:00:00 +0000
650+++ account_pain/i18n/fr.po 2013-10-31 17:26:11 +0000
651@@ -0,0 +1,78 @@
652+# French translation of openobject-addons.
653+# This file contains the translation of the following modules:
654+# * account_pain
655+#
656+msgid ""
657+msgstr ""
658+"Project-Id-Version: openobject-addons\n"
659+"Report-Msgid-Bugs-To: support@noviat.be\n"
660+"POT-Creation-Date: 2011-03-24 11:18:30.714000\n"
661+"PO-Revision-Date: 2011-03-24 11:18:30.714000\n"
662+"Last-Translator: Luc De Meyer (Noviat nv/sa)\n"
663+"Language-Team: \n"
664+"MIME-Version: 1.0\n"
665+"Content-Type: text/plain; charset=UTF-8\n"
666+"Content-Transfer-Encoding: 8bit\n"
667+
668+#. module: account_pain
669+#: view:account.pain.create:0
670+msgid "The ISO 20022 payment file has been created"
671+msgstr "Le fichier de paiement ISO 20022 est généré"
672+
673+#. module: account_pain
674+#: view:account.pain.create:0
675+msgid "Click on 'Save as' to save the file on your local disk."
676+msgstr "Sélectionnez 'Enregistrer sous' pour sauvegarder le fichier sur votre disque local."
677+
678+#. module: account_pain
679+#: field:account.pain.create,pain_data:0
680+msgid "Payment File"
681+msgstr "Fichier de paiement"
682+
683+#. module: account_pain
684+#: field:account.pain.create,pain_fname:0
685+msgid "Filename"
686+msgstr "Nom du fichier"
687+
688+#. module: account_pain
689+#: field:account.pain.create,note:0
690+msgid "Remarks"
691+msgstr "Remarques"
692+
693+#. module: account_pain
694+#: code:addons/account_pain/wizard/pain_wizard.py:0
695+#, python-format
696+msgid "Warning:\n"
697+msgstr "Alerte:\n"
698+
699+#. module: account_pain
700+#: code:addons/account_pain/wizard/pain_wizard.py:0
701+#, python-format
702+msgid "\nThe Payment Date on Payment Line %s has been changed."
703+msgstr "\nLa date de paiement du ligne de paiement %s a changé."
704+
705+#. module: account_pain
706+#: field:payment.line,name:0
707+msgid "Payment Line Ref."
708+msgstr "Ref. ligne de paiement"
709+
710+#. module: account_pain
711+#: field:payment.line,struct_comm_type:0
712+msgid "Structured Communication Type"
713+msgstr "Type de communication structurée"
714+
715+#. module: account_pain
716+#: selection:payment.line,struct_comm_type:0
717+msgid "BBA Structured Communication"
718+msgstr "Communication structurée belge (BBA)"
719+
720+#. module: account_pain
721+#: selection:payment.line,state:0
722+msgid "Free Communication"
723+msgstr "Communication libre"
724+
725+#. module: account_pain
726+#: selection:payment.line,state:0
727+msgid "Structured Communication"
728+msgstr "Communication structurée"
729+
730
731=== added file 'account_pain/i18n/nl.po'
732--- account_pain/i18n/nl.po 1970-01-01 00:00:00 +0000
733+++ account_pain/i18n/nl.po 2013-10-31 17:26:11 +0000
734@@ -0,0 +1,78 @@
735+# Dutch translation of openobject-addons.
736+# This file contains the translation of the following modules:
737+# * account_pain
738+#
739+msgid ""
740+msgstr ""
741+"Project-Id-Version: openobject-addons\n"
742+"Report-Msgid-Bugs-To: support@noviat.be\n"
743+"POT-Creation-Date: 2011-03-24 11:18:30.654000\n"
744+"PO-Revision-Date: 2011-03-24 11:18:30.654000\n"
745+"Last-Translator: Luc De Meyer (Noviat nv/sa)\n"
746+"Language-Team: \n"
747+"MIME-Version: 1.0\n"
748+"Content-Type: text/plain; charset=UTF-8\n"
749+"Content-Transfer-Encoding: 8bit\n"
750+
751+#. module: account_pain
752+#: view:account.pain.create:0
753+msgid "The ISO 20022 payment file has been created"
754+msgstr "Het ISO 20022 betalingsbestand is aangemaakt"
755+
756+#. module: account_pain
757+#: view:account.pain.create:0
758+msgid "Click on 'Save as' to save the file on your local disk."
759+msgstr "Selecteer 'Opslaan als' om dit bestand te bewaren op je lokale schijf."
760+
761+#. module: account_pain
762+#: field:account.pain.create,pain_data:0
763+msgid "Payment File"
764+msgstr "Betalingsbestand"
765+
766+#. module: account_pain
767+#: field:account.pain.create,pain_fname:0
768+msgid "Filename"
769+msgstr "Bestandsnaam"
770+
771+#. module: account_pain
772+#: field:account.pain.create,note:0
773+msgid "Remarks"
774+msgstr "Opmerkingen"
775+
776+#. module: account_pain
777+#: code:addons/account_pain/wizard/pain_wizard.py:0
778+#, python-format
779+msgid "Warning:\n"
780+msgstr "Waarschuwing:\n"
781+
782+#. module: account_pain
783+#: code:addons/account_pain/wizard/pain_wizard.py:0
784+#, python-format
785+msgid "\nThe Payment Date on Payment Line %s has been changed."
786+msgstr "\nDe betaaldatum van betaalregel %s is aangepast."
787+
788+#. module: account_pain
789+#: field:payment.line,name:0
790+msgid "Payment Line Ref."
791+msgstr "Ref. Betaalregel"
792+
793+#. module: account_pain
794+#: field:payment.line,struct_comm_type:0
795+msgid "Structured Communication Type"
796+msgstr "Type gestructureerde mededeling"
797+
798+#. module: account_pain
799+#: selection:payment.line,struct_comm_type:0
800+msgid "BBA Structured Communication"
801+msgstr "Belgische gestructureerde mededeling (BBA)"
802+
803+#. module: account_pain
804+#: selection:payment.line,state:0
805+msgid "Free Communication"
806+msgstr "Vrije mededeling"
807+
808+#. module: account_pain
809+#: selection:payment.line,state:0
810+msgid "Structured Communication"
811+msgstr "Gestructureerde mededeling"
812+
813
814=== added directory 'account_pain/static'
815=== added directory 'account_pain/static/src'
816=== added directory 'account_pain/static/src/img'
817=== added file 'account_pain/static/src/img/icon.png'
818Binary files account_pain/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and account_pain/static/src/img/icon.png 2013-10-31 17:26:11 +0000 differ
819=== added directory 'account_pain/wizard'
820=== added file 'account_pain/wizard/__init__.py'
821--- account_pain/wizard/__init__.py 1970-01-01 00:00:00 +0000
822+++ account_pain/wizard/__init__.py 2013-10-31 17:26:11 +0000
823@@ -0,0 +1,24 @@
824+# -*- encoding: utf-8 -*-
825+##############################################################################
826+#
827+# OpenERP, Open Source Management Solution
828+#
829+# Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
830+#
831+# This program is free software: you can redistribute it and/or modify
832+# it under the terms of the GNU Affero General Public License as
833+# published by the Free Software Foundation, either version 3 of the
834+# License, or (at your option) any later version.
835+#
836+# This program is distributed in the hope that it will be useful,
837+# but WITHOUT ANY WARRANTY; without even the implied warranty of
838+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
839+# GNU Affero General Public License for more details.
840+#
841+# You should have received a copy of the GNU Affero General Public License
842+# along with this program. If not, see <http://www.gnu.org/licenses/>.
843+#
844+##############################################################################
845+
846+from . import payment_order_create
847+from . import pain_wizard
848\ No newline at end of file
849
850=== added file 'account_pain/wizard/pain_wizard.py'
851--- account_pain/wizard/pain_wizard.py 1970-01-01 00:00:00 +0000
852+++ account_pain/wizard/pain_wizard.py 2013-10-31 17:26:11 +0000
853@@ -0,0 +1,303 @@
854+# -*- encoding: utf-8 -*-
855+##############################################################################
856+#
857+# OpenERP, Open Source Management Solution
858+#
859+# Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
860+#
861+# This program is free software: you can redistribute it and/or modify
862+# it under the terms of the GNU Affero General Public License as
863+# published by the Free Software Foundation, either version 3 of the
864+# License, or (at your option) any later version.
865+#
866+# This program is distributed in the hope that it will be useful,
867+# but WITHOUT ANY WARRANTY; without even the implied warranty of
868+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
869+# GNU Affero General Public License for more details.
870+#
871+# You should have received a copy of the GNU Affero General Public License
872+# along with this program. If not, see <http://www.gnu.org/licenses/>.
873+#
874+##############################################################################
875+
876+from openerp.tools.translate import _
877+from openerp.osv import fields, orm
878+import re
879+import time
880+import base64
881+from StringIO import StringIO
882+from lxml import etree
883+import tools
884+import logging
885+_logger = logging.getLogger(__name__)
886+
887+class account_payment_make_payment(orm.TransientModel):
888+ _inherit = 'account.payment.make.payment'
889+
890+ def launch_wizard(self, cr, uid, ids, context=None):
891+ """
892+ Search for a wizard to launch according to the type.
893+ Confirm the order without wizard if type is manual.
894+ """
895+ if context is None:
896+ context = {}
897+ obj_payment_order = self.pool.get('payment.order')
898+ obj_model = self.pool.get('ir.model.data')
899+ obj_act = self.pool.get('ir.actions.act_window')
900+ order = obj_payment_order.browse(cr, uid, context['active_id'], context)
901+ payment_type = order.mode and order.mode.type or 'manual'
902+ gw = obj_payment_order.get_wizard(payment_type)
903+ if (not gw) or (payment_type == 'manual'):
904+ obj_payment_order.set_done(cr, uid, [context['active_id']], context)
905+ return {'type': 'ir.actions.act_window_close'}
906+
907+ # add support community modules using the payment gateway wizard plugin
908+ module, wizard = gw
909+ result = obj_model._get_id(cr, uid, module, wizard)
910+ wiz_id = obj_model.read(cr, uid, [result], ['res_id'])[0]['res_id']
911+ if payment_type != 'iso20022':
912+ return_act = obj_act.read(cr, uid, [wiz_id])[0]
913+ return_act.update({'context': context})
914+ return return_act
915+
916+ # generate ISO 20022 XML
917+ data = self.generate_pain(cr, uid, context)
918+ apc_id = self.pool.get('account.pain.create').create(cr, uid, data)
919+ obj_model = self.pool.get('ir.model.data')
920+ model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'), ('name','=','account_pain_save_view')])
921+ resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id']
922+ return {
923+ 'name': _('The ISO 20022 payment file has been created'),
924+ 'view_type': 'form',
925+ 'view_mode': 'form',
926+ 'res_model': 'account.pain.create',
927+ 'res_id': apc_id,
928+ 'views': [(resource_id, 'form')],
929+ 'type': 'ir.actions.act_window',
930+ 'target': 'new',
931+ 'context': context,
932+ }
933+
934+ def format_comm(self, comm):
935+ bbacomm = re.sub('\D', '', comm)
936+ if len(bbacomm) == 12:
937+ base = int(bbacomm[:10])
938+ mod = base % 97 or 97
939+ if mod == int(bbacomm[-2:]):
940+ return bbacomm
941+ return False
942+
943+ def generate_pain(self, cr, uid, context):
944+ if not context:
945+ context = {}
946+ active_id = context.get('active_id', [])
947+
948+ payment_obj = self.pool.get('payment.order')
949+ payment_line_obj = self.pool.get('payment.line')
950+ attachment_obj = self.pool.get('ir.attachment')
951+ payment_line_obj = self.pool.get('payment.line')
952+ note = ''
953+
954+ payment = payment_obj.browse(cr, uid, active_id, context=context)
955+ payment_mode = payment.mode
956+ pain_fname = re.sub('\W', '_', payment.reference).lower() + '.xml'
957+ company = self.pool.get('res.users').browse(cr, uid, uid).company_id
958+ if not (payment_mode.bank_id.bank_bic or payment_mode.bank_id.bank.bic):
959+ raise orm.except_orm(_('Configuration Error!'),
960+ _("Please fill in the BIC code of the Bank Debtor Account for this Payment Order!"))
961+ if not payment.line_ids:
962+ raise orm.except_orm(_('Data Error!'),
963+ _("Your Payment Order does not contain payment instructions!"))
964+ if payment_mode.journal.currency and (payment_mode.journal.currency != company.currency_id):
965+ raise orm.except_orm(_('Payment Order Error!'),
966+ _('Only payments from a bank account in company currency are supported in the current release ' \
967+ 'of the ISO 20022 payment module!'))
968+
969+ # create XML
970+ ns_map = {
971+ None: 'urn:iso:std:iso:20022:tech:xsd:pain.001.001.03',
972+ 'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
973+ }
974+ pain = etree.Element('Document', nsmap = ns_map)
975+ CstmrCdtTrfInitn = etree.SubElement(pain, 'CstmrCdtTrfInitn')
976+ # GroupHeader
977+ GrpHdr = etree.SubElement(CstmrCdtTrfInitn, 'GrpHdr')
978+ MsgId = etree.SubElement(GrpHdr, 'MsgId')
979+ MsgId.text = payment.reference
980+ CreDtTm = etree.SubElement(GrpHdr, 'CreDtTm')
981+ CreDtTm.text = time.strftime('%Y-%m-%dT%H:%M:%S')
982+ NbOfTxs = etree.SubElement(GrpHdr, 'NbOfTxs')
983+ NbOfTxs.text = str(len(payment.line_ids))
984+ CtrlSum = etree.SubElement(GrpHdr, 'CtrlSum')
985+ CtrlSum.text = '%.2f' % payment.total
986+ InitgPty = etree.SubElement(GrpHdr, 'InitgPty')
987+ Nm = etree.SubElement(InitgPty, 'Nm')
988+ Nm.text = company.name
989+ if payment_mode.initgpty_id:
990+ Id = etree.SubElement(InitgPty, 'Id')
991+ OrgId = etree.SubElement(Id, 'OrgId')
992+ Othr = etree.SubElement(OrgId, 'Othr')
993+ Id = etree.SubElement(Othr, 'Id')
994+ Id.text = payment_mode.initgpty_id
995+ if payment_mode.initgpty_issr:
996+ Issr = etree.SubElement(Othr, 'Issr')
997+ Issr.text = payment_mode.initgpty_issr
998+ # PaymentInformation
999+ payment_method = 'TRF'
1000+ for line in payment.line_ids:
1001+ if line.currency != company.currency_id:
1002+ raise orm.except_orm(_('Payment Instruction Error!'),
1003+ _('Unsupported Payment Instruction in Payment Line %s.\n' \
1004+ 'Only payments in company currency are supported in the current release ' \
1005+ 'of the ISO 20022 payment module!') % line.name)
1006+ if not line.amount:
1007+ raise orm.except_orm(_('Payment Instruction Error!'),
1008+ _('Payment Instruction Error in Payment Line %s.\n' \
1009+ 'Please fill in the transaction amount!') %line.name)
1010+ if not (line.bank_id and line.bank_id.iban):
1011+ raise orm.except_orm(_('Payment Instruction Error!'),
1012+ _('Unsupported Payment Instruction in Payment Line %s.\n' \
1013+ 'Please fill in the IBAN number of the Bank Creditor Account for this Payment Line!') % line.name)
1014+
1015+ if payment.date_prefered == 'now':
1016+ execution_date = time.strftime('%Y-%m-%d')
1017+ elif payment.date_prefered == 'fixed':
1018+ execution_date = payment.date_scheduled
1019+ elif payment.date_prefered == 'due':
1020+ if not line.date:
1021+ if line.ml_maturity_date:
1022+ excution_date = ml_maturity_date
1023+ else:
1024+ execution_date = time.strftime('%Y-%m-%d')
1025+ else:
1026+ execution_date = line.date
1027+ else:
1028+ raise orm.except_orm(_('Unsupported Payment Order Option!'),
1029+ _("Please ensure that the 'Preferred date' is equal to 'Due date', 'Directly' or 'Fixed date'!"))
1030+ if execution_date < time.strftime('%Y-%m-%d'):
1031+ execution_date = time.strftime('%Y-%m-%d')
1032+ if line.date != execution_date:
1033+ note += _('\nThe Payment Date on Payment Line %s has been changed.') % line.name
1034+ payment_line_obj.write(cr, uid, line.id, {'date': execution_date})
1035+
1036+ PmtInf = etree.SubElement(CstmrCdtTrfInitn, 'PmtInf')
1037+ PmtInfId = etree.SubElement(PmtInf, 'PmtInfId')
1038+ PmtInfId.text = line.name
1039+ PmtMtd = etree.SubElement(PmtInf, 'PmtMtd')
1040+ PmtMtd.text = payment_method
1041+ BtchBookg = etree.SubElement(PmtInf, 'BtchBookg')
1042+ BtchBookg.text = 'false'
1043+ if payment_method == 'TRF':
1044+ PmtTpInf = etree.SubElement(PmtInf, 'PmtTpInf')
1045+ InstrPrty = etree.SubElement(PmtTpInf, 'InstrPrty')
1046+ InstrPrty.text = 'NORM'
1047+ SvcLvl = etree.SubElement(PmtTpInf, 'SvcLvl')
1048+ Cd = etree.SubElement(SvcLvl, 'Cd')
1049+ Cd.text = 'SEPA'
1050+ ReqdExctnDt = etree.SubElement(PmtInf, 'ReqdExctnDt')
1051+ ReqdExctnDt.text = execution_date
1052+ Dbtr = etree.SubElement(PmtInf, 'Dbtr')
1053+ Nm = etree.SubElement(Dbtr, 'Nm')
1054+ Nm.text = company.name
1055+ DbtrAcct = etree.SubElement(PmtInf, 'DbtrAcct')
1056+ Id = etree.SubElement(DbtrAcct, 'Id')
1057+ IBAN = etree.SubElement(Id, 'IBAN')
1058+ IBAN.text = payment_mode.bank_id.iban.upper().replace(' ','')
1059+ DbtrAgt = etree.SubElement(PmtInf, 'DbtrAgt')
1060+ FinInstnId = etree.SubElement(DbtrAgt, 'FinInstnId')
1061+ BIC = etree.SubElement(FinInstnId, 'BIC')
1062+ BIC.text = re.sub('\s','',payment_mode.bank_id.bank_bic.upper() or payment_mode.bank_id.bank.bic.upper())
1063+ ChrgBr = etree.SubElement(PmtInf, 'ChrgBr')
1064+ ChrgBr.text = 'SLEV'
1065+ CdtTrfTxInf = etree.SubElement(PmtInf, 'CdtTrfTxInf')
1066+ PmtId = etree.SubElement(CdtTrfTxInf, 'PmtId')
1067+ EndToEndId = etree.SubElement(PmtId, 'EndToEndId')
1068+ EndToEndId.text = line.name
1069+ Amt = etree.SubElement(CdtTrfTxInf, 'Amt')
1070+ InstdAmt = etree.SubElement(Amt, 'InstdAmt', Ccy=line.currency.name)
1071+ InstdAmt.text = '%.2f' % line.amount
1072+ if line.bank_id.iban[0:2].upper() not in ['BE']: # to be completed with other countries allowing payments without BIC
1073+ if not (line.bank_id.bank_bic or line.bank_id.bank.bic):
1074+ raise orm.except_orm(_('Configuration Error!'),
1075+ _('Unsupported Payment Instruction in Payment Line %s.\n' \
1076+ 'Please fill in the BIC code of the Bank Creditor Account for this Payment Line!') % line.name)
1077+ if line.bank_id.bank_bic or line.bank_id.bank.bic:
1078+ CdtrAgt = etree.SubElement(CdtTrfTxInf, 'CdtrAgt')
1079+ FinInstnId = etree.SubElement(CdtrAgt, 'FinInstnId')
1080+ BIC = etree.SubElement(FinInstnId, 'BIC')
1081+ BIC.text = re.sub('\s','',line.bank_id.bank_bic.upper() or line.bank_id.bank.bic.upper())
1082+ Cdtr = etree.SubElement(CdtTrfTxInf, 'Cdtr')
1083+ Nm = etree.SubElement(Cdtr, 'Nm')
1084+ Nm.text = line.partner_id.name
1085+ CdtrAcct = etree.SubElement(CdtTrfTxInf, 'CdtrAcct')
1086+ Id = etree.SubElement(CdtrAcct, 'Id')
1087+ IBAN = etree.SubElement(Id, 'IBAN')
1088+ IBAN.text = line.bank_id.iban.upper().replace(' ','')
1089+ if line.communication:
1090+ comm = line.communication
1091+ if line.communication2:
1092+ comm += ' ' + line.communication2
1093+ RmtInf = etree.SubElement(CdtTrfTxInf, 'RmtInf')
1094+ if line.state == 'normal':
1095+ Ustrd = etree.SubElement(RmtInf, 'Ustrd')
1096+ Ustrd.text = comm
1097+ elif line.state == 'structured':
1098+ Strd = etree.SubElement(RmtInf, 'Strd')
1099+ CdtrRefInf = etree.SubElement(Strd, 'CdtrRefInf')
1100+ Tp = etree.SubElement(CdtrRefInf, 'Tp')
1101+ CdOrPrtry = etree.SubElement(Tp, 'CdOrPrtry')
1102+ Cd = etree.SubElement(CdOrPrtry, 'Cd')
1103+ Cd.text = 'SCOR'
1104+ Issr = etree.SubElement(Tp, 'Issr')
1105+ Issr.text = 'BBA'
1106+ comm = self.format_comm(line.communication)
1107+ if not comm:
1108+ raise orm.except_orm(_('Payment Instruction Error!'),
1109+ _('Unsupported Structured Communication in Payment Line %s.\n' \
1110+ 'Only the Belgian Structured Communication format (BBA) is supported in the current release ' \
1111+ 'of the ISO 20022 payment module!') % line.name)
1112+ Ref = etree.SubElement(CdtrRefInf, 'Ref')
1113+ Ref.text = comm
1114+ else:
1115+ raise orm.except_orm(_('Configuration Error!'),
1116+ _('Unsupported Communication Type in Payment Line %s.\n') % line.name)
1117+ pain_data = etree.tostring(pain, encoding='UTF-8', xml_declaration=True, pretty_print=True)
1118+ # validate the generated XML schema
1119+ xsd = tools.file_open('account_pain/xsd/pain.001.001.03.xsd')
1120+ xmlschema_doc = etree.parse(xsd)
1121+ xmlschema = etree.XMLSchema(xmlschema_doc)
1122+ xml_to_validate = StringIO(pain_data)
1123+ parse_result = etree.parse(xml_to_validate)
1124+ if xmlschema.validate(parse_result):
1125+ pain_data = base64.encodestring(pain_data)
1126+ attachment_obj.create(cr, uid, {
1127+ 'name': pain_fname,
1128+ 'datas': pain_data,
1129+ 'datas_fname': pain_fname,
1130+ 'res_model': 'payment.order',
1131+ 'res_id': active_id,
1132+ }, context=context)
1133+ payment_obj.set_done(cr, uid, [active_id], context)
1134+ else:
1135+ _logger.error('The generated XML file does not fit the required schema !')
1136+ _logger.error(tools.ustr(xmlschema.error_log.last_error))
1137+ error = xmlschema.error_log[0]
1138+ raise orm.except_orm(_('The generated XML file does not fit the required schema !'),
1139+ error.message)
1140+
1141+ if note:
1142+ note = _('Warning:\n') + note
1143+
1144+ return {'pain_data': pain_data, 'pain_fname': pain_fname, 'note': note}
1145+
1146+class account_pain_create(orm.TransientModel):
1147+ _name = 'account.pain.create'
1148+ _description = 'ISO 20022 payment file'
1149+
1150+ _columns = {
1151+ 'pain_data': fields.binary('Payment File', required=True, readonly=True),
1152+ 'pain_fname': fields.char('Filename', size=128, required=True),
1153+ 'note': fields.text('Remarks'),
1154+ }
1155+
1156+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1157\ No newline at end of file
1158
1159=== added file 'account_pain/wizard/payment_order_create.py'
1160--- account_pain/wizard/payment_order_create.py 1970-01-01 00:00:00 +0000
1161+++ account_pain/wizard/payment_order_create.py 2013-10-31 17:26:11 +0000
1162@@ -0,0 +1,140 @@
1163+# -*- encoding: utf-8 -*-
1164+##############################################################################
1165+#
1166+# OpenERP, Open Source Management Solution
1167+#
1168+# Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
1169+#
1170+# This program is free software: you can redistribute it and/or modify
1171+# it under the terms of the GNU Affero General Public License as
1172+# published by the Free Software Foundation, either version 3 of the
1173+# License, or (at your option) any later version.
1174+#
1175+# This program is distributed in the hope that it will be useful,
1176+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1177+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1178+# GNU Affero General Public License for more details.
1179+#
1180+# You should have received a copy of the GNU Affero General Public License
1181+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1182+#
1183+##############################################################################
1184+
1185+from datetime import datetime, date, timedelta
1186+from lxml import etree
1187+from openerp.osv import fields, orm
1188+from tools.translate import _
1189+import logging
1190+_logger = logging.getLogger(__name__)
1191+
1192+class payment_order_create(orm.TransientModel):
1193+ _inherit = 'payment.order.create'
1194+
1195+ _defaults = {
1196+ 'duedate': lambda *a: (date.today() + timedelta(30)).isoformat(),
1197+ }
1198+
1199+ def journal_domain(self, cr, uid, context=None):
1200+ """
1201+ override this method in order to customise the journals to search on
1202+ """
1203+ journal_domain = [('journal_id.type', 'in', ['purchase', 'sale_refund', 'general', 'situation'])]
1204+ return journal_domain
1205+
1206+ def search_entries(self, cr, uid, ids, context=None):
1207+ """
1208+ Override the search_entries & fields_view_get methods of the account_payment payment.order.create object
1209+ """
1210+ line_obj = self.pool.get('account.move.line')
1211+ mod_obj = self.pool.get('ir.model.data')
1212+ if context is None:
1213+ context = {}
1214+ data = self.read(cr, uid, ids, [], context=context)[0]
1215+ search_due_date = data['duedate']
1216+ # Search for move line to pay:
1217+ domain = [('reconcile_id', '=', False), ('partner_id', '!=', False), ('account_id.type', 'in', ['payable', 'receivable']), ('amount_to_pay', '>', 0)] # update Noviat
1218+ domain = domain + ['|', ('date_maturity', '<=', search_due_date), ('date_maturity', '=', False)]
1219+ journal_domain = self.journal_domain(cr, uid)
1220+ domain = domain + journal_domain
1221+ line_ids = line_obj.search(cr, uid, domain, context=context)
1222+ context.update({'line_ids': line_ids})
1223+ model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'view_create_payment_order_lines')], context=context)
1224+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
1225+ return {'name': _('Populate Payment'),
1226+ 'context': context,
1227+ 'view_type': 'form',
1228+ 'view_mode': 'form',
1229+ 'res_model': 'payment.order.create',
1230+ 'views': [(resource_id,'form')],
1231+ 'type': 'ir.actions.act_window',
1232+ 'target': 'new',
1233+ }
1234+
1235+ """
1236+ add context to 'entries' field for use in account.move.line
1237+ """
1238+ def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
1239+ res = super(payment_order_create, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False)
1240+ if context and 'line_ids' in context and view_type == 'form':
1241+ doc = etree.XML(res['arch'])
1242+ nodes = doc.xpath("//field[@name='entries']")
1243+ for node in nodes:
1244+ # add context for use in account.move.line
1245+ node.set('context', "{'account_payment':'1', 'view_mode':'tree'}")
1246+ node.set('colspan', '4')
1247+ node.set('height', '300')
1248+ node.set('width', '800')
1249+ res['arch'] = etree.tostring(doc)
1250+ return res
1251+
1252+ def create_payment(self, cr, uid, ids, context=None):
1253+ """
1254+ This method replaces the original one for multi-currency purposes
1255+ """
1256+ order_obj = self.pool.get('payment.order')
1257+ line_obj = self.pool.get('account.move.line')
1258+ payment_obj = self.pool.get('payment.line')
1259+ if context is None:
1260+ context = {}
1261+ data = self.browse(cr, uid, ids, context=context)[0]
1262+ line_ids = [entry.id for entry in data.entries]
1263+ if not line_ids:
1264+ return {'type': 'ir.actions.act_window_close'}
1265+
1266+ payment = order_obj.browse(cr, uid, context['active_id'], context=context)
1267+ t = payment.mode.type == 'iso20022' and payment.mode.id or None
1268+ line2bank = line_obj.line2bank(cr, uid, line_ids, t, context)
1269+
1270+ company_currency = payment.mode.company_id.currency_id
1271+ payment_mode_currency = payment.mode.journal.currency or company_currency
1272+
1273+ ## Finally populate the current payment with new lines:
1274+ for line in line_obj.browse(cr, uid, line_ids, context=context):
1275+ if payment.date_prefered == "now":
1276+ #no payment date => immediate payment
1277+ date_to_pay = False
1278+ elif payment.date_prefered == 'due':
1279+ date_to_pay = line.date_maturity
1280+ elif payment.date_prefered == 'fixed':
1281+ date_to_pay = payment.date_scheduled
1282+
1283+ transaction_currency = line.currency_id or company_currency
1284+ if transaction_currency != payment_mode_currency and payment.mode.type == 'iso20022':
1285+ raise orm.except_orm(_('Unsupported Operation !'),
1286+ _("The payment in another currency as the originating transaction is not supported in the" \
1287+ "current release of the ISO 20022 Payment Gateway"
1288+ "\nTransaction Currency: %s, Payment Mode Currency: %s)" \
1289+ "\n\nPlease contact info@noviat.be if this is a requirement.")
1290+ %(transaction_currency, payment_mode_currency) )
1291+
1292+ payment_obj.create(cr, uid,{
1293+ 'move_line_id': line.id,
1294+ 'amount_currency': line.amount_to_pay,
1295+ 'bank_id': line2bank.get(line.id),
1296+ 'order_id': payment.id,
1297+ 'partner_id': line.partner_id and line.partner_id.id or False,
1298+ 'communication': line.ref or '/',
1299+ 'date': date_to_pay,
1300+ 'currency': line.currency_id.id or company_currency.id,
1301+ }, context=context)
1302+ return {'type': 'ir.actions.act_window_close'}
1303
1304=== added directory 'account_pain/xsd'
1305=== added file 'account_pain/xsd/pain.001.001.03.xsd'
1306--- account_pain/xsd/pain.001.001.03.xsd 1970-01-01 00:00:00 +0000
1307+++ account_pain/xsd/pain.001.001.03.xsd 2013-10-31 17:26:11 +0000
1308@@ -0,0 +1,921 @@
1309+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1310+<!--Generated by SWIFTStandards Workstation (build:R6.1.0.2) on 2009 Jan 08 17:30:53-->
1311+<xs:schema xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">
1312+ <xs:element name="Document" type="Document"/>
1313+ <xs:complexType name="AccountIdentification4Choice">
1314+ <xs:sequence>
1315+ <xs:choice>
1316+ <xs:element name="IBAN" type="IBAN2007Identifier"/>
1317+ <xs:element name="Othr" type="GenericAccountIdentification1"/>
1318+ </xs:choice>
1319+ </xs:sequence>
1320+ </xs:complexType>
1321+ <xs:complexType name="AccountSchemeName1Choice">
1322+ <xs:sequence>
1323+ <xs:choice>
1324+ <xs:element name="Cd" type="ExternalAccountIdentification1Code"/>
1325+ <xs:element name="Prtry" type="Max35Text"/>
1326+ </xs:choice>
1327+ </xs:sequence>
1328+ </xs:complexType>
1329+ <xs:simpleType name="ActiveOrHistoricCurrencyAndAmount_SimpleType">
1330+ <xs:restriction base="xs:decimal">
1331+ <xs:minInclusive value="0"/>
1332+ <xs:fractionDigits value="5"/>
1333+ <xs:totalDigits value="18"/>
1334+ </xs:restriction>
1335+ </xs:simpleType>
1336+ <xs:complexType name="ActiveOrHistoricCurrencyAndAmount">
1337+ <xs:simpleContent>
1338+ <xs:extension base="ActiveOrHistoricCurrencyAndAmount_SimpleType">
1339+ <xs:attribute name="Ccy" type="ActiveOrHistoricCurrencyCode" use="required"/>
1340+ </xs:extension>
1341+ </xs:simpleContent>
1342+ </xs:complexType>
1343+ <xs:simpleType name="ActiveOrHistoricCurrencyCode">
1344+ <xs:restriction base="xs:string">
1345+ <xs:pattern value="[A-Z]{3,3}"/>
1346+ </xs:restriction>
1347+ </xs:simpleType>
1348+ <xs:simpleType name="AddressType2Code">
1349+ <xs:restriction base="xs:string">
1350+ <xs:enumeration value="ADDR"/>
1351+ <xs:enumeration value="PBOX"/>
1352+ <xs:enumeration value="HOME"/>
1353+ <xs:enumeration value="BIZZ"/>
1354+ <xs:enumeration value="MLTO"/>
1355+ <xs:enumeration value="DLVY"/>
1356+ </xs:restriction>
1357+ </xs:simpleType>
1358+ <xs:complexType name="AmountType3Choice">
1359+ <xs:sequence>
1360+ <xs:choice>
1361+ <xs:element name="InstdAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
1362+ <xs:element name="EqvtAmt" type="EquivalentAmount2"/>
1363+ </xs:choice>
1364+ </xs:sequence>
1365+ </xs:complexType>
1366+ <xs:simpleType name="AnyBICIdentifier">
1367+ <xs:restriction base="xs:string">
1368+ <xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
1369+ </xs:restriction>
1370+ </xs:simpleType>
1371+ <xs:complexType name="Authorisation1Choice">
1372+ <xs:sequence>
1373+ <xs:choice>
1374+ <xs:element name="Cd" type="Authorisation1Code"/>
1375+ <xs:element name="Prtry" type="Max128Text"/>
1376+ </xs:choice>
1377+ </xs:sequence>
1378+ </xs:complexType>
1379+ <xs:simpleType name="Authorisation1Code">
1380+ <xs:restriction base="xs:string">
1381+ <xs:enumeration value="AUTH"/>
1382+ <xs:enumeration value="FDET"/>
1383+ <xs:enumeration value="FSUM"/>
1384+ <xs:enumeration value="ILEV"/>
1385+ </xs:restriction>
1386+ </xs:simpleType>
1387+ <xs:simpleType name="BICIdentifier">
1388+ <xs:restriction base="xs:string">
1389+ <xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
1390+ </xs:restriction>
1391+ </xs:simpleType>
1392+ <xs:simpleType name="BaseOneRate">
1393+ <xs:restriction base="xs:decimal">
1394+ <xs:fractionDigits value="10"/>
1395+ <xs:totalDigits value="11"/>
1396+ </xs:restriction>
1397+ </xs:simpleType>
1398+ <xs:simpleType name="BatchBookingIndicator">
1399+ <xs:restriction base="xs:boolean"/>
1400+ </xs:simpleType>
1401+ <xs:complexType name="BranchAndFinancialInstitutionIdentification4">
1402+ <xs:sequence>
1403+ <xs:element name="FinInstnId" type="FinancialInstitutionIdentification7"/>
1404+ <xs:element maxOccurs="1" minOccurs="0" name="BrnchId" type="BranchData2"/>
1405+ </xs:sequence>
1406+ </xs:complexType>
1407+ <xs:complexType name="BranchData2">
1408+ <xs:sequence>
1409+ <xs:element maxOccurs="1" minOccurs="0" name="Id" type="Max35Text"/>
1410+ <xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
1411+ <xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
1412+ </xs:sequence>
1413+ </xs:complexType>
1414+ <xs:complexType name="CashAccount16">
1415+ <xs:sequence>
1416+ <xs:element name="Id" type="AccountIdentification4Choice"/>
1417+ <xs:element maxOccurs="1" minOccurs="0" name="Tp" type="CashAccountType2"/>
1418+ <xs:element maxOccurs="1" minOccurs="0" name="Ccy" type="ActiveOrHistoricCurrencyCode"/>
1419+ <xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max70Text"/>
1420+ </xs:sequence>
1421+ </xs:complexType>
1422+ <xs:complexType name="CashAccountType2">
1423+ <xs:sequence>
1424+ <xs:choice>
1425+ <xs:element name="Cd" type="CashAccountType4Code"/>
1426+ <xs:element name="Prtry" type="Max35Text"/>
1427+ </xs:choice>
1428+ </xs:sequence>
1429+ </xs:complexType>
1430+ <xs:simpleType name="CashAccountType4Code">
1431+ <xs:restriction base="xs:string">
1432+ <xs:enumeration value="CASH"/>
1433+ <xs:enumeration value="CHAR"/>
1434+ <xs:enumeration value="COMM"/>
1435+ <xs:enumeration value="TAXE"/>
1436+ <xs:enumeration value="CISH"/>
1437+ <xs:enumeration value="TRAS"/>
1438+ <xs:enumeration value="SACC"/>
1439+ <xs:enumeration value="CACC"/>
1440+ <xs:enumeration value="SVGS"/>
1441+ <xs:enumeration value="ONDP"/>
1442+ <xs:enumeration value="MGLD"/>
1443+ <xs:enumeration value="NREX"/>
1444+ <xs:enumeration value="MOMA"/>
1445+ <xs:enumeration value="LOAN"/>
1446+ <xs:enumeration value="SLRY"/>
1447+ <xs:enumeration value="ODFT"/>
1448+ </xs:restriction>
1449+ </xs:simpleType>
1450+ <xs:complexType name="CategoryPurpose1Choice">
1451+ <xs:sequence>
1452+ <xs:choice>
1453+ <xs:element name="Cd" type="ExternalCategoryPurpose1Code"/>
1454+ <xs:element name="Prtry" type="Max35Text"/>
1455+ </xs:choice>
1456+ </xs:sequence>
1457+ </xs:complexType>
1458+ <xs:simpleType name="ChargeBearerType1Code">
1459+ <xs:restriction base="xs:string">
1460+ <xs:enumeration value="DEBT"/>
1461+ <xs:enumeration value="CRED"/>
1462+ <xs:enumeration value="SHAR"/>
1463+ <xs:enumeration value="SLEV"/>
1464+ </xs:restriction>
1465+ </xs:simpleType>
1466+ <xs:complexType name="Cheque6">
1467+ <xs:sequence>
1468+ <xs:element maxOccurs="1" minOccurs="0" name="ChqTp" type="ChequeType2Code"/>
1469+ <xs:element maxOccurs="1" minOccurs="0" name="ChqNb" type="Max35Text"/>
1470+ <xs:element maxOccurs="1" minOccurs="0" name="ChqFr" type="NameAndAddress10"/>
1471+ <xs:element maxOccurs="1" minOccurs="0" name="DlvryMtd" type="ChequeDeliveryMethod1Choice"/>
1472+ <xs:element maxOccurs="1" minOccurs="0" name="DlvrTo" type="NameAndAddress10"/>
1473+ <xs:element maxOccurs="1" minOccurs="0" name="InstrPrty" type="Priority2Code"/>
1474+ <xs:element maxOccurs="1" minOccurs="0" name="ChqMtrtyDt" type="ISODate"/>
1475+ <xs:element maxOccurs="1" minOccurs="0" name="FrmsCd" type="Max35Text"/>
1476+ <xs:element maxOccurs="2" minOccurs="0" name="MemoFld" type="Max35Text"/>
1477+ <xs:element maxOccurs="1" minOccurs="0" name="RgnlClrZone" type="Max35Text"/>
1478+ <xs:element maxOccurs="1" minOccurs="0" name="PrtLctn" type="Max35Text"/>
1479+ </xs:sequence>
1480+ </xs:complexType>
1481+ <xs:simpleType name="ChequeDelivery1Code">
1482+ <xs:restriction base="xs:string">
1483+ <xs:enumeration value="MLDB"/>
1484+ <xs:enumeration value="MLCD"/>
1485+ <xs:enumeration value="MLFA"/>
1486+ <xs:enumeration value="CRDB"/>
1487+ <xs:enumeration value="CRCD"/>
1488+ <xs:enumeration value="CRFA"/>
1489+ <xs:enumeration value="PUDB"/>
1490+ <xs:enumeration value="PUCD"/>
1491+ <xs:enumeration value="PUFA"/>
1492+ <xs:enumeration value="RGDB"/>
1493+ <xs:enumeration value="RGCD"/>
1494+ <xs:enumeration value="RGFA"/>
1495+ </xs:restriction>
1496+ </xs:simpleType>
1497+ <xs:complexType name="ChequeDeliveryMethod1Choice">
1498+ <xs:sequence>
1499+ <xs:choice>
1500+ <xs:element name="Cd" type="ChequeDelivery1Code"/>
1501+ <xs:element name="Prtry" type="Max35Text"/>
1502+ </xs:choice>
1503+ </xs:sequence>
1504+ </xs:complexType>
1505+ <xs:simpleType name="ChequeType2Code">
1506+ <xs:restriction base="xs:string">
1507+ <xs:enumeration value="CCHQ"/>
1508+ <xs:enumeration value="CCCH"/>
1509+ <xs:enumeration value="BCHQ"/>
1510+ <xs:enumeration value="DRFT"/>
1511+ <xs:enumeration value="ELDR"/>
1512+ </xs:restriction>
1513+ </xs:simpleType>
1514+ <xs:complexType name="ClearingSystemIdentification2Choice">
1515+ <xs:sequence>
1516+ <xs:choice>
1517+ <xs:element name="Cd" type="ExternalClearingSystemIdentification1Code"/>
1518+ <xs:element name="Prtry" type="Max35Text"/>
1519+ </xs:choice>
1520+ </xs:sequence>
1521+ </xs:complexType>
1522+ <xs:complexType name="ClearingSystemMemberIdentification2">
1523+ <xs:sequence>
1524+ <xs:element maxOccurs="1" minOccurs="0" name="ClrSysId" type="ClearingSystemIdentification2Choice"/>
1525+ <xs:element name="MmbId" type="Max35Text"/>
1526+ </xs:sequence>
1527+ </xs:complexType>
1528+ <xs:complexType name="ContactDetails2">
1529+ <xs:sequence>
1530+ <xs:element maxOccurs="1" minOccurs="0" name="NmPrfx" type="NamePrefix1Code"/>
1531+ <xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
1532+ <xs:element maxOccurs="1" minOccurs="0" name="PhneNb" type="PhoneNumber"/>
1533+ <xs:element maxOccurs="1" minOccurs="0" name="MobNb" type="PhoneNumber"/>
1534+ <xs:element maxOccurs="1" minOccurs="0" name="FaxNb" type="PhoneNumber"/>
1535+ <xs:element maxOccurs="1" minOccurs="0" name="EmailAdr" type="Max2048Text"/>
1536+ <xs:element maxOccurs="1" minOccurs="0" name="Othr" type="Max35Text"/>
1537+ </xs:sequence>
1538+ </xs:complexType>
1539+ <xs:simpleType name="CountryCode">
1540+ <xs:restriction base="xs:string">
1541+ <xs:pattern value="[A-Z]{2,2}"/>
1542+ </xs:restriction>
1543+ </xs:simpleType>
1544+ <xs:simpleType name="CreditDebitCode">
1545+ <xs:restriction base="xs:string">
1546+ <xs:enumeration value="CRDT"/>
1547+ <xs:enumeration value="DBIT"/>
1548+ </xs:restriction>
1549+ </xs:simpleType>
1550+ <xs:complexType name="CreditTransferTransactionInformation10">
1551+ <xs:sequence>
1552+ <xs:element name="PmtId" type="PaymentIdentification1"/>
1553+ <xs:element maxOccurs="1" minOccurs="0" name="PmtTpInf" type="PaymentTypeInformation19"/>
1554+ <xs:element name="Amt" type="AmountType3Choice"/>
1555+ <xs:element maxOccurs="1" minOccurs="0" name="XchgRateInf" type="ExchangeRateInformation1"/>
1556+ <xs:element maxOccurs="1" minOccurs="0" name="ChrgBr" type="ChargeBearerType1Code"/>
1557+ <xs:element maxOccurs="1" minOccurs="0" name="ChqInstr" type="Cheque6"/>
1558+ <xs:element maxOccurs="1" minOccurs="0" name="UltmtDbtr" type="PartyIdentification32"/>
1559+ <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt1" type="BranchAndFinancialInstitutionIdentification4"/>
1560+ <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt1Acct" type="CashAccount16"/>
1561+ <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt2" type="BranchAndFinancialInstitutionIdentification4"/>
1562+ <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt2Acct" type="CashAccount16"/>
1563+ <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt3" type="BranchAndFinancialInstitutionIdentification4"/>
1564+ <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt3Acct" type="CashAccount16"/>
1565+ <xs:element maxOccurs="1" minOccurs="0" name="CdtrAgt" type="BranchAndFinancialInstitutionIdentification4"/>
1566+ <xs:element maxOccurs="1" minOccurs="0" name="CdtrAgtAcct" type="CashAccount16"/>
1567+ <xs:element maxOccurs="1" minOccurs="0" name="Cdtr" type="PartyIdentification32"/>
1568+ <xs:element maxOccurs="1" minOccurs="0" name="CdtrAcct" type="CashAccount16"/>
1569+ <xs:element maxOccurs="1" minOccurs="0" name="UltmtCdtr" type="PartyIdentification32"/>
1570+ <xs:element maxOccurs="unbounded" minOccurs="0" name="InstrForCdtrAgt" type="InstructionForCreditorAgent1"/>
1571+ <xs:element maxOccurs="1" minOccurs="0" name="InstrForDbtrAgt" type="Max140Text"/>
1572+ <xs:element maxOccurs="1" minOccurs="0" name="Purp" type="Purpose2Choice"/>
1573+ <xs:element maxOccurs="10" minOccurs="0" name="RgltryRptg" type="RegulatoryReporting3"/>
1574+ <xs:element maxOccurs="1" minOccurs="0" name="Tax" type="TaxInformation3"/>
1575+ <xs:element maxOccurs="10" minOccurs="0" name="RltdRmtInf" type="RemittanceLocation2"/>
1576+ <xs:element maxOccurs="1" minOccurs="0" name="RmtInf" type="RemittanceInformation5"/>
1577+ </xs:sequence>
1578+ </xs:complexType>
1579+ <xs:complexType name="CreditorReferenceInformation2">
1580+ <xs:sequence>
1581+ <xs:element maxOccurs="1" minOccurs="0" name="Tp" type="CreditorReferenceType2"/>
1582+ <xs:element maxOccurs="1" minOccurs="0" name="Ref" type="Max35Text"/>
1583+ </xs:sequence>
1584+ </xs:complexType>
1585+ <xs:complexType name="CreditorReferenceType1Choice">
1586+ <xs:sequence>
1587+ <xs:choice>
1588+ <xs:element name="Cd" type="DocumentType3Code"/>
1589+ <xs:element name="Prtry" type="Max35Text"/>
1590+ </xs:choice>
1591+ </xs:sequence>
1592+ </xs:complexType>
1593+ <xs:complexType name="CreditorReferenceType2">
1594+ <xs:sequence>
1595+ <xs:element name="CdOrPrtry" type="CreditorReferenceType1Choice"/>
1596+ <xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
1597+ </xs:sequence>
1598+ </xs:complexType>
1599+ <xs:complexType name="CustomerCreditTransferInitiationV03">
1600+ <xs:sequence>
1601+ <xs:element name="GrpHdr" type="GroupHeader32"/>
1602+ <xs:element maxOccurs="unbounded" minOccurs="1" name="PmtInf" type="PaymentInstructionInformation3"/>
1603+ </xs:sequence>
1604+ </xs:complexType>
1605+ <xs:complexType name="DateAndPlaceOfBirth">
1606+ <xs:sequence>
1607+ <xs:element name="BirthDt" type="ISODate"/>
1608+ <xs:element maxOccurs="1" minOccurs="0" name="PrvcOfBirth" type="Max35Text"/>
1609+ <xs:element name="CityOfBirth" type="Max35Text"/>
1610+ <xs:element name="CtryOfBirth" type="CountryCode"/>
1611+ </xs:sequence>
1612+ </xs:complexType>
1613+ <xs:complexType name="DatePeriodDetails">
1614+ <xs:sequence>
1615+ <xs:element name="FrDt" type="ISODate"/>
1616+ <xs:element name="ToDt" type="ISODate"/>
1617+ </xs:sequence>
1618+ </xs:complexType>
1619+ <xs:simpleType name="DecimalNumber">
1620+ <xs:restriction base="xs:decimal">
1621+ <xs:fractionDigits value="17"/>
1622+ <xs:totalDigits value="18"/>
1623+ </xs:restriction>
1624+ </xs:simpleType>
1625+ <xs:complexType name="Document">
1626+ <xs:sequence>
1627+ <xs:element name="CstmrCdtTrfInitn" type="CustomerCreditTransferInitiationV03"/>
1628+ </xs:sequence>
1629+ </xs:complexType>
1630+ <xs:complexType name="DocumentAdjustment1">
1631+ <xs:sequence>
1632+ <xs:element name="Amt" type="ActiveOrHistoricCurrencyAndAmount"/>
1633+ <xs:element maxOccurs="1" minOccurs="0" name="CdtDbtInd" type="CreditDebitCode"/>
1634+ <xs:element maxOccurs="1" minOccurs="0" name="Rsn" type="Max4Text"/>
1635+ <xs:element maxOccurs="1" minOccurs="0" name="AddtlInf" type="Max140Text"/>
1636+ </xs:sequence>
1637+ </xs:complexType>
1638+ <xs:simpleType name="DocumentType3Code">
1639+ <xs:restriction base="xs:string">
1640+ <xs:enumeration value="RADM"/>
1641+ <xs:enumeration value="RPIN"/>
1642+ <xs:enumeration value="FXDR"/>
1643+ <xs:enumeration value="DISP"/>
1644+ <xs:enumeration value="PUOR"/>
1645+ <xs:enumeration value="SCOR"/>
1646+ </xs:restriction>
1647+ </xs:simpleType>
1648+ <xs:simpleType name="DocumentType5Code">
1649+ <xs:restriction base="xs:string">
1650+ <xs:enumeration value="MSIN"/>
1651+ <xs:enumeration value="CNFA"/>
1652+ <xs:enumeration value="DNFA"/>
1653+ <xs:enumeration value="CINV"/>
1654+ <xs:enumeration value="CREN"/>
1655+ <xs:enumeration value="DEBN"/>
1656+ <xs:enumeration value="HIRI"/>
1657+ <xs:enumeration value="SBIN"/>
1658+ <xs:enumeration value="CMCN"/>
1659+ <xs:enumeration value="SOAC"/>
1660+ <xs:enumeration value="DISP"/>
1661+ <xs:enumeration value="BOLD"/>
1662+ <xs:enumeration value="VCHR"/>
1663+ <xs:enumeration value="AROI"/>
1664+ <xs:enumeration value="TSUT"/>
1665+ </xs:restriction>
1666+ </xs:simpleType>
1667+ <xs:complexType name="EquivalentAmount2">
1668+ <xs:sequence>
1669+ <xs:element name="Amt" type="ActiveOrHistoricCurrencyAndAmount"/>
1670+ <xs:element name="CcyOfTrf" type="ActiveOrHistoricCurrencyCode"/>
1671+ </xs:sequence>
1672+ </xs:complexType>
1673+ <xs:complexType name="ExchangeRateInformation1">
1674+ <xs:sequence>
1675+ <xs:element maxOccurs="1" minOccurs="0" name="XchgRate" type="BaseOneRate"/>
1676+ <xs:element maxOccurs="1" minOccurs="0" name="RateTp" type="ExchangeRateType1Code"/>
1677+ <xs:element maxOccurs="1" minOccurs="0" name="CtrctId" type="Max35Text"/>
1678+ </xs:sequence>
1679+ </xs:complexType>
1680+ <xs:simpleType name="ExchangeRateType1Code">
1681+ <xs:restriction base="xs:string">
1682+ <xs:enumeration value="SPOT"/>
1683+ <xs:enumeration value="SALE"/>
1684+ <xs:enumeration value="AGRD"/>
1685+ </xs:restriction>
1686+ </xs:simpleType>
1687+ <xs:simpleType name="ExternalAccountIdentification1Code">
1688+ <xs:restriction base="xs:string">
1689+ <xs:minLength value="1"/>
1690+ <xs:maxLength value="4"/>
1691+ </xs:restriction>
1692+ </xs:simpleType>
1693+ <xs:simpleType name="ExternalCategoryPurpose1Code">
1694+ <xs:restriction base="xs:string">
1695+ <xs:minLength value="1"/>
1696+ <xs:maxLength value="4"/>
1697+ </xs:restriction>
1698+ </xs:simpleType>
1699+ <xs:simpleType name="ExternalClearingSystemIdentification1Code">
1700+ <xs:restriction base="xs:string">
1701+ <xs:minLength value="1"/>
1702+ <xs:maxLength value="5"/>
1703+ </xs:restriction>
1704+ </xs:simpleType>
1705+ <xs:simpleType name="ExternalFinancialInstitutionIdentification1Code">
1706+ <xs:restriction base="xs:string">
1707+ <xs:minLength value="1"/>
1708+ <xs:maxLength value="4"/>
1709+ </xs:restriction>
1710+ </xs:simpleType>
1711+ <xs:simpleType name="ExternalLocalInstrument1Code">
1712+ <xs:restriction base="xs:string">
1713+ <xs:minLength value="1"/>
1714+ <xs:maxLength value="35"/>
1715+ </xs:restriction>
1716+ </xs:simpleType>
1717+ <xs:simpleType name="ExternalOrganisationIdentification1Code">
1718+ <xs:restriction base="xs:string">
1719+ <xs:minLength value="1"/>
1720+ <xs:maxLength value="4"/>
1721+ </xs:restriction>
1722+ </xs:simpleType>
1723+ <xs:simpleType name="ExternalPersonIdentification1Code">
1724+ <xs:restriction base="xs:string">
1725+ <xs:minLength value="1"/>
1726+ <xs:maxLength value="4"/>
1727+ </xs:restriction>
1728+ </xs:simpleType>
1729+ <xs:simpleType name="ExternalPurpose1Code">
1730+ <xs:restriction base="xs:string">
1731+ <xs:minLength value="1"/>
1732+ <xs:maxLength value="4"/>
1733+ </xs:restriction>
1734+ </xs:simpleType>
1735+ <xs:simpleType name="ExternalServiceLevel1Code">
1736+ <xs:restriction base="xs:string">
1737+ <xs:minLength value="1"/>
1738+ <xs:maxLength value="4"/>
1739+ </xs:restriction>
1740+ </xs:simpleType>
1741+ <xs:complexType name="FinancialIdentificationSchemeName1Choice">
1742+ <xs:sequence>
1743+ <xs:choice>
1744+ <xs:element name="Cd" type="ExternalFinancialInstitutionIdentification1Code"/>
1745+ <xs:element name="Prtry" type="Max35Text"/>
1746+ </xs:choice>
1747+ </xs:sequence>
1748+ </xs:complexType>
1749+ <xs:complexType name="FinancialInstitutionIdentification7">
1750+ <xs:sequence>
1751+ <xs:element maxOccurs="1" minOccurs="0" name="BIC" type="BICIdentifier"/>
1752+ <xs:element maxOccurs="1" minOccurs="0" name="ClrSysMmbId" type="ClearingSystemMemberIdentification2"/>
1753+ <xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
1754+ <xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
1755+ <xs:element maxOccurs="1" minOccurs="0" name="Othr" type="GenericFinancialIdentification1"/>
1756+ </xs:sequence>
1757+ </xs:complexType>
1758+ <xs:complexType name="GenericAccountIdentification1">
1759+ <xs:sequence>
1760+ <xs:element name="Id" type="Max34Text"/>
1761+ <xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="AccountSchemeName1Choice"/>
1762+ <xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
1763+ </xs:sequence>
1764+ </xs:complexType>
1765+ <xs:complexType name="GenericFinancialIdentification1">
1766+ <xs:sequence>
1767+ <xs:element name="Id" type="Max35Text"/>
1768+ <xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="FinancialIdentificationSchemeName1Choice"/>
1769+ <xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
1770+ </xs:sequence>
1771+ </xs:complexType>
1772+ <xs:complexType name="GenericOrganisationIdentification1">
1773+ <xs:sequence>
1774+ <xs:element name="Id" type="Max35Text"/>
1775+ <xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="OrganisationIdentificationSchemeName1Choice"/>
1776+ <xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
1777+ </xs:sequence>
1778+ </xs:complexType>
1779+ <xs:complexType name="GenericPersonIdentification1">
1780+ <xs:sequence>
1781+ <xs:element name="Id" type="Max35Text"/>
1782+ <xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="PersonIdentificationSchemeName1Choice"/>
1783+ <xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
1784+ </xs:sequence>
1785+ </xs:complexType>
1786+ <xs:complexType name="GroupHeader32">
1787+ <xs:sequence>
1788+ <xs:element name="MsgId" type="Max35Text"/>
1789+ <xs:element name="CreDtTm" type="ISODateTime"/>
1790+ <xs:element maxOccurs="2" minOccurs="0" name="Authstn" type="Authorisation1Choice"/>
1791+ <xs:element name="NbOfTxs" type="Max15NumericText"/>
1792+ <xs:element maxOccurs="1" minOccurs="0" name="CtrlSum" type="DecimalNumber"/>
1793+ <xs:element name="InitgPty" type="PartyIdentification32"/>
1794+ <xs:element maxOccurs="1" minOccurs="0" name="FwdgAgt" type="BranchAndFinancialInstitutionIdentification4"/>
1795+ </xs:sequence>
1796+ </xs:complexType>
1797+ <xs:simpleType name="IBAN2007Identifier">
1798+ <xs:restriction base="xs:string">
1799+ <xs:pattern value="[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}"/>
1800+ </xs:restriction>
1801+ </xs:simpleType>
1802+ <xs:simpleType name="ISODate">
1803+ <xs:restriction base="xs:date"/>
1804+ </xs:simpleType>
1805+ <xs:simpleType name="ISODateTime">
1806+ <xs:restriction base="xs:dateTime"/>
1807+ </xs:simpleType>
1808+ <xs:simpleType name="Instruction3Code">
1809+ <xs:restriction base="xs:string">
1810+ <xs:enumeration value="CHQB"/>
1811+ <xs:enumeration value="HOLD"/>
1812+ <xs:enumeration value="PHOB"/>
1813+ <xs:enumeration value="TELB"/>
1814+ </xs:restriction>
1815+ </xs:simpleType>
1816+ <xs:complexType name="InstructionForCreditorAgent1">
1817+ <xs:sequence>
1818+ <xs:element maxOccurs="1" minOccurs="0" name="Cd" type="Instruction3Code"/>
1819+ <xs:element maxOccurs="1" minOccurs="0" name="InstrInf" type="Max140Text"/>
1820+ </xs:sequence>
1821+ </xs:complexType>
1822+ <xs:complexType name="LocalInstrument2Choice">
1823+ <xs:sequence>
1824+ <xs:choice>
1825+ <xs:element name="Cd" type="ExternalLocalInstrument1Code"/>
1826+ <xs:element name="Prtry" type="Max35Text"/>
1827+ </xs:choice>
1828+ </xs:sequence>
1829+ </xs:complexType>
1830+ <xs:simpleType name="Max10Text">
1831+ <xs:restriction base="xs:string">
1832+ <xs:minLength value="1"/>
1833+ <xs:maxLength value="10"/>
1834+ </xs:restriction>
1835+ </xs:simpleType>
1836+ <xs:simpleType name="Max128Text">
1837+ <xs:restriction base="xs:string">
1838+ <xs:minLength value="1"/>
1839+ <xs:maxLength value="128"/>
1840+ </xs:restriction>
1841+ </xs:simpleType>
1842+ <xs:simpleType name="Max140Text">
1843+ <xs:restriction base="xs:string">
1844+ <xs:minLength value="1"/>
1845+ <xs:maxLength value="140"/>
1846+ </xs:restriction>
1847+ </xs:simpleType>
1848+ <xs:simpleType name="Max15NumericText">
1849+ <xs:restriction base="xs:string">
1850+ <xs:pattern value="[0-9]{1,15}"/>
1851+ </xs:restriction>
1852+ </xs:simpleType>
1853+ <xs:simpleType name="Max16Text">
1854+ <xs:restriction base="xs:string">
1855+ <xs:minLength value="1"/>
1856+ <xs:maxLength value="16"/>
1857+ </xs:restriction>
1858+ </xs:simpleType>
1859+ <xs:simpleType name="Max2048Text">
1860+ <xs:restriction base="xs:string">
1861+ <xs:minLength value="1"/>
1862+ <xs:maxLength value="2048"/>
1863+ </xs:restriction>
1864+ </xs:simpleType>
1865+ <xs:simpleType name="Max34Text">
1866+ <xs:restriction base="xs:string">
1867+ <xs:minLength value="1"/>
1868+ <xs:maxLength value="34"/>
1869+ </xs:restriction>
1870+ </xs:simpleType>
1871+ <xs:simpleType name="Max35Text">
1872+ <xs:restriction base="xs:string">
1873+ <xs:minLength value="1"/>
1874+ <xs:maxLength value="35"/>
1875+ </xs:restriction>
1876+ </xs:simpleType>
1877+ <xs:simpleType name="Max4Text">
1878+ <xs:restriction base="xs:string">
1879+ <xs:minLength value="1"/>
1880+ <xs:maxLength value="4"/>
1881+ </xs:restriction>
1882+ </xs:simpleType>
1883+ <xs:simpleType name="Max70Text">
1884+ <xs:restriction base="xs:string">
1885+ <xs:minLength value="1"/>
1886+ <xs:maxLength value="70"/>
1887+ </xs:restriction>
1888+ </xs:simpleType>
1889+ <xs:complexType name="NameAndAddress10">
1890+ <xs:sequence>
1891+ <xs:element name="Nm" type="Max140Text"/>
1892+ <xs:element name="Adr" type="PostalAddress6"/>
1893+ </xs:sequence>
1894+ </xs:complexType>
1895+ <xs:simpleType name="NamePrefix1Code">
1896+ <xs:restriction base="xs:string">
1897+ <xs:enumeration value="DOCT"/>
1898+ <xs:enumeration value="MIST"/>
1899+ <xs:enumeration value="MISS"/>
1900+ <xs:enumeration value="MADM"/>
1901+ </xs:restriction>
1902+ </xs:simpleType>
1903+ <xs:simpleType name="Number">
1904+ <xs:restriction base="xs:decimal">
1905+ <xs:fractionDigits value="0"/>
1906+ <xs:totalDigits value="18"/>
1907+ </xs:restriction>
1908+ </xs:simpleType>
1909+ <xs:complexType name="OrganisationIdentification4">
1910+ <xs:sequence>
1911+ <xs:element maxOccurs="1" minOccurs="0" name="BICOrBEI" type="AnyBICIdentifier"/>
1912+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericOrganisationIdentification1"/>
1913+ </xs:sequence>
1914+ </xs:complexType>
1915+ <xs:complexType name="OrganisationIdentificationSchemeName1Choice">
1916+ <xs:sequence>
1917+ <xs:choice>
1918+ <xs:element name="Cd" type="ExternalOrganisationIdentification1Code"/>
1919+ <xs:element name="Prtry" type="Max35Text"/>
1920+ </xs:choice>
1921+ </xs:sequence>
1922+ </xs:complexType>
1923+ <xs:complexType name="Party6Choice">
1924+ <xs:sequence>
1925+ <xs:choice>
1926+ <xs:element name="OrgId" type="OrganisationIdentification4"/>
1927+ <xs:element name="PrvtId" type="PersonIdentification5"/>
1928+ </xs:choice>
1929+ </xs:sequence>
1930+ </xs:complexType>
1931+ <xs:complexType name="PartyIdentification32">
1932+ <xs:sequence>
1933+ <xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
1934+ <xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
1935+ <xs:element maxOccurs="1" minOccurs="0" name="Id" type="Party6Choice"/>
1936+ <xs:element maxOccurs="1" minOccurs="0" name="CtryOfRes" type="CountryCode"/>
1937+ <xs:element maxOccurs="1" minOccurs="0" name="CtctDtls" type="ContactDetails2"/>
1938+ </xs:sequence>
1939+ </xs:complexType>
1940+ <xs:complexType name="PaymentIdentification1">
1941+ <xs:sequence>
1942+ <xs:element maxOccurs="1" minOccurs="0" name="InstrId" type="Max35Text"/>
1943+ <xs:element name="EndToEndId" type="Max35Text"/>
1944+ </xs:sequence>
1945+ </xs:complexType>
1946+ <xs:complexType name="PaymentInstructionInformation3">
1947+ <xs:sequence>
1948+ <xs:element name="PmtInfId" type="Max35Text"/>
1949+ <xs:element name="PmtMtd" type="PaymentMethod3Code"/>
1950+ <xs:element maxOccurs="1" minOccurs="0" name="BtchBookg" type="BatchBookingIndicator"/>
1951+ <xs:element maxOccurs="1" minOccurs="0" name="NbOfTxs" type="Max15NumericText"/>
1952+ <xs:element maxOccurs="1" minOccurs="0" name="CtrlSum" type="DecimalNumber"/>
1953+ <xs:element maxOccurs="1" minOccurs="0" name="PmtTpInf" type="PaymentTypeInformation19"/>
1954+ <xs:element name="ReqdExctnDt" type="ISODate"/>
1955+ <xs:element maxOccurs="1" minOccurs="0" name="PoolgAdjstmntDt" type="ISODate"/>
1956+ <xs:element name="Dbtr" type="PartyIdentification32"/>
1957+ <xs:element name="DbtrAcct" type="CashAccount16"/>
1958+ <xs:element name="DbtrAgt" type="BranchAndFinancialInstitutionIdentification4"/>
1959+ <xs:element maxOccurs="1" minOccurs="0" name="DbtrAgtAcct" type="CashAccount16"/>
1960+ <xs:element maxOccurs="1" minOccurs="0" name="UltmtDbtr" type="PartyIdentification32"/>
1961+ <xs:element maxOccurs="1" minOccurs="0" name="ChrgBr" type="ChargeBearerType1Code"/>
1962+ <xs:element maxOccurs="1" minOccurs="0" name="ChrgsAcct" type="CashAccount16"/>
1963+ <xs:element maxOccurs="1" minOccurs="0" name="ChrgsAcctAgt" type="BranchAndFinancialInstitutionIdentification4"/>
1964+ <xs:element maxOccurs="unbounded" minOccurs="1" name="CdtTrfTxInf" type="CreditTransferTransactionInformation10"/>
1965+ </xs:sequence>
1966+ </xs:complexType>
1967+ <xs:simpleType name="PaymentMethod3Code">
1968+ <xs:restriction base="xs:string">
1969+ <xs:enumeration value="CHK"/>
1970+ <xs:enumeration value="TRF"/>
1971+ <xs:enumeration value="TRA"/>
1972+ </xs:restriction>
1973+ </xs:simpleType>
1974+ <xs:complexType name="PaymentTypeInformation19">
1975+ <xs:sequence>
1976+ <xs:element maxOccurs="1" minOccurs="0" name="InstrPrty" type="Priority2Code"/>
1977+ <xs:element maxOccurs="1" minOccurs="0" name="SvcLvl" type="ServiceLevel8Choice"/>
1978+ <xs:element maxOccurs="1" minOccurs="0" name="LclInstrm" type="LocalInstrument2Choice"/>
1979+ <xs:element maxOccurs="1" minOccurs="0" name="CtgyPurp" type="CategoryPurpose1Choice"/>
1980+ </xs:sequence>
1981+ </xs:complexType>
1982+ <xs:simpleType name="PercentageRate">
1983+ <xs:restriction base="xs:decimal">
1984+ <xs:fractionDigits value="10"/>
1985+ <xs:totalDigits value="11"/>
1986+ </xs:restriction>
1987+ </xs:simpleType>
1988+ <xs:complexType name="PersonIdentification5">
1989+ <xs:sequence>
1990+ <xs:element maxOccurs="1" minOccurs="0" name="DtAndPlcOfBirth" type="DateAndPlaceOfBirth"/>
1991+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericPersonIdentification1"/>
1992+ </xs:sequence>
1993+ </xs:complexType>
1994+ <xs:complexType name="PersonIdentificationSchemeName1Choice">
1995+ <xs:sequence>
1996+ <xs:choice>
1997+ <xs:element name="Cd" type="ExternalPersonIdentification1Code"/>
1998+ <xs:element name="Prtry" type="Max35Text"/>
1999+ </xs:choice>
2000+ </xs:sequence>
2001+ </xs:complexType>
2002+ <xs:simpleType name="PhoneNumber">
2003+ <xs:restriction base="xs:string">
2004+ <xs:pattern value="\+[0-9]{1,3}-[0-9()+\-]{1,30}"/>
2005+ </xs:restriction>
2006+ </xs:simpleType>
2007+ <xs:complexType name="PostalAddress6">
2008+ <xs:sequence>
2009+ <xs:element maxOccurs="1" minOccurs="0" name="AdrTp" type="AddressType2Code"/>
2010+ <xs:element maxOccurs="1" minOccurs="0" name="Dept" type="Max70Text"/>
2011+ <xs:element maxOccurs="1" minOccurs="0" name="SubDept" type="Max70Text"/>
2012+ <xs:element maxOccurs="1" minOccurs="0" name="StrtNm" type="Max70Text"/>
2013+ <xs:element maxOccurs="1" minOccurs="0" name="BldgNb" type="Max16Text"/>
2014+ <xs:element maxOccurs="1" minOccurs="0" name="PstCd" type="Max16Text"/>
2015+ <xs:element maxOccurs="1" minOccurs="0" name="TwnNm" type="Max35Text"/>
2016+ <xs:element maxOccurs="1" minOccurs="0" name="CtrySubDvsn" type="Max35Text"/>
2017+ <xs:element maxOccurs="1" minOccurs="0" name="Ctry" type="CountryCode"/>
2018+ <xs:element maxOccurs="7" minOccurs="0" name="AdrLine" type="Max70Text"/>
2019+ </xs:sequence>
2020+ </xs:complexType>
2021+ <xs:simpleType name="Priority2Code">
2022+ <xs:restriction base="xs:string">
2023+ <xs:enumeration value="HIGH"/>
2024+ <xs:enumeration value="NORM"/>
2025+ </xs:restriction>
2026+ </xs:simpleType>
2027+ <xs:complexType name="Purpose2Choice">
2028+ <xs:sequence>
2029+ <xs:choice>
2030+ <xs:element name="Cd" type="ExternalPurpose1Code"/>
2031+ <xs:element name="Prtry" type="Max35Text"/>
2032+ </xs:choice>
2033+ </xs:sequence>
2034+ </xs:complexType>
2035+ <xs:complexType name="ReferredDocumentInformation3">
2036+ <xs:sequence>
2037+ <xs:element maxOccurs="1" minOccurs="0" name="Tp" type="ReferredDocumentType2"/>
2038+ <xs:element maxOccurs="1" minOccurs="0" name="Nb" type="Max35Text"/>
2039+ <xs:element maxOccurs="1" minOccurs="0" name="RltdDt" type="ISODate"/>
2040+ </xs:sequence>
2041+ </xs:complexType>
2042+ <xs:complexType name="ReferredDocumentType1Choice">
2043+ <xs:sequence>
2044+ <xs:choice>
2045+ <xs:element name="Cd" type="DocumentType5Code"/>
2046+ <xs:element name="Prtry" type="Max35Text"/>
2047+ </xs:choice>
2048+ </xs:sequence>
2049+ </xs:complexType>
2050+ <xs:complexType name="ReferredDocumentType2">
2051+ <xs:sequence>
2052+ <xs:element name="CdOrPrtry" type="ReferredDocumentType1Choice"/>
2053+ <xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
2054+ </xs:sequence>
2055+ </xs:complexType>
2056+ <xs:complexType name="RegulatoryAuthority2">
2057+ <xs:sequence>
2058+ <xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
2059+ <xs:element maxOccurs="1" minOccurs="0" name="Ctry" type="CountryCode"/>
2060+ </xs:sequence>
2061+ </xs:complexType>
2062+ <xs:complexType name="RegulatoryReporting3">
2063+ <xs:sequence>
2064+ <xs:element maxOccurs="1" minOccurs="0" name="DbtCdtRptgInd" type="RegulatoryReportingType1Code"/>
2065+ <xs:element maxOccurs="1" minOccurs="0" name="Authrty" type="RegulatoryAuthority2"/>
2066+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Dtls" type="StructuredRegulatoryReporting3"/>
2067+ </xs:sequence>
2068+ </xs:complexType>
2069+ <xs:simpleType name="RegulatoryReportingType1Code">
2070+ <xs:restriction base="xs:string">
2071+ <xs:enumeration value="CRED"/>
2072+ <xs:enumeration value="DEBT"/>
2073+ <xs:enumeration value="BOTH"/>
2074+ </xs:restriction>
2075+ </xs:simpleType>
2076+ <xs:complexType name="RemittanceAmount1">
2077+ <xs:sequence>
2078+ <xs:element maxOccurs="1" minOccurs="0" name="DuePyblAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
2079+ <xs:element maxOccurs="1" minOccurs="0" name="DscntApldAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
2080+ <xs:element maxOccurs="1" minOccurs="0" name="CdtNoteAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
2081+ <xs:element maxOccurs="1" minOccurs="0" name="TaxAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
2082+ <xs:element maxOccurs="unbounded" minOccurs="0" name="AdjstmntAmtAndRsn" type="DocumentAdjustment1"/>
2083+ <xs:element maxOccurs="1" minOccurs="0" name="RmtdAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
2084+ </xs:sequence>
2085+ </xs:complexType>
2086+ <xs:complexType name="RemittanceInformation5">
2087+ <xs:sequence>
2088+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Ustrd" type="Max140Text"/>
2089+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Strd" type="StructuredRemittanceInformation7"/>
2090+ </xs:sequence>
2091+ </xs:complexType>
2092+ <xs:complexType name="RemittanceLocation2">
2093+ <xs:sequence>
2094+ <xs:element maxOccurs="1" minOccurs="0" name="RmtId" type="Max35Text"/>
2095+ <xs:element maxOccurs="1" minOccurs="0" name="RmtLctnMtd" type="RemittanceLocationMethod2Code"/>
2096+ <xs:element maxOccurs="1" minOccurs="0" name="RmtLctnElctrncAdr" type="Max2048Text"/>
2097+ <xs:element maxOccurs="1" minOccurs="0" name="RmtLctnPstlAdr" type="NameAndAddress10"/>
2098+ </xs:sequence>
2099+ </xs:complexType>
2100+ <xs:simpleType name="RemittanceLocationMethod2Code">
2101+ <xs:restriction base="xs:string">
2102+ <xs:enumeration value="FAXI"/>
2103+ <xs:enumeration value="EDIC"/>
2104+ <xs:enumeration value="URID"/>
2105+ <xs:enumeration value="EMAL"/>
2106+ <xs:enumeration value="POST"/>
2107+ <xs:enumeration value="SMSM"/>
2108+ </xs:restriction>
2109+ </xs:simpleType>
2110+ <xs:complexType name="ServiceLevel8Choice">
2111+ <xs:sequence>
2112+ <xs:choice>
2113+ <xs:element name="Cd" type="ExternalServiceLevel1Code"/>
2114+ <xs:element name="Prtry" type="Max35Text"/>
2115+ </xs:choice>
2116+ </xs:sequence>
2117+ </xs:complexType>
2118+ <xs:complexType name="StructuredRegulatoryReporting3">
2119+ <xs:sequence>
2120+ <xs:element maxOccurs="1" minOccurs="0" name="Tp" type="Max35Text"/>
2121+ <xs:element maxOccurs="1" minOccurs="0" name="Dt" type="ISODate"/>
2122+ <xs:element maxOccurs="1" minOccurs="0" name="Ctry" type="CountryCode"/>
2123+ <xs:element maxOccurs="1" minOccurs="0" name="Cd" type="Max10Text"/>
2124+ <xs:element maxOccurs="1" minOccurs="0" name="Amt" type="ActiveOrHistoricCurrencyAndAmount"/>
2125+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Inf" type="Max35Text"/>
2126+ </xs:sequence>
2127+ </xs:complexType>
2128+ <xs:complexType name="StructuredRemittanceInformation7">
2129+ <xs:sequence>
2130+ <xs:element maxOccurs="unbounded" minOccurs="0" name="RfrdDocInf" type="ReferredDocumentInformation3"/>
2131+ <xs:element maxOccurs="1" minOccurs="0" name="RfrdDocAmt" type="RemittanceAmount1"/>
2132+ <xs:element maxOccurs="1" minOccurs="0" name="CdtrRefInf" type="CreditorReferenceInformation2"/>
2133+ <xs:element maxOccurs="1" minOccurs="0" name="Invcr" type="PartyIdentification32"/>
2134+ <xs:element maxOccurs="1" minOccurs="0" name="Invcee" type="PartyIdentification32"/>
2135+ <xs:element maxOccurs="3" minOccurs="0" name="AddtlRmtInf" type="Max140Text"/>
2136+ </xs:sequence>
2137+ </xs:complexType>
2138+ <xs:complexType name="TaxAmount1">
2139+ <xs:sequence>
2140+ <xs:element maxOccurs="1" minOccurs="0" name="Rate" type="PercentageRate"/>
2141+ <xs:element maxOccurs="1" minOccurs="0" name="TaxblBaseAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
2142+ <xs:element maxOccurs="1" minOccurs="0" name="TtlAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
2143+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Dtls" type="TaxRecordDetails1"/>
2144+ </xs:sequence>
2145+ </xs:complexType>
2146+ <xs:complexType name="TaxAuthorisation1">
2147+ <xs:sequence>
2148+ <xs:element maxOccurs="1" minOccurs="0" name="Titl" type="Max35Text"/>
2149+ <xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
2150+ </xs:sequence>
2151+ </xs:complexType>
2152+ <xs:complexType name="TaxInformation3">
2153+ <xs:sequence>
2154+ <xs:element maxOccurs="1" minOccurs="0" name="Cdtr" type="TaxParty1"/>
2155+ <xs:element maxOccurs="1" minOccurs="0" name="Dbtr" type="TaxParty2"/>
2156+ <xs:element maxOccurs="1" minOccurs="0" name="AdmstnZn" type="Max35Text"/>
2157+ <xs:element maxOccurs="1" minOccurs="0" name="RefNb" type="Max140Text"/>
2158+ <xs:element maxOccurs="1" minOccurs="0" name="Mtd" type="Max35Text"/>
2159+ <xs:element maxOccurs="1" minOccurs="0" name="TtlTaxblBaseAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
2160+ <xs:element maxOccurs="1" minOccurs="0" name="TtlTaxAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
2161+ <xs:element maxOccurs="1" minOccurs="0" name="Dt" type="ISODate"/>
2162+ <xs:element maxOccurs="1" minOccurs="0" name="SeqNb" type="Number"/>
2163+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Rcrd" type="TaxRecord1"/>
2164+ </xs:sequence>
2165+ </xs:complexType>
2166+ <xs:complexType name="TaxParty1">
2167+ <xs:sequence>
2168+ <xs:element maxOccurs="1" minOccurs="0" name="TaxId" type="Max35Text"/>
2169+ <xs:element maxOccurs="1" minOccurs="0" name="RegnId" type="Max35Text"/>
2170+ <xs:element maxOccurs="1" minOccurs="0" name="TaxTp" type="Max35Text"/>
2171+ </xs:sequence>
2172+ </xs:complexType>
2173+ <xs:complexType name="TaxParty2">
2174+ <xs:sequence>
2175+ <xs:element maxOccurs="1" minOccurs="0" name="TaxId" type="Max35Text"/>
2176+ <xs:element maxOccurs="1" minOccurs="0" name="RegnId" type="Max35Text"/>
2177+ <xs:element maxOccurs="1" minOccurs="0" name="TaxTp" type="Max35Text"/>
2178+ <xs:element maxOccurs="1" minOccurs="0" name="Authstn" type="TaxAuthorisation1"/>
2179+ </xs:sequence>
2180+ </xs:complexType>
2181+ <xs:complexType name="TaxPeriod1">
2182+ <xs:sequence>
2183+ <xs:element maxOccurs="1" minOccurs="0" name="Yr" type="ISODate"/>
2184+ <xs:element maxOccurs="1" minOccurs="0" name="Tp" type="TaxRecordPeriod1Code"/>
2185+ <xs:element maxOccurs="1" minOccurs="0" name="FrToDt" type="DatePeriodDetails"/>
2186+ </xs:sequence>
2187+ </xs:complexType>
2188+ <xs:complexType name="TaxRecord1">
2189+ <xs:sequence>
2190+ <xs:element maxOccurs="1" minOccurs="0" name="Tp" type="Max35Text"/>
2191+ <xs:element maxOccurs="1" minOccurs="0" name="Ctgy" type="Max35Text"/>
2192+ <xs:element maxOccurs="1" minOccurs="0" name="CtgyDtls" type="Max35Text"/>
2193+ <xs:element maxOccurs="1" minOccurs="0" name="DbtrSts" type="Max35Text"/>
2194+ <xs:element maxOccurs="1" minOccurs="0" name="CertId" type="Max35Text"/>
2195+ <xs:element maxOccurs="1" minOccurs="0" name="FrmsCd" type="Max35Text"/>
2196+ <xs:element maxOccurs="1" minOccurs="0" name="Prd" type="TaxPeriod1"/>
2197+ <xs:element maxOccurs="1" minOccurs="0" name="TaxAmt" type="TaxAmount1"/>
2198+ <xs:element maxOccurs="1" minOccurs="0" name="AddtlInf" type="Max140Text"/>
2199+ </xs:sequence>
2200+ </xs:complexType>
2201+ <xs:complexType name="TaxRecordDetails1">
2202+ <xs:sequence>
2203+ <xs:element maxOccurs="1" minOccurs="0" name="Prd" type="TaxPeriod1"/>
2204+ <xs:element name="Amt" type="ActiveOrHistoricCurrencyAndAmount"/>
2205+ </xs:sequence>
2206+ </xs:complexType>
2207+ <xs:simpleType name="TaxRecordPeriod1Code">
2208+ <xs:restriction base="xs:string">
2209+ <xs:enumeration value="MM01"/>
2210+ <xs:enumeration value="MM02"/>
2211+ <xs:enumeration value="MM03"/>
2212+ <xs:enumeration value="MM04"/>
2213+ <xs:enumeration value="MM05"/>
2214+ <xs:enumeration value="MM06"/>
2215+ <xs:enumeration value="MM07"/>
2216+ <xs:enumeration value="MM08"/>
2217+ <xs:enumeration value="MM09"/>
2218+ <xs:enumeration value="MM10"/>
2219+ <xs:enumeration value="MM11"/>
2220+ <xs:enumeration value="MM12"/>
2221+ <xs:enumeration value="QTR1"/>
2222+ <xs:enumeration value="QTR2"/>
2223+ <xs:enumeration value="QTR3"/>
2224+ <xs:enumeration value="QTR4"/>
2225+ <xs:enumeration value="HLF1"/>
2226+ <xs:enumeration value="HLF2"/>
2227+ </xs:restriction>
2228+ </xs:simpleType>
2229+</xs:schema>

Subscribers

People subscribed via source and target branches