comment desktop controllers
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the activity log screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the pet adoption management screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the analytics and reporting screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the appointment scheduling screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
@@ -132,6 +138,10 @@ public class AppointmentController {
|
||||
loadAppointments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches appointments from the API (filtered by store and optionally by employee)
|
||||
* and updates both the table and the calendar event dots.
|
||||
*/
|
||||
private void loadAppointments(){
|
||||
new Thread(() -> {
|
||||
try{
|
||||
@@ -165,6 +175,11 @@ public class AppointmentController {
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a server-side search query and replaces the local list with results.
|
||||
* Also refreshes calendar dots to match the filtered set.
|
||||
* @param text the search query text
|
||||
*/
|
||||
private void applyFilter(String text) {
|
||||
String query = text == null || text.trim().isEmpty() ? null : text.trim();
|
||||
new Thread(() -> {
|
||||
@@ -334,6 +349,10 @@ public class AppointmentController {
|
||||
return (selected != null && selected.getId() != null) ? selected.getId() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the client-side filters (calendar date selection and status dropdown)
|
||||
* on top of whatever the server already returned.
|
||||
*/
|
||||
private void applyFilterPredicate() {
|
||||
String selectedStatus = cbStatusFilter.getValue();
|
||||
filtered.setPredicate(apt -> {
|
||||
@@ -372,6 +391,12 @@ public class AppointmentController {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the status string from the API to title case for display.
|
||||
* Handles inconsistencies like "cancelled" vs "canceled".
|
||||
* @param status raw status from the server
|
||||
* @return normalized display string
|
||||
*/
|
||||
private String normalizeAppointmentStatus(String status) {
|
||||
if (status == null) {
|
||||
return "Booked";
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the in-app messaging screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
@@ -105,6 +111,8 @@ public class ChatController {
|
||||
lvActiveConversations.setItems(activeConversations);
|
||||
lvClosedConversations.setItems(closedConversations);
|
||||
|
||||
// The two lists share a single selection — picking one clears the other.
|
||||
// selectionChanging flag prevents the clear from triggering a feedback loop.
|
||||
lvActiveConversations.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal) -> {
|
||||
if (newVal != null && !selectionChanging) {
|
||||
selectionChanging = true;
|
||||
@@ -304,6 +312,11 @@ public class ChatController {
|
||||
btnAttachment.setStyle("-fx-background-color: #e2e8f0; -fx-background-radius: 12; -fx-text-fill: #475569; -fx-cursor: hand;");
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a conversation list with custom cells showing title, preview, and status.
|
||||
* Highlights conversations that need pickup or reply in red.
|
||||
* @param lv the ListView to configure
|
||||
*/
|
||||
private void setupConversationListView(ListView<ConversationResponse> lv) {
|
||||
lv.setFixedCellSize(CHAT_CELL_HEIGHT);
|
||||
lv.setCellFactory(list -> new ListCell<>() {
|
||||
@@ -453,6 +466,12 @@ public class ChatController {
|
||||
scrollMessagesToBottom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an incoming message from the WebSocket.
|
||||
* Only adds it to the view if it belongs to the currently selected conversation
|
||||
* and hasn't already been rendered (dedup by message ID).
|
||||
* @param message the incoming message
|
||||
*/
|
||||
private void appendMessageIfSelected(MessageResponse message) {
|
||||
try {
|
||||
upsertConversationForMessage(message);
|
||||
@@ -474,6 +493,11 @@ public class ChatController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates a conversation in the list and re-sorts by last activity.
|
||||
* Called when the WebSocket pushes a conversation update (e.g. status change).
|
||||
* @param conversation the updated conversation from the server
|
||||
*/
|
||||
private void upsertConversation(ConversationResponse conversation) {
|
||||
Optional<ConversationResponse> existing = conversations.stream()
|
||||
.filter(item -> item.getId().equals(conversation.getId()))
|
||||
@@ -507,6 +531,10 @@ public class ChatController {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-selects the previously selected conversation after the list is rebuilt.
|
||||
* Needed because refreshSections() replaces all items, which clears the selection.
|
||||
*/
|
||||
private void restoreSelection() {
|
||||
if (selectedConversation == null) {
|
||||
return;
|
||||
@@ -528,6 +556,12 @@ public class ChatController {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a single chat bubble with avatar, author label, text, optional
|
||||
* image/attachment preview, and timestamp. Own messages go right, others left.
|
||||
* @param message the message to render
|
||||
* @return the bubble wrapped in an HBox
|
||||
*/
|
||||
private HBox createMessageBubble(MessageResponse message) {
|
||||
boolean mine = message.getSenderId() != null && message.getSenderId().equals(UserSession.getInstance().getUserId());
|
||||
|
||||
@@ -609,6 +643,13 @@ public class ChatController {
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Figures out the display label for a message sender.
|
||||
* Shows "You" for own messages, "AI Bot" for bot messages, and
|
||||
* "Staff" or "Customer" for everyone else.
|
||||
* @param message the message to resolve
|
||||
* @return the author display name
|
||||
*/
|
||||
private String resolveAuthorLabel(MessageResponse message) {
|
||||
if ("BOT".equalsIgnoreCase(message.getSenderRole())) {
|
||||
return message.getSenderDisplayName() != null && !message.getSenderDisplayName().isBlank()
|
||||
@@ -630,6 +671,12 @@ public class ChatController {
|
||||
return customerLabel != null ? customerLabel : "Customer #" + conversation.getCustomerId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the small status line under each conversation in the sidebar.
|
||||
* Shows assignment state (Automated, Assigned, Takeover requested, etc.) and time.
|
||||
* @param conversation the conversation to summarize
|
||||
* @return a short status string like "Assigned · Apr 10, 14:30"
|
||||
*/
|
||||
private String buildConversationMeta(ConversationResponse conversation) {
|
||||
String updated = conversation.getUpdatedAt() == null ? "" : TIME_FORMATTER.format(conversation.getUpdatedAt());
|
||||
if ("CLOSED".equals(conversation.getStatus())) {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the coupon management screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the customer accounts screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the inventory management screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the login screen and handles authentication.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the main layout with sidebar navigation.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
@@ -339,6 +345,10 @@ public class MainLayoutController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the current user info from the server on a background thread
|
||||
* and updates the sidebar avatar and display name.
|
||||
*/
|
||||
private void refreshProfileHeader() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
@@ -376,6 +386,12 @@ public class MainLayoutController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the avatar in the sidebar. Shows the uploaded image if available,
|
||||
* otherwise shows a colored circle with the user's initials.
|
||||
* @param displayName used to generate initials as a fallback
|
||||
* @param avatarImage the user's profile image, or null for the initials fallback
|
||||
*/
|
||||
private void renderAvatar(String displayName, Image avatarImage) {
|
||||
Circle border = new Circle(29);
|
||||
border.setFill(Color.web("#dbe4ee"));
|
||||
@@ -427,6 +443,11 @@ public class MainLayoutController {
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows or hides sidebar buttons based on the user's role.
|
||||
* Admin gets inventory, suppliers, staff accounts, etc.
|
||||
* Also kicks off chat WebSocket subscription in the background.
|
||||
*/
|
||||
private void applyRBAC() {
|
||||
UserSession session = UserSession.getInstance();
|
||||
|
||||
@@ -498,6 +519,10 @@ public class MainLayoutController {
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps the main content area to a different view.
|
||||
* @param fxmlFile the FXML filename inside the modelviews folder
|
||||
*/
|
||||
private void loadView(String fxmlFile) {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/modelviews/" + fxmlFile));
|
||||
@@ -551,6 +576,11 @@ public class MainLayoutController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps EXIF orientation tag values to rotation angles.
|
||||
* @param orientation the EXIF orientation value (1-8)
|
||||
* @return degrees to rotate the image
|
||||
*/
|
||||
private double exifOrientationToAngle(int orientation) {
|
||||
return switch (orientation) {
|
||||
case 3 -> 180;
|
||||
@@ -560,6 +590,13 @@ public class MainLayoutController {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually reads the EXIF orientation tag from raw JPEG bytes.
|
||||
* Walks the JPEG markers to find APP1 (Exif), then parses the TIFF IFD
|
||||
* entries looking for tag 0x0112 (orientation).
|
||||
* @param data raw JPEG image bytes
|
||||
* @return the orientation value (1-8), defaults to 1 if not found
|
||||
*/
|
||||
private int readExifOrientation(byte[] data) {
|
||||
try {
|
||||
if (data.length < 2 || (data[0] & 0xFF) != 0xFF || (data[1] & 0xFF) != 0xD8) return 1;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the pet listings screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the product catalog screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.animation.KeyFrame;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the product-supplier linking screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the purchase order management screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the sales and transactions screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
@@ -427,6 +433,10 @@ public class SaleController {
|
||||
new Thread(task).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows or hides the create-sale panel based on role.
|
||||
* Admins get read-only view; staff can create sales and process refunds.
|
||||
*/
|
||||
private void applyRoleMode() {
|
||||
boolean isAdmin = UserSession.getInstance().isAdmin();
|
||||
vbCreateSale.setVisible(!isAdmin);
|
||||
@@ -440,6 +450,12 @@ public class SaleController {
|
||||
refreshSales(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all sales from the API and flattens them into per-item line rows.
|
||||
* Applies any active store filter. Discounts are distributed proportionally
|
||||
* across line items using a ratio of total to subtotal.
|
||||
* @param showErrorDialog whether to show error dialogs on failure
|
||||
*/
|
||||
private void refreshSales(boolean showErrorDialog) {
|
||||
btnRefresh.setDisable(true);
|
||||
Task<List<SaleLineItem>> task = new Task<List<SaleLineItem>>() {
|
||||
@@ -456,6 +472,7 @@ public class SaleController {
|
||||
: "";
|
||||
|
||||
if (sale.getItems() != null && !sale.getItems().isEmpty()) {
|
||||
// Spread the discount evenly across line items via a ratio
|
||||
double saleSubtotal = sale.getSubtotalAmount() != null ? Math.abs(sale.getSubtotalAmount().doubleValue()) : 0;
|
||||
double saleActualTotal = sale.getTotalAmount() != null ? Math.abs(sale.getTotalAmount().doubleValue()) : 0;
|
||||
double discountRatio = saleSubtotal > 0 ? saleActualTotal / saleSubtotal : 1.0;
|
||||
@@ -816,6 +833,12 @@ public class SaleController {
|
||||
new Thread(task).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a SaleResponse from the API into a SaleDetail for the detail dialog.
|
||||
* Distributes discounts across line items the same way refreshSales does.
|
||||
* @param sale the API response
|
||||
* @return the mapped detail object
|
||||
*/
|
||||
private SaleDetail mapToSaleDetail(SaleResponse sale) {
|
||||
ObservableList<SaleDetail.SaleDetailItem> items = FXCollections.observableArrayList();
|
||||
double saleSubtotal = sale.getSubtotalAmount() != null ? Math.abs(sale.getSubtotalAmount().doubleValue()) : 0;
|
||||
@@ -858,6 +881,10 @@ public class SaleController {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates the cart summary: subtotal, coupon discount, loyalty discount, and final total.
|
||||
* Also updates the "points to earn" preview for the selected customer.
|
||||
*/
|
||||
private void updateCartTotal() {
|
||||
BigDecimal subtotal = BigDecimal.valueOf(cartItems.stream().mapToDouble(SaleCartItem::getTotal).sum());
|
||||
BigDecimal couponDiscount = calculateCouponDiscount(subtotal);
|
||||
@@ -900,6 +927,12 @@ public class SaleController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates how much the coupon takes off. Percentage coupons use the
|
||||
* subtotal; fixed-amount coupons are capped at the subtotal.
|
||||
* @param subtotal the cart subtotal before discounts
|
||||
* @return the discount amount
|
||||
*/
|
||||
private BigDecimal calculateCouponDiscount(BigDecimal subtotal) {
|
||||
if (appliedCoupon == null) {
|
||||
return BigDecimal.ZERO;
|
||||
@@ -911,6 +944,11 @@ public class SaleController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates loyalty point discount. Each point is worth $0.05.
|
||||
* @param subtotalAfterCoupon the amount after coupon discount
|
||||
* @return the loyalty discount amount
|
||||
*/
|
||||
private BigDecimal calculateLoyaltyDiscount(BigDecimal subtotalAfterCoupon) {
|
||||
if (!chkUseLoyaltyPoints.isSelected() || selectedCustomerData == null) {
|
||||
return BigDecimal.ZERO;
|
||||
@@ -919,6 +957,13 @@ public class SaleController {
|
||||
return BigDecimal.valueOf(pointsToUse).multiply(BigDecimal.valueOf(0.05));
|
||||
}
|
||||
|
||||
/**
|
||||
* Figures out how many loyalty points to redeem. Uses up to the customer's
|
||||
* full balance, but never more than would cover the remaining total.
|
||||
* The multiplier of 20 means 20 points = $1.00 of discount.
|
||||
* @param subtotalAfterCoupon amount left after coupon
|
||||
* @return number of points to use
|
||||
*/
|
||||
private int calculatePointsToUse(BigDecimal subtotalAfterCoupon) {
|
||||
if (selectedCustomerData == null || selectedCustomerData.getLoyaltyPoints() == null) {
|
||||
return 0;
|
||||
@@ -998,6 +1043,10 @@ public class SaleController {
|
||||
chkUseLoyaltyPoints.setDisable(disabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the combined text search, payment type, refund status, and customer filters.
|
||||
* @param filter the text search input
|
||||
*/
|
||||
private void applySalesFilter(String filter) {
|
||||
String f = filter == null ? "" : filter.trim().toLowerCase();
|
||||
String selectedPayment = cbFilterPayment.getValue();
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the services management screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the staff accounts screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the supplier management screen.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for creating or editing an adoption.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for creating or editing an appointment.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for creating or editing a coupon.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for editing customer details.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for adjusting inventory levels.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for adding or editing a pet.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for adding or editing a product.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for linking a product to a supplier.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog that shows purchase order details.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for processing a refund.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog that shows sale details.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for creating or editing a service.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for editing staff member details.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for registering a new staff member.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Controls the dialog for adding or editing a supplier.
|
||||
*
|
||||
* Author: Harkamal
|
||||
* Date: April 2026
|
||||
*/
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.event.EventHandler;
|
||||
|
||||
Reference in New Issue
Block a user