commit 6ed93c1f9a7e818529aa1b33291fa23e9acc542c Author: Alaa_Rifai123 Date: Thu Apr 16 14:55:45 2026 +0300 first comment diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..a0ccf77 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Environment-dependent path to Maven home directory +/mavenHomeManager.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0548357 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..7634a48 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/manager_notes.txt b/manager_notes.txt new file mode 100644 index 0000000..06a78fb --- /dev/null +++ b/manager_notes.txt @@ -0,0 +1,6 @@ +2025-12-23: +الجمهوؤية العربية + +2025-12-25: +الخط الاول زابط + diff --git a/photo_2026-01-25_11-44-58.jpg b/photo_2026-01-25_11-44-58.jpg new file mode 100644 index 0000000..8097a2c Binary files /dev/null and b/photo_2026-01-25_11-44-58.jpg differ diff --git a/production_lines.txt b/production_lines.txt new file mode 100644 index 0000000..193eb56 --- /dev/null +++ b/production_lines.txt @@ -0,0 +1 @@ +2025-12-23 - f diff --git a/products.csv b/products.csv new file mode 100644 index 0000000..89f6275 --- /dev/null +++ b/products.csv @@ -0,0 +1,3 @@ +id,name,materials +1,هاتف ذكي,101:2;102:1;103:1 +2,حاسوب محمول,102:1;101:3 diff --git a/src/CEO.java b/src/CEO.java new file mode 100644 index 0000000..8aa765b --- /dev/null +++ b/src/CEO.java @@ -0,0 +1,83 @@ +import java.util.ArrayList; + +public class CEO { + ProductLine k; + ProductLine u; + Invantory ss = Invantory.getInstance(); + + public CEO(ProductLine k) { + this.k = k; + } + + public CEO() { + + } + + public void addProductLine(String name) { + + ProductLine pl = new ProductLine(name); + Thread j=new Thread(pl); + j.start(); + + + CSV.writeProductLine(pl); + for (ProductLine h : ss.productesLine) { + System.out.println(h.getLineName()); + + } + } + + +public void edit(String lineName, String newStatus) throws NOTFOUND { + Invantory inv = Invantory.getInstance(); + ArrayList allLines = inv.getProductLines(); + + boolean found = false; + + for (ProductLine pl : allLines) { + if (pl.getLineName().equalsIgnoreCase(lineName)) { + pl.setEnum(newStatus); + found = true; + break; + } + } + + if (!found) { + throw new NOTFOUND("Production line not found: " + lineName); + } + + CSV.writeProductLine2(allLines); + + System.out.println("Status updated to " + newStatus + " and saved to CSV."); +} + + + + + + + + + + + + + + + + public String display() { + + StringBuilder report = new StringBuilder(); + + for (ProductLine j : ss.productesLine) { + + String line = + j.getLineName() + " " + "100%"; + + System.out.println(line); // ✅ خلي الطباعة مثل ما هي + report.append(line).append("\n"); // ✅ جمع النص + } + + return report.toString(); // ✅ رجّع النتيجة + } +} \ No newline at end of file diff --git a/src/CSV.java b/src/CSV.java new file mode 100644 index 0000000..5d5acfa --- /dev/null +++ b/src/CSV.java @@ -0,0 +1,380 @@ +import java.io.*; +import java.time.LocalDate; +import java.util.* ; +public class CSV { + File file1 = new File("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Item.csv"); + File file2 = new File("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Product.csv"); + public static void writeItem(Item item) { + try { + File file1 = new File("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Item.csv"); + BufferedWriter bw = new BufferedWriter(new FileWriter(file1, true)); + if (file1.length() == 0) { + bw.write("id,nameOfItem,category,quantity,price,theMinimumAllowed"); + bw.newLine(); + } + + bw.write(item.toString()); // ✅ + bw.newLine(); + bw.flush(); + bw.close(); + } catch (IOException e) { + String error = "An error occurred while reading the file"; + ErrorLogger.logError(error); + } + } + + public static void writeItem2(ArrayList items) { + try { + File file1 = new File("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Item.csv"); + BufferedWriter bw = new BufferedWriter(new FileWriter(file1)); + if (file1.length() == 0) { + bw.write("id,nameOfItem,category,quantity,price,theMinimumAllowed"); + bw.newLine(); + } for (Item item : items) { + bw.write(item.toString()); + bw.newLine(); + } + bw.flush(); + bw.close(); + } catch (IOException e) { + String error = "An error occurred while reading the file"; + ErrorLogger.logError(error); + } + } + + public static List readItem(String pathname) { + List items = new ArrayList<>(); + + try (BufferedReader br = new BufferedReader(new FileReader(pathname))) { + String line; + br.readLine(); + + while ((line = br.readLine()) != null) { + if (line.trim().isEmpty()) continue; + + String[] d = line.split(","); + + if (d.length != 6) continue; + + int id = Integer.parseInt(d[0].trim()); + String name = d[1].trim(); + String category = d[2].trim(); + int quantity = Integer.parseInt(d[3].trim()); + int price = Integer.parseInt(d[4].trim()); + int min = Integer.parseInt(d[5].trim()); + + Item item = new Item(id, name, price, quantity,min, category); + items.add(item); + } + + } catch (Exception e) { + ErrorLogger.logError("Error reading Item.csv"); + } + + return items; + } + + + + + + + + + + + + + + + + + + +public static void writeProduct(Product product) { + try { + File file2 = new File("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Product.csv"); + + boolean fileExists = file2.exists() && file2.length() > 0; + + BufferedWriter bw = new BufferedWriter(new FileWriter(file2, true)); + + if (!fileExists) { + bw.write("id,nameOfProduct,quantity,materials"); + bw.newLine(); + } + + StringBuilder sb = new StringBuilder(); + sb.append(product.getNumberOfProduct()).append(","); + sb.append(product.getNameOfProduct()).append(","); + sb.append(product.getQuantityOfProduct()).append(","); + + if (product.getP() != null && !product.getP().isEmpty()) { + for (Map.Entry entry : product.getP().entrySet()) { + sb.append(entry.getKey().getNameOfItem()) + .append(":") + .append(entry.getValue()) + .append(";"); + } + } + + bw.write(sb.toString()); + bw.newLine(); + bw.flush(); + bw.close(); + + } catch (IOException e) { + String error = "An error occurred while writing Product.csv"; + ErrorLogger.logError(error); + } +} + + + + + + + + + public static void writeProduct2(ArrayList products) { + File file2 = new File("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Product.csv"); + try { + BufferedWriter bw = new BufferedWriter(new FileWriter(file2)); + bw.write("id, nameOfProduct,HashMap p"); + bw.newLine(); + for (Product product : products) { + bw.write(product.toCSV()); + bw.newLine(); + } + bw.flush(); + bw.close(); + } catch (IOException e) { + String error = "An error occurred while reading the file"; + ErrorLogger.logError(error); + } + } + +public static List readProduct(String pathname) { + ArrayList products = new ArrayList<>(); + try (BufferedReader read = new BufferedReader(new FileReader(pathname))) { + read.readLine(); + Invantory inventory = Invantory.getInstance(); + + String line; + while ((line = read.readLine()) != null) { + if (line.trim().isEmpty()) continue; + + String[] d = line.split(","); + if (d.length < 4) continue; + + int id = Integer.parseInt(d[0].trim()); + String name = d[1].trim(); + int quantity = Integer.parseInt(d[2].trim()); + String materials = d[3].trim(); + + HashMap map = new HashMap<>(); + if (!materials.isEmpty()) { + String[] pairs = materials.split(";"); + for (String pair : pairs) { + if (pair.trim().isEmpty()) continue; + String[] itemParts = pair.split(":"); + if (itemParts.length < 2) continue; + Item item = inventory.searchByName(itemParts[0].trim()); + int qty = Integer.parseInt(itemParts[1].trim()); + if (item != null) map.put(item, qty); + } + } + + Product p = new Product(id, name, quantity, map); + products.add(p); + } + } catch (Exception e) { + ErrorLogger.logError("Error reading Product.csv"); + } + return products; +} + + + public static void writeProductLine(ProductLine productLine) { + try { + File file4 = new File("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\ProductLine.csv"); + BufferedWriter bw = new BufferedWriter(new FileWriter(file4, true)); + if (file4.length() == 0) { + bw.write("lineId,lineName,status"); + bw.newLine(); + } + + bw.write(productLine.toString()+ " "); + bw.newLine(); + bw.flush(); + bw.close(); + } catch (IOException e) { + String error = "An error occurred while reading the file"; + ErrorLogger.logError(error); + } + } + public static void writeProductLine2(ArrayListproductLines) { + File file4 = new File("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\ProductLine.csv"); + try(BufferedWriter bw = new BufferedWriter(new FileWriter(file4))) { + + ; + + bw.write("lineId,lineName,status"); + bw.newLine(); + for (ProductLine productLine:productLines){ + + bw.write(productLine.toString()+ " "); + bw.newLine(); + + } + + } catch (IOException e) { + String error = "An error occurred while reading the file"; + ErrorLogger.logError(error); + } + } + public static void writeLineNote(String lineName, String note) { + try { + File file = new File("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\LineNotes.csv"); + BufferedWriter bw = new BufferedWriter(new FileWriter(file, true)); + + if (file.length() == 0) { + bw.write("lineName,note,date"); + bw.newLine(); + } + + bw.write(lineName + "," + note.replace(",", " ") + "," + LocalDate.now()); + bw.newLine(); + bw.close(); + + } catch (IOException e) { + ErrorLogger.logError("Error writing notes file"); + } + } + + + public static List readProductLine(String pathname) { + List productLines = new ArrayList<>(); + try (BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\ProductLine.csv"))) { + String line = br.readLine(); + while ((line =br.readLine()) != null) { + if (line.trim().isEmpty() || line.startsWith("id")) { + continue; + } + String[] data = line.split(","); + try { + int id = Integer.parseInt(data[0].trim()); + String name = data[1].trim(); + String statusStr = data[2].trim(); + + ProductLine pl = new ProductLine(id, name); + pl.setEnum(statusStr); + + productLines.add(pl); + + + } catch (NumberFormatException e) { + String error = "Number format error in line"; + ErrorLogger.logError(error); + } + } + } catch (FileNotFoundException e) { + String error = "File not found"; + ErrorLogger.logError(error); + } catch (IOException e) { + String error = "An error occurred while reading the file"; + ErrorLogger.logError(error); + } + return productLines; + } + + + + + +public static void writeAllTasks(List tasks) { + String filePath = "C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Task.csv"; + File file = new File(filePath); + + try (FileWriter fw = new FileWriter(file, false); + BufferedWriter bw = new BufferedWriter(fw); + PrintWriter out = new PrintWriter(bw)) { + + out.println("number,NameOfProduct,LineName,Amount,Customer,StartDate,ExecutionDate,Status,FinishedAmount,PercentAge"); + + for (Task task : tasks) { + String productName = task.getPro() != null ? task.getPro().getNameOfProduct() : "Unknown"; + String lineName = task.getLineName() != null ? task.getLineName() : "NoLine"; + String startDate = task.getStartDate() != null ? task.getStartDate().toString() : ""; + String endDate = task.getExecutionDate() != null ? task.getExecutionDate().toString() : ""; + String status = task.getK() != null ? task.getK().toString() : "INPROGRESS"; + + out.println(String.join(",", + String.valueOf(task.getNumber()), + productName, + lineName, + String.valueOf(task.getAmount()), + task.getCustomer() != null ? task.getCustomer() : "", + startDate, + endDate, + status, + String.valueOf(task.getFinishedAmount()), + String.valueOf(task.getPercentAge()) + )); + } + + } catch (IOException e) { + ErrorLogger.logError("Error writing Task.csv"); + } +} + + +public static List readTask(String pathname) { + List tasks = new ArrayList<>(); + Invantory inv = Invantory.getInstance(); + + try (BufferedReader br = new BufferedReader(new FileReader(pathname))) { + String line = br.readLine(); + + while ((line = br.readLine()) != null) { + if (line.trim().isEmpty()) continue; + + String[] parts = line.split(","); + + if (parts.length < 8) continue; + + int id = Integer.parseInt(parts[0].trim()); + String productName = parts[1].trim(); + String lineName = parts[2].trim(); + int amount = Integer.parseInt(parts[3].trim()); + String customer = parts[4].trim(); + LocalDate startDate = !parts[5].trim().isEmpty() ? LocalDate.parse(parts[5].trim()) : LocalDate.now(); + LocalDate endDate = (parts.length > 6 && !parts[6].trim().isEmpty()) ? LocalDate.parse(parts[6].trim()) : null; + String status = parts[7].trim(); + + + int finished = (parts.length > 8) ? Integer.parseInt(parts[8].trim()) : 0; + double percent = (parts.length > 9) ? Double.parseDouble(parts[9].trim()) : 0.0; + + Product product = inv.searchAboutProductByname(productName); + if (product == null) product = new Product(-1, productName, 0, new HashMap<>()); + + Task task = new Task(id, product, amount, customer, startDate); + task.setenum(status); + task.setExecutionDate(endDate); + task.setLineName(lineName); + + + + + ProductLine l = inv.getProductLineByName(lineName); + if (l != null) task.login(l); + + tasks.add(task); + } + } catch (Exception e) { + System.out.println("❌ Error loading tasks: " + e.getMessage()); + } + return tasks; +} +} \ No newline at end of file diff --git a/src/Controller.java b/src/Controller.java new file mode 100644 index 0000000..5da0cd5 --- /dev/null +++ b/src/Controller.java @@ -0,0 +1,66 @@ +public class Controller { + + static CEO ceo = new CEO(); + Invantory invantory = Invantory.getInstance(); + + private static Controller instance; + + private Controller() { + invantory.productesLine.clear(); + invantory.productesLine.addAll( + CSV.readProductLine("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\ProductLine.csv") + ); + Invantory.loadInventory(); + + + } + + + public static Controller getInstance() { + if (instance == null) { + instance = new Controller(); + } + return instance; + } + void Edit(String name,String status) throws NOTFOUND { + ceo.edit(name,status); + } + +public Item AddItem(String nameOfItem, String category, int price, int quantity, int min) { + return invantory.AddItem(category, nameOfItem, price, quantity, min); +} + + public void Add(String lineName) { + ceo.addProductLine(lineName); + } + + public String Viow() { + return ceo.display(); + } + public void removeItemById(int itemId) throws NOTFOUND { + + Item item = Invantory.getInstance().getItem(itemId); + Invantory.getInstance().RemoveItem(item); + } + + public Item editItem( + int id, + String name, + String category, + int price, + int quantity, + int min + ) throws NOTFOUND { + + return invantory.editItem( + id, + name, + category, + price, + quantity, + min + ); + } + + +} diff --git a/src/Daily_Recordings b/src/Daily_Recordings new file mode 100644 index 0000000..e69de29 diff --git a/src/Daily_Recordings.java b/src/Daily_Recordings.java new file mode 100644 index 0000000..be97c66 --- /dev/null +++ b/src/Daily_Recordings.java @@ -0,0 +1,53 @@ +import java.io.*; +import java.time.LocalDate ; +import java.time.format.DateTimeFormatter; +public class Daily_Recordings { + Invantory i=Invantory.getInstance(); + public void Daily() { + String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + String fileName = "C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Daily_Recordings.txt" + date + ".txt"; +// try (PrintWriter writer = new PrintWriter(new FileWriter(fileName),true)) { +// writer.println("Daily Inventory Report"); +// writer.println("Date: " + date); +// writer.println(); +// writer.println("Products"); +// for (Product p : i.general_products.values()) { +// writer.println("ID: " + p.getNumberOfProduct() + +// ", Name: " + p.getNameOfProduct() + +// ", Qty: " + p.getQuantityOfProduct()); +// } +// writer.println(); +// writer.println("Items"); +// for (Item item : i.general_items.values()) { +// writer.println("ID: " + item.getIdOfItem() + +// ", Name: " + item.getNameOfItem() + +// ", Qty: " + item.getQuantity() + +// ", Price: " + item.getPrice()); +// } +// writer.println(); +// writer.println("End of Report"); +// System.out.println("Report saved: " + fileName); +// } catch (IOException e) { +// ErrorLogger.logError("Error: " + e.getMessage()); +// } + + try (PrintWriter writer = new PrintWriter(new FileWriter(fileName, true))) { + writer.println("Daily Inventory Report"); + writer.println("Date: " + date); + writer.println(); + writer.println("Items"); + for (Item item : Invantory.getInstance().general_items.values()) { + writer.println("ID: " + item.getIdOfItem() + + ", Name: " + item.getNameOfItem() + + ", Qty: " + item.getQuantity() + + ", Price: " + item.getPrice()); + } + writer.println("End of Report"); + } catch (IOException e) { + e.printStackTrace(); + } + + + + } +} \ No newline at end of file diff --git a/src/Daily_Recordings.txt b/src/Daily_Recordings.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/Daily_Recordings_2026-01-25.txt b/src/Daily_Recordings_2026-01-25.txt new file mode 100644 index 0000000..dccfd0d --- /dev/null +++ b/src/Daily_Recordings_2026-01-25.txt @@ -0,0 +1,6 @@ +Daily Inventory Report +Date: 2026-01-25 + +Items + +End of Report diff --git a/src/ErrorLogger.java b/src/ErrorLogger.java new file mode 100644 index 0000000..15297e9 --- /dev/null +++ b/src/ErrorLogger.java @@ -0,0 +1,12 @@ +import java.io.*; +public class ErrorLogger { + private static String ERROR_FILE = "C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\errors.txt"; + public static void logError(String message) { + try (PrintWriter pw = new PrintWriter(new FileWriter(ERROR_FILE, true))) { + pw.write(message); + pw.write("/n"); + } catch (IOException e) { + System.out.println("Failed to write error to file: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/Invantory.java b/src/Invantory.java new file mode 100644 index 0000000..70c97d6 --- /dev/null +++ b/src/Invantory.java @@ -0,0 +1,318 @@ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +public class Invantory { + static HashMap general_items = new HashMap<>(); + ArrayListproductesLine=new ArrayList<>(); + ArrayListtasks=new ArrayList<>(); + ArrayListtaskWasCancelled=new ArrayList<>(); + ArrayListgetProductesLine=new ArrayList<>(); + CSV csv; + static HashMap general_products = new HashMap<>(); + static Invantory invantory; + Item item ; + Product product; + + + +public static void loadInventory() { + Invantory instance = getInstance(); + + List items = CSV.readItem("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Item.csv"); // يفضل استخدام مسارات نسبية + general_items.clear(); + for (Item i : items) { + general_items.put(i.id, i); + } + + List products = CSV.readProduct("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Product.csv"); + general_products.clear(); + for (Product p : products) { + general_products.put(p.getNumberOfProduct(), p); + } + + instance.productesLine.clear(); + instance.productesLine.addAll(CSV.readProductLine("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\ProductLine.csv")); + + instance.tasks.clear(); + List loadedTasks = CSV.readTask("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Task.csv"); + + for (Task t : loadedTasks) { + ProductLine line = instance.getProductLineByName(t.getLineName()); + if (line != null) { + t.login(line); + } + if (!instance.tasks.contains(t)) { + instance.tasks.add(t); + } + } +} + + + + Invantory() + { + + } + public static Invantory getInstance() { + if (invantory==null) { + invantory = new Invantory(); + } + return invantory; + } + +public Item AddItem(String category, String nameOfItem, int price, int quantity, int min) { + Item item1 = new Item(category, nameOfItem, price, quantity, min); + + general_items.put(item1.getIdOfItem(), item1); + + CSV.writeItem2(new ArrayList<>(general_items.values())); + + return item1; +} + + public List getAllItems() { + return new ArrayList<>(items); + } + + + + public synchronized void increase(int itemid,int amount)throws NOTFOUND{ + Item item=general_items.get(itemid); + if (item==null) + { + String error="sorry,not found"; + ErrorLogger.logError(error); + throw new NOTFOUND(error); + } + item.setQuantity(item.getQuantity()+amount); + CSV.writeItem2(items); + System.out.println("amount"+amount+"was added"); + } + ArrayListitems=new ArrayList<>(); + ArrayListproducts=new ArrayList<>(); + + public void RemoveItem(Item item1) throws NOTFOUND { + if (!general_items.containsKey(item1.getIdOfItem())) { + throw new NOTFOUND("Item not found"); + } + + general_items.remove(item1.getIdOfItem()); + + CSV.writeItem2(new ArrayList<>(general_items.values())); + } + + + public boolean Check(Product p, int amount) { + for (Map.Entry entry : p.getP().entrySet()) { + Item l = entry.getKey(); + int requiredAmount = entry.getValue() * amount; + Item stockItem = general_items.get(l.getIdOfItem()); + if (stockItem == null || stockItem.getQuantity() < requiredAmount) { + ErrorLogger.logError("Not enough material for product"); + return false; + } + } + return true; + } + public void displayA(){ + items = (ArrayList) CSV.readItem("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Item.csv"); + + for (Item item1:items) + item1.print(); + + } + public void displayB(){ + products = (ArrayList) CSV.readProduct("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Product.csv"); + System.out.println(products.size()); + for (Product product1:products) + product1.printInfo(); + + } + + +public Item editItem( + int id, + String name, + String category, + int price, + int quantity, + int minAllowed +) throws NOTFOUND { + + Item item = general_items.get(id); + if (item == null) { + throw new NOTFOUND("Item not found"); + } + + item.setNameOfItem(name); + item.setCategory(category); + item.setPrice(price); + item.setQuantity(quantity); + item.setTheMinimumAllowed(minAllowed); + + CSV.writeItem2(new ArrayList<>(general_items.values())); + + return item; +} + + public synchronized void decrease(int id, int amount) throws NOTFOUND { + Item b = general_items.get(id); + if (b == null) { + String error = "Item " + id + " not found"; + ErrorLogger.logError(error); + throw new NOTFOUND(error); + } + if (b.getQuantity() < amount) { + String error = " Not enough quantity for item " + id; + ErrorLogger.logError(error); + throw new NOTFOUND(error); + } + b.setQuantity(b.getQuantity() - amount); + CSV.writeItem2(new ArrayList<>(general_items.values())); + + } + + public void UpdateItemQuantity(int id, int quantity) throws NOTFOUND { + Item item = general_items.get(id); + if (item != null) { + item.setQuantity(quantity); + CSV.writeItem2(new ArrayList<>(general_items.values())); + + System.out.println("The item quantity has been updated " + id + " to " + quantity); + } else { + String error = " Item " + id + " not found"; + ErrorLogger.logError(error); + throw new NOTFOUND(error); + } + } + + public Item getItem(int id) throws NOTFOUND { + Item item = general_items.get(id); + if (item == null) { + String error = " Item " + id + " not found"; + ErrorLogger.logError(error); + throw new NOTFOUND(error); + } + + return item; + } + + public Item searchByName(String name){ + + for (Item item : general_items.values()) { + if (item.getNameOfItem().equalsIgnoreCase(name)) { + return item; + } + } + String error = "Item " + name + " not found"; + ErrorLogger.logError(error); + + return null; + } + + public ListSearchByName(String name) { + return general_items.values().stream() + .filter(i -> i.getNameOfItem().toLowerCase().contains(name.toLowerCase())) + .collect(Collectors.toList()); + } + + public ListSearchByCategory(String category){ + return general_items.values().stream().filter(i->i.getCategory().toLowerCase().contains(category.toLowerCase())).collect(Collectors.toList()); + } + + public ListSearchByStatus(String status) throws NOTFOUND { + switch (status) { + case "AVAILABLE": + return general_items.values().stream().filter(i -> i.getQuantity() > 0).collect(Collectors.toList()); + case "Out_Of_Stock": + return general_items.values().stream().filter(i -> i.getQuantity() == 0).collect(Collectors.toList()); + case "BELOW_THRESHOLD": + return general_items.values().stream().filter(i -> i.getQuantity() < i.getTheMinimumAllowed()).collect(Collectors.toList()); + default: { + ErrorLogger.logError("not found any item have this status"); + throw new NOTFOUND("not found any item have this status"); + } + } + } + + public synchronized void SellProduct(int IdProduct, int Amount) throws NOTFOUND { + Product p = general_products.get(IdProduct); + if (p == null) { + String error = "Product " + IdProduct + " not found"; + ErrorLogger.logError(error); + throw new NOTFOUND(error); + } + if (p.getQuantityOfProduct() < Amount) { + String error = "Not enough quantity for product " + IdProduct; + ErrorLogger.logError(error); + throw new NOTFOUND(error); + } + p.setQuantityOfProduct(p.getQuantityOfProduct() - Amount); + System.out.println("Done"); + } + public void AddProduct(String nameOfProduct,HashMap p) { + Product product1=new Product( nameOfProduct, p); + general_products.put(product1.getNumberOfProduct(), product1); + CSV.writeProduct(product1); + } + + public Product getproduct(int id) throws NOTFOUND { + Product p = general_products.get(id); + if (p == null) { + String error = "Product " + id + " not found"; + ErrorLogger.logError(error); + throw new NOTFOUND(error); + } + return p; + } + + synchronized void IncreaseProduct(int id, int amount )throws NOTFOUND{ + Product p=general_products.get(id); + if(p==null) + throw new NOTFOUND("this is new product"); + + + p.setQuantityOfProduct( p.QuantityOfProduct+amount); + CSV.writeProduct2(products); + + } + + public Product searchAboutProductById(int i) { + for (Product k : general_products.values()) { + if (k.getNumberOfProduct() == i) + return k; + } + return null; + } + + + public Product searchAboutProductByname(String gg) { + for (Product k : general_products.values()) { + if (k.getNameOfProduct().equals(gg) ) + return k; + } + return null; + } + public ProductLine getProductLineByName(String name) { + for (ProductLine line : productesLine) { + if (line.getLineName().equalsIgnoreCase(name)) { + return line; + } + } + return null; + } + public int getNextTaskNumber() { + int max = 0; + for (Task t : tasks) { + if (t.getNumber() > max) max = t.getNumber(); + } + return max + 1; + } + + public ArrayList getProductLines() { + return productesLine; + } + +} \ No newline at end of file diff --git a/src/InventoryManagementFrame.java b/src/InventoryManagementFrame.java new file mode 100644 index 0000000..6e31a6c --- /dev/null +++ b/src/InventoryManagementFrame.java @@ -0,0 +1,452 @@ +import java.awt.*; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.util.List; +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import javax.swing.table.*; + +public class InventoryManagementFrame extends JFrame { + + Controller con = Controller.getInstance(); + Invantory ss = Invantory.getInstance(); + + private JTable table; + private DefaultTableModel tableModel; + private JTextField searchField; + private JComboBox searchTypeBox; + + // Dashboard labels + private JLabel totalLbl, availableLbl, lowLbl, belowMinLbl; + + // ===== Colors & Theme ===== + private final Color primaryOrange = new Color(255, 140, 0); + private final Color darkOrange = new Color(230, 120, 0); + private final Color softYellow = new Color(255, 230, 150); + private final Color backgroundColor = new Color(255, 248, 220); + private final Color lowRedText = new Color(180, 0, 0); + private final Color availableGreenText = new Color(0, 140, 0); + + private final Font titleFont = new Font("SansSerif", Font.BOLD, 34); + private final Font tableFont = new Font("SansSerif", Font.PLAIN, 16); + private final Font buttonFont = new Font("SansSerif", Font.BOLD, 18); + + public InventoryManagementFrame() { + + setTitle("Dominus – Inventory Management"); + setExtendedState(JFrame.MAXIMIZED_BOTH); + setDefaultCloseOperation(EXIT_ON_CLOSE); + setLayout(new BorderLayout()); + getContentPane().setBackground(backgroundColor); + + // ===== TITLE ===== + JLabel titleLabel = new JLabel("Inventory Management", SwingConstants.CENTER); + titleLabel.setFont(titleFont); + titleLabel.setForeground(primaryOrange); + titleLabel.setOpaque(true); + titleLabel.setBackground(softYellow); + titleLabel.setBorder(new EmptyBorder(25, 0, 25, 0)); + add(titleLabel, BorderLayout.NORTH); + + // ===== CENTER PANEL ===== + JPanel centerPanel = new JPanel(new BorderLayout()); + centerPanel.setBackground(backgroundColor); + add(centerPanel, BorderLayout.CENTER); + + // ===== TABLE ===== + String[] columns = {"ID", "Item Name", "Category", "Quantity", "Price", "Minimum Limit"}; + tableModel = new DefaultTableModel(columns, 0); + table = new JTable(tableModel); + table.setRowHeight(32); + table.setFont(tableFont); + table.setSelectionBackground(primaryOrange); + table.getTableHeader().setFont(new Font("SansSerif", Font.BOLD, 16)); + table.getTableHeader().setBackground(primaryOrange); + table.getTableHeader().setForeground(Color.WHITE); + + table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent( + JTable table, Object value, boolean isSelected, + boolean hasFocus, int row, int column) { + + Component c = super.getTableCellRendererComponent( + table, value, isSelected, hasFocus, row, column); + + if (!isSelected) { + c.setBackground(row % 2 == 0 ? Color.WHITE : softYellow); + } + + if (column == 3 && value != null) { // Quantity column + int qty = Integer.parseInt(value.toString()); + int min = Integer.parseInt(table.getValueAt(row, 5).toString()); + if (qty < min) c.setForeground(lowRedText); + else c.setForeground(availableGreenText); + } else { + c.setForeground(Color.BLACK); + } + return c; + } + }); + + JScrollPane tableScroll = new JScrollPane(table); + tableScroll.setBorder(BorderFactory.createLineBorder(primaryOrange, 2)); + + centerPanel.add(tableScroll, BorderLayout.CENTER); + + // ===== STATISTICS DASHBOARD ===== + JPanel statsPanel = new JPanel(new GridLayout(1, 4, 15, 15)); + statsPanel.setBackground(softYellow); + statsPanel.setBorder(BorderFactory.createTitledBorder("Statistics")); + + totalLbl = createStatLabel(primaryOrange); + availableLbl = createStatLabel(availableGreenText); + lowLbl = createStatLabel(lowRedText); + belowMinLbl = createStatLabel(new Color(150, 0, 150)); + + statsPanel.add(totalLbl); + statsPanel.add(availableLbl); + statsPanel.add(lowLbl); + statsPanel.add(belowMinLbl); + + centerPanel.add(statsPanel, BorderLayout.SOUTH); + + // ===== BUTTONS PANEL (RIGHT) ===== + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS)); + buttonsPanel.setBackground(softYellow); + buttonsPanel.setBorder(new EmptyBorder(30, 30, 30, 30)); + + Dimension btnSize = new Dimension(250, 55); + + JButton addBtn = createButton("Add Item", btnSize); + JButton editBtn = createButton("Edit Item", btnSize); + JButton deleteBtn = createButton("Delete Item", btnSize); + JButton saveBtn = createButton("Save Daily Report", btnSize); + JButton backBtn = createButton("Back", btnSize); + + addBtn.addActionListener(e -> addItem()); + editBtn.addActionListener(e -> editItem()); + deleteBtn.addActionListener(e -> deleteSelectedItem()); + saveBtn.addActionListener(e -> saveDailyReportFromCSV()); + backBtn.addActionListener(e -> { + new SupervisorMenuFrame(); + dispose(); + }); + + buttonsPanel.add(Box.createVerticalGlue()); + buttonsPanel.add(addBtn); + buttonsPanel.add(Box.createVerticalStrut(20)); + buttonsPanel.add(editBtn); + buttonsPanel.add(Box.createVerticalStrut(20)); + buttonsPanel.add(deleteBtn); + buttonsPanel.add(Box.createVerticalStrut(20)); + buttonsPanel.add(saveBtn); + buttonsPanel.add(Box.createVerticalStrut(20)); + buttonsPanel.add(backBtn); + buttonsPanel.add(Box.createVerticalGlue()); + + centerPanel.add(buttonsPanel, BorderLayout.EAST); + + // ===== SEARCH PANEL (ABOVE TABLE) ===== + JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + searchPanel.setBackground(backgroundColor); + searchPanel.setBorder(BorderFactory.createTitledBorder("Search Inventory")); + + searchField = new JTextField(15); + searchTypeBox = new JComboBox<>(new String[]{"Item Name", "Category", "Status"}); + + JComboBox statusOptionsBox = new JComboBox<>(new String[]{"Available", "Out of Stock", "Below Minimum"}); + statusOptionsBox.setVisible(false); + + searchTypeBox.addActionListener(e -> { + String selected = searchTypeBox.getSelectedItem().toString(); + if (selected.equals("Status")) { + statusOptionsBox.setVisible(true); + searchField.setEnabled(false); + } else { + statusOptionsBox.setVisible(false); + searchField.setEnabled(true); + } + }); + + JButton searchBtn = createButton("Search", new Dimension(120, 35)); + searchBtn.setFont(new Font("SansSerif", Font.BOLD, 14)); + searchBtn.addActionListener(e -> { + String type = searchTypeBox.getSelectedItem().toString(); + String text = searchField.getText(); + if (type.equals("Status")) text = statusOptionsBox.getSelectedItem().toString(); + search(text, type); + }); + + searchPanel.add(new JLabel("Search:")); + searchPanel.add(searchField); + searchPanel.add(searchTypeBox); + searchPanel.add(statusOptionsBox); + searchPanel.add(searchBtn); + + centerPanel.add(searchPanel, BorderLayout.NORTH); + + // Load existing items + loadItemsFromFile(); + updateDashboard(); + + setVisible(true); + } + + // ===== UTILITY METHODS ===== + private JLabel createStatLabel(Color color) { + JLabel lbl = new JLabel("", SwingConstants.CENTER); + lbl.setFont(new Font("SansSerif", Font.BOLD, 18)); + lbl.setForeground(color); + return lbl; + } + + private JButton createButton(String text, Dimension size) { + JButton btn = new JButton(text) { + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setColor(getModel().isPressed() ? darkOrange : primaryOrange); + g2.fillRoundRect(0, 0, getWidth(), getHeight(), 30, 30); + super.paintComponent(g); + g2.dispose(); + } + + protected void paintBorder(Graphics g) { + g.setColor(darkOrange); + ((Graphics2D) g).drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 30, 30); + } + }; + btn.setPreferredSize(size); + btn.setMaximumSize(size); + btn.setMinimumSize(size); + btn.setContentAreaFilled(false); + btn.setFocusPainted(false); + btn.setForeground(Color.WHITE); + btn.setFont(buttonFont); + btn.setAlignmentX(Component.CENTER_ALIGNMENT); + return btn; + } + + // ===== LOAD ITEMS ===== + private void loadItemsFromFile() { + tableModel.setRowCount(0); + List items = CSV.readItem("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Daily_Recordings"); + for (Item item : items) { + tableModel.addRow(new Object[]{ + item.getIdOfItem(), + item.getNameOfItem(), + item.getCategory(), + item.getQuantity(), + item.getPrice(), + item.getTheMinimumAllowed() + }); + } + updateDashboard(); + } + + // ===== DASHBOARD UPDATE ===== + private void updateDashboard() { + int total = tableModel.getRowCount(); + int available = 0, low = 0, belowMin = 0; + for (int i = 0; i < total; i++) { + int qty = Integer.parseInt(tableModel.getValueAt(i, 3).toString()); + int min = Integer.parseInt(tableModel.getValueAt(i, 5).toString()); + String status = tableModel.getValueAt(i, 4).toString(); + if (status.equalsIgnoreCase("Available")) available++; + if (status.equalsIgnoreCase("Low")) low++; + if (qty < min) belowMin++; + } + totalLbl.setText("Total Items: " + total); + availableLbl.setText("Available: " + available); + lowLbl.setText("Low Stock: " + low); + belowMinLbl.setText("Below Minimum: " + belowMin); + } + + // ===== ADD ITEM ===== + private void addItem() { + JTextField nameField = new JTextField(); + JTextField category = new JTextField(); + JTextField price = new JTextField(); + JTextField quantity = new JTextField(); + JTextField minimum = new JTextField(); + + JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5)); + panel.add(new JLabel("Item Name:")); + panel.add(nameField); + panel.add(new JLabel("Category:")); + panel.add(category); + panel.add(new JLabel("Price:")); + panel.add(price); + panel.add(new JLabel("Quantity:")); + panel.add(quantity); + panel.add(new JLabel("Minimum allowed:")); + panel.add(minimum); + + int result = JOptionPane.showConfirmDialog(this, panel, "Add Item", JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + String itemName = nameField.getText(); + String cat = category.getText(); + int pr = Integer.parseInt(price.getText()); + int qty = Integer.parseInt(quantity.getText()); + int min = Integer.parseInt(minimum.getText()); + + Item item = con.AddItem(itemName, cat, pr, qty, min); + tableModel.addRow(new Object[]{ + item.getIdOfItem(), + item.getNameOfItem(), + item.getCategory(), + item.getQuantity(), + item.getPrice(), + item.getTheMinimumAllowed() + }); + updateDashboard(); + } + } + + // ===== EDIT ITEM ===== + private void editItem() { + int selectedRow = table.getSelectedRow(); + if (selectedRow == -1) { + JOptionPane.showMessageDialog(this, "Please select an item to edit"); + return; + } + + int id = Integer.parseInt(tableModel.getValueAt(selectedRow, 0).toString()); + + JTextField nameField = new JTextField(tableModel.getValueAt(selectedRow, 1).toString()); + JTextField categoryField = new JTextField(tableModel.getValueAt(selectedRow, 2).toString()); + JTextField quantityField = new JTextField(tableModel.getValueAt(selectedRow, 3).toString()); + JTextField priceField = new JTextField(tableModel.getValueAt(selectedRow, 4).toString()); + JTextField minField = new JTextField(tableModel.getValueAt(selectedRow, 5).toString()); + + JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5)); + panel.add(new JLabel("Item Name:")); + panel.add(nameField); + panel.add(new JLabel("Category:")); + panel.add(categoryField); + panel.add(new JLabel("Quantity:")); + panel.add(quantityField); + panel.add(new JLabel("Price:")); + panel.add(priceField); + panel.add(new JLabel("Minimum Allowed:")); + panel.add(minField); + + int result = JOptionPane.showConfirmDialog(this, panel, "Edit Item", JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + try { + String name = nameField.getText(); + String category = categoryField.getText(); + int quantity = Integer.parseInt(quantityField.getText()); + int price = Integer.parseInt(priceField.getText()); + int min = Integer.parseInt(minField.getText()); + + Item updatedItem = con.editItem(id, name, category, price, quantity, min); + + tableModel.setValueAt(updatedItem.getNameOfItem(), selectedRow, 1); + tableModel.setValueAt(updatedItem.getCategory(), selectedRow, 2); + tableModel.setValueAt(updatedItem.getQuantity(), selectedRow, 3); + tableModel.setValueAt(updatedItem.getPrice(), selectedRow, 4); + tableModel.setValueAt(updatedItem.getTheMinimumAllowed(), selectedRow, 5); + + updateDashboard(); + + } catch (NumberFormatException ex) { + JOptionPane.showMessageDialog(this, "Please enter valid numbers"); + } catch (NOTFOUND ex) { + JOptionPane.showMessageDialog(this, ex.getMessage()); + } + } + } + + // ===== DELETE ITEM ===== + private void deleteSelectedItem() { + int row = table.getSelectedRow(); + if (row == -1) { + JOptionPane.showMessageDialog(this, "Please select an item to delete"); + return; + } + + int confirm = JOptionPane.showConfirmDialog(this, "Are you sure you want to delete this item?", "Confirm Delete", JOptionPane.YES_NO_OPTION); + if (confirm != JOptionPane.YES_OPTION) return; + + int modelRow = table.convertRowIndexToModel(row); + int itemId = Integer.parseInt(tableModel.getValueAt(modelRow, 0).toString()); + + try { + con.removeItemById(itemId); + tableModel.removeRow(modelRow); + updateDashboard(); + } catch (NOTFOUND e) { + JOptionPane.showMessageDialog(this, e.getMessage()); + } + } + + // ===== SEARCH ITEM ===== + private void search(String text, String type) { + try { + table.clearSelection(); + boolean found = false; + + if (type.equals("Status")) { + String selectedStatus = text.trim(); + for (int i = 0; i < table.getRowCount(); i++) { + int qty = Integer.parseInt(table.getValueAt(i, 3).toString()); + int min = Integer.parseInt(table.getValueAt(i, 5).toString()); + String status = qty == 0 ? "Out of Stock" : qty < min ? "Below Minimum" : "Available"; + if (status.equalsIgnoreCase(selectedStatus)) { + table.addRowSelectionInterval(i, i); + found = true; + } + } + } else { + text = text == null ? "" : text.trim().toLowerCase(); + for (int i = 0; i < table.getRowCount(); i++) { + String value = type.equals("Item Name") ? table.getValueAt(i, 1).toString() : table.getValueAt(i, 2).toString(); + if (value.toLowerCase().contains(text)) { + table.addRowSelectionInterval(i, i); + found = true; + } + } + } + + if (!found) JOptionPane.showMessageDialog(this, "No items found matching your search criteria"); + } catch (Exception e) { + JOptionPane.showMessageDialog(this, "An unexpected error occurred during search:\n" + e.getMessage()); + } + } + + // ===== SAVE DAILY REPORT ===== + private void saveDailyReportFromCSV() { + try { + String date = java.time.LocalDate.now().toString(); + String fileName = "C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Daily_Recordings_" + date + ".txt"; + + List itemsFromCSV = CSV.readItem("C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\Daily_Recordings"); + + try (PrintWriter writer = new PrintWriter(new FileWriter(fileName, false))) { + writer.println("Daily Inventory Report"); + writer.println("Date: " + date); + writer.println(); + writer.println("Items"); + for (Item item : itemsFromCSV) { + writer.println("ID: " + item.getIdOfItem() + + ", Name: " + item.getNameOfItem() + + ", Qty: " + item.getQuantity() + + ", Price: " + item.getPrice() + + ", min: " + item.getTheMinimumAllowed()); + } + writer.println(); + writer.println("End of Report"); + } + + JOptionPane.showMessageDialog(this, "Daily inventory report saved successfully"); + + } catch (Exception e) { + JOptionPane.showMessageDialog(this, "Error saving daily report: " + e.getMessage()); + } + } +} diff --git a/src/Item.csv b/src/Item.csv new file mode 100644 index 0000000..ebd8770 --- /dev/null +++ b/src/Item.csv @@ -0,0 +1,3 @@ +id,nameOfItem,category,quantity,price,theMinimumAllowed +7,kf,n,54,54,2 +8,dkjb,dub,52,584,5 diff --git a/src/Item.java b/src/Item.java new file mode 100644 index 0000000..6a98fe8 --- /dev/null +++ b/src/Item.java @@ -0,0 +1,83 @@ +public class Item { + int IdOfItem ; + static int id=0; + String NameOfItem ; + int Price ; + int Quantity ; + int TheMinimumAllowed ; + String Category ; + public Item( String category,String nameOfItem,int price,int quantity,int theMinimumAllowed) { + Category=category ; + IdOfItem =++id; + NameOfItem = nameOfItem; + Price=price; + Quantity=quantity; + TheMinimumAllowed=theMinimumAllowed ; + } + + +public Item(int id, String name, int price, int quantity, int minAllowed, String category) { + this.IdOfItem = id; + this.NameOfItem = name; + this.Price = price; + this.Quantity = quantity; + this.TheMinimumAllowed = minAllowed; + this.Category = category; + + if (id > Item.id) { + Item.id = id; + } +} + + + public int getIdOfItem() { + return IdOfItem; + } + public String getNameOfItem() { + return NameOfItem; + } + + public void setNameOfItem(String nameOfItem) { + NameOfItem = nameOfItem; + } + + public int getPrice() { + return Price; + } + + public void setPrice(int price) { + Price = price; + } + public int getQuantity() { + return Quantity; + } + public void setQuantity(int quantity) { + Quantity = quantity; + } + public int getTheMinimumAllowed() { + return TheMinimumAllowed; + } + + public void setTheMinimumAllowed(int theMinimumAllowed) { + TheMinimumAllowed = theMinimumAllowed; + } + + public String getCategory() { + return Category; + } + public void setCategory(String category) { + Category = category; + } + public void print() { + System.out.println( "Item{"+"id:"+getIdOfItem()+" "+"name:"+ getNameOfItem() + " "+"price:" +getPrice()+" "+ "Quantity:" + getQuantity()+" "+"The minimum allowed=" + getTheMinimumAllowed()+" "+"Category:" +getCategory()+"}"); + } + + @Override + public String toString() { + return getIdOfItem() + "," + + getNameOfItem() + "," +getCategory()+ "," +getQuantity() + + "," +getPrice() + "," + + getTheMinimumAllowed() + ; + } +} \ No newline at end of file diff --git a/src/LineNotes.csv b/src/LineNotes.csv new file mode 100644 index 0000000..332a70c --- /dev/null +++ b/src/LineNotes.csv @@ -0,0 +1,4 @@ +lineName,note,date +a,الخط سريع,2026-01-25 +a,الخط ليس سريع,2026-01-25 +hjbjfr,sidbjg,2026-01-25 diff --git a/src/LoginFrame.java b/src/LoginFrame.java new file mode 100644 index 0000000..1d50bae --- /dev/null +++ b/src/LoginFrame.java @@ -0,0 +1,252 @@ +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public class LoginFrame extends JFrame { + + private RoundedTextField usernameField; + private RoundedPasswordField passwordField; + private JComboBox roleBox; + private RoundedButton loginButton; + private JButton eyeButton; + + // ====== YELLOW THEME ====== + Color primaryYellow = new Color(255, 215, 0); + Color darkYellow = new Color(180, 140, 0); + Color deepText = new Color(70, 50, 0); + + public LoginFrame() { + + setTitle("alsb3"); + setExtendedState(JFrame.MAXIMIZED_BOTH); + setDefaultCloseOperation(EXIT_ON_CLOSE); + setLayout(null); + + BackgroundPanel backgroundPanel = + new BackgroundPanel("C:\\Users\\HP\\Desktop\\محاضرات\\خوارزميات\\عملي\\محاضرات المعيدة\\photo_2026-01-25_12-00-37.jpg"); + backgroundPanel.setLayout(null); + setContentPane(backgroundPanel); + + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + int W = screen.width; + int H = screen.height; + + int centerY = H / 2; + + int fieldW = 320; + int fieldH = 50; + int labelW = 170; + int labelH = 40; + int gap = 20; + int space = 85; + + // ====== نحرك المجموعة لليسار ====== + int groupW = labelW + gap + fieldW; + int groupX = 150; // بدل المنتصف صار يسار الشاشة + + int labelX = groupX; + int fieldX = groupX + labelW + gap; + + JLabel userLabel = new RoundedLabel("Username", darkYellow); + userLabel.setFont(new Font("Serif", Font.BOLD, 28)); + userLabel.setBounds(labelX, centerY - space, labelW, labelH); + backgroundPanel.add(userLabel); + + usernameField = new RoundedTextField(); + usernameField.setFont(new Font("Serif", Font.BOLD, 24)); + usernameField.setBackground(primaryYellow); + usernameField.setForeground(deepText); + usernameField.setBounds(fieldX, centerY - space, fieldW, fieldH); + backgroundPanel.add(usernameField); + + JLabel passLabel = new RoundedLabel("Password", darkYellow); + passLabel.setFont(new Font("Serif", Font.BOLD, 28)); + passLabel.setBounds(labelX, centerY, labelW, labelH); + backgroundPanel.add(passLabel); + + passwordField = new RoundedPasswordField(); + passwordField.setFont(new Font("Serif", Font.BOLD, 24)); + passwordField.setBackground(primaryYellow); + passwordField.setForeground(deepText); + passwordField.setBounds(fieldX, centerY, fieldW, fieldH); + backgroundPanel.add(passwordField); + + eyeButton = new JButton("\uD83D\uDC41"); + eyeButton.setFont(new Font("Serif", Font.BOLD, 24)); + eyeButton.setBounds(fieldX + fieldW + 10, centerY, 50, fieldH); + eyeButton.setFocusPainted(false); + eyeButton.setBorderPainted(false); + eyeButton.setContentAreaFilled(false); + eyeButton.setForeground(primaryYellow); + backgroundPanel.add(eyeButton); + + eyeButton.addActionListener(e -> togglePassword()); + + JLabel roleLabel = new RoundedLabel("Role", darkYellow); + roleLabel.setFont(new Font("Serif", Font.BOLD, 28)); + roleLabel.setBounds(labelX, centerY + space, labelW, labelH); + backgroundPanel.add(roleLabel); + + roleBox = new JComboBox<>(new String[]{"manager", "Supervisor"}); + roleBox.setFont(new Font("Serif", Font.BOLD, 24)); + roleBox.setBackground(primaryYellow); + roleBox.setForeground(deepText); + roleBox.setBounds(fieldX, centerY + space, fieldW, fieldH); + backgroundPanel.add(roleBox); + + // ====== زر تسجيل الدخول أصفر ====== + loginButton = new RoundedButton("Login"); + loginButton.setFont(new Font("Serif", Font.BOLD, 30)); + loginButton.setBackground(primaryYellow); + loginButton.setForeground(deepText); + + int btnW = 220; + int btnH = 55; + int buttonY = centerY + space * 2 + 10; + + loginButton.setBounds(groupX, buttonY, btnW, btnH); // صار عاليسار + backgroundPanel.add(loginButton); + + loginButton.addActionListener(e -> performLogin()); + + setVisible(true); + } + + private void togglePassword() { + if (passwordField.getEchoChar() == '\u2022') { + passwordField.setEchoChar((char) 0); + } else { + passwordField.setEchoChar('\u2022'); + } + } + + private void performLogin() { + String username = usernameField.getText().trim(); + String password = new String(passwordField.getPassword()).trim(); + String role = (String) roleBox.getSelectedItem(); + + if ("manager".equals(role) && "laith".equals(username) && "123".equals(password)) { + SwingUtilities.invokeLater(() -> new MangerFrame().setVisible(true)); + dispose(); + } else if ("Supervisor".equals(role) && "ali".equals(username) && "234".equals(password)) { + SwingUtilities.invokeLater(() -> new SupervisorMenuFrame().setVisible(true)); + dispose(); + } else { + JOptionPane.showMessageDialog( + this, + "Invalid username, password or role", + "Login Failed", + JOptionPane.ERROR_MESSAGE + ); + } + } + + // ====== الخلفية ====== + static class BackgroundPanel extends JPanel { + private Image background; + + public BackgroundPanel(String path) { + background = new ImageIcon(path).getImage(); + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g; + + if (background != null) { + g2.drawImage(background, 0, 0, getWidth(), getHeight(), this); + } + + g2.setFont(new Font("Serif", Font.BOLD, 130)); + String title = "Welcome to alsb3"; + + FontMetrics fm = g2.getFontMetrics(); + int x = 150; // صار عاليسار + int y = 170; + + g2.setColor(new Color(0, 0, 0, 120)); + g2.drawString(title, x + 4, y + 4); + + g2.setColor(new Color(255, 215, 0)); + g2.drawString(title, x, y); + } + } + + static class RoundedLabel extends JLabel { + private final Color bg; + + public RoundedLabel(String text, Color bg) { + super(text, SwingConstants.CENTER); + this.bg = bg; + setForeground(Color.WHITE); + } + + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + g2.setColor(bg); + g2.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20); + super.paintComponent(g); + } + } + + static class RoundedTextField extends JTextField { + public RoundedTextField() { + setOpaque(false); + addFocusListener(new GlowEffect(this)); + } + + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + g2.setColor(getBackground()); + g2.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20); + super.paintComponent(g); + } + } + + static class RoundedPasswordField extends JPasswordField { + public RoundedPasswordField() { + setOpaque(false); + setEchoChar('\u2022'); + addFocusListener(new GlowEffect(this)); + } + + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + g2.setColor(getBackground()); + g2.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20); + super.paintComponent(g); + } + } + + static class GlowEffect extends FocusAdapter { + private final JComponent comp; + + public GlowEffect(JComponent comp) { + this.comp = comp; + } + + public void focusGained(FocusEvent e) { + comp.setBorder(BorderFactory.createLineBorder(new Color(255, 200, 0), 3)); + } + + public void focusLost(FocusEvent e) { + comp.setBorder(null); + } + } + + static class RoundedButton extends JButton { + public RoundedButton(String text) { + super(text); + setContentAreaFilled(false); + setFocusPainted(false); + setBorderPainted(false); + } + + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + g2.setColor(getBackground()); + g2.fillRoundRect(0, 0, getWidth(), getHeight(), 25, 25); + super.paintComponent(g); + } + } +} diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..ce4c39d --- /dev/null +++ b/src/Main.java @@ -0,0 +1,25 @@ +import javax.swing.*; + +public class Main { + public static void main(String[] args) { + + + + SwingUtilities.invokeLater(() -> { + new SplashScreen().setVisible(true); + }); + + + SwingUtilities.invokeLater(() -> new SplashScreen().setVisible(true)); + Controller.getInstance(); + +// SwingUtilities.invokeLater(() -> new LoginFrame().setVisible(true)); + + +// SwingUtilities.invokeLater(() -> new MangerFrame().setVisible(true)); + +// SwingUtilities.invokeLater(() -> new SupervisorMenuFrame().setVisible(true)); +// SwingUtilities.invokeLater(() -> new InventoryManagementFrame().setVisible(true)); + + } +} \ No newline at end of file diff --git a/src/MangerFrame.java b/src/MangerFrame.java new file mode 100644 index 0000000..a65fc42 --- /dev/null +++ b/src/MangerFrame.java @@ -0,0 +1,390 @@ +import java.awt.*; +import java.time.LocalDate; +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; + +public class MangerFrame extends JFrame { + + Controller con = Controller.getInstance(); + Invantory ss = Invantory.getInstance(); + + private final Color primaryOrange = new Color(255, 140, 0); + private final Color darkOrange = new Color(230, 120, 0); + private final Color softYellow = new Color(255, 230, 150); + private final Color backgroundColor = new Color(255, 248, 220); + + private JTable table; + private DefaultTableModel tableModel; + + private JLabel totalLbl, activeLbl, stoppedLbl, maintenanceLbl; + + private final Font titleFont = new Font("SansSerif", Font.BOLD, 34); + private final Font buttonFont = new Font("SansSerif", Font.BOLD, 18); + private final Font tableFont = new Font("SansSerif", Font.PLAIN, 16); + + public MangerFrame() { + + setTitle("alsb3 – Production Management"); + setSize(1300, 750); + setExtendedState(JFrame.MAXIMIZED_BOTH); + setLocationRelativeTo(null); + setDefaultCloseOperation(EXIT_ON_CLOSE); + setLayout(new BorderLayout()); + getContentPane().setBackground(backgroundColor); + + // ===== TITLE ===== + JLabel titleLabel = new JLabel("alsb3 – Production Management", SwingConstants.CENTER); + titleLabel.setFont(titleFont); + titleLabel.setForeground(primaryOrange); + titleLabel.setBorder(new EmptyBorder(25, 0, 25, 0)); + titleLabel.setOpaque(true); + titleLabel.setBackground(softYellow); + add(titleLabel, BorderLayout.NORTH); + + JPanel centerPanel = new JPanel(new BorderLayout()); + centerPanel.setBackground(backgroundColor); + add(centerPanel, BorderLayout.CENTER); + + // ===== BUTTONS PANEL (RIGHT SIDE) ===== + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS)); + buttonsPanel.setBackground(softYellow); + buttonsPanel.setBorder(new EmptyBorder(30, 30, 30, 30)); + + Dimension btnSize = new Dimension(300, 55); + + JButton addLineBtn = createButton("Add Production Line", btnSize); + JButton updateStatusBtn = createButton("Update Line Status", btnSize); + JButton notesBtn = createButton("Evaluation & Notes", btnSize); + JButton performanceBtn = createButton("Production Lines Performance", btnSize); + JButton backBtn = createButton("Back", btnSize); + + buttonsPanel.add(Box.createVerticalGlue()); + buttonsPanel.add(addLineBtn); + buttonsPanel.add(Box.createVerticalStrut(20)); + buttonsPanel.add(updateStatusBtn); + buttonsPanel.add(Box.createVerticalStrut(20)); + buttonsPanel.add(notesBtn); + buttonsPanel.add(Box.createVerticalStrut(20)); + buttonsPanel.add(performanceBtn); + buttonsPanel.add(Box.createVerticalStrut(30)); + buttonsPanel.add(backBtn); + buttonsPanel.add(Box.createVerticalGlue()); + + centerPanel.add(buttonsPanel, BorderLayout.EAST); + + // ===== SEARCH PANEL ===== + JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + searchPanel.setBackground(backgroundColor); + searchPanel.setBorder(BorderFactory.createTitledBorder("Search Production Line by ID")); + + JTextField searchField = new JTextField(10); + JButton searchBtn = createButton("Search", new Dimension(120, 35)); + searchBtn.setFont(new Font("SansSerif", Font.BOLD, 14)); + searchBtn.addActionListener(e -> searchById(searchField.getText())); + + searchPanel.add(new JLabel("Line ID:")); + searchPanel.add(searchField); + searchPanel.add(searchBtn); + + centerPanel.add(searchPanel, BorderLayout.NORTH); + + // ===== TABLE ===== + String[] columns = {"ID", "Line Name", "Status"}; + tableModel = new DefaultTableModel(columns, 0); + table = new JTable(tableModel); + + table.setFont(tableFont); + table.setRowHeight(32); + table.setSelectionBackground(primaryOrange); + table.getTableHeader().setFont(new Font("SansSerif", Font.BOLD, 16)); + table.getTableHeader().setBackground(primaryOrange); + table.getTableHeader().setForeground(Color.WHITE); + + table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent( + JTable table, Object value, boolean isSelected, + boolean hasFocus, int row, int col) { + + Component c = super.getTableCellRendererComponent( + table, value, isSelected, hasFocus, row, col); + + if (!isSelected) { + c.setBackground(row % 2 == 0 ? Color.WHITE : softYellow); + } + + if (col == 2 && value != null) { + switch (value.toString()) { + case "Active": + c.setForeground(new Color(0, 150, 0)); + break; + case "Stopped": + c.setForeground(Color.RED); + break; + case "Under Maintenance": + c.setForeground(primaryOrange); + break; + default: + c.setForeground(Color.BLACK); + } + } else { + c.setForeground(Color.BLACK); + } + return c; + } + }); + + JScrollPane tableScroll = new JScrollPane(table); + tableScroll.setBorder(BorderFactory.createLineBorder(primaryOrange, 2)); + + centerPanel.add(tableScroll, BorderLayout.CENTER); + + // ===== STATISTICS ===== + JPanel statsPanel = new JPanel(new GridLayout(1, 4, 15, 15)); + statsPanel.setBackground(softYellow); + statsPanel.setBorder(BorderFactory.createTitledBorder("Statistics")); + + totalLbl = createStatLabel(); + activeLbl = createStatLabel(); + stoppedLbl = createStatLabel(); + maintenanceLbl = createStatLabel(); + + statsPanel.add(totalLbl); + statsPanel.add(activeLbl); + statsPanel.add(stoppedLbl); + statsPanel.add(maintenanceLbl); + + centerPanel.add(statsPanel, BorderLayout.SOUTH); + + // ===== ACTIONS ===== + addLineBtn.addActionListener(e -> addLine()); + updateStatusBtn.addActionListener(e -> updateLineStatus()); + notesBtn.addActionListener(e -> openNotesDialog()); + performanceBtn.addActionListener(e -> showPerformance()); + backBtn.addActionListener(e -> { + new LoginFrame(); + dispose(); + }); + + loadLinesToTable(); + updateStatistics(); + setVisible(true); + } + + private void updateLineStatus() { + int row = table.getSelectedRow(); + + if (row == -1) { + JOptionPane.showMessageDialog(this, "Please select a production line first"); + return; + } + + JComboBox statusBox = new JComboBox<>( + new String[]{"Active", "Stopped", "Under Maintenance"} + ); + + int result = JOptionPane.showConfirmDialog(this, statusBox, "Update Line Status", JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + String lineName = tableModel.getValueAt(row, 1).toString(); + String newStatus = statusBox.getSelectedItem().toString(); + + try { + con.Edit(lineName, newStatus); + + Invantory inv = Invantory.getInstance(); + CSV.writeProductLine2(inv.getProductLines()); + + tableModel.setValueAt(newStatus, row, 2); + updateStatistics(); + + JOptionPane.showMessageDialog(this, "Status updated and saved to file!"); + + } catch (NOTFOUND e) { + JOptionPane.showMessageDialog(this, e.getMessage()); + } + } + } + + private void showPerformance() { + + String V = con.Viow(); + System.out.println("the Performance viewed"); + + JTextArea area = new JTextArea(V, 12, 40); + area.setEditable(false); + + JOptionPane.showMessageDialog( + this, + new JScrollPane(area), + "Production Lines Performance", + JOptionPane.INFORMATION_MESSAGE + ); + + } + + private void searchById(String text) { + try { + int id = Integer.parseInt(text); + for (int i = 0; i < tableModel.getRowCount(); i++) { + if ((int) tableModel.getValueAt(i, 0) == id) { + table.setRowSelectionInterval(i, i); + table.scrollRectToVisible(table.getCellRect(i, 0, true)); + return; + } + } + JOptionPane.showMessageDialog(this, "Line not found"); + } catch (NumberFormatException e) { + JOptionPane.showMessageDialog(this, "Invalid ID"); + } + } + + private void openNotesDialog() { + + JComboBox lineBox = new JComboBox<>(); + for (ProductLine pl : ss.productesLine) { + lineBox.addItem(pl.getLineName()); + } + + JTextArea notesArea = new JTextArea(8, 30); + notesArea.setLineWrap(true); + notesArea.setWrapStyleWord(true); + + JPanel panel = new JPanel(new BorderLayout(5, 5)); + + JPanel top = new JPanel(new GridLayout(2, 1, 5, 5)); + top.add(new JLabel("Production Line:")); + top.add(lineBox); + + panel.add(top, BorderLayout.NORTH); + panel.add(new JScrollPane(notesArea), BorderLayout.CENTER); + + int result = JOptionPane.showConfirmDialog( + this, + panel, + "Evaluation & Notes", + JOptionPane.OK_CANCEL_OPTION + ); + + if (result == JOptionPane.OK_OPTION) { + + String lineName = lineBox.getSelectedItem().toString(); + String note = notesArea.getText(); + + if (note.trim().isEmpty()) { + JOptionPane.showMessageDialog(this, "Note cannot be empty"); + return; + } + + CSV.writeLineNote(lineName, note); + + JOptionPane.showMessageDialog(this, "Note saved successfully ✅"); + } + } + + private void addLine() { + + JTextField nameField = new JTextField(); + JTextField outputField = new JTextField(); + + JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5)); + panel.add(new JLabel("Line Name:")); + panel.add(nameField); + + int result = JOptionPane.showConfirmDialog( + this, panel, + "Add Production Line", JOptionPane.OK_CANCEL_OPTION + ); + + if (result == JOptionPane.OK_OPTION) { + + con.Add(nameField.getText()); + + ss.productesLine.clear(); + ss.productesLine.addAll( + CSV.readProductLine( + "C:\\Users\\alaa\\Desktop\\swing in project 3\\src\\ProductLine.csv" + ) + ); + + loadLinesToTable(); + updateStatistics(); + } + } + + private void updateStatistics() { + int total = tableModel.getRowCount(); + int a = 0, s = 0, m = 0; + + for (int i = 0; i < total; i++) { + switch (tableModel.getValueAt(i, 2).toString()) { + case "Active": a++; break; + case "Stopped": s++; break; + case "Under Maintenance": m++; break; + } + } + + totalLbl.setText("Total: " + total); + activeLbl.setText("Active: " + a); + stoppedLbl.setText("Stopped: " + s); + maintenanceLbl.setText("Maintenance: " + m); + } + + private JButton createButton(String text, Dimension size) { + + JButton btn = new JButton(text) { + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(getModel().isPressed() ? darkOrange : primaryOrange); + g2.fillRoundRect(0, 0, getWidth(), getHeight(), 30, 30); + + super.paintComponent(g); + g2.dispose(); + } + + protected void paintBorder(Graphics g) { + g.setColor(darkOrange); + ((Graphics2D) g).drawRoundRect(0, 0, + getWidth() - 1, getHeight() - 1, 30, 30); + } + }; + + btn.setPreferredSize(size); + btn.setMaximumSize(size); + btn.setMinimumSize(size); + btn.setContentAreaFilled(false); + btn.setFocusPainted(false); + btn.setForeground(Color.WHITE); + btn.setFont(buttonFont); + btn.setAlignmentX(Component.CENTER_ALIGNMENT); + + return btn; + } + + private void loadLinesToTable() { + tableModel.setRowCount(0); + for (ProductLine pl : ss.productesLine) { + tableModel.addRow(new Object[]{ + pl.getLineId(), + pl.getLineName(), + pl.getStatus() != null ? pl.getStatus().name().replace("_", " ") : "Active", + "-", + LocalDate.now() + }); + } + } + + private JLabel createStatLabel() { + JLabel lbl = new JLabel("", SwingConstants.CENTER); + lbl.setFont(new Font("SansSerif", Font.BOLD, 18)); + lbl.setForeground(primaryOrange); + return lbl; + } + +} diff --git a/src/NOTFOUND.java b/src/NOTFOUND.java new file mode 100644 index 0000000..e4f3eee --- /dev/null +++ b/src/NOTFOUND.java @@ -0,0 +1,5 @@ +public class NOTFOUND extends Exception { + NOTFOUND(String m) { + super(m); + } +} \ No newline at end of file diff --git a/src/Product.csv b/src/Product.csv new file mode 100644 index 0000000..694a5e9 --- /dev/null +++ b/src/Product.csv @@ -0,0 +1,8 @@ +id, nameOfProduct,HashMap p +1,jj,1,DDD:1; +1,jj,1,DDD:1; +1,jj,1,DDD:1; +1,jj,1,DDD:1; +1,jj,1,DDD:1; +1,jj,1,DDD:1; +1,jj,1,DDD:1; diff --git a/src/Product.java b/src/Product.java new file mode 100644 index 0000000..a604af1 --- /dev/null +++ b/src/Product.java @@ -0,0 +1,85 @@ +import java.util.HashMap ; +import java.util.Map; +public class Product { + private int NumberOfProduct ; + private String NameOfProduct ; + private static int AUTO_ID = 0; + int QuantityOfProduct=1 ; + HashMapP=new HashMap<>(); + +public Product(String name, HashMap p) { + this.NumberOfProduct = ++AUTO_ID; + this.NameOfProduct = name; + + this.P = p; +} + + +public Product(int idFromCsv, String name, int quantity, HashMap p) { + this.NumberOfProduct = idFromCsv; + AUTO_ID = Math.max(AUTO_ID, idFromCsv); // 🔥 مهم + this.NameOfProduct = name; + this.QuantityOfProduct = quantity; + this.P = p; +} + + + public int getQuantityOfProduct() { + return QuantityOfProduct; + } + public void setQuantityOfProduct(int quantityOfProduct) { + QuantityOfProduct = quantityOfProduct; + } + public HashMap getP() { + return P; + } + public int getNumberOfProduct() { + return NumberOfProduct; + } + public String getNameOfProduct() { + return NameOfProduct; + } + public void printInfo() { + System.out.println("Product{"+"id:" +getNumberOfProduct()+" "+"Name:"+ getNameOfProduct()+" "+"P:" +getP() +"}"); + } + + public String toCSV() { + StringBuilder sb = new StringBuilder(); + sb.append(NumberOfProduct).append(","); + sb.append(NameOfProduct).append(","); + sb.append(QuantityOfProduct).append(","); + + if (P != null && !P.isEmpty()) { + for (Map.Entry entry : P.entrySet()) { + sb.append(entry.getKey().getNameOfItem()) + .append(":") + .append(entry.getValue()) + .append(";"); + } + } + + return sb.toString(); + } + + + @Override + public String toString() { + return NameOfProduct ; + } + + + + + public String printMaterials() { + StringBuilder stringBuilder = new StringBuilder(); + for (Map.Entry entry : getP().entrySet()) { + Item item = entry.getKey(); + int quantity = entry.getValue(); + stringBuilder.append(item.getNameOfItem()) + .append(":") + .append(quantity) + .append(";"); + } + return stringBuilder.toString(); + } +} \ No newline at end of file diff --git a/src/ProductLine.csv b/src/ProductLine.csv new file mode 100644 index 0000000..434f97b --- /dev/null +++ b/src/ProductLine.csv @@ -0,0 +1,6 @@ +lineId,lineName,status +1,a,Active +2,b,Active +3,c,Active +4,hjbjfr,Stopped +5,dkujbjhr,Active diff --git a/src/ProductLine.java b/src/ProductLine.java new file mode 100644 index 0000000..e5d1f4d --- /dev/null +++ b/src/ProductLine.java @@ -0,0 +1,141 @@ +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; + +public class ProductLine implements Runnable { + static int id=0; + private int lineId; + private String lineName; + private Invantory inventory = Invantory.getInstance(); + + + public ProductLine(int id, String name) { + this.lineId = id; + this.lineName = name; + this.status = Ex.Active; + + if (id > ProductLine.id) { + ProductLine.id = id; + } + } + + + enum Ex {Active, Stopped, Under_Maintenance} + Ex status ; + + ArrayList t = new ArrayList<>(); + static ArrayListallTheTask=new ArrayList<>(); + static HashMap productTotals = new HashMap<>(); + float The_Proportion_Of_Production = 0.0f; + + private boolean isRunning = true; + private Task currentTask = null; + + +public ProductLine(String lineName) { + this.lineId = ++id; + this.lineName = lineName; + this.status = Ex.Active; + this.inventory = Invantory.getInstance(); +} + + +public synchronized void addTask(Task task) { + this.t.add(task); + this.currentTask = task; + notifyAll(); +} + +@Override +public void run() { + try { + while (true) { + Thread.sleep(100); + + + if (this.currentTask != null) { + Thread b=new Thread(currentTask); + b.start(); + + currentTask.setenum("INPROGRESS"); + for (int i = 1; i <= currentTask.getAmount(); i++) { + Thread.sleep(500); + + currentTask.setFinishedAmount(i); + + System.out.println("النسبة الآن: " + currentTask.getPercentAge()); + } + + CSV.writeAllTasks(Invantory.getInstance().tasks); + this.currentTask = null; + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } +} + + public void setCurrentTask(Task task) { + this.currentTask = task; + } + void calculateTotalProduction() { + + for (Task k : t) { + int productId = k.getPro().getNumberOfProduct(); + int amount = k.getAmount(); + productTotals.put(productId, productTotals.getOrDefault(productId, 0) + amount); + } + } + + +void The_Proportion_Of_Productiones() { + double totalProduced = 0; + double totalRequested = 0; + + for (Task task : t) { + totalProduced += task.getFinishedAmount(); + totalRequested += task.getAmount(); + } + + if (totalRequested > 0) { + The_Proportion_Of_Production = (float)((totalProduced * 100.0) / totalRequested); + } else { + The_Proportion_Of_Production = 0.0f; + } +} + + public void shutdownLine() { + this.isRunning = false; + synchronized (this) { + notifyAll(); + } + } + +void setEnum(String e) { + status = Ex.valueOf(e.replace(" ", "_")); +} + + public Ex getStatus() { return status; } + public String getLineName() { return lineName; } + public int getLineId() { return lineId; } + + public void totoString() { + System.out.println("ProductLine{" + + "id=" + lineId + + ", name='" + lineName + '\'' + + ", status=" + status + + ", productionShare=" + The_Proportion_Of_Production + "%" + + '}'); + } +public void setStatus(String status) { + this.status = Ex.valueOf(status.replace(" ", "_")); +} + + + @Override + public String toString() { + return lineId + "," + lineName + "," + status; + } + + +} \ No newline at end of file diff --git a/src/ProductLineManager.java b/src/ProductLineManager.java new file mode 100644 index 0000000..8ade6e2 --- /dev/null +++ b/src/ProductLineManager.java @@ -0,0 +1,90 @@ +import java.time.LocalDate; +import java.util.*; +import java.util.stream.Collectors; +public class ProductLineManager { + Invantory r=Invantory.getInstance(); + void addTask(int number, Product pro, int amount, String customer, LocalDate startDate){ + Task k=new Task( number, pro, amount, customer, startDate); + r.tasks.add(k); + + } + void cancelTask(Task km){ + km.setenum("cancelled"); + } + void display(ProductLine k ){ + for (Task l : k.t) { + l.printInfo(); + } + } + void displayTasks(Product s){ + for (Task b: r.tasks){ + if(b.getPro()==s){ + b.printInfo(); + } + } + } + void aVoidProductLine(Product s){ + for (ProductLine f:r.productesLine) + { + for (Task v:f.t){ + if (v.getPro()==s) + { + System.out.println( f.getLineName()); + break; + } + } + } + } + void taskstatuscancelled() { + System.out.println(r.tasks.stream() + .filter(i -> i != null && i.getK() != null) + .filter(i -> i.getK() == Task.Ex.CANCELLED) + .collect(Collectors.toList())); + } + void displayproductbelongtosbecificproductline(ProductLine k ){ + if (k.productTotals == null || k.productTotals.isEmpty()) { + System.out.println(" No products have been registered yet"); + return; + } + for (Map.Entryn:k.productTotals.entrySet()){ + Product kkk= r.searchAboutProductById(n.getKey()); + kkk.printInfo(); + + } + } + void printalltheproductsofallproductline(){ + for (ProductLine k : r.productesLine){ + for (Map.Entryn:k.productTotals.entrySet()){ + Product kkk= r.searchAboutProductById(n.getKey()); + kkk.printInfo(); + + } + } + } + void prntthemostpopularproduct(LocalDate start, LocalDate end) { + System.out.println("The most requested product:"); + Map count = new HashMap<>(); + for (Task task : r.tasks) { + if (task.getStartDate() != null && task.getExecutionDate() != null) { + if (!task.getStartDate().isBefore(start) && + !task.getExecutionDate().isAfter(end)) { + String name = task.getPro().getNameOfProduct(); + count.put(name, count.getOrDefault(name, 0) + 1); + } + } + } + String topProduct = null; + int max = 0; + for (Map.Entry entry : count.entrySet()) { + if (entry.getValue() > max) { + max = entry.getValue(); + topProduct = entry.getKey(); + } + } + if (topProduct != null) { + System.out.println(" " + topProduct + " (" + max + ")"); + } else { + System.out.println(" There aren't tasks"); + } + } +} \ No newline at end of file diff --git a/src/ProductionLinesManagementFrame.java b/src/ProductionLinesManagementFrame.java new file mode 100644 index 0000000..68b33cd --- /dev/null +++ b/src/ProductionLinesManagementFrame.java @@ -0,0 +1,561 @@ +import javax.swing.*; +import javax.swing.border.BevelBorder; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.time.LocalDate; + +public class ProductionLinesManagementFrame extends JFrame { + + private final Color fancyOrange = new Color(255, 140, 0); // اللون البرتقالي الأساسي + private final Color lightOrange = new Color(255, 220, 180); // خلفية الصفوف المتبادلة + private final Color babyOrange = new Color(255, 235, 200); // خلفية الواجهة + + private JTable table; + private DefaultTableModel tableModel; + + private String searchText = ""; + private int searchColumn = -1; + + public ProductionLinesManagementFrame() { + + setTitle("Production Lines Management"); + Task.currentUI = this; + + setSize(1300, 750); + setExtendedState(JFrame.MAXIMIZED_BOTH); + setDefaultCloseOperation(EXIT_ON_CLOSE); + setLocationRelativeTo(null); + setLayout(new BorderLayout()); + getContentPane().setBackground(babyOrange); + + JLabel title = new JLabel("Production Lines Management", SwingConstants.CENTER); + title.setFont(new Font("Verdana", Font.BOLD, 34)); + title.setForeground(fancyOrange); + title.setBorder(BorderFactory.createEmptyBorder(20, 0, 20, 0)); + add(title, BorderLayout.NORTH); + + JPanel centerPanel = new JPanel(new BorderLayout()); + centerPanel.setBackground(babyOrange); + add(centerPanel, BorderLayout.CENTER); + + // 🟧 لوحة الأزرار على اليمين + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS)); + buttonsPanel.setBackground(babyOrange); + buttonsPanel.setBorder( + BorderFactory.createCompoundBorder( + BorderFactory.createMatteBorder(0, 2, 0, 0, fancyOrange), + BorderFactory.createEmptyBorder(20, 20, 20, 20) + ) + ); + + Dimension btnSize = new Dimension(320, 58); + + JButton addTaskBtn = createButton("Add Task", btnSize); + addTaskBtn.addActionListener(e -> addNewTask()); + + JButton editTaskBtn = createButton("Edit Task", btnSize); + JButton cancelTaskBtn = createButton("Cancel Task", btnSize); + JButton productsByLineBtn = createButton("Products by Line", btnSize); + JButton linesByProductBtn = createButton("Line by Product", btnSize); + + JButton mostRequestedBtn = createButton("Most Requested Product", btnSize); + + + JButton backBtn = createButton("Back", btnSize); + backBtn.addActionListener(e -> { + new SupervisorMenuFrame(); + dispose(); + }); + + buttonsPanel.add(addTaskBtn); buttonsPanel.add(Box.createVerticalStrut(10)); + buttonsPanel.add(editTaskBtn); editTaskBtn.addActionListener(e -> editTask()); buttonsPanel.add(Box.createVerticalStrut(10)); + buttonsPanel.add(cancelTaskBtn); cancelTaskBtn.addActionListener(e -> cancelTask()); buttonsPanel.add(Box.createVerticalStrut(20)); + buttonsPanel.add(productsByLineBtn); productsByLineBtn.addActionListener(e -> filterTasksByLine()); buttonsPanel.add(Box.createVerticalStrut(10)); + buttonsPanel.add(linesByProductBtn); linesByProductBtn.addActionListener(e -> filterTasksByProduct()); buttonsPanel.add(Box.createVerticalStrut(20)); + + buttonsPanel.add(mostRequestedBtn); buttonsPanel.add(Box.createVerticalStrut(10)); + buttonsPanel.add(backBtn); + + // 🔹 أضف لوحة الأزرار على اليمين + centerPanel.add(buttonsPanel, BorderLayout.EAST); + + // 🔹 لوحة البحث + JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + searchPanel.setBackground(babyOrange); + searchPanel.setBorder(BorderFactory.createTitledBorder("Search ")); + + JComboBox filterBox = new JComboBox<>(new String[]{ "tasks by product","tasks by line "}); + JTextField searchField = new JTextField(15); + JButton searchBtn = createButton("Search", new Dimension(120, 35)); + searchBtn.addActionListener(e -> { + searchText = searchField.getText().trim(); + searchColumn = filterBox.getSelectedIndex() + 1; + table.clearSelection(); + table.repaint(); + }); + + JButton showAllBtn = createButton("Show All Tasks", new Dimension(180, 35)); + showAllBtn.setBackground(new Color(255, 180, 100)); + showAllBtn.addActionListener(e -> loadTasksTable()); + + searchPanel.add(new JLabel("Search by:")); + searchPanel.add(filterBox); + searchPanel.add(searchField); + searchPanel.add(searchBtn); + searchPanel.add(showAllBtn); + + centerPanel.add(searchPanel, BorderLayout.NORTH); + + // 🔹 جدول البيانات على اليسار + String[] columns = {"Task ID", "Production Line", "Product", "Amount", "Customer", "Start Date", "Status"}; + tableModel = new DefaultTableModel(columns, 0); + + table = new JTable(tableModel); + table.setRowHeight(30); + table.setFont(new Font("Arial", Font.PLAIN, 15)); + table.setSelectionBackground(fancyOrange); + + table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { + Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + if (!isSelected) { + if (!searchText.isEmpty() && searchColumn != -1) { + Object cellValue = table.getValueAt(row, searchColumn); + if (cellValue != null && cellValue.toString().toLowerCase().contains(searchText.toLowerCase())) { + c.setBackground(fancyOrange); + c.setForeground(Color.WHITE); + return c; + } + } + c.setBackground(row % 2 == 0 ? Color.WHITE : lightOrange); + c.setForeground(Color.BLACK); + } + return c; + } + }); + + JScrollPane scrollPane = new JScrollPane(table); + scrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(fancyOrange, 2), "Production Tasks")); + centerPanel.add(scrollPane, BorderLayout.CENTER); + + Invantory.loadInventory(); + loadTasksTable(); + setVisible(true); + } + + private JButton createButton(String text, Dimension size) { + JButton btn = new JButton(text); + btn.setPreferredSize(size); + btn.setMinimumSize(size); + btn.setMaximumSize(size); + btn.setFont(new Font("Arial", Font.BOLD, 16)); + btn.setBackground(fancyOrange); + btn.setForeground(Color.WHITE); + btn.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED)); + btn.setFocusPainted(false); + btn.setAlignmentX(Component.CENTER_ALIGNMENT); + return btn; + } + + // ⚡ جميع دوال إضافة، تعديل، إلغاء، تصفية... تبقى كما هي تماماً + // loadTasksTable(), addNewTask(), cancelTask(), editTask(), filterTasksByLine(), filterTasksByProduct(), viewProductsByLine(), viewLinesByProduct(), refreshTableData() + // ... يمكنك نسخها كما هي من الكود السابق بدون أي تعديل. + + + + +private void loadTasksTable() { + Invantory inv = Invantory.getInstance(); + + tableModel.setRowCount(0); + + for (Task task : inv.tasks) { + String productName = (task.getPro() != null) ? task.getPro().getNameOfProduct() : "Unknown"; + String lineName = (task.getLineName() != null) ? task.getLineName() : "No Line"; + + String status = (task.getK() != null) ? task.getK().toString() : "INPROGRESS"; + + + tableModel.addRow(new Object[]{ + task.getNumber(), + lineName, + productName, + task.getAmount(), + task.getCustomer(), + task.getStartDate(), + status, + String.format("%.1f%%", task.getPercentAge()) // 👈 جلب النسبة من كائن Task + }); + } +} + + + +private void addNewTask() { + Invantory inv = Invantory.getInstance(); + + JComboBox productBox = new JComboBox<>(); + for (Product p : inv.general_products.values()) productBox.addItem(p); + + JComboBox lineBox = new JComboBox<>(); + for (ProductLine line : inv.getProductLines()) lineBox.addItem(line.getLineName()); + + JTextField amountField = new JTextField(); + JTextField customerField = new JTextField(); + JTextField startDateField = new JTextField(LocalDate.now().toString()); + + JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5)); + panel.add(new JLabel("Product:")); panel.add(productBox); + panel.add(new JLabel("Amount:")); panel.add(amountField); + panel.add(new JLabel("Customer Name:")); panel.add(customerField); + panel.add(new JLabel("Start Date (YYYY-MM-DD):")); panel.add(startDateField); + panel.add(new JLabel("Production Line:")); panel.add(lineBox); + + int result = JOptionPane.showConfirmDialog(this, panel, "Add New Task", JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + try { + Product selectedProduct = (Product) productBox.getSelectedItem(); + String lineName = (String) lineBox.getSelectedItem(); + ProductLine selectedLine = inv.getProductLineByName(lineName); + int amount = Integer.parseInt(amountField.getText()); + String customer = customerField.getText(); + LocalDate startDate = LocalDate.parse(startDateField.getText()); + + int taskNumber = inv.getNextTaskNumber(); + Task task = new Task(taskNumber, selectedProduct, amount, customer, startDate); + + + task.login(selectedLine); + + if (!inv.tasks.contains(task)) { + inv.tasks.add(task); + } + + CSV.writeAllTasks(inv.tasks); + + + if (selectedLine != null) { + selectedLine.setCurrentTask(task); + } + + loadTasksTable(); + + JOptionPane.showMessageDialog(this, "Task #" + taskNumber + " added and production started!"); + + } catch (Exception ex) { + JOptionPane.showMessageDialog(this, "Error: " + ex.getMessage()); + ex.printStackTrace(); + } + } +} + private void cancelTask() { + int row = table.getSelectedRow(); + + if (row == -1) { + JOptionPane.showMessageDialog(this, "Please select a task from the table first."); + return; + } + + int confirm = JOptionPane.showConfirmDialog(this, + "Are you sure you want to cancel this task?", + "Confirm Cancellation", + JOptionPane.YES_NO_OPTION); + + if (confirm == JOptionPane.YES_OPTION) { + Invantory inv = Invantory.getInstance(); + + int taskId = (int) tableModel.getValueAt(row, 0); + + boolean found = false; + for (Task t : inv.tasks) { + if (t.getNumber() == taskId) { + t.setenum("CANCELLED"); + found = true; + break; + } + } + + if (found) { + CSV.writeAllTasks(inv.tasks); + + int statusColumn = tableModel.getColumnCount() - 1; + tableModel.setValueAt("CANCELLED", row, statusColumn); + + JOptionPane.showMessageDialog(this, "Task #" + taskId + " has been cancelled."); + } else { + JOptionPane.showMessageDialog(this, "Error: Task not found in memory."); + } + } + } + private void editTask() { + int row = table.getSelectedRow(); + + if (row == -1) { + JOptionPane.showMessageDialog(this, "Please select a task to edit."); + return; + } + + Invantory inv = Invantory.getInstance(); + int taskId = (int) tableModel.getValueAt(row, 0); + + Task taskToEdit = null; + for (Task t : inv.tasks) { + if (t.getNumber() == taskId) { + taskToEdit = t; + break; + } + } + + if (taskToEdit == null) return; + + JTextField customerField = new JTextField(taskToEdit.getCustomer()); + JTextField amountField = new JTextField(String.valueOf(taskToEdit.getAmount())); + + JComboBox productBox = new JComboBox<>(); + for (Product p : inv.general_products.values()) { + productBox.addItem(p); + if (p.getNameOfProduct().equals(taskToEdit.getPro().getNameOfProduct())) { + productBox.setSelectedItem(p); + } + } + + JComboBox lineBox = new JComboBox<>(); + for (ProductLine line : inv.getProductLines()) { + lineBox.addItem(line.getLineName()); + if (line.getLineName().equals(taskToEdit.getLineName())) { + lineBox.setSelectedItem(line.getLineName()); + } + } + + JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5)); + panel.add(new JLabel("Customer Name:")); + panel.add(customerField); + panel.add(new JLabel("Amount:")); + panel.add(amountField); + panel.add(new JLabel("Product:")); + panel.add(productBox); + panel.add(new JLabel("Production Line:")); + panel.add(lineBox); + + int result = JOptionPane.showConfirmDialog(this, panel, "Edit Task #" + taskId, JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + try { + taskToEdit.setCustomer(customerField.getText().trim()); + taskToEdit.setAmount(Integer.parseInt(amountField.getText().trim())); + taskToEdit.setPro((Product) productBox.getSelectedItem()); + + String newLineName = (String) lineBox.getSelectedItem(); + ProductLine newLine = inv.getProductLineByName(newLineName); + taskToEdit.login(newLine); + + CSV.writeAllTasks(inv.tasks); + + loadTasksTable(); + + JOptionPane.showMessageDialog(this, "Task #" + taskId + " updated successfully!"); + + } catch (NumberFormatException ex) { + JOptionPane.showMessageDialog(this, "Invalid Amount. Please enter a number."); + } catch (Exception ex) { + JOptionPane.showMessageDialog(this, "Error: " + ex.getMessage()); + } + } + } + private void filterTasksByLine() { + Invantory inv = Invantory.getInstance(); + + JComboBox lineBox = new JComboBox<>(); + for (ProductLine line : inv.getProductLines()) { + lineBox.addItem(line.getLineName()); + } + + int result = JOptionPane.showConfirmDialog(this, lineBox, + "Select Production Line to Filter", JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + String selectedLine = (String) lineBox.getSelectedItem(); + + tableModel.setRowCount(0); + + boolean found = false; + for (Task task : inv.tasks) { + if (task.getLineName() != null && task.getLineName().equalsIgnoreCase(selectedLine)) { + + String productName = (task.getPro() != null) ? task.getPro().getNameOfProduct() : "Unknown"; + String status = (task.getK() != null) ? task.getK().toString() : "INPROGRESS"; + + tableModel.addRow(new Object[]{ + task.getNumber(), + task.getLineName(), + productName, + task.getAmount(), + task.getCustomer(), + task.getStartDate(), + task.getExecutionDate(), + status + }); + found = true; + } + } + + if (!found) { + JOptionPane.showMessageDialog(this, "No tasks found for production line: " + selectedLine); + loadTasksTable(); + } + } + } + private void filterTasksByProduct() { + Invantory inv = Invantory.getInstance(); + + JComboBox productBox = new JComboBox<>(); + for (Product p : inv.general_products.values()) { + productBox.addItem(p.getNameOfProduct()); + } + + int result = JOptionPane.showConfirmDialog(this, productBox, + "Filter by Product", JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + String selectedProductName = (String) productBox.getSelectedItem(); + + tableModel.setRowCount(0); + + boolean found = false; + for (Task task : inv.tasks) { + if (task.getPro() != null && task.getPro().getNameOfProduct().equalsIgnoreCase(selectedProductName)) { + + String lineName = (task.getLineName() != null) ? task.getLineName() : "No Line"; + String status = (task.getK() != null) ? task.getK().toString() : "INPROGRESS"; + + tableModel.addRow(new Object[]{ + task.getNumber(), + lineName, + task.getPro().getNameOfProduct(), + task.getAmount(), + task.getCustomer(), + task.getStartDate(), + task.getExecutionDate(), + status + }); + found = true; + } + } + + if (!found) { + JOptionPane.showMessageDialog(this, "No tasks found for product: " + selectedProductName); + loadTasksTable(); + } + } + } + private void viewProductsByLine() { + Invantory inv = Invantory.getInstance(); + + JComboBox lineBox = new JComboBox<>(); + for (ProductLine line : inv.getProductLines()) { + lineBox.addItem(line.getLineName()); + } + + int result = JOptionPane.showConfirmDialog(this, lineBox, + "Select Line to View its Products", JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + String selectedLine = (String) lineBox.getSelectedItem(); + + tableModel.setRowCount(0); + + java.util.HashSet displayedSet = new java.util.HashSet<>(); + + boolean found = false; + for (Task task : inv.tasks) { + if (task.getLineName() != null && task.getLineName().equalsIgnoreCase(selectedLine)) { + + int productId = (task.getPro() != null) ? task.getPro().getNumberOfProduct() : -1; + String productName = (task.getPro() != null) ? task.getPro().getNameOfProduct() : "Unknown"; + String customerName = (task.getCustomer() != null) ? task.getCustomer() : "No Customer"; + + String uniqueKey = productId + "-" + customerName; + + if (!displayedSet.contains(uniqueKey)) { + tableModel.addRow(new Object[]{ + productId, + selectedLine, + productName, + task.getAmount(), + customerName, + task.getStartDate(), + task.getExecutionDate() != null ? task.getExecutionDate() : "—" + }); + displayedSet.add(uniqueKey); + found = true; + } + } + } + + if (!found) { + JOptionPane.showMessageDialog(this, "No products or users found for this line."); + loadTasksTable(); + } + } + } + private void viewLinesByProduct() { + Invantory inv = Invantory.getInstance(); + + JComboBox productBox = new JComboBox<>(); + for (Product p : inv.general_products.values()) { + productBox.addItem(p.getNameOfProduct()); + } + + int result = JOptionPane.showConfirmDialog(this, productBox, + "Select Product to View its Lines", JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + String selectedProduct = (String) productBox.getSelectedItem(); + + tableModel.setRowCount(0); + + java.util.HashSet displayedSet = new java.util.HashSet<>(); + + boolean found = false; + for (Task task : inv.tasks) { + if (task.getPro() != null && task.getPro().getNameOfProduct().equalsIgnoreCase(selectedProduct)) { + + String lineName = (task.getLineName() != null) ? task.getLineName() : "No Line"; + int productId = task.getPro().getNumberOfProduct(); + String customerName = (task.getCustomer() != null) ? task.getCustomer() : "Unknown"; + + String uniqueKey = lineName + "-" + customerName; + + if (!displayedSet.contains(uniqueKey)) { + tableModel.addRow(new Object[]{ + productId, + lineName, + selectedProduct, + task.getAmount(), + customerName, + task.getStartDate(), + task.getK() + }); + displayedSet.add(uniqueKey); + found = true; + } + } + } + + if (!found) { + JOptionPane.showMessageDialog(this, "No production lines are currently assigned to: " + selectedProduct); + loadTasksTable(); + } + } + } + + public void refreshTableData() { + SwingUtilities.invokeLater(() -> { + loadTasksTable(); + }); + } +} \ No newline at end of file diff --git a/src/SplashScreen.java b/src/SplashScreen.java new file mode 100644 index 0000000..ee51f56 --- /dev/null +++ b/src/SplashScreen.java @@ -0,0 +1,124 @@ +import javax.swing.*; +import java.awt.*; + +public class SplashScreen extends JFrame { + + private JProgressBar progressBar; + private Image backgroundImage; + + private static final String BACKGROUND_IMAGE_PATH = + "photo_2026-01-25_11-44-58.jpg"; + + public SplashScreen() { + setTitle("alsb3"); + + setUndecorated(true); + setExtendedState(JFrame.MAXIMIZED_BOTH); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + backgroundImage = new ImageIcon(BACKGROUND_IMAGE_PATH).getImage(); + + JPanel mainPanel = new JPanel() { + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g; + + g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + // رسم الخلفية + if (backgroundImage != null) { + g2.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), this); + } + + // ====== العنوان ====== + String text = "alsb3"; + Font font = new Font("Serif", Font.BOLD, 150); + g2.setFont(font); + + FontMetrics fm = g2.getFontMetrics(); + int x = (getWidth() - fm.stringWidth(text)) / 2; + int y = (getHeight() / 2) - 100; // مرفوع لفوق + + // ظل ناعم + g2.setColor(new Color(40, 40, 45, 170)); + g2.drawString(text, x + 6, y + 6); + + g2.setColor(new Color(90, 95, 105, 140)); + g2.drawString(text, x + 3, y + 3); + + // النص الأساسي + g2.setColor(new Color(190, 190, 190, 220)); + g2.drawString(text, x, y); + + g2.setColor(new Color(220, 220, 220, 100)); + g2.drawString(text, x - 2, y - 2); + + // ====== وضع شريط التحميل تحت العنوان ====== + progressBar.setBounds( + (getWidth() - 450) / 2, + y + 40, + 450, + 20 + ); + } + }; + + mainPanel.setLayout(null); + + // ====== شريط التحميل ====== + progressBar = new JProgressBar(0, 100); + progressBar.setForeground(new Color(255, 215, 0)); // أصفر + progressBar.setBackground(new Color(40, 45, 55)); + progressBar.setBorderPainted(false); + progressBar.setStringPainted(false); + + mainPanel.add(progressBar); + add(mainPanel); + + setVisible(true); + + startLoading(); + } + + private void startLoading() { + SwingWorker worker = + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + + Invantory inv = Invantory.getInstance(); + + for (ProductLine pl : inv.getProductLines()) { + Thread t = new Thread(pl); + t.start(); + System.out.println("✅ Engine Started: " + pl.getLineName()); + } + + for (int i = 0; i <= 100; i++) { + Thread.sleep(30); + publish(i); + } + return null; + } + + @Override + protected void process(java.util.List chunks) { + progressBar.setValue(chunks.get(chunks.size() - 1)); + } + + @Override + protected void done() { + SwingUtilities.invokeLater(() -> { + new LoginFrame().setVisible(true); + }); + dispose(); + } + }; + + worker.execute(); + } +} diff --git a/src/SupervisorMenuFrame.java b/src/SupervisorMenuFrame.java new file mode 100644 index 0000000..d861a4e --- /dev/null +++ b/src/SupervisorMenuFrame.java @@ -0,0 +1,136 @@ +import javax.swing.*; +import javax.swing.border.BevelBorder; +import java.awt.*; + +public class SupervisorMenuFrame extends JFrame { + + private final Color primaryOrange = new Color(255, 140, 0); + private final Color darkOrange = new Color(230, 120, 0); + private final Color softYellow = new Color(255, 230, 150); + private final Color backgroundColor = new Color(255, 248, 220); + + public SupervisorMenuFrame() { + + setTitle("alsb3– Production Supervisoment"); + setExtendedState(JFrame.MAXIMIZED_BOTH); // Full Screen + setDefaultCloseOperation(EXIT_ON_CLOSE); + setLayout(new BorderLayout()); + setLocationRelativeTo(null); + + BackgroundPanel backgroundPanel = + new BackgroundPanel("C:\\Users\\HP\\Desktop\\محاضرات\\خوارزميات\\عملي\\محاضرات المعيدة\\photo_2026-01-25_12-00-37.jpg"); // إزالة الصورة، أو ضع مسار خلفية برتقالي فاتح + backgroundPanel.setLayout(new BorderLayout()); + backgroundPanel.setBackground(backgroundColor); + setContentPane(backgroundPanel); + + JLabel titleLabel = new JLabel("alsb3 – Production Supervisoment", SwingConstants.CENTER); + titleLabel.setFont(new Font("SansSerif", Font.BOLD, 36)); + titleLabel.setForeground(primaryOrange); + titleLabel.setBorder(BorderFactory.createEmptyBorder(30, 0, 30, 0)); + titleLabel.setOpaque(true); + titleLabel.setBackground(softYellow); + backgroundPanel.add(titleLabel, BorderLayout.NORTH); + + JPanel centerPanel = new JPanel(new GridBagLayout()); + centerPanel.setOpaque(false); + backgroundPanel.add(centerPanel, BorderLayout.CENTER); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.insets = new Insets(20, 20, 20, 20); + gbc.fill = GridBagConstraints.HORIZONTAL; + + Dimension btnSize = new Dimension(420, 70); + + JLabel sectionTitle = new JLabel("Select Supervisor Operation", SwingConstants.CENTER); + sectionTitle.setFont(new Font("SansSerif", Font.BOLD, 24)); + sectionTitle.setForeground(primaryOrange); + sectionTitle.setOpaque(true); + sectionTitle.setBackground(softYellow); + sectionTitle.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20)); + + JButton inventoryBtn = createButton("Inventory Management", btnSize); + JButton productionBtn = createButton("Production Lines Management", btnSize); + JButton backBtn = createButton("Back", btnSize); + + gbc.gridx = 0; + gbc.gridy = 0; + centerPanel.add(sectionTitle, gbc); + + gbc.gridy++; + centerPanel.add(inventoryBtn, gbc); + + gbc.gridy++; + centerPanel.add(productionBtn, gbc); + + gbc.gridy++; + centerPanel.add(backBtn, gbc); + + inventoryBtn.addActionListener(e -> { + new InventoryManagementFrame(); + dispose(); + }); + + productionBtn.addActionListener(e -> { + new ProductionLinesManagementFrame(); + dispose(); + }); + + backBtn.addActionListener(e -> { + new LoginFrame(); + dispose(); + }); + + setVisible(true); + } + + private JButton createButton(String text, Dimension size) { + JButton btn = new JButton(text) { + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(getModel().isPressed() ? darkOrange : primaryOrange); + g2.fillRoundRect(0, 0, getWidth(), getHeight(), 30, 30); + + super.paintComponent(g); + g2.dispose(); + } + + protected void paintBorder(Graphics g) { + g.setColor(darkOrange); + ((Graphics2D) g).drawRoundRect(0, 0, + getWidth() - 1, getHeight() - 1, 30, 30); + } + }; + + btn.setPreferredSize(size); + btn.setMaximumSize(size); + btn.setMinimumSize(size); + btn.setContentAreaFilled(false); + btn.setFocusPainted(false); + btn.setForeground(Color.WHITE); + btn.setFont(new Font("SansSerif", Font.BOLD, 20)); + btn.setAlignmentX(Component.CENTER_ALIGNMENT); + + return btn; + } + + static class BackgroundPanel extends JPanel { + private Image background; + + public BackgroundPanel(String path) { + if (!path.isEmpty()) { + background = new ImageIcon(path).getImage(); + } + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + if (background != null) { + g.drawImage(background, 0, 0, getWidth(), getHeight(), this); + } + } + } +} diff --git a/src/Task.csv b/src/Task.csv new file mode 100644 index 0000000..93ce2ad --- /dev/null +++ b/src/Task.csv @@ -0,0 +1,6 @@ +number,NameOfProduct,LineName,Amount,Customer,StartDate,ExecutionDate,Status,FinishedAmount,PercentAge +1,jj,masa,1,jojo,2026-01-24,,INPROGRESS,0,0.0 +2,jj,ggg,1,jjj,2026-01-24,,INPROGRESS,0,0.0 +3,jj,maaaaai,5454,مجد,2026-01-25,,CANCELLED,0,0.0 +4,jj,b,78,nfg,2026-01-25,,INPROGRESS,0,0.0 +5,jj,c,98,alaa,2026-01-25,,INPROGRESS,0,0.0 diff --git a/src/Task.java b/src/Task.java new file mode 100644 index 0000000..caee047 --- /dev/null +++ b/src/Task.java @@ -0,0 +1,255 @@ + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Map; +public class Task implements Runnable { + private int number; + public static ProductionLinesManagementFrame currentUI; + Product pro; + ProductLine dd; + int Amount; + String Customer; + LocalDate StartDate; + LocalDate ExecutionDate; + Invantory i = Invantory.getInstance(); + Ex k; + int finishedAmount; + double percentAge; + + public void setLineName(String lineName) { + this.lineName = lineName; + } + + public String getLineName() { + return lineName; + } + + enum Ex {INPROGRESS, COMPLETE, CANCELLED} + private String lineName; + + + public void login(ProductLine line) { + this.dd = line; + this.lineName = (line != null) ? line.getLineName() : "NoLine"; + } + public Task(int number, Product pro, int amount, String customer, LocalDate startDate) { + this.number = number; + this.pro = pro; + this.Amount = amount; + this.Customer = customer; + this.StartDate = startDate; + this.setenum("INPROGRESS"); + } + + public Task(int number, String proName, String lineName, int amount, String customer, + LocalDate startDate, LocalDate executionDate, String status, float percentAge) { + this.number = number; + this.Amount = amount; + this.Customer = customer; + this.StartDate = startDate; + this.ExecutionDate = executionDate; + this.percentAge = percentAge; + try { + Product foundProduct = i.searchAboutProductByname(proName); + if (foundProduct != null) { + this.pro = foundProduct; + } + } catch (NullPointerException e){ + System.out.println("not found"); + ErrorLogger.logError("not found"); + } + + if (status != null && !status.isEmpty()) { + this.setenum(status); + } else { + this.setenum("INPROGRESS"); + } + + i.tasks.add(this); + } + + public void setenum(String e) { + try { + k = Ex.valueOf(e.toUpperCase()); + } catch (IllegalArgumentException ex) { + k = Ex.INPROGRESS; + } + } + + public Ex getK() { + return k; + } + + public void printInfo() { + System.out.println("📋 معلومات المهمة #" + number + ":"); + System.out.println(" المنتج: " + (pro != null ? pro.getNameOfProduct() : "غير محدد")); + System.out.println(" الكمية: " + Amount); + System.out.println(" العميل: " + Customer); + System.out.println(" تاريخ البدء: " + StartDate); + System.out.println(" تاريخ الانتهاء: " + (ExecutionDate != null ? ExecutionDate : "قيد التنفيذ")); + System.out.println(" الحالة: " + (k != null ? k.toString() : "INPROGRESS")); + System.out.println(" الكمية المنتجة: " + finishedAmount + "/" + Amount); + System.out.println(" النسبة: " + percentAge + "%"); + } + + public void printSimpleInfo() { + System.out.println("Task #" + number + + " - Product: " + (pro != null ? pro.getNameOfProduct() : "N/A") + + " - Amount: " + Amount + + " - Status: " + (k != null ? k : "INPROGRESS")); + } + + + + public void productlineinformation() { + if (dd != null) { + System.out.println("productLine: " + dd.getLineName() + + " (ID: " + dd.getLineId() + + ", status: " + dd.getStatus() + ")"); + } else { + ErrorLogger.logError("The task is not assigned to a production line"); + } + } + + + public int getNumber() { return number; } + public void setNumber(int number) { this.number = number; } + + public Product getPro() { return pro; } + public void setPro(Product pro) { this.pro = pro; } + + public ProductLine getDd() { return dd; } + + public int getAmount() { return Amount; } + public void setAmount(int amount) { Amount = amount; } + + public String getCustomer() { return Customer; } + public void setCustomer(String customer) { Customer = customer; } + + public LocalDate getStartDate() { return StartDate; } + public void setStartDate(LocalDate startDate) { StartDate = startDate; } + + public LocalDate getExecutionDate() { return ExecutionDate; } + public void setExecutionDate(LocalDate executionDate) { ExecutionDate = executionDate; } + + public int getFinishedAmount() { return finishedAmount; } + public double getPercentAge() { return percentAge; } + + + +@Override +public void run() { + + setenum("INPROGRESS"); + try { + if (i.Check(pro, Amount)) { + for (Map.Entry entry : pro.getP().entrySet()) { + i.decrease(entry.getKey().getIdOfItem(), entry.getValue() * Amount); + } + + int stepAmount = Amount / 10; + for (int f = 1; f <= 10; f++) { + if (this.k == Ex.CANCELLED) { + if (currentUI != null) currentUI.refreshTableData(); + return; + } + + Thread.sleep(1000); + + if (f < 10) { + i.IncreaseProduct(pro.getNumberOfProduct(), stepAmount); + finishedAmount = stepAmount * f; + } else { + int remaining = Amount - (stepAmount * 9); + i.IncreaseProduct(pro.getNumberOfProduct(), remaining); + finishedAmount = Amount; + } + percentAge = f * 10.0; + + if (currentUI != null) { + currentUI.refreshTableData(); + } + } + + setenum("COMPLETE"); + ExecutionDate = LocalDate.now(); + if (currentUI != null) currentUI.refreshTableData(); + + } else { + setenum("CANCELLED"); + if (currentUI != null) currentUI.refreshTableData(); + } + } catch (Exception e) { + setenum("CANCELLED"); + if (currentUI != null) currentUI.refreshTableData(); + } +} + public void showPercentAge() { + System.out.println("الكمية المنتجة: " + finishedAmount + "/" + Amount); + System.out.println("النسبة المئوية: " + percentAge + "%"); + } + + @Override + public String toString() { + String lineName = (dd != null) ? dd.getLineName() : "NoLine"; + String execDate = (ExecutionDate != null) ? ExecutionDate.toString() : ""; + String status = (k != null) ? k.toString() : "INPROGRESS"; + String productName = (pro != null) ? pro.getNameOfProduct() : "Unknown"; + + return number + "," + + productName + "," + + lineName + "," + + Amount + "," + + Customer + "," + + (StartDate != null ? StartDate.toString() : "") + "," + + execDate + "," + + status + "," + + finishedAmount + "," + + percentAge; + } + +public void setFinishedAmount(int finishedAmount) { + this.finishedAmount = finishedAmount; + + if (this.Amount > 0) { + this.percentAge = (finishedAmount * 100.0) / this.Amount; + } + + if (this.percentAge >= 100) { + this.percentAge = 100.0; + this.setenum("COMPLETED"); + this.ExecutionDate = java.time.LocalDate.now(); + } + + if (currentUI != null) { + currentUI.refreshTableData(); + } +} + + public static void loadInventory() { + try { + ArrayList loadedTasks = (ArrayList) CSV.readTask("C:\\Users\\victus\\Desktop\\Object-Oriented Programming JAVA in Arabic\\Factory\\src\\Task.csv"); + Invantory inv = Invantory.getInstance(); + + for (Task task : loadedTasks) { + boolean exists = false; + for (Task existing : inv.tasks) { + if (existing.getNumber() == task.getNumber()) { + exists = true; + break; + } + } + + if (!exists) { + inv.tasks.add(task); + } + } + + + } catch (Exception e) { + ErrorLogger.logError("Error loading tasks"); + } + } + + +} \ No newline at end of file diff --git a/src/errors.txt b/src/errors.txt new file mode 100644 index 0000000..64e5d22 --- /dev/null +++ b/src/errors.txt @@ -0,0 +1 @@ +Item DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nError reading Item.csv/nError reading Item.csv/nError reading Item.csv/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nError reading Item.csv/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nError reading Item.csv/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/nItem DDD not found/n \ No newline at end of file diff --git a/src/notes.csv b/src/notes.csv new file mode 100644 index 0000000..e69de29 diff --git a/swing in project 3.iml b/swing in project 3.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/swing in project 3.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file