Merge lp:~therp-nl/account-banking/upgrade-6.0 into lp:account-banking

Proposed by Stefan Rijnhart (Opener)
Status: Needs review
Proposed branch: lp:~therp-nl/account-banking/upgrade-6.0
Merge into: lp:account-banking
Diff against target: 3078 lines (+1102/-1099) (has conflicts)
32 files modified
THIS_BRANCH_IS_DEPRECATED.txt (+3/-0)
account_banking/__terp__.py (+3/-55)
account_banking/account_banking.py (+260/-269)
account_banking/account_banking_import_wizard.xml (+0/-15)
account_banking/account_banking_payment_wizard.xml (+0/-22)
account_banking/account_banking_view.xml (+106/-18)
account_banking/data/account_banking_data.xml (+2/-2)
account_banking/security/ir.model.access.csv (+2/-0)
account_banking/wizard/__init__.py (+1/-1)
account_banking/wizard/account_payment_order.py (+113/-0)
account_banking/wizard/bank_import.py (+149/-137)
account_banking/wizard/bank_import_view.xml (+52/-0)
account_banking/wizard/banktools.py (+24/-16)
account_banking/wizard/wizard_payment_order.py (+0/-212)
account_banking_fi_patu/__terp__.py (+2/-3)
account_banking_nl_abnamro/__openerp__.py (+2/-8)
account_banking_nl_abnamro/__terp__.py (+2/-8)
account_banking_nl_clieop/__terp__.py (+8/-6)
account_banking_nl_clieop/account_banking_export_wizard.xml (+0/-15)
account_banking_nl_clieop/account_banking_nl_clieop.py (+7/-13)
account_banking_nl_clieop/account_banking_nl_clieop.xml (+36/-13)
account_banking_nl_clieop/data/banking_export_clieop.xml (+9/-3)
account_banking_nl_clieop/migrations/0.63/post-fill-ir_model_id.py (+44/-0)
account_banking_nl_clieop/security/ir.model.access.csv (+2/-0)
account_banking_nl_clieop/wizard/clieop.py (+2/-2)
account_banking_nl_clieop/wizard/export_clieop.py (+204/-249)
account_banking_nl_clieop/wizard/export_clieop_view.xml (+58/-0)
account_banking_nl_girotel/__terp__.py (+2/-3)
account_banking_nl_multibank/__terp__.py (+2/-3)
account_banking_nl_triodos/__openerp__.py (+2/-13)
account_banking_nl_triodos/__terp__.py (+2/-13)
account_banking_nl_triodos/triodos.py (+3/-0)
Text conflict in account_banking/account_banking.py
Text conflict in account_banking/account_banking_view.xml
Text conflict in account_banking/wizard/bank_import.py
Text conflict in account_banking_nl_clieop/__terp__.py
To merge this branch: bzr merge lp:~therp-nl/account-banking/upgrade-6.0
Reviewer Review Type Date Requested Status
Stefan Rijnhart (Opener) (community) Needs Resubmitting
Pieter J. Kersten (EduSense BV) Needs Fixing
Review via email: mp+59146@code.launchpad.net

Description of the change

Hi Pieter,

this branch is a migration of account_banking to OpenERP 6.0. Below is a short description of the modifications. Given the size of the update, I suspect we will be in touch about this merge.

Regards,
Stefan.

* Account Banking

Migration to OpenERP 6.0
---
Adapt to changes in models of account and account_payment
Adapt to changes in xml view definitions
Restore payment.type functionality from version 5 as payment.mode.type
Restore launch_wizard functionality from version 5
Migrate changes from button_confirm() in v5 to create_move_from_st_line()
Store reference to reconciliation on transaction line
Make old style wizards work properly in GTK and web client
Change journal domains to type=bank

Additional changes:
- Fixes incomplete reconciliations being generated due to account.move.line "line_id" vs. "line_ids' confusion
- Fix bug where a matching invoice is "found" as many times as the number of addresses a partner has
- Fix error in German BBAN format (does not have a trailing check digit)

* Clieop module

Migration to OpenERP 6.0
---
Adapt payment.typea to payment.mode.type
Make old style wizards work properly in GTK and web client

Additional changes:
---
Payment order status now remains unchanged when a test clieop is generated
To avoid confusion between saving the clieop file and finishing the wizard,
the 'Save' button and label have been changed to 'OK/Finish'.

To post a comment you must log in.
Revision history for this message
Pieter J. Kersten (EduSense BV) (pieterj) wrote :
Download full text (3.1 KiB)

Generic:
    I can see a lot of technical improvements for v6. However, there were
    more changes than just the technical ones. For starters, v6 introduced
    the voucher layer between account and account_payment. I'm missing
    this in your proposal. Is this code used in production? If so,
    what are the experiences? How does it coexist/cooperate with the
    payment/voucher system?

    I can see you tried to stay as close to the v5 version as possible.
    However, I'm second guessing some of the changes for v5, due to the
    semantic changes in v6. One is the move of the period_id on
    account.bank.statement to account.bank.statement.line. Thanks to
    account_voucher, it creates more trouble than its worth it. I'm planning
    to change the statement generation code to fold around the current
    limitations of v6. This would simplify ABF's dependancies greatly.

Many changes seem to me not v6 specific. I will backport these to v5. See my
remarks below.

account_banking/account_banking.py: @-890,+878:
    I will backport this modified to v5. Testing on iterator capabilities is
    more extendable IMO than testing on simple types.

account_banking/account_banking.py: @-911,+901 -922,911:
    Oops, left some lingering code. Thanks for noting.
    Backporting to v5, excluding the style change.

account_banking/account_banking.py: @-1188,+1177:
    Ok, backporting to v5.

account_banking/account_banking.py: @-1197,+1186:
    You managed to come up with yet another source. Nice.
    I'll add it to v5.

account_banking/account_banking.py: @-1218,+1210 -1239,+1231:
    Not sure if this is an improvement. I'll leave it for now.
    Won't take the style change.

account_banking/sepa/iban.py:
    This change is not conform specs. Any sources I can check for this?
    Will leave it untill more info arrives.

account_banking/sepa/online.py/BBAN_is_IBAN:
    See your point. Using slightly improved version for v5.

account_banking/wizard/bank_import/@@ -544,+545:
    This is unneeded. You don't use it anywhere. Won't take it.

account_banking/wizard/bank_import/@@ -567,+568, -730,+730 and -743,+743:
    These are just style changes. Wont take these.

account_banking/wizard/bank_import/@@ -753,+753:
    See your point. Your solution is however not always correct.
    Backporting improved version to v5.

account_banking/wizard/bank_import/@@ -795,+798:
    Can't see any value in this change. Just make sure that
        isinstance(transaction.remote_account, (str, unicode)) is True
    which must be done in the import parsers.

account_banking/wizard/bank_import/@@ -922,+918:
    Ok, see your point. Backporting to v5

account_banking/wizard/banktools/get_or_create_partner:
    Ok, backporting the unique construct to v5.
    Having some difficulties with the defensive field resolving code.
    Is this really needed? Never faced any problems with it.

account_banking/wizard/banktools/create_bank_account:
    What is the purpose of these changes?
    I can't see a semantic value for a catch-all 'UNKNOWN' bank.
    Problem is, when the bank gets known, chances are it won't be
    the same as "the other" accounts with UNKNOWN tied to it.
   ...

Read more...

Revision history for this message
Pieter J. Kersten (EduSense BV) (pieterj) wrote :

BTW, if that wasn't obvious to you already, great job!

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :
Download full text (3.4 KiB)

Hi Pieter,

again, thank you for your fast and perceptive response! I agree with
most of your remarks. Please find some additional comments below.

On 27-04-11 12:30, Pieter J. Kersten (EduSense BV) wrote:
> Generic:
> I can see a lot of technical improvements for v6. However, there were
> more changes than just the technical ones. For starters, v6 introduced
> the voucher layer between account and account_payment. I'm missing
> this in your proposal. Is this code used in production? If so,
> what are the experiences? How does it coexist/cooperate with the
> payment/voucher system?

This code is used in a couple of small setups. We knowingly ignored
account_voucher for this version in order to simplify verification of
the operation of the migrated code. The process of payments (through
payment orders) and bank reconciliation works fine without it, but a
logical next step would be looking at integrating account_voucher.

> account_banking/account_banking.py: @-1218,+1210 -1239,+1231:
> Not sure if this is an improvement. I'll leave it for now.
>
We felt the error was a bit too harsh on the account number, given the
poor performance of the online iban service for Dutch bank accounts. It
is a matter of taste. We will be looking at integrating a paid service
for iban/bic lookups.

> account_banking/sepa/iban.py:
> This change is not conform specs. Any sources I can check for this?
> Will leave it untill more info arrives.

This change was triggered by a real transaction. We looked to Wikipedia
for confirmation
(http://en.wikipedia.org/wiki/International_Bank_Account_Number lists
German bbank as 18n, no check digit). Ecbs has the length listed as 18!n
as well (http://www.ecbs.org/iban/germany-bank-account-number.html)

> account_banking/wizard/bank_import/@@ -544,+545:
> This is unneeded. You don't use it anywhere. Won't take it.
>
No, it is used in line 931, although I did not introduce it.

> account_banking/wizard/bank_import/@@ -795,+798:
> Can't see any value in this change. Just make sure that
> isinstance(transaction.remote_account, (str, unicode)) is True
> which must be done in the import parsers.
In the ABNAmro filter the remote owner, but not the remote_account is
retrieved in case of a payment terminal transaction. I would rather
check here than having to initialize remote_account as an empty string.

> account_banking/wizard/banktools/get_or_create_partner:
> Ok, backporting the unique construct to v5.
> Having some difficulties with the defensive field resolving code.
> Is this really needed? Never faced any problems with it.

Yes, if we take requiredness into account, some checks are superfluous.
I would suggest to just keep

     user.company_id.partner_id.country and
user.company_id.partner_id.country.id or False

> account_banking/wizard/banktools/create_bank_account:
> What is the purpose of these changes?
> I can't see a semantic value for a catch-all 'UNKNOWN' bank.
> Problem is, when the bank gets known, chances are it won't be
> the same as "the other" accounts with UNKNOWN tied to it.
> Better leave ...

Read more...

Revision history for this message
Pieter J. Kersten (EduSense BV) (pieterj) wrote :
Download full text (4.5 KiB)

Hi Stefan,

Thanks for your answers. I've adapted some changes to ABF in order to
address some of your remarks.
Most notably:

1. Adapted German localized BBAN format
2. Changed model members to default to str (makes
isinstance(model.member, (str, unicode)) == True, even when untouched)
3. Reactivated apparently untested path in wizard.
4. Added more remarks to parser template regarding numbering issues
(prevent future discussions)

Can you please pull these, remove your visual/style changes and create a
new merge proposal?

One question remains: What is your definition of "poor performance"
regarding the online Dutch IBAN/BIC convertor?
BTW, I'm not sure if paying will enhance the data quality. Most paid
services simply calculate their responses.

With your new proposal, I will check ABF's cooperation with
vouchers/payments. I'm interested to see how it behaves.
I was already planning on updating ABF to face the new semantics. This
looks like a welcome jump start.
BTW, I'll start a new branch for this, in order to allow backports to v5.

TIA,
--
Pieter J. Kersten
*T:* +31 630 230208
*KvK:* 08178777
Logo EduSense B.V. <http://www.edusense.nl>

Op 28-04-11 08:55 schreef Stefan Rijnhart (Therp):
> Hi Pieter,
>
> again, thank you for your fast and perceptive response! I agree with
> most of your remarks. Please find some additional comments below.
>
>
> On 27-04-11 12:30, Pieter J. Kersten (EduSense BV) wrote:
>> Generic:
>> I can see a lot of technical improvements for v6. However, there were
>> more changes than just the technical ones. For starters, v6 introduced
>> the voucher layer between account and account_payment. I'm missing
>> this in your proposal. Is this code used in production? If so,
>> what are the experiences? How does it coexist/cooperate with the
>> payment/voucher system?
> This code is used in a couple of small setups. We knowingly ignored
> account_voucher for this version in order to simplify verification of
> the operation of the migrated code. The process of payments (through
> payment orders) and bank reconciliation works fine without it, but a
> logical next step would be looking at integrating account_voucher.
>
>> account_banking/account_banking.py: @-1218,+1210 -1239,+1231:
>> Not sure if this is an improvement. I'll leave it for now.
>>
> We felt the error was a bit too harsh on the account number, given the
> poor performance of the online iban service for Dutch bank accounts. It
> is a matter of taste. We will be looking at integrating a paid service
> for iban/bic lookups.
>
>> account_banking/sepa/iban.py:
>> This change is not conform specs. Any sources I can check for this?
>> Will leave it untill more info arrives.
> This change was triggered by a real transaction. We looked to Wikipedia
> for confirmation
> (http://en.wikipedia.org/wiki/International_Bank_Account_Number lists
> German bbank as 18n, no check digit). Ecbs has the length listed as 18!n
> as well (http://www.ecbs.org/iban/germany-bank-account-number.html)
>
>> account_banking/wizard/bank_import/@@ -544,+545:
>> This is unneeded. You don't use it anywhere. Won't take it.
>>
> N...

Read more...

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

On 28-04-11 10:13, Pieter J. Kersten (EduSense BV) wrote:
> One question remains: What is your definition of "poor performance"
> regarding the online Dutch IBAN/BIC convertor?
We encountered a number of unrecognized bank accounts, most notably the
bank account of the Chamber of Commerce in our region as well as some of
the customers' Triodos accounts. The prominence of these accounts
naturally influenced our appreciation of the online service's performance.

Regards,
Stefan.

--
Therp - Maatwerk in open ontwikkeling

Stefan Rijnhart - Ontwerp en implementatie

mail: <email address hidden>
tel: +31 (0) 614478606
web: http://therp.nl

Revision history for this message
Jan Verlaan (jan-verlaan) wrote :

Hope to see 2 versions in future, one for V5 and one for V6.
Merging only the upgrade to V6 would leave only a version for V6, while several users will stay on V5 for the next years.

Revision history for this message
Pieter J. Kersten (EduSense BV) (pieterj) wrote :

This will be the case.
--
Pieter J. Kersten

Op 29-04-11 15:38 schreef Jan Verlaan (Veritos):
> Hope to see 2 versions in future, one for V5 and one for V6.
> Merging only the upgrade to V6 would leave only a version for V6, while several users will stay on V5 for the next years.

60. By Stefan Rijnhart (Opener)

[MRG] backports from previous merge request

61. By Stefan Rijnhart (Opener)

Undo style changes and changes in error messages

62. By Stefan Rijnhart (Opener)

[FIX] Cannot use storage trigger on field 'id'

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi Pieter,

Your backports have been merged in this branch.

I have kept assigning code 'UNKNOW' to unknown banks. The reference to res_bank is required for res_partner_banks in 6.0. Without this modification a multitude of unknown banks can get accumulated.

You might still want to look at the following changes for backporting to v5:

account_banking/wizard/bank_import.py @@ -801,7 +802,7 @@
account_banking/sepa/online.py @@ -134,7 +134,7 @@

Regards,
Stefan.

review: Needs Resubmitting
Revision history for this message
Pieter J. Kersten (EduSense BV) (pieterj) wrote :

Hi Stefan,

Thanks for the two typos I left open during v5 backport.
I've reviewed the patch for v6. There are a few issues I can see for now.

1. The domains in the forms are too restrictive in its current form. The 'suitable_bank_types' method in account_payment can return more than just 'bank'. After installing base_iban, it can also return 'iban', which is a valid bank account type for ABF too. There can be more. So instead of using a hard coded domain, I suggest extending the form with suitable bank types (hidden? context?) and setting the domain to this list ('type','in',types_list)

2. I can see how changing state on payment orders during testing of ClieOp can mess things up, but not being able to save it at all is a bit too restrictive for me. Preventing switching states when saving test batches should do just fine.

3. Instead of using a catch all bank, I prefer to have an optional relationship between res_partner_bank and res_bank. This way you can relax requirements. The current layout of res_bank is too biased for Belgian and German usage anyway - a bank code is required, which is not even known in some countries, including the Netherlands. You could add a constraint to require a valid bank when code is filled in order to prevent regression for bankcode-users.

BTW, I've reserved trunk for v6.0 development from now on.

review: Needs Fixing
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :
Download full text (3.2 KiB)

Hi Pieter,

Thank you for your comments. I hope you will accept the clarifications
below.

On 05-05-11 17:11, Pieter J. Kersten (EduSense BV) wrote:
> 1. The domains in the forms are too restrictive in its current form. The 'suitable_bank_types' method in account_payment can return more than just 'bank'. After installing base_iban, it can also return 'iban', which is a valid bank account type for ABF too. There can be more. So instead of using a hard coded domain, I suggest extending the form with suitable bank types (hidden? context?) and setting the domain to this list ('type','in',types_list)
My notion here is that you may be mislead by the domains for journals
which I have modified. OpenERP 6 separated cash and bank journals by
introducing a new type 'bank' in addition to 'cash'. I have modified the
code accordingly.

As for suitable bank types, I took a shortcut and had done away with
them at all as I was trying to find out the current status of the
payment_order module. It seemed to be blocking all payment orders
because its method suitable_bank_types() returned no bank types at all
under any condition. I modified it to always return all bank types,
which seemed to solve the problem that no bank account was ever selected
for the payment order lines. Having another look now, the real cause
appears to be the pretty awful implementation of line2bank() in the
original payment_order module which initializes all keys in the
dictionary to False and then only provides a meaningful value if a key
is not in the dictionary.

That insight gives me with the key to implement the notion of suitable
bank types in this branch after all. I will have a go at that in the
next couple of weeks.

> 2. I can see how changing state on payment orders during testing of ClieOp can mess things up, but not being able to save it at all is a bit too restrictive for me. Preventing switching states when saving test batches should do just fine.

That was exactly my intent, and if I am not mistaken the code does just
that. Files are available for download in the wizard and afterwards in
the list of generated clieop files.

> 3. Instead of using a catch all bank, I prefer to have an optional relationship between res_partner_bank and res_bank. This way you can relax requirements. The current layout of res_bank is too biased for Belgian and German usage anyway - a bank code is required, which is not even known in some countries, including the Netherlands. You could add a constraint to require a valid bank when code is filled in order to prevent regression for bankcode-users.

As the res.bank on res.partner.bank is required in the base module, it
is reasonable for developers to expect this field to be defined on the
object. Such code already lives in the module l10n_ch. I would hate to
introduce instability by creating resources of type res.partner.bank
without a res.bank. Note that, in a previous mail, we ourselves agreed
to apply defensive object browsing only to complement requiredness of
fields. As such, I would rather not follow your suggestion.

Kind regards,
Stefan.

--
Therp - Maatwerk in open ontwikkeling

Stefan Rijnhart - Ontwerp en imple...

Read more...

63. By Stefan Rijnhart (Opener)

[MRG] fixes from parent branch already included in this branch

64. By Stefan Rijnhart (Opener)

[IMP] Restores suitable bank types functionality similar to V5

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi Pieter,

the branch has been updated with functionality for suitable bank type matching when filling payment orders. Support for this in account_payment is derelict, so I had to include some adaptations to the code in this module.

Cheers,
Stefan.

review: Needs Resubmitting
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi Pieter,

it has been a month since my last resubmit. Have you had a chance to review?

Cheers,
Stefan.

65. By Stefan Rijnhart (Opener)

[REF] Import wizard is now a new style (osv_memory) wizard

66. By Stefan Rijnhart (Opener)

[REF] Payment wizards are now new style (osv_memory) wizards
[FIX] Allow for ClieOp export with empty reference

67. By Stefan Rijnhart (Opener)

[IMP] Provide upgrade path for the previously pushed revision
[FIX] Layout change in the Triodos CSV format (account numbers)

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi Pieter,

the wizards have now been migrated to osv_memory. As a side effect, this makes dynamically selecting the payment wizard much more transparent.

An upgrade path for early adopters of this branch is provided (in nl_clieop/migrations/0.63). You can leave it in, it is harmless for new users but the revision number of the clieop module (and as a consequence, the name of the migrations subfolder) is a guess of course and should be changed when you merge the branch.

Regards,
Stefan.

review: Needs Resubmitting
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Forgot to mention that a small functional change has been made in the latest revisions: the field 'payment_order_ids' on banking.export.clieop is now a proper many2many, and a tab has been added to its view with this field.

68. By Stefan Rijnhart (Opener)

[FIX] Take moves from new refund journal types into account when matching transactions

Revision history for this message
Chris Halls (halls) wrote :

credativ is working on porting this to 6.1. I have already been in contact with Stefan to check we are not duplicating existing work.

Revision history for this message
Erwin van der Linde (erwin-7) wrote :

> credativ is working on porting this to 6.1. I have already been in contact
> with Stefan to check we are not duplicating existing work.

Dear Chris / Stefan,

Is there any update info on the porting matter?

Thanks in advance!

Cheers,

Erwin

Revision history for this message
Chris Halls (halls) wrote :

> Is there any update info on the porting matter?

Hi Erwin

We've had to revert back to 6.0 because of the delayed 6.1 release, but we do already have a number of changes. As far as I remember, we haven't yet completely sorted out how to specify bank accounts using the new combined account number + IBAN format. Would you like us to put the changes we have so far somewhere for you to look at?

Chris

Revision history for this message
Stefanr (stefan-stefanlinux) wrote :

On 10/25/2011 11:09 AM, Chris Halls (credativ) wrote:
>> Is there any update info on the porting matter?
> Hi Erwin
>
> We've had to revert back to 6.0 because of the delayed 6.1 release, but we do already have a number of changes. As far as I remember, we haven't yet completely sorted out how to specify bank accounts using the new combined account number + IBAN format. Would you like us to put the changes we have so far somewhere for you to look at?
>

Hi Chris,

it would be a good idea to put your changes on Launchpad.

Cheers,
Stefan.

69. By Stefan Rijnhart (Opener)

[FIX] iban read method to accept a single item or a list (Dmitrijs Ledkovs)

70. By Stefan Rijnhart (Opener)

[FIX] UnboundLocalError: local variable 'payment_lines' referenced before assignment (Dmitrijs Ledkovs)

Revision history for this message
Dimitri John Ledkov (ex-credativ) (dle-credativ) wrote :

Heya all,

Changes we did for 6.1 are pending to be uploaded to launchpad. I will do it, when I have spare capacity.

For two clients we deployed to we totally ignore vouchers, and it works fine.

Ideally we want a 6.0 & 6.1 branches started and merged as soon as possible preferably as series targets, e.g. lp:account-banking/6.0

I've submitted two bug-fixes which apply to v5 and upgrade-6.0 (merged into upgrade-6.0 already). And we are maintaining our own ~credativ/upgrade-6.0 branch for our customers currently. But we'd rather merge into lp:account-banking/6.0 to ease maintenance.

Please note that there is a non-working version of account_banking in addons-extra/6.0

Please note that account_banking should conflict with account_payment_extension (both use the same relation table for many2many, but a different target table resulting in very peculiar error messages).

Do any of you have commit access to addons-extra?

Regards,

Dmitrijs.

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

>
> Please note that there is a non-working version of account_banking in addons-
> extra/6.0
>
> Do any of you have commit access to addons-extra?

Hi Dmitrijs,

as it turned out, other people have now duplicated some of our work because of these obsolete versions in the extra addons branches, which also turn up on http://apps.openerp.com.

I think the extra addons branches should be obsolete now that you can add any branch on that site, so I removed the account_banking modules from extra-6.0 and extra-trunk completely.

Cheers,
Stefan.

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

This branch has been abandoned. Please go to https://launchpad.net/banking-addons

71. By Stefan Rijnhart (Opener)

[ADD] Announce deprecation of this branch

Unmerged revisions

71. By Stefan Rijnhart (Opener)

[ADD] Announce deprecation of this branch

70. By Stefan Rijnhart (Opener)

[FIX] UnboundLocalError: local variable 'payment_lines' referenced before assignment (Dmitrijs Ledkovs)

69. By Stefan Rijnhart (Opener)

[FIX] iban read method to accept a single item or a list (Dmitrijs Ledkovs)

68. By Stefan Rijnhart (Opener)

[FIX] Take moves from new refund journal types into account when matching transactions

67. By Stefan Rijnhart (Opener)

[IMP] Provide upgrade path for the previously pushed revision
[FIX] Layout change in the Triodos CSV format (account numbers)

66. By Stefan Rijnhart (Opener)

[REF] Payment wizards are now new style (osv_memory) wizards
[FIX] Allow for ClieOp export with empty reference

65. By Stefan Rijnhart (Opener)

[REF] Import wizard is now a new style (osv_memory) wizard

64. By Stefan Rijnhart (Opener)

[IMP] Restores suitable bank types functionality similar to V5

63. By Stefan Rijnhart (Opener)

[MRG] fixes from parent branch already included in this branch

62. By Stefan Rijnhart (Opener)

[FIX] Cannot use storage trigger on field 'id'

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'THIS_BRANCH_IS_DEPRECATED.txt'
--- THIS_BRANCH_IS_DEPRECATED.txt 1970-01-01 00:00:00 +0000
+++ THIS_BRANCH_IS_DEPRECATED.txt 2011-11-23 10:40:16 +0000
@@ -0,0 +1,3 @@
1This branch has been replaced by lp:banking-addons/6.0
2
3See https://launchpad.net/banking-addons
04
=== modified file 'account_banking/__terp__.py'
--- account_banking/__terp__.py 2011-11-08 13:10:34 +0000
+++ account_banking/__terp__.py 2011-11-23 10:40:16 +0000
@@ -35,66 +35,14 @@
35 'update_xml': [35 'update_xml': [
36 'security/ir.model.access.csv',36 'security/ir.model.access.csv',
37 'data/account_banking_data.xml',37 'data/account_banking_data.xml',
38 'account_banking_import_wizard.xml',38 'wizard/bank_import_view.xml',
39 'account_banking_payment_wizard.xml',
40 'account_banking_view.xml',39 'account_banking_view.xml',
41 'account_banking_workflow.xml',40 'account_banking_workflow.xml',
42 ],41 ],
43 'demo_xml': [],42 'demo_xml': [],
44 'description': '''43 'description': '''
45 Module to do banking.44Do not install this module. This branch has been replaced by lp:banking-addons/6.0
4645See https://launchpad.net/banking-addons
47 Note: This module is depending on BeautifulSoup.
48
49 This modules tries to combine all current banking import and export
50 schemes. Rationale for this is that it is quite common to have foreign
51 bank account numbers next to national bank account numbers. The current
52 approach, which hides the national banking interface schemes in the
53 l10n_xxx modules, makes it very difficult to use these simultanious.
54 A more banking oriented approach seems more logical and cleaner.
55
56 Changes to default OpenERP:
57
58 * Puts focus on the real life messaging with banks:
59 + Bank statement lines upgraded to independent bank transactions.
60 + Banking statements have no special accountancy meaning, they're just
61 message envelopes for a number of bank transactions.
62 + Bank statements can be either encoded by hand to reflect the document
63 version of Bank Statements, or created as an optional side effect of
64 importing Bank Transactions.
65
66 * Preparations for SEPA:
67 + IBAN accounts are the standard in the SEPA countries
68 + local accounts are derived from SEPA (excluding Turkey) but are
69 considered to be identical to the corresponding SEPA account.
70 + Banks are identified with either Country + Bank code + Branch code or BIC
71 + Each bank can have its own pace in introducing SEPA into their
72 communication with their customers.
73 + National online databases can be used to convert BBAN's to IBAN's.
74 + The SWIFT database is consulted for bank information.
75
76 * Adds dropin extensible import facility for bank communication in:
77 - Drop-in input parser development.
78 - MultiBank (NL) format transaction files available as
79 account_banking_nl_multibank,
80
81 * Extends payments for digital banking:
82 + Adapted workflow in payments to reflect banking operations
83 + Relies on account_payment mechanics to extend with export generators.
84 - ClieOp3 (NL) payment and direct debit orders files available as
85 account_banking_nl_clieop
86
87 * Additional features for the import/export mechanism:
88 + Automatic matching and creation of bank accounts, banks and partners,
89 during import of statements.
90 + Automatic matching with invoices and payments.
91 + Sound import mechanism, allowing multiple imports of the same
92 transactions repeated over multiple files.
93 + Journal configuration per bank account.
94 + Business logic and format parsing strictly separated to ease the
95 development of new parsers.
96 + No special configuration needed for the parsers, new parsers are
97 recognized and made available at server (re)start.
98 ''',46 ''',
99 'active': False,47 'active': False,
100 'installable': True,48 'installable': True,
10149
=== modified file 'account_banking/account_banking.py'
--- account_banking/account_banking.py 2011-11-08 13:10:34 +0000
+++ account_banking/account_banking.py 2011-11-23 10:40:16 +0000
@@ -63,6 +63,7 @@
63from osv import osv, fields63from osv import osv, fields
64from tools.translate import _64from tools.translate import _
65from wizard.banktools import get_or_create_bank65from wizard.banktools import get_or_create_bank
66import decimal_precision as dp
66import pooler67import pooler
67import netsvc68import netsvc
68from tools import config69from tools import config
@@ -184,6 +185,60 @@
184 }185 }
185account_banking_imported_file()186account_banking_imported_file()
186187
188class payment_mode_type(osv.osv):
189 _name= 'payment.mode.type'
190 _description= 'Payment Mode Type'
191 _columns= {
192 'name': fields.char(
193 'Name', size=64, required=True,
194 help='Payment Type'
195 ),
196 'code': fields.char(
197 'Code', size=64, required=True,
198 help='Specify the Code for Payment Type'
199 ),
200 # Setting suitable_bank_types to required pending
201 # https://bugs.launchpad.net/openobject-addons/+bug/786845
202 'suitable_bank_types': fields.many2many(
203 'res.partner.bank.type',
204 'bank_type_payment_type_rel',
205 'pay_type_id','bank_type_id',
206 'Suitable bank types', required=True),
207 'ir_model_id': fields.many2one(
208 'ir.model', 'Payment wizard',
209 help=('Select the Payment Wizard for payments of this type. '
210 'Leave empty for manual processing'),
211 domain=[('osv_memory', '=', True)],
212 ),
213 }
214
215payment_mode_type()
216
217class payment_mode(osv.osv):
218 ''' Restoring the payment type from version 5,
219 used to select the export wizard (if any) '''
220 _inherit = "payment.mode"
221
222 def suitable_bank_types(self, cr, uid, payment_mode_id=None, context=None):
223 """ Reinstates functional code for suitable bank type filtering.
224 Current code in account_payment is disfunctional.
225 """
226 res = []
227 payment_mode = self.browse(
228 cr, uid, payment_mode_id, context)
229 if (payment_mode and payment_mode.type and
230 payment_mode.type.suitable_bank_types):
231 res = [type.code for type in payment_mode.type.suitable_bank_types]
232 return res
233
234 _columns = {
235 'type': fields.many2one(
236 'payment.mode.type', 'Payment type',
237 help='Select the Payment Type for the Payment Mode.'
238 ),
239 }
240payment_mode()
241
187class account_bank_statement(osv.osv):242class account_bank_statement(osv.osv):
188 '''243 '''
189 Extensions from account_bank_statement:244 Extensions from account_bank_statement:
@@ -265,228 +320,139 @@
265 # '''320 # '''
266 # return None321 # return None
267322
268 def button_confirm(self, cursor, uid, ids, context=None):323 def create_move_from_st_line(self, cr, uid, st_line_id,
269 '''324 company_currency_id, st_line_number,
270 Trigger function for button 'Confirm'325 context=None):
271 As this function completely replaces the old one in account, other
272 modules who wish to alter behavior of this function but want to
273 cooperate with account_banking, should move their functionality to
274
275 on_button_confirm(self, cursor, uid, ids, context=None)
276
277 and drop any calls to super() herein.
278 In order to allow usage with and without account_banking, one could
279 use
280
281 def on_button_confirm(...):
282 # Your code here
283
284 def button_confirm(...):
285 super(my_class, self).button_confirm(...)
286 self.on_button_confirm(...)
287
288 This way, code duplication is minimized.
289 '''
290 # This is largely a copy of the original code in account326 # This is largely a copy of the original code in account
327 # Modifications are marked with AB
291 # As there is no valid inheritance mechanism for large actions, this328 # As there is no valid inheritance mechanism for large actions, this
292 # is the only option to add functionality to existing actions.329 # is the only option to add functionality to existing actions.
293 # WARNING: when the original code changes, this trigger has to be330 # WARNING: when the original code changes, this trigger has to be
294 # updated in sync.331 # updated in sync.
295 done = []332 if context is None:
333 context = {}
296 res_currency_obj = self.pool.get('res.currency')334 res_currency_obj = self.pool.get('res.currency')
297 res_users_obj = self.pool.get('res.users')
298 account_move_obj = self.pool.get('account.move')335 account_move_obj = self.pool.get('account.move')
299 account_move_line_obj = self.pool.get('account.move.line')336 account_move_line_obj = self.pool.get('account.move.line')
300 account_bank_statement_line_obj = \337 account_bank_statement_line_obj = self.pool.get(
301 self.pool.get('account.bank.statement.line')338 'account.bank.statement.line')
302339 st_line = account_bank_statement_line_obj.browse(cr, uid, st_line_id,
303 company_currency_id = res_users_obj.browse(cursor, uid, uid,340 context=context)
304 context=context).company_id.currency_id.id341 st = st_line.statement_id
305342
306 for st in self.browse(cursor, uid, ids, context):343 context.update({'date': st_line.date})
307 if not st.state=='draft':344 period_id = self._get_period(
308 continue345 cr, uid, st_line.date, context=context) # AB
309346
310 # Calculate statement balance from the contained lines347 move_id = account_move_obj.create(cr, uid, {
311 end_bal = st.balance_end or 0.0348 'journal_id': st.journal_id.id,
312 if not (abs(end_bal - st.balance_end_real) < 0.0001):349 'period_id': period_id, # AB
350 'date': st_line.date,
351 'name': st_line_number,
352 }, context=context)
353 account_bank_statement_line_obj.write(cr, uid, [st_line.id], {
354 'move_ids': [(4, move_id, False)]
355 })
356
357 if st_line.amount >= 0:
358 account_id = st.journal_id.default_credit_account_id.id
359 else:
360 account_id = st.journal_id.default_debit_account_id.id
361
362 acc_cur = ((st_line.amount <= 0 and
363 st.journal_id.default_debit_account_id) or
364 st_line.account_id)
365 context.update({
366 'res.currency.compute.account': acc_cur,
367 })
368 amount = res_currency_obj.compute(cr, uid, st.currency.id,
369 company_currency_id, st_line.amount, context=context)
370
371 val = {
372 'name': st_line.name,
373 'date': st_line.date,
374 'ref': st_line.ref,
375 'move_id': move_id,
376 'partner_id': (((st_line.partner_id) and st_line.partner_id.id) or
377 False),
378 'account_id': (st_line.account_id) and st_line.account_id.id,
379 'credit': ((amount>0) and amount) or 0.0,
380 'debit': ((amount<0) and -amount) or 0.0,
381 'statement_id': st.id,
382 'journal_id': st.journal_id.id,
383 'period_id': period_id, # AB
384 'currency_id': st.currency.id,
385 'analytic_account_id': (st_line.analytic_account_id and
386 st_line.analytic_account_id.id or
387 False),
388 }
389
390 if st.currency.id <> company_currency_id:
391 amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
392 st.currency.id, amount, context=context)
393 val['amount_currency'] = -amount_cur
394
395 if (st_line.account_id and st_line.account_id.currency_id and
396 st_line.account_id.currency_id.id <> company_currency_id):
397 val['currency_id'] = st_line.account_id.currency_id.id
398 amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
399 st_line.account_id.currency_id.id, amount, context=context)
400 val['amount_currency'] = -amount_cur
401
402 move_line_id = account_move_line_obj.create(
403 cr, uid, val, context=context)
404 torec = move_line_id
405
406 # Fill the secondary amount/currency
407 # if currency is not the same than the company
408 amount_currency = False
409 currency_id = False
410 if st.currency.id <> company_currency_id:
411 amount_currency = st_line.amount
412 currency_id = st.currency.id
413 account_move_line_obj.create(cr, uid, {
414 'name': st_line.name,
415 'date': st_line.date,
416 'ref': st_line.ref,
417 'move_id': move_id,
418 'partner_id': (((st_line.partner_id) and st_line.partner_id.id) or
419 False),
420 'account_id': account_id,
421 'credit': ((amount < 0) and -amount) or 0.0,
422 'debit': ((amount > 0) and amount) or 0.0,
423 'statement_id': st.id,
424 'journal_id': st.journal_id.id,
425 'period_id': period_id, # AB
426 'amount_currency': amount_currency,
427 'currency_id': currency_id,
428 }, context=context)
429
430 for line in account_move_line_obj.browse(cr, uid, [x.id for x in
431 account_move_obj.browse(cr, uid, move_id,
432 context=context).line_id],
433 context=context):
434 if line.state <> 'valid':
313 raise osv.except_osv(_('Error !'),435 raise osv.except_osv(_('Error !'),
314 _('The statement balance is incorrect !\n') +436 _('Journal Item "%s" is not valid') % line.name)
315 _('The expected balance (%.2f) is different '437
316 'than the computed one. (%.2f)') % (438 # Bank statements will not consider boolean on journal entry_posted
317 st.balance_end_real, st.balance_end439 account_move_obj.post(cr, uid, [move_id], context=context)
318 ))440
319 if (not st.journal_id.default_credit_account_id) \441 """
320 or (not st.journal_id.default_debit_account_id):442 Account-banking:
321 raise osv.except_osv(_('Configration Error !'),443 - Write stored reconcile_id
322 _('Please verify that an account is defined in the journal.'))444 - Pay invoices through workflow
323445 """
324 for line in st.move_line_ids:446 if st_line.reconcile_id:
325 if line.state != 'valid':447 account_move_line_obj.write(cr, uid, [torec], {
326 raise osv.except_osv(_('Error !'),448 'reconcile_id': st_line.reconcile_id.id }, context=context)
327 _('The account entries lines are not in valid state.'))449 for move_line in (st_line.reconcile_id.line_id or []) + (
328450 st_line.reconcile_id.line_partial_ids or []):
329 for move in st.line_ids:451 netsvc.LocalService("workflow").trg_trigger(
330 context.update({'date':move.date})452 uid, 'account.move.line', move_line.id, cr)
331 # Essence of the change is here...453 """ End account-banking """
332 period_id = self._get_period(cursor, uid, move.date, context=context)454
333 move_id = account_move_obj.create(cursor, uid, {455 return move_id
334 'journal_id': st.journal_id.id,
335 # .. and here
336 'period_id': period_id,
337 'date': move.date,
338 }, context=context)
339 account_bank_statement_line_obj.write(cursor, uid, [move.id], {
340 'move_ids': [(4, move_id, False)]
341 })
342 if not move.amount:
343 continue
344
345 torec = []
346 if move.amount >= 0:
347 account_id = st.journal_id.default_credit_account_id.id
348 else:
349 account_id = st.journal_id.default_debit_account_id.id
350 acc_cur = ((move.amount<=0) and st.journal_id.default_debit_account_id) \
351 or move.account_id
352 amount = res_currency_obj.compute(cursor, uid, st.currency.id,
353 company_currency_id, move.amount, context=context,
354 account=acc_cur)
355 if move.reconcile_id and move.reconcile_id.line_new_ids:
356 for newline in move.reconcile_id.line_new_ids:
357 amount += newline.amount
358
359 val = {
360 'name': move.name,
361 'date': move.date,
362 'ref': move.ref,
363 'move_id': move_id,
364 'partner_id': ((move.partner_id) and move.partner_id.id) or False,
365 'account_id': (move.account_id) and move.account_id.id,
366 'credit': ((amount>0) and amount) or 0.0,
367 'debit': ((amount<0) and -amount) or 0.0,
368 'statement_id': st.id,
369 'journal_id': st.journal_id.id,
370 'period_id': period_id,
371 'currency_id': st.currency.id,
372 }
373
374 amount = res_currency_obj.compute(cursor, uid, st.currency.id,
375 company_currency_id, move.amount, context=context,
376 account=acc_cur)
377 if st.currency.id != company_currency_id:
378 amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
379 st.currency.id, amount, context=context,
380 account=acc_cur)
381 val['amount_currency'] = -amount_cur
382
383 if move.account_id and move.account_id.currency_id and move.account_id.currency_id.id != company_currency_id:
384 val['currency_id'] = move.account_id.currency_id.id
385 amount_cur = res_currency_obj.compute(cursor, uid, company_currency_id,
386 move.account_id.currency_id.id, amount, context=context,
387 account=acc_cur)
388 val['amount_currency'] = -amount_cur
389
390 torec.append(account_move_line_obj.create(cursor, uid, val , context=context))
391
392 if move.reconcile_id and move.reconcile_id.line_new_ids:
393 for newline in move.reconcile_id.line_new_ids:
394 account_move_line_obj.create(cursor, uid, {
395 'name': newline.name or move.name,
396 'date': move.date,
397 'ref': move.ref,
398 'move_id': move_id,
399 'partner_id': ((move.partner_id) and move.partner_id.id) or False,
400 'account_id': (newline.account_id) and newline.account_id.id,
401 'debit': newline.amount>0 and newline.amount or 0.0,
402 'credit': newline.amount<0 and -newline.amount or 0.0,
403 'statement_id': st.id,
404 'journal_id': st.journal_id.id,
405 'period_id': period_id,
406 }, context=context)
407
408 # Fill the secondary amount/currency
409 # if currency is not the same than the company
410 amount_currency = False
411 currency_id = False
412 if st.currency.id <> company_currency_id:
413 amount_currency = move.amount
414 currency_id = st.currency.id
415
416 account_move_line_obj.create(cursor, uid, {
417 'name': move.name,
418 'date': move.date,
419 'ref': move.ref,
420 'move_id': move_id,
421 'partner_id': ((move.partner_id) and move.partner_id.id) or False,
422 'account_id': account_id,
423 'credit': ((amount < 0) and -amount) or 0.0,
424 'debit': ((amount > 0) and amount) or 0.0,
425 'statement_id': st.id,
426 'journal_id': st.journal_id.id,
427 'period_id': period_id,
428 'amount_currency': amount_currency,
429 'currency_id': currency_id,
430 }, context=context)
431
432 for line in account_move_line_obj.browse(cursor, uid, [x.id for x in
433 account_move_obj.browse(cursor, uid, move_id, context=context).line_id
434 ], context=context):
435 if line.state != 'valid':
436 raise osv.except_osv(
437 _('Error !'),
438 _('Account move line "%s" is not valid')
439 % line.name
440 )
441
442 if move.reconcile_id and move.reconcile_id.line_ids:
443 ## Search if move has already a partial reconciliation
444 previous_partial = False
445 for line_reconcile_move in move.reconcile_id.line_ids:
446 if line_reconcile_move.reconcile_partial_id:
447 previous_partial = True
448 break
449 ##
450 torec += map(lambda x: x.id, move.reconcile_id.line_ids)
451 #try:
452 if abs(move.reconcile_amount-move.amount)<0.0001:
453
454 writeoff_acc_id = False
455 #There should only be one write-off account!
456 for entry in move.reconcile_id.line_new_ids:
457 writeoff_acc_id = entry.account_id.id
458 break
459 ## If we have already a partial reconciliation
460 ## We need to make a partial reconciliation
461 ## To add this amount to previous paid amount
462 if previous_partial:
463 account_move_line_obj.reconcile_partial(cr, uid, torec, 'statement', context)
464 ## If it's the first reconciliation, we do a full reconciliation as regular
465 else:
466 account_move_line_obj.reconcile(
467 cursor, uid, torec, 'statement',
468 writeoff_acc_id=writeoff_acc_id,
469 writeoff_period_id=st.period_id.id,
470 writeoff_journal_id=st.journal_id.id,
471 context=context
472 )
473 else:
474 account_move_line_obj.reconcile_partial(
475 cursor, uid, torec, 'statement', context
476 )
477
478 if st.journal_id.entry_posted:
479 account_move_obj.write(cursor, uid, [move_id], {'state':'posted'})
480 done.append(st.id)
481 self.write(cursor, uid, done, {'state':'confirm'}, context=context)
482
483 # Be nice to other modules as well, relay button_confirm calls to
484 # on_button_confirm calls.
485 for other in self._abf_others:
486 if hasattr(other, 'on_button_confirm'):
487 other.on_button_confirm(self, cursor, uid, ids, context=context)
488
489 return True
490456
491account_bank_statement()457account_bank_statement()
492458
@@ -564,9 +530,23 @@
564 # res[line.id] = 0.0530 # res[line.id] = 0.0
565 # return res531 # return res
566532
533 def _get_invoice_id(self, cr, uid, ids, name, args, context=None):
534 res = {}
535 for st_line in self.browse(cr, uid, ids, context):
536 res[st_line.id] = False
537 for move_line in (st_line.reconcile_id and
538 (st_line.reconcile_id.line_id or []) +
539 (st_line.reconcile_id.line_partial_ids or []) or
540 []):
541 if move_line.invoice:
542 res[st_line.id] = move_line.invoice.id
543 continue
544 return res
545
567 _columns = {546 _columns = {
568 # Redefines547 # Redefines
569 'amount': fields.float('Amount', readonly=True,548 'amount': fields.float('Amount', readonly=True,
549 digits_compute=dp.get_precision('Account'),
570 states={'draft': [('readonly', False)]}),550 states={'draft': [('readonly', False)]}),
571 'ref': fields.char('Ref.', size=32, readonly=True,551 'ref': fields.char('Ref.', size=32, readonly=True,
572 states={'draft': [('readonly', False)]}),552 states={'draft': [('readonly', False)]}),
@@ -596,6 +576,13 @@
596 required=False,576 required=False,
597 states={'confirm': [('readonly', True)]},577 states={'confirm': [('readonly', True)]},
598 ),578 ),
579 'reconcile_id': fields.many2one(
580 'account.move.reconcile', 'Reconciliation', readonly=True
581 ),
582 'invoice_id': fields.function(
583 _get_invoice_id, method=True, string='Linked Invoice',
584 type='many2one', relation='account.invoice'
585 ),
599 }586 }
600587
601 _defaults = {588 _defaults = {
@@ -604,57 +591,8 @@
604 'currency': _get_currency,591 'currency': _get_currency,
605 }592 }
606593
607 def onchange_partner_id(self, cursor, uid, line_id, partner_id, type,
608 currency_id, context=None
609 ):
610 '''
611 Find default accounts when encoding statements by hand
612 '''
613 if not partner_id:
614 return {}
615
616 result = {}
617 if not currency_id:
618 users_obj = self.pool.get('res.users')
619 currency_id = users_obj.browse(
620 cursor, uid, uid, context=context
621 ).company_id.currency_id.id
622 result['currency_id'] = currency_id
623
624 partner_obj = self.pool.get('res.partner')
625 partner = partner_obj.browse(cursor, uid, partner_id, context=context)
626 if partner.supplier and not partner.customer:
627 if partner.property_account_payable.id:
628 result['account_id'] = partner.property_account_payable.id
629 result['type'] = 'supplier'
630 elif partner.customer and not partner.supplier:
631 if partner.property_account_receivable.id:
632 result['account_id'] = partner.property_account_receivable.id
633 result['type'] = 'customer'
634
635 return result and {'value': result} or {}
636
637account_bank_statement_line()594account_bank_statement_line()
638595
639class payment_type(osv.osv):
640 '''
641 Make description field translatable #, add country context
642 '''
643 _inherit = 'payment.type'
644 _columns = {
645 'name': fields.char('Name', size=64, required=True, translate=True,
646 help='Payment Type'
647 ),
648 #'country_id': fields.many2one('res.country', 'Country',
649 # required=False,
650 # help='Use this to limit this type to a specific country'
651 # ),
652 }
653 #_defaults = {
654 # 'country_id': lambda *a: False,
655 #}
656payment_type()
657
658class payment_line(osv.osv):596class payment_line(osv.osv):
659 '''597 '''
660 Add extra export_state and date_done fields; make destination bank account598 Add extra export_state and date_done fields; make destination bank account
@@ -814,6 +752,7 @@
814 Enable extra states for payment exports and add extra functionality.752 Enable extra states for payment exports and add extra functionality.
815 '''753 '''
816 _inherit = 'payment.order'754 _inherit = 'payment.order'
755<<<<<<< TREE
817756
818 def __no_transactions(self, cursor, uid, ids, field_name, arg=None,757 def __no_transactions(self, cursor, uid, ids, field_name, arg=None,
819 context=None):758 context=None):
@@ -862,8 +801,11 @@
862 cursor.execute(query)801 cursor.execute(query)
863 return dict(cursor.fetchall())802 return dict(cursor.fetchall())
864803
804=======
805
806>>>>>>> MERGE-SOURCE
865 _columns = {807 _columns = {
866 'date_planned': fields.date(808 'date_scheduled': fields.date(
867 'Scheduled date if fixed',809 'Scheduled date if fixed',
868 states={810 states={
869 'sent': [('readonly', True)],811 'sent': [('readonly', True)],
@@ -941,6 +883,47 @@
941 ),883 ),
942 }884 }
943885
886 def launch_wizard(self, cr, uid, ids, context=None):
887 """
888 Search for a wizard to launch according to the type.
889 If type is manual. just confirm the order.
890 Previously (pre-v6) in account_payment/wizard/wizard_pay.py
891 """
892 if context == None:
893 context={}
894 result = {}
895 orders = self.browse(cr, uid, ids, context)
896 order = orders[0]
897 # check if a wizard is defined for the first order
898 if order.mode.type and order.mode.type.ir_model_id:
899 context['active_ids'] = ids
900 wizard_model = order.mode.type.ir_model_id.model
901 wizard_obj = self.pool.get(wizard_model)
902 wizard_id = wizard_obj.create(cr, uid, {}, context)
903 result = {
904 'name': wizard_obj._description or 'Payment Order Export',
905 'view_type': 'form',
906 'view_mode': 'form',
907 'res_model': wizard_model,
908 'domain': [],
909 'context': context,
910 'type': 'ir.actions.act_window',
911 'target': 'new',
912 'res_id': wizard_id,
913 'nodestroy': True,
914 }
915 else:
916 # should all be manual orders without type or wizard model
917 for order in orders[1:]:
918 if order.mode.type and order.mode.type.ir_model_id:
919 raise osv.except_osv(
920 _('Error'),
921 _('You can only combine payment orders of the same type')
922 )
923 # process manual payments
924 self.action_sent(cr, uid, ids, context)
925 return result
926
944 def _write_payment_lines(self, cursor, uid, ids, **kwargs):927 def _write_payment_lines(self, cursor, uid, ids, **kwargs):
945 '''928 '''
946 ORM method for setting attributes of corresponding payment.line objects.929 ORM method for setting attributes of corresponding payment.line objects.
@@ -1180,8 +1163,13 @@
1180 Convert IBAN electronic format to IBAN display format1163 Convert IBAN electronic format to IBAN display format
1181 '''1164 '''
1182 records = self._founder.read(self, *args, **kwargs)1165 records = self._founder.read(self, *args, **kwargs)
1166<<<<<<< TREE
1183 if not hasattr(records, '__iter__'):1167 if not hasattr(records, '__iter__'):
1184 records = [records]1168 records = [records]
1169=======
1170 if not isinstance(records, list):
1171 records = [records,]
1172>>>>>>> MERGE-SOURCE
1185 for record in records:1173 for record in records:
1186 if 'iban' in record and record['iban']:1174 if 'iban' in record and record['iban']:
1187 record['iban'] = unicode(sepa.IBAN(record['iban']))1175 record['iban'] = unicode(sepa.IBAN(record['iban']))
@@ -1268,12 +1256,15 @@
1268 ):1256 ):
1269 country_ids = [user.company_id.partner_id.country.id]1257 country_ids = [user.company_id.partner_id.country.id]
1270 else:1258 else:
1271 # Ok, tried everything, give up and leave it to the user1259 if (user.company_id and user.company_id.partner_id and
1272 return warning(_('Insufficient data'),1260 user.company_id.partner_id.country):
1273 _('Insufficient data to select online '1261 country_ids = [user.company_id.partner_id.country.id]
1274 'conversion database')1262 else:
1275 )1263 # Ok, tried everything, give up and leave it to the user
12761264 return warning(_('Insufficient data'),
1265 _('Insufficient data to select online '
1266 'conversion database')
1267 )
1277 result = {'value': values}1268 result = {'value': values}
1278 # Complete data with online database when available1269 # Complete data with online database when available
1279 if country.code in sepa.IBAN.countries:1270 if country.code in sepa.IBAN.countries:
12801271
=== removed file 'account_banking/account_banking_import_wizard.xml'
--- account_banking/account_banking_import_wizard.xml 2010-01-26 20:55:24 +0000
+++ account_banking/account_banking_import_wizard.xml 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!--
3 Copyright (C) EduSense BV <http://www.edusense.nl>
4 All rights reserved.
5 The licence is in the file __terp__.py
6-->
7<openerp>
8 <data>
9 <wizard id="wizard_account_banking_import_file"
10 string="Import Bank Statements File"
11 model="account.bank.statement"
12 name="account_banking.banking_import"
13 />
14 </data>
15</openerp>
160
=== removed file 'account_banking/account_banking_payment_wizard.xml'
--- account_banking/account_banking_payment_wizard.xml 2011-02-12 13:37:09 +0000
+++ account_banking/account_banking_payment_wizard.xml 1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!--
3 Copyright (C) EduSense BV <http://www.edusense.nl>
4 All rights reserved.
5 The licence is in the file __terp__.py
6-->
7<openerp>
8 <data>
9 <wizard id="wizard_account_banking_payment_manual"
10 menu="False"
11 string="Manual Bank Payment"
12 model="account_payment.payment.order"
13 name="account_banking.payment_manual"
14 />
15 <wizard id="account_payment.wizard_populate_payment"
16 menu="False"
17 string="Populate payment"
18 model="payment.order"
19 name="account_payment.populate_payment"
20 />
21 </data>
22</openerp>
230
=== modified file 'account_banking/account_banking_view.xml'
--- account_banking/account_banking_view.xml 2011-11-07 12:34:48 +0000
+++ account_banking/account_banking_view.xml 2011-11-23 10:40:16 +0000
@@ -42,7 +42,7 @@
42 <field name="company_id" />42 <field name="company_id" />
43 <separator string="Bank Account Details" colspan="4" />43 <separator string="Bank Account Details" colspan="4" />
44 <field name="partner_bank_id" /> <!-- Needs domain for used companies /-->44 <field name="partner_bank_id" /> <!-- Needs domain for used companies /-->
45 <field name="journal_id" domain="[('type','=','cash')]" />45 <field name="journal_id" domain="[('type','=','bank')]" />
46 <separator string="Default Accounts for Unknown Movements" colspan="4" />46 <separator string="Default Accounts for Unknown Movements" colspan="4" />
47 <field name="default_credit_account_id" />47 <field name="default_credit_account_id" />
48 <field name="default_debit_account_id" />48 <field name="default_debit_account_id" />
@@ -61,7 +61,7 @@
61 <tree string="Default Import Settings for Bank Account">61 <tree string="Default Import Settings for Bank Account">
62 <field name="company_id" />62 <field name="company_id" />
63 <field name="partner_bank_id" /> <!-- Needs domain for used companies /-->63 <field name="partner_bank_id" /> <!-- Needs domain for used companies /-->
64 <field name="journal_id" domain="[('type','=','cash')]" />64 <field name="journal_id" domain="[('type','=','bank')]" />
65 </tree>65 </tree>
66 </field>66 </field>
67 </record>67 </record>
@@ -140,10 +140,18 @@
140 <menuitem name="Import Bank Statements File"140 <menuitem name="Import Bank Statements File"
141 id="menu_account_banking_import_wizard"141 id="menu_account_banking_import_wizard"
142 parent="account_banking.menu_finance_banking_actions"142 parent="account_banking.menu_finance_banking_actions"
143 type="wizard"
144 action="wizard_account_banking_import_file"143 action="wizard_account_banking_import_file"
145 sequence="15"/>144 sequence="15"/>
146145
146 <!-- Add the import wizard to the statement's right menu -->
147 <act_window name="Import Bank Statements File"
148 res_model="account.banking.bank.import"
149 src_model="account.bank.statement"
150 view_mode="form"
151 target="new"
152 key2="client_action_multi"
153 id="act_account_banking_import_wizard"/>
154
147 <!-- Create right menu entry to see statements -->155 <!-- Create right menu entry to see statements -->
148 <act_window name="Bank Statements File"156 <act_window name="Bank Statements File"
149 domain="[('id','=',banking_id)]"157 domain="[('id','=',banking_id)]"
@@ -170,7 +178,15 @@
170 <field name="model">account.bank.statement</field>178 <field name="model">account.bank.statement</field>
171 <field name="type">form</field>179 <field name="type">form</field>
172 <field name="arch" type="xml">180 <field name="arch" type="xml">
173 <field name="period_id" position="replace"/>181 <data>
182 <field name="period_id" position="replace"/>
183 <xpath expr="/form/notebook/page[@string='Transaction']/field/tree/field[@name='name']" position="replace">
184 <field name="name" required="1"/>
185 </xpath>
186 <xpath expr="/form/notebook/page[@string='Transaction']/field/form/field[@name='name']" position="replace">
187 <field name="name" required="1"/>
188 </xpath>
189 </data>
174 </field>190 </field>
175 </record>191 </record>
176 <record id="view_banking_bank_statement_form_2" model="ir.ui.view">192 <record id="view_banking_bank_statement_form_2" model="ir.ui.view">
@@ -179,7 +195,7 @@
179 <field name="model">account.bank.statement</field>195 <field name="model">account.bank.statement</field>
180 <field name="type">form</field>196 <field name="type">form</field>
181 <field name="arch" type="xml">197 <field name="arch" type="xml">
182 <xpath expr="/form/notebook/page[@string='Entry encoding']/field/tree/field[@name='type']" position="after">198 <xpath expr="/form/notebook/page[@string='Transaction']/field/tree/field[@name='ref']" position="after">
183 <field name="period_id"/>199 <field name="period_id"/>
184 </xpath>200 </xpath>
185 </field>201 </field>
@@ -190,7 +206,7 @@
190 <field name="model">account.bank.statement</field>206 <field name="model">account.bank.statement</field>
191 <field name="type">form</field>207 <field name="type">form</field>
192 <field name="arch" type="xml">208 <field name="arch" type="xml">
193 <xpath expr="/form/notebook/page[@string='Entry encoding']/field/form/field[@name='type']" position="after">209 <xpath expr="/form/notebook/page[@string='Transaction']/field/form/field[@name='ref']" position="after">
194 <field name="period_id"/>210 <field name="period_id"/>
195 </xpath>211 </xpath>
196 </field>212 </field>
@@ -235,9 +251,19 @@
235 <field name="model">account.bank.statement</field>251 <field name="model">account.bank.statement</field>
236 <field name="type">form</field>252 <field name="type">form</field>
237 <field name="arch" type="xml">253 <field name="arch" type="xml">
238 <xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='partner_id']" position="after">254 <data>
239 <field name="partner_bank_id"/>255 <xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='partner_id']" position="after">
240 </xpath>256 <field name="partner_bank_id"/>
257 </xpath>
258 <xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='amount']" position="after">
259 <field name="invoice_id"/>
260 <field name="reconcile_id"/>
261 </xpath>
262 <xpath expr="/form/notebook/page/field[@name='line_ids']/form/field[@name='amount']" position="after">
263 <field name="invoice_id"/>
264 <field name="reconcile_id"/>
265 </xpath>
266 </data>
241 </field>267 </field>
242 </record>268 </record>
243 <record id="view_banking_bank_statement_form_6" model="ir.ui.view">269 <record id="view_banking_bank_statement_form_6" model="ir.ui.view">
@@ -252,6 +278,7 @@
252 </field>278 </field>
253 </record>279 </record>
254280
281<<<<<<< TREE
255 <!-- Reset trigger on button_confirm to the trigger code in this module -->282 <!-- Reset trigger on button_confirm to the trigger code in this module -->
256 <record id="view_banking_bank_statement_form_7" model="ir.ui.view">283 <record id="view_banking_bank_statement_form_7" model="ir.ui.view">
257 <field name="name">account.bank.statement.form.banking-7</field>284 <field name="name">account.bank.statement.form.banking-7</field>
@@ -264,21 +291,44 @@
264 </button>291 </button>
265 </field>292 </field>
266 </record>293 </record>
294=======
295 <!-- Make buttons on payment order sensitive for extra states,
296 restore wizard functionality when making payments
297 -->
298>>>>>>> MERGE-SOURCE
267299
268 <!-- Make buttons on payment order sensitive for extra states -->
269 <record id="view_banking_payment_order_form_1" model="ir.ui.view">300 <record id="view_banking_payment_order_form_1" model="ir.ui.view">
270 <field name="name">account.payment.order.form.banking-1</field>301 <field name="name">account.payment.order.form.banking-1</field>
271 <field name="inherit_id" ref="account_payment.view_payment_order_form" />302 <field name="inherit_id" ref="account_payment.view_payment_order_form" />
272 <field name="model">payment.order</field>303 <field name="model">payment.order</field>
273 <field name="type">form</field>304 <field name="type">form</field>
274 <field name="arch" type="xml">305 <field name="arch" type="xml">
275 <xpath expr="/form/button[@string='Select Invoices to Pay']"306 <data>
276 position="replace">307 <xpath expr="/form/group/button[@string='Select Invoices to Pay']"
277 <button name="%(account_payment.wizard_populate_payment)s"308 position="replace">
278 colspan="2" type="action" states="draft,open"309 <button colspan="2" name="%(account_payment.action_create_payment_order)s"
279 string="Select Invoices to Pay"310 string="Select Invoices to Pay" type="action"
280 />311 attrs="{'invisible':[('state','!=','draft')]}"
281 </xpath>312 icon="gtk-find"
313 />
314 </xpath>
315 <xpath expr="/form/group/button[@string='Make Payments']"
316 position="replace">
317 <button name="launch_wizard" states="open" string="Make Payments" type="object" icon="gtk-execute"/>
318 <newline/>
319 </xpath>
320 </data>
321 </field>
322 </record>
323 <record id="view_banking_payment_order_tree_1" model="ir.ui.view">
324 <field name="name">account.payment.order.tree.banking-1</field>
325 <field name="inherit_id" ref="account_payment.view_payment_order_tree" />
326 <field name="model">payment.order</field>
327 <field name="type">tree</field>
328 <field name="arch" type="xml">
329 <button string="Make Payments" position="replace">
330 <button name="launch_wizard" states="open" string="Make Payments" type="object" icon="gtk-execute"/>
331 </button>
282 </field>332 </field>
283 </record>333 </record>
284334
@@ -353,7 +403,7 @@
353 <field name="type">form</field>403 <field name="type">form</field>
354 <field name="arch" type="xml">404 <field name="arch" type="xml">
355 <xpath expr="/form/notebook/page/field[@name='bank_ids']/tree/field[@name='acc_number']" position="replace">405 <xpath expr="/form/notebook/page/field[@name='bank_ids']/tree/field[@name='acc_number']" position="replace">
356 <field name="acc_number" on_change="onchange_acc_number(acc_number, parent.id, country_id)" />406 <field name="acc_number" on_change="onchange_acc_number(acc_number, parent.id, country_id)" select="1" />
357 </xpath>407 </xpath>
358 </field>408 </field>
359 </record>409 </record>
@@ -371,5 +421,43 @@
371 </field>421 </field>
372 </record>422 </record>
373423
424 <!-- Insert payment_mode.type -->
425 <record id="view_payment_mode_form_inherit" model="ir.ui.view">
426 <field name="name">payment.mode.form.inherit</field>
427 <field name="model">payment.mode</field>
428 <field name="inherit_id" ref="account_payment.view_payment_mode_form"/>
429 <field name="type">form</field>
430 <field name="arch" type="xml">
431 <field name="company_id" position="after">
432 <field name="type"/>
433 </field>
434 </field>
435 </record>
436 <record id="view_payment_mode_tree_inherit" model="ir.ui.view">
437 <field name="name">payment.mode.tree.inherit</field>
438 <field name="model">payment.mode</field>
439 <field name="inherit_id" ref="account_payment.view_payment_mode_tree"/>
440 <field name="type">tree</field>
441 <field name="arch" type="xml">
442 <field name="company_id" position="after">
443 <field name="type"/>
444 </field>
445 </field>
446 </record>
447
448 <!-- basic view for payment mode type -->
449 <record model="ir.ui.view" id="view_payment_mode_type_form">
450 <field name="name">view.payment.mode.type.form</field>
451 <field name="model">payment.mode.type</field>
452 <field name="type">form</field>
453 <field name="arch" type="xml">
454 <form>
455 <field name="name" />
456 <field name="code" />
457 <field name="suitable_bank_types"/>
458 <field name="ir_model_id"/>
459 </form>
460 </field>
461 </record>
374 </data>462 </data>
375</openerp>463</openerp>
376464
=== modified file 'account_banking/data/account_banking_data.xml'
--- account_banking/data/account_banking_data.xml 2010-12-20 10:58:51 +0000
+++ account_banking/data/account_banking_data.xml 2011-11-23 10:40:16 +0000
@@ -17,14 +17,14 @@
17 Ratio: one can have bank accounts in foreign banks. Foreign17 Ratio: one can have bank accounts in foreign banks. Foreign
18 addresses not automatically involve international banking.18 addresses not automatically involve international banking.
19 -->19 -->
20 <record id="bank_normal_field_contry" model="res.partner.bank.type.field">20 <record id="base.bank_normal_field_contry" model="res.partner.bank.type.field">
21 <field name="name">country_id</field>21 <field name="name">country_id</field>
22 <field name="bank_type_id" ref="base.bank_normal"/>22 <field name="bank_type_id" ref="base.bank_normal"/>
23 <field eval="False" name="required"/>23 <field eval="False" name="required"/>
24 <field eval="False" name="readonly"/>24 <field eval="False" name="readonly"/>
25 </record>25 </record>
26 <!-- Add manual bank transfer as default payment option -->26 <!-- Add manual bank transfer as default payment option -->
27 <record model="payment.type" id="account_banking.manual_bank_tranfer">27 <record model="payment.mode.type" id="account_banking.manual_bank_tranfer">
28 <field name="name">Manual Bank Transfer</field>28 <field name="name">Manual Bank Transfer</field>
29 <field name="code">BANKMAN</field>29 <field name="code">BANKMAN</field>
30 <field name="suitable_bank_types"30 <field name="suitable_bank_types"
3131
=== modified file 'account_banking/security/ir.model.access.csv'
--- account_banking/security/ir.model.access.csv 2010-12-20 10:58:51 +0000
+++ account_banking/security/ir.model.access.csv 2011-11-23 10:40:16 +0000
@@ -1,3 +1,5 @@
1"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"1"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
2"access_account_banking_settings","account.banking.account.settings","model_account_banking_account_settings","account.group_account_manager",1,1,1,12"access_account_banking_settings","account.banking.account.settings","model_account_banking_account_settings","account.group_account_manager",1,1,1,1
3"access_account_banking_settings_user","account.banking.account.settings user","model_account_banking_account_settings","account.group_account_user",1,0,0,0
3"access_account_banking_import","account.bankimport","model_account_banking_imported_file","account.group_account_user",1,1,1,14"access_account_banking_import","account.bankimport","model_account_banking_imported_file","account.group_account_user",1,1,1,1
5"access_payment_mode_type","payment.mode.type","model_payment_mode_type","account_payment.group_account_payment",1,1,1,1
46
=== modified file 'account_banking/wizard/__init__.py'
--- account_banking/wizard/__init__.py 2011-02-12 13:37:09 +0000
+++ account_banking/wizard/__init__.py 2011-11-23 10:40:16 +0000
@@ -20,6 +20,6 @@
20##############################################################################20##############################################################################
21import bank_import21import bank_import
22import bank_payment_manual22import bank_payment_manual
23import wizard_payment_order23import account_payment_order
2424
25# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:25# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2626
=== added file 'account_banking/wizard/account_payment_order.py'
--- account_banking/wizard/account_payment_order.py 1970-01-01 00:00:00 +0000
+++ account_banking/wizard/account_payment_order.py 2011-11-23 10:40:16 +0000
@@ -0,0 +1,113 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
5# All Rights Reserved
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import datetime
23from osv import osv
24from account_banking.struct import struct
25from account_banking.parsers import convert
26
27today = datetime.date.today
28
29def str2date(str):
30 dt = convert.str2date(str, '%Y-%m-%d')
31 return datetime.date(dt.year, dt.month, dt.day)
32
33class payment_order_create(osv.osv_memory):
34 _inherit = 'payment.order.create'
35
36 def create_payment(self, cr, uid, ids, context=None):
37 '''
38 This method is a slightly modified version of the existing method on this
39 model in account_payment.
40 - pass the payment mode to line2bank()
41 - allow invoices to create influence on the payment process: not only 'Free'
42 references are allowed, but others as well
43 - check date_to_pay is not in the past.
44 '''
45
46 order_obj = self.pool.get('payment.order')
47 line_obj = self.pool.get('account.move.line')
48 payment_obj = self.pool.get('payment.line')
49 if context is None:
50 context = {}
51 data = self.read(cr, uid, ids, [], context=context)[0]
52 line_ids = data['entries']
53 if not line_ids:
54 return {'type': 'ir.actions.act_window_close'}
55
56 payment = order_obj.browse(cr, uid, context['active_id'], context=context)
57 ### account banking
58 # t = None
59 # line2bank = line_obj.line2bank(cr, uid, line_ids, t, context)
60 line2bank = line_obj.line2bank(cr, uid, line_ids, payment.mode.id, context)
61 _today = today()
62 ### end account banking
63
64 ## Finally populate the current payment with new lines:
65 for line in line_obj.browse(cr, uid, line_ids, context=context):
66 if payment.date_prefered == "now":
67 #no payment date => immediate payment
68 date_to_pay = False
69 elif payment.date_prefered == 'due':
70 ### account_banking
71 # date_to_pay = line.date_maturity
72 date_to_pay = line.date_maturity and \
73 str2date(line.date_maturity) > _today\
74 and line.date_maturity or False
75 ### end account banking
76 elif payment.date_prefered == 'fixed':
77 ### account_banking
78 # date_to_pay = payment.date_planned
79 date_to_pay = payment.date_planned and \
80 str2date(payment.date_planned) > _today\
81 and payment.date_planned or False
82 ### end account banking
83
84 ### account_banking
85 state = communication2 = False
86 communication = line.ref or '/'
87 if line.invoice:
88 if line.invoice.reference_type == 'structured':
89 state = 'structured'
90 communication = line.invoice.reference
91 else:
92 state = 'normal'
93 communication2 = line.invoice.reference
94 ### end account_banking
95
96 payment_obj.create(cr, uid,{
97 'move_line_id': line.id,
98 'amount_currency': line.amount_to_pay,
99 'bank_id': line2bank.get(line.id),
100 'order_id': payment.id,
101 'partner_id': line.partner_id and line.partner_id.id or False,
102 ### account banking
103 # 'communication': line.ref or '/'
104 'communication': communication,
105 'communication2': communication2,
106 'state': state,
107 ### end account banking
108 'date': date_to_pay,
109 'currency': line.invoice and line.invoice.currency_id.id or False,
110 }, context=context)
111 return {'type': 'ir.actions.act_window_close'}
112
113payment_order_create()
0114
=== modified file 'account_banking/wizard/bank_import.py'
--- account_banking/wizard/bank_import.py 2011-11-07 22:23:48 +0000
+++ account_banking/wizard/bank_import.py 2011-11-23 10:40:16 +0000
@@ -28,9 +28,8 @@
28The parsing is done in the parser modules. Every parser module is required to28The parsing is done in the parser modules. Every parser module is required to
29use parser.models as a mean of communication with the business logic.29use parser.models as a mean of communication with the business logic.
30'''30'''
31import pooler31from osv import osv, fields
32import time32import time
33import wizard
34import netsvc33import netsvc
35import base6434import base64
36import datetime35import datetime
@@ -41,6 +40,7 @@
41from account_banking.struct import struct40from account_banking.struct import struct
42from account_banking import sepa41from account_banking import sepa
43from banktools import *42from banktools import *
43import decimal_precision as dp
4444
45bt = models.mem_bank_transaction45bt = models.mem_bank_transaction
4646
@@ -55,6 +55,7 @@
55 '''55 '''
56 return models.parser_type.get_parser_types()56 return models.parser_type.get_parser_types()
5757
58<<<<<<< TREE
58class banking_import(wizard.interface):59class banking_import(wizard.interface):
59 '''60 '''
60 Wizard to import bank statements. Generic code, parsing is done in the61 Wizard to import bank statements. Generic code, parsing is done in the
@@ -130,10 +131,14 @@
130131
131 def _fill_results(self, *args, **kwargs):132 def _fill_results(self, *args, **kwargs):
132 return {'log': self._log}133 return {'log': self._log}
134=======
135class banking_import(osv.osv_memory):
136 _name = 'account.banking.bank.import'
137>>>>>>> MERGE-SOURCE
133138
134 def _get_move_info(self, cursor, uid, move_line, partner_bank_id=False,139 def _get_move_info(self, cursor, uid, move_line, partner_bank_id=False,
135 partial=False):140 partial=False):
136 reconcile_obj = self.pool.get('account.bank.statement.reconcile')141 reconcile_obj = self.pool.get('account.move.reconcile')
137 type_map = {142 type_map = {
138 'out_invoice': 'customer',143 'out_invoice': 'customer',
139 'in_invoice': 'supplier',144 'in_invoice': 'supplier',
@@ -153,7 +158,14 @@
153158
154 if partial:159 if partial:
155 move_line.reconcile_partial_id = reconcile_obj.create(160 move_line.reconcile_partial_id = reconcile_obj.create(
161<<<<<<< TREE
156 cursor, uid, {'line_partial_ids': [(6, 0, [move_line.id])]}162 cursor, uid, {'line_partial_ids': [(6, 0, [move_line.id])]}
163=======
164 cursor, uid, {
165 'type': 'auto',
166 'line_partial_ids': [(4, 0, [move_line.id])]
167 }
168>>>>>>> MERGE-SOURCE
157 )169 )
158 else:170 else:
159 if move_line.reconcile_partial_id:171 if move_line.reconcile_partial_id:
@@ -164,7 +176,12 @@
164 partial_ids = []176 partial_ids = []
165 move_line.reconcile_id = reconcile_obj.create(177 move_line.reconcile_id = reconcile_obj.create(
166 cursor, uid, {178 cursor, uid, {
179<<<<<<< TREE
167 'line_ids': [180 'line_ids': [
181=======
182 'type': 'auto',
183 'line_id': [
184>>>>>>> MERGE-SOURCE
168 (4, x, False) for x in [move_line.id] + partial_ids185 (4, x, False) for x in [move_line.id] + partial_ids
169 ],186 ],
170 'line_partial_ids': [187 'line_partial_ids': [
@@ -228,12 +245,13 @@
228 return []245 return []
229246
230 def _link_payment(self, cursor, uid, trans, payment_lines,247 def _link_payment(self, cursor, uid, trans, payment_lines,
231 partner_ids, bank_account_ids, log):248 partner_ids, bank_account_ids, log, linked_payments):
232 '''249 '''
233 Find the payment order belonging to this reference - if there is one250 Find the payment order belonging to this reference - if there is one
234 When sending payments, the returned bank info should be identical to251 When sending payments, the returned bank info should be identical to
235 ours.252 ours.
236 '''253 '''
254<<<<<<< TREE
237 # TODO:255 # TODO:
238 # 1. Not sure what side effects are created when payments are done256 # 1. Not sure what side effects are created when payments are done
239 # for credited customer invoices, which will be matched later on257 # for credited customer invoices, which will be matched later on
@@ -247,6 +265,11 @@
247 # intertwined. Ignoring this causes double processing of the same265 # intertwined. Ignoring this causes double processing of the same
248 # payment line.266 # payment line.
249267
268=======
269 # TODO: Not sure what side effects are created when payments are done
270 # for credited customer invoices, which will be matched later on too.
271 digits = dp.get_precision('Account')(cursor)[1]
272>>>>>>> MERGE-SOURCE
250 candidates = [x for x in payment_lines273 candidates = [x for x in payment_lines
251 if x.id not in self.__linked_payments and274 if x.id not in self.__linked_payments and
252 (not self._cached(x.move_line_id)) and 275 (not self._cached(x.move_line_id)) and
@@ -260,6 +283,7 @@
260 ]283 ]
261 if len(candidates) == 1:284 if len(candidates) == 1:
262 candidate = candidates[0]285 candidate = candidates[0]
286<<<<<<< TREE
263 self.__linked_payments[candidate.id] = True287 self.__linked_payments[candidate.id] = True
264 self._cache(candidate.move_line_id)288 self._cache(candidate.move_line_id)
265 payment_line_obj = self.pool.get('payment.line')289 payment_line_obj = self.pool.get('payment.line')
@@ -271,12 +295,21 @@
271 cursor, uid, candidate.move_line_id,295 cursor, uid, candidate.move_line_id,
272 partner_bank_id=\296 partner_bank_id=\
273 bank_account_ids and bank_account_ids[0].id or False297 bank_account_ids and bank_account_ids[0].id or False
298=======
299 # Check cache to prevent multiple matching of a single payment
300 if candidate.id not in linked_payments:
301 linked_payments[candidate.id] = True
302 payment_line_obj = self.pool.get('payment.line')
303 payment_line_obj.write(cursor, uid, [candidate.id], {
304 'export_state': 'done',
305 'date_done': trans.effective_date.strftime('%Y-%m-%d')}
306>>>>>>> MERGE-SOURCE
274 )307 )
275308
276 return False309 return False
277310
278 def _link_invoice(self, cursor, uid, trans, move_lines,311 def _link_invoice(self, cursor, uid, trans, move_lines,
279 partner_ids, bank_account_ids, log):312 partner_ids, bank_account_ids, log, linked_invoices):
280 '''313 '''
281 Find the invoice belonging to this reference - if there is one314 Find the invoice belonging to this reference - if there is one
282 Use the sales journal to check.315 Use the sales journal to check.
@@ -360,6 +393,22 @@
360393
361 return False394 return False
362395
396<<<<<<< TREE
397=======
398 def _cached(move_line):
399 '''Check if the move_line has been cached'''
400 return move_line.id in linked_invoices
401
402 def _cache(move_line, remaining=0.0):
403 '''Cache the move_line'''
404 linked_invoices[move_line.id] = remaining
405
406 def _remaining(move_line):
407 '''Return the remaining amount for a previously matched move_line
408 '''
409 return linked_invoices[move_line.id]
410
411>>>>>>> MERGE-SOURCE
363 def _sign(invoice):412 def _sign(invoice):
364 '''Return the direction of an invoice'''413 '''Return the direction of an invoice'''
365 return {'in_invoice': -1, 414 return {'in_invoice': -1,
@@ -368,7 +417,7 @@
368 'out_refund': -1417 'out_refund': -1
369 }[invoice.type]418 }[invoice.type]
370419
371 digits = int(config['price_accuracy'])420 digits = dp.get_precision('Account')(cursor)[1]
372 partial = False421 partial = False
373422
374 # Search invoice on partner423 # Search invoice on partner
@@ -465,8 +514,6 @@
465 for x in best or candidates514 for x in best or candidates
466 ])515 ])
467 })516 })
468 self.__multiple_matches.append((trans, best or
469 candidates))
470 move_line = False517 move_line = False
471 partial = False518 partial = False
472519
@@ -543,7 +590,7 @@
543 if not account_info.costs_account_id:590 if not account_info.costs_account_id:
544 return []591 return []
545592
546 digits = int(config['price_accuracy'])593 digits = dp.get_precision('Account')(cursor)[1]
547 amount = round(abs(trans.transferred_amount), digits)594 amount = round(abs(trans.transferred_amount), digits)
548 # Make sure to be able to pinpoint our costs invoice for later595 # Make sure to be able to pinpoint our costs invoice for later
549 # matching596 # matching
@@ -591,14 +638,10 @@
591 invoice_line = invoice_lines,638 invoice_line = invoice_lines,
592 ))639 ))
593 invoice = invoice_obj.browse(cursor, uid, invoice_id)640 invoice = invoice_obj.browse(cursor, uid, invoice_id)
594 # Set number
595 invoice.action_number(cursor, uid, [invoice_id])
596 # Create moves
597 invoice.action_move_create(cursor, uid, [invoice_id])
598 # Create workflow641 # Create workflow
642 invoice_obj.button_compute(cursor, uid, [invoice_id],
643 {'type': 'in_invoice'}, set_total=True)
599 wf_service = netsvc.LocalService('workflow')644 wf_service = netsvc.LocalService('workflow')
600 res = wf_service.trg_create(uid, 'account.invoice', invoice.id,
601 cursor)
602 # Move to state 'open'645 # Move to state 'open'
603 wf_service.trg_validate(uid, 'account.invoice', invoice.id,646 wf_service.trg_validate(uid, 'account.invoice', invoice.id,
604 'invoice_open', cursor)647 'invoice_open', cursor)
@@ -606,17 +649,16 @@
606 # return move_lines to mix with the rest649 # return move_lines to mix with the rest
607 return [x for x in invoice.move_id.line_id if x.account_id.reconcile]650 return [x for x in invoice.move_id.line_id if x.account_id.reconcile]
608651
609 def _import_statements_file(self, cursor, uid, data, context):652 def import_statements_file(self, cursor, uid, ids, context):
610 '''653 '''
611 Import bank statements / bank transactions file.654 Import bank statements / bank transactions file.
612 This method represents the business logic, the parser modules655 This method represents the business logic, the parser modules
613 represent the decoding logic.656 represent the decoding logic.
614 '''657 '''
615 form = data['form']658 banking_import = self.browse(cursor, uid, ids, context)[0]
616 statements_file = form['file']659 statements_file = banking_import.file
617 data = base64.decodestring(statements_file)660 data = base64.decodestring(statements_file)
618661
619 self.pool = pooler.get_pool(cursor.dbname)
620 company_obj = self.pool.get('res.company')662 company_obj = self.pool.get('res.company')
621 user_obj = self.pool.get('res.user')663 user_obj = self.pool.get('res.user')
622 partner_obj = self.pool.get('res.partner')664 partner_obj = self.pool.get('res.partner')
@@ -632,28 +674,24 @@
632 digits = int(config['price_accuracy'])674 digits = int(config['price_accuracy'])
633675
634 # get the parser to parse the file676 # get the parser to parse the file
635 parser_code = form['parser']677 parser_code = banking_import.parser
636 parser = models.create_parser(parser_code)678 parser = models.create_parser(parser_code)
637 if not parser:679 if not parser:
638 raise wizard.except_wizard(680 raise osv.except_osv(
639 _('ERROR!'),681 _('ERROR!'),
640 _('Unable to import parser %(parser)s. Parser class not found.') %682 _('Unable to import parser %(parser)s. Parser class not found.') %
641 {'parser':parser_code}683 {'parser': parser_code}
642 )684 )
643685
644 # Get the company686 # Get the company
645 company = form['company']687 company = (banking_import.company or
646 if not company:688 user_obj.browse(cursor, uid, uid, context).company_id)
647 user_data = user_obj.browse(cursor, uid, uid, context)
648 company = company_obj.browse(
649 cursor, uid, company or user_data.company_id.id, context
650 )
651689
652 # Parse the file690 # Parse the file
653 statements = parser.parse(data)691 statements = parser.parse(data)
654692
655 if any([x for x in statements if not x.is_valid()]):693 if any([x for x in statements if not x.is_valid()]):
656 raise wizard.except_wizard(694 raise osv.except_osv(
657 _('ERROR!'),695 _('ERROR!'),
658 _('The imported statements appear to be invalid! Check your file.')696 _('The imported statements appear to be invalid! Check your file.')
659 )697 )
@@ -682,6 +720,9 @@
682 error_accounts = {}720 error_accounts = {}
683 info = {}721 info = {}
684 imported_statement_ids = []722 imported_statement_ids = []
723 linked_payments = {}
724 linked_invoices = {}
725 payment_lines = []
685726
686 if statements:727 if statements:
687 # Get default defaults728 # Get default defaults
@@ -690,7 +731,8 @@
690731
691 # Get interesting journals once732 # Get interesting journals once
692 journal_ids = journal_obj.search(cursor, uid, [733 journal_ids = journal_obj.search(cursor, uid, [
693 ('type', 'in', ('sale','purchase')),734 ('type', 'in', ('sale','purchase',
735 'purchase_refund','sale_refund')),
694 ('company_id', '=', company.id),736 ('company_id', '=', company.id),
695 ])737 ])
696 # Get all unreconciled moves predating the last statement in one big738 # Get all unreconciled moves predating the last statement in one big
@@ -718,6 +760,7 @@
718 "o.state = 'sent' AND "760 "o.state = 'sent' AND "
719 "l.date_done IS NULL"761 "l.date_done IS NULL"
720 )762 )
763<<<<<<< TREE
721 line_ids = [x[0] for x in cursor.fetchall()]764 line_ids = [x[0] for x in cursor.fetchall()]
722 if line_ids:765 if line_ids:
723 # Get payment_orders and calculated total amounts as well in766 # Get payment_orders and calculated total amounts as well in
@@ -740,6 +783,11 @@
740 order_totals.keys()783 order_totals.keys()
741 ))784 ))
742 ]785 ]
786=======
787 payment_line_ids = [x[0] for x in cursor.fetchall()]
788 if payment_line_ids:
789 payment_lines = payment_line_obj.browse(cursor, uid, payment_line_ids)
790>>>>>>> MERGE-SOURCE
743791
744 for statement in statements:792 for statement in statements:
745 if statement.local_account in error_accounts:793 if statement.local_account in error_accounts:
@@ -749,7 +797,7 @@
749 continue797 continue
750798
751 # Create fallback currency code799 # Create fallback currency code
752 currency_code = statement.local_currency or company.currency_id.code800 currency_code = statement.local_currency or company.currency_id.name
753801
754 # Check cache for account info/currency802 # Check cache for account info/currency
755 if statement.local_account in info and \803 if statement.local_account in info and \
@@ -781,7 +829,7 @@
781 continue829 continue
782830
783 # Get required currency code831 # Get required currency code
784 currency_code = account_info.currency_id.code832 currency_code = account_info.currency_id.name
785833
786 # Cache results834 # Cache results
787 if not statement.local_account in info:835 if not statement.local_account in info:
@@ -793,7 +841,7 @@
793841
794 # Final check: no coercion of currencies!842 # Final check: no coercion of currencies!
795 if statement.local_currency \843 if statement.local_currency \
796 and account_info.currency_id.code != statement.local_currency:844 and account_info.currency_id.name != statement.local_currency:
797 # TODO: convert currencies?845 # TODO: convert currencies?
798 results.log.append(846 results.log.append(
799 _('Statement %(statement_id)s for account %(bank_account)s' 847 _('Statement %(statement_id)s for account %(bank_account)s'
@@ -970,7 +1018,7 @@
970 move_info = self._link_payment(1018 move_info = self._link_payment(
971 cursor, uid, transaction,1019 cursor, uid, transaction,
972 payment_lines, partner_ids,1020 payment_lines, partner_ids,
973 partner_banks, results.log1021 partner_banks, results.log, linked_payments,
974 )1022 )
9751023
976 # Second guess, invoice -> may split transaction, so beware1024 # Second guess, invoice -> may split transaction, so beware
@@ -980,7 +1028,7 @@
980 # these, and invoice matching still has to be done.1028 # these, and invoice matching still has to be done.
981 move_info, remainder = self._link_invoice(1029 move_info, remainder = self._link_invoice(
982 cursor, uid, transaction, move_lines, partner_ids,1030 cursor, uid, transaction, move_lines, partner_ids,
983 partner_banks, results.log1031 partner_banks, results.log, linked_invoices,
984 )1032 )
985 if remainder:1033 if remainder:
986 injected.append(remainder)1034 injected.append(remainder)
@@ -1087,107 +1135,71 @@
1087 state = results.error_cnt and 'error' or 'ready'1135 state = results.error_cnt and 'error' or 'ready'
1088 statement_file_obj.write(cursor, uid, import_id, dict(1136 statement_file_obj.write(cursor, uid, import_id, dict(
1089 state = state, log = text_log,1137 state = state, log = text_log,
1090 ))1138 ), context)
1091 if results.error_cnt or not imported_statement_ids:1139 if not imported_statement_ids:
1092 self._nextstate = 'view_error'1140 # file state can be 'ready' while import state is 'error'
1093 else:1141 state = 'error'
1094 self._nextstate = 'view_statements'1142 self.write(cursor, uid, [ids[0]], dict(
1095 self._import_id = import_id1143 import_id = import_id, log = text_log, state = state,
1096 self._log = text_log1144 statement_ids = [[6, 0, imported_statement_ids]],
1097 self._statement_ids = imported_statement_ids1145 ), context)
1098 return {}1146 return {
10991147 'name': _('Import Bank Transactions File'),
1100 def _action_open_window(self, cursor, uid, data, context):1148 'view_type': 'form',
1101 '''1149 'view_mode': 'form',
1102 Open a window with the resulting bank statements1150 'view_id': False,
1103 '''1151 'res_model': self._name,
1104 # TODO: this needs fiddling. The resulting window is informative,1152 'domain': [],
1105 # but not very usefull...1153 'context': dict(context, active_ids=ids),
1106 module_obj = self.pool.get('ir.model.data')1154 'type': 'ir.actions.act_window',
1107 action_obj = self.pool.get('ir.actions.act_window')1155 'target': 'new',
1108 result = module_obj._get_id(1156 'res_id': ids[0] or False,
1109 cursor, uid, 'account', 'action_bank_statement_tree'1157 }
1110 )1158
1111 id = module_obj.read(cursor, uid, [result], ['res_id'])[0]['res_id']1159 _columns = {
1112 result = action_obj.read(cursor, uid, [id])[0]1160 'company': fields.many2one(
1113 result['context'] = str({'banking_id': self._import_id})1161 'res.company', 'Company', required=True,
1114 return result1162 states={
11151163 'ready': [('readonly', True)],
1116 def _action_open_import(self, cursor, uid, data, context):1164 'error': [('readonly', True)],
1117 '''1165 },
1118 Open a window with the resulting import in error1166 ),
1119 '''1167 'file': fields.binary(
1120 return dict(1168 'Statements File', required=True,
1121 view_type = 'form',1169 help = ('The Transactions File to import. Please note that while it is '
1122 view_mode = 'form,tree',1170 'perfectly safe to reload the same file multiple times or to load in '
1123 res_model = 'account.banking.imported.file',1171 'timeframe overlapping statements files, there are formats that may '
1124 view_id = False,1172 'introduce different sequencing, which may create double entries.\n\n'
1125 type = 'ir.actions.act_window',1173 'To stay on the safe side, always load bank statements files using the '
1126 res_id = self._import_id1174 'same format.'),
1127 )1175 states={
11281176 'ready': [('readonly', True)],
1129 def _check_next_state(self, cursor, uid, data, context):1177 'error': [('readonly', True)],
1130 return self._nextstate1178 },
11311179 ),
1132 states = {1180 'parser': fields.selection(
1133 'init' : {1181 parser_types, 'File Format', required=True,
1134 'actions' : [],1182 states={
1135 'result' : {1183 'ready': [('readonly', True)],
1136 'type' : 'form',1184 'error': [('readonly', True)],
1137 'arch' : import_form,1185 },
1138 'fields': import_fields,1186 ),
1139 'state': [('end', '_Cancel', 'gtk-cancel'),1187 'log': fields.text('Log', readonly=True),
1140 ('import', '_Ok', 'gtk-ok'),1188 'state': fields.selection(
1141 ]1189 [('init', 'init'), ('ready', 'ready'),
1142 }1190 ('error', 'error')],
1143 },1191 'State', readonly=True),
1144 'import': {1192 'import_id': fields.many2one(
1145 'actions': [_import_statements_file],1193 'account.banking.imported.file', 'Import File'),
1146 'result': {1194 # osv_memory does not seem to support one2many
1147 'type': 'choice',1195 'statement_ids': fields.many2many(
1148 'next_state': _check_next_state,1196 'account.bank.statement', 'rel_wiz_statements', 'wizard_id',
1149 }1197 'statement_id', 'Imported Bank Statements'),
1150 },1198 }
1151 'view_statements' : {1199
1152 'actions': [_fill_results],1200 _defaults = {
1153 'result': {1201 'state': 'init',
1154 'type': 'form',1202 }
1155 'arch': result_form,1203banking_import()
1156 'fields': result_fields,
1157 'state': [('end', '_Close', 'gtk-close'),
1158 ('open_statements', '_View Statements', 'gtk-ok'),
1159 ]
1160 }
1161 },
1162 'view_error': {
1163 'actions': [_fill_results],
1164 'result': {
1165 'type': 'form',
1166 'arch': result_form,
1167 'fields': result_fields,
1168 'state': [('end', '_Close', 'gtk-close'),
1169 ('open_import', '_View Imported File', 'gtk-ok'),
1170 ]
1171 }
1172 },
1173 'open_import': {
1174 'actions': [],
1175 'result': {
1176 'type': 'action',
1177 'action': _action_open_import,
1178 'state': 'end'
1179 }
1180 },
1181 'open_statements': {
1182 'actions': [],
1183 'result': {
1184 'type': 'action',
1185 'action': _action_open_window,
1186 'state': 'end'
1187 }
1188 },
1189 }
1190
1191banking_import('account_banking.banking_import')
11921204
1193# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:1205# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
11941206
=== added file 'account_banking/wizard/bank_import_view.xml'
--- account_banking/wizard/bank_import_view.xml 1970-01-01 00:00:00 +0000
+++ account_banking/wizard/bank_import_view.xml 2011-11-23 10:40:16 +0000
@@ -0,0 +1,52 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="view_banking_import" model="ir.ui.view">
5 <field name="name">account.banking.bank.import</field>
6 <field name="model">account.banking.bank.import</field>
7 <field name="type">form</field>
8 <field name="arch" type="xml">
9 <form string="Import Bank Transactions File">
10 <group colspan="4">
11 <separator colspan="4" string="Select the processing details:"/>
12 <field name="company" colspan="1"/>
13 <field name="file"/>
14 <newline />
15 <field name="parser"/>
16 <field name="state" invisible="1"/>
17 </group>
18 <group colspan="4" states="ready,error">
19 <separator colspan="4" string="Results:"/>
20 <field name="log" colspan="4" nolabel="1" width="500"/>
21 </group>
22 <group colspan="4" states="ready">
23 <field name="statement_ids" colspan="4" nolabel="1"/>
24 </group>
25 <group colspan="2" states="init">
26 <button icon="gtk-cancel"
27 special="cancel"
28 string="Cancel"/>
29 <button icon="gtk-ok"
30 string="Import"
31 name="import_statements_file"
32 type="object"/>
33 </group>
34 <button icon="gtk-close"
35 special="cancel"
36 string="Close"
37 states="ready,error"/>
38 </form>
39 </field>
40 </record>
41
42 <record id="wizard_account_banking_import_file" model="ir.actions.act_window">
43 <field name="name">Import Bank Statements File</field>
44 <field name="type">ir.actions.act_window</field>
45 <field name="res_model">account.banking.bank.import</field>
46 <field name="view_type">form</field>
47 <field name="view_mode">tree,form</field>
48 <field name="view_id" ref="view_banking_import"/>
49 <field name="target">new</field>
50 </record>
51 </data>
52</openerp>
053
=== modified file 'account_banking/wizard/banktools.py'
--- account_banking/wizard/banktools.py 2011-04-27 11:42:52 +0000
+++ account_banking/wizard/banktools.py 2011-11-23 10:40:16 +0000
@@ -216,12 +216,12 @@
216 # Find matching journal for currency216 # Find matching journal for currency
217 journal_obj = pool.get('account.journal')217 journal_obj = pool.get('account.journal')
218 journal_ids = journal_obj.search(cursor, uid, [218 journal_ids = journal_obj.search(cursor, uid, [
219 ('type', '=', 'cash'),219 ('type', '=', 'bank'),
220 ('currency', '=', currency or company.currency_id.code)220 ('currency', '=', currency or company.currency_id.name)
221 ])221 ])
222 if not journal_ids and currency == company.currency_id.code:222 if not journal_ids and currency == company.currency_id.name:
223 journal_ids = journal_obj.search(cursor, uid, [223 journal_ids = journal_obj.search(cursor, uid, [
224 ('type', '=', 'cash'), ('currency', '=', False)224 ('type', '=', 'bank'), ('currency', '=', False)
225 ])225 ])
226 if journal_ids:226 if journal_ids:
227 criteria.append(('journal_id', 'in', journal_ids))227 criteria.append(('journal_id', 'in', journal_ids))
@@ -302,9 +302,9 @@
302 else:302 else:
303 info = struct(name=name, code=code)303 info = struct(name=name, code=code)
304304
305 if info.code and ((not online) or not bank_id):305 if not online or not bank_id:
306 bank_id = bank_obj.create(cursor, uid, dict(306 bank_id = bank_obj.create(cursor, uid, dict(
307 code = info.code,307 code = info.code or 'UNKNOW',
308 name = info.name or _('Unknown Bank'),308 name = info.name or _('Unknown Bank'),
309 country = country_id,309 country = country_id,
310 bic = bic,310 bic = bic,
@@ -341,12 +341,18 @@
341 cursor, uid, partner_id).country341 cursor, uid, partner_id).country
342 country_code = country.code342 country_code = country.code
343 country_id = country.id343 country_id = country.id
344 elif iban.valid:344 else:
345 country_ids = country_obj.search(cursor, uid,345 if iban.valid:
346 [('code', '=', iban.countrycode)]346 country_ids = country_obj.search(cursor, uid,
347 )347 [('code', '=', iban.countrycode)]
348 )
349 else:
350 country_ids = country_obj.search(cursor, uid,
351 [('code', '=', country_code)]
352 )
348 country_id = country_ids[0]353 country_id = country_ids[0]
349 354
355 account_info = False
350 if not iban.valid:356 if not iban.valid:
351 # No, try to convert to IBAN357 # No, try to convert to IBAN
352 values.state = 'bank'358 values.state = 'bank'
@@ -362,9 +368,11 @@
362 bic = account_info.bic368 bic = account_info.bic
363369
364 if bic:370 if bic:
365 values.bank_id = get_or_create_bank(pool, cursor, uid, bic)371 values.bank = get_or_create_bank(pool, cursor, uid, bic)[0]
366372
367 elif bankcode:373 else:
374 if not bankcode:
375 bankcode = "UNKNOW"
368 # Try to link bank376 # Try to link bank
369 bank_obj = pool.get('res.bank')377 bank_obj = pool.get('res.bank')
370 bank_ids = bank_obj.search(cursor, uid, [378 bank_ids = bank_obj.search(cursor, uid, [
@@ -372,10 +380,10 @@
372 ])380 ])
373 if bank_ids:381 if bank_ids:
374 # Check BIC on existing banks382 # Check BIC on existing banks
375 values.bank_id = bank_ids[0]383 values.bank = bank_ids[0]
376 bank = bank_obj.browse(cursor, uid, values.bank_id)384 bank = bank_obj.browse(cursor, uid, values.bank)
377 if not bank.bic:385 if not bank.bic:
378 bank_obj.write(cursor, uid, values.bank_id, dict(bic=bic))386 bank_obj.write(cursor, uid, values.bank, dict(bic=bic))
379 else:387 else:
380 # New bank - create388 # New bank - create
381 res = struct(country_id=country_id)389 res = struct(country_id=country_id)
@@ -389,7 +397,7 @@
389 res.code = bankcode397 res.code = bankcode
390 res.name = _('Unknown Bank')398 res.name = _('Unknown Bank')
391399
392 values.bank_id = bank_obj.create(cursor, uid, res)400 values.bank = bank_obj.create(cursor, uid, res)
393401
394 # Create bank account and return402 # Create bank account and return
395 return pool.get('res.partner.bank').create(cursor, uid, values)403 return pool.get('res.partner.bank').create(cursor, uid, values)
396404
=== removed file 'account_banking/wizard/wizard_payment_order.py'
--- account_banking/wizard/wizard_payment_order.py 2011-02-13 09:28:59 +0000
+++ account_banking/wizard/wizard_payment_order.py 1970-01-01 00:00:00 +0000
@@ -1,212 +0,0 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# Copyright (C) EduSense BV (<http://www.edusense.nl>).
5# All Rights Reserved.
6#
7# OpenERP, Open Source Management Solution
8# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
9#
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program. If not, see <http://www.gnu.org/licenses/>.
22#
23##############################################################################
24import datetime
25import wizard
26import pooler
27from tools.misc import UpdateableStr
28from tools.translate import _
29from account_banking.struct import struct
30from account_banking.parsers import convert
31
32__doc__ = '''
33This module is a slightly modified version of the identical named payment
34order wizard in account_payment. The rationale for this bulk copy is the
35inability to inherit wizards in OpenERP versions prior to version 6.
36The modifications in this wizard allows invoices to create influence on the
37payment process: not only 'Free' references are allowed, but others as well.
38
39In order to allow further projects based on account_banking to inherit from
40this wizard, the complete wizard is made object oriented, as is should have
41been from the start.
42'''
43
44today = datetime.date.today
45
46def str2date(str):
47 dt = convert.str2date(str, '%Y-%m-%d')
48 return datetime.date(dt.year, dt.month, dt.day)
49
50class wizard_payment_order(wizard.interface):
51 '''
52 Create a payment object with lines corresponding to the account move line
53 to pay according to the date and the mode provided by the user.
54 Hypothesis:
55 - Small number of non-reconcilied move line , payment mode and bank account type,
56 - Big number of partner and bank account.
57
58 If a type is given, unsuitable account move lines are ignored.
59 '''
60
61 FORM = UpdateableStr()
62 FIELDS = {
63 'entries': {
64 'string':'Entries',
65 'type':'many2many',
66 'relation': 'account.move.line',
67 },
68 }
69 field_duedate = {
70 'duedate': {
71 'string': 'Due Date',
72 'type': 'date',
73 'required': True,
74 'default': lambda *a: convert.date2str(today()),
75 },
76 }
77 arch_duedate='''<?xml version="1.0"?>
78 <form string="Search Payment lines">
79 <field name="duedate" />
80 </form>'''
81
82
83 def search_entries(self, cursor, uid, data, context):
84 '''
85 Search for invoices that can be paid
86 '''
87 search_due_date = data['form']['duedate']
88
89 pool = pooler.get_pool(cursor.dbname)
90 order_obj = pool.get('payment.order')
91 move_line_obj = pool.get('account.move.line')
92
93 payment = order_obj.browse(cursor, uid, data['id'], context=context)
94 if payment.mode:
95 ctx = '''context="{'journal_id': %d}"''' % payment.mode.journal.id
96 else:
97 ctx = ''
98
99 # Search account.move.line to pay:
100 domain = [
101 ('reconcile_id', '=', False),
102 ('account_id.type', '=', 'payable'),
103 ('amount_to_pay', '>', 0),
104 '|', ('date_maturity','<=',search_due_date),
105 ('date_maturity','=',False)
106 ]
107 line_ids = move_line_obj.search(cursor, uid, domain, context=context)
108 self.FORM.string = '''<?xml version="1.0"?>
109 <form string="Populate Payment:">
110 <field name="entries" colspan="4" height="300" width="800" nolabel="1"
111 domain="[('id', 'in', [%s])]" %s
112 />
113 </form>''' % (','.join([str(x) for x in line_ids]), ctx)
114 return {}
115
116 def get_communication(self, line):
117 '''
118 Method to fill the communication and communication2 lines of a payment
119 line. Returns (state, comm1, comm2).
120 '''
121 if line.invoice.reference_type == 'structured':
122 return ('structured', line.invoice.reference, '')
123 return ('normal', '', line.invoice.reference)
124
125 def create_payment(self, cursor, uid, data, context):
126 '''
127 Create payment lines from the data of previously created payable
128 invoices
129 '''
130 ids = data['form']['entries'][0][2]
131 if not ids:
132 return {}
133
134 pool = pooler.get_pool(cursor.dbname)
135 order_obj = pool.get('payment.order')
136 move_line_obj = pool.get('account.move.line')
137 payment_line_obj = pool.get('payment.line')
138
139 payment = order_obj.browse(cursor, uid, data['id'], context=context)
140 ptype = payment.mode and payment.mode.type.id or None
141 line2bank = move_line_obj.line2bank(cursor, uid, ids, ptype, context)
142 _today = today()
143 retval = struct()
144
145 # Populate the current payment with new lines
146 for line in move_line_obj.browse(cursor, uid, ids, context=context):
147 if payment.date_prefered == 'now':
148 # no payment date means immediate payment
149 date_to_pay = False
150 elif payment.date_prefered == 'due':
151 date_to_pay = line.date_maturity and \
152 str2date(line.date_maturity) > _today\
153 and line.date_maturity or False
154 elif payment.date_prefered == 'fixed':
155 date_to_pay = payment.date_planned and \
156 str2date(payment.date_planned) > _today\
157 and payment.date_planned or False
158 values = struct(
159 move_line_id = line.id,
160 amount_currency = line.amount_to_pay,
161 bank_id = line2bank.get(line.id),
162 order_id = payment.id,
163 partner_id = line.partner_id and line.partner_id.id or False,
164 date = date_to_pay,
165 currency = False,
166 )
167 if line.invoice:
168 values.state, values.communication, values.communication2 = \
169 self.get_communication(line)
170 values.currency = line.invoice.currency_id.id,
171 payment_line_obj.create(cursor, uid, values, context=context)
172
173 return {}
174
175 states = {
176 'init': {
177 'actions': [],
178 'result': {
179 'type': 'form',
180 'arch': arch_duedate,
181 'fields': field_duedate,
182 'state': [
183 ('end','_Cancel'),
184 ('search','_Search', '', True)
185 ]
186 },
187 },
188 'search': {
189 'actions': [search_entries],
190 'result': {
191 'type': 'form',
192 'arch': FORM,
193 'fields': FIELDS,
194 'state': [
195 ('end','_Cancel'),
196 ('create','_Add to payment order', '', True)
197 ]
198 },
199 },
200 'create': {
201 'actions': [],
202 'result': {
203 'type': 'action',
204 'action': create_payment,
205 'state': 'end'
206 }
207 },
208 }
209
210wizard_payment_order('account_payment.populate_payment')
211
212# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2130
=== modified file 'account_banking_fi_patu/__terp__.py'
--- account_banking_fi_patu/__terp__.py 2011-11-08 13:10:34 +0000
+++ account_banking_fi_patu/__terp__.py 2011-11-23 10:40:16 +0000
@@ -33,9 +33,8 @@
33 'category': 'Account Banking',33 'category': 'Account Banking',
34 'depends': ['account_banking'],34 'depends': ['account_banking'],
35 'description': '''35 'description': '''
36 Module to import Finnish PATU format transation files.36Do not install this module. This branch has been replaced by lp:banking-addons/6.0
3737See https://launchpad.net/banking-addons
38 This modules contains no logic, just an import filter for account_banking.
39 ''',38 ''',
40 'active': False,39 'active': False,
41 'installable': True,40 'installable': True,
4241
=== modified file 'account_banking_nl_abnamro/__openerp__.py'
--- account_banking_nl_abnamro/__openerp__.py 2011-04-26 21:00:12 +0000
+++ account_banking_nl_abnamro/__openerp__.py 2011-11-23 10:40:16 +0000
@@ -39,14 +39,8 @@
39 ],39 ],
40 'demo_xml': [],40 'demo_xml': [],
41 'description': '''41 'description': '''
42Import filter for abnamro (NL) bank transaction files (txt/tab format).42Do not install this module. This branch has been replaced by lp:banking-addons/6.0
4343See https://launchpad.net/banking-addons
44No formal specifications of the file layout are released by abnamro. You can
45help improve the performance of this import filter on
46https://launchpad.net/account-banking.
47
48Imported bank transfers are organized in statements covering periods of one week,
49even if the imported files cover a different period.
50 ''',44 ''',
51 'active': False,45 'active': False,
52 'installable': True,46 'installable': True,
5347
=== modified file 'account_banking_nl_abnamro/__terp__.py'
--- account_banking_nl_abnamro/__terp__.py 2011-11-08 13:10:34 +0000
+++ account_banking_nl_abnamro/__terp__.py 2011-11-23 10:40:16 +0000
@@ -39,14 +39,8 @@
39 ],39 ],
40 'demo_xml': [],40 'demo_xml': [],
41 'description': '''41 'description': '''
42Import filter for abnamro (NL) bank transaction files (txt/tab format).42Do not install this module. This branch has been replaced by lp:banking-addons/6.0
4343See https://launchpad.net/banking-addons
44No formal specifications of the file layout are released by abnamro. You can
45help improve the performance of this import filter on
46https://launchpad.net/account-banking.
47
48Imported bank transfers are organized in statements covering periods of one week,
49even if the imported files cover a different period.
50 ''',44 ''',
51 'active': False,45 'active': False,
52 'installable': True,46 'installable': True,
5347
=== modified file 'account_banking_nl_clieop/__terp__.py'
--- account_banking_nl_clieop/__terp__.py 2011-11-08 13:10:34 +0000
+++ account_banking_nl_clieop/__terp__.py 2011-11-23 10:40:16 +0000
@@ -25,7 +25,11 @@
25##############################################################################25##############################################################################
26{26{
27 'name': 'Account Banking NL ClieOp',27 'name': 'Account Banking NL ClieOp',
28<<<<<<< TREE
28 'version': '0.67',29 'version': '0.67',
30=======
31 'version': '0.63',
32>>>>>>> MERGE-SOURCE
29 'license': 'GPL-3',33 'license': 'GPL-3',
30 'author': 'EduSense BV',34 'author': 'EduSense BV',
31 'website': 'http://www.edusense.nl',35 'website': 'http://www.edusense.nl',
@@ -33,17 +37,15 @@
33 'depends': ['account_banking'],37 'depends': ['account_banking'],
34 'init_xml': [],38 'init_xml': [],
35 'update_xml': [39 'update_xml': [
36 #'security/ir.model.access.csv',
37 'account_banking_nl_clieop.xml',40 'account_banking_nl_clieop.xml',
38 'account_banking_export_wizard.xml',41 'wizard/export_clieop_view.xml',
39 'data/banking_export_clieop.xml',42 'data/banking_export_clieop.xml',
43 'security/ir.model.access.csv',
40 ],44 ],
41 'demo_xml': [],45 'demo_xml': [],
42 'description': '''46 'description': '''
43 Module to export payment orders in ClieOp format.47Do not install this module. This branch has been replaced by lp:banking-addons/6.0
4448See https://launchpad.net/banking-addons
45 ClieOp format is used by Dutch banks to batch national bank transfers.
46 This module uses the account_banking logic.
47 ''',49 ''',
48 'active': False,50 'active': False,
49 'installable': True,51 'installable': True,
5052
=== removed file 'account_banking_nl_clieop/account_banking_export_wizard.xml'
--- account_banking_nl_clieop/account_banking_export_wizard.xml 2010-01-26 20:55:24 +0000
+++ account_banking_nl_clieop/account_banking_export_wizard.xml 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!--
3 Copyright (C) EduSense BV <http://www.edusense.nl>
4 All rights reserved.
5 The licence is in the file __terp__.py
6-->
7<openerp>
8 <data>
9 <wizard id="wizard_account_banking_export_clieop"
10 string="Export ClieOp File"
11 model="payment.order"
12 name="account_banking_nl_clieop.banking_export_clieop"
13 />
14 </data>
15</openerp>
160
=== modified file 'account_banking_nl_clieop/account_banking_nl_clieop.py'
--- account_banking_nl_clieop/account_banking_nl_clieop.py 2010-01-26 20:55:24 +0000
+++ account_banking_nl_clieop/account_banking_nl_clieop.py 2011-11-23 10:40:16 +0000
@@ -22,25 +22,19 @@
22from datetime import date22from datetime import date
23from tools.translate import _23from tools.translate import _
2424
25class payment_order(osv.osv):
26 '''
27 Attach export_clieop wizard to payment order and allow traceability
28 '''
29 _inherit = 'payment.order'
30 def get_wizard(self, type):
31 if type in ['CLIEOPPAY', 'CLIEOPINC', 'CLIEOPSAL']:
32 return self._module, 'wizard_account_banking_export_clieop'
33 return super(payment_order, self).get_wizard(type)
34payment_order()
35
36class clieop_export(osv.osv):25class clieop_export(osv.osv):
37 '''ClieOp3 Export'''26 '''ClieOp3 Export'''
38 _name = 'banking.export.clieop'27 _name = 'banking.export.clieop'
39 _description = __doc__28 _description = __doc__
29 _rec_name = 'identification'
4030
41 _columns = {31 _columns = {
42 'payment_order_ids':32 'payment_order_ids': fields.many2many(
43 fields.text('Payment Orders'),33 'payment.order',
34 'account_payment_order_clieop_rel',
35 'banking_export_clieop_id', 'account_order_id',
36 'Payment Orders',
37 readonly=True),
44 'testcode':38 'testcode':
45 fields.selection([('T', _('Yes')), ('P', _('No'))],39 fields.selection([('T', _('Yes')), ('P', _('No'))],
46 'Test Run', readonly=True),40 'Test Run', readonly=True),
4741
=== modified file 'account_banking_nl_clieop/account_banking_nl_clieop.xml'
--- account_banking_nl_clieop/account_banking_nl_clieop.xml 2010-01-28 10:59:35 +0000
+++ account_banking_nl_clieop/account_banking_nl_clieop.xml 2011-11-23 10:40:16 +0000
@@ -14,19 +14,33 @@
14 <field name="type">form</field>14 <field name="type">form</field>
15 <field name="arch" type="xml">15 <field name="arch" type="xml">
16 <form string="Client Opdrachten Export">16 <form string="Client Opdrachten Export">
17 <separator string="General Information" colspan="4" />17 <notebook>
18 <field name="filetype" />18 <page string="General Information">
19 <field name="identification" />19 <field name="filetype" />
20 <separator string="ClieOp Information" colspan="4" />20 <field name="identification" />
21 <field name="total_amount" />21 <separator string="ClieOp Information" colspan="4" />
22 <field name="check_no_accounts" />22 <field name="total_amount" />
23 <field name="no_transactions" />23 <field name="check_no_accounts" />
24 <separator string="Processing Information" colspan="4" />24 <field name="no_transactions" />
25 <field name="prefered_date" />25 <separator string="Processing Information" colspan="4" />
26 <field name="date_generated" />26 <field name="prefered_date" />
27 <field name="testcode" />27 <field name="date_generated" />
28 <newline />28 <field name="testcode" />
29 <field name="file" colspan="4" />29 <newline />
30 <field name="file" colspan="4" />
31 </page>
32 <page string="Payment Orders">
33 <field name="payment_order_ids" colspan="4" nolabel="1">
34 <tree colors="blue:state in ('draft');gray:state in ('cancel','done');black:state in ('open')" string="Payment order">
35 <field name="reference"/>
36 <field name="date_created"/>
37 <field name="date_done"/>
38 <field name="total"/>
39 <field name="state"/>
40 </tree>
41 </field>
42 </page>
43 </notebook>
30 </form>44 </form>
31 </field>45 </field>
32 </record>46 </record>
@@ -59,5 +73,14 @@
59 sequence="12"73 sequence="12"
60 />74 />
6175
76 <!-- Create right menu entry to see generated files -->
77 <act_window name="Generated ClieOp3 Files"
78 domain="[('payment_order_ids', '=', active_id)]"
79 res_model="banking.export.clieop"
80 src_model="payment.order"
81 view_type="form"
82 view_mode="tree,form"
83 id="act_banking_export_clieop_payment_order"/>
84
62 </data>85 </data>
63</openerp>86</openerp>
6487
=== modified file 'account_banking_nl_clieop/data/banking_export_clieop.xml'
--- account_banking_nl_clieop/data/banking_export_clieop.xml 2010-12-20 10:58:51 +0000
+++ account_banking_nl_clieop/data/banking_export_clieop.xml 2011-11-23 10:40:16 +0000
@@ -1,25 +1,31 @@
1<?xml version="1.0" encoding="utf-8"?>1<?xml version="1.0" encoding="utf-8"?>
2<openerp>2<openerp>
3 <data noupdate="1">3 <data noupdate="1">
4 <record model="payment.type" id="account_banking_nl_clieop.export_clieop_inc">4 <record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_inc">
5 <field name="name">ClieOp3 Direct Debit Batch</field>5 <field name="name">ClieOp3 Direct Debit Batch</field>
6 <field name="code">CLIEOPINC</field>6 <field name="code">CLIEOPINC</field>
7 <field name="suitable_bank_types"7 <field name="suitable_bank_types"
8 eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />8 eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
9 <field name="ir_model_id"
10 ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
9 </record>11 </record>
1012
11 <record model="payment.type" id="account_banking_nl_clieop.export_clieop_pay">13 <record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_pay">
12 <field name="name">ClieOp3 Payment Batch</field>14 <field name="name">ClieOp3 Payment Batch</field>
13 <field name="code">CLIEOPPAY</field>15 <field name="code">CLIEOPPAY</field>
14 <field name="suitable_bank_types"16 <field name="suitable_bank_types"
15 eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />17 eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
18 <field name="ir_model_id"
19 ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
16 </record>20 </record>
1721
18 <record model="payment.type" id="account_banking_nl_clieop.export_clieop_sal">22 <record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_sal">
19 <field name="name">ClieOp3 Salary Payment Batch</field>23 <field name="name">ClieOp3 Salary Payment Batch</field>
20 <field name="code">CLIEOPSAL</field>24 <field name="code">CLIEOPSAL</field>
21 <field name="suitable_bank_types"25 <field name="suitable_bank_types"
22 eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />26 eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
27 <field name="ir_model_id"
28 ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
23 </record>29 </record>
24 </data>30 </data>
25</openerp>31</openerp>
2632
=== added directory 'account_banking_nl_clieop/migrations'
=== added directory 'account_banking_nl_clieop/migrations/0.63'
=== added file 'account_banking_nl_clieop/migrations/0.63/post-fill-ir_model_id.py'
--- account_banking_nl_clieop/migrations/0.63/post-fill-ir_model_id.py 1970-01-01 00:00:00 +0000
+++ account_banking_nl_clieop/migrations/0.63/post-fill-ir_model_id.py 2011-11-23 10:40:16 +0000
@@ -0,0 +1,44 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (C) 2011 Therp BV (<http://therp.nl>)
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19##############################################################################
20
21""" This script covers the migration of the payment wizards from old style to
22new style (osv_memory). It guarantees an easy upgrade for early adopters
23of the 6.0 branch of this OpenERP module. Note that a migration from OpenERP
245.0 to OpenERP 6.0 with respect to this module is not covered by this script.
25"""
26
27__name__ = "payment.mode.type:: Add new style payment wizards to existing payment mode types"
28
29def migrate(cr, version):
30 cr.execute ("UPDATE payment_mode_type"
31 " SET ir_model_id = data1.res_id"
32 " FROM ir_model_data data1,"
33 " ir_model_data data2"
34 " WHERE data2.res_id = payment_mode_type.id"
35 " AND data1.module = 'account_banking_nl_clieop'"
36 " AND data1.model = 'ir.model'"
37 " AND data1.name = 'model_banking_export_clieop_wizard'"
38 " AND data2.module = 'account_banking_nl_clieop'"
39 " AND data2.model = 'payment.mode.type'"
40 " AND data2.name IN ('export_clieop_inc',"
41 " 'export_clieop_pay',"
42 " 'export_clieop_sal'"
43 " )"
44 )
045
=== added directory 'account_banking_nl_clieop/security'
=== added file 'account_banking_nl_clieop/security/ir.model.access.csv'
--- account_banking_nl_clieop/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
+++ account_banking_nl_clieop/security/ir.model.access.csv 2011-11-23 10:40:16 +0000
@@ -0,0 +1,2 @@
1"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
2"access_banking_export_clieop","banking.export.clieop","model_banking_export_clieop","account_payment.group_account_payment",1,1,1,1
03
=== modified file 'account_banking_nl_clieop/wizard/clieop.py'
--- account_banking_nl_clieop/wizard/clieop.py 2011-03-10 15:25:05 +0000
+++ account_banking_nl_clieop/wizard/clieop.py 2011-11-23 10:40:16 +0000
@@ -76,7 +76,7 @@
7676
77 def __init__(self, id='1', seqno=1, duplicate=False):77 def __init__(self, id='1', seqno=1, duplicate=False):
78 super(HeaderRecord, self).__init__()78 super(HeaderRecord, self).__init__()
79 self.sender_id = id79 self.sender_id = id or ''
80 self.file_id = '%02d%02d' % (self.creation_date.day, seqno)80 self.file_id = '%02d%02d' % (self.creation_date.day, seqno)
81 self.duplicatecode = duplicate and '2' or '1'81 self.duplicatecode = duplicate and '2' or '1'
82#}}}82#}}}
@@ -362,7 +362,7 @@
362 self.header.variantcode = batch_id and 'C' or 'B'362 self.header.variantcode = batch_id and 'C' or 'B'
363 self.header.transactiongroup = transactiongroup363 self.header.transactiongroup = transactiongroup
364 self.header.batch_tracer = batch_tracer364 self.header.batch_tracer = batch_tracer
365 self.header.batch_id = batch_id365 self.header.batch_id = batch_id or ''
366 self.header.accountno_sender = rekeningnr366 self.header.accountno_sender = rekeningnr
367 self.sender.name_sender = sender367 self.sender.name_sender = sender
368 self.sender.preferred_execution_date = execution_date368 self.sender.preferred_execution_date = execution_date
369369
=== modified file 'account_banking_nl_clieop/wizard/export_clieop.py'
--- account_banking_nl_clieop/wizard/export_clieop.py 2011-02-12 13:37:09 +0000
+++ account_banking_nl_clieop/wizard/export_clieop.py 2011-11-23 10:40:16 +0000
@@ -19,12 +19,11 @@
19#19#
20##############################################################################20##############################################################################
2121
22import wizard
23import pooler
24import base6422import base64
25from datetime import datetime, date, timedelta23from datetime import datetime, date, timedelta
24from osv import osv, fields
25from tools.translate import _
26from account_banking import sepa26from account_banking import sepa
27from tools.translate import _
28import clieop27import clieop
2928
30def strpdate(arg, format='%Y-%m-%d'):29def strpdate(arg, format='%Y-%m-%d'):
@@ -35,151 +34,131 @@
35 '''shortcut'''34 '''shortcut'''
36 return arg.strftime(format)35 return arg.strftime(format)
3736
38class wizard_banking_export_clieop(wizard.interface):37class banking_export_clieop_wizard(osv.osv_memory):
39 form = '''<?xml version="1.0"?>38 _name = 'banking.export.clieop.wizard'
40<form string="Client Opdrachten Export">39 _description = 'Client Opdrachten Export'
41 <separator colspan="4" string="Processing Details" />40 _columns = {
42 <field name="batchtype" />41 'state': fields.selection(
43 <field name="execution_date" />42 [
44 <field name="test" />43 ('create', 'Create'),
45 <separator colspan="4" string="Reference for further communication" />44 ('finish', 'Finish')
46 <field name="reference" colspan="2" />45 ],
47 <separator colspan="4" string="Additional message for all transactions" />46 'State',
48 <field name="fixed_message" />47 readonly=True,
49</form>'''48 ),
5049 'reference': fields.char(
51 fields = {50 'Reference', size=5,
52 'reference' : {51 help=('The bank will use this reference in feedback communication '
53 'string': 'Reference',52 'to refer to this run. Only five characters are available.'
54 'type': 'char',53 ),
55 'size': 5,54 ),
56 'required': False,55 'batchtype': fields.selection(
57 'help': ('The bank will use this reference in feedback communication '56 [
58 'to refer to this run. Only five characters are available.'
59 )
60 },
61 'batchtype': {
62 'string': 'Type',
63 'type': 'selection',
64 'selection': [
65 ('CLIEOPPAY', 'Payments'),57 ('CLIEOPPAY', 'Payments'),
66 ('CLIEOPSAL', 'Salary Payments'),58 ('CLIEOPSAL', 'Salary Payments'),
67 ('CLIEOPINC', 'Direct Debits'),59 ('CLIEOPINC', 'Direct Debits'),
68 ],60 ], 'Type', readonly=True,
69 'readonly': True,61 ),
70 },62 'execution_date': fields.date(
71 'execution_date': {63 'Execution Date',
72 'string': 'Execution Date',64 help=('This is the date the file should be processed by the bank. '
73 'type': 'date',65 'Don\'t choose a date beyond the nearest date in your '
74 'required': False,66 'payments. The latest allowed date is 30 days from now.\n'
75 'help': ('This is the date the file should be processed by the bank. '67 'Please keep in mind that banks only execute on working days '
76 'Don\'t choose a date beyond the nearest date in your '68 'and typically use a delay of two days between execution date '
77 'payments. The latest allowed date is 30 days from now.\n'69 'and effective transfer date.'
78 'Please keep in mind that banks only execute on working days '70 ),
79 'and typically use a delay of two days between execution date '71 ),
80 'and effective transfer date.'72 'test': fields.boolean(
81 ),73 'Test Run',
82 },74 help=('Select this if you want your bank to run a test process '
83 'test': {75 'rather then execute your orders for real.'
84 'string': 'Test Run',76 ),
85 'type': 'boolean',77 ),
86 'required': True,78 'fixed_message': fields.char(
87 'default': True,79 'Fixed Message', size=32,
88 'help': ('Select this if you want your bank to run a test process '80 help=('A fixed message to apply to all transactions in addition to '
89 'rather then execute your orders for real.'81 'the individual messages.'
90 )82 ),
91 },83 ),
92 'fixed_message': {84 # file fields
93 'string': 'Fixed Message',85 'file_id': fields.many2one(
94 'type': 'char',86 'banking.export.clieop',
95 'size': 32,87 'ClieOp File',
96 'required': False,88 readonly=True
97 'default': '',89 ),
98 'help': ('A fixed message to apply to all transactions in addition to '90 # fields.related does not seem to support
99 'the individual messages.'91 # fields of type selection
100 ),92 'testcode': fields.selection(
101 },93 [('T', _('Yes')), ('P', _('No'))],
102 }94 'Test Run', readonly=True,
10395 ),
104 file_form = '''<?xml version="1.0"?>96 'filetype': fields.selection(
105<form string="Client Opdrachten Export">97 [
106 <field name="filetype" />
107 <field name="identification" />
108 <field name="total_amount" />
109 <field name="check_no_accounts" />
110 <field name="no_transactions" />
111 <field name="prefered_date" />
112 <field name="testcode" />
113 <newline/>
114 <field name="file" />
115 <field name="log" colspan="4" nolabel="1" />
116</form>'''
117
118 file_fields = {
119 'testcode': {
120 'string': 'Test Run',
121 'type': 'selection',
122 'selection': [('T', _('Yes')), ('P', _('No'))],
123 'required': False,
124 'readonly': True,
125 },
126 'prefered_date': {
127 'string': 'Prefered Processing Date',
128 'type': 'date',
129 'required': False,
130 'readonly': True,
131 },
132 'no_transactions': {
133 'string': 'Number of Transactions',
134 'type': 'int',
135 'required': False,
136 'readonly': True,
137 },
138 'check_no_accounts': {
139 'string': 'Check Number Accounts',
140 'type': 'char',
141 'size': 5,
142 'required': False,
143 'readonly': True,
144 },
145 'total_amount': {
146 'string': 'Total Amount',
147 'type': 'float',
148 'required': False,
149 'readonly': True,
150 },
151 'identification': {
152 'string': 'Identification',
153 'type': 'char',
154 'size': 6,
155 'required': False,
156 'readonly': True,
157 },
158 'filetype': {
159 'string': 'File Type',
160 'type': 'selection',
161 'selection': [
162 ('CREDBET', 'Payment Batch'),98 ('CREDBET', 'Payment Batch'),
163 ('SALARIS', 'Salary Payment Batch'),99 ('SALARIS', 'Salary Payment Batch'),
164 ('INCASSO', 'Direct Debit Batch'),100 ('INCASSO', 'Direct Debit Batch'),
165 ],101 ],
166 'required': False,102 'File Type',
167 'readonly': True,103 readonly=True,
168 },104 ),
169 'file': {105 'prefered_date': fields.related(
170 'string': 'ClieOp File',106 'file_id', 'prefered_date',
171 'type': 'binary',107 type='date',
172 'required': False,108 string='Prefered Processing Date',
173 'readonly': True,109 readonly=True,
174 },110 ),
175 'log': {111 'no_transactions': fields.related(
176 'string': 'Log',112 'file_id', 'no_transactions',
177 'type': 'text',113 type ='integer',
178 'readonly': True,114 string='Number of Transactions',
179 },115 readonly=True,
180 }116 ),
181117 'check_no_accounts': fields.related(
182 def _check_orders(self, cursor, uid, data, context):118 'file_id', 'check_no_accounts',
119 type='char', size=5,
120 string='Check Number Accounts',
121 readonly=True,
122 ),
123 'total_amount': fields.related(
124 'file_id', 'total_amount',
125 type='float',
126 string='Total Amount',
127 readonly=True,
128 ),
129 'identification': fields.related(
130 'file_id', 'identification',
131 type='char', size=6,
132 string='Identification',
133 readonly=True,
134 ),
135 'file': fields.related(
136 'file_id', 'file', type='binary',
137 readonly=True,
138 string='File',
139 ),
140 'payment_order_ids': fields.many2many(
141 'payment.order', 'rel_wiz_payorders', 'wizard_id',
142 'payment_order_id', 'Payment Orders',
143 readonly=True,
144 ),
145 }
146
147 _defaults = {
148 'test': True,
149 }
150
151 def create(self, cursor, uid, vals, context=None):
152 '''
153 Retrieve a sane set of default values based on the payment orders
154 from the context.
155 '''
156 if 'batchtype' not in vals:
157 self.check_orders(cursor, uid, vals, context)
158 return super(banking_export_clieop_wizard, self).create(
159 cursor, uid, vals, context)
160
161 def check_orders(self, cursor, uid, vals, context):
183 '''162 '''
184 Check payment type for all orders.163 Check payment type for all orders.
185164
@@ -191,14 +170,14 @@
191 Also mind that rates for batches are way higher than those for170 Also mind that rates for batches are way higher than those for
192 transactions. It pays to limit the number of batches.171 transactions. It pays to limit the number of batches.
193 '''172 '''
194 form = data['form']
195 today = date.today()173 today = date.today()
196 pool = pooler.get_pool(cursor.dbname)174 payment_order_obj = self.pool.get('payment.order')
197 payment_order_obj = pool.get('payment.order')
198175
176 # Payment order ids are provided in the context
177 payment_order_ids = context.get('active_ids', [])
199 runs = {}178 runs = {}
200 # Only orders of same type can be combined179 # Only orders of same type can be combined
201 payment_orders = payment_order_obj.browse(cursor, uid, data['ids'])180 payment_orders = payment_order_obj.browse(cursor, uid, payment_order_ids)
202 for payment_order in payment_orders:181 for payment_order in payment_orders:
203182
204 payment_type = payment_order.mode.type.code183 payment_type = payment_order.mode.type.code
@@ -226,34 +205,33 @@
226 else:205 else:
227 execution_date = today206 execution_date = today
228 if execution_date and execution_date >= max_date:207 if execution_date and execution_date >= max_date:
229 raise wizard.except_wizard(208 raise osv.except_osv(
230 _('Error'),209 _('Error'),
231 _('You can\'t create ClieOp orders more than 30 days in advance.')210 _('You can\'t create ClieOp orders more than 30 days in advance.')
232 )211 )
233 # Sanity check: can't process in the past
234 form['execution_date'] = strfdate(max(execution_date, today))
235
236 if len(runs) != 1:212 if len(runs) != 1:
237 raise wizard.except_wizard(213 raise osv.except_osv(
238 _('Error'),214 _('Error'),
239 _('You can only combine payment orders of the same type')215 _('You can only combine payment orders of the same type')
240 )216 )
241217
242 form['batchtype'] = type = runs.keys()[0]218 type = runs.keys()[0]
243 form['reference'] = runs[type][0].reference[-5:]219 vals.update({
244 return form220 'execution_date': strfdate(max(execution_date, today)),
221 'batchtype': type,
222 'reference': runs[type][0].reference[-5:],
223 'payment_order_ids': [[6, 0, payment_order_ids]],
224 'state': 'create',
225 })
245226
246 def _create_clieop(self, cursor, uid, data, context):227 def create_clieop(self, cursor, uid, ids, context):
247 '''228 '''
248 Wizard to actually create the ClieOp3 file229 Wizard to actually create the ClieOp3 file
249 '''230 '''
250 pool = pooler.get_pool(cursor.dbname)231 payment_order_obj = self.pool.get('payment.order')
251 payment_order_obj = pool.get('payment.order')232 clieop_export = self.browse(cursor, uid, ids, context)[0]
252 form = data['form']
253
254 clieopfile = None233 clieopfile = None
255 payment_orders = payment_order_obj.browse(cursor, uid, data['ids'])234 for payment_order in clieop_export.payment_order_ids:
256 for payment_order in payment_orders:
257 if not clieopfile:235 if not clieopfile:
258 # Just once: create clieop file236 # Just once: create clieop file
259 our_account_owner = payment_order.mode.bank_id.owner_name \237 our_account_owner = payment_order.mode.bank_id.owner_name \
@@ -264,19 +242,19 @@
264 payment_order.mode.bank_id.iban242 payment_order.mode.bank_id.iban
265 ).localized_BBAN243 ).localized_BBAN
266 if not our_account_nr:244 if not our_account_nr:
267 raise wizard.except_wizard(245 raise osv.except_osv(
268 _('Error'),246 _('Error'),
269 _('Your bank account has to have a valid account number')247 _('Your bank account has to have a valid account number')
270 )248 )
271 clieopfile = {'CLIEOPPAY': clieop.PaymentsFile,249 clieopfile = {'CLIEOPPAY': clieop.PaymentsFile,
272 'CLIEOPINC': clieop.DirectDebitFile,250 'CLIEOPINC': clieop.DirectDebitFile,
273 'CLIEOPSAL': clieop.SalaryPaymentsFile,251 'CLIEOPSAL': clieop.SalaryPaymentsFile,
274 }[form['batchtype']](252 }[clieop_export['batchtype']](
275 identification = form['reference'],253 identification = clieop_export['reference'],
276 execution_date = form['execution_date'],254 execution_date = clieop_export['execution_date'],
277 name_sender = our_account_owner,255 name_sender = our_account_owner,
278 accountno_sender = our_account_nr,256 accountno_sender = our_account_nr,
279 test = form['test']257 test = clieop_export['test']
280 )258 )
281259
282 # ClieOp3 files can contain multiple batches, but we put all260 # ClieOp3 files can contain multiple batches, but we put all
@@ -285,21 +263,21 @@
285 # cheaper to combine than it is to split. As we split out all263 # cheaper to combine than it is to split. As we split out all
286 # reported errors afterwards, there is no additional gain in264 # reported errors afterwards, there is no additional gain in
287 # using multiple batches.265 # using multiple batches.
288 if form['fixed_message']:266 if clieop_export['fixed_message']:
289 messages = [form['fixed_message']]267 messages = [clieop_export['fixed_message']]
290 else:268 else:
291 messages = []269 messages = []
292 # The first payment order processed sets the reference of the270 # The first payment order processed sets the reference of the
293 # batch.271 # batch.
294 batch = clieopfile.batch(272 batch = clieopfile.batch(
295 messages = messages,273 messages = messages,
296 batch_id = payment_order.reference274 batch_id = clieop_export['reference']
297 )275 )
298276
299 for line in payment_order.line_ids:277 for line in payment_order.line_ids:
300 # Check on missing partner of bank account (this can happen!)278 # Check on missing partner of bank account (this can happen!)
301 if not line.bank_id or not line.bank_id.partner_id:279 if not line.bank_id or not line.bank_id.partner_id:
302 raise wizard.except_wizard(280 raise osv.except_osv(
303 _('Error'),281 _('Error'),
304 _('There is insufficient information.\r\n'282 _('There is insufficient information.\r\n'
305 'Both destination address and account '283 'Both destination address and account '
@@ -318,13 +296,13 @@
318 # Is this an IBAN account?296 # Is this an IBAN account?
319 if iban.valid:297 if iban.valid:
320 if iban.countrycode != 'NL':298 if iban.countrycode != 'NL':
321 raise wizard.except_wizard(299 raise osv.except_osv(
322 _('Error'),300 _('Error'),
323 _('You cannot send international bank transfers '301 _('You cannot send international bank transfers '
324 'through ClieOp3!')302 'through ClieOp3!')
325 )303 )
326 other_account_nr = iban.localized_BBAN304 other_account_nr = iban.localized_BBAN
327 if form['batchtype'] == 'CLIEOPINC':305 if clieop_export['batchtype'] == 'CLIEOPINC':
328 kwargs['accountno_beneficiary'] = our_account_nr306 kwargs['accountno_beneficiary'] = our_account_nr
329 kwargs['accountno_payer'] = other_account_nr307 kwargs['accountno_payer'] = other_account_nr
330 else:308 else:
@@ -334,86 +312,63 @@
334312
335 # Generate the specifics of this clieopfile313 # Generate the specifics of this clieopfile
336 order = clieopfile.order314 order = clieopfile.order
337 values = dict(315 file_id = self.pool.get('banking.export.clieop').create(
338 filetype = order.name_transactioncode,316 cursor, uid, dict(
339 identification = order.identification,317 filetype = order.name_transactioncode,
340 prefered_date = strfdate(order.preferred_execution_date),318 identification = order.identification,
341 total_amount = int(order.total_amount) / 100.0,319 prefered_date = strfdate(order.preferred_execution_date),
342 check_no_accounts = order.total_accountnos,320 total_amount = int(order.total_amount) / 100.0,
343 no_transactions = order.nr_posts,321 check_no_accounts = order.total_accountnos,
344 testcode = order.testcode,322 no_transactions = order.nr_posts,
345 file = base64.encodestring(clieopfile.rawdata),323 testcode = order.testcode,
346 )324 file = base64.encodestring(clieopfile.rawdata),
347 form.update(values)325 daynumber = int(clieopfile.header.file_id[2:]),
348 values['daynumber'] = int(clieopfile.header.file_id[2:])326 payment_order_ids = [
349 values['payment_order_ids'] = ','.join(map(str, data['ids']))327 [6, 0, [x.id for x in clieop_export['payment_order_ids']]]
350 data['file_id'] = pool.get('banking.export.clieop').create(cursor, uid, values)328 ],
351 data['clieop'] = clieopfile329 ), context)
352 form['log'] = ''330 self.write(cursor, uid, [ids[0]], dict(
353 return form331 filetype = order.name_transactioncode,
332 testcode = order.testcode,
333 file_id = file_id,
334 state = 'finish',
335 ), context)
336 return {
337 'name': _('Client Opdrachten Export'),
338 'view_type': 'form',
339 'view_mode': 'form',
340 'res_model': self._name,
341 'domain': [],
342 'context': dict(context, active_ids=ids),
343 'type': 'ir.actions.act_window',
344 'target': 'new',
345 'res_id': ids[0] or False,
346 }
354347
355 def _cancel_clieop(self, cursor, uid, data, context):348 def cancel_clieop(self, cursor, uid, ids, context):
356 '''349 '''
357 Cancel the ClieOp: just drop the file350 Cancel the ClieOp: just drop the file
358 '''351 '''
359 pool = pooler.get_pool(cursor.dbname)352 clieop_export = self.read(cursor, uid, ids, ['file_id'], context)[0]
360 pool.get('banking.export.clieop').unlink(cursor, uid, data['file_id'])353 self.pool.get('banking.export.clieop').unlink(cursor, uid, clieop_export['file_id'])
361 return {'state': 'end'}354 return {'type': 'ir.actions.act_window_close'}
362355
363 def _save_clieop(self, cursor, uid, data, context):356 def save_clieop(self, cursor, uid, ids, context):
364 '''357 '''
365 Save the ClieOp: mark all payments in the file as 'sent'.358 Save the ClieOp: mark all payments in the file as 'sent', if not a test
366 '''359 '''
367 pool = pooler.get_pool(cursor.dbname)360 clieop_export = self.browse(
368 clieop_obj = pool.get('banking.export.clieop')361 cursor, uid, ids, context)[0]
369 payment_order_obj = pool.get('payment.order')362 if not clieop_export['test']:
370 clieop_file = clieop_obj.write(363 clieop_obj = self.pool.get('banking.export.clieop')
371 cursor, uid, data['file_id'], {'state':'sent'}364 payment_order_obj = self.pool.get('payment.order')
372 )365 clieop_file = clieop_obj.write(
373 payment_order_obj.write(cursor, uid, data['ids'], {'state': 'sent'})366 cursor, uid, clieop_export['file_id'].id, {'state':'sent'}
374 return {'state': 'end'}367 )
375368 payment_order_obj.action_sent(
376 states = {369 cursor, uid, [x.id for x in clieop_export['payment_order_ids']])
377 'init': {370 return {'type': 'ir.actions.act_window_close'}
378 'actions': [_check_orders],371
379 'result': {372banking_export_clieop_wizard()
380 'type': 'form',
381 'arch': form,
382 'fields' : fields,
383 'state': [
384 ('end', 'Cancel', 'gtk-cancel'),
385 ('create', 'Create', 'gtk-ok'),
386 ]
387 }
388 },
389 'create': {
390 'actions': [_create_clieop],
391 'result': {
392 'type': 'form',
393 'arch': file_form,
394 'fields': file_fields,
395 'state': [
396 ('cancel', 'Cancel', 'gtk-cancel'),
397 ('save', 'Save', 'gtk-save'),
398 ]
399 },
400 },
401 'cancel': {
402 'actions': [_cancel_clieop],
403 'result': {
404 'type': 'state',
405 'state': 'end'
406 }
407 },
408 'save': {
409 'actions': [_save_clieop],
410 'result': {
411 'type': 'state',
412 'state': 'end'
413 },
414 }
415 }
416
417wizard_banking_export_clieop('account_banking_nl_clieop.banking_export_clieop')
418373
419# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:374# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
420375
=== added file 'account_banking_nl_clieop/wizard/export_clieop_view.xml'
--- account_banking_nl_clieop/wizard/export_clieop_view.xml 1970-01-01 00:00:00 +0000
+++ account_banking_nl_clieop/wizard/export_clieop_view.xml 2011-11-23 10:40:16 +0000
@@ -0,0 +1,58 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="banking_export_clieop_wizard_view" model="ir.ui.view">
5 <field name="name">banking.export.clieop.wizard.view</field>
6 <field name="model">banking.export.clieop.wizard</field>
7 <field name="type">form</field>
8 <field name="arch" type="xml">
9 <form string="Client Opdrachten Export">
10 <field name="state" invisible="True"/>
11 <group states="create">
12 <separator colspan="4" string="Processing Details" />
13 <field name="batchtype" />
14 <field name="execution_date" />
15 <field name="test" />
16 <separator colspan="4" string="Reference for further communication" />
17 <field name="reference" colspan="2" />
18 <separator colspan="4" string="Additional message for all transactions" />
19 <field name="fixed_message" />
20 <newline/>
21 <button icon="gtk-close"
22 special="cancel"
23 string="Cancel"
24 />
25 <button icon="gtk-ok"
26 string="Create"
27 name="create_clieop"
28 type="object"
29 />
30 </group>
31 <group states="finish">
32 <field name="filetype" />
33 <field name="identification" />
34 <field name="total_amount" />
35 <field name="check_no_accounts" />
36 <field name="no_transactions" />
37 <field name="prefered_date" />
38 <field name="testcode" />
39 <newline/>
40 <field name="file_id" />
41 <field name="file" />
42 <newline/>
43 <button icon="gtk-close"
44 string="Cancel"
45 name="cancel_clieop"
46 type="object"
47 />
48 <button icon="gtk-ok"
49 string="Finish"
50 name="save_clieop"
51 type="object"
52 />
53 </group>
54 </form>
55 </field>
56 </record>
57 </data>
58</openerp>
059
=== modified file 'account_banking_nl_girotel/__terp__.py'
--- account_banking_nl_girotel/__terp__.py 2011-11-08 13:10:34 +0000
+++ account_banking_nl_girotel/__terp__.py 2011-11-23 10:40:16 +0000
@@ -37,9 +37,8 @@
37 ],37 ],
38 'demo_xml': [],38 'demo_xml': [],
39 'description': '''39 'description': '''
40 Module to import Dutch Girotel format transation files.40Do not install this module. This branch has been replaced by lp:banking-addons/6.0
4141See https://launchpad.net/banking-addons
42 This modules contains no logic, just an import filter for account_banking.
43 ''',42 ''',
44 'active': False,43 'active': False,
45 'installable': True,44 'installable': True,
4645
=== modified file 'account_banking_nl_multibank/__terp__.py'
--- account_banking_nl_multibank/__terp__.py 2011-11-08 13:10:34 +0000
+++ account_banking_nl_multibank/__terp__.py 2011-11-23 10:40:16 +0000
@@ -37,9 +37,8 @@
37 ],37 ],
38 'demo_xml': [],38 'demo_xml': [],
39 'description': '''39 'description': '''
40 Module to import Dutch Multibank format transation files.40Do not install this module. This branch has been replaced by lp:banking-addons/6.0
4141See https://launchpad.net/banking-addons
42 This modules contains no logic, just an import filter for account_banking.
43 ''',42 ''',
44 'active': False,43 'active': False,
45 'installable': True,44 'installable': True,
4645
=== modified file 'account_banking_nl_triodos/__openerp__.py'
--- account_banking_nl_triodos/__openerp__.py 2011-04-26 21:00:12 +0000
+++ account_banking_nl_triodos/__openerp__.py 2011-11-23 10:40:16 +0000
@@ -39,19 +39,8 @@
39 ],39 ],
40 'demo_xml': [],40 'demo_xml': [],
41 'description': '''41 'description': '''
42Module to import Dutch Triodos bank format transation files (CSV format).42Do not install this module. This branch has been replaced by lp:banking-addons/6.0
4343See https://launchpad.net/banking-addons
44As the Triodos bank does not provide detailed specification concerning possible
45values and their meaning for the fields in the CSV file format, the statements
46are parsed according to an educated guess based on incomplete information.
47You can contact the account-banking developers through their launchpad page and
48help improve the performance of this import filter on
49https://launchpad.net/account-banking.
50
51Note that imported bank transfers are organized in statements covering periods
52of one week, even if the imported files cover a different period.
53
54This modules contains no logic, just an import filter for account_banking.
55 ''',44 ''',
56 'active': False,45 'active': False,
57 'installable': True,46 'installable': True,
5847
=== modified file 'account_banking_nl_triodos/__terp__.py'
--- account_banking_nl_triodos/__terp__.py 2011-11-08 13:10:34 +0000
+++ account_banking_nl_triodos/__terp__.py 2011-11-23 10:40:16 +0000
@@ -39,19 +39,8 @@
39 ],39 ],
40 'demo_xml': [],40 'demo_xml': [],
41 'description': '''41 'description': '''
42Module to import Dutch Triodos bank format transation files (CSV format).42Do not install this module. This branch has been replaced by lp:banking-addons/6.0
4343See https://launchpad.net/banking-addons
44As the Triodos bank does not provide detailed specification concerning possible
45values and their meaning for the fields in the CSV file format, the statements
46are parsed according to an educated guess based on incomplete information.
47You can contact the account-banking developers through their launchpad page and
48help improve the performance of this import filter on
49https://launchpad.net/account-banking.
50
51Note that imported bank transfers are organized in statements covering periods
52of one week, even if the imported files cover a different period.
53
54This modules contains no logic, just an import filter for account_banking.
55 ''',44 ''',
56 'active': False,45 'active': False,
57 'installable': True,46 'installable': True,
5847
=== modified file 'account_banking_nl_triodos/triodos.py'
--- account_banking_nl_triodos/triodos.py 2011-04-27 10:16:40 +0000
+++ account_banking_nl_triodos/triodos.py 2011-11-23 10:40:16 +0000
@@ -68,6 +68,9 @@
68 # Set statement_id based on week number68 # Set statement_id based on week number
69 self.statement_id = self.effective_date.strftime('%Yw%W')69 self.statement_id = self.effective_date.strftime('%Yw%W')
70 self.id = str(subno).zfill(4)70 self.id = str(subno).zfill(4)
71 # Normalize basic account numbers
72 self.remote_account = self.remote_account.replace('.', '').zfill(10)
73 self.local_account = self.local_account.replace('.', '').zfill(10)
7174
72class transaction(models.mem_bank_transaction):75class transaction(models.mem_bank_transaction):
73 '''76 '''