Bug 405 - CompanyTransaction & CompanyAccount: Negative balance when tried to debit credit_account type with insufficient fund
Summary: CompanyTransaction & CompanyAccount: Negative balance when tried to debit cre...
Status: RESOLVED FIXED
Alias: None
Product: Group 3
Classification: Unclassified
Component: Corporation Accounting System (show other bugs)
Version: unspecified
Hardware: PC Windows
: --- critical
Assignee: Hsu To-Liang
URL:
Depends on:
Blocks:
 
Reported: 2020-11-14 21:23 HKT by Hsu To-Liang
Modified: 2020-12-04 21:12 HKT (History)
0 users

See Also:


Attachments
CompanyAccount: when testing printTLedger (19.45 KB, text/plain)
2020-11-14 21:23 HKT, Hsu To-Liang
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Hsu To-Liang 2020-11-14 21:23:53 HKT
Created attachment 43 [details]
CompanyAccount: when testing printTLedger

Note that Cash account is of DEBIT_ACCOUNT type (debitting to Cash means increasing balance, creditting to Cash means decreasing)

Consider the following test case:

1. Cash account has a beginning balance of 0
2. Debit cash account with 1,000 -> now cash account has balance 1,000
3. Credit cash account with 2,000 -> will lead to balance -1,000 -> this transaction is not valid, should not be recorded at all

Code for test case: (may refer to attachement)
//
Company lukecompany=new Company();
CompanyAccount cashAccount=lukecompany.getAccountList().get("Cash");
Date tday=new Date();
CompanyTransaction trans1=new CompanyTransaction("id12334", tday, "Cash", "Accounts Payable",1000.0, "Borrow from bank");
CompanyTransaction trans2=new CompanyTransaction("id12335", tday, "Land", "Cash", 2000.0,"Buy land with cash");
lukecompany.recordTransaction(trans1);
lukecompany.recordTransaction(trans2);
		
cashAccount.printTLedger();
//

Output result:
                          Cash
--------------------------------------------------------------
Debit                          | Credit                        
--------------------------------------------------------------
TransID        |Amount         |TransID        |Amount         
--------------------------------------------------------------
id12334        |1000.0         |id12335        |2000.0         
--------------------------------------------------------------
Total          |-1000.0        |               |               
--------------------------------------------------------------
Comment 1 Hsu To-Liang 2020-12-04 21:12:42 HKT
Solved, add validation process before recording each transaction. 
I have put into consideration all 4 possible combinations:

  [Action]   [Account Type]
1.[Credit] a [Credit Account]
2.[Debit]  a [Debit Account]
3.[Credit] a [Debit Account]
4.[Debit]  a [Credit Account]

note that for 1 and 2, the balance will only increase, so no need for checking sufficient fund. On the other hand, for 3 and 4, the balance will decrease, therefore should test if the deducted amount is higher than current balance.

public boolean isValidTransaction(CompanyTransaction trans) {
		
		CompanyAccount accountToDebit = accountList.get(trans.getDebittedAccount());
		CompanyAccount accountToCredit = accountList.get(trans.getCredittedAccount());
		
		if (accountToCredit == null) {
			System.out.println("Error: " + trans.getCredittedAccount() + " is not a valid account.");
			return false;
		} else if (accountToDebit == null) {
			System.out.println("Error: " + trans.getDebittedAccount() + " is not a valid account.");
			return false;
		}
		
		//for credit account type, if debit means decrease -> may have credit balance < 0
		if(accountToDebit.getAccountType() == CompanyAccountType.CREDIT_ACCOUNT) {
			if(accountToDebit.getBalance() - trans.getAmount()<0) {
				System.out.println("Error: Cannot debit account "+trans.getDebittedAccount());
				return false;
			}
		}
		
		//for debit account type, if credit means decrease -> may have insufficient fund
		if(accountToCredit.getAccountType() == CompanyAccountType.DEBIT_ACCOUNT) {
			if(accountToCredit.getBalance() - trans.getAmount()<0) {
				System.out.println("Error: Cannot credit account "+trans.getCredittedAccount());
				return false;
			}
		}
		
		return true;
	}