diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..236b96f --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.DS_Store +*.vscode +a.out +build/ +*.DSYM diff --git a/build-project.sh b/build-project.sh index 20a6d00..14d12da 100755 --- a/build-project.sh +++ b/build-project.sh @@ -34,7 +34,7 @@ for file in employeeLogin.c createEmployeeAccount.c; do done -gcc mainMenu.c error.c createEmployeeAccount.c showGeneralInfoEmployee.c employeeLogin.c createCustomer.c helperFunctions.c loginCustomer.c customerMenu.c main.c calculatorAdd.c calculatorDivide.c calculatorFactorial.c calculatorGetUserInput.c calculatorGetUserInputFactorial.c calculatorMultiply.c calculatorSubtract.c displayMenuCalculator.c requestLoan.c -o main +gcc mainMenu.c error.c createEmployeeAccount.c showGeneralInfoEmployee.c employeeLogin.c createCustomer.c helperFunctions.c loginCustomer.c customerMenu.c main.c calculatorAdd.c calculatorDivide.c calculatorFactorial.c calculatorGetUserInput.c calculatorGetUserInputFactorial.c calculatorMultiply.c calculatorSubtract.c displayMenuCalculator.c checkLoanEligibility.c currencyExchange.c currentCustomerAccountBalance.c depositMoney.c displayDisclaimer.c interestCalculator.c requestLoan.c sendMoney.c updateCustomerAccountBalance.c withdrawMoney.c -o main ./main rm main diff --git a/project.yml b/project.yml index 5c0d1db..ecf0084 100644 --- a/project.yml +++ b/project.yml @@ -33,6 +33,8 @@ :test: - +:tests/** - -:tests/support + - +:tests/** + - -:tests/support :source: - src/createCustomer.* - src/customerLogin.* @@ -51,8 +53,14 @@ - src/calculatorSubtract.* - src/displayMenuCalculator.* - src/requestLoan.* + - src/checkLoanEligibility.* + - src/currenczExchange.* + - src/currentCustomerAccountBalance.* + - src/depositMoney.* + - src/displayDisclaimer.* :support: - tests/support + - tests/support :libraries: [] :defines: diff --git a/src/.vscode/c_cpp_properties.json b/src/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..5a5047e --- /dev/null +++ b/src/.vscode/c_cpp_properties.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "windowsSdkVersion": "10.0.19041.0", + "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "windows-msvc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/src/CustomerData.txt b/src/CustomerData.txt index e2c3570..3a6723a 100644 --- a/src/CustomerData.txt +++ b/src/CustomerData.txt @@ -1,7 +1,69 @@ -4675275=1234 -ID=4675275 -Forename=Frank -Surname=Burkhardt +1234=example +ID=1234 +forename=Test +Surname=Testermann +password=example +balance=150.5 + +1235=example +ID=1235 +forename=Test +Surname=Testermann +password=example +balance=290 + +1236=example +ID=1236 +forename=Test +Surname=Testermann +password=example +balance=194.5 + +1237=example +ID=1237 +forename=Test +Surname=Testermann +password=example +balance=340 + +1238=example +ID=1238 +forename=Test +Surname=Testermann +password=example +balance=1200 + +1666=example +ID=1237 +forename=Test +Surname=Testermann +password=example +balance=340 + +1327=example +ID=1238 +forename=Test +Surname=Testermann +password=example +balance=1200 +2189837=1234 +ID=2189837 +Forename=Mark +Surname=Karlsen Password=1234 Balance=50.0000€ +6984947=okdsjhasdjhksdj +ID=6984947 +Forename=Karl +Surname=Marx +Password=okdsjhasdjhksdj +Balance=600.0000€ + +7765335=123 +ID=7765335 +Forename=Friedrich +Surname=Moller +Password=123 +Balance=50.0000€ + diff --git a/src/_file_information.h b/src/_file_information.h new file mode 100644 index 0000000..9b919c4 --- /dev/null +++ b/src/_file_information.h @@ -0,0 +1,2 @@ +#define MAX_LENGTH 200 +#define CUSTOMER_DATA_FILE "src/CustomerData.txt" \ No newline at end of file diff --git a/src/checkLoanEligibility.c b/src/checkLoanEligibility.c new file mode 100644 index 0000000..e3ba64c --- /dev/null +++ b/src/checkLoanEligibility.c @@ -0,0 +1,30 @@ +#include "checkLoanEligibility.h" +#include "_file_information.h" + +bool checkLoanEligibility(int user_id) { + + // Eligible only when user is present in CustomerDataFile + + bool keep_reading = true; + bool eligibility = false; + char buffer[MAX_LENGTH]; + + FILE *file = fopen(CUSTOMER_DATA_FILE, "r"); + + while(keep_reading) { + fgets(buffer, MAX_LENGTH, file); + + if (feof(file)) { + keep_reading = false; + } + if(user_id == atoi(buffer)) { + eligibility = true; + keep_reading = false; + } + + } + + fclose(file); + return eligibility; + +} \ No newline at end of file diff --git a/src/checkLoanEligibility.h b/src/checkLoanEligibility.h new file mode 100644 index 0000000..4415c60 --- /dev/null +++ b/src/checkLoanEligibility.h @@ -0,0 +1,10 @@ +#ifndef CHECKLOANELIGIBILITY_H_ +#define CHECKLOANELIGIBILITY_H_ + +#include +#include +#include + +bool checkLoanEligibility(int user_id); + +#endif \ No newline at end of file diff --git a/src/currencyExchange.c b/src/currencyExchange.c new file mode 100644 index 0000000..83bf372 --- /dev/null +++ b/src/currencyExchange.c @@ -0,0 +1,20 @@ +#include "currencyExchange.h" + +float convert(float euro, int newCurrencyCode) { + switch(newCurrencyCode) { + case CURRENCY_CODE_USD: + return ( euro * USD_RATE_OF_ONE_EURO ); + + case CURRENCY_CODE_GBP: + return ( euro * GBP_RATE_OF_ONE_EURO ); + + case CURRENCY_CODE_JAPANESE_YEN: + return ( euro * JAPANESE_YEN_RATE_OF_ONE_EURO ); + + case CURRENCY_CODE_CHINESE_YUAN: + return ( euro * CHINESE_YUAN_RATE_OF_ONE_EURO ); + + } + + return -1; +} \ No newline at end of file diff --git a/src/currencyExchange.h b/src/currencyExchange.h new file mode 100644 index 0000000..49208aa --- /dev/null +++ b/src/currencyExchange.h @@ -0,0 +1,18 @@ +#ifndef CURRENCYEXCHANGE_H_ +#define CURRENCYEXCHANGE_H_ + +#include + +#define USD_RATE_OF_ONE_EURO 1.07 +#define GBP_RATE_OF_ONE_EURO 0.89 +#define JAPANESE_YEN_RATE_OF_ONE_EURO 140.9 +#define CHINESE_YUAN_RATE_OF_ONE_EURO 7.29 + +#define CURRENCY_CODE_USD 1 +#define CURRENCY_CODE_GBP 2 +#define CURRENCY_CODE_JAPANESE_YEN 3 +#define CURRENCY_CODE_CHINESE_YUAN 4 + +float convert(float euro, int newCurrencyCode); + +#endif \ No newline at end of file diff --git a/src/currentCustomerAccountBalance.c b/src/currentCustomerAccountBalance.c new file mode 100644 index 0000000..e7335a0 --- /dev/null +++ b/src/currentCustomerAccountBalance.c @@ -0,0 +1,65 @@ +#include "currentCustomerAccountBalance.h" +//#include "_file_information.h" + + +float fetchBalanceFromBalanceString(char balance_String[MAX_LENGTH]) { + float balance = 0; + char *token = strtok(balance_String, "="); // separates string to two parts + while (token != NULL) { + if (atoi(token) != 0) { + balance = atof(token); // converts string to float + break; + } + token = strtok(NULL, "="); + } + return balance; +} + +float readFileAndGetAvailableBalance(FILE *file, char stringID[MAX_LENGTH]) { + float balance = 0; + bool keep_reading = true; + char buffer[MAX_LENGTH]; + char balance_String[MAX_LENGTH]; + + while(keep_reading) { + fgets(buffer, MAX_LENGTH, file); + if (feof(file)) { + keep_reading = false; + } + else if(strstr(buffer, stringID)) { + for (int i = 0; i < 4; i++) { + fgets(buffer, MAX_LENGTH, file); + } + strcpy(balance_String, buffer); + balance = fetchBalanceFromBalanceString(balance_String); + keep_reading = false; + } + + } + return balance; +} + +float getAvailableAccountBalance(int user_id) { + float availableBalance = 0; + char stringID[MAX_LENGTH] = "ID="; + char user_id_as_string[MAX_LENGTH]; + + sprintf(user_id_as_string, "%d", user_id); // converts user_id to string + strcat(stringID, user_id_as_string); + // Now stringID is "ID=user_id" + + FILE *file = fopen(CUSTOMER_DATA_FILE, "r"); + if(file == 0) { + printf("Error: customer data file cannot be opened!\n"); + return 0; + } + else { + availableBalance = readFileAndGetAvailableBalance(file, stringID); + } + + + fclose(file); + + return availableBalance; + +} \ No newline at end of file diff --git a/src/currentCustomerAccountBalance.h b/src/currentCustomerAccountBalance.h new file mode 100644 index 0000000..36bb66e --- /dev/null +++ b/src/currentCustomerAccountBalance.h @@ -0,0 +1,16 @@ +#ifndef CurrentCustomerAccountBalance_H +#define CurrentCustomerAccountBalance_H + + +#include +#include +#include +#include + +#include "_file_information.h" + +float getAvailableAccountBalance(int user_id); +float fetchBalanceFromBalanceString(char balance_String[MAX_LENGTH]); +float readFileAndGetAvailableBalance(FILE *file, char stringID[MAX_LENGTH]); + +#endif \ No newline at end of file diff --git a/src/customerMenu.c b/src/customerMenu.c index 49a8e19..2d21d3d 100644 --- a/src/customerMenu.c +++ b/src/customerMenu.c @@ -1,6 +1,6 @@ #include "customerMenu.h" -int customerChoiceForMenuItem(int numberOfMenuItem) +int customerChoiceForMenuItem(int numberOfMenuItem, unsigned int *ptr) { int returnStatus = 0; switch(numberOfMenuItem){ @@ -31,7 +31,7 @@ int customerChoiceForMenuItem(int numberOfMenuItem) return returnStatus; } -void showAllMenuEntries() +void showAllMenuEntries(unsigned int *ptr) { int userDecision = 0; @@ -57,16 +57,17 @@ void showAllMenuEntries() puts("Your decision: "); scanf("%d",&userDecision); - customerChoiceForMenuItem(userDecision); + customerChoiceForMenuItem(userDecision, ptr); } -void menu(customer_t *c) +void menu(unsigned int *ptr) { - if(c==NULL){ + if(ptr==NULL){ puts("Invalid pointer. Aborting!"); exit(-1); }else{ puts("Welcome!"); - showAllMenuEntries(); + printf("Your ID is: %u\n", *ptr); + showAllMenuEntries(ptr); } } diff --git a/src/customerMenu.h b/src/customerMenu.h index 482789b..9590d9f 100644 --- a/src/customerMenu.h +++ b/src/customerMenu.h @@ -2,6 +2,6 @@ #include #include "customerProperties.h" #include "requestLoan.h" -int customerChoiceForMenuItem(int); -void showAllMenuEntries(); -void menu(customer_t *); +int customerChoiceForMenuItem(int, unsigned int *pointer); +void showAllMenuEntries(unsigned int *pointer); +void menu(unsigned int *pointer); \ No newline at end of file diff --git a/src/depositMoney.c b/src/depositMoney.c new file mode 100644 index 0000000..5732f7e --- /dev/null +++ b/src/depositMoney.c @@ -0,0 +1,77 @@ +#include "depositMoney.h" +#include "updateCustomerAccountBalance.h" +#include "currentCustomerAccountBalance.h" + +void askToTryAgain(bool afterError, int customerID){ + char choice; + + printf("\n"); + if(afterError){ + printf("Would you like to try again? [y] yes [n] no: "); + }else{ + printf("Would you like to make another deposit? [y] yes [n] no: "); + } + scanf(" %c", &choice); + switch(choice){ + case 'y': + depositMoney(customerID); + break; + case 'n': + break; + } + +} + +bool depositMoney(int customerID){ + + float availableAccountBalance=getAvailableAccountBalance(customerID); + if(availableAccountBalance<0){ + printf("\nCould not retreive account balance. Please contact staff.\n"); + } + float amountToDeposit = 0; + + printf("\nPlease enter the amount you want to deposit: "); + scanf("%f", &amountToDeposit); + + if(amountToDeposit>=0 && amountToDeposit>MINIMUM_DEPOSIT_AMOUNT){ + if(updateAvailableAccountBalance(customerID, availableAccountBalance+amountToDeposit)){ + printf("\nYou have successfully deposited %.2f. New account balance is %.2f", amountToDeposit, availableAccountBalance+amountToDeposit); + askToTryAgain(false,customerID); + return true; + }else{ + printf("Something went wrong. Please contact staff."); + return false; + } + }else if(amountToDeposit>0){ + printf("The amount you entered is lower than the minimum amount."); + askToTryAgain(true,customerID); + return false; //amount lower than minimum deposit amount + }else{ + printf("Invalid input."); + askToTryAgain(true,customerID); + return false; //invalid input + } + return false; +} + +bool depositSpecificAmount(int customerID, float amount){ + + float availableAccountBalance=getAvailableAccountBalance(customerID); + + if(amount>0){ + if(updateAvailableAccountBalance(customerID, availableAccountBalance+amount)){ + return true; + }else{ + return false; + } + } + return false; +} + +/* +int main(){ + depositSpecificAmount(1234,5000); + //depositMoney(1234); + return 0; +} +*/ \ No newline at end of file diff --git a/src/depositMoney.h b/src/depositMoney.h new file mode 100644 index 0000000..c06d44f --- /dev/null +++ b/src/depositMoney.h @@ -0,0 +1,9 @@ +#include +#include "customerProperties.h" +#include +#define MINIMUM_DEPOSIT_AMOUNT 5 + + +bool depositMoney(int customerID); +void askToTryAgain(bool afterError, int customerID); +bool depositSpecificAmount(int customerID, float amount); \ No newline at end of file diff --git a/src/displayDisclaimer.c b/src/displayDisclaimer.c new file mode 100644 index 0000000..a324e93 --- /dev/null +++ b/src/displayDisclaimer.c @@ -0,0 +1,20 @@ +#include "displayDisclaimer.h" + +void displayDisclaimer(){ + printf(" W E L C O M E T O \n"); + printf(" .______ .___ ___. _______.\n"); + printf(" | _ \\ | \\/ | / |\n"); + printf(" | |_) | | \\ / | | (----`\n"); + printf(" | _ < | |\\/| | \\ \\ \n"); + printf(" | |_) | | | | | .----) | \n"); + printf(" |______/ |__| |__| |_______/ \n"); + printf(" \n"); + printf("B A N K M A N A G E M E N T S Y S T E M\n"); + printf(":.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:\n"); + printf("Created by Atharva, Can, Haytham, Julius, Shivam, and Yahya for AI1001.\n"); +} + +// int main(){ +// displayDisclaimer(); +// return 1; +// } \ No newline at end of file diff --git a/src/displayDisclaimer.h b/src/displayDisclaimer.h new file mode 100644 index 0000000..7043974 --- /dev/null +++ b/src/displayDisclaimer.h @@ -0,0 +1,7 @@ +#ifndef DISPLAYDISCLAIMER_H_ +#define DISPLAYDISCLAIMER_H_ +#include + +void displayDisclaimer(); + +#endif \ No newline at end of file diff --git a/src/employeesCredentialsList.txt b/src/employeesCredentialsList.txt index ed5a12d..7b854aa 100644 --- a/src/employeesCredentialsList.txt +++ b/src/employeesCredentialsList.txt @@ -9,3 +9,31 @@ Julius Insertcatfdai7057 Mohamed MDfdai6618 Shivam Schivam007fdlt3781 + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/employeesData.txt b/src/employeesData.txt index 16f8e9a..bf7405b 100644 --- a/src/employeesData.txt +++ b/src/employeesData.txt @@ -32,3 +32,59 @@ Name : Shivam Last name : Chaudhary Adress : Fulda,leipzigerstrasse,6 Phone number : +4918756871384 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/interestCalculator.c b/src/interestCalculator.c new file mode 100644 index 0000000..9964047 --- /dev/null +++ b/src/interestCalculator.c @@ -0,0 +1,162 @@ +#include "interestCalculator.h" + + +void troubleshoot(int errorCode){ + printf("Error! The requested operation was terminated because of an issue. Here are some details about the error:\n---------------\n"); + + switch(errorCode){ + case 0: + printf("Principal amount not valid. Make sure it is a valid number over the value of zero."); + break; + case 1: + printf("Interest rate not valid. Make sure it is a valid number over the value of zero."); + break; + case 2: + printf("Duration not valid. Make sure it is a valid number over the value of zero."); + break; + case 3: + printf("Invalid option. Aborting."); + break; + case 4: + printf("Your goal cannot be smaller than your principal funds. Aborting."); + break; + } +} + +void askForSavingGoal(float principalAmount, float accInterestPerYear) { + char c; + float goal; + float timeForGoal; + + printf("\nWould you like to set a saving goal? [y/n]: "); + scanf(" %c", &c); + + if (c != 'y' && c != 'Y') { + return; + } + + printf("\nPlease enter your goal amount in €: "); + scanf("%f", &goal); + + if (goal < principalAmount) { + troubleshoot(4); + return; + } + + timeForGoal = (goal - principalAmount) / accInterestPerYear; + printf("\nIn %.1f years you will reach your goal of %.2f.\n", timeForGoal, goal); +} + + +float initiateInterest(float principalAmount, float interest, float time){ + return principalAmount*(1+(interest*time)); +} + +void calculateYearlyInterest(){ + float principalAmount; + float interestPerYear; + float timeInYears; + int choice; + + printf("Please enter the principal amount:"); + if (scanf("%f", &principalAmount) != 1 || principalAmount <= 0) { + troubleshoot(0); + return; + } + + printf("\nPlease enter interest per year (percentage):"); + if (scanf("%f", &interestPerYear) != 1 || interestPerYear <= 0) { + troubleshoot(0); + return; + } + printf("\nWould you like to enter the time in [1]months or in [2]years?\n"); + scanf("%d",&choice); + if(choice==1){ + printf("\nPlease enter interest time in months:"); + if (scanf("%f", &timeInYears) != 1 || timeInYears <= 0) { + troubleshoot(2); + return; + } + timeInYears=timeInYears/12; + + }else if(choice==2){ + printf("\nPlease enter interest time in years:"); + if (scanf("%f", &timeInYears) != 1 || timeInYears <= 0) { + troubleshoot(2); + return; + } + }else{ + troubleshoot(2); + } + + + + float interestDecimal=interestPerYear/100; + + float result= initiateInterest(principalAmount,interestDecimal,timeInYears); + printf("\nAmount with the interest is %.2f€.",result); + askForSavingGoal(principalAmount,principalAmount*interestDecimal); +} +void calculateMonthlyInterest(){ + float principalAmount; + float interestPerMonth; + float timeInMonths; + + printf("Please enter the principal amount:"); + if (scanf("%f", &principalAmount) != 1 || principalAmount <= 0) { + troubleshoot(0); + return; + } + + printf("\nPlease enter interest per month (percentage):"); + if (scanf("%f", &interestPerMonth) != 1 || interestPerMonth <= 0) { + troubleshoot(0); + return; + } + + printf("\nPlease enter interest time in months:"); + if (scanf("%f", &timeInMonths) != 1 || timeInMonths <= 0) { + troubleshoot(2); + return; + } + + float interestDecimal=interestPerMonth/100; + + float result= initiateInterest(principalAmount,interestDecimal,timeInMonths); + printf("\nAmount with the interest is %.2f€.",result); +} + +void initiateCalculator() { + int input; + char c; + + printf("Welcome to the interest calculator. Please select an option:\n" + "[1] Calculate yearly interest\n" + "[2] Calculate monthly interest\n"); + scanf("%d", &input); + + switch (input) { + case 1: + calculateYearlyInterest(); + break; + case 2: + calculateMonthlyInterest(); + break; + default: + break; + } + + printf("\nThank you for using our services. Would you like to do another calculation? [y/n]: "); + scanf(" %c", &c); + + if (c == 'y' || c == 'Y') { + initiateCalculator(); + } +} + + +// int main(){ + +// initiateCalculator(); + +// } diff --git a/src/interestCalculator.h b/src/interestCalculator.h new file mode 100644 index 0000000..0c9c3b9 --- /dev/null +++ b/src/interestCalculator.h @@ -0,0 +1,11 @@ +#ifndef INTERESTCALCULATOR_H_ +#define INTERESTCALCULATOR_H_ + +#include + +void calculateYearlyInterest(); +void calculateMonthlyInterest(); +void askForSavingGoal(float principalAmount, float accInterestPerYear); +float initiateInterest(float principalAmount, float interest, float time); +void troubleshoot(int errorCode); +#endif \ No newline at end of file diff --git a/src/lineReplacer.h b/src/lineReplacer.h new file mode 100644 index 0000000..c3ee57b --- /dev/null +++ b/src/lineReplacer.h @@ -0,0 +1,11 @@ +#ifndef LINEREPLACER_H_ +#define LINEREPLACER_H_ + +#include +#include +#include +#include + +void replaceLineInFile(const char* file_name, int line, const char* new_line); //replaces the line at "line" on the file "file_name", with the new line "new_line". + +#endif \ No newline at end of file diff --git a/src/loginCustomer.c b/src/loginCustomer.c index f466181..bc84e19 100644 --- a/src/loginCustomer.c +++ b/src/loginCustomer.c @@ -42,11 +42,12 @@ void collectCustomerDataForLogin(int attempts) exit(-1); } bool loginSuccessful = loginCustomer(&c); + unsigned int value = toUnsignedInteger(c.IDAsString); free(c.IDAsString); free(c.password); if(loginSuccessful) { - //call menu(); - menu(&c); + int *ptr = &value; + menu(ptr); }else if(!loginSuccessful && attempts < MAX_LOGIN_ATTEMPTS){ printf("You have %d attempts left.\n", MAX_LOGIN_ATTEMPTS - attempts); collectCustomerDataForLogin(++attempts); diff --git a/src/loginCustomer.h b/src/loginCustomer.h index e126f86..b9d2b17 100644 --- a/src/loginCustomer.h +++ b/src/loginCustomer.h @@ -7,6 +7,7 @@ #include "createCustomer.h" #include "customerMenu.h" #include "error.h" +#include "customerProperties.h" #define MAX_LOGIN_ATTEMPTS 3 bool checkLogin(bool); void collectCustomerDataForLogin(int); diff --git a/src/sendMoney.c b/src/sendMoney.c new file mode 100644 index 0000000..191dca0 --- /dev/null +++ b/src/sendMoney.c @@ -0,0 +1,120 @@ +#include "sendMoney.h" +#include "depositMoney.h" +#include "withdrawMoney.h" +#include "currencyExchange.h" +#include "currentCustomerAccountBalance.h" +#include "updateCustomerAccountBalance.h" + + + +void showBalance(int customerID){ + float balance=getAvailableAccountBalance(customerID); + printf("\n:.:.:.:.:.:"); + printf("\nYour current balance is %.2f.\n",balance); + printf(":.:.:.:.:.:\n"); +} + +float askToConvert(float input, int customerID){ + char c; + char symbol[]=""; + int id; + float converted; + printf("\nWould you like to convert the amount from € to another currency?[y] yes [any] no\n"); + scanf(" %c",&c); + if(c=='y'||c=='Y'){ + printf("\nPlease select from one of the following currencties to convert to:"); + printf("\n[1] USD"); + printf("\n[2] GBP"); + printf("\n[3] YEN"); + printf("\n[4] YUAN\n"); + scanf("%d",&id); + + if(id>0&&id<5){ + converted=convert(input,id); + }else{ + return 0; + } + switch(id){ + case 1: + symbol[0]='$'; + break; + case 2: + symbol[0]='P'; + break; + case 3: + symbol[0]='Y'; + break; + case 4: + symbol[0]='X'; + break; + } + printf("\nYou have successfuly transfered %.2f%s to [%d]",converted, symbol,customerID); + return converted; + }else{ + return 0; + } +} + +void askToShowBalance(int customerID){ + char c; + printf("\nWould you like to see your remaining balance? [y] yes [any] no\n"); + scanf(" %c",&c); + if(c=='y' || c=='Y'){ + showBalance(customerID); + } + return; +} + +bool sendMoney(int customerID){ + float availableAccountBalance=getAvailableAccountBalance(customerID); + float amountToSend; + int recID; + + showBalance(customerID); + printf("\nHow much would you like to send?\n"); + scanf("%f",&amountToSend); + if(amountToSend>0 && amountToSend1000){ + bool recExists=checkCustomerExists(recID); + if(recExists){ + if(recID==customerID){ + printf("\nYou cannot send money to yourself. Aborting. \n"); + return false; + } + else{ + if(withdrawSpecificAmount(customerID, amountToSend)){ + if(depositSpecificAmount(recID, amountToSend)){ + askToConvert(amountToSend, recID); + //printf("\nYou have successfuly transfered %.2f€ to [%d]",amountToSend,recID); + askToShowBalance(customerID); + return true; + } + else{ + printf("\nSomething went wrong with the transfer. Please contact staff."); + } + } + } + + }else{ + printf("\nThis ID is not from a customer of our bank. A transfer fee of %.2f€ will be taken.\n", TRANSFER_FEE); + if(withdrawSpecificAmount(customerID, amountToSend+TRANSFER_FEE)){ + askToConvert(amountToSend, recID); + //printf("\nYou have successfuly transfered %.2f€ to [%d]\n",amountToSend,recID); + askToShowBalance(customerID); + return true; + } + } + } + else + { + printf("\nThe ID you have entered is not valid. Aborting. \n"); + } + + }else{ + //error + return false; + } + return false; +} \ No newline at end of file diff --git a/src/sendMoney.h b/src/sendMoney.h new file mode 100644 index 0000000..df64387 --- /dev/null +++ b/src/sendMoney.h @@ -0,0 +1,14 @@ +#ifndef SENDMONEY_H +#define SENDMONEY_H +#include +#include +#include +#include + +#define TRANSFER_FEE 0.8 +void showBalance(int customerID); +float askToConvert(float input, int customerID); +void askToShowBalance(int customerID); +bool sendMoney(int customerID); + +#endif // SENDMONEY_H diff --git a/src/updateCustomerAccountBalance.c b/src/updateCustomerAccountBalance.c new file mode 100644 index 0000000..900928e --- /dev/null +++ b/src/updateCustomerAccountBalance.c @@ -0,0 +1,169 @@ +#include "updateCustomerAccountBalance.h" +#include "lineReplacer.h" +#include "_file_information.h" + +void troubleShoot(int errorCode){ + printf("Error! The requested operation was terminated because of an issue. Here are some details about the error:\n---------------\n"); + + switch(errorCode){ + case 0: + printf("Requested file could not be opened. Are you sure it exists or that the program has the required permissions?"); + break; + case 1: + printf("A temporary file could not be generated. Are you sure the bank management system has the required authorization to create new files?"); + break; + case 2: + printf("Replacement of the old file failed. Are you sure the bank management system has the required authorization to delete files?"); + break; + case 3: + printf("Renaming of a file failed. Are you sure the bank management system has the required authorization to rename files?"); + break; + case 4: + printf("Could not find the customer. Please contact customer support."); + break; + } +} + +void replaceLineInFile(const char* file_name, int line, const char* new_line){ + FILE* file = fopen(file_name, "r"); + if (file == NULL) { + troubleShoot(0); + return; + } + char current_string[1024]; + int current_line = 1; + char *temp_file_name = "temp.txt"; + FILE* temp_file = fopen(temp_file_name, "w"); + if (temp_file == NULL) { + troubleShoot(1); + fclose(file); + return; + } + while (fgets(current_string, sizeof(current_string), file) != NULL) { + if (current_line == line) { + fprintf(temp_file, "%s", new_line); + fputs("\n", temp_file); + } else { + fprintf(temp_file, "%s", current_string); + } + current_line++; + } + fclose(file); + fclose(temp_file); + if(remove(file_name)!=0){ + troubleShoot(2); + } // Remove the original file + if(rename(temp_file_name, file_name)!=0){ + troubleShoot(3); + } // Rename the temp file to the original file +} + +void replaceBalanceInString(float replacementBalance, int currentLine) { + char newBalanceLine[MAX_LENGTH] = "balance="; + char balance_as_string[MAX_LENGTH]; + sprintf(balance_as_string, "%g", replacementBalance); //converts replacement balance to string + strcat(newBalanceLine, balance_as_string); + replaceLineInFile(CUSTOMER_DATA_FILE,currentLine,newBalanceLine); +} + +bool updateAvailableAccountBalance(int user_id, float newBalance){ + bool keep_reading = true; + bool customer_found=false; + char buffer[MAX_LENGTH]; + char stringID[MAX_LENGTH] = "ID="; + char user_id_as_string[MAX_LENGTH]; + char balance_String[MAX_LENGTH]; + int currentLine=0; + + sprintf(user_id_as_string, "%d", user_id); // converts user_id to string + strcat(stringID, user_id_as_string); + + FILE *file = fopen(CUSTOMER_DATA_FILE, "r+"); + if (file == NULL) { + troubleShoot(0); + return false; + } + while(keep_reading) { + fgets(buffer, MAX_LENGTH, file); + currentLine++; + if (feof(file)) { + keep_reading = false; + } + else if(strstr(buffer, stringID)) { //found the customer + + for (int i = 0; i < 4; i++) { + fgets(buffer, MAX_LENGTH, file); + } + + strcpy(balance_String, buffer); + currentLine+=4; + keep_reading = false; + customer_found=true; + } + + } + + fclose(file);; + if(customer_found){ + replaceBalanceInString(newBalance,currentLine); + return true; + }else{ + troubleShoot(4); + } + return false; + +} +bool checkCustomerExists(int customerID){ + bool keep_reading = true; + bool customer_found=false; + char buffer[MAX_LENGTH]; + char stringID[MAX_LENGTH] = "ID="; + char user_id_as_string[MAX_LENGTH]; + char balance_String[MAX_LENGTH]; + int currentLine=0; + + sprintf(user_id_as_string, "%d", customerID); // converts user_id to string + strcat(stringID, user_id_as_string); + + FILE *file = fopen(CUSTOMER_DATA_FILE, "r+"); + if (file == NULL) { + return false; + } + while(keep_reading) { + fgets(buffer, MAX_LENGTH, file); + currentLine++; + if (feof(file)) { + keep_reading = false; + } + else if(strstr(buffer, stringID)) { //found the customer + + for (int i = 0; i < 4; i++) { + fgets(buffer, MAX_LENGTH, file); + } + + strcpy(balance_String, buffer); + currentLine+=4; + keep_reading = false; + customer_found=true; + } + + } + + fclose(file);; + if(customer_found){ + return true; + }else{ + return false; + } + return false; + +} + +//traditional testing section +/* +int main(int argc, char *argv[]) +{ + updateAvailableAccountBalance(1327,70); + return 0; +} +*/ diff --git a/src/updateCustomerAccountBalance.h b/src/updateCustomerAccountBalance.h new file mode 100644 index 0000000..5b056f4 --- /dev/null +++ b/src/updateCustomerAccountBalance.h @@ -0,0 +1,15 @@ +#ifndef UpdateCustomerAccountBalance_H +#define UpdateCustomerAccountBalance_H + +#include +#include +#include +#include + + + +bool updateAvailableAccountBalance(int user_id, float newBalance); +bool checkCustomerExists(int customerID); +void replaceBalanceInString(float replacementBalance, int currentLine); + +#endif \ No newline at end of file diff --git a/src/withdrawMoney.c b/src/withdrawMoney.c new file mode 100644 index 0000000..65e23b2 --- /dev/null +++ b/src/withdrawMoney.c @@ -0,0 +1,103 @@ +#include "withdrawMoney.h" +#include "updateCustomerAccountBalance.h" +#include "currentCustomerAccountBalance.h" + + +void notifyCustomer(float amountToWithdraw, float remainingAccountBalance, int user_id) { + char c; + + printf("You have successfully withdrawn %.2f €.\n", amountToWithdraw); + printf("Remaining account balance: %.2f €\n\n", remainingAccountBalance); + printf("Would you like to do another withdrawal? [y] yes [any] no\n"); + scanf(" %c", &c); + + if (c=='y'||c=='Y') { + withdraw(user_id); + }else{ + return; + } +} + +float initiateWithdraw(float amountToWithdraw, float availableAccountBalance) { + float remainingAccountBalance = (availableAccountBalance - amountToWithdraw); + + return remainingAccountBalance; +} + +bool withdraw(int user_id) { + float amountToWithdraw; + char tryDifferentAmount; + float remainingAccountBalance; + bool updateSuccess = false; + + float availableAccountBalance = getAvailableAccountBalance(user_id); + + printf("\n:.:.:.:.:.:"); + printf("\nYour current balance is %.2f.\n",availableAccountBalance); + printf(":.:.:.:.:.:\n"); + + printf("Enter amount to withdraw: "); + scanf("%f", &amountToWithdraw); + + + if (amountToWithdraw > 0) { + if (amountToWithdraw <= availableAccountBalance) { + + if(amountToWithdraw>MAX_AMOUNT){ + printf("\nYou cannot withdraw more than %d€.",MAX_AMOUNT); + return false; + } + + remainingAccountBalance = initiateWithdraw(amountToWithdraw, availableAccountBalance); + updateSuccess = updateAvailableAccountBalance(user_id, remainingAccountBalance); + if( updateSuccess ) { + notifyCustomer(amountToWithdraw, remainingAccountBalance, user_id); + } + else { + printf("Some error occured! Sorry for the inconvenience caused.\n"); + } + return updateSuccess; + + } + else { + printf("You don't have sufficient money to withdraw. Do you want to try different amount?\n[y]: Yes, any other key : exit"); + scanf("%c", &tryDifferentAmount); + if (tryDifferentAmount == 'Y' || tryDifferentAmount == 'y') { + withdraw(user_id); + } + else { + //showAllMenuEntries(); + return false; + } + } + } + else { + printf("Invalid Input! Please try again.\n"); + withdraw(user_id); + } + return false; +} + +bool withdrawSpecificAmount(int user_id, float amountToWithdraw) { + float remainingAccountBalance; + + + float availableAccountBalance = getAvailableAccountBalance(user_id); + if (amountToWithdraw > 0) { + + if (amountToWithdraw <= availableAccountBalance) { + + remainingAccountBalance = initiateWithdraw(amountToWithdraw, availableAccountBalance); + if(updateAvailableAccountBalance(user_id, remainingAccountBalance)){ + return true; + } + + } + } + return false; +} + +// int main(){ +// withdraw(1234); +// return 1; +// } \ No newline at end of file diff --git a/src/withdrawMoney.h b/src/withdrawMoney.h new file mode 100644 index 0000000..2303078 --- /dev/null +++ b/src/withdrawMoney.h @@ -0,0 +1,14 @@ +#ifndef WITHDRAWMONEY_H_ +#define WITHDRAWMONEY_H_ + +#include +#include + +#define MAX_AMOUNT 10000 + +bool withdraw(int user_id); +float initiateWithdraw(float amountToWithdraw, float availableAccountBalance); +void notifyCustomer(float amountToWithdraw, float remainingAccountBalance, int user_id); +bool withdrawSpecificAmount(int user_id, float amountToWithdraw); + +#endif \ No newline at end of file diff --git a/team.md b/team.md new file mode 100644 index 0000000..f0e0a28 --- /dev/null +++ b/team.md @@ -0,0 +1,6 @@ +- Can Hacioglu, fdlt3817 +- Atharva Kishor Naik, fdai7514 +- Julius Philipp Engel, fdai7057 +- Shivam Chaudhary, fdlt3781 +- Mohamed Yahya Dahi, fdai6618 +- Haytham Daoula, fdai7207 \ No newline at end of file diff --git a/tests/test_CustomerMenu.c b/tests/test_CustomerMenu.c index 96c3f9d..044301b 100644 --- a/tests/test_CustomerMenu.c +++ b/tests/test_CustomerMenu.c @@ -5,21 +5,22 @@ void test_customerChoiceForMenuEntry() { int decision = 1; + unsigned int *ptr = NULL; /*customer choses to send money, return 1*/ - TEST_ASSERT_EQUAL_INT(1, customerChoiceForMenuItem(decision)); + TEST_ASSERT_EQUAL_INT(1, customerChoiceForMenuItem(decision,ptr)); /*customer choses to withdraw money, return 2*/ decision = 2; - TEST_ASSERT_EQUAL_INT(2, customerChoiceForMenuItem(decision)); + TEST_ASSERT_EQUAL_INT(2, customerChoiceForMenuItem(decision,ptr)); /*customer choses to deposit money, return 3*/ decision = 3; - TEST_ASSERT_EQUAL_INT(3, customerChoiceForMenuItem(decision)); + TEST_ASSERT_EQUAL_INT(3, customerChoiceForMenuItem(decision,ptr)); /*customer choses to request a loan, return 4*/ decision = 4; - TEST_ASSERT_EQUAL_INT(4, customerChoiceForMenuItem(decision)); + TEST_ASSERT_EQUAL_INT(4, customerChoiceForMenuItem(decision,ptr)); /*invalid input values, the return value should always be -1*/ int arrayOfInvalidValues[] = {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,0, 123,3247,6839,38593,3033,55055}; int length = sizeof(arrayOfInvalidValues)/sizeof(int); for(int i=0;i +#include "unity.h" +#include "../src/currentCustomerAccountBalance.c" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_fetchBalanceFromBalanceString(void) { + + /* Arrange */ + + char balanceString[5][100] = { + "balance=0", + "balance=100", + "balance=200", + "balance=300", + "balance=400" + }; + + /* Act */ + + float balance = 0; + float result[5]; + float expected[5]; + + for (int i = 0; i < 5; i++) { + result[i] = fetchBalanceFromBalanceString(balanceString[i]); + } + + /* Assert */ + + for (int i = 0; i < 5; i++) { + expected[i] = balance; + balance += 100; + } + + for (int i =0; i < 5; i++) { + TEST_ASSERT_EQUAL_FLOAT(expected[i],result[i]); + } + + +} + + +void test_checkFileOpen(void) { + + /* Act and assert */ + + FILE *file = fopen(CUSTOMER_DATA_FILE, "r"); + + TEST_ASSERT_TRUE(file); + + fclose(file); +} + +void test_failOpenFile(void) { + + /* Act and assert */ + + FILE *file = fopen("false_file_name", "r"); + + TEST_ASSERT_FALSE(file); + +} + +void test_getAvailableAccountBalance(void) { + + /* Act and assert */ + + int user_id = 1234; // Random user_id (because idea is to read the file and get a float value) + float max = FLT_MAX; + int result = getAvailableAccountBalance(user_id); + + TEST_ASSERT_TRUE(result < max); // Pass if function is successfully called and a float value (balance) is returned +} + + + + +#endif // TEST diff --git a/tests/test_depositMoney.c b/tests/test_depositMoney.c new file mode 100644 index 0000000..186ef28 --- /dev/null +++ b/tests/test_depositMoney.c @@ -0,0 +1,36 @@ +#include "unity.h" +#include "../src/currentCustomerAccountBalance.c" +#include "../src/depositMoney.c" +#include "../src/updateCustomerAccountBalance.c" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_depositSpecificAmount(void) { + + /* Arrange */ + + int length = 5; + int userIDs[] = {1234,1235,1236,1237,1238}; + float amountToDeposit[] = {200.5, 340, 244.5, 340, 1200}; + + bool result[length]; + + /* Act */ + + for (int i = 0; i < length; i++) { + result[i] = depositSpecificAmount( userIDs[i], amountToDeposit[i] ); + } + + /* Assert */ + + for (int i = 0; i < length; i++) { + TEST_ASSERT_TRUE(result[i]); + } + +} \ No newline at end of file diff --git a/tests/test_interestCalculator.c b/tests/test_interestCalculator.c new file mode 100644 index 0000000..1aa11ca --- /dev/null +++ b/tests/test_interestCalculator.c @@ -0,0 +1,50 @@ +#ifdef TEST + +#include "unity.h" +#include "../src/interestCalculator.c" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_initiateInterest(void) { + + /* Arrange */ + + int length = 10; + float startAmount[] = {34, 233, 4400, 1600, 245, 34544, 3767.32, 1422, 5435, 8199}; + float yearlyInterest=12; + float durationInYears=2.5; + + float monthlyInterest=8; + float durationInMonths=3.9; + + float resultsYearly[length]; + float resultsMonthly[length]; + + float expectedYearly[]={44.2,302.9,5720,2080,318.5,44907.2,4897.516,1848.6,7065.5,10658.7}; + float expectedMonthly[]={44.608,305.696,5772.8,2099.2,321.44,45321.73,4942.724,1865.664,7130.72,10757.09}; + + /* Act */ + + for (int i = 0; i < length; i++) { + resultsYearly[i]=initiateInterest(startAmount[i],yearlyInterest/100, durationInYears); + } + for (int i = 0; i < length; i++) { + resultsMonthly[i]=initiateInterest(startAmount[i],monthlyInterest/100, durationInMonths); + } + + /* Assert*/ + + for (int i = 0; i < length; i++) { + TEST_ASSERT_EQUAL_FLOAT(expectedYearly[i], resultsYearly[i]); + TEST_ASSERT_EQUAL_FLOAT(expectedMonthly[i], resultsMonthly[i]); + } +} + + +#endif // TEST \ No newline at end of file diff --git a/tests/test_updateCustomerAccountBalance.c b/tests/test_updateCustomerAccountBalance.c new file mode 100644 index 0000000..f1b4acd --- /dev/null +++ b/tests/test_updateCustomerAccountBalance.c @@ -0,0 +1,67 @@ +#ifdef TEST + +#include "unity.h" + +#include "../src/updateCustomerAccountBalance.c" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_updateAvailableAccountBalanceSuccess(void){ + + /* + int id1 = 1234; + int id2 = 1327; + int id3 = 1666; + + int newBalance1=500; + int newBalance2=800; + int newBalance3=700; + + bool results1=updateAvailableAccountBalance(id1,newBalance1); + bool results2=updateAvailableAccountBalance(id2,newBalance2); + bool results3=updateAvailableAccountBalance(id3,newBalance3); + + TEST_ASSERT_TRUE(results1); + TEST_ASSERT_TRUE(results2); + TEST_ASSERT_TRUE(results3); + */ + + /* Arrange */ + + int length = 5; + + float amountToUpdate[] = {200.5, 340, 244.5, 340, 1200}; + int userIDs[] = {1234,1235,1236,1237,1238}; + + float expectedValue[length]; + bool result[length]; + + /* Act */ + + for (int i = 0; i < length; i++) { + result[i] = updateAvailableAccountBalance(userIDs[i],amountToUpdate[i]); + } + + /* Assert */ + + for (int i = 0; i < length; i++) { + TEST_ASSERT_TRUE(result[i]); + } + +} +void test_failOpenFile(void) { + + /* Act and assert */ + + FILE *file = fopen("false_file_name", "r"); + + TEST_ASSERT_FALSE(file); + +} +#endif diff --git a/tests/test_withdrawMoney.c b/tests/test_withdrawMoney.c new file mode 100644 index 0000000..5a492fd --- /dev/null +++ b/tests/test_withdrawMoney.c @@ -0,0 +1,93 @@ +#ifdef TEST + +#include "unity.h" +#include "../src/withdrawMoney.c" +#include "../src/updateCustomerAccountBalance.c" +#include "../src/currentCustomerAccountBalance.c" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_initiateWithdraw(void) { + + /* Arrange */ + + int length = 10; + + float amountToWithdraw[] = {200.5, 340, 244.5, 340, 1200, 3232, 1123, 460.5, 900, 1005}; + float availableAccountBalance[] = {2000, 3400, 2445, 3400, 6000, 5000, 1000, 2000, 2000, 9000}; + + float expectedValue[length]; + float result[length]; + + /* Act */ + + for (int i = 0; i < length; i++) { + result[i] = initiateWithdraw( amountToWithdraw[i], availableAccountBalance[i] ); + } + + /* Assert */ + + for (int i = 0; i < length; i++) { + expectedValue[i] = ( availableAccountBalance[i] - amountToWithdraw[i] ); + } + + for (int i = 0; i < length; i++) { + TEST_ASSERT_EQUAL_FLOAT(expectedValue[i],result[i]); + } + +} + +void test_withdrawSpecificAmountSuccess(void) { + + /* Arrange */ + + int user_id[3] = {1234, 1235, 1236}; // user_ids from file for testing + + bool result[3]; + + /* Act */ + + for (int i = 0; i < 3; i++) { + result[i] = withdrawSpecificAmount(user_id[i], 50); + } + + /* Assert */ + + for (int i = 0; i < 3; i++) { + TEST_ASSERT_TRUE(result[i]); // Pass if withdrawal is successful + } + +} + +void test_withdrawSpecificAmountFailure(void) { + + /* Arrange */ + + int user_id[3] = {12934, 13027, 16606}; // Random wrong user_ids + + bool result[3]; + + /* Act */ + + for (int i = 0; i < 3; i++) { + result[i] = withdrawSpecificAmount(user_id[i], 50); + } + + /* Assert */ + + for (int i = 0; i < 3; i++) { + TEST_ASSERT_FALSE(result[i]); // Pass if withdrawal fails and function returns false + } + +} + + + + +#endif // TEST