Create a TaxReturn class with fields that hold a taxpayer\'s SocialSecurity numb
ID: 3677500 • Letter: C
Question
Create a TaxReturn class with fields that hold a taxpayer's SocialSecurity number, last name, first name, street address, city, state, zip code, annual income, marital status,and tax liabilty. Include a constructor that requires arguments that provide values for all the fields other than the tax liability. The constructor calculates the tax liability based on annual income and the percentages in the following table. below are the values for the marital status single income; 0-20,000 15% married 14% 20,single 20,001-50,000 22% married 20% single 50,001 and over 30% married 28%
Explanation / Answer
Menu.java
import Part1.*;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Menu {
public final static int INPUT_TYPE_STRING = 0;
public final static int INPUT_TYPE_INT = 1;
private int menuType; // Type of Menu [ 0 - CONSOLE , 1 - GUI ]
private String menuHeading; // Menu Heading or Title
private int numberOfOptions; // The number of options in the menu
private String[] menuOptions; // The array that holds the options in String format
private String[] menuReturnValues; // The array that holds the return values of the options
private String returnType; // Determines whether return values are int based [ false ] or String based [ true ]
Scanner input;
private int inputType;
private String menuOption;
private String simpleMenuChoice;
public Menu( int menuType, int inputType, String menuOption ) {
this.menuType = menuType;
this.inputType = inputType;
this.menuOption = menuOption;
}
public String runSimpleMenu() {
if( menuType == 0 ) {
input = new Scanner(System.in);
System.out.print(menuOption);
if( inputType == INPUT_TYPE_STRING ) {
simpleMenuChoice = input.next();
return simpleMenuChoice;
} else if ( inputType == INPUT_TYPE_INT ) {
simpleMenuChoice = "" + input.nextInt();
return simpleMenuChoice;
} else {
System.out.println("MENU CLASS / Constructor Simple CONSOLE : ERROR");
return "" + 0;
}
} else if( menuType == 1 ) {
simpleMenuChoice = JOptionPane.showInputDialog(menuOption);
return simpleMenuChoice;
} else {
System.out.println("MENU CLASS / Constructor Simple : ERROR");
return "" + 0;
}
}
/**
*
* Creates a " NUMBERED " menu object taking into account the following:
*
* menuType - 0 = Console Based, 1 = GUI Based
* menuHeading - Single String
* menuOptions - Array of Strings
* returnType = "string" means return values are STRING based. "int" means return values are INTEGER based
*/
public Menu(int menuType, String menuHeading, String[] menuOptions, String returnType) {
this.menuType = menuType; // Set the menu type to be console or GUI
this.menuHeading = menuHeading; // Set the Menu Heading
numberOfOptions = menuOptions.length; // Set the number of menu options
setMenuOptions(menuOptions); // Set the options into the menu
menuReturnValues = new String[numberOfOptions];
this.returnType = returnType;
if( returnType.equals("string") )
setMenuReturnValues(menuOptions);
else if( returnType.equals("int") )
setMenuReturnValuesInt(menuOptions);
else
System.out.println("MENU CLASS / Constructor [ Simple Menu ] : ERROR");
}
/**
*
* Puts together a menu based on the attribute values and returns a string for
* the menu output to use.
*/
public String createSimpleMenu() {
String menuText = menuOption + System.lineSeparator();
return "";
}
public String createMenu() {
String menuText = "" + menuHeading + System.lineSeparator();
for(int i = 0; i < numberOfOptions; i++) {
menuText += "(" + (i+1) + ") - " + menuOptions[i] + System.lineSeparator();
}
return menuText;
}
/**
*
* Generates a GUI Menu based on the attribute values provided in the object
* created
*/
public String runMenu() {
// If the menuType is CONSOLE based
if( menuType == 0 ) {
input = new Scanner(System.in);
System.out.print(createMenu() + System.lineSeparator() + "Your choice?: ");
int choice = input.nextInt();
return menuReturnValues[(choice-1)];
// If the menuType is GUI based
} else if( menuType == 1 ) {
int choice = Integer.parseInt(JOptionPane.showInputDialog(createMenu()));
return menuReturnValues[(choice-1)];
// If there is another value entered in error
} else {
System.out.println("No menu generated. There was an invalid option");
return "" + 0;
}
}
public String getMenuHeading() {
return menuHeading;
}
public void setMenuHeading(String menuHeading) {
this.menuHeading = menuHeading;
}
public int getNumberOfOptions() {
return numberOfOptions;
}
public void setNumberOfOptions(int numberOfOptions) {
this.numberOfOptions = numberOfOptions;
}
public String[] getMenuOptions() {
return menuOptions;
}
public void setMenuOptions(String[] menuOptions) {
this.menuOptions = menuOptions;
}
public String[] getMenuReturnValues() {
return menuReturnValues;
}
public void setMenuReturnValues(String[] menuReturnValues) {
this.menuReturnValues = menuReturnValues;
}
public void setMenuReturnValuesInt(String[] menuReturnValues) {
for( int i = 0; i < menuReturnValues.length; i++ ) {
this.menuReturnValues[i] = "" + (i + 1);
}
}
}
PrepareTax.java
import java.util.StringTokenizer;
import javax.swing.JOptionPane;
/**
*
* PrepareTax class tests the TaxReturn class. Also holds all menu functionality
* allowing for user input.
*/
public class PrepareTax {
public final static int VALID_SIN_CHECK = 11; // Number of items to check in the value
public final static int VALID_ZIPCODE_CHECK = 6; // Number of items to check in the value
public static String[] menuOptions = { "Sin", "Annual Income", "Last Name", "First Name", "Street Address", "City", "State", "Zip Code", "Marital Status"};
public static Menu mainMenu;
private static StringBuilder taxData = new StringBuilder("#Sin,#Annual Income,#Last Name,#First Name,#Street Address,#City,#State,#Zip Code,#Marital Status");
public static void main(String[] args) {
mainMenu = new Menu(1,"TAX RETURN MENU:",menuOptions,"string");
String menuChoice;
do {
// From the main menu, the option is returned as a string to menuChoice
menuChoice = mainMenu.runMenu();
getTaxReturnData(menuChoice);
} while( !isAllDataEntered() );
// Create a tokenizer to break up the data from the String
StringTokenizer taxDataToken = new StringTokenizer(taxData.toString(), ",");
// Create the TaxReturn Object after all validation is complete
TaxReturn aNewReturn = new TaxReturn(taxDataToken.nextToken(),Double.parseDouble(taxDataToken.nextToken()),
taxDataToken.nextToken(),taxDataToken.nextToken(),taxDataToken.nextToken(),taxDataToken.nextToken(),
taxDataToken.nextToken(),taxDataToken.nextToken(),taxDataToken.nextToken());
// Display the TaxReturn object
JOptionPane.showMessageDialog(null, aNewReturn);
}
/**
*
* Takes the choice entered by the user from the menu. Uses it to validate input and enter
* data into a StringBuilder object.
* Once data is entered into the StringBuilder object, the method will update the Menu display and
* show *COMPLETED*. Will also prevent further updates once the value is entered.
*/
public static void getTaxReturnData(String choice) {
String temp, valueChoice;
// If there is a slot to enter the data AND the data is valid ( checking for Marital Status, Zip Code...etc
if( taxData.toString().contains("#"+choice) ){
// Get the value for the choice from user
valueChoice = JOptionPane.showInputDialog("Enter value for (" + choice + "): ");
// If the data entered is valid...
if( isDataValid(choice, valueChoice) ) {
// Replace the value from the user with the right spot in the string
temp = taxData.toString().replace("#"+choice, valueChoice);
// Delete the string
taxData.delete(0, taxData.length());
// Recreate it with the change
taxData.append(temp);
// Change the menu to display completed for each section
for( int i = 0; i < menuOptions.length; ++i ) {
if( menuOptions[i].equals(choice) )
menuOptions[i] = menuOptions[i].replace(choice, "*COMPLETED* " + choice);
}
} // END: if( isDataValid(valueChoice) ) { .....
} else {
JOptionPane.showMessageDialog(null, "You have already entered for that option. Please choose again");
}
//System.out.println(taxData);
} // END: getTaxReturnData
/**
*
* Verifies the validity on the string argument 'valueChoice' by different methods
* for four of the attributes required ( SIN, ANNUAL INCOME, ZIP CODE & MARITAL STATUS )
* Based on 'menuChoice' valueChoice is checked to ensure these attributes meet the criteria
* required.
*/
public static boolean isDataValid(String menuChoice, String valueChoice) {
boolean valid;
// ****************** SIN ************************
if( menuChoice.equalsIgnoreCase("sin")) {
// The Social Security number is not in the correct format, with digits and dashes
// in the appropriate positions; for example, 999-99-9999.
int validCheck = 0;
for( int i = 0; i < valueChoice.length(); ++i ){
// Check all digits that are not the dash position
if( i != 3 && i != 6 ){
if( Character.isDigit(valueChoice.charAt(i)) ){
//System.out.println("Digit checked. It's good");
++validCheck;
}else{
//System.out.println("digit not good");
--validCheck;
}
}else{
// Check the dash positions
if( valueChoice.charAt(i) == '-'){
//System.out.println("There is a dash in the right spot");
++validCheck;
}else{
//System.out.println("dash not good");
--validCheck;
}
} // END: if( i != 3 && i != 6 ){ .....
} // END: for( int i = 0; i < valueChoice.length(); ++i ){ .....
if( validCheck == VALID_SIN_CHECK )
valid = true;
else {
JOptionPane.showMessageDialog(null, menuChoice + " is not valid. Please re-enter");
valid = false;
}
// ****************** MARITAL STATUS ************************
} else if( menuChoice.equalsIgnoreCase("marital status")) {
// The marital status does not begin with one of the following: “S”, “s”, “M”, or “m”.
//System.out.println("statuschoice " + valueChoice.charAt(0));
valueChoice = valueChoice.toLowerCase();
if( valueChoice.charAt(0) != 'm' && valueChoice.charAt(0) != 's' ){
//System.out.println("marital status is false");
valid = false;
} else {
//System.out.println("marital status is true.");
valid = true;
}
// ****************** ANNUAL INCOME ************************
} else if( menuChoice.equalsIgnoreCase("annual Income")) {
// The annual income is negative.
if( Integer.parseInt(valueChoice) < 0 ){
JOptionPane.showMessageDialog(null, menuChoice + " is not valid. Please re-enter");
valid = false;
} else {
valid = true;
}
// ****************** ZIP CODE ************************
} else if( menuChoice.equalsIgnoreCase("zip code") ){
int validCheck = 0;
// The zip code is not five digits.
// If the user entry is equal to 5 characters...
if( valueChoice.length() == 5){
//System.out.println("zip code passed 5 character check");
// Loop through the choice to check and ensure each one is a digit
for( int i = 0; i < valueChoice.length(); ++i ){
if( Character.isDigit(valueChoice.charAt(i)) ){
++validCheck;
} else
--validCheck;
}
// Is false if it didn't pass the digit loop check
++validCheck;
} else {
// False if it didn't pass the 5 character check
--validCheck;
}
// If the counter equals all of the checked items...
if( validCheck == VALID_ZIPCODE_CHECK )
valid = true;
else {
JOptionPane.showMessageDialog(null, menuChoice + " is not valid. Please re-enter");
valid = false;
}
// ****************** ANYTHING ELSE GOES THROUGH ************************
} else {
// Anything other than the above can go through and be entered as tax data
valid = true;
}
return valid;
}
/**
*
* Will verify all positions in the StringBuilder object 'taxData'. If all sections
* are found to be verified and entered it will return a boolean flag to terminate the
* loop that repeats the main menu and allow the TaxReturn object to be created.
*/
public static boolean isAllDataEntered() {
boolean valid;
if( taxData.toString().contains("#") ){
//System.out.println("data not valid. keep loop going");
valid = false;
}else{
//System.out.println("data valid. stop loop");
valid = true;
}
return valid;
}
}
TaxReturn.java
import java.text.DecimalFormat;
/**
*
* TaxReturn class represents an object of a TaxReturn
* @author Christopher Sigouin
*/
public class TaxReturn {
public final static String MARITAL_STATUS_SINGLE = "single";
public final static String MARITAL_STATUS_MARRIED = "married";
public final static int INCOME_TAX_BRACKET_20K = 20000;
public final static int INCOME_TAX_BRACKET_50K = 50000;
public final static double PERCENTAGE_SINGLE_0_TO_20k = .15; // 15%
public final static double PERCENTAGE_SINGLE_20k_TO_50k = .22; // 22%
public final static double PERCENTAGE_SINGLE_50k_PLUS = .30; // 30%
public final static double PERCENTAGE_MARRIED_0_TO_20k = .14; // 14%
public final static double PERCENTAGE_MARRIED_20k_TO_50k = .20; // 20%
public final static double PERCENTAGE_MARRIED_50k_PLUS = .28; // 28%
private double annualIncome, taxLiability;
String sin, lastName, firstName, streetAddress, city, state, zipCode, maritalStatus;
DecimalFormat twoDecimalPlaces = new DecimalFormat("#.00");
/**
*
* Constructor for the TaxReturn class. Takes all attributes as arguments except for
* taxLiability
*/
public TaxReturn(String sin, double annualIncome, String lastName, String firstName, String streetAddress,
String city, String state, String zipCode, String maritalStatus ) {
// Constructor that requires arguments that provide values for all the fields other than the tax liability
this.sin = sin;
this.annualIncome = annualIncome;
this.lastName = lastName;
this.firstName = firstName;
this.streetAddress = streetAddress;
this.city = city;
this.state = state;
this.zipCode = zipCode;
this.maritalStatus = maritalStatus;
// Constructor calculates the tax liability based on annual income and the percentages
calculateTaxLiability();
}
/**
*
* toString method display a TaxReturn object
*/
@Override
public String toString() {
return "YOUR TAX RETURN: " + System.lineSeparator() + System.lineSeparator() +
"SIN: " + sin + System.lineSeparator() +
"ANNUAL INCOME: $" + twoDecimalPlaces.format(annualIncome) + System.lineSeparator() +
"TAX LIABILITY: " + taxLiability + System.lineSeparator() +
"LAST NAME: " + lastName + System.lineSeparator() +
"FIRST NAME: " + firstName + System.lineSeparator() +
"STREET ADDRESS: " + streetAddress + System.lineSeparator() +
"CITY: " + city + System.lineSeparator() +
"STATE: " + state + System.lineSeparator() +
"ZIP CODE: " + zipCode + System.lineSeparator() +
"MARITAL STATUS: " + maritalStatus + System.lineSeparator() +
"TAX LIABILITY: $" + twoDecimalPlaces.format(taxLiability);
}
/**
*
* Calculates the tax liability based on annual income and the percentages
*/
private void calculateTaxLiability() {
if( annualIncome <= INCOME_TAX_BRACKET_20K ){
if( maritalStatus.equalsIgnoreCase(MARITAL_STATUS_SINGLE))
taxLiability = annualIncome * PERCENTAGE_SINGLE_0_TO_20k;
if( maritalStatus.equalsIgnoreCase(MARITAL_STATUS_MARRIED))
taxLiability = annualIncome * PERCENTAGE_MARRIED_0_TO_20k;
} else if ( annualIncome > INCOME_TAX_BRACKET_20K && annualIncome <= INCOME_TAX_BRACKET_50K ){
if( maritalStatus.equalsIgnoreCase(MARITAL_STATUS_SINGLE))
taxLiability = annualIncome * PERCENTAGE_SINGLE_20k_TO_50k;
if( maritalStatus.equalsIgnoreCase(MARITAL_STATUS_MARRIED))
taxLiability = annualIncome * PERCENTAGE_MARRIED_20k_TO_50k;
} else {
if( maritalStatus.equalsIgnoreCase(MARITAL_STATUS_SINGLE))
taxLiability = annualIncome * PERCENTAGE_SINGLE_50k_PLUS;
if( maritalStatus.equalsIgnoreCase(MARITAL_STATUS_MARRIED))
taxLiability = annualIncome * PERCENTAGE_MARRIED_50k_PLUS;
}
} // END: calculateTaxLiability()
}// END: TaxReturn class