From 8ea13832533501cfbdfeef40e7094eff691dadfa Mon Sep 17 00:00:00 2001 From: opdhk Date: Mon, 23 Sep 2024 23:38:46 +0300 Subject: [PATCH 1/4] implemented method getSalaryInfo(...) according to requirements of README.MD --- src/main/java/core/basesyntax/SalaryInfo.java | 91 ++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/src/main/java/core/basesyntax/SalaryInfo.java b/src/main/java/core/basesyntax/SalaryInfo.java index 4a34339b5..77d6eb820 100644 --- a/src/main/java/core/basesyntax/SalaryInfo.java +++ b/src/main/java/core/basesyntax/SalaryInfo.java @@ -1,7 +1,96 @@ package core.basesyntax; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + public class SalaryInfo { + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + private static final int DATE_INDEX = 0; + private static final int HOURS_INDEX = 2; + private static final int INCOME_INDEX = 3; + private static final int NAME_INDEX = 1; + private static final String DATA_DELIMITER = " "; + private static final String INDEX_NAME_DELIMITER = ":"; + private static final String INDEX_NAME_PAIRS_DELIMITER = "|"; + private static final String REPORT_DELIMITER = " - "; + private static final String REPORT_HEADER = "Report for period "; + public String getSalaryInfo(String[] names, String[] data, String dateFrom, String dateTo) { - return null; + String indexedNameString = buildIndexedNameString(names); + int[] salaries = new int[names.length]; + for (String dataRecord : data) { + String[] records = dataRecord.split(DATA_DELIMITER); + if (!indexedNameString.contains(records[NAME_INDEX])) { + continue; + } + LocalDate parsedRecordDate = parseStringToLocalDate(records[DATE_INDEX]); + if (parsedRecordDate.isBefore(parseStringToLocalDate(dateFrom))) { + continue; + } + if (parsedRecordDate.isAfter(parseStringToLocalDate(dateTo))) { + continue; + } + int salariesIndex = getSalariesIndexByName(indexedNameString, records[NAME_INDEX]); + try { + salaries[salariesIndex] += + Integer.parseInt(records[INCOME_INDEX]) * Integer.parseInt( + records[HOURS_INDEX]); + } catch (NumberFormatException e) { + throw new RuntimeException( + "Wrong format of working hours or income per hour in " + "records line."); + } + } + return composeReport(names, dateFrom, dateTo, salaries); + } + + private static int getSalariesIndexByName(String indexedNameString, String employeeName) { + int startIndex = indexedNameString.lastIndexOf(INDEX_NAME_PAIRS_DELIMITER, + indexedNameString.indexOf(employeeName)); + int endIndex = indexedNameString.indexOf(INDEX_NAME_DELIMITER, startIndex); + String indexSalaries = indexedNameString.substring(startIndex + 1, endIndex); + try { + return Integer.parseInt(indexSalaries); + } catch (NumberFormatException e) { + throw new RuntimeException("Wrong index format in indexed string of employee names."); + } + } + + private static String composeReport(String[] names, String dateFrom, String dateTo, + int[] salaries) { + StringBuilder reportBuilder = new StringBuilder(REPORT_HEADER).append(dateFrom) + .append(REPORT_DELIMITER) + .append(dateTo) + .append(System.lineSeparator()); + for (int i = 0; i < names.length; i++) { + reportBuilder.append(names[i]).append(" - ").append(salaries[i]); + if (i < names.length - 1) { + reportBuilder.append(System.lineSeparator()); + } + } + return String.valueOf(reportBuilder); + } + + private static String buildIndexedNameString(String[] names) { + StringBuilder indexedNameBuilder = new StringBuilder(); + int index = 0; + for (String name : names) { + indexedNameBuilder.append(index) + .append(INDEX_NAME_DELIMITER) + .append(name) + .append(INDEX_NAME_PAIRS_DELIMITER); + index++; + } + return String.valueOf(indexedNameBuilder); + } + + private static LocalDate parseStringToLocalDate(String date) { + LocalDate dateParsed; + try { + dateParsed = LocalDate.parse(date, FORMATTER); + } catch (DateTimeParseException e) { + throw new RuntimeException("Wrong date format."); + } + return dateParsed; } } From 56e726748f72b75058d20a2c313fd7d33b229abb Mon Sep 17 00:00:00 2001 From: opdhk Date: Tue, 24 Sep 2024 15:18:55 +0300 Subject: [PATCH 2/4] fixed issues: * parsing dateFrom and dateTo transferred outside the loop; * hardcoded delimiter ' - ' changed to constant; * employee name with delimiters used to prevent situation for incorrect index search if employee name is a substring for another employee name * recommendation to change stringBuilder.toString() instead of String.valueOf(stringBuilder) ignored --- src/main/java/core/basesyntax/SalaryInfo.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/core/basesyntax/SalaryInfo.java b/src/main/java/core/basesyntax/SalaryInfo.java index 77d6eb820..825b2cd39 100644 --- a/src/main/java/core/basesyntax/SalaryInfo.java +++ b/src/main/java/core/basesyntax/SalaryInfo.java @@ -19,16 +19,18 @@ public class SalaryInfo { public String getSalaryInfo(String[] names, String[] data, String dateFrom, String dateTo) { String indexedNameString = buildIndexedNameString(names); int[] salaries = new int[names.length]; + LocalDate dateFromParsed = parseStringToLocalDate(dateFrom); + LocalDate dateToParsed = parseStringToLocalDate(dateTo); for (String dataRecord : data) { String[] records = dataRecord.split(DATA_DELIMITER); if (!indexedNameString.contains(records[NAME_INDEX])) { continue; } LocalDate parsedRecordDate = parseStringToLocalDate(records[DATE_INDEX]); - if (parsedRecordDate.isBefore(parseStringToLocalDate(dateFrom))) { + if (parsedRecordDate.isBefore(dateFromParsed)) { continue; } - if (parsedRecordDate.isAfter(parseStringToLocalDate(dateTo))) { + if (parsedRecordDate.isAfter(dateToParsed)) { continue; } int salariesIndex = getSalariesIndexByName(indexedNameString, records[NAME_INDEX]); @@ -45,8 +47,10 @@ public String getSalaryInfo(String[] names, String[] data, String dateFrom, Stri } private static int getSalariesIndexByName(String indexedNameString, String employeeName) { + String employeeNameFormatted = + INDEX_NAME_DELIMITER + employeeName + INDEX_NAME_PAIRS_DELIMITER; int startIndex = indexedNameString.lastIndexOf(INDEX_NAME_PAIRS_DELIMITER, - indexedNameString.indexOf(employeeName)); + indexedNameString.indexOf(employeeNameFormatted)); int endIndex = indexedNameString.indexOf(INDEX_NAME_DELIMITER, startIndex); String indexSalaries = indexedNameString.substring(startIndex + 1, endIndex); try { @@ -63,7 +67,7 @@ private static String composeReport(String[] names, String dateFrom, String date .append(dateTo) .append(System.lineSeparator()); for (int i = 0; i < names.length; i++) { - reportBuilder.append(names[i]).append(" - ").append(salaries[i]); + reportBuilder.append(names[i]).append(REPORT_DELIMITER).append(salaries[i]); if (i < names.length - 1) { reportBuilder.append(System.lineSeparator()); } From 6e8dfe42ca5c3c1878cac9d99dd608163bbe819c Mon Sep 17 00:00:00 2001 From: opdhk Date: Wed, 25 Sep 2024 21:59:16 +0300 Subject: [PATCH 3/4] changed according to the reviewer's fixes --- src/main/java/core/basesyntax/SalaryInfo.java | 98 ++++--------------- 1 file changed, 21 insertions(+), 77 deletions(-) diff --git a/src/main/java/core/basesyntax/SalaryInfo.java b/src/main/java/core/basesyntax/SalaryInfo.java index 825b2cd39..3d5c704c7 100644 --- a/src/main/java/core/basesyntax/SalaryInfo.java +++ b/src/main/java/core/basesyntax/SalaryInfo.java @@ -2,7 +2,6 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; public class SalaryInfo { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy"); @@ -11,90 +10,35 @@ public class SalaryInfo { private static final int INCOME_INDEX = 3; private static final int NAME_INDEX = 1; private static final String DATA_DELIMITER = " "; - private static final String INDEX_NAME_DELIMITER = ":"; - private static final String INDEX_NAME_PAIRS_DELIMITER = "|"; private static final String REPORT_DELIMITER = " - "; private static final String REPORT_HEADER = "Report for period "; public String getSalaryInfo(String[] names, String[] data, String dateFrom, String dateTo) { - String indexedNameString = buildIndexedNameString(names); + final LocalDate fromDate = LocalDate.parse(dateFrom, FORMATTER); + final LocalDate toDate = LocalDate.parse(dateTo, FORMATTER); + StringBuilder report = new StringBuilder(REPORT_HEADER).append(dateFrom) + .append(REPORT_DELIMITER) + .append(dateTo); int[] salaries = new int[names.length]; - LocalDate dateFromParsed = parseStringToLocalDate(dateFrom); - LocalDate dateToParsed = parseStringToLocalDate(dateTo); - for (String dataRecord : data) { - String[] records = dataRecord.split(DATA_DELIMITER); - if (!indexedNameString.contains(records[NAME_INDEX])) { - continue; - } - LocalDate parsedRecordDate = parseStringToLocalDate(records[DATE_INDEX]); - if (parsedRecordDate.isBefore(dateFromParsed)) { - continue; - } - if (parsedRecordDate.isAfter(dateToParsed)) { - continue; - } - int salariesIndex = getSalariesIndexByName(indexedNameString, records[NAME_INDEX]); - try { - salaries[salariesIndex] += - Integer.parseInt(records[INCOME_INDEX]) * Integer.parseInt( - records[HOURS_INDEX]); - } catch (NumberFormatException e) { - throw new RuntimeException( - "Wrong format of working hours or income per hour in " + "records line."); + for (String info : data) { + String[] parts = info.split(DATA_DELIMITER); + LocalDate recordDay = LocalDate.parse(parts[DATE_INDEX], FORMATTER); + if ((recordDay.isAfter(fromDate) || recordDay.isEqual(fromDate)) && ( + recordDay.isBefore(toDate) || recordDay.isEqual(toDate))) { + for (int i = 0; i < names.length; i++) { + if (names[i].equals(parts[NAME_INDEX])) { + salaries[i] += Integer.parseInt(parts[HOURS_INDEX]) * Integer.parseInt( + parts[INCOME_INDEX]); + } + } } } - return composeReport(names, dateFrom, dateTo, salaries); - } - - private static int getSalariesIndexByName(String indexedNameString, String employeeName) { - String employeeNameFormatted = - INDEX_NAME_DELIMITER + employeeName + INDEX_NAME_PAIRS_DELIMITER; - int startIndex = indexedNameString.lastIndexOf(INDEX_NAME_PAIRS_DELIMITER, - indexedNameString.indexOf(employeeNameFormatted)); - int endIndex = indexedNameString.indexOf(INDEX_NAME_DELIMITER, startIndex); - String indexSalaries = indexedNameString.substring(startIndex + 1, endIndex); - try { - return Integer.parseInt(indexSalaries); - } catch (NumberFormatException e) { - throw new RuntimeException("Wrong index format in indexed string of employee names."); - } - } - - private static String composeReport(String[] names, String dateFrom, String dateTo, - int[] salaries) { - StringBuilder reportBuilder = new StringBuilder(REPORT_HEADER).append(dateFrom) - .append(REPORT_DELIMITER) - .append(dateTo) - .append(System.lineSeparator()); for (int i = 0; i < names.length; i++) { - reportBuilder.append(names[i]).append(REPORT_DELIMITER).append(salaries[i]); - if (i < names.length - 1) { - reportBuilder.append(System.lineSeparator()); - } - } - return String.valueOf(reportBuilder); - } - - private static String buildIndexedNameString(String[] names) { - StringBuilder indexedNameBuilder = new StringBuilder(); - int index = 0; - for (String name : names) { - indexedNameBuilder.append(index) - .append(INDEX_NAME_DELIMITER) - .append(name) - .append(INDEX_NAME_PAIRS_DELIMITER); - index++; - } - return String.valueOf(indexedNameBuilder); - } - - private static LocalDate parseStringToLocalDate(String date) { - LocalDate dateParsed; - try { - dateParsed = LocalDate.parse(date, FORMATTER); - } catch (DateTimeParseException e) { - throw new RuntimeException("Wrong date format."); + report.append(System.lineSeparator()) + .append((names[i])) + .append(REPORT_DELIMITER) + .append(salaries[i]); } - return dateParsed; + return report.toString(); } } From 9e53943be45b15d31efb980d72d522e8eeda4f65 Mon Sep 17 00:00:00 2001 From: opdhk Date: Thu, 26 Sep 2024 22:18:52 +0300 Subject: [PATCH 4/4] 2nd iteration of changes according to the reviewer's fixes --- src/main/java/core/basesyntax/SalaryInfo.java | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main/java/core/basesyntax/SalaryInfo.java b/src/main/java/core/basesyntax/SalaryInfo.java index 3d5c704c7..c39dda75e 100644 --- a/src/main/java/core/basesyntax/SalaryInfo.java +++ b/src/main/java/core/basesyntax/SalaryInfo.java @@ -16,23 +16,37 @@ public class SalaryInfo { public String getSalaryInfo(String[] names, String[] data, String dateFrom, String dateTo) { final LocalDate fromDate = LocalDate.parse(dateFrom, FORMATTER); final LocalDate toDate = LocalDate.parse(dateTo, FORMATTER); - StringBuilder report = new StringBuilder(REPORT_HEADER).append(dateFrom) - .append(REPORT_DELIMITER) - .append(dateTo); int[] salaries = new int[names.length]; for (String info : data) { String[] parts = info.split(DATA_DELIMITER); LocalDate recordDay = LocalDate.parse(parts[DATE_INDEX], FORMATTER); - if ((recordDay.isAfter(fromDate) || recordDay.isEqual(fromDate)) && ( - recordDay.isBefore(toDate) || recordDay.isEqual(toDate))) { - for (int i = 0; i < names.length; i++) { - if (names[i].equals(parts[NAME_INDEX])) { - salaries[i] += Integer.parseInt(parts[HOURS_INDEX]) * Integer.parseInt( - parts[INCOME_INDEX]); - } - } + if (isWithinDateRange(recordDay, fromDate, toDate)) { + calculateSalaries(names, parts, salaries); } } + return composeReport(names, dateFrom, dateTo, salaries); + } + + private static boolean isWithinDateRange(LocalDate currentDate, LocalDate fromDate, + LocalDate toDate) { + return (currentDate.isAfter(fromDate) || currentDate.isEqual(fromDate)) && ( + currentDate.isBefore(toDate) || currentDate.isEqual(toDate)); + } + + private static void calculateSalaries(String[] names, String[] parts, int[] salaries) { + for (int i = 0; i < names.length; i++) { + if (names[i].equals(parts[NAME_INDEX])) { + salaries[i] += Integer.parseInt(parts[HOURS_INDEX]) * Integer.parseInt( + parts[INCOME_INDEX]); + } + } + } + + private static String composeReport(String[] names, String dateFrom, String dateTo, + int[] salaries) { + StringBuilder report = new StringBuilder(REPORT_HEADER).append(dateFrom) + .append(REPORT_DELIMITER) + .append(dateTo); for (int i = 0; i < names.length; i++) { report.append(System.lineSeparator()) .append((names[i]))