develop #1

Open
Z.Gharagozloo.M wants to merge 4 commits from develop into main
4 changed files with 163 additions and 69 deletions
+12 -10
View File
@@ -2,6 +2,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Scanner; import java.util.Scanner;
public class Main { public class Main {
@@ -15,19 +16,20 @@ public class Main {
} }
Scanner scanner = new Scanner(input); Scanner scanner = new Scanner(input);
// TODO: while (scanner.hasNextLine()) {
// - Read each line from products.csv String line = scanner.nextLine();
// - For each line, parse productId, name, and price String[] columns = line.split(",");
// - The format of the file is like this:
// [productId],[name],[price]
// - Store Product objects in the productCatalog ArrayList
// NOTE int productId = Integer.parseInt(columns[0]);
// - The data in products.csv is guaranteed to be valid. String name = columns[1];
double price = Double.parseDouble(columns[2]);
productCatalog.add(new Product(productId, name, price));
}
} }
public static void main(String[] args)
{ public static void main(String[] args) throws IOException {
try { try {
loadProducts(); loadProducts();
} catch (IOException e) { } catch (IOException e) {
+3
View File
@@ -9,6 +9,8 @@ public class Product {
this.price = price; this.price = price;
} }
public int getProductID() { public int getProductID() {
return productID; return productID;
} }
@@ -20,4 +22,5 @@ public class Product {
public double getPrice() { public double getPrice() {
return price; return price;
} }
} }
+148 -59
View File
@@ -1,4 +1,9 @@
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List; import java.util.List;
import java.util.Scanner;
public class ReportGenerator { public class ReportGenerator {
@@ -13,71 +18,155 @@ public class ReportGenerator {
public ReportGenerator(String ordersFilePath, List<Product> productList) { public ReportGenerator(String ordersFilePath, List<Product> productList) {
this.ordersFilePath = ordersFilePath; this.ordersFilePath = ordersFilePath;
this.productList = productList; this.productList = productList;
this.totalFinalCost = 0.0;
this.totalQuantity = 0;
this.totalDiscountValue = 0.0;
this.totalInvalidLines = 0;
} }
public void processFile() public void processFile() throws IOException {
{ Scanner scanner = null;
// TODO: InputStream input = null;
// 1. Open the order details CSV file
// 2. Read the file line by line try {
// 3. Split each line using comma delimiter input = Main.class
// (each line is guaranteed to contain exactly two commas) .getClassLoader()
// 4. Each line contains exactly 3 values in the format: .getResourceAsStream("2025_order_details.csv");
// [productId],[quantity],[discountPercent] if (input == null) {
// 5. Attempt to convert values: throw new IOException("2025_order_details.csv not found");
// - productId -> int }
// - quantity -> int scanner = new Scanner(input);
// - discountPercent -> int int lineNumber = 0;
// NOTE:
// - quantity and discountPercent may contain invalid characters while (scanner.hasNextLine()) {
// (e.g., letters instead of numbers). lineNumber++;
// - If parsing any value fails (NumberFormatException), String line = scanner.nextLine();
// the entire line must be considered invalid.
// - Use try-catch blocks and exception handling to safely String[] columns = line.split(",");
// handle parsing and validation errors without stopping
// the processing of the remaining lines. int productId = 0;
// 6. Validate parsed values: int quantity = 0;
// - productId must be greater than 0 int discountPercent = 0;
// - quantity must be greater than 0 boolean isValid = true;
// - discountPercent must be between 0 and 99 inclusive String errorReason = "";
// 7. Look for a Product in productList that matches productId
// 8. If no Product with that ID exists in the catalog, //Validation and parsing productId
// the entire line is considered invalid try {
// 9. If all values are valid and the product exists, calculate: productId = Integer.parseInt(columns[0]);
// subtotal = quantity * product price if (productId <= 0) {
// discountValue = subtotal * discountPercent / 100 isValid = false;
// finalCost = subtotal - discountValue errorReason = "productId must be > 0 (got " + productId + ")";
// 10. Update report totals: }
// - totalQuantity += quantity } catch (NumberFormatException e) {
// - totalFinalCost += finalCost isValid = false;
// - totalDiscountValue += discountValue errorReason = "productId is not a valid integer ('" + columns[0] + "')";
// 11. If any parsing error, validation failure, or missing product occurs: }
// - increment totalInvalidLines
// - skip the line and continue processing the next line //Validation and parsing quantity (if productId was valid)
// 12. Close all file resources if (isValid) {
try {
quantity = Integer.parseInt(columns[1]);
if (quantity <= 0) {
isValid = false;
errorReason = "quantity must be > 0 (got " + quantity + ")";
}
} catch (NumberFormatException e) {
isValid = false;
errorReason = "quantity is not a valid integer ('" + columns[1] + "')";
}
}
//Validation and parsing discountPercent (if productId and quantity were valid)
if (isValid) {
try {
discountPercent = Integer.parseInt(columns[2].trim());
if (discountPercent < 0 || discountPercent > 99) {
isValid = false;
errorReason = "discountPercent must be between 0-99 (got " + discountPercent + ")";
}
} catch (NumberFormatException e) {
isValid = false;
errorReason = "discountPercent is not a valid integer ('" + columns[2] + "')";
}
}
//Skipping the line if no Product with that ID exists in the catalog
Product product = null;
if (isValid) {
product = findProductById(productId);
if (product == null) {
isValid = false;
errorReason = "Product with ID " + productId + " not found in catalog";
}
}
if (!isValid) {
System.out.println("Line " + lineNumber + " SKIPPED: " + errorReason);
totalInvalidLines++;
continue;
}
double productPrice = product.getPrice();
double subtotal = quantity * productPrice;
double discountValue = subtotal * discountPercent / 100;
double finalCost = subtotal - discountValue;
totalQuantity += quantity;
totalDiscountValue += discountValue;
totalFinalCost += finalCost;
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
throw e;
} finally {
if (scanner != null) {
scanner.close();
}
if (input != null) {
try {
input.close();
} catch (IOException e) {
System.err.println("Error closing input stream: " + e.getMessage());
}
}
}
}
private Product findProductById(int productId) {
for (Product product : productList) {
if (product.getProductID() == productId) {
return product;
}
}
return null;
} }
public void saveReport() public void saveReport()
{ {
// TODO: PrintWriter writer = null;
// 1. Build a formatted report string
// 2. Include:
// - total quantity
// - total final cost
// - total discount value
// - total invalid lines
// 3. Create/open output report file (name it report.txt)
// 4. Write report string into file
// 5. Handle file writing exceptions
// 6. Close writer resources
/* Example Structure try {
========= SALES REPORT ========= StringBuilder report = new StringBuilder();
Total Quantity Sold: 42 report.append("========= SALES REPORT =========\n");
Total Final Cost: $1520.75 report.append(String.format("Total Quantity Sold: %d\n", totalQuantity));
Total Discount Value: $230.50 report.append(String.format("Total Final Cost: $%.2f\n", totalFinalCost));
Invalid Rows: 3 report.append(String.format("Total Discount Value: $%.2f\n", totalDiscountValue));
================================ report.append(String.format("Invalid Rows: %d\n", totalInvalidLines));
*/ report.append("================================\n");
String outputFileName = "report.txt";
writer = new PrintWriter(new FileWriter(outputFileName));
writer.print(report.toString());
System.out.println("Report saved successfully to: " + outputFileName);
System.out.println("\n" + report.toString());
} catch (IOException e) {
System.err.println("Error writing report to file: " + e.getMessage());
e.printStackTrace();
} finally {
if (writer != null) {
writer.close();
}
}
} }
} }