From 137d1c3244fc039da8d1db5fb9f82993e2e0de81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Faure-Lacroix?= Date: Tue, 17 Mar 2015 20:35:33 +0300 Subject: [PATCH] PEP8 account_banking_reconciliation --- account_banking_reconciliation/__openerp__.py | 136 +++- .../account_banking_reconciliation.py | 728 ++++++++++++++---- .../account_move_line.py | 26 +- 3 files changed, 694 insertions(+), 196 deletions(-) diff --git a/account_banking_reconciliation/__openerp__.py b/account_banking_reconciliation/__openerp__.py index 80362cb67..b01f95419 100644 --- a/account_banking_reconciliation/__openerp__.py +++ b/account_banking_reconciliation/__openerp__.py @@ -25,68 +25,152 @@ 'category': 'Accounting and Financial Management', 'description': """ -This module is designed to provide an easy method in which OpenERP accounting users can manually reconcile/validate their financial transactions from their financial institution/transaction providers (e.g. Paypal, A financial institution, google wallet, etc) against OpenERP GL Chart of Account bank accounts. +This module is designed to provide an easy method in which OpenERP +accounting users can manually reconcile/validate their financial +transactions from their financial institution/transaction providers +(e.g. Paypal, A financial institution, google wallet, etc) against +OpenERP GL Chart of Account bank accounts. -Users will be able to validate and indicate if a transaction has "Cleared the Bank" using a checkmark on a new Reconcile Financial Account Statement view on each individual financial transaction. Users will also be able to mark transactions on a bank account for future research. +Users will be able to validate and indicate if a transaction has +"Cleared the Bank" using a checkmark on a new Reconcile Financial +Account Statement view on each individual financial transaction. +Users will also be able to mark transactions on a bank account for +future research. -The idea is that as a first step users will manually look at their paper statement and line-by-line check off which financial transactions have cleared the bank in OpenERP using the new Bank Reconciliation Wizard. These changes will be displayed on the new Reconcile Financial Account Statement tree view screen. This is the process in which many companies reconcile (aka Audit) their bank account statements and accounting system today and represents good segregation of duties +The idea is that as a first step users will manually look at their +paper statement and line-by-line check off which financial +transactions have cleared the bank in OpenERP using the new Bank +Reconciliation Wizard. These changes will be displayed on the new +Reconcile Financial Account Statement tree view screen. This is the +process in which many companies reconcile (aka Audit) their bank +account statements and accounting system today and represents good +segregation of duties Users can save their in-process reconciliations. BACKGROUND -Using the search view filters - users will also be able to effectively sort, filter the transactions on a particular GL Financial Account. This new screen will display the journal items associated with a particular bank account. Several of the field labels have been relabeled to a more common vernacular. +Using the search view filters - users will also be able to effectively +sort, filter the transactions on a particular GL Financial Account. +This new screen will display the journal items associated with a +particular bank account. Several of the field labels have been +relabeled to a more common vernacular. -(Future) Phase II of the project - will extend this module to include a wizard to pre-filter the tree view, and include additional reports for accountants. And include the ability to execute quick entry of common statement related transactions such as recording bank service fees (an Expense), and Interest Income Earned on the bank account (Income), when allowed by law. Often, companies will print their reconciliation, staple it to their bank statement and file the documents for future review and audit. +(Future) Phase II of the project - will extend this module to include +a wizard to pre-filter the tree view, and include additional reports +for accountants. And include the ability to execute quick entry of +common statement related transactions such as recording bank service +fees (an Expense), and Interest Income Earned on the bank account +(Income), when allowed by law. Often, companies will print their +reconciliation, staple it to their bank statement and file the documents +for future review and audit. -(Future) Phase III of the project will extend this module to include more information to add further clarity throughout OpenERP for financial transactions, and include the ability to quickly compare an imported bank statement with a GL Bank Account's recorded transaction, including autoreconciling them - and providing the information available for review +(Future) Phase III of the project will extend this module to include +more information to add further clarity throughout OpenERP for financial +transactions, and include the ability to quickly compare an imported bank +statement with a GL Bank Account's recorded transaction, including +autoreconciling them - and providing the information available for review The need for this module is driven by the following: -OpenERP's default functionality doesn't support the typical "BANK" account reconciliation process found in many countries (e.g. the US) -Users want to easily record whether bank transactions sent to their bank have "cleared the bank"- definition of "cleared the bank": presented to the bank for payment and paid by the bank - added/subtracted funds on a bank account. -Users want the ability to validate if the bank processed the transactions them correctly (e.g. properly encoded transaction - e.g. company sent a payment of $20.20 to the bank. Was it processed for $20.20?). This can be considered "Auditing the bank statement". We don't assume the bank correctly processed any transaction. -Users want to understand what payments they've made are still outstanding and have not been paid by the bank. -The financial auditing segregation standard of separating the duties of: recording customer payments and making deposits; recording supplier payments and writing checks; and monitoring bank account activity. This segregation of duties is necessary to monitor and help prevent fraud. +OpenERP's default functionality doesn't support the typical "BANK" account +reconciliation process found in many countries (e.g. the US) + +Users want to easily record whether bank transactions sent to their bank +have "cleared the bank"- definition of "cleared the bank": presented to +the bank for payment and paid by the bank - added/subtracted funds on +a bank account. + +Users want the ability to validate if the bank processed the transactions +them correctly (e.g. properly encoded transaction - e.g. company sent a +payment of $20.20 to the bank. Was it processed for $20.20?). This can +be considered "Auditing the bank statement". We don't assume the bank +correctly processed any transaction. + +Users want to understand what payments they've made are still outstanding +and have not been paid by the bank. +The financial auditing segregation standard of separating the duties of: +recording customer payments and making deposits; recording supplier payments +and writing checks; and monitoring bank account activity. This segregation +of duties is necessary to monitor and help prevent fraud. Assumptions: -1.Companies using OpenERP have setup a One-to-one relationship between their bank accounts and their OpenERP GL accounts. Each bank account should have a corresponding GL account that is not shared with another account. +1. Companies using OpenERP have setup a One-to-one relationship between + their bank accounts and their OpenERP GL accounts. Each bank account + should have a corresponding GL account that is not shared with another + account. Example: OpenERP GL Account # Corresponding Bank Account - 10100 Bank (AR) Account Checking 5434 (held at Institution A) + 10100 Bank (AR) Account Checking 5434 + (held at Institution A) 10200 Master Bank Account 2343 (held at Institution A) - 10300 Bank Payable Account Checking 5678 (held at Institution A) + 10300 Bank Payable Account Checking 5678 + (held at Institution A) 10400 Bank Payroll Account 6656 (held at Institution B) 10500 Paypal Account 3343 (held at Paypal) 10600 Google Wallet Account 6788 10700 AMEX Corporate Card Account 9989 -2.Companies have included a Non-Deposited Funds Account in their GL account (typically in current assets in their bank account areas). This account is used to store payments that have been recorded in OpenERP - but not yet deposited into the financial institution. (NOTE: this account is important to have if the user "batches check deposits"- which is the process of making a large single deposits of customer payment into the bank (e.g. $20,000USD), but it is made up of smaller checks (e.g. 20 checks of $1,000 each). Many banks just record the total deposit amount ($20,000) and don¬タルt provide the breakdown of the individual checks that make up the larger deposit. This setup approach enables users to drill down and see the individual checks that make up a larger deposit. +2. Companies have included a Non-Deposited Funds Account in their GL account + (typically in current assets in their bank account areas). This account + is used to store payments that have been recorded in OpenERP - but not + yet deposited into the financial institution. (NOTE: this account is + important to have if the user "batches check deposits"- which is the + process of making a large single deposits of customer payment into the + bank (e.g. $20,000USD), but it is made up of smaller checks + (e.g. 20 checks of $1,000 each). Many banks just record the total deposit + amount ($20,000) and don¬タルt provide the breakdown of the individual + checks that make up the larger deposit. This setup approach enables users + to drill down and see the individual checks that make up a larger deposit. Recommendations: -From a cash management and financial control perspective it is recommended that users establish the following four(4) bank accounts at their financial institution at a minimum to handle financial transactions. (NOTE: we recommend users place the last 4 digits of their bank account in the GL account name of the account. It helps accountants in their management of the system): +From a cash management and financial control perspective it is recommended +that users establish the following four(4) bank accounts at their financial +institution at a minimum to handle financial transactions. +(NOTE: we recommend users place the last 4 digits of their bank account in +the GL account name of the account. It helps accountants in their management +of the system): Bank (AR) Account Checking 5434 -This is a checking account designated as the account where payments made to the company are deposited (e.g. a customer payment made by check is deposited here, or a customer paying by electronic transaction EFT/ACH is deposited into this GL). +This is a checking account designated as the account where payments made to +the company are deposited (e.g. a customer payment made by check is +deposited here, or a customer paying by electronic transaction EFT/ACH is +deposited into this GL). Master Bank Account 2343 -This is the master account in which the company keeps the majority of their funds. Often with the most limited access. +This is the master account in which the company keeps the majority of their +funds. Often with the most limited access. Bank Payable Account Checking 5678 -This is a checking account designated for the company to pay their expenses from. (e.g. Company writes a check to pay a supplier for their office supplies). +This is a checking account designated for the company to pay their expenses +from. (e.g. Company writes a check to pay a supplier for their office +supplies). Bank Payroll Account 6656 -This is a checking account designated for a company to pay their employees and payroll. +This is a checking account designated for a company to pay their +employees and payroll. +NOTE: There has been common confusion in the OpenERP community about +managing bank statements in the base OpenERP system. This module +hopes to alleviate this gap and provide users with a sound alternative +to maintain fiscal control, be easy to understand, and allow for +future growth. -NOTE: There has been common confusion in the OpenERP community about managing bank statements in the base OpenERP system. This module hopes to alleviate this gap and provide users with a sound alternative to maintain fiscal control, be easy to understand, and allow for future growth. +Why this approach? Users in OpenERP have several options in which to +record financial transactions that affect the balances of a bank account +(GL Bank Account entries). We believe our approach allows these to work +in conjunction with each other: Import Electronic Bank Statements to enter +payments (this approach follows the philosophy that you first find out +that a transaction has occurred from your bank ¬タモ which is very common in +Europe due to the electronic nature of transactions). -Why this approach? Users in OpenERP have several options in which to record financial transactions that affect the balances of a bank account (GL Bank Account entries). We believe our approach allows these to work in conjunction with each other: Import Electronic Bank Statements to enter payments (this approach follows the philosophy that you first find out that a transaction has occurred from your bank ¬タモ which is very common in Europe due to the electronic nature of transactions). -Payment Order Payments (using the direct Method) - Payments are instantly recorded and financial transactions posted into the GL -Voucher Payments - Payments are instantly recorded and financial transactions posted into the GL -Sales Receipts/Refunds -Transfers between accounts (a new module is being developed to help manage this) +Payment Order Payments (using the direct Method) - Payments are instantly +recorded and financial transactions posted into the GL +Voucher Payments - Payments are instantly recorded and financial transactions +posted into the GL Sales Receipts/Refunds +Transfers between accounts (a new module is being developed to help +manage this) Funds moved from the Undeposited Funds GL account to a Bank Account GL account. Direct Journal Entries diff --git a/account_banking_reconciliation/account_banking_reconciliation.py b/account_banking_reconciliation/account_banking_reconciliation.py index 53f6ef2e8..929f5534d 100644 --- a/account_banking_reconciliation/account_banking_reconciliation.py +++ b/account_banking_reconciliation/account_banking_reconciliation.py @@ -25,24 +25,44 @@ from openerp.osv import fields, osv from openerp.tools.translate import _ import decimal_precision as dp + class bank_acc_rec_statement(osv.osv): def check_group(self, cr, uid, ids, context=None): """Check if following security constraints are implemented for groups: - Bank Statement Preparer– they can create, view and delete any of the Bank Statements provided the Bank Statement is not in the DONE state, - or the Ready for Review state. - Bank Statement Verifier – they can create, view, edit, and delete any of the Bank Statements information at any time. - NOTE: DONE Bank Statements are only allowed to be deleted by a Bank Statement Verifier.""" + Bank Statement Preparer – they can create, view and delete any of + the Bank Statements provided the Bank Statement is not in the DONE + state, or the Ready for Review state. + + Bank Statement Verifier – they can create, view, edit, and delete any + of the Bank Statements information at any time. + + NOTE: DONE Bank Statements are only allowed to be deleted by a Bank + Statement Verifier. + """ model_data_obj = self.pool.get('ir.model.data') res_groups_obj = self.pool.get('res.groups') - group_verifier_id = model_data_obj._get_id(cr, uid, 'account_banking_reconciliation', 'group_bank_stmt_verifier') + group_verifier_id = model_data_obj._get_id( + cr, uid, + 'account_banking_reconciliation', 'group_bank_stmt_verifier' + ) for statement in self.browse(cr, uid, ids, context=context): if group_verifier_id: - res_id = model_data_obj.read(cr, uid, [group_verifier_id], ['res_id'])[0]['res_id'] - group_verifier = res_groups_obj.browse(cr, uid, res_id, context=context) + res_id = model_data_obj.read( + cr, uid, [group_verifier_id], ['res_id'] + )[0]['res_id'] + group_verifier = res_groups_obj.browse( + cr, uid, res_id, context=context + ) group_user_ids = [user.id for user in group_verifier.users] - if statement.state!='draft' and uid not in group_user_ids: - raise osv.except_osv(_('User Error !'), - _("Only a member of '%s' group may delete/edit bank statements when not in draft state!" %(group_verifier.name))) + if statement.state != 'draft' and uid not in group_user_ids: + raise osv.except_osv( + _('User Error'), + _( + "Only a member of '%s' group may delete/edit " + "bank statements when not in draft state!" % + (group_verifier.name) + ) + ) return True def copy(self, cr, uid, id, default={}, context=None): @@ -51,29 +71,52 @@ class bank_acc_rec_statement(osv.osv): 'debit_move_line_ids': [], 'name': '', }) - return super(bank_acc_rec_statement, self).copy(cr, uid, id, default=default, context=context) + return super(bank_acc_rec_statement, self).copy( + cr, uid, id, default=default, context=context + ) def write(self, cr, uid, ids, vals, context=None): - self.check_group(cr, uid, ids, context) # Check if the user is allowed to perform the action - return super(bank_acc_rec_statement, self).write(cr, uid, ids, vals, context=context) + # Check if the user is allowed to perform the action + self.check_group(cr, uid, ids, context) + return super(bank_acc_rec_statement, self).write( + cr, uid, ids, vals, context=context + ) def unlink(self, cr, uid, ids, context=None): - "Reset the related account.move.line to be re-assigned later to statement." + """ + Reset the related account.move.line to be re-assigned later + to statement. + """ statement_line_obj = self.pool.get('bank.acc.rec.statement.line') - self.check_group(cr, uid, ids, context) # Check if the user is allowed to perform the action + # Check if the user is allowed to perform the action + self.check_group(cr, uid, ids, context) for statement in self.browse(cr, uid, ids, context=context): - statement_lines = statement.credit_move_line_ids + statement.debit_move_line_ids + statement_lines = ( + statement.credit_move_line_ids + + statement.debit_move_line_ids + ) statement_line_ids = map(lambda x: x.id, statement_lines) - statement_line_obj.unlink(cr, uid, statement_line_ids, context=context) # call unlink method to reset - return super(bank_acc_rec_statement, self).unlink(cr, uid, ids, context=context) + # call unlink method to reset + statement_line_obj.unlink( + cr, uid, statement_line_ids, context=context + ) + return super(bank_acc_rec_statement, self).unlink( + cr, uid, ids, context=context + ) def check_difference_balance(self, cr, uid, ids, context=None): "Check if difference balance is zero or not." for statement in self.browse(cr, uid, ids, context=context): if statement.difference != 0.0: - raise osv.except_osv(_('Warning!'), - _("Prior to reconciling a statement, all differences must be accounted for and the Difference balance must be zero." \ - " Please review and make necessary changes.")) + raise osv.except_osv( + _('Warning!'), + _( + "Prior to reconciling a statement, all differences " + "must be accounted for and the Difference balance " + "must be zero. Please review and make necessary " + "changes." + ) + ) return True def action_cancel(self, cr, uid, ids, context=None): @@ -89,26 +132,50 @@ class bank_acc_rec_statement(osv.osv): return True def action_process(self, cr, uid, ids, context=None): - """Set the account move lines as 'Cleared' and Assign 'Bank Acc Rec Statement ID' - for the statement lines which are marked as 'Cleared'.""" + """ + Set the account move lines as 'Cleared' and Assign + 'Bank Acc Rec Statement ID' for the statement lines which + are marked as 'Cleared'. + """ account_move_line_obj = self.pool.get('account.move.line') statement_line_obj = self.pool.get('bank.acc.rec.statement.line') # If difference balance not zero prevent further processing self.check_difference_balance(cr, uid, ids, context=context) for statement in self.browse(cr, uid, ids, context=context): - statement_lines = statement.credit_move_line_ids + statement.debit_move_line_ids + statement_lines = ( + statement.credit_move_line_ids + + statement.debit_move_line_ids + ) for statement_line in statement_lines: - #Mark the move lines as 'Cleared'mand assign the 'Bank Acc Rec Statement ID' + # Mark the move lines as 'Cleared'mand assign + # the 'Bank Acc Rec Statement ID' if statement_line.move_line_id: - account_move_line_obj.write(cr, uid, [statement_line.move_line_id.id], - {'cleared_bank_account': statement_line.cleared_bank_account, - 'bank_acc_rec_statement_id': statement_line.cleared_bank_account and statement.id or False - }, context=context) + account_move_line_obj.write( + cr, uid, + [statement_line.move_line_id.id], + { + 'cleared_bank_account': ( + statement_line.cleared_bank_account + ), + 'bank_acc_rec_statement_id': ( + statement_line.cleared_bank_account and + statement.id or + False + ), + }, + context=context + ) - self.write(cr, uid, [statement.id], {'state': 'done', - 'verified_by_user_id': uid, - 'verified_date': time.strftime('%Y-%m-%d') - }, context=context) + self.write( + cr, uid, + [statement.id], + { + 'state': 'done', + 'verified_by_user_id': uid, + 'verified_date': time.strftime('%Y-%m-%d') + }, + context=context + ) return True def action_cancel_draft(self, cr, uid, ids, context=None): @@ -116,28 +183,49 @@ class bank_acc_rec_statement(osv.osv): account_move_line_obj = self.pool.get('account.move.line') statement_line_obj = self.pool.get('bank.acc.rec.statement.line') for statement in self.browse(cr, uid, ids, context=context): - statement_lines = statement.credit_move_line_ids + statement.debit_move_line_ids + statement_lines = ( + statement.credit_move_line_ids + + statement.debit_move_line_ids + ) line_ids = [] statement_line_ids = [] for statement_line in statement_lines: statement_line_ids.append(statement_line.id) if statement_line.move_line_id.id: - line_ids.append(statement_line.move_line_id.id) # Find move lines related to statement lines - + # Find move lines related to statement lines + line_ids.append(statement_line.move_line_id.id) # Reset 'Cleared' and 'Bank Acc Rec Statement ID' to False - account_move_line_obj.write(cr, uid, line_ids, {'cleared_bank_account': False, - 'bank_acc_rec_statement_id': False, - }, context=context) + account_move_line_obj.write( + cr, uid, + line_ids, + { + 'cleared_bank_account': False, + 'bank_acc_rec_statement_id': False, + }, + context=context + ) # Reset 'Cleared' in statement lines - statement_line_obj.write(cr, uid, statement_line_ids, {'cleared_bank_account': False, - 'research_required': False - }, context=context) + statement_line_obj.write( + cr, uid, + statement_line_ids, + { + 'cleared_bank_account': False, + 'research_required': False + }, + context=context + ) # Reset statement - self.write(cr, uid, [statement.id], {'state': 'draft', - 'verified_by_user_id': False, - 'verified_date': False - }, context=context) + self.write( + cr, uid, + [statement.id], + { + 'state': 'draft', + 'verified_by_user_id': False, + 'verified_date': False + }, + context=context + ) return True @@ -145,31 +233,53 @@ class bank_acc_rec_statement(osv.osv): """Mark all the statement lines as 'Cleared'.""" statement_line_obj = self.pool.get('bank.acc.rec.statement.line') for statement in self.browse(cr, uid, ids, context=context): - statement_lines = statement.credit_move_line_ids + statement.debit_move_line_ids + statement_lines = ( + statement.credit_move_line_ids + + statement.debit_move_line_ids + ) statement_line_ids = map(lambda x: x.id, statement_lines) - statement_line_obj.write(cr, uid, statement_line_ids, {'cleared_bank_account': True}, context=context) + statement_line_obj.write( + cr, uid, + statement_line_ids, + {'cleared_bank_account': True}, + context=context + ) return True def action_unselect_all(self, cr, uid, ids, context=None): """Reset 'Cleared' in all the statement lines.""" statement_line_obj = self.pool.get('bank.acc.rec.statement.line') for statement in self.browse(cr, uid, ids, context=context): - statement_lines = statement.credit_move_line_ids + statement.debit_move_line_ids + statement_lines = ( + statement.credit_move_line_ids + + statement.debit_move_line_ids + ) statement_line_ids = map(lambda x: x.id, statement_lines) - statement_line_obj.write(cr, uid, statement_line_ids, {'cleared_bank_account': False}, context=context) + statement_line_obj.write( + cr, uid, + statement_line_ids, + {'cleared_bank_account': False}, + context=context + ) return True def _get_balance(self, cr, uid, ids, name, args, context=None): """Computed as following: - A) Deposits, Credits, and Interest Amount: Total SUM of Amts of lines with Cleared = True - Deposits, Credits, and Interest # of Items: Total of number of lines with Cleared = True + A) Deposits, Credits, and Interest Amount: + Total SUM of Amts of lines with Cleared = True + Deposits, Credits, and Interest # of Items: + Total of number of lines with Cleared = True B) Checks, Withdrawals, Debits, and Service Charges Amount: Checks, Withdrawals, Debits, and Service Charges Amount # of Items: - Cleared Balance (Total Sum of the Deposit Amount Cleared (A) – Total Sum of Checks Amount Cleared (B)) - Difference= (Ending Balance – Beginning Balance) - cleared balance = should be zero. + Cleared Balance (Total Sum of the Deposit Amount Cleared (A) – + Total Sum of Checks Amount Cleared (B)) + Difference= (Ending Balance – Beginning Balance) - + cleared balance = should be zero. """ res = {} - account_precision = self.pool.get('decimal.precision').precision_get(cr,uid, 'Account') + account_precision = self.pool.get('decimal.precision').precision_get( + cr, uid, 'Account' + ) for statement in self.browse(cr, uid, ids, context=context): res[statement.id] = { 'sum_of_credits': 0.0, @@ -201,9 +311,21 @@ class bank_acc_rec_statement(osv.osv): res[statement.id]['sum_of_debits_unclear'] += sum_debit res[statement.id]['sum_of_debits_lines_unclear'] += 1.0 - res[statement.id]['cleared_balance'] = round(res[statement.id]['sum_of_debits'] - res[statement.id]['sum_of_credits'], account_precision) - res[statement.id]['uncleared_balance'] = round(res[statement.id]['sum_of_debits_unclear'] - res[statement.id]['sum_of_credits_unclear'], account_precision) - res[statement.id]['difference'] = round((statement.ending_balance - statement.starting_balance) - res[statement.id]['cleared_balance'], account_precision) + res[statement.id]['cleared_balance'] = round( + res[statement.id]['sum_of_debits'] - + res[statement.id]['sum_of_credits'], + account_precision + ) + res[statement.id]['uncleared_balance'] = round( + res[statement.id]['sum_of_debits_unclear'] - + res[statement.id]['sum_of_credits_unclear'], + account_precision + ) + res[statement.id]['difference'] = round( + (statement.ending_balance - statement.starting_balance) - + res[statement.id]['cleared_balance'], + account_precision + ) return res def _get_move_line_write(self, line): @@ -250,11 +372,17 @@ class bank_acc_rec_statement(osv.osv): if not obj.suppress_ending_date_filter: domain += [('date', '<=', obj.ending_date)] - line_ids = account_move_line_obj.search(cr, uid, domain, context=context) - for line in account_move_line_obj.browse(cr, uid, line_ids, context=context): + line_ids = account_move_line_obj.search( + cr, uid, domain, context=context + ) + lines = account_move_line_obj.browse( + cr, uid, line_ids, context=context + ) + for line in lines: if obj.keep_previous_uncleared_entries: - #only take bank_acc_rec_statement at state cancel or done - if not self.is_b_a_r_s_state_done(cr, uid, line.id, context=context): + # only take bank_acc_rec_statement at state cancel or done + if not self.is_b_a_r_s_state_done( + cr, uid, line.id, context=context): continue res = (0, 0, self._get_move_line_write(line)) if line.credit: @@ -267,41 +395,74 @@ class bank_acc_rec_statement(osv.osv): def is_b_a_r_s_state_done(self, cr, uid, move_line_id, context=None): statement_line_obj = self.pool.get('bank.acc.rec.statement.line') - statement_line_ids = statement_line_obj.search(cr, uid, [('move_line_id', '=', move_line_id)], context=context) + statement_line_ids = statement_line_obj.search( + cr, uid, [('move_line_id', '=', move_line_id)], context=context + ) for state_line in statement_line_ids: - b_a_r_s_line = statement_line_obj.browse(cr, uid, state_line, context=context) - b_a_r_s = self.browse(cr, uid, b_a_r_s_line.statement_id.id, context=context) + b_a_r_s_line = statement_line_obj.browse( + cr, uid, state_line, context=context + ) + b_a_r_s = self.browse( + cr, uid, b_a_r_s_line.statement_id.id, context=context + ) if b_a_r_s and b_a_r_s.state not in ("done", "cancel"): return False return True - def onchange_account_id(self, cr, uid, ids, account_id, ending_date, suppress_ending_date_filter, keep_previous_uncleared_entries, context=None): + def onchange_account_id( + self, cr, uid, ids, account_id, ending_date, + suppress_ending_date_filter, keep_previous_uncleared_entries, + context=None + ): account_move_line_obj = self.pool.get('account.move.line') statement_line_obj = self.pool.get('bank.acc.rec.statement.line') - val = {'value': {'credit_move_line_ids': [], 'debit_move_line_ids': []}} + val = { + 'value': { + 'credit_move_line_ids': [], + 'debit_move_line_ids': [] + } + } if account_id: for statement in self.browse(cr, uid, ids, context=context): - statement_line_ids = statement_line_obj.search(cr, uid, [('statement_id', '=', statement.id)], context=context) - # call unlink method to reset and remove existing statement lines and - # mark reset field values in related move lines - statement_line_obj.unlink(cr, uid, statement_line_ids, context=context) + statement_line_ids = statement_line_obj.search( + cr, uid, + [('statement_id', '=', statement.id)], + context=context + ) + # call unlink method to reset and remove existing + # statement lines and mark reset field values in + # related move lines + statement_line_obj.unlink( + cr, uid, statement_line_ids, context=context + ) # Apply filter on move lines to allow - #1. credit and debit side journal items in posted state of the selected GL account - #2. Journal items which are not assigned to previous bank statements - #3. Date less than or equal to ending date provided the 'Suppress Ending Date Filter' is not checked + # 1. credit and debit side journal items in posted state + # of the selected GL account + # 2. Journal items which are not assigned to previous + # bank statements + # 3. Date less than or equal to ending date provided the + # 'Suppress Ending Date Filter' is not checked # get previous uncleared entries - domain = [('account_id', '=', account_id), ('move_id.state', '=', 'posted'), ('cleared_bank_account', '=', False)] + domain = [ + ('account_id', '=', account_id), + ('move_id.state', '=', 'posted'), + ('cleared_bank_account', '=', False) + ] if not keep_previous_uncleared_entries: domain += [('draft_assigned_to_statement', '=', False)] if not suppress_ending_date_filter: domain += [('date', '<=', ending_date)] - line_ids = account_move_line_obj.search(cr, uid, domain, context=context) - for line in account_move_line_obj.browse(cr, uid, line_ids, context=context): + line_ids = account_move_line_obj.search( + cr, uid, domain, context=context + ) + for line in account_move_line_obj.browse( + cr, uid, line_ids, context=context): if keep_previous_uncleared_entries: - #only take bank_acc_rec_statement at state cancel or done - if not self.is_b_a_r_s_state_done(cr, uid, line.id, context=context): + # only take bank_acc_rec_statement at state cancel or done + if not self.is_b_a_r_s_state_done( + cr, uid, line.id, context=context): continue res = self._get_move_line_write(line) if res['type'] == 'cr': @@ -312,113 +473,356 @@ class bank_acc_rec_statement(osv.osv): _name = "bank.acc.rec.statement" _columns = { - 'name': fields.char('Name', required=True, size=64, states={'done':[('readonly', True)]}, help="This is a unique name identifying the statement (e.g. Bank X January 2012)."), - 'account_id': fields.many2one('account.account', 'Account', required=True, - states={'done':[('readonly', True)]}, domain="[('company_id', '=', company_id), ('type', '!=', 'view')]", - help="The Bank/Gl Account that is being reconciled."), - 'ending_date': fields.date('Ending Date', required=True, states={'done':[('readonly', True)]}, help="The ending date of your bank statement."), - 'starting_balance': fields.float('Starting Balance', required=True, digits_compute=dp.get_precision('Account'), help="The Starting Balance on your bank statement.", states={'done':[('readonly', True)]}), - 'ending_balance': fields.float('Ending Balance', required=True, digits_compute=dp.get_precision('Account'), help="The Ending Balance on your bank statement.", states={'done':[('readonly', True)]}), - 'company_id': fields.many2one('res.company', 'Company', required=True, readonly=True, - help="The Company for which the deposit ticket is made to"), + 'name': fields.char( + 'Name', + required=True, + size=64, + states={'done': [('readonly', True)]}, + help=( + "This is a unique name identifying the statement " + "(e.g. Bank X January 2012)." + ), + ), + 'account_id': fields.many2one( + 'account.account', + 'Account', + required=True, + states={'done': [('readonly', True)]}, + domain="[('company_id', '=', company_id), ('type', '!=', 'view')]", + help="The Bank/Gl Account that is being reconciled." + ), + 'ending_date': fields.date( + 'Ending Date', + required=True, + states={'done': [('readonly', True)]}, + help="The ending date of your bank statement." + ), + 'starting_balance': fields.float( + 'Starting Balance', + required=True, + digits_compute=dp.get_precision('Account'), + help="The Starting Balance on your bank statement.", + states={'done': [('readonly', True)]} + ), + 'ending_balance': fields.float( + 'Ending Balance', + required=True, + digits_compute=dp.get_precision('Account'), + help="The Ending Balance on your bank statement.", + states={'done': [('readonly', True)]} + ), + 'company_id': fields.many2one( + 'res.company', + 'Company', + required=True, + readonly=True, + help="The Company for which the deposit ticket is made to" + ), 'notes': fields.text('Notes'), - 'verified_date': fields.date('Verified Date', states={'done':[('readonly', True)]}, - help="Date in which Deposit Ticket was verified."), - 'verified_by_user_id': fields.many2one('res.users', 'Verified By', states={'done':[('readonly', True)]}, - help="Entered automatically by the “last user” who saved it. System generated."), - 'credit_move_line_ids': fields.one2many('bank.acc.rec.statement.line', 'statement_id', 'Credits', - domain=[('type','=','cr')], context={'default_type':'cr'}, states={'done':[('readonly', True)]}), - 'debit_move_line_ids': fields.one2many('bank.acc.rec.statement.line', 'statement_id', 'Debits', - domain=[('type','=','dr')], context={'default_type':'dr'}, states={'done':[('readonly', True)]}), - 'cleared_balance': fields.function(_get_balance, method=True, string='Cleared Balance', digits_compute=dp.get_precision('Account'), - type='float', help="Total Sum of the Deposit Amount Cleared – Total Sum of Checks, Withdrawals, Debits, and Service Charges Amount Cleared", - multi="balance"), - 'difference': fields.function(_get_balance, method=True, type='float', string='Difference', digits_compute=dp.get_precision('Account'), - help="(Ending Balance – Beginning Balance) - Cleared Balance.", multi="balance"), - 'sum_of_credits': fields.function(_get_balance, method=True, string='Checks, Withdrawals, Debits, and Service Charges Amount', digits_compute=dp.get_precision('Account'), - type='float', help="Total SUM of Amts of lines with Cleared = True", - multi="balance"), - 'sum_of_debits': fields.function(_get_balance, method=True, type='float', string='Deposits, Credits, and Interest Amount', digits_compute=dp.get_precision('Account'), - help="Total SUM of Amts of lines with Cleared = True", multi="balance"), - 'sum_of_credits_lines': fields.function(_get_balance, method=True, string='Checks, Withdrawals, Debits, and Service Charges # of Items', - type='float', help="Total of number of lines with Cleared = True", - multi="balance"), - 'sum_of_debits_lines': fields.function(_get_balance, method=True, type='float', string='Deposits, Credits, and Interest # of Items', - help="Total of number of lines with Cleared = True", multi="balance"), - 'uncleared_balance': fields.function(_get_balance, method=True, string='Uncleared Balance', digits_compute=dp.get_precision('Account'), - type='float', help="Total Sum of the Deposit Amount Cleared – Total Sum of Checks, Withdrawals, Debits, and Service Charges Amount Cleared", - multi="balance"), - 'sum_of_credits_unclear': fields.function(_get_balance, method=True, string='Checks, Withdrawals, Debits, and Service Charges Amount', digits_compute=dp.get_precision('Account'), - type='float', help="Total SUM of Amts of lines with Cleared = True", - multi="balance"), - 'sum_of_debits_unclear': fields.function(_get_balance, method=True, type='float', string='Deposits, Credits, and Interest Amount', digits_compute=dp.get_precision('Account'), - help="Total SUM of Amts of lines with Cleared = True", multi="balance"), - 'sum_of_credits_lines_unclear': fields.function(_get_balance, method=True, string='Checks, Withdrawals, Debits, and Service Charges # of Items', - type='float', help="Total of number of lines with Cleared = True", - multi="balance"), - 'sum_of_debits_lines_unclear': fields.function(_get_balance, method=True, type='float', string='Deposits, Credits, and Interest # of Items', - help="Total of number of lines with Cleared = True", multi="balance"), - 'suppress_ending_date_filter': fields.boolean('Remove Ending Date Filter', help="If this is checked then the Statement End Date filter on the transactions below will not occur. All transactions would come over."), - 'keep_previous_uncleared_entries': fields.boolean('Keep Previous Uncleared Entries', help="If this is checked then the previous uncleared entries will be include."), - 'state': fields.selection([ - ('draft','Draft'), - ('to_be_reviewed','Ready for Review'), - ('done','Done'), - ('cancel', 'Cancel') - ],'State', select=True, readonly=True), + 'verified_date': fields.date( + 'Verified Date', + states={'done': [('readonly', True)]}, + help="Date in which Deposit Ticket was verified." + ), + 'verified_by_user_id': fields.many2one( + 'res.users', + 'Verified By', + states={'done': [('readonly', True)]}, + help=( + "Entered automatically by the “last user” who " + "saved it. System generated." + ), + ), + 'credit_move_line_ids': fields.one2many( + 'bank.acc.rec.statement.line', + 'statement_id', + 'Credits', + domain=[('type', '=', 'cr')], + context={'default_type': 'cr'}, + states={'done': [('readonly', True)]} + ), + 'debit_move_line_ids': fields.one2many( + 'bank.acc.rec.statement.line', + 'statement_id', + 'Debits', + domain=[('type', '=', 'dr')], + context={'default_type': 'dr'}, + states={'done': [('readonly', True)]} + ), + 'cleared_balance': fields.function( + _get_balance, + method=True, + string='Cleared Balance', + digits_compute=dp.get_precision('Account'), + type='float', + help=( + "Total Sum of the Deposit Amount Cleared – Total Sum of " + "Checks, Withdrawals, Debits, and Service Charges " + "Amount Cleared" + ), + multi="balance" + ), + 'difference': fields.function( + _get_balance, + method=True, + type='float', + string='Difference', + digits_compute=dp.get_precision('Account'), + help="(Ending Balance – Beginning Balance) - Cleared Balance.", + multi="balance" + ), + 'sum_of_credits': fields.function( + _get_balance, + method=True, + string='Checks, Withdrawals, Debits, and Service Charges Amount', + digits_compute=dp.get_precision('Account'), + type='float', + help="Total SUM of Amts of lines with Cleared = True", + multi="balance" + ), + 'sum_of_debits': fields.function( + _get_balance, + method=True, + type='float', + string='Deposits, Credits, and Interest Amount', + digits_compute=dp.get_precision('Account'), + help="Total SUM of Amts of lines with Cleared = True", + multi="balance" + ), + 'sum_of_credits_lines': fields.function( + _get_balance, + method=True, + string=( + 'Checks, Withdrawals, Debits, and Service Charges ' + '# of Items' + ), + type='float', + help="Total of number of lines with Cleared = True", + multi="balance" + ), + 'sum_of_debits_lines': fields.function( + _get_balance, + method=True, + type='float', + string='Deposits, Credits, and Interest # of Items', + help="Total of number of lines with Cleared = True", + multi="balance" + ), + 'uncleared_balance': fields.function( + _get_balance, + method=True, + string='Uncleared Balance', + digits_compute=dp.get_precision('Account'), + type='float', + help=( + "Total Sum of the Deposit Amount Cleared – Total Sum " + "of Checks, Withdrawals, Debits, and Service Charges " + "Amount Cleared" + ), + multi="balance" + ), + 'sum_of_credits_unclear': fields.function( + _get_balance, + method=True, + string='Checks, Withdrawals, Debits, and Service Charges Amount', + digits_compute=dp.get_precision('Account'), + type='float', + help="Total SUM of Amts of lines with Cleared = True", + multi="balance" + ), + 'sum_of_debits_unclear': fields.function( + _get_balance, + method=True, + type='float', + string='Deposits, Credits, and Interest Amount', + digits_compute=dp.get_precision('Account'), + help="Total SUM of Amts of lines with Cleared = True", + multi="balance" + ), + 'sum_of_credits_lines_unclear': fields.function( + _get_balance, + method=True, + string=( + 'Checks, Withdrawals, Debits, and Service ' + 'Charges # of Items' + ), + type='float', help="Total of number of lines with Cleared = True", + multi="balance"), + 'sum_of_debits_lines_unclear': fields.function( + _get_balance, + method=True, + type='float', + string='Deposits, Credits, and Interest # of Items', + help="Total of number of lines with Cleared = True", + multi="balance" + ), + 'suppress_ending_date_filter': fields.boolean( + 'Remove Ending Date Filter', + help=( + "If this is checked then the Statement End Date " + "filter on the transactions below will not occur. " + "All transactions would come over." + ), + ), + 'keep_previous_uncleared_entries': fields.boolean( + 'Keep Previous Uncleared Entries', + help=( + "If this is checked then the previous uncleared entries " + "will be include." + ) + ), + 'state': fields.selection( + [ + ('draft', 'Draft'), + ('to_be_reviewed', 'Ready for Review'), + ('done', 'Done'), + ('cancel', 'Cancel') + ], + 'State', + select=True, + readonly=True + ), } + _defaults = { 'state': 'draft', - 'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id, + 'company_id': ( + lambda self, cr, uid, c: self.pool.get('res.users').browse( + cr, uid, uid, c + ).company_id.id + ), 'ending_date': time.strftime('%Y-%m-%d'), } + _order = "ending_date desc" _sql_constraints = [ - ('name_company_uniq', 'unique (name, company_id, account_id)', 'The name of the statement must be unique per company and G/L account!') + ( + 'name_company_uniq', + 'unique (name, company_id, account_id)', + ( + 'The name of the statement must be unique per company ' + 'and G/L account!' + ) + ) ] + + bank_acc_rec_statement() + class bank_acc_rec_statement_line(osv.osv): _name = "bank.acc.rec.statement.line" _description = "Statement Line" _columns = { - 'name': fields.char('Name', size=64, help="Derived from the related Journal Item.", required=True), - 'ref': fields.char('Reference', size=64, help="Derived from related Journal Item."), - 'partner_id': fields.many2one('res.partner', string='Partner', help="Derived from related Journal Item."), - 'amount': fields.float('Amount', digits_compute=dp.get_precision('Account'), - help="Derived from the 'debit' amount from related Journal Item."), - 'amount_in_currency': fields.float('Amount in Currency', digits_compute=dp.get_precision('Account'), - help="Amount in currency from the related Journal Item."), - 'date': fields.date('Date', required=True, help="Derived from related Journal Item."), - 'statement_id': fields.many2one('bank.acc.rec.statement', 'Statement', required=True, ondelete='cascade'), - 'move_line_id': fields.many2one('account.move.line', 'Journal Item', help="Related Journal Item."), - 'cleared_bank_account': fields.boolean('Cleared? ', help='Check if the transaction has cleared from the bank'), - 'research_required': fields.boolean('Research Required? ', help='Check if the transaction should be researched by Accounting personal'), - 'currency_id': fields.many2one('res.currency', 'Currency', help="The optional other currency if it is a multi-currency entry."), - 'type':fields.selection([('dr','Debit'),('cr','Credit')], 'Cr/Dr'), + 'name': fields.char( + 'Name', + size=64, + help="Derived from the related Journal Item.", + required=True + ), + 'ref': fields.char( + 'Reference', + size=64, + help="Derived from related Journal Item." + ), + 'partner_id': fields.many2one( + 'res.partner', + string='Partner', + help="Derived from related Journal Item." + ), + 'amount': fields.float( + 'Amount', + digits_compute=dp.get_precision('Account'), + help="Derived from the 'debit' amount from related Journal Item." + ), + 'amount_in_currency': fields.float( + 'Amount in Currency', + digits_compute=dp.get_precision('Account'), + help="Amount in currency from the related Journal Item." + ), + 'date': fields.date( + 'Date', + required=True, + help="Derived from related Journal Item." + ), + 'statement_id': fields.many2one( + 'bank.acc.rec.statement', + 'Statement', + required=True, + ondelete='cascade' + ), + 'move_line_id': fields.many2one( + 'account.move.line', + 'Journal Item', + help="Related Journal Item." + ), + 'cleared_bank_account': fields.boolean( + 'Cleared? ', + help='Check if the transaction has cleared from the bank' + ), + 'research_required': fields.boolean( + 'Research Required? ', + help=( + 'Check if the transaction should be researched by ' + 'Accounting personal' + ), + ), + 'currency_id': fields.many2one( + 'res.currency', + 'Currency', + help="The optional other currency if it is a multi-currency entry." + ), + 'type': fields.selection( + [ + ('dr', 'Debit'), + ('cr', 'Credit') + ], + 'Cr/Dr' + ), } def create(self, cr, uid, vals, context=None): account_move_line_obj = self.pool.get('account.move.line') # Prevent manually adding new statement line. - # This would allow only onchange method to pre-populate statement lines based on the filter rules. + # This would allow only onchange method to pre-populate + # statement lines based on the filter rules. if not vals.get('move_line_id', False): - raise osv.except_osv(_('Processing Error'),_('You cannot add any new bank statement line manually as of this revision!')) - account_move_line_obj.write(cr, uid, [vals['move_line_id']], {'draft_assigned_to_statement': True}, context=context) - return super(bank_acc_rec_statement_line, self).create(cr, uid, vals, context=context) + raise osv.except_osv( + _('Processing Error'), + _('You cannot add any new bank statement line ' + 'manually as of this revision!') + ) + account_move_line_obj.write( + cr, uid, + [vals['move_line_id']], + {'draft_assigned_to_statement': True}, + context=context + ) + return super(bank_acc_rec_statement_line, self).create( + cr, uid, vals, context=context + ) def unlink(self, cr, uid, ids, context=None): account_move_line_obj = self.pool.get('account.move.line') - move_line_ids = [line.move_line_id.id - for line in self.browse(cr, uid, ids, context=context) - if line.move_line_id] + move_line_ids = [ + line.move_line_id.id + for line in self.browse(cr, uid, ids, context=context) + if line.move_line_id + ] # Reset field values in move lines to be added later - account_move_line_obj.write(cr, uid, move_line_ids, {'draft_assigned_to_statement': False, - 'cleared_bank_account': False, - 'bank_acc_rec_statement_id': False, - }, context=context) - return super(bank_acc_rec_statement_line, self).unlink(cr, uid, ids, context=context) + account_move_line_obj.write( + cr, uid, + move_line_ids, + { + 'draft_assigned_to_statement': False, + 'cleared_bank_account': False, + 'bank_acc_rec_statement_id': False, + }, + context=context + ) + return super(bank_acc_rec_statement_line, self).unlink( + cr, uid, ids, context=context + ) + bank_acc_rec_statement_line() - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/account_banking_reconciliation/account_move_line.py b/account_banking_reconciliation/account_move_line.py index 6b60a0edc..d881c59a6 100644 --- a/account_banking_reconciliation/account_move_line.py +++ b/account_banking_reconciliation/account_move_line.py @@ -19,16 +19,26 @@ # along with this program. If not, see . # ############################################################################## +from osv import fields, osv -from osv import fields,osv class account_move_line(osv.osv): - _inherit='account.move.line' + _inherit = 'account.move.line' _columns = { - 'cleared_bank_account': fields.boolean('Cleared? ', help='Check if the transaction has cleared from the bank'), - 'bank_acc_rec_statement_id': fields.many2one('bank.acc.rec.statement', 'Bank Acc Rec Statement', help="The Bank Acc Rec Statement linked with the journal item"), - 'draft_assigned_to_statement': fields.boolean('Assigned to Statement? ', help='Check if the move line is assigned to statement lines') + 'cleared_bank_account': fields.boolean( + 'Cleared? ', + help='Check if the transaction has cleared from the bank' + ), + 'bank_acc_rec_statement_id': fields.many2one( + 'bank.acc.rec.statement', + 'Bank Acc Rec Statement', + help="The Bank Acc Rec Statement linked with the journal item" + ), + 'draft_assigned_to_statement': fields.boolean( + 'Assigned to Statement? ', + help='Check if the move line is assigned to statement lines' + ) } def copy_data(self, cr, uid, id, default=None, context=None): @@ -41,6 +51,6 @@ class account_move_line(osv.osv): draft_assigned_to_statement=False, ) - return super(account_move_line, self).copy_data(cr, uid, id, - default=default, - context=context) + return super(account_move_line, self).copy_data( + cr, uid, id, default=default, context=context + )