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
1=== added file 'THIS_BRANCH_IS_DEPRECATED.txt'
2--- THIS_BRANCH_IS_DEPRECATED.txt 1970-01-01 00:00:00 +0000
3+++ THIS_BRANCH_IS_DEPRECATED.txt 2011-11-23 10:40:16 +0000
4@@ -0,0 +1,3 @@
5+This branch has been replaced by lp:banking-addons/6.0
6+
7+See https://launchpad.net/banking-addons
8
9=== modified file 'account_banking/__terp__.py'
10--- account_banking/__terp__.py 2011-11-08 13:10:34 +0000
11+++ account_banking/__terp__.py 2011-11-23 10:40:16 +0000
12@@ -35,66 +35,14 @@
13 'update_xml': [
14 'security/ir.model.access.csv',
15 'data/account_banking_data.xml',
16- 'account_banking_import_wizard.xml',
17- 'account_banking_payment_wizard.xml',
18+ 'wizard/bank_import_view.xml',
19 'account_banking_view.xml',
20 'account_banking_workflow.xml',
21 ],
22 'demo_xml': [],
23 'description': '''
24- Module to do banking.
25-
26- Note: This module is depending on BeautifulSoup.
27-
28- This modules tries to combine all current banking import and export
29- schemes. Rationale for this is that it is quite common to have foreign
30- bank account numbers next to national bank account numbers. The current
31- approach, which hides the national banking interface schemes in the
32- l10n_xxx modules, makes it very difficult to use these simultanious.
33- A more banking oriented approach seems more logical and cleaner.
34-
35- Changes to default OpenERP:
36-
37- * Puts focus on the real life messaging with banks:
38- + Bank statement lines upgraded to independent bank transactions.
39- + Banking statements have no special accountancy meaning, they're just
40- message envelopes for a number of bank transactions.
41- + Bank statements can be either encoded by hand to reflect the document
42- version of Bank Statements, or created as an optional side effect of
43- importing Bank Transactions.
44-
45- * Preparations for SEPA:
46- + IBAN accounts are the standard in the SEPA countries
47- + local accounts are derived from SEPA (excluding Turkey) but are
48- considered to be identical to the corresponding SEPA account.
49- + Banks are identified with either Country + Bank code + Branch code or BIC
50- + Each bank can have its own pace in introducing SEPA into their
51- communication with their customers.
52- + National online databases can be used to convert BBAN's to IBAN's.
53- + The SWIFT database is consulted for bank information.
54-
55- * Adds dropin extensible import facility for bank communication in:
56- - Drop-in input parser development.
57- - MultiBank (NL) format transaction files available as
58- account_banking_nl_multibank,
59-
60- * Extends payments for digital banking:
61- + Adapted workflow in payments to reflect banking operations
62- + Relies on account_payment mechanics to extend with export generators.
63- - ClieOp3 (NL) payment and direct debit orders files available as
64- account_banking_nl_clieop
65-
66- * Additional features for the import/export mechanism:
67- + Automatic matching and creation of bank accounts, banks and partners,
68- during import of statements.
69- + Automatic matching with invoices and payments.
70- + Sound import mechanism, allowing multiple imports of the same
71- transactions repeated over multiple files.
72- + Journal configuration per bank account.
73- + Business logic and format parsing strictly separated to ease the
74- development of new parsers.
75- + No special configuration needed for the parsers, new parsers are
76- recognized and made available at server (re)start.
77+Do not install this module. This branch has been replaced by lp:banking-addons/6.0
78+See https://launchpad.net/banking-addons
79 ''',
80 'active': False,
81 'installable': True,
82
83=== modified file 'account_banking/account_banking.py'
84--- account_banking/account_banking.py 2011-11-08 13:10:34 +0000
85+++ account_banking/account_banking.py 2011-11-23 10:40:16 +0000
86@@ -63,6 +63,7 @@
87 from osv import osv, fields
88 from tools.translate import _
89 from wizard.banktools import get_or_create_bank
90+import decimal_precision as dp
91 import pooler
92 import netsvc
93 from tools import config
94@@ -184,6 +185,60 @@
95 }
96 account_banking_imported_file()
97
98+class payment_mode_type(osv.osv):
99+ _name= 'payment.mode.type'
100+ _description= 'Payment Mode Type'
101+ _columns= {
102+ 'name': fields.char(
103+ 'Name', size=64, required=True,
104+ help='Payment Type'
105+ ),
106+ 'code': fields.char(
107+ 'Code', size=64, required=True,
108+ help='Specify the Code for Payment Type'
109+ ),
110+ # Setting suitable_bank_types to required pending
111+ # https://bugs.launchpad.net/openobject-addons/+bug/786845
112+ 'suitable_bank_types': fields.many2many(
113+ 'res.partner.bank.type',
114+ 'bank_type_payment_type_rel',
115+ 'pay_type_id','bank_type_id',
116+ 'Suitable bank types', required=True),
117+ 'ir_model_id': fields.many2one(
118+ 'ir.model', 'Payment wizard',
119+ help=('Select the Payment Wizard for payments of this type. '
120+ 'Leave empty for manual processing'),
121+ domain=[('osv_memory', '=', True)],
122+ ),
123+ }
124+
125+payment_mode_type()
126+
127+class payment_mode(osv.osv):
128+ ''' Restoring the payment type from version 5,
129+ used to select the export wizard (if any) '''
130+ _inherit = "payment.mode"
131+
132+ def suitable_bank_types(self, cr, uid, payment_mode_id=None, context=None):
133+ """ Reinstates functional code for suitable bank type filtering.
134+ Current code in account_payment is disfunctional.
135+ """
136+ res = []
137+ payment_mode = self.browse(
138+ cr, uid, payment_mode_id, context)
139+ if (payment_mode and payment_mode.type and
140+ payment_mode.type.suitable_bank_types):
141+ res = [type.code for type in payment_mode.type.suitable_bank_types]
142+ return res
143+
144+ _columns = {
145+ 'type': fields.many2one(
146+ 'payment.mode.type', 'Payment type',
147+ help='Select the Payment Type for the Payment Mode.'
148+ ),
149+ }
150+payment_mode()
151+
152 class account_bank_statement(osv.osv):
153 '''
154 Extensions from account_bank_statement:
155@@ -265,228 +320,139 @@
156 # '''
157 # return None
158
159- def button_confirm(self, cursor, uid, ids, context=None):
160- '''
161- Trigger function for button 'Confirm'
162- As this function completely replaces the old one in account, other
163- modules who wish to alter behavior of this function but want to
164- cooperate with account_banking, should move their functionality to
165-
166- on_button_confirm(self, cursor, uid, ids, context=None)
167-
168- and drop any calls to super() herein.
169- In order to allow usage with and without account_banking, one could
170- use
171-
172- def on_button_confirm(...):
173- # Your code here
174-
175- def button_confirm(...):
176- super(my_class, self).button_confirm(...)
177- self.on_button_confirm(...)
178-
179- This way, code duplication is minimized.
180- '''
181+ def create_move_from_st_line(self, cr, uid, st_line_id,
182+ company_currency_id, st_line_number,
183+ context=None):
184 # This is largely a copy of the original code in account
185+ # Modifications are marked with AB
186 # As there is no valid inheritance mechanism for large actions, this
187 # is the only option to add functionality to existing actions.
188 # WARNING: when the original code changes, this trigger has to be
189 # updated in sync.
190- done = []
191+ if context is None:
192+ context = {}
193 res_currency_obj = self.pool.get('res.currency')
194- res_users_obj = self.pool.get('res.users')
195 account_move_obj = self.pool.get('account.move')
196 account_move_line_obj = self.pool.get('account.move.line')
197- account_bank_statement_line_obj = \
198- self.pool.get('account.bank.statement.line')
199-
200- company_currency_id = res_users_obj.browse(cursor, uid, uid,
201- context=context).company_id.currency_id.id
202-
203- for st in self.browse(cursor, uid, ids, context):
204- if not st.state=='draft':
205- continue
206-
207- # Calculate statement balance from the contained lines
208- end_bal = st.balance_end or 0.0
209- if not (abs(end_bal - st.balance_end_real) < 0.0001):
210+ account_bank_statement_line_obj = self.pool.get(
211+ 'account.bank.statement.line')
212+ st_line = account_bank_statement_line_obj.browse(cr, uid, st_line_id,
213+ context=context)
214+ st = st_line.statement_id
215+
216+ context.update({'date': st_line.date})
217+ period_id = self._get_period(
218+ cr, uid, st_line.date, context=context) # AB
219+
220+ move_id = account_move_obj.create(cr, uid, {
221+ 'journal_id': st.journal_id.id,
222+ 'period_id': period_id, # AB
223+ 'date': st_line.date,
224+ 'name': st_line_number,
225+ }, context=context)
226+ account_bank_statement_line_obj.write(cr, uid, [st_line.id], {
227+ 'move_ids': [(4, move_id, False)]
228+ })
229+
230+ if st_line.amount >= 0:
231+ account_id = st.journal_id.default_credit_account_id.id
232+ else:
233+ account_id = st.journal_id.default_debit_account_id.id
234+
235+ acc_cur = ((st_line.amount <= 0 and
236+ st.journal_id.default_debit_account_id) or
237+ st_line.account_id)
238+ context.update({
239+ 'res.currency.compute.account': acc_cur,
240+ })
241+ amount = res_currency_obj.compute(cr, uid, st.currency.id,
242+ company_currency_id, st_line.amount, context=context)
243+
244+ val = {
245+ 'name': st_line.name,
246+ 'date': st_line.date,
247+ 'ref': st_line.ref,
248+ 'move_id': move_id,
249+ 'partner_id': (((st_line.partner_id) and st_line.partner_id.id) or
250+ False),
251+ 'account_id': (st_line.account_id) and st_line.account_id.id,
252+ 'credit': ((amount>0) and amount) or 0.0,
253+ 'debit': ((amount<0) and -amount) or 0.0,
254+ 'statement_id': st.id,
255+ 'journal_id': st.journal_id.id,
256+ 'period_id': period_id, # AB
257+ 'currency_id': st.currency.id,
258+ 'analytic_account_id': (st_line.analytic_account_id and
259+ st_line.analytic_account_id.id or
260+ False),
261+ }
262+
263+ if st.currency.id <> company_currency_id:
264+ amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
265+ st.currency.id, amount, context=context)
266+ val['amount_currency'] = -amount_cur
267+
268+ if (st_line.account_id and st_line.account_id.currency_id and
269+ st_line.account_id.currency_id.id <> company_currency_id):
270+ val['currency_id'] = st_line.account_id.currency_id.id
271+ amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
272+ st_line.account_id.currency_id.id, amount, context=context)
273+ val['amount_currency'] = -amount_cur
274+
275+ move_line_id = account_move_line_obj.create(
276+ cr, uid, val, context=context)
277+ torec = move_line_id
278+
279+ # Fill the secondary amount/currency
280+ # if currency is not the same than the company
281+ amount_currency = False
282+ currency_id = False
283+ if st.currency.id <> company_currency_id:
284+ amount_currency = st_line.amount
285+ currency_id = st.currency.id
286+ account_move_line_obj.create(cr, uid, {
287+ 'name': st_line.name,
288+ 'date': st_line.date,
289+ 'ref': st_line.ref,
290+ 'move_id': move_id,
291+ 'partner_id': (((st_line.partner_id) and st_line.partner_id.id) or
292+ False),
293+ 'account_id': account_id,
294+ 'credit': ((amount < 0) and -amount) or 0.0,
295+ 'debit': ((amount > 0) and amount) or 0.0,
296+ 'statement_id': st.id,
297+ 'journal_id': st.journal_id.id,
298+ 'period_id': period_id, # AB
299+ 'amount_currency': amount_currency,
300+ 'currency_id': currency_id,
301+ }, context=context)
302+
303+ for line in account_move_line_obj.browse(cr, uid, [x.id for x in
304+ account_move_obj.browse(cr, uid, move_id,
305+ context=context).line_id],
306+ context=context):
307+ if line.state <> 'valid':
308 raise osv.except_osv(_('Error !'),
309- _('The statement balance is incorrect !\n') +
310- _('The expected balance (%.2f) is different '
311- 'than the computed one. (%.2f)') % (
312- st.balance_end_real, st.balance_end
313- ))
314- if (not st.journal_id.default_credit_account_id) \
315- or (not st.journal_id.default_debit_account_id):
316- raise osv.except_osv(_('Configration Error !'),
317- _('Please verify that an account is defined in the journal.'))
318-
319- for line in st.move_line_ids:
320- if line.state != 'valid':
321- raise osv.except_osv(_('Error !'),
322- _('The account entries lines are not in valid state.'))
323-
324- for move in st.line_ids:
325- context.update({'date':move.date})
326- # Essence of the change is here...
327- period_id = self._get_period(cursor, uid, move.date, context=context)
328- move_id = account_move_obj.create(cursor, uid, {
329- 'journal_id': st.journal_id.id,
330- # .. and here
331- 'period_id': period_id,
332- 'date': move.date,
333- }, context=context)
334- account_bank_statement_line_obj.write(cursor, uid, [move.id], {
335- 'move_ids': [(4, move_id, False)]
336- })
337- if not move.amount:
338- continue
339-
340- torec = []
341- if move.amount >= 0:
342- account_id = st.journal_id.default_credit_account_id.id
343- else:
344- account_id = st.journal_id.default_debit_account_id.id
345- acc_cur = ((move.amount<=0) and st.journal_id.default_debit_account_id) \
346- or move.account_id
347- amount = res_currency_obj.compute(cursor, uid, st.currency.id,
348- company_currency_id, move.amount, context=context,
349- account=acc_cur)
350- if move.reconcile_id and move.reconcile_id.line_new_ids:
351- for newline in move.reconcile_id.line_new_ids:
352- amount += newline.amount
353-
354- val = {
355- 'name': move.name,
356- 'date': move.date,
357- 'ref': move.ref,
358- 'move_id': move_id,
359- 'partner_id': ((move.partner_id) and move.partner_id.id) or False,
360- 'account_id': (move.account_id) and move.account_id.id,
361- 'credit': ((amount>0) and amount) or 0.0,
362- 'debit': ((amount<0) and -amount) or 0.0,
363- 'statement_id': st.id,
364- 'journal_id': st.journal_id.id,
365- 'period_id': period_id,
366- 'currency_id': st.currency.id,
367- }
368-
369- amount = res_currency_obj.compute(cursor, uid, st.currency.id,
370- company_currency_id, move.amount, context=context,
371- account=acc_cur)
372- if st.currency.id != company_currency_id:
373- amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
374- st.currency.id, amount, context=context,
375- account=acc_cur)
376- val['amount_currency'] = -amount_cur
377-
378- if move.account_id and move.account_id.currency_id and move.account_id.currency_id.id != company_currency_id:
379- val['currency_id'] = move.account_id.currency_id.id
380- amount_cur = res_currency_obj.compute(cursor, uid, company_currency_id,
381- move.account_id.currency_id.id, amount, context=context,
382- account=acc_cur)
383- val['amount_currency'] = -amount_cur
384-
385- torec.append(account_move_line_obj.create(cursor, uid, val , context=context))
386-
387- if move.reconcile_id and move.reconcile_id.line_new_ids:
388- for newline in move.reconcile_id.line_new_ids:
389- account_move_line_obj.create(cursor, uid, {
390- 'name': newline.name or move.name,
391- 'date': move.date,
392- 'ref': move.ref,
393- 'move_id': move_id,
394- 'partner_id': ((move.partner_id) and move.partner_id.id) or False,
395- 'account_id': (newline.account_id) and newline.account_id.id,
396- 'debit': newline.amount>0 and newline.amount or 0.0,
397- 'credit': newline.amount<0 and -newline.amount or 0.0,
398- 'statement_id': st.id,
399- 'journal_id': st.journal_id.id,
400- 'period_id': period_id,
401- }, context=context)
402-
403- # Fill the secondary amount/currency
404- # if currency is not the same than the company
405- amount_currency = False
406- currency_id = False
407- if st.currency.id <> company_currency_id:
408- amount_currency = move.amount
409- currency_id = st.currency.id
410-
411- account_move_line_obj.create(cursor, uid, {
412- 'name': move.name,
413- 'date': move.date,
414- 'ref': move.ref,
415- 'move_id': move_id,
416- 'partner_id': ((move.partner_id) and move.partner_id.id) or False,
417- 'account_id': account_id,
418- 'credit': ((amount < 0) and -amount) or 0.0,
419- 'debit': ((amount > 0) and amount) or 0.0,
420- 'statement_id': st.id,
421- 'journal_id': st.journal_id.id,
422- 'period_id': period_id,
423- 'amount_currency': amount_currency,
424- 'currency_id': currency_id,
425- }, context=context)
426-
427- for line in account_move_line_obj.browse(cursor, uid, [x.id for x in
428- account_move_obj.browse(cursor, uid, move_id, context=context).line_id
429- ], context=context):
430- if line.state != 'valid':
431- raise osv.except_osv(
432- _('Error !'),
433- _('Account move line "%s" is not valid')
434- % line.name
435- )
436-
437- if move.reconcile_id and move.reconcile_id.line_ids:
438- ## Search if move has already a partial reconciliation
439- previous_partial = False
440- for line_reconcile_move in move.reconcile_id.line_ids:
441- if line_reconcile_move.reconcile_partial_id:
442- previous_partial = True
443- break
444- ##
445- torec += map(lambda x: x.id, move.reconcile_id.line_ids)
446- #try:
447- if abs(move.reconcile_amount-move.amount)<0.0001:
448-
449- writeoff_acc_id = False
450- #There should only be one write-off account!
451- for entry in move.reconcile_id.line_new_ids:
452- writeoff_acc_id = entry.account_id.id
453- break
454- ## If we have already a partial reconciliation
455- ## We need to make a partial reconciliation
456- ## To add this amount to previous paid amount
457- if previous_partial:
458- account_move_line_obj.reconcile_partial(cr, uid, torec, 'statement', context)
459- ## If it's the first reconciliation, we do a full reconciliation as regular
460- else:
461- account_move_line_obj.reconcile(
462- cursor, uid, torec, 'statement',
463- writeoff_acc_id=writeoff_acc_id,
464- writeoff_period_id=st.period_id.id,
465- writeoff_journal_id=st.journal_id.id,
466- context=context
467- )
468- else:
469- account_move_line_obj.reconcile_partial(
470- cursor, uid, torec, 'statement', context
471- )
472-
473- if st.journal_id.entry_posted:
474- account_move_obj.write(cursor, uid, [move_id], {'state':'posted'})
475- done.append(st.id)
476- self.write(cursor, uid, done, {'state':'confirm'}, context=context)
477-
478- # Be nice to other modules as well, relay button_confirm calls to
479- # on_button_confirm calls.
480- for other in self._abf_others:
481- if hasattr(other, 'on_button_confirm'):
482- other.on_button_confirm(self, cursor, uid, ids, context=context)
483-
484- return True
485+ _('Journal Item "%s" is not valid') % line.name)
486+
487+ # Bank statements will not consider boolean on journal entry_posted
488+ account_move_obj.post(cr, uid, [move_id], context=context)
489+
490+ """
491+ Account-banking:
492+ - Write stored reconcile_id
493+ - Pay invoices through workflow
494+ """
495+ if st_line.reconcile_id:
496+ account_move_line_obj.write(cr, uid, [torec], {
497+ 'reconcile_id': st_line.reconcile_id.id }, context=context)
498+ for move_line in (st_line.reconcile_id.line_id or []) + (
499+ st_line.reconcile_id.line_partial_ids or []):
500+ netsvc.LocalService("workflow").trg_trigger(
501+ uid, 'account.move.line', move_line.id, cr)
502+ """ End account-banking """
503+
504+ return move_id
505
506 account_bank_statement()
507
508@@ -564,9 +530,23 @@
509 # res[line.id] = 0.0
510 # return res
511
512+ def _get_invoice_id(self, cr, uid, ids, name, args, context=None):
513+ res = {}
514+ for st_line in self.browse(cr, uid, ids, context):
515+ res[st_line.id] = False
516+ for move_line in (st_line.reconcile_id and
517+ (st_line.reconcile_id.line_id or []) +
518+ (st_line.reconcile_id.line_partial_ids or []) or
519+ []):
520+ if move_line.invoice:
521+ res[st_line.id] = move_line.invoice.id
522+ continue
523+ return res
524+
525 _columns = {
526 # Redefines
527 'amount': fields.float('Amount', readonly=True,
528+ digits_compute=dp.get_precision('Account'),
529 states={'draft': [('readonly', False)]}),
530 'ref': fields.char('Ref.', size=32, readonly=True,
531 states={'draft': [('readonly', False)]}),
532@@ -596,6 +576,13 @@
533 required=False,
534 states={'confirm': [('readonly', True)]},
535 ),
536+ 'reconcile_id': fields.many2one(
537+ 'account.move.reconcile', 'Reconciliation', readonly=True
538+ ),
539+ 'invoice_id': fields.function(
540+ _get_invoice_id, method=True, string='Linked Invoice',
541+ type='many2one', relation='account.invoice'
542+ ),
543 }
544
545 _defaults = {
546@@ -604,57 +591,8 @@
547 'currency': _get_currency,
548 }
549
550- def onchange_partner_id(self, cursor, uid, line_id, partner_id, type,
551- currency_id, context=None
552- ):
553- '''
554- Find default accounts when encoding statements by hand
555- '''
556- if not partner_id:
557- return {}
558-
559- result = {}
560- if not currency_id:
561- users_obj = self.pool.get('res.users')
562- currency_id = users_obj.browse(
563- cursor, uid, uid, context=context
564- ).company_id.currency_id.id
565- result['currency_id'] = currency_id
566-
567- partner_obj = self.pool.get('res.partner')
568- partner = partner_obj.browse(cursor, uid, partner_id, context=context)
569- if partner.supplier and not partner.customer:
570- if partner.property_account_payable.id:
571- result['account_id'] = partner.property_account_payable.id
572- result['type'] = 'supplier'
573- elif partner.customer and not partner.supplier:
574- if partner.property_account_receivable.id:
575- result['account_id'] = partner.property_account_receivable.id
576- result['type'] = 'customer'
577-
578- return result and {'value': result} or {}
579-
580 account_bank_statement_line()
581
582-class payment_type(osv.osv):
583- '''
584- Make description field translatable #, add country context
585- '''
586- _inherit = 'payment.type'
587- _columns = {
588- 'name': fields.char('Name', size=64, required=True, translate=True,
589- help='Payment Type'
590- ),
591- #'country_id': fields.many2one('res.country', 'Country',
592- # required=False,
593- # help='Use this to limit this type to a specific country'
594- # ),
595- }
596- #_defaults = {
597- # 'country_id': lambda *a: False,
598- #}
599-payment_type()
600-
601 class payment_line(osv.osv):
602 '''
603 Add extra export_state and date_done fields; make destination bank account
604@@ -814,6 +752,7 @@
605 Enable extra states for payment exports and add extra functionality.
606 '''
607 _inherit = 'payment.order'
608+<<<<<<< TREE
609
610 def __no_transactions(self, cursor, uid, ids, field_name, arg=None,
611 context=None):
612@@ -862,8 +801,11 @@
613 cursor.execute(query)
614 return dict(cursor.fetchall())
615
616+=======
617+
618+>>>>>>> MERGE-SOURCE
619 _columns = {
620- 'date_planned': fields.date(
621+ 'date_scheduled': fields.date(
622 'Scheduled date if fixed',
623 states={
624 'sent': [('readonly', True)],
625@@ -941,6 +883,47 @@
626 ),
627 }
628
629+ def launch_wizard(self, cr, uid, ids, context=None):
630+ """
631+ Search for a wizard to launch according to the type.
632+ If type is manual. just confirm the order.
633+ Previously (pre-v6) in account_payment/wizard/wizard_pay.py
634+ """
635+ if context == None:
636+ context={}
637+ result = {}
638+ orders = self.browse(cr, uid, ids, context)
639+ order = orders[0]
640+ # check if a wizard is defined for the first order
641+ if order.mode.type and order.mode.type.ir_model_id:
642+ context['active_ids'] = ids
643+ wizard_model = order.mode.type.ir_model_id.model
644+ wizard_obj = self.pool.get(wizard_model)
645+ wizard_id = wizard_obj.create(cr, uid, {}, context)
646+ result = {
647+ 'name': wizard_obj._description or 'Payment Order Export',
648+ 'view_type': 'form',
649+ 'view_mode': 'form',
650+ 'res_model': wizard_model,
651+ 'domain': [],
652+ 'context': context,
653+ 'type': 'ir.actions.act_window',
654+ 'target': 'new',
655+ 'res_id': wizard_id,
656+ 'nodestroy': True,
657+ }
658+ else:
659+ # should all be manual orders without type or wizard model
660+ for order in orders[1:]:
661+ if order.mode.type and order.mode.type.ir_model_id:
662+ raise osv.except_osv(
663+ _('Error'),
664+ _('You can only combine payment orders of the same type')
665+ )
666+ # process manual payments
667+ self.action_sent(cr, uid, ids, context)
668+ return result
669+
670 def _write_payment_lines(self, cursor, uid, ids, **kwargs):
671 '''
672 ORM method for setting attributes of corresponding payment.line objects.
673@@ -1180,8 +1163,13 @@
674 Convert IBAN electronic format to IBAN display format
675 '''
676 records = self._founder.read(self, *args, **kwargs)
677+<<<<<<< TREE
678 if not hasattr(records, '__iter__'):
679 records = [records]
680+=======
681+ if not isinstance(records, list):
682+ records = [records,]
683+>>>>>>> MERGE-SOURCE
684 for record in records:
685 if 'iban' in record and record['iban']:
686 record['iban'] = unicode(sepa.IBAN(record['iban']))
687@@ -1268,12 +1256,15 @@
688 ):
689 country_ids = [user.company_id.partner_id.country.id]
690 else:
691- # Ok, tried everything, give up and leave it to the user
692- return warning(_('Insufficient data'),
693- _('Insufficient data to select online '
694- 'conversion database')
695- )
696-
697+ if (user.company_id and user.company_id.partner_id and
698+ user.company_id.partner_id.country):
699+ country_ids = [user.company_id.partner_id.country.id]
700+ else:
701+ # Ok, tried everything, give up and leave it to the user
702+ return warning(_('Insufficient data'),
703+ _('Insufficient data to select online '
704+ 'conversion database')
705+ )
706 result = {'value': values}
707 # Complete data with online database when available
708 if country.code in sepa.IBAN.countries:
709
710=== removed file 'account_banking/account_banking_import_wizard.xml'
711--- account_banking/account_banking_import_wizard.xml 2010-01-26 20:55:24 +0000
712+++ account_banking/account_banking_import_wizard.xml 1970-01-01 00:00:00 +0000
713@@ -1,15 +0,0 @@
714-<?xml version="1.0" encoding="utf-8"?>
715-<!--
716- Copyright (C) EduSense BV <http://www.edusense.nl>
717- All rights reserved.
718- The licence is in the file __terp__.py
719--->
720-<openerp>
721- <data>
722- <wizard id="wizard_account_banking_import_file"
723- string="Import Bank Statements File"
724- model="account.bank.statement"
725- name="account_banking.banking_import"
726- />
727- </data>
728-</openerp>
729
730=== removed file 'account_banking/account_banking_payment_wizard.xml'
731--- account_banking/account_banking_payment_wizard.xml 2011-02-12 13:37:09 +0000
732+++ account_banking/account_banking_payment_wizard.xml 1970-01-01 00:00:00 +0000
733@@ -1,22 +0,0 @@
734-<?xml version="1.0" encoding="utf-8"?>
735-<!--
736- Copyright (C) EduSense BV <http://www.edusense.nl>
737- All rights reserved.
738- The licence is in the file __terp__.py
739--->
740-<openerp>
741- <data>
742- <wizard id="wizard_account_banking_payment_manual"
743- menu="False"
744- string="Manual Bank Payment"
745- model="account_payment.payment.order"
746- name="account_banking.payment_manual"
747- />
748- <wizard id="account_payment.wizard_populate_payment"
749- menu="False"
750- string="Populate payment"
751- model="payment.order"
752- name="account_payment.populate_payment"
753- />
754- </data>
755-</openerp>
756
757=== modified file 'account_banking/account_banking_view.xml'
758--- account_banking/account_banking_view.xml 2011-11-07 12:34:48 +0000
759+++ account_banking/account_banking_view.xml 2011-11-23 10:40:16 +0000
760@@ -42,7 +42,7 @@
761 <field name="company_id" />
762 <separator string="Bank Account Details" colspan="4" />
763 <field name="partner_bank_id" /> <!-- Needs domain for used companies /-->
764- <field name="journal_id" domain="[('type','=','cash')]" />
765+ <field name="journal_id" domain="[('type','=','bank')]" />
766 <separator string="Default Accounts for Unknown Movements" colspan="4" />
767 <field name="default_credit_account_id" />
768 <field name="default_debit_account_id" />
769@@ -61,7 +61,7 @@
770 <tree string="Default Import Settings for Bank Account">
771 <field name="company_id" />
772 <field name="partner_bank_id" /> <!-- Needs domain for used companies /-->
773- <field name="journal_id" domain="[('type','=','cash')]" />
774+ <field name="journal_id" domain="[('type','=','bank')]" />
775 </tree>
776 </field>
777 </record>
778@@ -140,10 +140,18 @@
779 <menuitem name="Import Bank Statements File"
780 id="menu_account_banking_import_wizard"
781 parent="account_banking.menu_finance_banking_actions"
782- type="wizard"
783 action="wizard_account_banking_import_file"
784 sequence="15"/>
785
786+ <!-- Add the import wizard to the statement's right menu -->
787+ <act_window name="Import Bank Statements File"
788+ res_model="account.banking.bank.import"
789+ src_model="account.bank.statement"
790+ view_mode="form"
791+ target="new"
792+ key2="client_action_multi"
793+ id="act_account_banking_import_wizard"/>
794+
795 <!-- Create right menu entry to see statements -->
796 <act_window name="Bank Statements File"
797 domain="[('id','=',banking_id)]"
798@@ -170,7 +178,15 @@
799 <field name="model">account.bank.statement</field>
800 <field name="type">form</field>
801 <field name="arch" type="xml">
802- <field name="period_id" position="replace"/>
803+ <data>
804+ <field name="period_id" position="replace"/>
805+ <xpath expr="/form/notebook/page[@string='Transaction']/field/tree/field[@name='name']" position="replace">
806+ <field name="name" required="1"/>
807+ </xpath>
808+ <xpath expr="/form/notebook/page[@string='Transaction']/field/form/field[@name='name']" position="replace">
809+ <field name="name" required="1"/>
810+ </xpath>
811+ </data>
812 </field>
813 </record>
814 <record id="view_banking_bank_statement_form_2" model="ir.ui.view">
815@@ -179,7 +195,7 @@
816 <field name="model">account.bank.statement</field>
817 <field name="type">form</field>
818 <field name="arch" type="xml">
819- <xpath expr="/form/notebook/page[@string='Entry encoding']/field/tree/field[@name='type']" position="after">
820+ <xpath expr="/form/notebook/page[@string='Transaction']/field/tree/field[@name='ref']" position="after">
821 <field name="period_id"/>
822 </xpath>
823 </field>
824@@ -190,7 +206,7 @@
825 <field name="model">account.bank.statement</field>
826 <field name="type">form</field>
827 <field name="arch" type="xml">
828- <xpath expr="/form/notebook/page[@string='Entry encoding']/field/form/field[@name='type']" position="after">
829+ <xpath expr="/form/notebook/page[@string='Transaction']/field/form/field[@name='ref']" position="after">
830 <field name="period_id"/>
831 </xpath>
832 </field>
833@@ -235,9 +251,19 @@
834 <field name="model">account.bank.statement</field>
835 <field name="type">form</field>
836 <field name="arch" type="xml">
837- <xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='partner_id']" position="after">
838- <field name="partner_bank_id"/>
839- </xpath>
840+ <data>
841+ <xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='partner_id']" position="after">
842+ <field name="partner_bank_id"/>
843+ </xpath>
844+ <xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='amount']" position="after">
845+ <field name="invoice_id"/>
846+ <field name="reconcile_id"/>
847+ </xpath>
848+ <xpath expr="/form/notebook/page/field[@name='line_ids']/form/field[@name='amount']" position="after">
849+ <field name="invoice_id"/>
850+ <field name="reconcile_id"/>
851+ </xpath>
852+ </data>
853 </field>
854 </record>
855 <record id="view_banking_bank_statement_form_6" model="ir.ui.view">
856@@ -252,6 +278,7 @@
857 </field>
858 </record>
859
860+<<<<<<< TREE
861 <!-- Reset trigger on button_confirm to the trigger code in this module -->
862 <record id="view_banking_bank_statement_form_7" model="ir.ui.view">
863 <field name="name">account.bank.statement.form.banking-7</field>
864@@ -264,21 +291,44 @@
865 </button>
866 </field>
867 </record>
868+=======
869+ <!-- Make buttons on payment order sensitive for extra states,
870+ restore wizard functionality when making payments
871+ -->
872+>>>>>>> MERGE-SOURCE
873
874- <!-- Make buttons on payment order sensitive for extra states -->
875 <record id="view_banking_payment_order_form_1" model="ir.ui.view">
876 <field name="name">account.payment.order.form.banking-1</field>
877 <field name="inherit_id" ref="account_payment.view_payment_order_form" />
878 <field name="model">payment.order</field>
879 <field name="type">form</field>
880 <field name="arch" type="xml">
881- <xpath expr="/form/button[@string='Select Invoices to Pay']"
882- position="replace">
883- <button name="%(account_payment.wizard_populate_payment)s"
884- colspan="2" type="action" states="draft,open"
885- string="Select Invoices to Pay"
886- />
887- </xpath>
888+ <data>
889+ <xpath expr="/form/group/button[@string='Select Invoices to Pay']"
890+ position="replace">
891+ <button colspan="2" name="%(account_payment.action_create_payment_order)s"
892+ string="Select Invoices to Pay" type="action"
893+ attrs="{'invisible':[('state','!=','draft')]}"
894+ icon="gtk-find"
895+ />
896+ </xpath>
897+ <xpath expr="/form/group/button[@string='Make Payments']"
898+ position="replace">
899+ <button name="launch_wizard" states="open" string="Make Payments" type="object" icon="gtk-execute"/>
900+ <newline/>
901+ </xpath>
902+ </data>
903+ </field>
904+ </record>
905+ <record id="view_banking_payment_order_tree_1" model="ir.ui.view">
906+ <field name="name">account.payment.order.tree.banking-1</field>
907+ <field name="inherit_id" ref="account_payment.view_payment_order_tree" />
908+ <field name="model">payment.order</field>
909+ <field name="type">tree</field>
910+ <field name="arch" type="xml">
911+ <button string="Make Payments" position="replace">
912+ <button name="launch_wizard" states="open" string="Make Payments" type="object" icon="gtk-execute"/>
913+ </button>
914 </field>
915 </record>
916
917@@ -353,7 +403,7 @@
918 <field name="type">form</field>
919 <field name="arch" type="xml">
920 <xpath expr="/form/notebook/page/field[@name='bank_ids']/tree/field[@name='acc_number']" position="replace">
921- <field name="acc_number" on_change="onchange_acc_number(acc_number, parent.id, country_id)" />
922+ <field name="acc_number" on_change="onchange_acc_number(acc_number, parent.id, country_id)" select="1" />
923 </xpath>
924 </field>
925 </record>
926@@ -371,5 +421,43 @@
927 </field>
928 </record>
929
930+ <!-- Insert payment_mode.type -->
931+ <record id="view_payment_mode_form_inherit" model="ir.ui.view">
932+ <field name="name">payment.mode.form.inherit</field>
933+ <field name="model">payment.mode</field>
934+ <field name="inherit_id" ref="account_payment.view_payment_mode_form"/>
935+ <field name="type">form</field>
936+ <field name="arch" type="xml">
937+ <field name="company_id" position="after">
938+ <field name="type"/>
939+ </field>
940+ </field>
941+ </record>
942+ <record id="view_payment_mode_tree_inherit" model="ir.ui.view">
943+ <field name="name">payment.mode.tree.inherit</field>
944+ <field name="model">payment.mode</field>
945+ <field name="inherit_id" ref="account_payment.view_payment_mode_tree"/>
946+ <field name="type">tree</field>
947+ <field name="arch" type="xml">
948+ <field name="company_id" position="after">
949+ <field name="type"/>
950+ </field>
951+ </field>
952+ </record>
953+
954+ <!-- basic view for payment mode type -->
955+ <record model="ir.ui.view" id="view_payment_mode_type_form">
956+ <field name="name">view.payment.mode.type.form</field>
957+ <field name="model">payment.mode.type</field>
958+ <field name="type">form</field>
959+ <field name="arch" type="xml">
960+ <form>
961+ <field name="name" />
962+ <field name="code" />
963+ <field name="suitable_bank_types"/>
964+ <field name="ir_model_id"/>
965+ </form>
966+ </field>
967+ </record>
968 </data>
969 </openerp>
970
971=== modified file 'account_banking/data/account_banking_data.xml'
972--- account_banking/data/account_banking_data.xml 2010-12-20 10:58:51 +0000
973+++ account_banking/data/account_banking_data.xml 2011-11-23 10:40:16 +0000
974@@ -17,14 +17,14 @@
975 Ratio: one can have bank accounts in foreign banks. Foreign
976 addresses not automatically involve international banking.
977 -->
978- <record id="bank_normal_field_contry" model="res.partner.bank.type.field">
979+ <record id="base.bank_normal_field_contry" model="res.partner.bank.type.field">
980 <field name="name">country_id</field>
981 <field name="bank_type_id" ref="base.bank_normal"/>
982 <field eval="False" name="required"/>
983 <field eval="False" name="readonly"/>
984 </record>
985 <!-- Add manual bank transfer as default payment option -->
986- <record model="payment.type" id="account_banking.manual_bank_tranfer">
987+ <record model="payment.mode.type" id="account_banking.manual_bank_tranfer">
988 <field name="name">Manual Bank Transfer</field>
989 <field name="code">BANKMAN</field>
990 <field name="suitable_bank_types"
991
992=== modified file 'account_banking/security/ir.model.access.csv'
993--- account_banking/security/ir.model.access.csv 2010-12-20 10:58:51 +0000
994+++ account_banking/security/ir.model.access.csv 2011-11-23 10:40:16 +0000
995@@ -1,3 +1,5 @@
996 "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
997 "access_account_banking_settings","account.banking.account.settings","model_account_banking_account_settings","account.group_account_manager",1,1,1,1
998+"access_account_banking_settings_user","account.banking.account.settings user","model_account_banking_account_settings","account.group_account_user",1,0,0,0
999 "access_account_banking_import","account.bankimport","model_account_banking_imported_file","account.group_account_user",1,1,1,1
1000+"access_payment_mode_type","payment.mode.type","model_payment_mode_type","account_payment.group_account_payment",1,1,1,1
1001
1002=== modified file 'account_banking/wizard/__init__.py'
1003--- account_banking/wizard/__init__.py 2011-02-12 13:37:09 +0000
1004+++ account_banking/wizard/__init__.py 2011-11-23 10:40:16 +0000
1005@@ -20,6 +20,6 @@
1006 ##############################################################################
1007 import bank_import
1008 import bank_payment_manual
1009-import wizard_payment_order
1010+import account_payment_order
1011
1012 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1013
1014=== added file 'account_banking/wizard/account_payment_order.py'
1015--- account_banking/wizard/account_payment_order.py 1970-01-01 00:00:00 +0000
1016+++ account_banking/wizard/account_payment_order.py 2011-11-23 10:40:16 +0000
1017@@ -0,0 +1,113 @@
1018+# -*- coding: utf-8 -*-
1019+##############################################################################
1020+#
1021+# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
1022+# All Rights Reserved
1023+#
1024+# This program is free software: you can redistribute it and/or modify
1025+# it under the terms of the GNU General Public License as published by
1026+# the Free Software Foundation, either version 3 of the License, or
1027+# (at your option) any later version.
1028+#
1029+# This program is distributed in the hope that it will be useful,
1030+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1031+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1032+# GNU General Public License for more details.
1033+#
1034+# You should have received a copy of the GNU General Public License
1035+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1036+#
1037+##############################################################################
1038+
1039+import datetime
1040+from osv import osv
1041+from account_banking.struct import struct
1042+from account_banking.parsers import convert
1043+
1044+today = datetime.date.today
1045+
1046+def str2date(str):
1047+ dt = convert.str2date(str, '%Y-%m-%d')
1048+ return datetime.date(dt.year, dt.month, dt.day)
1049+
1050+class payment_order_create(osv.osv_memory):
1051+ _inherit = 'payment.order.create'
1052+
1053+ def create_payment(self, cr, uid, ids, context=None):
1054+ '''
1055+ This method is a slightly modified version of the existing method on this
1056+ model in account_payment.
1057+ - pass the payment mode to line2bank()
1058+ - allow invoices to create influence on the payment process: not only 'Free'
1059+ references are allowed, but others as well
1060+ - check date_to_pay is not in the past.
1061+ '''
1062+
1063+ order_obj = self.pool.get('payment.order')
1064+ line_obj = self.pool.get('account.move.line')
1065+ payment_obj = self.pool.get('payment.line')
1066+ if context is None:
1067+ context = {}
1068+ data = self.read(cr, uid, ids, [], context=context)[0]
1069+ line_ids = data['entries']
1070+ if not line_ids:
1071+ return {'type': 'ir.actions.act_window_close'}
1072+
1073+ payment = order_obj.browse(cr, uid, context['active_id'], context=context)
1074+ ### account banking
1075+ # t = None
1076+ # line2bank = line_obj.line2bank(cr, uid, line_ids, t, context)
1077+ line2bank = line_obj.line2bank(cr, uid, line_ids, payment.mode.id, context)
1078+ _today = today()
1079+ ### end account banking
1080+
1081+ ## Finally populate the current payment with new lines:
1082+ for line in line_obj.browse(cr, uid, line_ids, context=context):
1083+ if payment.date_prefered == "now":
1084+ #no payment date => immediate payment
1085+ date_to_pay = False
1086+ elif payment.date_prefered == 'due':
1087+ ### account_banking
1088+ # date_to_pay = line.date_maturity
1089+ date_to_pay = line.date_maturity and \
1090+ str2date(line.date_maturity) > _today\
1091+ and line.date_maturity or False
1092+ ### end account banking
1093+ elif payment.date_prefered == 'fixed':
1094+ ### account_banking
1095+ # date_to_pay = payment.date_planned
1096+ date_to_pay = payment.date_planned and \
1097+ str2date(payment.date_planned) > _today\
1098+ and payment.date_planned or False
1099+ ### end account banking
1100+
1101+ ### account_banking
1102+ state = communication2 = False
1103+ communication = line.ref or '/'
1104+ if line.invoice:
1105+ if line.invoice.reference_type == 'structured':
1106+ state = 'structured'
1107+ communication = line.invoice.reference
1108+ else:
1109+ state = 'normal'
1110+ communication2 = line.invoice.reference
1111+ ### end account_banking
1112+
1113+ payment_obj.create(cr, uid,{
1114+ 'move_line_id': line.id,
1115+ 'amount_currency': line.amount_to_pay,
1116+ 'bank_id': line2bank.get(line.id),
1117+ 'order_id': payment.id,
1118+ 'partner_id': line.partner_id and line.partner_id.id or False,
1119+ ### account banking
1120+ # 'communication': line.ref or '/'
1121+ 'communication': communication,
1122+ 'communication2': communication2,
1123+ 'state': state,
1124+ ### end account banking
1125+ 'date': date_to_pay,
1126+ 'currency': line.invoice and line.invoice.currency_id.id or False,
1127+ }, context=context)
1128+ return {'type': 'ir.actions.act_window_close'}
1129+
1130+payment_order_create()
1131
1132=== modified file 'account_banking/wizard/bank_import.py'
1133--- account_banking/wizard/bank_import.py 2011-11-07 22:23:48 +0000
1134+++ account_banking/wizard/bank_import.py 2011-11-23 10:40:16 +0000
1135@@ -28,9 +28,8 @@
1136 The parsing is done in the parser modules. Every parser module is required to
1137 use parser.models as a mean of communication with the business logic.
1138 '''
1139-import pooler
1140+from osv import osv, fields
1141 import time
1142-import wizard
1143 import netsvc
1144 import base64
1145 import datetime
1146@@ -41,6 +40,7 @@
1147 from account_banking.struct import struct
1148 from account_banking import sepa
1149 from banktools import *
1150+import decimal_precision as dp
1151
1152 bt = models.mem_bank_transaction
1153
1154@@ -55,6 +55,7 @@
1155 '''
1156 return models.parser_type.get_parser_types()
1157
1158+<<<<<<< TREE
1159 class banking_import(wizard.interface):
1160 '''
1161 Wizard to import bank statements. Generic code, parsing is done in the
1162@@ -130,10 +131,14 @@
1163
1164 def _fill_results(self, *args, **kwargs):
1165 return {'log': self._log}
1166+=======
1167+class banking_import(osv.osv_memory):
1168+ _name = 'account.banking.bank.import'
1169+>>>>>>> MERGE-SOURCE
1170
1171 def _get_move_info(self, cursor, uid, move_line, partner_bank_id=False,
1172 partial=False):
1173- reconcile_obj = self.pool.get('account.bank.statement.reconcile')
1174+ reconcile_obj = self.pool.get('account.move.reconcile')
1175 type_map = {
1176 'out_invoice': 'customer',
1177 'in_invoice': 'supplier',
1178@@ -153,7 +158,14 @@
1179
1180 if partial:
1181 move_line.reconcile_partial_id = reconcile_obj.create(
1182+<<<<<<< TREE
1183 cursor, uid, {'line_partial_ids': [(6, 0, [move_line.id])]}
1184+=======
1185+ cursor, uid, {
1186+ 'type': 'auto',
1187+ 'line_partial_ids': [(4, 0, [move_line.id])]
1188+ }
1189+>>>>>>> MERGE-SOURCE
1190 )
1191 else:
1192 if move_line.reconcile_partial_id:
1193@@ -164,7 +176,12 @@
1194 partial_ids = []
1195 move_line.reconcile_id = reconcile_obj.create(
1196 cursor, uid, {
1197+<<<<<<< TREE
1198 'line_ids': [
1199+=======
1200+ 'type': 'auto',
1201+ 'line_id': [
1202+>>>>>>> MERGE-SOURCE
1203 (4, x, False) for x in [move_line.id] + partial_ids
1204 ],
1205 'line_partial_ids': [
1206@@ -228,12 +245,13 @@
1207 return []
1208
1209 def _link_payment(self, cursor, uid, trans, payment_lines,
1210- partner_ids, bank_account_ids, log):
1211+ partner_ids, bank_account_ids, log, linked_payments):
1212 '''
1213 Find the payment order belonging to this reference - if there is one
1214 When sending payments, the returned bank info should be identical to
1215 ours.
1216 '''
1217+<<<<<<< TREE
1218 # TODO:
1219 # 1. Not sure what side effects are created when payments are done
1220 # for credited customer invoices, which will be matched later on
1221@@ -247,6 +265,11 @@
1222 # intertwined. Ignoring this causes double processing of the same
1223 # payment line.
1224
1225+=======
1226+ # TODO: Not sure what side effects are created when payments are done
1227+ # for credited customer invoices, which will be matched later on too.
1228+ digits = dp.get_precision('Account')(cursor)[1]
1229+>>>>>>> MERGE-SOURCE
1230 candidates = [x for x in payment_lines
1231 if x.id not in self.__linked_payments and
1232 (not self._cached(x.move_line_id)) and
1233@@ -260,6 +283,7 @@
1234 ]
1235 if len(candidates) == 1:
1236 candidate = candidates[0]
1237+<<<<<<< TREE
1238 self.__linked_payments[candidate.id] = True
1239 self._cache(candidate.move_line_id)
1240 payment_line_obj = self.pool.get('payment.line')
1241@@ -271,12 +295,21 @@
1242 cursor, uid, candidate.move_line_id,
1243 partner_bank_id=\
1244 bank_account_ids and bank_account_ids[0].id or False
1245+=======
1246+ # Check cache to prevent multiple matching of a single payment
1247+ if candidate.id not in linked_payments:
1248+ linked_payments[candidate.id] = True
1249+ payment_line_obj = self.pool.get('payment.line')
1250+ payment_line_obj.write(cursor, uid, [candidate.id], {
1251+ 'export_state': 'done',
1252+ 'date_done': trans.effective_date.strftime('%Y-%m-%d')}
1253+>>>>>>> MERGE-SOURCE
1254 )
1255
1256 return False
1257
1258 def _link_invoice(self, cursor, uid, trans, move_lines,
1259- partner_ids, bank_account_ids, log):
1260+ partner_ids, bank_account_ids, log, linked_invoices):
1261 '''
1262 Find the invoice belonging to this reference - if there is one
1263 Use the sales journal to check.
1264@@ -360,6 +393,22 @@
1265
1266 return False
1267
1268+<<<<<<< TREE
1269+=======
1270+ def _cached(move_line):
1271+ '''Check if the move_line has been cached'''
1272+ return move_line.id in linked_invoices
1273+
1274+ def _cache(move_line, remaining=0.0):
1275+ '''Cache the move_line'''
1276+ linked_invoices[move_line.id] = remaining
1277+
1278+ def _remaining(move_line):
1279+ '''Return the remaining amount for a previously matched move_line
1280+ '''
1281+ return linked_invoices[move_line.id]
1282+
1283+>>>>>>> MERGE-SOURCE
1284 def _sign(invoice):
1285 '''Return the direction of an invoice'''
1286 return {'in_invoice': -1,
1287@@ -368,7 +417,7 @@
1288 'out_refund': -1
1289 }[invoice.type]
1290
1291- digits = int(config['price_accuracy'])
1292+ digits = dp.get_precision('Account')(cursor)[1]
1293 partial = False
1294
1295 # Search invoice on partner
1296@@ -465,8 +514,6 @@
1297 for x in best or candidates
1298 ])
1299 })
1300- self.__multiple_matches.append((trans, best or
1301- candidates))
1302 move_line = False
1303 partial = False
1304
1305@@ -543,7 +590,7 @@
1306 if not account_info.costs_account_id:
1307 return []
1308
1309- digits = int(config['price_accuracy'])
1310+ digits = dp.get_precision('Account')(cursor)[1]
1311 amount = round(abs(trans.transferred_amount), digits)
1312 # Make sure to be able to pinpoint our costs invoice for later
1313 # matching
1314@@ -591,14 +638,10 @@
1315 invoice_line = invoice_lines,
1316 ))
1317 invoice = invoice_obj.browse(cursor, uid, invoice_id)
1318- # Set number
1319- invoice.action_number(cursor, uid, [invoice_id])
1320- # Create moves
1321- invoice.action_move_create(cursor, uid, [invoice_id])
1322 # Create workflow
1323+ invoice_obj.button_compute(cursor, uid, [invoice_id],
1324+ {'type': 'in_invoice'}, set_total=True)
1325 wf_service = netsvc.LocalService('workflow')
1326- res = wf_service.trg_create(uid, 'account.invoice', invoice.id,
1327- cursor)
1328 # Move to state 'open'
1329 wf_service.trg_validate(uid, 'account.invoice', invoice.id,
1330 'invoice_open', cursor)
1331@@ -606,17 +649,16 @@
1332 # return move_lines to mix with the rest
1333 return [x for x in invoice.move_id.line_id if x.account_id.reconcile]
1334
1335- def _import_statements_file(self, cursor, uid, data, context):
1336+ def import_statements_file(self, cursor, uid, ids, context):
1337 '''
1338 Import bank statements / bank transactions file.
1339 This method represents the business logic, the parser modules
1340 represent the decoding logic.
1341 '''
1342- form = data['form']
1343- statements_file = form['file']
1344+ banking_import = self.browse(cursor, uid, ids, context)[0]
1345+ statements_file = banking_import.file
1346 data = base64.decodestring(statements_file)
1347
1348- self.pool = pooler.get_pool(cursor.dbname)
1349 company_obj = self.pool.get('res.company')
1350 user_obj = self.pool.get('res.user')
1351 partner_obj = self.pool.get('res.partner')
1352@@ -632,28 +674,24 @@
1353 digits = int(config['price_accuracy'])
1354
1355 # get the parser to parse the file
1356- parser_code = form['parser']
1357+ parser_code = banking_import.parser
1358 parser = models.create_parser(parser_code)
1359 if not parser:
1360- raise wizard.except_wizard(
1361+ raise osv.except_osv(
1362 _('ERROR!'),
1363 _('Unable to import parser %(parser)s. Parser class not found.') %
1364- {'parser':parser_code}
1365+ {'parser': parser_code}
1366 )
1367
1368 # Get the company
1369- company = form['company']
1370- if not company:
1371- user_data = user_obj.browse(cursor, uid, uid, context)
1372- company = company_obj.browse(
1373- cursor, uid, company or user_data.company_id.id, context
1374- )
1375+ company = (banking_import.company or
1376+ user_obj.browse(cursor, uid, uid, context).company_id)
1377
1378 # Parse the file
1379 statements = parser.parse(data)
1380
1381 if any([x for x in statements if not x.is_valid()]):
1382- raise wizard.except_wizard(
1383+ raise osv.except_osv(
1384 _('ERROR!'),
1385 _('The imported statements appear to be invalid! Check your file.')
1386 )
1387@@ -682,6 +720,9 @@
1388 error_accounts = {}
1389 info = {}
1390 imported_statement_ids = []
1391+ linked_payments = {}
1392+ linked_invoices = {}
1393+ payment_lines = []
1394
1395 if statements:
1396 # Get default defaults
1397@@ -690,7 +731,8 @@
1398
1399 # Get interesting journals once
1400 journal_ids = journal_obj.search(cursor, uid, [
1401- ('type', 'in', ('sale','purchase')),
1402+ ('type', 'in', ('sale','purchase',
1403+ 'purchase_refund','sale_refund')),
1404 ('company_id', '=', company.id),
1405 ])
1406 # Get all unreconciled moves predating the last statement in one big
1407@@ -718,6 +760,7 @@
1408 "o.state = 'sent' AND "
1409 "l.date_done IS NULL"
1410 )
1411+<<<<<<< TREE
1412 line_ids = [x[0] for x in cursor.fetchall()]
1413 if line_ids:
1414 # Get payment_orders and calculated total amounts as well in
1415@@ -740,6 +783,11 @@
1416 order_totals.keys()
1417 ))
1418 ]
1419+=======
1420+ payment_line_ids = [x[0] for x in cursor.fetchall()]
1421+ if payment_line_ids:
1422+ payment_lines = payment_line_obj.browse(cursor, uid, payment_line_ids)
1423+>>>>>>> MERGE-SOURCE
1424
1425 for statement in statements:
1426 if statement.local_account in error_accounts:
1427@@ -749,7 +797,7 @@
1428 continue
1429
1430 # Create fallback currency code
1431- currency_code = statement.local_currency or company.currency_id.code
1432+ currency_code = statement.local_currency or company.currency_id.name
1433
1434 # Check cache for account info/currency
1435 if statement.local_account in info and \
1436@@ -781,7 +829,7 @@
1437 continue
1438
1439 # Get required currency code
1440- currency_code = account_info.currency_id.code
1441+ currency_code = account_info.currency_id.name
1442
1443 # Cache results
1444 if not statement.local_account in info:
1445@@ -793,7 +841,7 @@
1446
1447 # Final check: no coercion of currencies!
1448 if statement.local_currency \
1449- and account_info.currency_id.code != statement.local_currency:
1450+ and account_info.currency_id.name != statement.local_currency:
1451 # TODO: convert currencies?
1452 results.log.append(
1453 _('Statement %(statement_id)s for account %(bank_account)s'
1454@@ -970,7 +1018,7 @@
1455 move_info = self._link_payment(
1456 cursor, uid, transaction,
1457 payment_lines, partner_ids,
1458- partner_banks, results.log
1459+ partner_banks, results.log, linked_payments,
1460 )
1461
1462 # Second guess, invoice -> may split transaction, so beware
1463@@ -980,7 +1028,7 @@
1464 # these, and invoice matching still has to be done.
1465 move_info, remainder = self._link_invoice(
1466 cursor, uid, transaction, move_lines, partner_ids,
1467- partner_banks, results.log
1468+ partner_banks, results.log, linked_invoices,
1469 )
1470 if remainder:
1471 injected.append(remainder)
1472@@ -1087,107 +1135,71 @@
1473 state = results.error_cnt and 'error' or 'ready'
1474 statement_file_obj.write(cursor, uid, import_id, dict(
1475 state = state, log = text_log,
1476- ))
1477- if results.error_cnt or not imported_statement_ids:
1478- self._nextstate = 'view_error'
1479- else:
1480- self._nextstate = 'view_statements'
1481- self._import_id = import_id
1482- self._log = text_log
1483- self._statement_ids = imported_statement_ids
1484- return {}
1485-
1486- def _action_open_window(self, cursor, uid, data, context):
1487- '''
1488- Open a window with the resulting bank statements
1489- '''
1490- # TODO: this needs fiddling. The resulting window is informative,
1491- # but not very usefull...
1492- module_obj = self.pool.get('ir.model.data')
1493- action_obj = self.pool.get('ir.actions.act_window')
1494- result = module_obj._get_id(
1495- cursor, uid, 'account', 'action_bank_statement_tree'
1496- )
1497- id = module_obj.read(cursor, uid, [result], ['res_id'])[0]['res_id']
1498- result = action_obj.read(cursor, uid, [id])[0]
1499- result['context'] = str({'banking_id': self._import_id})
1500- return result
1501-
1502- def _action_open_import(self, cursor, uid, data, context):
1503- '''
1504- Open a window with the resulting import in error
1505- '''
1506- return dict(
1507- view_type = 'form',
1508- view_mode = 'form,tree',
1509- res_model = 'account.banking.imported.file',
1510- view_id = False,
1511- type = 'ir.actions.act_window',
1512- res_id = self._import_id
1513- )
1514-
1515- def _check_next_state(self, cursor, uid, data, context):
1516- return self._nextstate
1517-
1518- states = {
1519- 'init' : {
1520- 'actions' : [],
1521- 'result' : {
1522- 'type' : 'form',
1523- 'arch' : import_form,
1524- 'fields': import_fields,
1525- 'state': [('end', '_Cancel', 'gtk-cancel'),
1526- ('import', '_Ok', 'gtk-ok'),
1527- ]
1528- }
1529- },
1530- 'import': {
1531- 'actions': [_import_statements_file],
1532- 'result': {
1533- 'type': 'choice',
1534- 'next_state': _check_next_state,
1535- }
1536- },
1537- 'view_statements' : {
1538- 'actions': [_fill_results],
1539- 'result': {
1540- 'type': 'form',
1541- 'arch': result_form,
1542- 'fields': result_fields,
1543- 'state': [('end', '_Close', 'gtk-close'),
1544- ('open_statements', '_View Statements', 'gtk-ok'),
1545- ]
1546- }
1547- },
1548- 'view_error': {
1549- 'actions': [_fill_results],
1550- 'result': {
1551- 'type': 'form',
1552- 'arch': result_form,
1553- 'fields': result_fields,
1554- 'state': [('end', '_Close', 'gtk-close'),
1555- ('open_import', '_View Imported File', 'gtk-ok'),
1556- ]
1557- }
1558- },
1559- 'open_import': {
1560- 'actions': [],
1561- 'result': {
1562- 'type': 'action',
1563- 'action': _action_open_import,
1564- 'state': 'end'
1565- }
1566- },
1567- 'open_statements': {
1568- 'actions': [],
1569- 'result': {
1570- 'type': 'action',
1571- 'action': _action_open_window,
1572- 'state': 'end'
1573- }
1574- },
1575- }
1576-
1577-banking_import('account_banking.banking_import')
1578+ ), context)
1579+ if not imported_statement_ids:
1580+ # file state can be 'ready' while import state is 'error'
1581+ state = 'error'
1582+ self.write(cursor, uid, [ids[0]], dict(
1583+ import_id = import_id, log = text_log, state = state,
1584+ statement_ids = [[6, 0, imported_statement_ids]],
1585+ ), context)
1586+ return {
1587+ 'name': _('Import Bank Transactions File'),
1588+ 'view_type': 'form',
1589+ 'view_mode': 'form',
1590+ 'view_id': False,
1591+ 'res_model': self._name,
1592+ 'domain': [],
1593+ 'context': dict(context, active_ids=ids),
1594+ 'type': 'ir.actions.act_window',
1595+ 'target': 'new',
1596+ 'res_id': ids[0] or False,
1597+ }
1598+
1599+ _columns = {
1600+ 'company': fields.many2one(
1601+ 'res.company', 'Company', required=True,
1602+ states={
1603+ 'ready': [('readonly', True)],
1604+ 'error': [('readonly', True)],
1605+ },
1606+ ),
1607+ 'file': fields.binary(
1608+ 'Statements File', required=True,
1609+ help = ('The Transactions File to import. Please note that while it is '
1610+ 'perfectly safe to reload the same file multiple times or to load in '
1611+ 'timeframe overlapping statements files, there are formats that may '
1612+ 'introduce different sequencing, which may create double entries.\n\n'
1613+ 'To stay on the safe side, always load bank statements files using the '
1614+ 'same format.'),
1615+ states={
1616+ 'ready': [('readonly', True)],
1617+ 'error': [('readonly', True)],
1618+ },
1619+ ),
1620+ 'parser': fields.selection(
1621+ parser_types, 'File Format', required=True,
1622+ states={
1623+ 'ready': [('readonly', True)],
1624+ 'error': [('readonly', True)],
1625+ },
1626+ ),
1627+ 'log': fields.text('Log', readonly=True),
1628+ 'state': fields.selection(
1629+ [('init', 'init'), ('ready', 'ready'),
1630+ ('error', 'error')],
1631+ 'State', readonly=True),
1632+ 'import_id': fields.many2one(
1633+ 'account.banking.imported.file', 'Import File'),
1634+ # osv_memory does not seem to support one2many
1635+ 'statement_ids': fields.many2many(
1636+ 'account.bank.statement', 'rel_wiz_statements', 'wizard_id',
1637+ 'statement_id', 'Imported Bank Statements'),
1638+ }
1639+
1640+ _defaults = {
1641+ 'state': 'init',
1642+ }
1643+banking_import()
1644
1645 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1646
1647=== added file 'account_banking/wizard/bank_import_view.xml'
1648--- account_banking/wizard/bank_import_view.xml 1970-01-01 00:00:00 +0000
1649+++ account_banking/wizard/bank_import_view.xml 2011-11-23 10:40:16 +0000
1650@@ -0,0 +1,52 @@
1651+<?xml version="1.0" encoding="utf-8"?>
1652+<openerp>
1653+ <data>
1654+ <record id="view_banking_import" model="ir.ui.view">
1655+ <field name="name">account.banking.bank.import</field>
1656+ <field name="model">account.banking.bank.import</field>
1657+ <field name="type">form</field>
1658+ <field name="arch" type="xml">
1659+ <form string="Import Bank Transactions File">
1660+ <group colspan="4">
1661+ <separator colspan="4" string="Select the processing details:"/>
1662+ <field name="company" colspan="1"/>
1663+ <field name="file"/>
1664+ <newline />
1665+ <field name="parser"/>
1666+ <field name="state" invisible="1"/>
1667+ </group>
1668+ <group colspan="4" states="ready,error">
1669+ <separator colspan="4" string="Results:"/>
1670+ <field name="log" colspan="4" nolabel="1" width="500"/>
1671+ </group>
1672+ <group colspan="4" states="ready">
1673+ <field name="statement_ids" colspan="4" nolabel="1"/>
1674+ </group>
1675+ <group colspan="2" states="init">
1676+ <button icon="gtk-cancel"
1677+ special="cancel"
1678+ string="Cancel"/>
1679+ <button icon="gtk-ok"
1680+ string="Import"
1681+ name="import_statements_file"
1682+ type="object"/>
1683+ </group>
1684+ <button icon="gtk-close"
1685+ special="cancel"
1686+ string="Close"
1687+ states="ready,error"/>
1688+ </form>
1689+ </field>
1690+ </record>
1691+
1692+ <record id="wizard_account_banking_import_file" model="ir.actions.act_window">
1693+ <field name="name">Import Bank Statements File</field>
1694+ <field name="type">ir.actions.act_window</field>
1695+ <field name="res_model">account.banking.bank.import</field>
1696+ <field name="view_type">form</field>
1697+ <field name="view_mode">tree,form</field>
1698+ <field name="view_id" ref="view_banking_import"/>
1699+ <field name="target">new</field>
1700+ </record>
1701+ </data>
1702+</openerp>
1703
1704=== modified file 'account_banking/wizard/banktools.py'
1705--- account_banking/wizard/banktools.py 2011-04-27 11:42:52 +0000
1706+++ account_banking/wizard/banktools.py 2011-11-23 10:40:16 +0000
1707@@ -216,12 +216,12 @@
1708 # Find matching journal for currency
1709 journal_obj = pool.get('account.journal')
1710 journal_ids = journal_obj.search(cursor, uid, [
1711- ('type', '=', 'cash'),
1712- ('currency', '=', currency or company.currency_id.code)
1713+ ('type', '=', 'bank'),
1714+ ('currency', '=', currency or company.currency_id.name)
1715 ])
1716- if not journal_ids and currency == company.currency_id.code:
1717+ if not journal_ids and currency == company.currency_id.name:
1718 journal_ids = journal_obj.search(cursor, uid, [
1719- ('type', '=', 'cash'), ('currency', '=', False)
1720+ ('type', '=', 'bank'), ('currency', '=', False)
1721 ])
1722 if journal_ids:
1723 criteria.append(('journal_id', 'in', journal_ids))
1724@@ -302,9 +302,9 @@
1725 else:
1726 info = struct(name=name, code=code)
1727
1728- if info.code and ((not online) or not bank_id):
1729+ if not online or not bank_id:
1730 bank_id = bank_obj.create(cursor, uid, dict(
1731- code = info.code,
1732+ code = info.code or 'UNKNOW',
1733 name = info.name or _('Unknown Bank'),
1734 country = country_id,
1735 bic = bic,
1736@@ -341,12 +341,18 @@
1737 cursor, uid, partner_id).country
1738 country_code = country.code
1739 country_id = country.id
1740- elif iban.valid:
1741- country_ids = country_obj.search(cursor, uid,
1742- [('code', '=', iban.countrycode)]
1743- )
1744+ else:
1745+ if iban.valid:
1746+ country_ids = country_obj.search(cursor, uid,
1747+ [('code', '=', iban.countrycode)]
1748+ )
1749+ else:
1750+ country_ids = country_obj.search(cursor, uid,
1751+ [('code', '=', country_code)]
1752+ )
1753 country_id = country_ids[0]
1754
1755+ account_info = False
1756 if not iban.valid:
1757 # No, try to convert to IBAN
1758 values.state = 'bank'
1759@@ -362,9 +368,11 @@
1760 bic = account_info.bic
1761
1762 if bic:
1763- values.bank_id = get_or_create_bank(pool, cursor, uid, bic)
1764+ values.bank = get_or_create_bank(pool, cursor, uid, bic)[0]
1765
1766- elif bankcode:
1767+ else:
1768+ if not bankcode:
1769+ bankcode = "UNKNOW"
1770 # Try to link bank
1771 bank_obj = pool.get('res.bank')
1772 bank_ids = bank_obj.search(cursor, uid, [
1773@@ -372,10 +380,10 @@
1774 ])
1775 if bank_ids:
1776 # Check BIC on existing banks
1777- values.bank_id = bank_ids[0]
1778- bank = bank_obj.browse(cursor, uid, values.bank_id)
1779+ values.bank = bank_ids[0]
1780+ bank = bank_obj.browse(cursor, uid, values.bank)
1781 if not bank.bic:
1782- bank_obj.write(cursor, uid, values.bank_id, dict(bic=bic))
1783+ bank_obj.write(cursor, uid, values.bank, dict(bic=bic))
1784 else:
1785 # New bank - create
1786 res = struct(country_id=country_id)
1787@@ -389,7 +397,7 @@
1788 res.code = bankcode
1789 res.name = _('Unknown Bank')
1790
1791- values.bank_id = bank_obj.create(cursor, uid, res)
1792+ values.bank = bank_obj.create(cursor, uid, res)
1793
1794 # Create bank account and return
1795 return pool.get('res.partner.bank').create(cursor, uid, values)
1796
1797=== removed file 'account_banking/wizard/wizard_payment_order.py'
1798--- account_banking/wizard/wizard_payment_order.py 2011-02-13 09:28:59 +0000
1799+++ account_banking/wizard/wizard_payment_order.py 1970-01-01 00:00:00 +0000
1800@@ -1,212 +0,0 @@
1801-# -*- encoding: utf-8 -*-
1802-##############################################################################
1803-#
1804-# Copyright (C) EduSense BV (<http://www.edusense.nl>).
1805-# All Rights Reserved.
1806-#
1807-# OpenERP, Open Source Management Solution
1808-# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
1809-#
1810-# This program is free software: you can redistribute it and/or modify
1811-# it under the terms of the GNU General Public License as published by
1812-# the Free Software Foundation, either version 3 of the License, or
1813-# (at your option) any later version.
1814-#
1815-# This program is distributed in the hope that it will be useful,
1816-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1817-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1818-# GNU General Public License for more details.
1819-#
1820-# You should have received a copy of the GNU General Public License
1821-# along with this program. If not, see <http://www.gnu.org/licenses/>.
1822-#
1823-##############################################################################
1824-import datetime
1825-import wizard
1826-import pooler
1827-from tools.misc import UpdateableStr
1828-from tools.translate import _
1829-from account_banking.struct import struct
1830-from account_banking.parsers import convert
1831-
1832-__doc__ = '''
1833-This module is a slightly modified version of the identical named payment
1834-order wizard in account_payment. The rationale for this bulk copy is the
1835-inability to inherit wizards in OpenERP versions prior to version 6.
1836-The modifications in this wizard allows invoices to create influence on the
1837-payment process: not only 'Free' references are allowed, but others as well.
1838-
1839-In order to allow further projects based on account_banking to inherit from
1840-this wizard, the complete wizard is made object oriented, as is should have
1841-been from the start.
1842-'''
1843-
1844-today = datetime.date.today
1845-
1846-def str2date(str):
1847- dt = convert.str2date(str, '%Y-%m-%d')
1848- return datetime.date(dt.year, dt.month, dt.day)
1849-
1850-class wizard_payment_order(wizard.interface):
1851- '''
1852- Create a payment object with lines corresponding to the account move line
1853- to pay according to the date and the mode provided by the user.
1854- Hypothesis:
1855- - Small number of non-reconcilied move line , payment mode and bank account type,
1856- - Big number of partner and bank account.
1857-
1858- If a type is given, unsuitable account move lines are ignored.
1859- '''
1860-
1861- FORM = UpdateableStr()
1862- FIELDS = {
1863- 'entries': {
1864- 'string':'Entries',
1865- 'type':'many2many',
1866- 'relation': 'account.move.line',
1867- },
1868- }
1869- field_duedate = {
1870- 'duedate': {
1871- 'string': 'Due Date',
1872- 'type': 'date',
1873- 'required': True,
1874- 'default': lambda *a: convert.date2str(today()),
1875- },
1876- }
1877- arch_duedate='''<?xml version="1.0"?>
1878- <form string="Search Payment lines">
1879- <field name="duedate" />
1880- </form>'''
1881-
1882-
1883- def search_entries(self, cursor, uid, data, context):
1884- '''
1885- Search for invoices that can be paid
1886- '''
1887- search_due_date = data['form']['duedate']
1888-
1889- pool = pooler.get_pool(cursor.dbname)
1890- order_obj = pool.get('payment.order')
1891- move_line_obj = pool.get('account.move.line')
1892-
1893- payment = order_obj.browse(cursor, uid, data['id'], context=context)
1894- if payment.mode:
1895- ctx = '''context="{'journal_id': %d}"''' % payment.mode.journal.id
1896- else:
1897- ctx = ''
1898-
1899- # Search account.move.line to pay:
1900- domain = [
1901- ('reconcile_id', '=', False),
1902- ('account_id.type', '=', 'payable'),
1903- ('amount_to_pay', '>', 0),
1904- '|', ('date_maturity','<=',search_due_date),
1905- ('date_maturity','=',False)
1906- ]
1907- line_ids = move_line_obj.search(cursor, uid, domain, context=context)
1908- self.FORM.string = '''<?xml version="1.0"?>
1909- <form string="Populate Payment:">
1910- <field name="entries" colspan="4" height="300" width="800" nolabel="1"
1911- domain="[('id', 'in', [%s])]" %s
1912- />
1913- </form>''' % (','.join([str(x) for x in line_ids]), ctx)
1914- return {}
1915-
1916- def get_communication(self, line):
1917- '''
1918- Method to fill the communication and communication2 lines of a payment
1919- line. Returns (state, comm1, comm2).
1920- '''
1921- if line.invoice.reference_type == 'structured':
1922- return ('structured', line.invoice.reference, '')
1923- return ('normal', '', line.invoice.reference)
1924-
1925- def create_payment(self, cursor, uid, data, context):
1926- '''
1927- Create payment lines from the data of previously created payable
1928- invoices
1929- '''
1930- ids = data['form']['entries'][0][2]
1931- if not ids:
1932- return {}
1933-
1934- pool = pooler.get_pool(cursor.dbname)
1935- order_obj = pool.get('payment.order')
1936- move_line_obj = pool.get('account.move.line')
1937- payment_line_obj = pool.get('payment.line')
1938-
1939- payment = order_obj.browse(cursor, uid, data['id'], context=context)
1940- ptype = payment.mode and payment.mode.type.id or None
1941- line2bank = move_line_obj.line2bank(cursor, uid, ids, ptype, context)
1942- _today = today()
1943- retval = struct()
1944-
1945- # Populate the current payment with new lines
1946- for line in move_line_obj.browse(cursor, uid, ids, context=context):
1947- if payment.date_prefered == 'now':
1948- # no payment date means immediate payment
1949- date_to_pay = False
1950- elif payment.date_prefered == 'due':
1951- date_to_pay = line.date_maturity and \
1952- str2date(line.date_maturity) > _today\
1953- and line.date_maturity or False
1954- elif payment.date_prefered == 'fixed':
1955- date_to_pay = payment.date_planned and \
1956- str2date(payment.date_planned) > _today\
1957- and payment.date_planned or False
1958- values = struct(
1959- move_line_id = line.id,
1960- amount_currency = line.amount_to_pay,
1961- bank_id = line2bank.get(line.id),
1962- order_id = payment.id,
1963- partner_id = line.partner_id and line.partner_id.id or False,
1964- date = date_to_pay,
1965- currency = False,
1966- )
1967- if line.invoice:
1968- values.state, values.communication, values.communication2 = \
1969- self.get_communication(line)
1970- values.currency = line.invoice.currency_id.id,
1971- payment_line_obj.create(cursor, uid, values, context=context)
1972-
1973- return {}
1974-
1975- states = {
1976- 'init': {
1977- 'actions': [],
1978- 'result': {
1979- 'type': 'form',
1980- 'arch': arch_duedate,
1981- 'fields': field_duedate,
1982- 'state': [
1983- ('end','_Cancel'),
1984- ('search','_Search', '', True)
1985- ]
1986- },
1987- },
1988- 'search': {
1989- 'actions': [search_entries],
1990- 'result': {
1991- 'type': 'form',
1992- 'arch': FORM,
1993- 'fields': FIELDS,
1994- 'state': [
1995- ('end','_Cancel'),
1996- ('create','_Add to payment order', '', True)
1997- ]
1998- },
1999- },
2000- 'create': {
2001- 'actions': [],
2002- 'result': {
2003- 'type': 'action',
2004- 'action': create_payment,
2005- 'state': 'end'
2006- }
2007- },
2008- }
2009-
2010-wizard_payment_order('account_payment.populate_payment')
2011-
2012-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2013
2014=== modified file 'account_banking_fi_patu/__terp__.py'
2015--- account_banking_fi_patu/__terp__.py 2011-11-08 13:10:34 +0000
2016+++ account_banking_fi_patu/__terp__.py 2011-11-23 10:40:16 +0000
2017@@ -33,9 +33,8 @@
2018 'category': 'Account Banking',
2019 'depends': ['account_banking'],
2020 'description': '''
2021- Module to import Finnish PATU format transation files.
2022-
2023- This modules contains no logic, just an import filter for account_banking.
2024+Do not install this module. This branch has been replaced by lp:banking-addons/6.0
2025+See https://launchpad.net/banking-addons
2026 ''',
2027 'active': False,
2028 'installable': True,
2029
2030=== modified file 'account_banking_nl_abnamro/__openerp__.py'
2031--- account_banking_nl_abnamro/__openerp__.py 2011-04-26 21:00:12 +0000
2032+++ account_banking_nl_abnamro/__openerp__.py 2011-11-23 10:40:16 +0000
2033@@ -39,14 +39,8 @@
2034 ],
2035 'demo_xml': [],
2036 'description': '''
2037-Import filter for abnamro (NL) bank transaction files (txt/tab format).
2038-
2039-No formal specifications of the file layout are released by abnamro. You can
2040-help improve the performance of this import filter on
2041-https://launchpad.net/account-banking.
2042-
2043-Imported bank transfers are organized in statements covering periods of one week,
2044-even if the imported files cover a different period.
2045+Do not install this module. This branch has been replaced by lp:banking-addons/6.0
2046+See https://launchpad.net/banking-addons
2047 ''',
2048 'active': False,
2049 'installable': True,
2050
2051=== modified file 'account_banking_nl_abnamro/__terp__.py'
2052--- account_banking_nl_abnamro/__terp__.py 2011-11-08 13:10:34 +0000
2053+++ account_banking_nl_abnamro/__terp__.py 2011-11-23 10:40:16 +0000
2054@@ -39,14 +39,8 @@
2055 ],
2056 'demo_xml': [],
2057 'description': '''
2058-Import filter for abnamro (NL) bank transaction files (txt/tab format).
2059-
2060-No formal specifications of the file layout are released by abnamro. You can
2061-help improve the performance of this import filter on
2062-https://launchpad.net/account-banking.
2063-
2064-Imported bank transfers are organized in statements covering periods of one week,
2065-even if the imported files cover a different period.
2066+Do not install this module. This branch has been replaced by lp:banking-addons/6.0
2067+See https://launchpad.net/banking-addons
2068 ''',
2069 'active': False,
2070 'installable': True,
2071
2072=== modified file 'account_banking_nl_clieop/__terp__.py'
2073--- account_banking_nl_clieop/__terp__.py 2011-11-08 13:10:34 +0000
2074+++ account_banking_nl_clieop/__terp__.py 2011-11-23 10:40:16 +0000
2075@@ -25,7 +25,11 @@
2076 ##############################################################################
2077 {
2078 'name': 'Account Banking NL ClieOp',
2079+<<<<<<< TREE
2080 'version': '0.67',
2081+=======
2082+ 'version': '0.63',
2083+>>>>>>> MERGE-SOURCE
2084 'license': 'GPL-3',
2085 'author': 'EduSense BV',
2086 'website': 'http://www.edusense.nl',
2087@@ -33,17 +37,15 @@
2088 'depends': ['account_banking'],
2089 'init_xml': [],
2090 'update_xml': [
2091- #'security/ir.model.access.csv',
2092 'account_banking_nl_clieop.xml',
2093- 'account_banking_export_wizard.xml',
2094+ 'wizard/export_clieop_view.xml',
2095 'data/banking_export_clieop.xml',
2096+ 'security/ir.model.access.csv',
2097 ],
2098 'demo_xml': [],
2099 'description': '''
2100- Module to export payment orders in ClieOp format.
2101-
2102- ClieOp format is used by Dutch banks to batch national bank transfers.
2103- This module uses the account_banking logic.
2104+Do not install this module. This branch has been replaced by lp:banking-addons/6.0
2105+See https://launchpad.net/banking-addons
2106 ''',
2107 'active': False,
2108 'installable': True,
2109
2110=== removed file 'account_banking_nl_clieop/account_banking_export_wizard.xml'
2111--- account_banking_nl_clieop/account_banking_export_wizard.xml 2010-01-26 20:55:24 +0000
2112+++ account_banking_nl_clieop/account_banking_export_wizard.xml 1970-01-01 00:00:00 +0000
2113@@ -1,15 +0,0 @@
2114-<?xml version="1.0" encoding="utf-8"?>
2115-<!--
2116- Copyright (C) EduSense BV <http://www.edusense.nl>
2117- All rights reserved.
2118- The licence is in the file __terp__.py
2119--->
2120-<openerp>
2121- <data>
2122- <wizard id="wizard_account_banking_export_clieop"
2123- string="Export ClieOp File"
2124- model="payment.order"
2125- name="account_banking_nl_clieop.banking_export_clieop"
2126- />
2127- </data>
2128-</openerp>
2129
2130=== modified file 'account_banking_nl_clieop/account_banking_nl_clieop.py'
2131--- account_banking_nl_clieop/account_banking_nl_clieop.py 2010-01-26 20:55:24 +0000
2132+++ account_banking_nl_clieop/account_banking_nl_clieop.py 2011-11-23 10:40:16 +0000
2133@@ -22,25 +22,19 @@
2134 from datetime import date
2135 from tools.translate import _
2136
2137-class payment_order(osv.osv):
2138- '''
2139- Attach export_clieop wizard to payment order and allow traceability
2140- '''
2141- _inherit = 'payment.order'
2142- def get_wizard(self, type):
2143- if type in ['CLIEOPPAY', 'CLIEOPINC', 'CLIEOPSAL']:
2144- return self._module, 'wizard_account_banking_export_clieop'
2145- return super(payment_order, self).get_wizard(type)
2146-payment_order()
2147-
2148 class clieop_export(osv.osv):
2149 '''ClieOp3 Export'''
2150 _name = 'banking.export.clieop'
2151 _description = __doc__
2152+ _rec_name = 'identification'
2153
2154 _columns = {
2155- 'payment_order_ids':
2156- fields.text('Payment Orders'),
2157+ 'payment_order_ids': fields.many2many(
2158+ 'payment.order',
2159+ 'account_payment_order_clieop_rel',
2160+ 'banking_export_clieop_id', 'account_order_id',
2161+ 'Payment Orders',
2162+ readonly=True),
2163 'testcode':
2164 fields.selection([('T', _('Yes')), ('P', _('No'))],
2165 'Test Run', readonly=True),
2166
2167=== modified file 'account_banking_nl_clieop/account_banking_nl_clieop.xml'
2168--- account_banking_nl_clieop/account_banking_nl_clieop.xml 2010-01-28 10:59:35 +0000
2169+++ account_banking_nl_clieop/account_banking_nl_clieop.xml 2011-11-23 10:40:16 +0000
2170@@ -14,19 +14,33 @@
2171 <field name="type">form</field>
2172 <field name="arch" type="xml">
2173 <form string="Client Opdrachten Export">
2174- <separator string="General Information" colspan="4" />
2175- <field name="filetype" />
2176- <field name="identification" />
2177- <separator string="ClieOp Information" colspan="4" />
2178- <field name="total_amount" />
2179- <field name="check_no_accounts" />
2180- <field name="no_transactions" />
2181- <separator string="Processing Information" colspan="4" />
2182- <field name="prefered_date" />
2183- <field name="date_generated" />
2184- <field name="testcode" />
2185- <newline />
2186- <field name="file" colspan="4" />
2187+ <notebook>
2188+ <page string="General Information">
2189+ <field name="filetype" />
2190+ <field name="identification" />
2191+ <separator string="ClieOp Information" colspan="4" />
2192+ <field name="total_amount" />
2193+ <field name="check_no_accounts" />
2194+ <field name="no_transactions" />
2195+ <separator string="Processing Information" colspan="4" />
2196+ <field name="prefered_date" />
2197+ <field name="date_generated" />
2198+ <field name="testcode" />
2199+ <newline />
2200+ <field name="file" colspan="4" />
2201+ </page>
2202+ <page string="Payment Orders">
2203+ <field name="payment_order_ids" colspan="4" nolabel="1">
2204+ <tree colors="blue:state in ('draft');gray:state in ('cancel','done');black:state in ('open')" string="Payment order">
2205+ <field name="reference"/>
2206+ <field name="date_created"/>
2207+ <field name="date_done"/>
2208+ <field name="total"/>
2209+ <field name="state"/>
2210+ </tree>
2211+ </field>
2212+ </page>
2213+ </notebook>
2214 </form>
2215 </field>
2216 </record>
2217@@ -59,5 +73,14 @@
2218 sequence="12"
2219 />
2220
2221+ <!-- Create right menu entry to see generated files -->
2222+ <act_window name="Generated ClieOp3 Files"
2223+ domain="[('payment_order_ids', '=', active_id)]"
2224+ res_model="banking.export.clieop"
2225+ src_model="payment.order"
2226+ view_type="form"
2227+ view_mode="tree,form"
2228+ id="act_banking_export_clieop_payment_order"/>
2229+
2230 </data>
2231 </openerp>
2232
2233=== modified file 'account_banking_nl_clieop/data/banking_export_clieop.xml'
2234--- account_banking_nl_clieop/data/banking_export_clieop.xml 2010-12-20 10:58:51 +0000
2235+++ account_banking_nl_clieop/data/banking_export_clieop.xml 2011-11-23 10:40:16 +0000
2236@@ -1,25 +1,31 @@
2237 <?xml version="1.0" encoding="utf-8"?>
2238 <openerp>
2239 <data noupdate="1">
2240- <record model="payment.type" id="account_banking_nl_clieop.export_clieop_inc">
2241+ <record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_inc">
2242 <field name="name">ClieOp3 Direct Debit Batch</field>
2243 <field name="code">CLIEOPINC</field>
2244 <field name="suitable_bank_types"
2245 eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
2246+ <field name="ir_model_id"
2247+ ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
2248 </record>
2249
2250- <record model="payment.type" id="account_banking_nl_clieop.export_clieop_pay">
2251+ <record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_pay">
2252 <field name="name">ClieOp3 Payment Batch</field>
2253 <field name="code">CLIEOPPAY</field>
2254 <field name="suitable_bank_types"
2255 eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
2256+ <field name="ir_model_id"
2257+ ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
2258 </record>
2259
2260- <record model="payment.type" id="account_banking_nl_clieop.export_clieop_sal">
2261+ <record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_sal">
2262 <field name="name">ClieOp3 Salary Payment Batch</field>
2263 <field name="code">CLIEOPSAL</field>
2264 <field name="suitable_bank_types"
2265 eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
2266+ <field name="ir_model_id"
2267+ ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
2268 </record>
2269 </data>
2270 </openerp>
2271
2272=== added directory 'account_banking_nl_clieop/migrations'
2273=== added directory 'account_banking_nl_clieop/migrations/0.63'
2274=== added file 'account_banking_nl_clieop/migrations/0.63/post-fill-ir_model_id.py'
2275--- account_banking_nl_clieop/migrations/0.63/post-fill-ir_model_id.py 1970-01-01 00:00:00 +0000
2276+++ account_banking_nl_clieop/migrations/0.63/post-fill-ir_model_id.py 2011-11-23 10:40:16 +0000
2277@@ -0,0 +1,44 @@
2278+# -*- coding: utf-8 -*-
2279+##############################################################################
2280+#
2281+# Copyright (C) 2011 Therp BV (<http://therp.nl>)
2282+#
2283+# This program is free software: you can redistribute it and/or modify
2284+# it under the terms of the GNU General Public License as published by
2285+# the Free Software Foundation, either version 3 of the License, or
2286+# (at your option) any later version.
2287+#
2288+# This program is distributed in the hope that it will be useful,
2289+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2290+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2291+# GNU General Public License for more details.
2292+#
2293+# You should have received a copy of the GNU General Public License
2294+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2295+#
2296+##############################################################################
2297+
2298+""" This script covers the migration of the payment wizards from old style to
2299+new style (osv_memory). It guarantees an easy upgrade for early adopters
2300+of the 6.0 branch of this OpenERP module. Note that a migration from OpenERP
2301+5.0 to OpenERP 6.0 with respect to this module is not covered by this script.
2302+"""
2303+
2304+__name__ = "payment.mode.type:: Add new style payment wizards to existing payment mode types"
2305+
2306+def migrate(cr, version):
2307+ cr.execute ("UPDATE payment_mode_type"
2308+ " SET ir_model_id = data1.res_id"
2309+ " FROM ir_model_data data1,"
2310+ " ir_model_data data2"
2311+ " WHERE data2.res_id = payment_mode_type.id"
2312+ " AND data1.module = 'account_banking_nl_clieop'"
2313+ " AND data1.model = 'ir.model'"
2314+ " AND data1.name = 'model_banking_export_clieop_wizard'"
2315+ " AND data2.module = 'account_banking_nl_clieop'"
2316+ " AND data2.model = 'payment.mode.type'"
2317+ " AND data2.name IN ('export_clieop_inc',"
2318+ " 'export_clieop_pay',"
2319+ " 'export_clieop_sal'"
2320+ " )"
2321+ )
2322
2323=== added directory 'account_banking_nl_clieop/security'
2324=== added file 'account_banking_nl_clieop/security/ir.model.access.csv'
2325--- account_banking_nl_clieop/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
2326+++ account_banking_nl_clieop/security/ir.model.access.csv 2011-11-23 10:40:16 +0000
2327@@ -0,0 +1,2 @@
2328+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
2329+"access_banking_export_clieop","banking.export.clieop","model_banking_export_clieop","account_payment.group_account_payment",1,1,1,1
2330
2331=== modified file 'account_banking_nl_clieop/wizard/clieop.py'
2332--- account_banking_nl_clieop/wizard/clieop.py 2011-03-10 15:25:05 +0000
2333+++ account_banking_nl_clieop/wizard/clieop.py 2011-11-23 10:40:16 +0000
2334@@ -76,7 +76,7 @@
2335
2336 def __init__(self, id='1', seqno=1, duplicate=False):
2337 super(HeaderRecord, self).__init__()
2338- self.sender_id = id
2339+ self.sender_id = id or ''
2340 self.file_id = '%02d%02d' % (self.creation_date.day, seqno)
2341 self.duplicatecode = duplicate and '2' or '1'
2342 #}}}
2343@@ -362,7 +362,7 @@
2344 self.header.variantcode = batch_id and 'C' or 'B'
2345 self.header.transactiongroup = transactiongroup
2346 self.header.batch_tracer = batch_tracer
2347- self.header.batch_id = batch_id
2348+ self.header.batch_id = batch_id or ''
2349 self.header.accountno_sender = rekeningnr
2350 self.sender.name_sender = sender
2351 self.sender.preferred_execution_date = execution_date
2352
2353=== modified file 'account_banking_nl_clieop/wizard/export_clieop.py'
2354--- account_banking_nl_clieop/wizard/export_clieop.py 2011-02-12 13:37:09 +0000
2355+++ account_banking_nl_clieop/wizard/export_clieop.py 2011-11-23 10:40:16 +0000
2356@@ -19,12 +19,11 @@
2357 #
2358 ##############################################################################
2359
2360-import wizard
2361-import pooler
2362 import base64
2363 from datetime import datetime, date, timedelta
2364+from osv import osv, fields
2365+from tools.translate import _
2366 from account_banking import sepa
2367-from tools.translate import _
2368 import clieop
2369
2370 def strpdate(arg, format='%Y-%m-%d'):
2371@@ -35,151 +34,131 @@
2372 '''shortcut'''
2373 return arg.strftime(format)
2374
2375-class wizard_banking_export_clieop(wizard.interface):
2376- form = '''<?xml version="1.0"?>
2377-<form string="Client Opdrachten Export">
2378- <separator colspan="4" string="Processing Details" />
2379- <field name="batchtype" />
2380- <field name="execution_date" />
2381- <field name="test" />
2382- <separator colspan="4" string="Reference for further communication" />
2383- <field name="reference" colspan="2" />
2384- <separator colspan="4" string="Additional message for all transactions" />
2385- <field name="fixed_message" />
2386-</form>'''
2387-
2388- fields = {
2389- 'reference' : {
2390- 'string': 'Reference',
2391- 'type': 'char',
2392- 'size': 5,
2393- 'required': False,
2394- 'help': ('The bank will use this reference in feedback communication '
2395- 'to refer to this run. Only five characters are available.'
2396- )
2397- },
2398- 'batchtype': {
2399- 'string': 'Type',
2400- 'type': 'selection',
2401- 'selection': [
2402+class banking_export_clieop_wizard(osv.osv_memory):
2403+ _name = 'banking.export.clieop.wizard'
2404+ _description = 'Client Opdrachten Export'
2405+ _columns = {
2406+ 'state': fields.selection(
2407+ [
2408+ ('create', 'Create'),
2409+ ('finish', 'Finish')
2410+ ],
2411+ 'State',
2412+ readonly=True,
2413+ ),
2414+ 'reference': fields.char(
2415+ 'Reference', size=5,
2416+ help=('The bank will use this reference in feedback communication '
2417+ 'to refer to this run. Only five characters are available.'
2418+ ),
2419+ ),
2420+ 'batchtype': fields.selection(
2421+ [
2422 ('CLIEOPPAY', 'Payments'),
2423 ('CLIEOPSAL', 'Salary Payments'),
2424 ('CLIEOPINC', 'Direct Debits'),
2425- ],
2426- 'readonly': True,
2427- },
2428- 'execution_date': {
2429- 'string': 'Execution Date',
2430- 'type': 'date',
2431- 'required': False,
2432- 'help': ('This is the date the file should be processed by the bank. '
2433- 'Don\'t choose a date beyond the nearest date in your '
2434- 'payments. The latest allowed date is 30 days from now.\n'
2435- 'Please keep in mind that banks only execute on working days '
2436- 'and typically use a delay of two days between execution date '
2437- 'and effective transfer date.'
2438- ),
2439- },
2440- 'test': {
2441- 'string': 'Test Run',
2442- 'type': 'boolean',
2443- 'required': True,
2444- 'default': True,
2445- 'help': ('Select this if you want your bank to run a test process '
2446- 'rather then execute your orders for real.'
2447- )
2448- },
2449- 'fixed_message': {
2450- 'string': 'Fixed Message',
2451- 'type': 'char',
2452- 'size': 32,
2453- 'required': False,
2454- 'default': '',
2455- 'help': ('A fixed message to apply to all transactions in addition to '
2456- 'the individual messages.'
2457- ),
2458- },
2459- }
2460-
2461- file_form = '''<?xml version="1.0"?>
2462-<form string="Client Opdrachten Export">
2463- <field name="filetype" />
2464- <field name="identification" />
2465- <field name="total_amount" />
2466- <field name="check_no_accounts" />
2467- <field name="no_transactions" />
2468- <field name="prefered_date" />
2469- <field name="testcode" />
2470- <newline/>
2471- <field name="file" />
2472- <field name="log" colspan="4" nolabel="1" />
2473-</form>'''
2474-
2475- file_fields = {
2476- 'testcode': {
2477- 'string': 'Test Run',
2478- 'type': 'selection',
2479- 'selection': [('T', _('Yes')), ('P', _('No'))],
2480- 'required': False,
2481- 'readonly': True,
2482- },
2483- 'prefered_date': {
2484- 'string': 'Prefered Processing Date',
2485- 'type': 'date',
2486- 'required': False,
2487- 'readonly': True,
2488- },
2489- 'no_transactions': {
2490- 'string': 'Number of Transactions',
2491- 'type': 'int',
2492- 'required': False,
2493- 'readonly': True,
2494- },
2495- 'check_no_accounts': {
2496- 'string': 'Check Number Accounts',
2497- 'type': 'char',
2498- 'size': 5,
2499- 'required': False,
2500- 'readonly': True,
2501- },
2502- 'total_amount': {
2503- 'string': 'Total Amount',
2504- 'type': 'float',
2505- 'required': False,
2506- 'readonly': True,
2507- },
2508- 'identification': {
2509- 'string': 'Identification',
2510- 'type': 'char',
2511- 'size': 6,
2512- 'required': False,
2513- 'readonly': True,
2514- },
2515- 'filetype': {
2516- 'string': 'File Type',
2517- 'type': 'selection',
2518- 'selection': [
2519+ ], 'Type', readonly=True,
2520+ ),
2521+ 'execution_date': fields.date(
2522+ 'Execution Date',
2523+ help=('This is the date the file should be processed by the bank. '
2524+ 'Don\'t choose a date beyond the nearest date in your '
2525+ 'payments. The latest allowed date is 30 days from now.\n'
2526+ 'Please keep in mind that banks only execute on working days '
2527+ 'and typically use a delay of two days between execution date '
2528+ 'and effective transfer date.'
2529+ ),
2530+ ),
2531+ 'test': fields.boolean(
2532+ 'Test Run',
2533+ help=('Select this if you want your bank to run a test process '
2534+ 'rather then execute your orders for real.'
2535+ ),
2536+ ),
2537+ 'fixed_message': fields.char(
2538+ 'Fixed Message', size=32,
2539+ help=('A fixed message to apply to all transactions in addition to '
2540+ 'the individual messages.'
2541+ ),
2542+ ),
2543+ # file fields
2544+ 'file_id': fields.many2one(
2545+ 'banking.export.clieop',
2546+ 'ClieOp File',
2547+ readonly=True
2548+ ),
2549+ # fields.related does not seem to support
2550+ # fields of type selection
2551+ 'testcode': fields.selection(
2552+ [('T', _('Yes')), ('P', _('No'))],
2553+ 'Test Run', readonly=True,
2554+ ),
2555+ 'filetype': fields.selection(
2556+ [
2557 ('CREDBET', 'Payment Batch'),
2558 ('SALARIS', 'Salary Payment Batch'),
2559 ('INCASSO', 'Direct Debit Batch'),
2560- ],
2561- 'required': False,
2562- 'readonly': True,
2563- },
2564- 'file': {
2565- 'string': 'ClieOp File',
2566- 'type': 'binary',
2567- 'required': False,
2568- 'readonly': True,
2569- },
2570- 'log': {
2571- 'string': 'Log',
2572- 'type': 'text',
2573- 'readonly': True,
2574- },
2575- }
2576-
2577- def _check_orders(self, cursor, uid, data, context):
2578+ ],
2579+ 'File Type',
2580+ readonly=True,
2581+ ),
2582+ 'prefered_date': fields.related(
2583+ 'file_id', 'prefered_date',
2584+ type='date',
2585+ string='Prefered Processing Date',
2586+ readonly=True,
2587+ ),
2588+ 'no_transactions': fields.related(
2589+ 'file_id', 'no_transactions',
2590+ type ='integer',
2591+ string='Number of Transactions',
2592+ readonly=True,
2593+ ),
2594+ 'check_no_accounts': fields.related(
2595+ 'file_id', 'check_no_accounts',
2596+ type='char', size=5,
2597+ string='Check Number Accounts',
2598+ readonly=True,
2599+ ),
2600+ 'total_amount': fields.related(
2601+ 'file_id', 'total_amount',
2602+ type='float',
2603+ string='Total Amount',
2604+ readonly=True,
2605+ ),
2606+ 'identification': fields.related(
2607+ 'file_id', 'identification',
2608+ type='char', size=6,
2609+ string='Identification',
2610+ readonly=True,
2611+ ),
2612+ 'file': fields.related(
2613+ 'file_id', 'file', type='binary',
2614+ readonly=True,
2615+ string='File',
2616+ ),
2617+ 'payment_order_ids': fields.many2many(
2618+ 'payment.order', 'rel_wiz_payorders', 'wizard_id',
2619+ 'payment_order_id', 'Payment Orders',
2620+ readonly=True,
2621+ ),
2622+ }
2623+
2624+ _defaults = {
2625+ 'test': True,
2626+ }
2627+
2628+ def create(self, cursor, uid, vals, context=None):
2629+ '''
2630+ Retrieve a sane set of default values based on the payment orders
2631+ from the context.
2632+ '''
2633+ if 'batchtype' not in vals:
2634+ self.check_orders(cursor, uid, vals, context)
2635+ return super(banking_export_clieop_wizard, self).create(
2636+ cursor, uid, vals, context)
2637+
2638+ def check_orders(self, cursor, uid, vals, context):
2639 '''
2640 Check payment type for all orders.
2641
2642@@ -191,14 +170,14 @@
2643 Also mind that rates for batches are way higher than those for
2644 transactions. It pays to limit the number of batches.
2645 '''
2646- form = data['form']
2647 today = date.today()
2648- pool = pooler.get_pool(cursor.dbname)
2649- payment_order_obj = pool.get('payment.order')
2650+ payment_order_obj = self.pool.get('payment.order')
2651
2652+ # Payment order ids are provided in the context
2653+ payment_order_ids = context.get('active_ids', [])
2654 runs = {}
2655 # Only orders of same type can be combined
2656- payment_orders = payment_order_obj.browse(cursor, uid, data['ids'])
2657+ payment_orders = payment_order_obj.browse(cursor, uid, payment_order_ids)
2658 for payment_order in payment_orders:
2659
2660 payment_type = payment_order.mode.type.code
2661@@ -226,34 +205,33 @@
2662 else:
2663 execution_date = today
2664 if execution_date and execution_date >= max_date:
2665- raise wizard.except_wizard(
2666+ raise osv.except_osv(
2667 _('Error'),
2668 _('You can\'t create ClieOp orders more than 30 days in advance.')
2669 )
2670- # Sanity check: can't process in the past
2671- form['execution_date'] = strfdate(max(execution_date, today))
2672-
2673 if len(runs) != 1:
2674- raise wizard.except_wizard(
2675+ raise osv.except_osv(
2676 _('Error'),
2677 _('You can only combine payment orders of the same type')
2678 )
2679
2680- form['batchtype'] = type = runs.keys()[0]
2681- form['reference'] = runs[type][0].reference[-5:]
2682- return form
2683+ type = runs.keys()[0]
2684+ vals.update({
2685+ 'execution_date': strfdate(max(execution_date, today)),
2686+ 'batchtype': type,
2687+ 'reference': runs[type][0].reference[-5:],
2688+ 'payment_order_ids': [[6, 0, payment_order_ids]],
2689+ 'state': 'create',
2690+ })
2691
2692- def _create_clieop(self, cursor, uid, data, context):
2693+ def create_clieop(self, cursor, uid, ids, context):
2694 '''
2695 Wizard to actually create the ClieOp3 file
2696 '''
2697- pool = pooler.get_pool(cursor.dbname)
2698- payment_order_obj = pool.get('payment.order')
2699- form = data['form']
2700-
2701+ payment_order_obj = self.pool.get('payment.order')
2702+ clieop_export = self.browse(cursor, uid, ids, context)[0]
2703 clieopfile = None
2704- payment_orders = payment_order_obj.browse(cursor, uid, data['ids'])
2705- for payment_order in payment_orders:
2706+ for payment_order in clieop_export.payment_order_ids:
2707 if not clieopfile:
2708 # Just once: create clieop file
2709 our_account_owner = payment_order.mode.bank_id.owner_name \
2710@@ -264,19 +242,19 @@
2711 payment_order.mode.bank_id.iban
2712 ).localized_BBAN
2713 if not our_account_nr:
2714- raise wizard.except_wizard(
2715+ raise osv.except_osv(
2716 _('Error'),
2717 _('Your bank account has to have a valid account number')
2718 )
2719 clieopfile = {'CLIEOPPAY': clieop.PaymentsFile,
2720 'CLIEOPINC': clieop.DirectDebitFile,
2721 'CLIEOPSAL': clieop.SalaryPaymentsFile,
2722- }[form['batchtype']](
2723- identification = form['reference'],
2724- execution_date = form['execution_date'],
2725+ }[clieop_export['batchtype']](
2726+ identification = clieop_export['reference'],
2727+ execution_date = clieop_export['execution_date'],
2728 name_sender = our_account_owner,
2729 accountno_sender = our_account_nr,
2730- test = form['test']
2731+ test = clieop_export['test']
2732 )
2733
2734 # ClieOp3 files can contain multiple batches, but we put all
2735@@ -285,21 +263,21 @@
2736 # cheaper to combine than it is to split. As we split out all
2737 # reported errors afterwards, there is no additional gain in
2738 # using multiple batches.
2739- if form['fixed_message']:
2740- messages = [form['fixed_message']]
2741+ if clieop_export['fixed_message']:
2742+ messages = [clieop_export['fixed_message']]
2743 else:
2744 messages = []
2745 # The first payment order processed sets the reference of the
2746 # batch.
2747 batch = clieopfile.batch(
2748 messages = messages,
2749- batch_id = payment_order.reference
2750+ batch_id = clieop_export['reference']
2751 )
2752
2753 for line in payment_order.line_ids:
2754 # Check on missing partner of bank account (this can happen!)
2755 if not line.bank_id or not line.bank_id.partner_id:
2756- raise wizard.except_wizard(
2757+ raise osv.except_osv(
2758 _('Error'),
2759 _('There is insufficient information.\r\n'
2760 'Both destination address and account '
2761@@ -318,13 +296,13 @@
2762 # Is this an IBAN account?
2763 if iban.valid:
2764 if iban.countrycode != 'NL':
2765- raise wizard.except_wizard(
2766+ raise osv.except_osv(
2767 _('Error'),
2768 _('You cannot send international bank transfers '
2769 'through ClieOp3!')
2770 )
2771 other_account_nr = iban.localized_BBAN
2772- if form['batchtype'] == 'CLIEOPINC':
2773+ if clieop_export['batchtype'] == 'CLIEOPINC':
2774 kwargs['accountno_beneficiary'] = our_account_nr
2775 kwargs['accountno_payer'] = other_account_nr
2776 else:
2777@@ -334,86 +312,63 @@
2778
2779 # Generate the specifics of this clieopfile
2780 order = clieopfile.order
2781- values = dict(
2782- filetype = order.name_transactioncode,
2783- identification = order.identification,
2784- prefered_date = strfdate(order.preferred_execution_date),
2785- total_amount = int(order.total_amount) / 100.0,
2786- check_no_accounts = order.total_accountnos,
2787- no_transactions = order.nr_posts,
2788- testcode = order.testcode,
2789- file = base64.encodestring(clieopfile.rawdata),
2790- )
2791- form.update(values)
2792- values['daynumber'] = int(clieopfile.header.file_id[2:])
2793- values['payment_order_ids'] = ','.join(map(str, data['ids']))
2794- data['file_id'] = pool.get('banking.export.clieop').create(cursor, uid, values)
2795- data['clieop'] = clieopfile
2796- form['log'] = ''
2797- return form
2798+ file_id = self.pool.get('banking.export.clieop').create(
2799+ cursor, uid, dict(
2800+ filetype = order.name_transactioncode,
2801+ identification = order.identification,
2802+ prefered_date = strfdate(order.preferred_execution_date),
2803+ total_amount = int(order.total_amount) / 100.0,
2804+ check_no_accounts = order.total_accountnos,
2805+ no_transactions = order.nr_posts,
2806+ testcode = order.testcode,
2807+ file = base64.encodestring(clieopfile.rawdata),
2808+ daynumber = int(clieopfile.header.file_id[2:]),
2809+ payment_order_ids = [
2810+ [6, 0, [x.id for x in clieop_export['payment_order_ids']]]
2811+ ],
2812+ ), context)
2813+ self.write(cursor, uid, [ids[0]], dict(
2814+ filetype = order.name_transactioncode,
2815+ testcode = order.testcode,
2816+ file_id = file_id,
2817+ state = 'finish',
2818+ ), context)
2819+ return {
2820+ 'name': _('Client Opdrachten Export'),
2821+ 'view_type': 'form',
2822+ 'view_mode': 'form',
2823+ 'res_model': self._name,
2824+ 'domain': [],
2825+ 'context': dict(context, active_ids=ids),
2826+ 'type': 'ir.actions.act_window',
2827+ 'target': 'new',
2828+ 'res_id': ids[0] or False,
2829+ }
2830
2831- def _cancel_clieop(self, cursor, uid, data, context):
2832+ def cancel_clieop(self, cursor, uid, ids, context):
2833 '''
2834 Cancel the ClieOp: just drop the file
2835 '''
2836- pool = pooler.get_pool(cursor.dbname)
2837- pool.get('banking.export.clieop').unlink(cursor, uid, data['file_id'])
2838- return {'state': 'end'}
2839-
2840- def _save_clieop(self, cursor, uid, data, context):
2841- '''
2842- Save the ClieOp: mark all payments in the file as 'sent'.
2843- '''
2844- pool = pooler.get_pool(cursor.dbname)
2845- clieop_obj = pool.get('banking.export.clieop')
2846- payment_order_obj = pool.get('payment.order')
2847- clieop_file = clieop_obj.write(
2848- cursor, uid, data['file_id'], {'state':'sent'}
2849- )
2850- payment_order_obj.write(cursor, uid, data['ids'], {'state': 'sent'})
2851- return {'state': 'end'}
2852-
2853- states = {
2854- 'init': {
2855- 'actions': [_check_orders],
2856- 'result': {
2857- 'type': 'form',
2858- 'arch': form,
2859- 'fields' : fields,
2860- 'state': [
2861- ('end', 'Cancel', 'gtk-cancel'),
2862- ('create', 'Create', 'gtk-ok'),
2863- ]
2864- }
2865- },
2866- 'create': {
2867- 'actions': [_create_clieop],
2868- 'result': {
2869- 'type': 'form',
2870- 'arch': file_form,
2871- 'fields': file_fields,
2872- 'state': [
2873- ('cancel', 'Cancel', 'gtk-cancel'),
2874- ('save', 'Save', 'gtk-save'),
2875- ]
2876- },
2877- },
2878- 'cancel': {
2879- 'actions': [_cancel_clieop],
2880- 'result': {
2881- 'type': 'state',
2882- 'state': 'end'
2883- }
2884- },
2885- 'save': {
2886- 'actions': [_save_clieop],
2887- 'result': {
2888- 'type': 'state',
2889- 'state': 'end'
2890- },
2891- }
2892- }
2893-
2894-wizard_banking_export_clieop('account_banking_nl_clieop.banking_export_clieop')
2895+ clieop_export = self.read(cursor, uid, ids, ['file_id'], context)[0]
2896+ self.pool.get('banking.export.clieop').unlink(cursor, uid, clieop_export['file_id'])
2897+ return {'type': 'ir.actions.act_window_close'}
2898+
2899+ def save_clieop(self, cursor, uid, ids, context):
2900+ '''
2901+ Save the ClieOp: mark all payments in the file as 'sent', if not a test
2902+ '''
2903+ clieop_export = self.browse(
2904+ cursor, uid, ids, context)[0]
2905+ if not clieop_export['test']:
2906+ clieop_obj = self.pool.get('banking.export.clieop')
2907+ payment_order_obj = self.pool.get('payment.order')
2908+ clieop_file = clieop_obj.write(
2909+ cursor, uid, clieop_export['file_id'].id, {'state':'sent'}
2910+ )
2911+ payment_order_obj.action_sent(
2912+ cursor, uid, [x.id for x in clieop_export['payment_order_ids']])
2913+ return {'type': 'ir.actions.act_window_close'}
2914+
2915+banking_export_clieop_wizard()
2916
2917 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2918
2919=== added file 'account_banking_nl_clieop/wizard/export_clieop_view.xml'
2920--- account_banking_nl_clieop/wizard/export_clieop_view.xml 1970-01-01 00:00:00 +0000
2921+++ account_banking_nl_clieop/wizard/export_clieop_view.xml 2011-11-23 10:40:16 +0000
2922@@ -0,0 +1,58 @@
2923+<?xml version="1.0" encoding="utf-8"?>
2924+<openerp>
2925+ <data>
2926+ <record id="banking_export_clieop_wizard_view" model="ir.ui.view">
2927+ <field name="name">banking.export.clieop.wizard.view</field>
2928+ <field name="model">banking.export.clieop.wizard</field>
2929+ <field name="type">form</field>
2930+ <field name="arch" type="xml">
2931+ <form string="Client Opdrachten Export">
2932+ <field name="state" invisible="True"/>
2933+ <group states="create">
2934+ <separator colspan="4" string="Processing Details" />
2935+ <field name="batchtype" />
2936+ <field name="execution_date" />
2937+ <field name="test" />
2938+ <separator colspan="4" string="Reference for further communication" />
2939+ <field name="reference" colspan="2" />
2940+ <separator colspan="4" string="Additional message for all transactions" />
2941+ <field name="fixed_message" />
2942+ <newline/>
2943+ <button icon="gtk-close"
2944+ special="cancel"
2945+ string="Cancel"
2946+ />
2947+ <button icon="gtk-ok"
2948+ string="Create"
2949+ name="create_clieop"
2950+ type="object"
2951+ />
2952+ </group>
2953+ <group states="finish">
2954+ <field name="filetype" />
2955+ <field name="identification" />
2956+ <field name="total_amount" />
2957+ <field name="check_no_accounts" />
2958+ <field name="no_transactions" />
2959+ <field name="prefered_date" />
2960+ <field name="testcode" />
2961+ <newline/>
2962+ <field name="file_id" />
2963+ <field name="file" />
2964+ <newline/>
2965+ <button icon="gtk-close"
2966+ string="Cancel"
2967+ name="cancel_clieop"
2968+ type="object"
2969+ />
2970+ <button icon="gtk-ok"
2971+ string="Finish"
2972+ name="save_clieop"
2973+ type="object"
2974+ />
2975+ </group>
2976+ </form>
2977+ </field>
2978+ </record>
2979+ </data>
2980+</openerp>
2981
2982=== modified file 'account_banking_nl_girotel/__terp__.py'
2983--- account_banking_nl_girotel/__terp__.py 2011-11-08 13:10:34 +0000
2984+++ account_banking_nl_girotel/__terp__.py 2011-11-23 10:40:16 +0000
2985@@ -37,9 +37,8 @@
2986 ],
2987 'demo_xml': [],
2988 'description': '''
2989- Module to import Dutch Girotel format transation files.
2990-
2991- This modules contains no logic, just an import filter for account_banking.
2992+Do not install this module. This branch has been replaced by lp:banking-addons/6.0
2993+See https://launchpad.net/banking-addons
2994 ''',
2995 'active': False,
2996 'installable': True,
2997
2998=== modified file 'account_banking_nl_multibank/__terp__.py'
2999--- account_banking_nl_multibank/__terp__.py 2011-11-08 13:10:34 +0000
3000+++ account_banking_nl_multibank/__terp__.py 2011-11-23 10:40:16 +0000
3001@@ -37,9 +37,8 @@
3002 ],
3003 'demo_xml': [],
3004 'description': '''
3005- Module to import Dutch Multibank format transation files.
3006-
3007- This modules contains no logic, just an import filter for account_banking.
3008+Do not install this module. This branch has been replaced by lp:banking-addons/6.0
3009+See https://launchpad.net/banking-addons
3010 ''',
3011 'active': False,
3012 'installable': True,
3013
3014=== modified file 'account_banking_nl_triodos/__openerp__.py'
3015--- account_banking_nl_triodos/__openerp__.py 2011-04-26 21:00:12 +0000
3016+++ account_banking_nl_triodos/__openerp__.py 2011-11-23 10:40:16 +0000
3017@@ -39,19 +39,8 @@
3018 ],
3019 'demo_xml': [],
3020 'description': '''
3021-Module to import Dutch Triodos bank format transation files (CSV format).
3022-
3023-As the Triodos bank does not provide detailed specification concerning possible
3024-values and their meaning for the fields in the CSV file format, the statements
3025-are parsed according to an educated guess based on incomplete information.
3026-You can contact the account-banking developers through their launchpad page and
3027-help improve the performance of this import filter on
3028-https://launchpad.net/account-banking.
3029-
3030-Note that imported bank transfers are organized in statements covering periods
3031-of one week, even if the imported files cover a different period.
3032-
3033-This modules contains no logic, just an import filter for account_banking.
3034+Do not install this module. This branch has been replaced by lp:banking-addons/6.0
3035+See https://launchpad.net/banking-addons
3036 ''',
3037 'active': False,
3038 'installable': True,
3039
3040=== modified file 'account_banking_nl_triodos/__terp__.py'
3041--- account_banking_nl_triodos/__terp__.py 2011-11-08 13:10:34 +0000
3042+++ account_banking_nl_triodos/__terp__.py 2011-11-23 10:40:16 +0000
3043@@ -39,19 +39,8 @@
3044 ],
3045 'demo_xml': [],
3046 'description': '''
3047-Module to import Dutch Triodos bank format transation files (CSV format).
3048-
3049-As the Triodos bank does not provide detailed specification concerning possible
3050-values and their meaning for the fields in the CSV file format, the statements
3051-are parsed according to an educated guess based on incomplete information.
3052-You can contact the account-banking developers through their launchpad page and
3053-help improve the performance of this import filter on
3054-https://launchpad.net/account-banking.
3055-
3056-Note that imported bank transfers are organized in statements covering periods
3057-of one week, even if the imported files cover a different period.
3058-
3059-This modules contains no logic, just an import filter for account_banking.
3060+Do not install this module. This branch has been replaced by lp:banking-addons/6.0
3061+See https://launchpad.net/banking-addons
3062 ''',
3063 'active': False,
3064 'installable': True,
3065
3066=== modified file 'account_banking_nl_triodos/triodos.py'
3067--- account_banking_nl_triodos/triodos.py 2011-04-27 10:16:40 +0000
3068+++ account_banking_nl_triodos/triodos.py 2011-11-23 10:40:16 +0000
3069@@ -68,6 +68,9 @@
3070 # Set statement_id based on week number
3071 self.statement_id = self.effective_date.strftime('%Yw%W')
3072 self.id = str(subno).zfill(4)
3073+ # Normalize basic account numbers
3074+ self.remote_account = self.remote_account.replace('.', '').zfill(10)
3075+ self.local_account = self.local_account.replace('.', '').zfill(10)
3076
3077 class transaction(models.mem_bank_transaction):
3078 '''