mirror of
https://github.com/klmp200/PQT_Gestionnaire_vente_stock.git
synced 2024-11-16 21:33:21 +00:00
Merge branch 'develop' into feature/#1_développement_code_métier_partie_client
This commit is contained in:
commit
df5837f79a
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
#Ignoring Intellij workspace specific folders and files
|
||||
/**/.idea/workspace.xml
|
||||
/**/tasks.xml
|
||||
|
||||
/**/.idea/libraries
|
||||
|
||||
#Ignoring target folders
|
||||
**/target/
|
Binary file not shown.
Binary file not shown.
8
Workspace/.idea/artifacts/server_war.xml
Normal file
8
Workspace/.idea/artifacts/server_war.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="war" name="server:war">
|
||||
<output-path>$PROJECT_DIR$/server/target</output-path>
|
||||
<root id="archive" name="server-1.0-SNAPSHOT.war">
|
||||
<element id="artifact" artifact-name="server:war exploded" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
23
Workspace/.idea/artifacts/server_war_exploded.xml
Normal file
23
Workspace/.idea/artifacts/server_war_exploded.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="exploded-war" name="server:war exploded">
|
||||
<output-path>$PROJECT_DIR$/server/target/server-1.0-SNAPSHOT</output-path>
|
||||
<root id="root">
|
||||
<element id="directory" name="WEB-INF">
|
||||
<element id="directory" name="classes">
|
||||
<element id="module-output" name="server" />
|
||||
</element>
|
||||
<element id="directory" name="lib">
|
||||
<element id="archive" name="core-1.0-SNAPSHOT.jar">
|
||||
<element id="module-output" name="core" />
|
||||
</element>
|
||||
<element id="library" level="project" name="Maven: com.google.code.gson:gson:2.8.1" />
|
||||
<element id="library" level="project" name="Maven: commons-io:commons-io:2.4" />
|
||||
</element>
|
||||
</element>
|
||||
<element id="directory" name="META-INF">
|
||||
<element id="file-copy" path="$PROJECT_DIR$/server/target/server-1.0-SNAPSHOT/META-INF/MANIFEST.MF" />
|
||||
</element>
|
||||
<element id="javaee-facet-resources" facet="server/web/Web" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
9
Workspace/.idea/codeStyleSettings.xml
Normal file
9
Workspace/.idea/codeStyleSettings.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectCodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value />
|
||||
</option>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</component>
|
||||
</project>
|
@ -8,12 +8,13 @@
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="client" />
|
||||
<module name="core" />
|
||||
<module name="server" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel>
|
||||
<module name="client" target="1.8" />
|
||||
<module name="core" target="1.8" />
|
||||
<module name="server" target="1.5" />
|
||||
<module name="server" target="1.8" />
|
||||
<module name="Workspace" target="1.8" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
|
@ -1,15 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="FrameworkDetectionExcludesConfiguration">
|
||||
<file type="web" url="file://$PROJECT_DIR$/server" />
|
||||
</component>
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="ignoredFiles">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$/server/pom.xml" />
|
||||
</set>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
|
@ -5,6 +5,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/Workspace.iml" filepath="$PROJECT_DIR$/Workspace.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/client/client.iml" filepath="$PROJECT_DIR$/client/client.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/core.iml" filepath="$PROJECT_DIR$/core/core.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/server/server.iml" filepath="$PROJECT_DIR$/server/server.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
@ -11,6 +11,8 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
</component>
|
||||
</module>
|
50
Workspace/client/src/main/java/com/pqt/client/Main.java
Normal file
50
Workspace/client/src/main/java/com/pqt/client/Main.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.pqt.client;
|
||||
|
||||
import com.pqt.client.gui.main_frame.MainFrame;
|
||||
import com.pqt.client.gui.modules.account_screen.AccountScreen;
|
||||
import com.pqt.client.gui.modules.sale_screen.SaleScreen;
|
||||
import com.pqt.client.gui.modules.stat_screen.StatScreen;
|
||||
import com.pqt.client.gui.modules.stock_screen.StockScreen;
|
||||
import com.pqt.client.gui.ressources.components.generics.others.SideBar;
|
||||
import com.pqt.client.gui.ressources.components.generics.others.listeners.ISideBarListener;
|
||||
import com.pqt.client.gui.ressources.components.generics.toast.ToastFactory;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.sale.SaleService;
|
||||
import com.pqt.client.module.stat.StatService;
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
import javafx.application.Application;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class Main extends Application{
|
||||
|
||||
public static void main(String[] args){
|
||||
launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
SaleService saleService = new SaleService();
|
||||
StockService stockService = new StockService();
|
||||
AccountService accountService = new AccountService();
|
||||
StatService statService = new StatService();
|
||||
|
||||
MainFrame mainFrame = new MainFrame(accountService);
|
||||
mainFrame.addModule(new SaleScreen(accountService, stockService, saleService), true);
|
||||
mainFrame.addModule(new StockScreen(stockService, accountService));
|
||||
mainFrame.addModule(new StatScreen(statService));
|
||||
mainFrame.addModule(new AccountScreen(accountService));
|
||||
|
||||
|
||||
Scene scene = new Scene(mainFrame.getPane(), 800, 600);
|
||||
scene.getStylesheets().clear();
|
||||
scene.getStylesheets().addAll(getClass().getResource(GUICssTool.getCssFilePath()).toExternalForm());
|
||||
|
||||
ToastFactory.init(primaryStage);
|
||||
primaryStage.setTitle(GUIStringTool.getAppTitle());
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.show();
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.pqt.client.gui.main_frame;
|
||||
|
||||
import com.pqt.client.gui.modules.IGuiModule;
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class MainFrame implements IFXComponent {
|
||||
|
||||
private MainFrameView view;
|
||||
private MainFrameController ctrl;
|
||||
|
||||
public MainFrame(AccountService accountService) {
|
||||
MainFrameModel model = new MainFrameModel(accountService);
|
||||
ctrl = new MainFrameController(model);
|
||||
model.addListener(ctrl);
|
||||
|
||||
view = new MainFrameView(ctrl);
|
||||
ctrl.setView(view);
|
||||
ctrl.updateView();
|
||||
}
|
||||
|
||||
public void addModule(IGuiModule module, boolean setActive){
|
||||
ctrl.addModule(module, setActive);
|
||||
}
|
||||
|
||||
public void addModule(IGuiModule module){
|
||||
ctrl.addModule(module, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return view.getPane();
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package com.pqt.client.gui.main_frame;
|
||||
|
||||
import com.pqt.client.gui.main_frame.listeners.IMainFrameModelListener;
|
||||
import com.pqt.client.gui.modules.IGuiModule;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.listeners.IAccountComponentListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.event.Event;
|
||||
|
||||
class MainFrameController implements IMainFrameModelListener {
|
||||
|
||||
private MainFrameModel model;
|
||||
private MainFrameView view;
|
||||
private IValidatorComponentListener accountManagerAccountListener;
|
||||
|
||||
MainFrameController(MainFrameModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
void setView(MainFrameView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
void updateView(){
|
||||
view.feedAccountCollectionToManager(model.getAccounts());
|
||||
view.setCurrentAccount(model.getCurrentAccount());
|
||||
if(model.getCurrentAccount()!=null)
|
||||
view.updateModuleButtonLock(model.getCurrentAccount().getPermissionLevel());
|
||||
else
|
||||
view.updateModuleButtonLock(AccountLevel.getLowest());
|
||||
}
|
||||
|
||||
void addModule(IGuiModule module, boolean activationRequired) {
|
||||
boolean activate = activationRequired
|
||||
&& model.getCurrentAccount()!=null
|
||||
&& model.getCurrentAccount().getPermissionLevel().compareTo(module.getLowestRequiredAccountLevel())>=0;
|
||||
this.view.addGuiModule(module.getModuleName(),module.getPane(), module.getLowestRequiredAccountLevel(), activate);
|
||||
}
|
||||
|
||||
IValidatorComponentListener getAccountManagerValidatorListener() {
|
||||
return new IValidatorComponentListener() {
|
||||
@Override
|
||||
public void onValidationEvent() {
|
||||
if(view.isAccountCreationPossible())
|
||||
model.connectAccount(view.create());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelEvent() {
|
||||
model.disconnectCurrentAccount();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
IAccountComponentListener getAccountManagerAccountListener() {
|
||||
return new IAccountComponentListener() {
|
||||
@Override
|
||||
public void onRefreshContentRequestEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContentClickEvent(Event event, Account eventTarget) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAddContentRequestEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveContentRequestEvent(Account content) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetailContentRequestEvent(Account content) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountStatusChangedEvent(boolean status) {
|
||||
updateView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountCollectionChangedEvent() {
|
||||
updateView();
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package com.pqt.client.gui.main_frame;
|
||||
|
||||
import com.pqt.client.gui.main_frame.listeners.IMainFrameModelListener;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.account.listeners.IAccountListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
class MainFrameModel {
|
||||
|
||||
private EventListenerList listenerList;
|
||||
private AccountService accountService;
|
||||
|
||||
MainFrameModel(AccountService accountService) {
|
||||
listenerList = new EventListenerList();
|
||||
this.accountService = accountService;
|
||||
this.accountService.addListener(new IAccountListener() {
|
||||
@Override
|
||||
public void onAccountStatusChangedEvent(boolean status) {
|
||||
MainFrameModel.this.fireAccountStatusChangedEvent(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountListChangedEvent() {
|
||||
MainFrameModel.this.fireAccountCollectionChangedEvent();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fireAccountCollectionChangedEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IMainFrameModelListener.class)).forEach(IMainFrameModelListener::onAccountCollectionChangedEvent);
|
||||
}
|
||||
|
||||
private void fireAccountStatusChangedEvent(boolean status) {
|
||||
Arrays.stream(listenerList.getListeners(IMainFrameModelListener.class)).forEach(l->l.onAccountStatusChangedEvent(status));
|
||||
}
|
||||
|
||||
void connectAccount(Account account) {
|
||||
accountService.setCurrentAccount(account);
|
||||
accountService.logInCurrentAccount(account.getPassword());
|
||||
}
|
||||
|
||||
void disconnectCurrentAccount() {
|
||||
accountService.logOutCurrentAccount();
|
||||
}
|
||||
|
||||
Collection<Account> getAccounts(){
|
||||
return accountService.getAllAccounts();
|
||||
}
|
||||
|
||||
void addListener(IMainFrameModelListener listener){
|
||||
listenerList.add(IMainFrameModelListener.class, listener);
|
||||
}
|
||||
|
||||
void removeListener(IMainFrameModelListener listener){
|
||||
listenerList.remove(IMainFrameModelListener.class, listener);
|
||||
}
|
||||
|
||||
Account getCurrentAccount() {
|
||||
return accountService.getCurrentAccount();
|
||||
}
|
||||
}
|
@ -0,0 +1,142 @@
|
||||
package com.pqt.client.gui.main_frame;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.AccountManager;
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.others.SideBar;
|
||||
import com.pqt.client.gui.ressources.components.generics.others.listeners.ISideBarListener;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ToolBar;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
class MainFrameView implements IFXComponent{
|
||||
|
||||
private final MainFrameController ctrl;
|
||||
|
||||
private BorderPane mainPane;
|
||||
private AccountManager accountManager;
|
||||
private VBox buttonHolder;
|
||||
private ObjectProperty<AccountLevel> currentAccountLevel;
|
||||
|
||||
MainFrameView(MainFrameController ctrl) {
|
||||
this.ctrl = ctrl;
|
||||
currentAccountLevel = new SimpleObjectProperty<>(AccountLevel.getLowest());
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui(){
|
||||
mainPane = new BorderPane();
|
||||
mainPane.getStyleClass().addAll("main-module-pane", "main-frame");
|
||||
|
||||
buttonHolder = new VBox();
|
||||
|
||||
SideBar sidebar = new SideBar();
|
||||
sidebar.setFillWidth(true);
|
||||
SideBar.setVgrow(buttonHolder, Priority.ALWAYS);
|
||||
buttonHolder.prefWidthProperty().bind(sidebar.widthProperty());
|
||||
sidebar.getChildren().add(buttonHolder);
|
||||
|
||||
accountManager = new AccountManager();
|
||||
accountManager.addListener(ctrl.getAccountManagerValidatorListener());
|
||||
accountManager.addListener(ctrl.getAccountManagerAccountListener());
|
||||
accountManager.getPane().prefWidthProperty().bind(sidebar.widthProperty());
|
||||
sidebar.getChildren().add(accountManager.getPane());
|
||||
|
||||
mainPane.setLeft(sidebar);
|
||||
|
||||
Button sidebarCtrl = new Button();
|
||||
if(sidebar.isExpanded())
|
||||
sidebarCtrl.setText(GUIStringTool.getSideBarCollapseButtonLabel());
|
||||
else
|
||||
sidebarCtrl.setText(GUIStringTool.getSideBarExpandButtonLabel());
|
||||
sidebarCtrl.setOnMouseClicked(event -> {
|
||||
if(sidebar.isExpanded())
|
||||
sidebar.collapse();
|
||||
else if(sidebar.isCollapsed())
|
||||
sidebar.expand();
|
||||
});
|
||||
sidebar.addListener(new ISideBarListener() {
|
||||
@Override
|
||||
public void onCollapsedFinished() {
|
||||
sidebarCtrl.setText(GUIStringTool.getSideBarExpandButtonLabel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExpandFinished() {
|
||||
sidebarCtrl.setText(GUIStringTool.getSideBarCollapseButtonLabel());
|
||||
}
|
||||
});
|
||||
mainPane.setTop(sidebarCtrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
void addGuiModule(String moduleName, Pane moduleContent, AccountLevel requiredLevel, boolean setActive){
|
||||
Button button = new Button(moduleName);
|
||||
button.getStyleClass().add("menu-button");
|
||||
|
||||
Runnable buttonActivationCode = ()->{
|
||||
buttonHolder.getChildren()
|
||||
.stream()
|
||||
.filter(Button.class::isInstance)
|
||||
.map(Button.class::cast)
|
||||
.forEach(b-> b.getStyleClass().remove("menu-button-selected"));
|
||||
button.getStyleClass().add("menu-button-selected");
|
||||
Platform.runLater(()->{
|
||||
buttonHolder.getChildren().forEach(Node::applyCss);
|
||||
mainPane.setCenter(moduleContent);
|
||||
});
|
||||
};
|
||||
button.setOnMouseClicked(event-> {
|
||||
if(event.getButton().equals(MouseButton.PRIMARY))
|
||||
buttonActivationCode.run();
|
||||
});
|
||||
button.setOnKeyTyped(event->{
|
||||
if (event.getCode().equals(KeyCode.ENTER))
|
||||
buttonActivationCode.run();
|
||||
});
|
||||
currentAccountLevel.addListener((obs, oldVal, newVal)->button.setDisable(requiredLevel.compareTo(newVal)>0));
|
||||
button.setDisable(requiredLevel.compareTo(currentAccountLevel.get())>0);
|
||||
if(setActive)
|
||||
buttonActivationCode.run();
|
||||
buttonHolder.getChildren().add(button);
|
||||
}
|
||||
|
||||
boolean isAccountCreationPossible(){
|
||||
return accountManager.isCreationPossible();
|
||||
}
|
||||
|
||||
Account create(){
|
||||
return accountManager.create();
|
||||
}
|
||||
|
||||
void setCurrentAccount(Account account){
|
||||
accountManager.setCurrentAccount(account);
|
||||
}
|
||||
|
||||
void feedAccountCollectionToManager(Collection<Account> accounts){
|
||||
accountManager.display(accounts);
|
||||
}
|
||||
|
||||
void updateModuleButtonLock(AccountLevel level) {
|
||||
currentAccountLevel.setValue(level);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.pqt.client.gui.main_frame.listeners;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface IMainFrameModelListener extends EventListener{
|
||||
void onAccountStatusChangedEvent(boolean status);
|
||||
void onAccountCollectionChangedEvent();
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.pqt.client.gui.modules;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
|
||||
public interface IGuiModule extends IFXComponent{
|
||||
String getModuleName();
|
||||
AccountLevel getLowestRequiredAccountLevel();
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.pqt.client.gui.modules.account_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.IGuiModule;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class AccountScreen implements IGuiModule {
|
||||
|
||||
private AccountScreenView view;
|
||||
|
||||
public AccountScreen(AccountService accountService) {
|
||||
AccountScreenModel model = new AccountScreenModel(accountService);
|
||||
AccountScreenController ctrl = new AccountScreenController(model);
|
||||
view = new AccountScreenView(ctrl);
|
||||
|
||||
ctrl.setView(view);
|
||||
ctrl.updateView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModuleName() {
|
||||
return GUIStringTool.getAccountGuiModuleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountLevel getLowestRequiredAccountLevel() {
|
||||
return AccountLevel.WAITER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return view.getPane();
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package com.pqt.client.gui.modules.account_screen;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
|
||||
class AccountScreenController {
|
||||
|
||||
private AccountScreenModel model;
|
||||
private AccountScreenView view;
|
||||
|
||||
AccountScreenController(AccountScreenModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
void setView(AccountScreenView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
void updateView() {
|
||||
updateViewAccountCollection();
|
||||
updateViewActionLock();
|
||||
}
|
||||
|
||||
private void updateViewAccountCollection(){
|
||||
view.setAccountCollection(model.getAccountCollection());
|
||||
}
|
||||
|
||||
private void updateViewActionLock() {
|
||||
if (model.getCurrentAccount() != null) {
|
||||
view.setAddAccountActionLocked(AccountLevel.MASTER.compareTo(model.getCurrentAccount().getPermissionLevel()) > 0);
|
||||
view.setDetailAccountActionLocked(!view.isItemSelected() || AccountLevel.MASTER.compareTo(model.getCurrentAccount().getPermissionLevel()) > 0);
|
||||
view.setRemoveAccountActionLocked(!view.isItemSelected() || AccountLevel.MASTER.compareTo(model.getCurrentAccount().getPermissionLevel()) > 0);
|
||||
}else{
|
||||
view.setAddAccountActionLocked(true);
|
||||
view.setDetailAccountActionLocked(true);
|
||||
view.setRemoveAccountActionLocked(true);
|
||||
}
|
||||
}
|
||||
|
||||
IValidatorComponentListener getDetailScreenValidationListener(){
|
||||
return new IValidatorComponentListener() {
|
||||
@Override
|
||||
public void onValidationEvent() {
|
||||
if(view.isDetailCreationPossible()){
|
||||
if(view.getDetailScreenInitialValue()!=null){
|
||||
model.modifyAccount(view.getDetailScreenInitialValue(), view.getDetailScreenCreatedValue());
|
||||
}else{
|
||||
model.addAccount(view.getDetailScreenCreatedValue());
|
||||
}
|
||||
view.hideDetailScreen();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelEvent() {
|
||||
view.hideDetailScreen();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void onAddAccountRequested() {
|
||||
view.showDetailScreen(null, model.getLevels());
|
||||
}
|
||||
|
||||
void onDetailAccountRequested() {
|
||||
if(view.isItemSelected())
|
||||
view.showDetailScreen(view.getSelectedItem(), model.getLevels());
|
||||
}
|
||||
|
||||
void onRemoveAccountRequested() {
|
||||
if(view.isItemSelected())
|
||||
model.removeAccount(view.getSelectedItem());
|
||||
}
|
||||
|
||||
void onRefreshAccountRequested() {
|
||||
this.updateView();
|
||||
}
|
||||
|
||||
void onSelectedAccountChanged(Account oldVal, Account newVal) {
|
||||
updateViewActionLock();
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.pqt.client.gui.modules.account_screen;
|
||||
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
|
||||
//TODO MAJ les méthds modif, add et remove une fois que l'accountService prend en compte les modifs
|
||||
class AccountScreenModel {
|
||||
|
||||
private AccountService accountService;
|
||||
|
||||
AccountScreenModel(AccountService accountService) {
|
||||
this.accountService = accountService;
|
||||
}
|
||||
|
||||
void modifyAccount(Account oldVal, Account newVal) {
|
||||
//accountService.submitAccountUpdate(oldVal, newVal);
|
||||
}
|
||||
|
||||
void addAccount(Account newVal) {
|
||||
//accountService.submitAccountUpdate(null, newVal);
|
||||
}
|
||||
|
||||
void removeAccount(Account oldVal) {
|
||||
//accountService.submitAccountUpdate(oldVal, null);
|
||||
}
|
||||
|
||||
Collection<Account> getAccountCollection() {
|
||||
return accountService.getAllAccounts();
|
||||
}
|
||||
|
||||
Account getCurrentAccount() {
|
||||
return accountService.getCurrentAccount();
|
||||
}
|
||||
|
||||
Collection<AccountLevel> getLevels() {
|
||||
//TODO régler ça aussi
|
||||
//return accountService.getAvailableLevels();
|
||||
return EnumSet.allOf(AccountLevel.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,178 @@
|
||||
package com.pqt.client.gui.modules.account_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.account_screen.account_manager_screen.AccountManagerScreen;
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class AccountScreenView implements IFXComponent{
|
||||
|
||||
private AccountScreenController ctrl;
|
||||
private StackPane mainPane;
|
||||
private BorderPane mainPaneContent;
|
||||
private TableView<Account> tableView;
|
||||
private AccountManagerScreen accountManagerScreen;
|
||||
|
||||
private Button addAccountButton, detailAccountButton, removeAccountButton;
|
||||
|
||||
|
||||
AccountScreenView(AccountScreenController ctrl) {
|
||||
this.ctrl = ctrl;
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui() {
|
||||
mainPane = new StackPane();
|
||||
mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
|
||||
|
||||
mainPaneContent = new BorderPane();
|
||||
|
||||
tableView = new TableView<>();
|
||||
|
||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
tableView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal)-> ctrl.onSelectedAccountChanged(oldVal, newVal));
|
||||
TableColumn<Account, String> nameColumn = new TableColumn<>(GUIStringTool.getAccountNameColumnHeaderLabel());
|
||||
nameColumn.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().getUsername()));
|
||||
tableView.getColumns().add(nameColumn);
|
||||
|
||||
TableColumn<Account, String> levelColumn = new TableColumn<>(GUIStringTool.getAccountLevelColumnHeaderLabel());
|
||||
levelColumn.setCellValueFactory(param -> new SimpleStringProperty(
|
||||
GUIStringTool.getAccountLevelStringRenderer().render(param.getValue().getPermissionLevel())
|
||||
));
|
||||
tableView.getColumns().add(levelColumn);
|
||||
mainPaneContent.setCenter(tableView);
|
||||
|
||||
HBox mainPaneTopContent = new HBox();
|
||||
mainPaneTopContent.setFillHeight(true);
|
||||
|
||||
Label label = new Label(GUIStringTool.getAccountListTitleLabel());
|
||||
label.getStyleClass().add(GUICssTool.getTitleTextStyleClass());
|
||||
mainPaneTopContent.getChildren().add(label);
|
||||
|
||||
HBox separator = new HBox();
|
||||
ToolBar buttonToolbar = new ToolBar();
|
||||
addAccountButton = new Button(GUIStringTool.getAddButtonLabel());
|
||||
addAccountButton.setOnMouseClicked(event->{
|
||||
if (event.getButton().equals(MouseButton.PRIMARY))
|
||||
ctrl.onAddAccountRequested();
|
||||
});
|
||||
buttonToolbar.getItems().add(addAccountButton);
|
||||
detailAccountButton = new Button(GUIStringTool.getDetailButtonLabel());
|
||||
detailAccountButton.setOnMouseClicked(event->{
|
||||
if (event.getButton().equals(MouseButton.PRIMARY))
|
||||
ctrl.onDetailAccountRequested();
|
||||
});
|
||||
buttonToolbar.getItems().add(detailAccountButton);
|
||||
removeAccountButton = new Button(GUIStringTool.getRemoveButtonLabel());
|
||||
removeAccountButton.setOnMouseClicked(event->{
|
||||
if (event.getButton().equals(MouseButton.PRIMARY))
|
||||
ctrl.onRemoveAccountRequested();
|
||||
});
|
||||
buttonToolbar.getItems().add(removeAccountButton);
|
||||
Button refreshAccountButton = new Button(GUIStringTool.getRefreshButtonLabel());
|
||||
refreshAccountButton.setOnMouseClicked(event->{
|
||||
if (event.getButton().equals(MouseButton.PRIMARY))
|
||||
ctrl.onRefreshAccountRequested();
|
||||
});
|
||||
buttonToolbar.getItems().add(refreshAccountButton);
|
||||
|
||||
mainPaneTopContent.getChildren().addAll(separator, buttonToolbar);
|
||||
HBox.setHgrow(separator, Priority.ALWAYS);
|
||||
|
||||
mainPaneContent.setTop(mainPaneTopContent);
|
||||
mainPane.getChildren().add(mainPaneContent);
|
||||
}
|
||||
|
||||
boolean isItemSelected(){
|
||||
return tableView.getSelectionModel().getSelectedItem()!=null;
|
||||
}
|
||||
|
||||
Account getSelectedItem(){
|
||||
return tableView.getSelectionModel().getSelectedItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
boolean isDetailCreationPossible() {
|
||||
return accountManagerScreen!=null && accountManagerScreen.isCreationPossible();
|
||||
}
|
||||
|
||||
Account getDetailScreenInitialValue() {
|
||||
if(accountManagerScreen!=null)
|
||||
return accountManagerScreen.getInitialValue();
|
||||
return null;
|
||||
}
|
||||
|
||||
Account getDetailScreenCreatedValue() {
|
||||
if(accountManagerScreen!=null)
|
||||
return accountManagerScreen.create();
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isDetailScreenShown(){
|
||||
return accountManagerScreen!=null;
|
||||
}
|
||||
|
||||
void showDetailScreen(Account initialValue, Collection<AccountLevel> availableLevels){
|
||||
if(!isDetailScreenShown()){
|
||||
Pane separator = new Pane();
|
||||
separator.getStyleClass().add(GUICssTool.getIntermediaryPaneStyleClass());
|
||||
accountManagerScreen = new AccountManagerScreen(initialValue, availableLevels);
|
||||
accountManagerScreen.addListener(ctrl.getDetailScreenValidationListener());
|
||||
|
||||
Platform.runLater(()->{
|
||||
mainPane.getChildren().addAll(separator, accountManagerScreen.getPane());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void hideDetailScreen(){
|
||||
if(isDetailScreenShown()){
|
||||
List<Node> toRemove = mainPane.getChildren()
|
||||
.stream()
|
||||
.filter(node->!node.equals(mainPaneContent))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Platform.runLater(()->{
|
||||
mainPane.getChildren().removeAll(toRemove);
|
||||
accountManagerScreen = null;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void setAccountCollection(Collection<Account> accountCollection) {
|
||||
Platform.runLater(()->{
|
||||
tableView.getItems().clear();
|
||||
if(accountCollection!=null)
|
||||
tableView.getItems().addAll(accountCollection);
|
||||
});
|
||||
}
|
||||
|
||||
void setAddAccountActionLocked(boolean locked) {
|
||||
addAccountButton.setDisable(locked);
|
||||
}
|
||||
|
||||
void setDetailAccountActionLocked(boolean locked) {
|
||||
detailAccountButton.setDisable(locked);
|
||||
}
|
||||
|
||||
void setRemoveAccountActionLocked(boolean locked) {
|
||||
removeAccountButton.setDisable(locked);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.pqt.client.gui.modules.account_screen.account_manager_screen;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.creators.IFXCreatorComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.IFXValidatorComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
//TODO à faire
|
||||
public class AccountManagerScreen implements IFXValidatorComponent, IFXCreatorComponent<Account>{
|
||||
|
||||
private AccountManagerScreenModel model;
|
||||
private AccountManagerScreenView view;
|
||||
private AccountManagerScreenController ctrl;
|
||||
|
||||
public AccountManagerScreen(Account initialValue, Collection<AccountLevel> availableLevels) {
|
||||
model = new AccountManagerScreenModel(initialValue, availableLevels);
|
||||
ctrl = new AccountManagerScreenController(model);
|
||||
view = new AccountManagerScreenView(ctrl);
|
||||
|
||||
ctrl.setView(view);
|
||||
ctrl.updateView();
|
||||
}
|
||||
|
||||
public Account getInitialValue(){
|
||||
return model.getInitialValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account create() {
|
||||
return model.getCurrentValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreationPossible() {
|
||||
return model.isCurrentValueValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IValidatorComponentListener l) {
|
||||
ctrl.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IValidatorComponentListener l) {
|
||||
ctrl.removeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return view.getPane();
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.pqt.client.gui.modules.account_screen.account_manager_screen;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
|
||||
class AccountManagerScreenController {
|
||||
|
||||
private EventListenerList listenerList;
|
||||
private AccountManagerScreenView view;
|
||||
private AccountManagerScreenModel model;
|
||||
|
||||
AccountManagerScreenController(AccountManagerScreenModel model) {
|
||||
listenerList = new EventListenerList();
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
void setView(AccountManagerScreenView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
void updateView() {
|
||||
view.setLevelCollection(model.getAccountLevelCollection());
|
||||
view.setData(model.getCurrentValue());
|
||||
}
|
||||
|
||||
void addListener(IValidatorComponentListener l) {
|
||||
listenerList.add(IValidatorComponentListener.class, l);
|
||||
}
|
||||
|
||||
void removeListener(IValidatorComponentListener l) {
|
||||
listenerList.remove(IValidatorComponentListener.class, l);
|
||||
}
|
||||
|
||||
void onNameChanged(String oldVal, String newVal) {
|
||||
model.changeName(newVal);
|
||||
}
|
||||
|
||||
void onPasswordChanged(String oldVal, String newVal) {
|
||||
model.changePassword(newVal);
|
||||
}
|
||||
|
||||
void onLevelChanged(AccountLevel oldVal, AccountLevel newVal) {
|
||||
model.changeLevel(newVal);
|
||||
}
|
||||
|
||||
void onValidationEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class))
|
||||
.forEach(IValidatorComponentListener::onValidationEvent);
|
||||
}
|
||||
|
||||
void onCancelEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class))
|
||||
.forEach(IValidatorComponentListener::onCancelEvent);
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.pqt.client.gui.modules.account_screen.account_manager_screen;
|
||||
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
class AccountManagerScreenModel {
|
||||
private Account currentValue;
|
||||
private Account initialValue;
|
||||
private Set<AccountLevel> levels;
|
||||
|
||||
AccountManagerScreenModel(Account initialValue, Collection<AccountLevel> availableLevels) {
|
||||
levels = new HashSet<>();
|
||||
if(availableLevels!=null)
|
||||
levels.addAll(availableLevels);
|
||||
this.initialValue = initialValue;
|
||||
this.currentValue = (initialValue!=null?new Account(initialValue):getNewAccount());
|
||||
}
|
||||
|
||||
Account getCurrentValue() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
Account getInitialValue() {
|
||||
return initialValue;
|
||||
}
|
||||
|
||||
boolean isCurrentValueValid() {
|
||||
return !currentValue.equals(initialValue)
|
||||
&& currentValue.getUsername()!=null
|
||||
&& !currentValue.getUsername().isEmpty()
|
||||
&& currentValue.getPermissionLevel()!=null;
|
||||
}
|
||||
|
||||
Collection<AccountLevel> getAccountLevelCollection(){
|
||||
return levels;
|
||||
}
|
||||
|
||||
void changeName(String username) {
|
||||
currentValue.setUsername(username);
|
||||
}
|
||||
|
||||
void changePassword(String password) {
|
||||
currentValue.setPassword(password);
|
||||
}
|
||||
|
||||
void changeLevel(AccountLevel level) {
|
||||
currentValue.setPermissionLevel(level);
|
||||
}
|
||||
|
||||
private Account getNewAccount() {
|
||||
Account account = new Account();
|
||||
account.setUsername("");
|
||||
account.setPassword("");
|
||||
account.setPermissionLevel(levels.stream().min(Enum::compareTo).orElse(AccountLevel.getLowest()));
|
||||
return account;
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.pqt.client.gui.modules.account_screen.account_manager_screen;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
class AccountManagerScreenView implements IFXComponent{
|
||||
|
||||
private StackPane mainPane;
|
||||
private AccountManagerScreenController ctrl;
|
||||
|
||||
private ChoiceBox<AccountLevel> levelChoiceBox;
|
||||
private TextField nameTextField;
|
||||
private PasswordField passwordField;
|
||||
|
||||
AccountManagerScreenView(AccountManagerScreenController ctrl) {
|
||||
this.ctrl = ctrl;
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui() {
|
||||
mainPane = new StackPane();
|
||||
|
||||
BorderPane mainPaneContent = new BorderPane();
|
||||
|
||||
|
||||
GridPane mainPaneCenterContent = new GridPane();
|
||||
mainPaneCenterContent.setAlignment(Pos.CENTER);
|
||||
Label nameLabel = new Label(GUIStringTool.getUsernameLabel());
|
||||
nameTextField = new TextField();
|
||||
nameTextField.textProperty().addListener((obs, oldVal, newVal)->ctrl.onNameChanged(oldVal, newVal));
|
||||
mainPaneCenterContent.add(nameLabel, 0, 0);
|
||||
mainPaneCenterContent.add(nameTextField, 1,0);
|
||||
|
||||
Label passwordLabel = new Label(GUIStringTool.getPasswordLabel());
|
||||
passwordField = new PasswordField();
|
||||
passwordField.textProperty().addListener((obs, oldVal, newVal)->ctrl.onPasswordChanged(oldVal, newVal));
|
||||
mainPaneCenterContent.add(passwordLabel, 0, 1);
|
||||
mainPaneCenterContent.add(passwordField, 1,1);
|
||||
|
||||
Label levelLabel = new Label(GUIStringTool.getUserLevelLabel());
|
||||
levelChoiceBox = new ChoiceBox<>();
|
||||
levelChoiceBox.valueProperty().addListener((obs, oldVal, newVal)->ctrl.onLevelChanged(oldVal, newVal));
|
||||
mainPaneCenterContent.add(levelLabel, 0, 2);
|
||||
mainPaneCenterContent.add(levelChoiceBox, 1,2);
|
||||
|
||||
mainPaneContent.setCenter(mainPaneCenterContent);
|
||||
|
||||
HBox mainPaneBottomContent = new HBox();
|
||||
mainPaneBottomContent.setFillHeight(true);
|
||||
Button validationButton = new Button(GUIStringTool.getValidationButtonLabel());
|
||||
validationButton.setOnMouseClicked(event -> {
|
||||
if (event.getButton().equals(MouseButton.PRIMARY))
|
||||
ctrl.onValidationEvent();
|
||||
});
|
||||
Button cancelButton = new Button(GUIStringTool.getCancelButtonLabel());
|
||||
cancelButton.setOnMouseClicked(event -> {
|
||||
if (event.getButton().equals(MouseButton.PRIMARY))
|
||||
ctrl.onCancelEvent();
|
||||
});
|
||||
HBox separator = new HBox();
|
||||
|
||||
mainPaneBottomContent.getChildren().addAll(separator, validationButton, cancelButton);
|
||||
HBox.setHgrow(separator, Priority.ALWAYS);
|
||||
|
||||
mainPaneContent.setBottom(mainPaneBottomContent);
|
||||
mainPane.getChildren().add(mainPaneContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
void setLevelCollection(Collection<AccountLevel> levelCollection) {
|
||||
Platform.runLater(()->{
|
||||
levelChoiceBox.getItems().clear();
|
||||
levelChoiceBox.getItems().addAll(levelCollection);
|
||||
});
|
||||
}
|
||||
|
||||
void setData(Account data) {
|
||||
Platform.runLater(()->{
|
||||
if(data!=null){
|
||||
nameTextField.setText(data.getUsername());
|
||||
passwordField.setText(data.getPassword());
|
||||
levelChoiceBox.setValue(data.getPermissionLevel());
|
||||
}else{
|
||||
nameTextField.setText("");
|
||||
passwordField.setText("");
|
||||
levelChoiceBox.setValue(levelChoiceBox.getItems()
|
||||
.stream()
|
||||
.min(Enum::compareTo)
|
||||
.orElse(AccountLevel.getLowest()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.pqt.client.gui.modules.sale_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.IGuiModule;
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.sale.SaleService;
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class SaleScreen implements IGuiModule {
|
||||
|
||||
private SaleScreenView view;
|
||||
|
||||
public SaleScreen(AccountService accountService, StockService stockService, SaleService saleService) {
|
||||
SaleScreenModel model = new SaleScreenModel(accountService, stockService, saleService);
|
||||
SaleScreenController ctrl = new SaleScreenController(model);
|
||||
view = new SaleScreenView(ctrl);
|
||||
|
||||
ctrl.setView(view);
|
||||
ctrl.updateView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return view.getPane();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModuleName() {
|
||||
return GUIStringTool.getSaleGuiModuleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountLevel getLowestRequiredAccountLevel() {
|
||||
return AccountLevel.WAITER;
|
||||
}
|
||||
}
|
@ -0,0 +1,191 @@
|
||||
package com.pqt.client.gui.modules.sale_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.sale_screen.listeners.ISaleScreenModelListener;
|
||||
import com.pqt.client.gui.modules.sale_screen.sale_validation_screen.listeners.ISaleValidationScreenListener;
|
||||
import com.pqt.client.gui.ressources.components.specifics.products.listeners.IStockComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.specifics.sale.listeners.ISaleComponentListener;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.core.entities.sale.SaleStatus;
|
||||
import com.pqt.core.entities.sale.SaleType;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.event.Event;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class SaleScreenController {
|
||||
|
||||
private SaleScreenModel model;
|
||||
private SaleScreenView view;
|
||||
|
||||
SaleScreenController(SaleScreenModel model) {
|
||||
this.model = model;
|
||||
this.model.addListener(new ISaleScreenModelListener() {
|
||||
@Override
|
||||
public void onSaleValidatedEvent() {
|
||||
SaleScreenController.this.onSaleValidationSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaleNotValidatedEvent(SaleStatus status, Throwable cause) {
|
||||
onSaleValidationError(status, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStockUpdatedEvent() {
|
||||
view.setProducts(model.getProductList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountConnectedStateUpdatedEvent() {
|
||||
updateActionLock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountListUpdatedEvent() {
|
||||
view.setAccounts(model.getAccountList());
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void onSaleValidationSuccess() {
|
||||
view.setSaleStatus(SaleStatus.ACCEPTED);
|
||||
}
|
||||
|
||||
private void onSaleValidationError(SaleStatus status, Throwable cause) {
|
||||
view.setSaleStatus(status);
|
||||
}
|
||||
|
||||
void setView(SaleScreenView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
void onAccountSelectedAsBeneficiary(Account account){
|
||||
model.setSaleBeneficiary(account);
|
||||
}
|
||||
|
||||
private Sale getCurrentSale(){
|
||||
return model.getCurrentSale();
|
||||
}
|
||||
|
||||
private void updateSale(){
|
||||
view.setSale(getCurrentSale());
|
||||
updateActionLock();
|
||||
}
|
||||
|
||||
private void updateActionLock() {
|
||||
boolean validationButtonEnabled = model.checkValidity(getCurrentSale())
|
||||
&& model.isCurrentAccountConnected()
|
||||
&& model.getCurrentAccountLevel().compareTo(AccountLevel.WAITER)>=0;
|
||||
view.setValidationButtonEnabled(validationButtonEnabled);
|
||||
}
|
||||
|
||||
private void updateData(){
|
||||
view.setProducts(fetchProductList());
|
||||
view.setSaleTypes(fetchSaleTypeList());
|
||||
view.setAccounts(fetchAccountList());
|
||||
}
|
||||
|
||||
void updateView(){
|
||||
updateData();
|
||||
updateSale();
|
||||
}
|
||||
|
||||
private List<Product> fetchProductList(){
|
||||
return model.getProductList();
|
||||
}
|
||||
private List<Account> fetchAccountList(){
|
||||
return model.getAccountList();
|
||||
}
|
||||
private List<SaleType> fetchSaleTypeList(){
|
||||
return model.getSaleTypeList();
|
||||
}
|
||||
|
||||
ISaleComponentListener getSaleDisplayerListener() {
|
||||
return new ISaleComponentListener() {
|
||||
@Override
|
||||
public void onComponentClickEvent(Event event, Product product) {
|
||||
model.removeProductFromSale(product);
|
||||
SaleScreenController.this.updateSale();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshContentRequestEvent() {}
|
||||
|
||||
@Override
|
||||
public void onContentClickEvent(Event event, Sale eventTarget) {}
|
||||
|
||||
@Override
|
||||
public void onAddContentRequestEvent() {}
|
||||
|
||||
@Override
|
||||
public void onRemoveContentRequestEvent(Sale content) {}
|
||||
|
||||
@Override
|
||||
public void onDetailContentRequestEvent(Sale content) {}
|
||||
};
|
||||
}
|
||||
|
||||
IStockComponentListener getStockDisplayerListener() {
|
||||
return new IStockComponentListener() {
|
||||
@Override
|
||||
public void onRefreshContentRequestEvent() {}
|
||||
|
||||
@Override
|
||||
public void onContentClickEvent(Event event, Product eventTarget) {
|
||||
if(eventTarget!=null) {
|
||||
model.addProductToSale(eventTarget);
|
||||
SaleScreenController.this.updateSale();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAddContentRequestEvent() {}
|
||||
|
||||
@Override
|
||||
public void onRemoveContentRequestEvent(Product content) {}
|
||||
|
||||
@Override
|
||||
public void onDetailContentRequestEvent(Product content) {}
|
||||
};
|
||||
}
|
||||
|
||||
Account getDefaultAccount() {
|
||||
return new Account(null, null, AccountLevel.getLowest());
|
||||
}
|
||||
|
||||
IValidatorComponentListener getValidatorListener() {
|
||||
return new IValidatorComponentListener() {
|
||||
@Override
|
||||
public void onValidationEvent() {
|
||||
if(model.commitSale())
|
||||
view.switchToSaleValidationWaitingMode(model.getTempSaleId(), model.getCurrentSale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelEvent() {
|
||||
model.clearSale();
|
||||
SaleScreenController.this.updateView();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void onSaleTypeSelected(SaleType saleType) {
|
||||
model.setSaleType(saleType);
|
||||
}
|
||||
|
||||
ISaleValidationScreenListener getSaleValidationScreenListener() {
|
||||
return saleValidatedSuccessfully -> {
|
||||
view.switchToSaleCompositionMode();
|
||||
if(saleValidatedSuccessfully){
|
||||
model.clearSale();
|
||||
}
|
||||
|
||||
updateView();
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
package com.pqt.client.gui.modules.sale_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.sale_screen.listeners.ISaleScreenModelListener;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.account.listeners.IAccountListener;
|
||||
import com.pqt.client.module.sale.SaleBuilder;
|
||||
import com.pqt.client.module.sale.SaleService;
|
||||
import com.pqt.client.module.sale.listeners.ISaleListener;
|
||||
import com.pqt.client.module.stock.Listeners.IStockListener;
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.core.entities.sale.SaleStatus;
|
||||
import com.pqt.core.entities.sale.SaleType;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class SaleScreenModel {
|
||||
|
||||
private EventListenerList listeners;
|
||||
|
||||
private AccountService accountService;
|
||||
private StockService stockService;
|
||||
private SaleService saleService;
|
||||
|
||||
private SaleBuilder currentSaleBuilder;
|
||||
private long tempSaleId;
|
||||
|
||||
SaleScreenModel(AccountService accountService, StockService stockService, SaleService saleService) {
|
||||
if(accountService==null || stockService==null || saleService==null)
|
||||
throw new NullPointerException("At least one of the following services is null : account, stock, sale");
|
||||
|
||||
listeners = new EventListenerList();
|
||||
this.accountService = accountService;
|
||||
this.stockService = stockService;
|
||||
this.saleService = saleService;
|
||||
|
||||
saleService.addListener(new ISaleListener() {
|
||||
@Override
|
||||
public void onSaleValidationSuccess(long saleId) {
|
||||
if(saleId == SaleScreenModel.this.tempSaleId){
|
||||
SaleScreenModel.this.fireSaleValidatedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaleValidationError(long saleId, Throwable cause) {
|
||||
if(saleId == SaleScreenModel.this.tempSaleId){
|
||||
SaleScreenModel.this.fireSaleNotValidatedEvent(SaleStatus.ABORTED, cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaleValidationRefused(long saleId, Throwable cause) {
|
||||
if(saleId == SaleScreenModel.this.tempSaleId){
|
||||
SaleScreenModel.this.fireSaleNotValidatedEvent(SaleStatus.REFUSED, cause);
|
||||
}
|
||||
}
|
||||
});
|
||||
stockService.addListener(new IStockListener() {
|
||||
@Override
|
||||
public void onGetProductListSuccessEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetProductListErrorEvent(Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetProductListRefusedEvent(Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProductListUpdateSuccessEvent(long id) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProductListUpdateErrorEvent(long id, Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProductListUpdateRefusedEvent(long id, Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProductListChangedEvent() {
|
||||
fireStockUpdatedEvent();
|
||||
}
|
||||
});
|
||||
accountService.addListener(new IAccountListener() {
|
||||
@Override
|
||||
public void onAccountStatusChangedEvent(boolean status) {
|
||||
fireAccountConnectedStatusUpdateEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountListChangedEvent() {
|
||||
fireAccountListUpdatedEvent();
|
||||
}
|
||||
});
|
||||
|
||||
clearSale();
|
||||
}
|
||||
|
||||
private void fireSaleValidatedEvent() {
|
||||
Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
|
||||
.forEach(ISaleScreenModelListener::onSaleValidatedEvent);
|
||||
}
|
||||
|
||||
private void fireSaleNotValidatedEvent(SaleStatus status, Throwable cause) {
|
||||
Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
|
||||
.forEach(l->l.onSaleNotValidatedEvent(status, cause));
|
||||
}
|
||||
|
||||
private void fireStockUpdatedEvent(){
|
||||
Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
|
||||
.forEach(ISaleScreenModelListener::onStockUpdatedEvent);
|
||||
}
|
||||
|
||||
private void fireAccountListUpdatedEvent(){
|
||||
Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
|
||||
.forEach(ISaleScreenModelListener::onAccountListUpdatedEvent);
|
||||
}
|
||||
|
||||
private void fireAccountConnectedStatusUpdateEvent() {
|
||||
Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
|
||||
.forEach(ISaleScreenModelListener::onAccountConnectedStateUpdatedEvent);
|
||||
}
|
||||
|
||||
List<Account> getAccountList() {
|
||||
return accountService.getAllAccounts();
|
||||
}
|
||||
|
||||
List<SaleType> getSaleTypeList() {
|
||||
return saleService.getSaleTypes();
|
||||
}
|
||||
|
||||
Sale getCurrentSale() {
|
||||
return currentSaleBuilder!=null?currentSaleBuilder.build():null;
|
||||
}
|
||||
|
||||
List<Product> getProductList() {
|
||||
return stockService.getProducts().stream().filter(Product::isSellable).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
void clearSale() {
|
||||
currentSaleBuilder = getNewSaleBuilder();
|
||||
tempSaleId = -1;
|
||||
}
|
||||
|
||||
private SaleBuilder getNewSaleBuilder(){
|
||||
SaleBuilder saleBuilder = saleService.getNewSaleBuilder();
|
||||
saleBuilder.orderedBy(accountService.getCurrentAccount());
|
||||
saleBuilder.saleType(SaleType.CASH);
|
||||
return saleBuilder;
|
||||
}
|
||||
|
||||
boolean commitSale() {
|
||||
if(!checkValidity(currentSaleBuilder.build()))
|
||||
return false;
|
||||
|
||||
tempSaleId = saleService.commitSale(currentSaleBuilder);
|
||||
return tempSaleId!=-1;
|
||||
}
|
||||
|
||||
boolean checkValidity(Sale sale) {
|
||||
return sale.getProducts().size()>0
|
||||
&& sale.getOrderedBy()!=null
|
||||
&& sale.getType()!=null;
|
||||
}
|
||||
|
||||
long getTempSaleId(){
|
||||
return tempSaleId;
|
||||
}
|
||||
|
||||
void addProductToSale(Product product) {
|
||||
if(currentSaleBuilder!=null)
|
||||
currentSaleBuilder.addProduct(product);
|
||||
}
|
||||
|
||||
void removeProductFromSale(Product product) {
|
||||
if(currentSaleBuilder!=null)
|
||||
currentSaleBuilder.removeProduct(product);
|
||||
}
|
||||
|
||||
void setSaleType(SaleType saleType) {
|
||||
if(currentSaleBuilder!=null)
|
||||
currentSaleBuilder.saleType(saleType);
|
||||
}
|
||||
|
||||
void setSaleBeneficiary(Account saleBeneficiary) {
|
||||
if(currentSaleBuilder!=null)
|
||||
currentSaleBuilder.orderedFor(saleBeneficiary);
|
||||
}
|
||||
|
||||
void addListener(ISaleScreenModelListener listener){
|
||||
listeners.add(ISaleScreenModelListener.class, listener);
|
||||
}
|
||||
|
||||
void removeListener(ISaleScreenModelListener listener){
|
||||
listeners.remove(ISaleScreenModelListener.class, listener);
|
||||
}
|
||||
|
||||
boolean isCurrentAccountConnected() {
|
||||
return accountService.isCurrentAccountLoggedIn();
|
||||
}
|
||||
|
||||
AccountLevel getCurrentAccountLevel() {
|
||||
if(accountService.getCurrentAccount()!=null)
|
||||
return accountService.getCurrentAccount().getPermissionLevel();
|
||||
else
|
||||
return AccountLevel.getLowest();
|
||||
}
|
||||
}
|
@ -0,0 +1,224 @@
|
||||
package com.pqt.client.gui.modules.sale_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.sale_screen.sale_validation_screen.SaleValidationScreen;
|
||||
import com.pqt.client.gui.ressources.components.CommandComposerSaleDisplayer;
|
||||
import com.pqt.client.gui.ressources.components.SimpleValidator;
|
||||
import com.pqt.client.gui.ressources.components.generics.javafx_override.CssEnabledGridPane;
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.gui.ressources.components.CategoryTabStockDisplayer;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.core.entities.sale.SaleStatus;
|
||||
import com.pqt.core.entities.sale.SaleType;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import javafx.application.Platform;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class SaleScreenView implements IFXComponent {
|
||||
|
||||
private SaleScreenController ctrl;
|
||||
|
||||
private SaleValidationScreen saleValidationScreen;
|
||||
private StackPane mainPane;
|
||||
private BorderPane mainPaneContent;
|
||||
|
||||
private CategoryTabStockDisplayer stockDisplayer;
|
||||
private CommandComposerSaleDisplayer saleDisplayer;
|
||||
private TextField saleMakerAccountDisplayer;
|
||||
private ChoiceBox<Account> saleBeneficiaryAccountDisplayer;
|
||||
private ChoiceBox<SaleType> saleTypeDisplayer;
|
||||
private TextField salePriceDisplayer;
|
||||
private SimpleValidator validator;
|
||||
|
||||
SaleScreenView(SaleScreenController ctrl) {
|
||||
this.ctrl = ctrl;
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui() {
|
||||
mainPane = new StackPane();
|
||||
mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
|
||||
|
||||
mainPaneContent = new BorderPane();
|
||||
|
||||
/*
|
||||
-----------------------CENTER PANE-----------------------
|
||||
*/
|
||||
{
|
||||
mainPaneContent.prefWidthProperty().bind(mainPane.widthProperty());
|
||||
mainPaneContent.prefHeightProperty().bind(mainPane.heightProperty());
|
||||
|
||||
stockDisplayer = new CategoryTabStockDisplayer();
|
||||
stockDisplayer.addListener(ctrl.getStockDisplayerListener());
|
||||
|
||||
saleDisplayer = new CommandComposerSaleDisplayer();
|
||||
saleDisplayer.addListener(ctrl.getSaleDisplayerListener());
|
||||
|
||||
HBox mainContentCenterPane = new HBox();
|
||||
mainContentCenterPane.getChildren().addAll(stockDisplayer.getPane(), saleDisplayer.getPane());
|
||||
mainContentCenterPane.setFillHeight(true);
|
||||
stockDisplayer.getPane().prefWidthProperty().bind(mainContentCenterPane.widthProperty().divide(2));
|
||||
saleDisplayer.getPane().prefWidthProperty().bind(mainContentCenterPane.widthProperty().divide(2));
|
||||
|
||||
mainPaneContent.setCenter(mainContentCenterPane);
|
||||
}
|
||||
/*
|
||||
-----------------------BOTTOM PANE-----------------------
|
||||
*/
|
||||
{
|
||||
HBox mainContentBottomPane = new HBox();
|
||||
mainContentBottomPane.setFillHeight(true);
|
||||
mainContentBottomPane.setAlignment(Pos.CENTER);
|
||||
// Sale secondary data configuration (author, beneficiary, payment type, etc...
|
||||
{
|
||||
saleMakerAccountDisplayer = new TextField();
|
||||
saleMakerAccountDisplayer.setEditable(false);
|
||||
saleMakerAccountDisplayer.setPromptText(GUIStringTool.getSaleMakerTextFieldPromptText());
|
||||
|
||||
saleBeneficiaryAccountDisplayer = new ChoiceBox<>();
|
||||
saleBeneficiaryAccountDisplayer.setConverter(GUIStringTool.getAccountStringConverter());
|
||||
saleBeneficiaryAccountDisplayer.getSelectionModel()
|
||||
.selectedItemProperty()
|
||||
.addListener((observable, oldElem, newElem) -> ctrl.onAccountSelectedAsBeneficiary(newElem));
|
||||
|
||||
saleTypeDisplayer = new ChoiceBox<>();
|
||||
saleTypeDisplayer.setConverter(GUIStringTool.getSaleTypeStringConverter());
|
||||
saleTypeDisplayer.getSelectionModel()
|
||||
.selectedItemProperty()
|
||||
.addListener((observable, oldElem, newElem) -> ctrl.onSaleTypeSelected(newElem));
|
||||
|
||||
salePriceDisplayer = new TextField();
|
||||
salePriceDisplayer.setEditable(false);
|
||||
salePriceDisplayer.setPromptText(GUIStringTool.getSalePriceTextFieldPromptText());
|
||||
|
||||
|
||||
GridPane mainContentBottomCenterPane = new CssEnabledGridPane();
|
||||
mainContentBottomCenterPane.add(new Label(GUIStringTool.getSaleMakerTextFieldLabel()), 0, 0);
|
||||
mainContentBottomCenterPane.add(saleMakerAccountDisplayer, 1, 0);
|
||||
mainContentBottomCenterPane.add(new Label(GUIStringTool.getSaleBeneficiaryTextFieldLabel()), 0, 1);
|
||||
mainContentBottomCenterPane.add(saleBeneficiaryAccountDisplayer, 1, 1);
|
||||
mainContentBottomCenterPane.add(new Label(GUIStringTool.getSaleTypeTextFieldLabel()), 0, 2);
|
||||
mainContentBottomCenterPane.add(saleTypeDisplayer, 1, 2);
|
||||
mainContentBottomCenterPane.add(new Label(GUIStringTool.getSalePriceTextFieldLabel()), 0, 3);
|
||||
mainContentBottomCenterPane.add(salePriceDisplayer, 1, 3);
|
||||
|
||||
mainContentBottomPane.getChildren().add(mainContentBottomCenterPane);
|
||||
}
|
||||
//Sale Validator
|
||||
{
|
||||
AnchorPane anchorPane = new AnchorPane();
|
||||
validator = new SimpleValidator(true);
|
||||
validator.addListener(ctrl.getValidatorListener());
|
||||
anchorPane.getChildren().add(validator.getPane());
|
||||
AnchorPane.setRightAnchor(validator.getPane(), 0d);
|
||||
AnchorPane.setBottomAnchor(validator.getPane(), 0d);
|
||||
|
||||
mainContentBottomPane.getChildren().add(anchorPane);
|
||||
HBox.setHgrow(anchorPane, Priority.ALWAYS);
|
||||
}
|
||||
mainPaneContent.setBottom(mainContentBottomPane);
|
||||
}
|
||||
/*
|
||||
------------------------MAIN PANE------------------------
|
||||
*/
|
||||
mainPane.getChildren().add(mainPaneContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
void switchToSaleValidationWaitingMode(long saleId, Sale sale){
|
||||
boolean clearChildren = mainPane.getChildren().size()>1;
|
||||
|
||||
Pane greyIntermediaryPane = new Pane();
|
||||
greyIntermediaryPane.getStyleClass().clear();
|
||||
greyIntermediaryPane.getStyleClass().add(GUICssTool.getIntermediaryPaneStyleClass());
|
||||
|
||||
saleValidationScreen = new SaleValidationScreen(saleId, sale);
|
||||
saleValidationScreen.addListener(ctrl.getSaleValidationScreenListener());
|
||||
Platform.runLater(()->{
|
||||
if(clearChildren){
|
||||
mainPane.getChildren().clear();
|
||||
mainPane.getChildren().add(mainPaneContent);
|
||||
}
|
||||
|
||||
StackPane.setAlignment(saleValidationScreen.getPane(), Pos.CENTER);
|
||||
mainPane.getChildren().addAll(greyIntermediaryPane, saleValidationScreen.getPane());
|
||||
});
|
||||
}
|
||||
|
||||
void switchToSaleCompositionMode(){
|
||||
Node[] childrenToRemove = mainPane.getChildren()
|
||||
.stream()
|
||||
.filter(child->!child.equals(mainPaneContent))
|
||||
.collect(Collectors.toList())
|
||||
.toArray(new Node[]{});
|
||||
Platform.runLater(()->mainPane.getChildren().removeAll(childrenToRemove));
|
||||
}
|
||||
|
||||
void setProducts(List<Product> products) {
|
||||
stockDisplayer.display(products);
|
||||
}
|
||||
|
||||
void setSaleTypes(List<SaleType> saleTypes) {
|
||||
Platform.runLater(()->{
|
||||
saleTypeDisplayer.getItems().clear();
|
||||
if(saleTypes!=null)
|
||||
saleTypeDisplayer.getItems().addAll(saleTypes);
|
||||
});
|
||||
}
|
||||
|
||||
void setAccounts(List<Account> accounts) {
|
||||
Platform.runLater(()->{
|
||||
saleBeneficiaryAccountDisplayer.getItems().clear();
|
||||
saleBeneficiaryAccountDisplayer.getItems().add(ctrl.getDefaultAccount());
|
||||
if(accounts!=null)
|
||||
saleBeneficiaryAccountDisplayer.getItems().addAll(accounts);
|
||||
});
|
||||
}
|
||||
|
||||
void setSale(Sale sale) {
|
||||
if(sale!=null) {
|
||||
saleDisplayer.display(sale);
|
||||
|
||||
String price = GUIStringTool.getPriceRenderer().render(sale.getTotalPrice());
|
||||
String currentAccount = GUIStringTool.getAccountStringConverter().toString(sale.getOrderedBy());
|
||||
|
||||
Platform.runLater(() -> {
|
||||
salePriceDisplayer.setText(price);
|
||||
saleMakerAccountDisplayer.setText(currentAccount);
|
||||
|
||||
selectElement(saleTypeDisplayer, sale.getType());
|
||||
selectElement(saleBeneficiaryAccountDisplayer, sale.getOrderedFor());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void selectElement(ChoiceBox<T> choiceBox, T element){
|
||||
if(element!=null){
|
||||
if(!choiceBox.getItems().contains(element))
|
||||
choiceBox.getItems().add(element);
|
||||
choiceBox.getSelectionModel().select(element);
|
||||
}else
|
||||
choiceBox.getSelectionModel().clearSelection();
|
||||
}
|
||||
|
||||
void setSaleStatus(SaleStatus status){
|
||||
this.saleValidationScreen.setSaleStatus(status);
|
||||
}
|
||||
|
||||
void setValidationButtonEnabled(boolean validationButtonEnabled) {
|
||||
validator.setValidationButtonEnable(validationButtonEnabled);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.pqt.client.gui.modules.sale_screen.listeners;
|
||||
|
||||
import com.pqt.core.entities.sale.SaleStatus;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface ISaleScreenModelListener extends EventListener {
|
||||
void onSaleValidatedEvent();
|
||||
void onSaleNotValidatedEvent(SaleStatus status, Throwable cause);
|
||||
void onStockUpdatedEvent();
|
||||
void onAccountConnectedStateUpdatedEvent();
|
||||
void onAccountListUpdatedEvent();
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package com.pqt.client.gui.modules.sale_screen.sale_validation_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.sale_screen.sale_validation_screen.listeners.ISaleValidationScreenListener;
|
||||
import com.pqt.client.gui.ressources.components.generics.javafx_override.CssEnabledGridPane;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.core.entities.sale.SaleStatus;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SaleValidationScreen {
|
||||
|
||||
private Pane mainPane;
|
||||
|
||||
private TextField saleStatusTextField;
|
||||
private SaleStatus saleStatus;
|
||||
private ProgressIndicator progressIndicator;
|
||||
private Button validationButton;
|
||||
|
||||
private EventListenerList listeners;
|
||||
|
||||
public SaleValidationScreen(long saleId, Sale sale) {
|
||||
listeners = new EventListenerList();
|
||||
mainPane = new Pane();
|
||||
mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
|
||||
|
||||
saleStatus = sale.getStatus();
|
||||
|
||||
BorderPane mainPaneContent = new BorderPane();
|
||||
|
||||
GridPane centerPane = new CssEnabledGridPane();
|
||||
centerPane.setAlignment(Pos.CENTER);
|
||||
|
||||
Label saleIdLabel = new Label(GUIStringTool.getSaleIdLabel());
|
||||
centerPane.add(saleIdLabel, 0, 0);
|
||||
|
||||
TextField saleIdTextField = new TextField(Long.toString(saleId));
|
||||
saleIdTextField.setEditable(false);
|
||||
centerPane.add(saleIdTextField, 1, 0);
|
||||
|
||||
Label saleStatusLabel = new Label(GUIStringTool.getSaleStatusLabel());
|
||||
centerPane.add(saleStatusLabel, 0, 1);
|
||||
|
||||
saleStatusTextField = new TextField(GUIStringTool.getSaleStatusRenderer().render(saleStatus));
|
||||
saleStatusTextField.setEditable(false);
|
||||
centerPane.add(saleStatusTextField, 1, 1);
|
||||
|
||||
validationButton = new Button(GUIStringTool.getOkButtonLabel());
|
||||
validationButton.setDisable(saleStatus.equals(SaleStatus.PENDING));
|
||||
validationButton.setOnMouseClicked(event->fireScreenClose(saleStatus.equals(SaleStatus.ACCEPTED)));
|
||||
centerPane.add(validationButton, 1,2);
|
||||
|
||||
mainPaneContent.setCenter(centerPane);
|
||||
|
||||
progressIndicator = new ProgressIndicator();
|
||||
mainPaneContent.setLeft(progressIndicator);
|
||||
|
||||
mainPaneContent.prefHeightProperty().bind(mainPane.heightProperty());
|
||||
mainPaneContent.prefWidthProperty().bind(mainPane.widthProperty());
|
||||
mainPane.getChildren().add(mainPaneContent);
|
||||
}
|
||||
|
||||
private void fireScreenClose(boolean saleValidatedSuccessFully) {
|
||||
if(!validationButton.isDisable()){
|
||||
Arrays.stream(listeners.getListeners(ISaleValidationScreenListener.class))
|
||||
.forEach(listener->listener.onScreenClose(saleValidatedSuccessFully));
|
||||
}
|
||||
}
|
||||
|
||||
public void addListener(ISaleValidationScreenListener listener){
|
||||
listeners.add(ISaleValidationScreenListener.class, listener);
|
||||
}
|
||||
|
||||
public void setSaleStatus(SaleStatus status){
|
||||
saleStatus = status;
|
||||
Platform.runLater(()->{
|
||||
validationButton.setDisable(saleStatus.equals(SaleStatus.PENDING));
|
||||
saleStatusTextField.setText(GUIStringTool.getSaleStatusRenderer().render(status));
|
||||
progressIndicator.setProgress((status.equals(SaleStatus.PENDING)?ProgressIndicator.INDETERMINATE_PROGRESS:1F));
|
||||
});
|
||||
}
|
||||
|
||||
public Pane getPane(){
|
||||
return mainPane;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.client.gui.modules.sale_screen.sale_validation_screen.listeners;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface ISaleValidationScreenListener extends EventListener {
|
||||
void onScreenClose(boolean saleValidatedSuccessfully);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.pqt.client.gui.modules.stat_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.IGuiModule;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.module.stat.StatService;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class StatScreen implements IGuiModule {
|
||||
|
||||
private StatScreenView view;
|
||||
|
||||
public StatScreen(StatService statService) {
|
||||
StatScreenModel model = new StatScreenModel(statService);
|
||||
StatScreenController ctrl = new StatScreenController(model);
|
||||
view = new StatScreenView();
|
||||
|
||||
ctrl.setView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModuleName() {
|
||||
return GUIStringTool.getStatGuiModuleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountLevel getLowestRequiredAccountLevel() {
|
||||
return AccountLevel.STAFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return view.getPane();
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.pqt.client.gui.modules.stat_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.stat_screen.listeners.IStatScreenModelListener;
|
||||
|
||||
class StatScreenController implements IStatScreenModelListener{
|
||||
|
||||
private StatScreenModel model;
|
||||
private StatScreenView view;
|
||||
|
||||
StatScreenController(StatScreenModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
void setView(StatScreenView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatisticsChangedEvent() {
|
||||
view.display(model.getStatistics());
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.pqt.client.gui.modules.stat_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.stat_screen.listeners.IStatScreenModelListener;
|
||||
import com.pqt.client.module.stat.StatService;
|
||||
import com.pqt.client.module.stat.listeners.IStatListener;
|
||||
import com.pqt.client.module.stat.listeners.StatListenerAdapter;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
class StatScreenModel {
|
||||
private EventListenerList listenerList;
|
||||
private StatService statService;
|
||||
|
||||
StatScreenModel(StatService statService) {
|
||||
this.statService = statService;
|
||||
listenerList = new EventListenerList();
|
||||
this.statService.addListener(new StatListenerAdapter() {
|
||||
@Override
|
||||
public void onGetStatSuccess() {
|
||||
Arrays.stream(listenerList.getListeners(IStatScreenModelListener.class)).forEach(IStatScreenModelListener::onStatisticsChangedEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Map<String, String> getStatistics() {
|
||||
return statService.getStats();
|
||||
}
|
||||
|
||||
void addListener(IStatScreenModelListener l){
|
||||
listenerList.add(IStatScreenModelListener.class, l);
|
||||
}
|
||||
|
||||
void removeListener(IStatScreenModelListener l){
|
||||
listenerList.remove(IStatScreenModelListener.class, l);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.pqt.client.gui.modules.stat_screen;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class StatScreenView implements IFXComponent {
|
||||
|
||||
private TextArea statTextArea;
|
||||
private Pane mainPane;
|
||||
|
||||
StatScreenView() {
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui() {
|
||||
mainPane = new Pane();
|
||||
mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
|
||||
|
||||
statTextArea = new TextArea();
|
||||
mainPane.getChildren().add(statTextArea);
|
||||
statTextArea.setId("stat-screen-text-area");
|
||||
statTextArea.setWrapText(true);
|
||||
statTextArea.setEditable(false);
|
||||
statTextArea.prefWidthProperty().bind(mainPane.widthProperty());
|
||||
statTextArea.prefHeightProperty().bind(mainPane.heightProperty());
|
||||
}
|
||||
|
||||
void display(Map<String, String> statistics){
|
||||
List<String> lines = new ArrayList<>();
|
||||
|
||||
if(statistics!=null)
|
||||
lines.addAll(statistics.keySet()
|
||||
.stream()
|
||||
.map(key->String.format(" * %s : %s", key, statistics.get(key)))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
Platform.runLater(()->lines.forEach(line -> statTextArea.appendText(line+"\n")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.client.gui.modules.stat_screen.listeners;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface IStatScreenModelListener extends EventListener {
|
||||
void onStatisticsChangedEvent();
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.pqt.client.gui.modules.stock_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.IGuiModule;
|
||||
import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreen;
|
||||
import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreenFactory;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class StockScreen implements IGuiModule {
|
||||
|
||||
private StockScreenView view;
|
||||
|
||||
public StockScreen(StockService stockService, AccountService accountService) {
|
||||
StockScreenModel model = new StockScreenModel(stockService, accountService);
|
||||
StockScreenController ctrl = new StockScreenController(model);
|
||||
view = new StockScreenView(ctrl, new ProductManagerScreenFactory(stockService));
|
||||
|
||||
model.addListener(ctrl);
|
||||
ctrl.setView(view);
|
||||
ctrl.refreshView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModuleName() {
|
||||
return "Stock";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountLevel getLowestRequiredAccountLevel() {
|
||||
return AccountLevel.WAITER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return view.getPane();
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package com.pqt.client.gui.modules.stock_screen;
|
||||
|
||||
|
||||
import com.pqt.client.gui.modules.stock_screen.listeners.IStockItemEventListener;
|
||||
import com.pqt.client.gui.modules.stock_screen.listeners.IStockScreenModelListener;
|
||||
import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreen;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
|
||||
class StockScreenController implements IStockScreenModelListener{
|
||||
|
||||
private StockScreenModel model;
|
||||
private StockScreenView view;
|
||||
|
||||
StockScreenController(StockScreenModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
void setView(StockScreenView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
void onAddProductRequest() {
|
||||
detailProduct(null);
|
||||
}
|
||||
|
||||
void onDetailProductRequest() {
|
||||
if(view.getSelectedProduct()!=null)
|
||||
detailProduct(view.getSelectedProduct());
|
||||
}
|
||||
|
||||
private void detailProduct(Product product){
|
||||
view.switchToDetailMode(product);
|
||||
}
|
||||
|
||||
IValidatorComponentListener getDetailScreenValidationListener(){
|
||||
return new IValidatorComponentListener() {
|
||||
@Override
|
||||
public void onValidationEvent() {
|
||||
if(view.isDetailScreenCreationPossible()) {
|
||||
if (view.hasDetailScreenInitialValue()){
|
||||
modifyProduct(view.getDetailScreenInitialValue(), view.getDetailScreenCreation());
|
||||
}else{
|
||||
addProduct(view.getDetailScreenCreation());
|
||||
}
|
||||
view.switchToGeneralMode();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelEvent() {
|
||||
view.switchToGeneralMode();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void onDeleteProductRequest() {
|
||||
deleteProduct(view.getSelectedProduct());
|
||||
}
|
||||
|
||||
private void addProduct(Product product){
|
||||
model.commitProductAddition(product);
|
||||
}
|
||||
|
||||
private void modifyProduct(Product oldProduct, Product newProduct){
|
||||
model.commitProductModification(oldProduct, newProduct);
|
||||
}
|
||||
|
||||
private void deleteProduct(Product product){
|
||||
model.commitProductDeletion(product);;
|
||||
}
|
||||
|
||||
void onRefreshProductsRequest() {
|
||||
refreshView();
|
||||
}
|
||||
|
||||
IStockItemEventListener getProductActivationListener() {
|
||||
return this::detailProduct;
|
||||
}
|
||||
|
||||
void refreshView(){
|
||||
view.display(model.getProductCollection());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStockUpdatedEvent() {
|
||||
refreshView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAcccountConnectedStatusUpdatedEvent() {
|
||||
updateViewActionLock();
|
||||
}
|
||||
|
||||
void updateViewActionLock(){
|
||||
if(model.isAccountConnected() && model.getConnectedAccountLevel().compareTo(AccountLevel.MASTER)>=0){
|
||||
view.setAddProductActionLocked(false);
|
||||
view.setEditProductActionLocked(view.getSelectedProduct()==null);
|
||||
view.setRemoveProductActionLocked(view.getSelectedProduct()==null);
|
||||
}else{
|
||||
view.setAddProductActionLocked(true);
|
||||
view.setEditProductActionLocked(true);
|
||||
view.setRemoveProductActionLocked(true);
|
||||
}
|
||||
}
|
||||
|
||||
void onProductSelectedChange(){
|
||||
updateViewActionLock();
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.pqt.client.gui.modules.stock_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.stock_screen.listeners.IStockScreenModelListener;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.account.listeners.IAccountListener;
|
||||
import com.pqt.client.module.stock.Listeners.StockListenerAdapter;
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
class StockScreenModel {
|
||||
|
||||
private StockService stockService;
|
||||
private AccountService accountService;
|
||||
private EventListenerList listenerList;
|
||||
|
||||
StockScreenModel(StockService stockService, AccountService accountService) {
|
||||
listenerList = new EventListenerList();
|
||||
this.stockService = stockService;
|
||||
this.stockService.addListener(new StockListenerAdapter(){
|
||||
@Override
|
||||
public void onProductListChangedEvent() {
|
||||
StockScreenModel.this.fireProductCollectionChanged();
|
||||
}
|
||||
});
|
||||
this.accountService = accountService;
|
||||
this.accountService.addListener(new IAccountListener() {
|
||||
@Override
|
||||
public void onAccountStatusChangedEvent(boolean status) {
|
||||
StockScreenModel.this.fireConnectedStatusChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountListChangedEvent() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fireConnectedStatusChanged() {
|
||||
Arrays.stream(listenerList.getListeners(IStockScreenModelListener.class))
|
||||
.forEach(IStockScreenModelListener::onAcccountConnectedStatusUpdatedEvent);
|
||||
}
|
||||
|
||||
private void fireProductCollectionChanged() {
|
||||
Arrays.stream(listenerList.getListeners(IStockScreenModelListener.class))
|
||||
.forEach(IStockScreenModelListener::onStockUpdatedEvent);
|
||||
}
|
||||
|
||||
Collection<Product> getProductCollection() {
|
||||
return stockService.getProducts();
|
||||
}
|
||||
|
||||
void commitProductDeletion(Product product) {
|
||||
stockService.commitUpdate(stockService.getNewUpdateBuilder().removeProduct(product));
|
||||
}
|
||||
|
||||
void commitProductModification(Product oldProduct, Product newProduct) {
|
||||
stockService.commitUpdate(stockService.getNewUpdateBuilder().modifyProduct(oldProduct, newProduct));
|
||||
}
|
||||
|
||||
void commitProductAddition(Product product) {
|
||||
stockService.commitUpdate(stockService.getNewUpdateBuilder().addProduct(product));
|
||||
}
|
||||
|
||||
void addListener(IStockScreenModelListener l){
|
||||
listenerList.add(IStockScreenModelListener.class, l);
|
||||
}
|
||||
|
||||
void removeListener(IStockScreenModelListener l){
|
||||
listenerList.remove(IStockScreenModelListener.class, l);
|
||||
}
|
||||
|
||||
boolean isAccountConnected() {
|
||||
return accountService.isCurrentAccountLoggedIn();
|
||||
}
|
||||
|
||||
AccountLevel getConnectedAccountLevel() {
|
||||
if(accountService.getCurrentAccount()!=null)
|
||||
return accountService.getCurrentAccount().getPermissionLevel();
|
||||
else
|
||||
return AccountLevel.getLowest();
|
||||
}
|
||||
}
|
@ -0,0 +1,242 @@
|
||||
package com.pqt.client.gui.modules.stock_screen;
|
||||
|
||||
import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreen;
|
||||
import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreenFactory;
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.gui.ressources.strings.IObjectStringRenderer;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class StockScreenView implements IFXComponent {
|
||||
|
||||
private StockScreenController ctrl;
|
||||
private StackPane mainPane;
|
||||
private BorderPane mainPaneContent;
|
||||
private TableView<Product> stockTableView;
|
||||
private ProductManagerScreenFactory productManagerScreenFactory;
|
||||
private ProductManagerScreen currentDetailScreen;
|
||||
private Button addProductButton;
|
||||
private Button detailProductButton;
|
||||
private Button removeProductButton;
|
||||
|
||||
StockScreenView(StockScreenController ctrl, ProductManagerScreenFactory productManagerScreenFactory) {
|
||||
this.ctrl = ctrl;
|
||||
this.productManagerScreenFactory = productManagerScreenFactory;
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui() {
|
||||
mainPane = new StackPane();
|
||||
mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
|
||||
mainPaneContent = new BorderPane();
|
||||
mainPane.getChildren().add(mainPaneContent);
|
||||
mainPaneContent.prefWidthProperty().bind(mainPane.widthProperty());
|
||||
mainPaneContent.prefHeightProperty().bind(mainPane.heightProperty());
|
||||
|
||||
addProductButton = new Button(GUIStringTool.getAddButtonLabel());
|
||||
addProductButton.setOnMouseClicked(event -> ctrl.onAddProductRequest());
|
||||
detailProductButton = new Button(GUIStringTool.getDetailButtonLabel());
|
||||
detailProductButton.setOnMouseClicked(event -> ctrl.onDetailProductRequest());
|
||||
detailProductButton.setDisable(true);
|
||||
removeProductButton = new Button(GUIStringTool.getRemoveButtonLabel());
|
||||
removeProductButton.setDisable(true);
|
||||
removeProductButton.setOnMouseClicked(event -> ctrl.onDeleteProductRequest());
|
||||
Button refreshProductButton = new Button(GUIStringTool.getRefreshButtonLabel());
|
||||
refreshProductButton.setOnMouseClicked(event -> ctrl.onRefreshProductsRequest());
|
||||
|
||||
ToolBar actionToolbar = new ToolBar();
|
||||
actionToolbar.getItems().addAll(addProductButton, detailProductButton, removeProductButton, refreshProductButton);
|
||||
|
||||
HBox mainPaneTopContent = new HBox();
|
||||
HBox separator = new HBox();
|
||||
mainPaneTopContent.getChildren().addAll(separator, actionToolbar);
|
||||
HBox.setHgrow(separator, Priority.ALWAYS);
|
||||
mainPaneContent.setTop(mainPaneTopContent);
|
||||
|
||||
PseudoClass outOfStockPseudoClass = PseudoClass.getPseudoClass("stock-out");
|
||||
PseudoClass lowStockPseudoClass = PseudoClass.getPseudoClass("stock-low");
|
||||
PseudoClass highStockPseudoClass = PseudoClass.getPseudoClass("stock-high");
|
||||
stockTableView = new TableView<>();
|
||||
stockTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
stockTableView.setRowFactory(tableView->{
|
||||
TableRow<Product> row = new TableRow<>();
|
||||
row.itemProperty().addListener((obs, oldVal, newVal)->{
|
||||
if(newVal!=null){
|
||||
row.pseudoClassStateChanged(outOfStockPseudoClass, newVal.getAmountRemaining()<=0);
|
||||
row.pseudoClassStateChanged(lowStockPseudoClass, newVal.getAmountRemaining()>0 && newVal.getAmountRemaining()<30);
|
||||
row.pseudoClassStateChanged(highStockPseudoClass, newVal.getAmountRemaining()>=30);
|
||||
}else{
|
||||
row.pseudoClassStateChanged(outOfStockPseudoClass, false);
|
||||
row.pseudoClassStateChanged(lowStockPseudoClass, false);
|
||||
row.pseudoClassStateChanged(highStockPseudoClass, false);
|
||||
}
|
||||
});
|
||||
row.setOnMouseClicked(event -> {
|
||||
if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2)
|
||||
ctrl.getProductActivationListener().onProductActivated(row.getItem());
|
||||
});
|
||||
row.setOnKeyTyped(event -> {
|
||||
if (event.getCode().equals(KeyCode.ENTER))
|
||||
ctrl.getProductActivationListener().onProductActivated(row.getItem());
|
||||
});
|
||||
return row;
|
||||
});
|
||||
stockTableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
|
||||
stockTableView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal)->ctrl.onProductSelectedChange());
|
||||
List<TableColumn<Product, ?>> columns = new ArrayList<>();
|
||||
|
||||
columns.add(createNewTableColumn(String.class,
|
||||
GUIStringTool.getProductNameColumnHeader(),
|
||||
param -> new SimpleStringProperty(param.getValue().getName()),
|
||||
null
|
||||
));
|
||||
columns.add(createNewTableColumn(String.class,
|
||||
GUIStringTool.getProductCategoryColumnHeader(),
|
||||
param -> new SimpleStringProperty(param.getValue().getCategory().getName()),
|
||||
null
|
||||
));
|
||||
columns.add(createNewTableColumn(Integer.class,
|
||||
GUIStringTool.getProductAmountRemainingColumnHeader(),
|
||||
param -> new SimpleIntegerProperty(param.getValue().getAmountRemaining()).asObject(),
|
||||
null
|
||||
));
|
||||
columns.add(createNewTableColumn(Integer.class,
|
||||
GUIStringTool.getProductAmountSoldColumnHeader(),
|
||||
param -> new SimpleIntegerProperty(param.getValue().getAmountSold()).asObject(),
|
||||
null
|
||||
));
|
||||
columns.add(createNewTableColumn(Double.class,
|
||||
GUIStringTool.getProductPriceColumnHeader(),
|
||||
param -> new SimpleDoubleProperty(param.getValue().getPrice()).asObject(),
|
||||
GUIStringTool.getPriceRenderer()
|
||||
));
|
||||
columns.add(createNewTableColumn(Boolean.class,
|
||||
GUIStringTool.getProductIsSellableColumnHeader(),
|
||||
param -> new SimpleBooleanProperty(param.getValue().isSellable()),
|
||||
GUIStringTool.getBooleanRenderer()
|
||||
));
|
||||
|
||||
stockTableView.getColumns().addAll(columns);
|
||||
mainPaneContent.setCenter(stockTableView);
|
||||
}
|
||||
|
||||
private <T> TableColumn<Product, T> createNewTableColumn(Class<T> clazz,
|
||||
String header,
|
||||
Callback<TableColumn.CellDataFeatures<Product, T>, ObservableValue<T>> cellValueFactory,
|
||||
IObjectStringRenderer<T> renderer){
|
||||
TableColumn<Product, T> column = new TableColumn<>();
|
||||
if(header!=null)
|
||||
column.setText(header);
|
||||
if(cellValueFactory!=null)
|
||||
column.setCellValueFactory(cellValueFactory);
|
||||
if(renderer!=null)
|
||||
column.setCellFactory(table -> new TableCell<Product, T>() {
|
||||
@Override
|
||||
protected void updateItem(T item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item == null || empty) {
|
||||
setText(null);
|
||||
setStyle("");
|
||||
} else {
|
||||
setText(renderer.render(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return column;
|
||||
}
|
||||
|
||||
void display(Collection<Product> productCollection){
|
||||
Platform.runLater(()->{
|
||||
this.stockTableView.getItems().clear();
|
||||
this.stockTableView.getItems().addAll(productCollection);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
Product getSelectedProduct() {
|
||||
return stockTableView.getSelectionModel().getSelectedItem();
|
||||
}
|
||||
|
||||
void switchToDetailMode(Product product) {
|
||||
if(currentDetailScreen==null){
|
||||
currentDetailScreen = productManagerScreenFactory.create(product);
|
||||
currentDetailScreen.addListener(ctrl.getDetailScreenValidationListener());
|
||||
Pane separator = new Pane();
|
||||
separator.getStyleClass().add(GUICssTool.getIntermediaryPaneStyleClass());
|
||||
Platform.runLater(()->mainPane.getChildren().addAll(separator, currentDetailScreen.getPane()));
|
||||
}
|
||||
}
|
||||
|
||||
void switchToGeneralMode() {
|
||||
if(currentDetailScreen!=null){
|
||||
List<Node> toRemove = mainPane.getChildren()
|
||||
.stream()
|
||||
.filter(node->!node.equals(mainPaneContent))
|
||||
.collect(Collectors.toList());
|
||||
Platform.runLater(()->{
|
||||
mainPane.getChildren().removeAll(toRemove);
|
||||
currentDetailScreen = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
boolean isDetailScreenCreationPossible() {
|
||||
System.out.println("test creation possible : ");
|
||||
return currentDetailScreen!=null && currentDetailScreen.isCreationPossible();
|
||||
}
|
||||
|
||||
boolean hasDetailScreenInitialValue() {
|
||||
return currentDetailScreen!=null && currentDetailScreen.hasInitialValue();
|
||||
}
|
||||
|
||||
Product getDetailScreenInitialValue() {
|
||||
if(currentDetailScreen!=null)
|
||||
return currentDetailScreen.getInitialValueSnapshot();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
Product getDetailScreenCreation() {
|
||||
if(currentDetailScreen!=null)
|
||||
return currentDetailScreen.create();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
void setAddProductActionLocked(boolean locked){
|
||||
addProductButton.setDisable(locked);
|
||||
}
|
||||
|
||||
void setRemoveProductActionLocked(boolean locked){
|
||||
removeProductButton.setDisable(locked);
|
||||
}
|
||||
|
||||
void setEditProductActionLocked(boolean locked){
|
||||
detailProductButton.setDisable(locked);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.client.gui.modules.stock_screen.listeners;
|
||||
|
||||
import com.pqt.core.entities.product.Product;
|
||||
|
||||
public interface IStockItemEventListener {
|
||||
void onProductActivated(Product product);
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.pqt.client.gui.modules.stock_screen.listeners;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface IStockScreenModelListener extends EventListener {
|
||||
void onStockUpdatedEvent();
|
||||
void onAcccountConnectedStatusUpdatedEvent();
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.pqt.client.gui.modules.stock_screen.product_manager_screen;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.creators.IFXCreatorComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.IFXValidatorComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class ProductManagerScreen implements IFXCreatorComponent<Product>, IFXValidatorComponent {
|
||||
|
||||
private ProductManagerScreenView view;
|
||||
private ProductManagerScreenModel model;
|
||||
private ProductManagerScreenController ctrl;
|
||||
|
||||
public ProductManagerScreen(Product initialData, StockService stockService){
|
||||
model = new ProductManagerScreenModel(initialData, stockService);
|
||||
ctrl = new ProductManagerScreenController(model);
|
||||
view = new ProductManagerScreenView(ctrl);
|
||||
ctrl.setView(view);
|
||||
ctrl.updateView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Product create() {
|
||||
return model.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreationPossible() {
|
||||
return model.isProductCreationPossible();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return view.getPane();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IValidatorComponentListener l) {
|
||||
ctrl.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IValidatorComponentListener l) {
|
||||
ctrl.removeListener(l);
|
||||
}
|
||||
|
||||
public boolean hasInitialValue(){
|
||||
return model.hasInitialData();
|
||||
}
|
||||
|
||||
public Product getInitialValueSnapshot(){
|
||||
return new Product(model.getInitialData());
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package com.pqt.client.gui.modules.stock_screen.product_manager_screen;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.core.entities.product.Category;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
|
||||
class ProductManagerScreenController {
|
||||
|
||||
private EventListenerList listenerList;
|
||||
private ProductManagerScreenModel model;
|
||||
private ProductManagerScreenView view;
|
||||
|
||||
ProductManagerScreenController(ProductManagerScreenModel model) {
|
||||
listenerList = new EventListenerList();
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
void setView(ProductManagerScreenView view){
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
ChangeListener<? super Product> getProductComponentSelectionListener() {
|
||||
return (obs, oldValue, newValue)->{
|
||||
if(newValue!=null) {
|
||||
if (model.isComponent(newValue))
|
||||
model.removeComponent(newValue);
|
||||
else
|
||||
model.addComponent(newValue);
|
||||
updateView();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void updateView() {
|
||||
view.setProduct(model.getActualProductState());
|
||||
view.setCategoryCollection(model.getCategoryCollection());
|
||||
view.setProductCollection(model.getEligibleComponentList());
|
||||
}
|
||||
|
||||
IValidatorComponentListener getValidatorListener() {
|
||||
return new IValidatorComponentListener() {
|
||||
@Override
|
||||
public void onValidationEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class)).forEach(IValidatorComponentListener::onValidationEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class)).forEach(IValidatorComponentListener::onCancelEvent);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void addListener(IValidatorComponentListener l) {
|
||||
listenerList.add(IValidatorComponentListener.class, l);
|
||||
}
|
||||
|
||||
public void removeListener(IValidatorComponentListener l) {
|
||||
listenerList.remove(IValidatorComponentListener.class, l);
|
||||
}
|
||||
|
||||
boolean isProductHighlighted(Product product) {
|
||||
return model.getActualProductState().getComponents().contains(product);
|
||||
}
|
||||
|
||||
void onNameChanged(String oldVal, String newVal) {
|
||||
model.changeName(newVal);
|
||||
}
|
||||
|
||||
void onPriceChanged(double oldVal, double newVal) {
|
||||
model.changePrice(newVal);
|
||||
}
|
||||
|
||||
void onCategoryChanged(Category oldVal, Category newVal) {
|
||||
model.changeCategory(newVal);
|
||||
}
|
||||
|
||||
void onAmountRemainingChanged(int oldVal, int newVal) {
|
||||
model.changeAmountRemaining(newVal);
|
||||
}
|
||||
|
||||
void onAmountSoldChanged(int oldVal, int newVal) {
|
||||
model.changeAmountSold(newVal);
|
||||
}
|
||||
|
||||
void onSellableStateChanged(boolean oldVal, boolean newVal) {
|
||||
model.setSellable(newVal);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.pqt.client.gui.modules.stock_screen.product_manager_screen;
|
||||
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
|
||||
public final class ProductManagerScreenFactory {
|
||||
|
||||
private StockService stockService;
|
||||
|
||||
public ProductManagerScreenFactory(StockService stockService) {
|
||||
this.stockService = stockService;
|
||||
}
|
||||
|
||||
public ProductManagerScreen create(Product product){
|
||||
return new ProductManagerScreen(product, stockService);
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package com.pqt.client.gui.modules.stock_screen.product_manager_screen;
|
||||
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
import com.pqt.core.entities.product.Category;
|
||||
import com.pqt.core.entities.product.LightweightProduct;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class ProductManagerScreenModel {
|
||||
|
||||
private StockService stockService;
|
||||
private Product initialData;
|
||||
private Product currentData;
|
||||
|
||||
ProductManagerScreenModel(Product initialData, StockService stockService) {
|
||||
this.stockService = stockService;
|
||||
this.initialData = initialData;
|
||||
if(initialData==null)
|
||||
currentData = new Product();
|
||||
else
|
||||
currentData = new Product(initialData);
|
||||
}
|
||||
|
||||
List<Product> getEligibleComponentList() {
|
||||
return stockService.getProductsExcluding(currentData);
|
||||
}
|
||||
|
||||
Product getActualProductState(){
|
||||
return currentData;
|
||||
}
|
||||
|
||||
Product create() {
|
||||
if(isProductCreationPossible())
|
||||
return currentData;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isProductCreationPossible() {
|
||||
return (initialData!=null && !currentData.equals(initialData))
|
||||
&& !currentData.getName().isEmpty()
|
||||
&& currentData.getCategory()!=null
|
||||
&& currentData.getPrice()>=0;
|
||||
}
|
||||
|
||||
void addComponent(Product product) {
|
||||
currentData.getComponents().add(product);
|
||||
}
|
||||
|
||||
void removeComponent(Product product) {
|
||||
currentData.getComponents().remove(product);
|
||||
}
|
||||
|
||||
void changeCategory(Category category){
|
||||
this.currentData.setCategory(category);
|
||||
}
|
||||
|
||||
void changePrice(double price){
|
||||
this.currentData.setPrice(price);
|
||||
}
|
||||
|
||||
void changeName(String name){
|
||||
this.currentData.setName(name);
|
||||
}
|
||||
|
||||
void changeAmountRemaining(int amount){
|
||||
this.currentData.setAmountRemaining(amount);
|
||||
}
|
||||
|
||||
void changeAmountSold(int amount){
|
||||
this.currentData.setAmountSold(amount);
|
||||
}
|
||||
|
||||
void setSellable(boolean sellable){
|
||||
this.currentData.setSellable(sellable);
|
||||
}
|
||||
|
||||
Collection<Category> getCategoryCollection() {
|
||||
return stockService.getProducts()
|
||||
.stream()
|
||||
.map(Product::getCategory)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
boolean isComponent(Product product) {
|
||||
return currentData.getComponents().contains(product);
|
||||
}
|
||||
|
||||
boolean hasInitialData(){
|
||||
return initialData!=null;
|
||||
}
|
||||
|
||||
Product getInitialData(){
|
||||
return initialData;
|
||||
}
|
||||
}
|
@ -0,0 +1,212 @@
|
||||
package com.pqt.client.gui.modules.stock_screen.product_manager_screen;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.SimpleValidator;
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.javafx_override.CssEnabledGridPane;
|
||||
import com.pqt.client.gui.ressources.components.generics.javafx_override.HighlightListCell;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.core.entities.product.Category;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collection;
|
||||
|
||||
class ProductManagerScreenView implements IFXComponent {
|
||||
|
||||
private ProductManagerScreenController ctrl;
|
||||
|
||||
private int gridLines;
|
||||
private StackPane mainPane;
|
||||
private BorderPane mainPaneContent;
|
||||
private TextField productNameTextField,
|
||||
productAmountRemainingTextField,
|
||||
productAmountSoldTextField,
|
||||
productPriceTextField;
|
||||
private ComboBox<Category> productCategoryComboBox;
|
||||
private CheckBox productSellableCheckBox;
|
||||
private ListView<Product> productComponentsListView;
|
||||
|
||||
ProductManagerScreenView(ProductManagerScreenController ctrl) {
|
||||
this.ctrl = ctrl;
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui() {
|
||||
mainPane = new StackPane();
|
||||
mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
|
||||
|
||||
mainPaneContent = new BorderPane();
|
||||
|
||||
GridPane mainPaneCenterContent = new CssEnabledGridPane();
|
||||
mainPaneCenterContent.setAlignment(Pos.CENTER);
|
||||
gridLines = 0;
|
||||
NumberFormat priceFormat = NumberFormat.getNumberInstance();
|
||||
NumberFormat intFormat = NumberFormat.getIntegerInstance();
|
||||
|
||||
Label productNameLabel = new Label(GUIStringTool.getProductNameLabel());
|
||||
productNameTextField = new TextField();
|
||||
productNameTextField.textProperty().addListener((obs, oldVal, newVal)->ctrl.onNameChanged(oldVal,newVal));
|
||||
addLineToGrid(mainPaneCenterContent, productNameLabel, productNameTextField);
|
||||
|
||||
Label productCategoryLabel = new Label(GUIStringTool.getProductCategoryLabel());
|
||||
productCategoryComboBox = new ComboBox<>();
|
||||
productCategoryComboBox.setEditable(true);
|
||||
productCategoryComboBox.setConverter(GUIStringTool.getCategoryStringConverter());
|
||||
productCategoryComboBox.valueProperty().addListener((obs, oldVal, newVal)->ctrl.onCategoryChanged(oldVal, newVal));
|
||||
addLineToGrid(mainPaneCenterContent, productCategoryLabel, productCategoryComboBox);
|
||||
|
||||
Label productAmountRemainingLabel = new Label(GUIStringTool.getProductAmountRemainingLabel());
|
||||
productAmountRemainingTextField = getNumberOnlyTextField(intFormat);
|
||||
productAmountRemainingTextField.textProperty().addListener((obs, oldVal, newVal)->{
|
||||
try{
|
||||
int oldInt = oldVal.isEmpty()?0:Integer.parseInt(oldVal);
|
||||
int newInt = newVal.isEmpty()?0:Integer.parseInt(newVal);
|
||||
ctrl.onAmountRemainingChanged(oldInt, newInt);
|
||||
}catch(NumberFormatException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
addLineToGrid(mainPaneCenterContent, productAmountRemainingLabel, productAmountRemainingTextField);
|
||||
|
||||
Label productAmountSoldLabel = new Label(GUIStringTool.getProductAmountSoldLabel());
|
||||
productAmountSoldTextField = getNumberOnlyTextField(intFormat);
|
||||
productAmountSoldTextField.textProperty().addListener((obs, oldVal, newVal)->{
|
||||
try{
|
||||
int oldInt = oldVal.isEmpty()?0:Integer.parseInt(oldVal);
|
||||
int newInt = newVal.isEmpty()?0:Integer.parseInt(newVal);
|
||||
ctrl.onAmountSoldChanged(oldInt, newInt);
|
||||
}catch(NumberFormatException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
addLineToGrid(mainPaneCenterContent, productAmountSoldLabel, productAmountSoldTextField);
|
||||
|
||||
Label productSellableLabel = new Label(GUIStringTool.getProductSellableLabel());
|
||||
productSellableCheckBox = new CheckBox();
|
||||
productSellableCheckBox.selectedProperty().addListener((obs, oldVal, newVal)->ctrl.onSellableStateChanged(oldVal,newVal));
|
||||
addLineToGrid(mainPaneCenterContent, productSellableLabel, productSellableCheckBox);
|
||||
|
||||
Label productPriceLabel = new Label(GUIStringTool.getProductPriceLabel());
|
||||
productPriceTextField = getNumberOnlyTextField(priceFormat);
|
||||
productPriceTextField.textProperty().addListener((obs, oldVal, newVal)->{
|
||||
try{
|
||||
ctrl.onPriceChanged((oldVal.isEmpty()?-1:Double.parseDouble(oldVal)), (newVal.isEmpty()?-1:Double.parseDouble(newVal)));
|
||||
}catch(NumberFormatException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
addLineToGrid(mainPaneCenterContent, productPriceLabel, productPriceTextField);
|
||||
|
||||
mainPaneContent.setCenter(mainPaneCenterContent);
|
||||
|
||||
VBox mainPaneRightContent = new VBox();
|
||||
mainPaneRightContent.setAlignment(Pos.CENTER);
|
||||
Label title = new Label(GUIStringTool.getComponentListTitleLabel());
|
||||
title.setAlignment(Pos.CENTER);
|
||||
title.getStyleClass().add(GUICssTool.getTitleTextStyleClass());
|
||||
productComponentsListView = new ListView<>();
|
||||
productComponentsListView.setCellFactory(listView->new HighlightListCell<Product>(){
|
||||
@Override
|
||||
protected void updateItem(Product item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if(item==null || empty){
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
}else{
|
||||
setText(GUIStringTool.getSimpleProductStringRenderer().render(item));
|
||||
if(ctrl.isProductHighlighted(item)){
|
||||
if(!isHightlighted()) {
|
||||
setHighLight(true);
|
||||
applyCss();
|
||||
}
|
||||
}else {
|
||||
if (isHightlighted()) {
|
||||
setHighLight(false);
|
||||
applyCss();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
productComponentsListView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
|
||||
productComponentsListView.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue)->{
|
||||
this.ctrl.getProductComponentSelectionListener().changed(obs, oldValue, newValue);
|
||||
if(newValue!=null)
|
||||
Platform.runLater(()->productComponentsListView.getSelectionModel().clearSelection(productComponentsListView.getSelectionModel().getSelectedIndex()));
|
||||
});
|
||||
|
||||
mainPaneRightContent.getChildren().addAll(title, productComponentsListView);
|
||||
mainPaneContent.setRight(mainPaneRightContent);
|
||||
|
||||
HBox mainPaneBottomContent = new HBox();
|
||||
HBox separator = new HBox();
|
||||
SimpleValidator validator = new SimpleValidator();
|
||||
validator.addListener(ctrl.getValidatorListener());
|
||||
mainPaneBottomContent.getChildren().addAll(separator, validator.getPane());
|
||||
HBox.setHgrow(separator, Priority.ALWAYS);
|
||||
|
||||
mainPaneContent.setBottom(mainPaneBottomContent);
|
||||
mainPane.getChildren().add(mainPaneContent);
|
||||
}
|
||||
|
||||
private void addLineToGrid(GridPane grid, Node... nodes){
|
||||
gridLines++;
|
||||
int columnIndex = 0;
|
||||
for(Node node : nodes){
|
||||
grid.add(node, columnIndex, gridLines);
|
||||
columnIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private TextField getNumberOnlyTextField(NumberFormat format){
|
||||
TextField textField = new TextField();
|
||||
textField.textProperty().addListener((obs, oldValue, newValue)->{
|
||||
if(!newValue.matches("^[-+]?[0-9]+[.,]?[0-9]*$"))
|
||||
Platform.runLater(()->textField.setText(oldValue));
|
||||
});
|
||||
return textField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
void setProduct(Product product){
|
||||
if(product!=null){
|
||||
Platform.runLater(()->{
|
||||
productNameTextField.setText(product.getName());
|
||||
productCategoryComboBox.setValue(product.getCategory());
|
||||
productAmountRemainingTextField.setText(Integer.toString(product.getAmountRemaining()));
|
||||
productAmountRemainingTextField.setEditable(product.getComponents().isEmpty());
|
||||
productAmountSoldTextField.setText(Integer.toString(product.getAmountSold()));
|
||||
productComponentsListView.getItems().clear();
|
||||
productComponentsListView.getItems().addAll(product.getComponents());
|
||||
productSellableCheckBox.setSelected(product.isSellable());
|
||||
productPriceTextField.setText(Double.toString(product.getPrice()));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setCategoryCollection(Collection<Category> categoryCollection){
|
||||
Platform.runLater(()->{
|
||||
productCategoryComboBox.getItems().clear();
|
||||
productCategoryComboBox.getItems().addAll(categoryCollection);
|
||||
});
|
||||
}
|
||||
|
||||
void setProductCollection(Collection<Product> productCollection){
|
||||
Platform.runLater(()->{
|
||||
productComponentsListView.getItems().clear();
|
||||
productComponentsListView.getItems().addAll(productCollection);
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
package com.pqt.client.gui.ressources.components;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.creators.IFXCreatorComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.IFXValidatorComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.listeners.IAccountComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.SimpleValidatorComponentFirerer;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.IFXAccountsDisplayerComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.listeners.SimpleAccountComponentFirerer;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class AccountManager implements IFXAccountsDisplayerComponent, IFXValidatorComponent, IFXCreatorComponent<Account> {
|
||||
|
||||
private Pane mainPane;
|
||||
|
||||
private VBox mainDisconnectedPane, mainConnectedPane;
|
||||
private TextField connectedUsernameField;
|
||||
private ChoiceBox<Account> disconnectedUsernameField;
|
||||
private PasswordField passwordField;
|
||||
|
||||
private SimpleAccountComponentFirerer accountEventFirerer;
|
||||
private SimpleValidatorComponentFirerer validatorEventFirerer;
|
||||
|
||||
private Account currentAccount;
|
||||
|
||||
public AccountManager() {
|
||||
accountEventFirerer = new SimpleAccountComponentFirerer();
|
||||
validatorEventFirerer = new SimpleValidatorComponentFirerer();
|
||||
|
||||
currentAccount = null;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mainPane = new Pane();
|
||||
|
||||
mainConnectedPane = new VBox();
|
||||
mainDisconnectedPane = new VBox();
|
||||
|
||||
connectedUsernameField = new TextField();
|
||||
connectedUsernameField.setEditable(false);
|
||||
|
||||
Button disconnectButton = new Button(GUIStringTool.getLogoutButtonLabel());
|
||||
disconnectButton.setOnMouseClicked(event->validatorEventFirerer.fireCancelEvent());
|
||||
disconnectButton.setOnKeyTyped(event->{if(event.getCode().equals(KeyCode.ENTER)) validatorEventFirerer.fireCancelEvent();});
|
||||
|
||||
mainConnectedPane.getChildren().addAll(connectedUsernameField, disconnectButton);
|
||||
|
||||
|
||||
disconnectedUsernameField = new ChoiceBox<>();
|
||||
disconnectedUsernameField.setConverter(GUIStringTool.getAccountStringConverter());
|
||||
|
||||
passwordField = new PasswordField();
|
||||
passwordField.setPromptText(GUIStringTool.getPasswordFieldPromptText());
|
||||
|
||||
Button validationButton = new Button(GUIStringTool.getLoginButtonLabel());
|
||||
validationButton.setOnMouseClicked(event-> validatorEventFirerer.fireValidationEvent());
|
||||
validationButton.setOnKeyTyped(event->{if(event.getCode().equals(KeyCode.ENTER)) validatorEventFirerer.fireValidationEvent();});
|
||||
|
||||
mainDisconnectedPane.getChildren().addAll(disconnectedUsernameField, passwordField, validationButton);
|
||||
|
||||
refreshMainPane();
|
||||
display(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(Collection<Account> content) {
|
||||
Platform.runLater(()->{
|
||||
if(content!=null && content.size()>0)
|
||||
disconnectedUsernameField.setItems(FXCollections.observableArrayList(content));
|
||||
else{
|
||||
disconnectedUsernameField.getItems().clear();
|
||||
disconnectedUsernameField.getItems().add(new Account("null", "", AccountLevel.getLowest()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setCurrentAccount(Account account){
|
||||
currentAccount = account;
|
||||
Platform.runLater(()->connectedUsernameField.setText(GUIStringTool.getAccountStringConverter().toString(currentAccount)));
|
||||
refreshMainPane();
|
||||
}
|
||||
|
||||
private void refreshMainPane() {
|
||||
if(currentAccount!=null)
|
||||
Platform.runLater(
|
||||
()->{
|
||||
mainPane.getChildren().clear();
|
||||
mainPane.getChildren().add(mainConnectedPane);
|
||||
}
|
||||
);
|
||||
else
|
||||
Platform.runLater(
|
||||
()->{
|
||||
mainPane.getChildren().clear();
|
||||
mainPane.getChildren().add(mainDisconnectedPane);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public Account getCurrentAccount() {
|
||||
return currentAccount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IAccountComponentListener l) {
|
||||
accountEventFirerer.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IAccountComponentListener l) {
|
||||
accountEventFirerer.removeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IValidatorComponentListener l) {
|
||||
validatorEventFirerer.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IValidatorComponentListener l) {
|
||||
validatorEventFirerer.removeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account create() {
|
||||
if(!isCreationPossible())
|
||||
return null;
|
||||
|
||||
return new Account(disconnectedUsernameField.getValue().getUsername(), passwordField.getText(), disconnectedUsernameField.getValue().getPermissionLevel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreationPossible() {
|
||||
return currentAccount==null
|
||||
&& disconnectedUsernameField.getAccessibleText()!=null
|
||||
&& !disconnectedUsernameField.getAccessibleText().isEmpty()
|
||||
&& passwordField.getText()!=null
|
||||
&& !passwordField.getText().isEmpty();
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
package com.pqt.client.gui.ressources.components;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.IFXDisplayerComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.products.listeners.IStockComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.specifics.products.listeners.SimpleStockComponentFirerer;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.gui.ressources.strings.IObjectStringRenderer;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CategoryTabStockDisplayer implements IFXDisplayerComponent<Collection<Product>, IStockComponentListener> {
|
||||
|
||||
private SimpleStockComponentFirerer firerer;
|
||||
private BorderPane mainPane;
|
||||
private TabPane tabPane;
|
||||
|
||||
public CategoryTabStockDisplayer() {
|
||||
init();
|
||||
firerer = new SimpleStockComponentFirerer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(Collection<Product> content) {
|
||||
final ObservableList<Tab> tabs = FXCollections.observableArrayList();
|
||||
if(content!=null){
|
||||
List<String> categories = content.stream().map(product->product.getCategory().getName()).distinct().collect(Collectors.toList());
|
||||
|
||||
for(String cat : categories){
|
||||
tabs.add(createCategoryTab(cat, content.stream().filter(p->p.getCategory().getName().equals(cat)).collect(Collectors.toList())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Platform.runLater(()->{
|
||||
tabPane.getTabs().clear();
|
||||
tabPane.getTabs().addAll(tabs);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IStockComponentListener l) {
|
||||
firerer.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IStockComponentListener l) {
|
||||
firerer.removeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
private void init(){
|
||||
mainPane = new BorderPane();
|
||||
|
||||
Label title = new Label(GUIStringTool.getCategorytabStockDisplayerTitle());
|
||||
title.setAlignment(Pos.CENTER);
|
||||
title.getStyleClass().add(GUICssTool.getTitleTextStyleClass());
|
||||
|
||||
HBox topPane = new HBox();
|
||||
topPane.setFillHeight(true);
|
||||
topPane.setAlignment(Pos.CENTER);
|
||||
topPane.getChildren().add(title);
|
||||
|
||||
mainPane.setTop(topPane);
|
||||
|
||||
tabPane = new TabPane();
|
||||
mainPane.setCenter(tabPane);
|
||||
}
|
||||
|
||||
private Tab createCategoryTab(String categoryName, Collection<Product> products){
|
||||
Tab tab = new Tab(categoryName);
|
||||
tab.closableProperty().setValue(false);
|
||||
|
||||
ListView<Product> listView = new ListView<>();
|
||||
listView.setCellFactory(list->new ListCell<Product>(){
|
||||
|
||||
@Override
|
||||
protected void updateItem(Product item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (empty || item == null) {
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
} else {
|
||||
setText(CategoryTabStockDisplayer.getProductRenderer().render(item));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
listView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
|
||||
listView.setEditable(false);
|
||||
listView.setOnMouseClicked(event->{
|
||||
firerer.fireContentClickEvent(event, listView.getSelectionModel().getSelectedItem());
|
||||
Platform.runLater(()->listView.getSelectionModel().clearSelection(listView.getSelectionModel().getSelectedIndex()));
|
||||
});
|
||||
listView.setOnKeyTyped(event -> {
|
||||
if(event.getCode().equals(KeyCode.ENTER)){
|
||||
firerer.fireContentClickEvent(event, listView.getSelectionModel().getSelectedItem());
|
||||
Platform.runLater(()->listView.getSelectionModel().clearSelection(listView.getSelectionModel().getSelectedIndex()));
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
|
||||
listView.setItems(FXCollections.observableArrayList(products));
|
||||
|
||||
tab.setContent(listView);
|
||||
return tab;
|
||||
}
|
||||
|
||||
private static IObjectStringRenderer<Product> getProductRenderer(){
|
||||
return GUIStringTool.getDetailledProductStringRenderer();
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package com.pqt.client.gui.ressources.components;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.specifics.sale.IFXSaleDisplayerComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.sale.listeners.ISaleComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.specifics.sale.listeners.SimpleSaleComponentFirerer;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class CommandComposerSaleDisplayer implements IFXSaleDisplayerComponent {
|
||||
|
||||
private SimpleSaleComponentFirerer firerer;
|
||||
private BorderPane mainPane;
|
||||
private ListView<Product> listView;
|
||||
|
||||
private Sale sale;
|
||||
|
||||
public CommandComposerSaleDisplayer() {
|
||||
firerer = new SimpleSaleComponentFirerer();
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mainPane = new BorderPane();
|
||||
|
||||
Label title = new Label(GUIStringTool.getCommandComposerTitleLabel());
|
||||
title.setAlignment(Pos.CENTER);
|
||||
title.getStyleClass().add(GUICssTool.getTitleTextStyleClass());
|
||||
|
||||
HBox topPane = new HBox();
|
||||
topPane.setFillHeight(true);
|
||||
topPane.setAlignment(Pos.CENTER);
|
||||
topPane.getChildren().add(title);
|
||||
|
||||
mainPane.setTop(topPane);
|
||||
|
||||
listView = new ListView<>();
|
||||
listView.setCellFactory(list->new ListCell<Product>(){
|
||||
@Override
|
||||
protected void updateItem(Product item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (empty || item == null) {
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
} else {
|
||||
setText(GUIStringTool.getSaleItemStringRenderer().render(item, sale.getProducts().get(item)));
|
||||
}
|
||||
}
|
||||
});
|
||||
listView.setEditable(false);
|
||||
listView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
|
||||
listView.setOnMouseClicked(event->firerer.fireComponentClickEvent(event, listView.getSelectionModel().getSelectedItem()));
|
||||
listView.setOnKeyTyped(event -> {
|
||||
if(event.getCode().equals(KeyCode.ENTER)){
|
||||
firerer.fireComponentClickEvent(event, listView.getSelectionModel().getSelectedItem());
|
||||
}
|
||||
});
|
||||
mainPane.setCenter(listView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(Sale content) {
|
||||
if(content ==null)
|
||||
return;
|
||||
|
||||
this.sale = content;
|
||||
Platform.runLater(()->{
|
||||
this.listView.getItems().clear();
|
||||
this.listView.getItems().addAll(this.sale.getProducts().keySet());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(ISaleComponentListener l) {
|
||||
firerer.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(ISaleComponentListener l) {
|
||||
firerer.removeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package com.pqt.client.gui.ressources.components;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.IFXValidatorComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentFirerer;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.SimpleValidatorComponentFirerer;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class SimpleValidator implements IFXValidatorComponent {
|
||||
|
||||
private final IValidatorComponentFirerer firerer;
|
||||
private Pane pane;
|
||||
private boolean askConfirmation;
|
||||
private Button validationButton, cancelButton;
|
||||
|
||||
public SimpleValidator() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public SimpleValidator(boolean askConfirmation) {
|
||||
firerer = new SimpleValidatorComponentFirerer();
|
||||
this.askConfirmation = askConfirmation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IValidatorComponentListener l) {
|
||||
firerer.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IValidatorComponentListener l) {
|
||||
firerer.removeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
if(pane == null)
|
||||
pane = createPane();
|
||||
return pane;
|
||||
}
|
||||
|
||||
private Pane createPane(){
|
||||
GridPane grid = new GridPane();
|
||||
grid.getStyleClass().add("validator");
|
||||
|
||||
validationButton = new Button(GUIStringTool.getValidationButtonLabel());
|
||||
validationButton.setOnMouseClicked(event->{
|
||||
getValidationButtonProcess().process();
|
||||
});
|
||||
grid.add(validationButton, 0,0);
|
||||
|
||||
cancelButton = new Button(GUIStringTool.getCancelButtonLabel());
|
||||
cancelButton.setOnMouseClicked(event->{
|
||||
getCancelButtonProcess().process();
|
||||
});
|
||||
grid.add(cancelButton, 1, 0);
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
private IButtonProcess getValidationButtonProcess(){
|
||||
return ()->{
|
||||
if(validationButton.getText().equals(GUIStringTool.getValidationButtonLabel())){
|
||||
if(askConfirmation)
|
||||
Platform.runLater(()->validationButton.setText(GUIStringTool.getConfirmationValidationButtonLabel()));
|
||||
else
|
||||
firerer.fireValidationEvent();
|
||||
}else{
|
||||
if(validationButton.getText().equals(GUIStringTool.getConfirmationValidationButtonLabel()))
|
||||
firerer.fireValidationEvent();
|
||||
Platform.runLater(()->validationButton.setText(GUIStringTool.getValidationButtonLabel()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IButtonProcess getCancelButtonProcess(){
|
||||
return ()->{
|
||||
if(cancelButton.getText().equals(GUIStringTool.getCancelButtonLabel())){
|
||||
if(askConfirmation)
|
||||
Platform.runLater(()->cancelButton.setText(GUIStringTool.getConfirmationCancelButtonLabel()));
|
||||
else
|
||||
firerer.fireCancelEvent();
|
||||
}else{
|
||||
Platform.runLater(()->cancelButton.setText(GUIStringTool.getCancelButtonLabel()));
|
||||
firerer.fireCancelEvent();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
private interface IButtonProcess{
|
||||
void process();
|
||||
}
|
||||
|
||||
public void setValidationButtonEnable(boolean enable){
|
||||
this.validationButton.setDisable(!enable);
|
||||
}
|
||||
|
||||
public void setCancelationButtonEnable(boolean enable){
|
||||
this.cancelButton.setDisable(!enable);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.client.gui.ressources.components.generics;
|
||||
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public interface IFXComponent {
|
||||
Pane getPane();
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.creators;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
|
||||
public interface IFXCreatorComponent<T> extends IFXComponent{
|
||||
T create();
|
||||
boolean isCreationPossible();
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.displayers;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.listeners.IDisplayerComponentListener;
|
||||
|
||||
public interface IFXDisplayerComponent<T, U extends IDisplayerComponentListener> extends IFXComponent{
|
||||
void display(T content);
|
||||
void addListener(U l);
|
||||
void removeListener(U l);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.displayers.listeners;
|
||||
|
||||
import javafx.event.Event;
|
||||
|
||||
public interface IDisplayerComponentFirerer<T> {
|
||||
void fireRefreshContentRequestEvent();
|
||||
void fireContentClickEvent(Event event, T eventTarget);
|
||||
void fireAddContentRequestEvent();
|
||||
void fireRemoveContentRequestEvent(T content);
|
||||
void fireDetailContentRequestEvent(T content);
|
||||
void addListener(IDisplayerComponentListener<T> l);
|
||||
void removeListener(IDisplayerComponentListener<T> l);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.displayers.listeners;
|
||||
|
||||
import javafx.event.Event;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface IDisplayerComponentListener<T> extends EventListener {
|
||||
void onRefreshContentRequestEvent();
|
||||
void onContentClickEvent(Event event, T eventTarget);
|
||||
void onAddContentRequestEvent();
|
||||
void onRemoveContentRequestEvent(T content);
|
||||
void onDetailContentRequestEvent(T content);
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.displayers.listeners;
|
||||
|
||||
import javafx.event.Event;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SimpleDisplayerComponentFirerer<T, U extends IDisplayerComponentListener<T>> implements IDisplayerComponentFirerer<T> {
|
||||
|
||||
protected EventListenerList listenerList;
|
||||
protected Class<U> clazz;
|
||||
|
||||
public SimpleDisplayerComponentFirerer(Class<U> clazz) {
|
||||
listenerList = new EventListenerList();
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireRefreshContentRequestEvent() {
|
||||
Arrays.stream(listenerList.getListeners(clazz)).forEach(IDisplayerComponentListener::onRefreshContentRequestEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireContentClickEvent(Event event, T eventTarget) {
|
||||
Arrays.stream(listenerList.getListeners(clazz)).forEach(l->l.onContentClickEvent(event, eventTarget));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireAddContentRequestEvent() {
|
||||
Arrays.stream(listenerList.getListeners(clazz)).forEach(IDisplayerComponentListener::onAddContentRequestEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireRemoveContentRequestEvent(T content) {
|
||||
Arrays.stream(listenerList.getListeners(clazz)).forEach(l->l.onRemoveContentRequestEvent(content));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireDetailContentRequestEvent(T content) {
|
||||
Arrays.stream(listenerList.getListeners(clazz)).forEach(l->l.onDetailContentRequestEvent(content));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IDisplayerComponentListener<T> l) throws IllegalArgumentException {
|
||||
if(clazz.isInstance(l)){
|
||||
listenerList.add(clazz, clazz.cast(l));
|
||||
}else{
|
||||
throw new IllegalArgumentException("Listener must implement the following interface : "+clazz.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IDisplayerComponentListener<T> l) {
|
||||
if (clazz.isInstance(l)) {
|
||||
listenerList.remove(clazz, clazz.cast(l));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.javafx_override;
|
||||
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
||||
public class CssEnabledGridPane extends GridPane {
|
||||
|
||||
public CssEnabledGridPane() {
|
||||
super();
|
||||
this.getStyleClass().add("grid-pane");
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.javafx_override;
|
||||
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.scene.control.ListCell;
|
||||
|
||||
public class HighlightListCell<T> extends ListCell<T> {
|
||||
|
||||
private PseudoClass highlightPC;
|
||||
private boolean highlighted;
|
||||
|
||||
public HighlightListCell() {
|
||||
super();
|
||||
highlighted = false;
|
||||
highlightPC = PseudoClass.getPseudoClass("highlighted");
|
||||
}
|
||||
|
||||
public void setHighLight(boolean highLight){
|
||||
highlighted = highLight;
|
||||
this.pseudoClassStateChanged(highlightPC, highLight);
|
||||
}
|
||||
|
||||
public boolean isHightlighted(){
|
||||
return highlighted;
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.others;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.others.listeners.ISideBarListener;
|
||||
import javafx.animation.Animation;
|
||||
import javafx.animation.Transition;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.css.*;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class SideBar extends VBox {
|
||||
|
||||
private static final StyleablePropertyFactory<SideBar> FACTORY = new StyleablePropertyFactory<>(VBox.getClassCssMetaData());
|
||||
|
||||
private static final CssMetaData<SideBar, Number> EXPANDED_WIDTH =
|
||||
FACTORY.createSizeCssMetaData("-pqt-expanded-width",p->p.expandedWidth, 100, false);
|
||||
|
||||
private StyleableProperty<Number> expandedWidth;
|
||||
private EventListenerList listenerList;
|
||||
private Animation collapseSideBar, expandSideBar;
|
||||
|
||||
/** creates a sidebar containing a vertical alignment of the given nodes */
|
||||
public SideBar(Node... children) {
|
||||
listenerList = new EventListenerList();
|
||||
getStyleClass().add("sidebar");
|
||||
this.setMinWidth(0);
|
||||
this.expandedWidth = new SimpleStyleableDoubleProperty(EXPANDED_WIDTH, this, "expanded-width");
|
||||
this.setPrefWidth(expandedWidth.getValue().doubleValue());
|
||||
|
||||
setAlignment(Pos.CENTER);
|
||||
getChildren().addAll(children);
|
||||
|
||||
// create an animation to show a sidebar.
|
||||
expandSideBar = new Transition() {
|
||||
{
|
||||
setCycleDuration(Duration.millis(250));
|
||||
}
|
||||
protected void interpolate(double frac) {
|
||||
SideBar.this.setVisible(true);
|
||||
final double curWidth = expandedWidth.getValue().doubleValue() * frac;
|
||||
setPrefWidth(curWidth);
|
||||
setTranslateX(-expandedWidth.getValue().doubleValue() + curWidth);
|
||||
}
|
||||
};
|
||||
expandSideBar.onFinishedProperty().set(actionEvent ->
|
||||
Arrays.stream(listenerList.getListeners(ISideBarListener.class))
|
||||
.forEach(ISideBarListener::onExpandFinished)
|
||||
);
|
||||
|
||||
|
||||
// create an animation to hide sidebar.
|
||||
collapseSideBar = new Transition() {
|
||||
{
|
||||
setCycleDuration(Duration.millis(250));
|
||||
}
|
||||
protected void interpolate(double frac) {
|
||||
final double curWidth = expandedWidth.getValue().doubleValue() * (1.0 - frac);
|
||||
setPrefWidth(curWidth);
|
||||
setTranslateX(-expandedWidth.getValue().doubleValue() + curWidth);
|
||||
}
|
||||
};
|
||||
collapseSideBar.onFinishedProperty().set(actionEvent ->{
|
||||
setVisible(false);
|
||||
Arrays.stream(listenerList.getListeners(ISideBarListener.class))
|
||||
.forEach(ISideBarListener::onCollapsedFinished);
|
||||
});
|
||||
collapse();
|
||||
}
|
||||
|
||||
public void expand(){
|
||||
if (expandSideBar.statusProperty().get() == Animation.Status.STOPPED
|
||||
&& collapseSideBar.statusProperty().get() == Animation.Status.STOPPED) {
|
||||
if (!isVisible()) {
|
||||
expandSideBar.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void collapse(){
|
||||
if (expandSideBar.statusProperty().get() == Animation.Status.STOPPED
|
||||
&& collapseSideBar.statusProperty().get() == Animation.Status.STOPPED) {
|
||||
if (isVisible()) {
|
||||
collapseSideBar.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isExpanded(){
|
||||
return isVisible() && expandSideBar.statusProperty().get().equals(Animation.Status.STOPPED);
|
||||
}
|
||||
|
||||
public boolean isCollapsed() {
|
||||
return !isVisible() && collapseSideBar.statusProperty().get().equals(Animation.Status.STOPPED);
|
||||
}
|
||||
|
||||
public void addListener(ISideBarListener listener){
|
||||
listenerList.add(ISideBarListener.class, listener);
|
||||
}
|
||||
|
||||
public void removeListener(ISideBarListener listener){
|
||||
listenerList.remove(ISideBarListener.class, listener);
|
||||
}
|
||||
|
||||
|
||||
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
|
||||
return FACTORY.getCssMetaData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
|
||||
return FACTORY.getCssMetaData();
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.others.listeners;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface ISideBarListener extends EventListener {
|
||||
|
||||
void onCollapsedFinished();
|
||||
void onExpandFinished();
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.toast;
|
||||
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.KeyValue;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import javafx.util.Duration;
|
||||
|
||||
final class Toast {
|
||||
static void toast(Stage ownerStage, String toastMsg, int toastDelay, int fadeInDelay, int fadeOutDelay) {
|
||||
Stage toastStage = new Stage();
|
||||
toastStage.initOwner(ownerStage);
|
||||
toastStage.setResizable(false);
|
||||
toastStage.initStyle(StageStyle.TRANSPARENT);
|
||||
|
||||
Text text = new Text(toastMsg);
|
||||
text.getStyleClass().add("toast-text");
|
||||
|
||||
StackPane root = new StackPane(text);
|
||||
root.getStyleClass().add("toast-pane");
|
||||
root.setOpacity(0);
|
||||
|
||||
Scene scene = new Scene(root);
|
||||
scene.setFill(Color.TRANSPARENT);
|
||||
scene.getStylesheets().addAll(Toast.class.getResource(GUICssTool.getCssFilePath()).toExternalForm());
|
||||
toastStage.setScene(scene);
|
||||
toastStage.show();
|
||||
|
||||
Timeline fadeInTimeline = new Timeline();
|
||||
KeyFrame fadeInKey1 = new KeyFrame(Duration.millis(fadeInDelay), new KeyValue (toastStage.getScene().getRoot().opacityProperty(), 1));
|
||||
fadeInTimeline.getKeyFrames().add(fadeInKey1);
|
||||
fadeInTimeline.setOnFinished((ae) ->
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(toastDelay);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Timeline fadeOutTimeline = new Timeline();
|
||||
KeyFrame fadeOutKey1 = new KeyFrame(Duration.millis(fadeOutDelay), new KeyValue (toastStage.getScene().getRoot().opacityProperty(), 0));
|
||||
fadeOutTimeline.getKeyFrames().add(fadeOutKey1);
|
||||
fadeOutTimeline.setOnFinished((aeb) -> toastStage.close());
|
||||
fadeOutTimeline.play();
|
||||
}).start());
|
||||
fadeInTimeline.play();
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.toast;
|
||||
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class ToastFactory {
|
||||
|
||||
private static ToastFactory INSTANCE = null;
|
||||
|
||||
private Stage stage;
|
||||
private int delay, fadeInDelay, fadeOutDelay;
|
||||
|
||||
private ToastFactory(Stage stage){
|
||||
this.stage = stage;
|
||||
delay = 3000;
|
||||
fadeInDelay = 250;
|
||||
fadeOutDelay = 250;
|
||||
}
|
||||
|
||||
public void setToastDelay(int msDelay){
|
||||
this.delay = msDelay;
|
||||
}
|
||||
|
||||
public void setToastFadeInDelay(int msDelay){
|
||||
this.fadeInDelay = msDelay;
|
||||
}
|
||||
|
||||
public void setToastFadeOutDelay(int msDelay){
|
||||
this.fadeOutDelay = msDelay;
|
||||
}
|
||||
|
||||
public void toast(String message){
|
||||
Toast.toast(stage, message, delay, fadeInDelay, fadeOutDelay);
|
||||
}
|
||||
|
||||
public static void init(Stage stage){
|
||||
INSTANCE = new ToastFactory(stage);
|
||||
}
|
||||
|
||||
public static boolean isInitialized(){
|
||||
return INSTANCE!=null;
|
||||
}
|
||||
|
||||
public static ToastFactory getINSTANCE(){
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.validators;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
|
||||
public interface IFXValidatorComponent extends IFXComponent{
|
||||
void addListener(IValidatorComponentListener l);
|
||||
void removeListener(IValidatorComponentListener l);
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.validators.listeners;
|
||||
|
||||
public interface IValidatorComponentFirerer {
|
||||
void addListener(IValidatorComponentListener l);
|
||||
void removeListener(IValidatorComponentListener l);
|
||||
|
||||
void fireValidationEvent();
|
||||
void fireCancelEvent();
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.validators.listeners;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface IValidatorComponentListener extends EventListener {
|
||||
void onValidationEvent();
|
||||
void onCancelEvent();
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.pqt.client.gui.ressources.components.generics.validators.listeners;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SimpleValidatorComponentFirerer implements IValidatorComponentFirerer {
|
||||
|
||||
private EventListenerList listenerList;
|
||||
|
||||
public SimpleValidatorComponentFirerer() {
|
||||
listenerList = new EventListenerList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IValidatorComponentListener l) {
|
||||
listenerList.add(IValidatorComponentListener.class, l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IValidatorComponentListener l) {
|
||||
listenerList.remove(IValidatorComponentListener.class, l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireValidationEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class)).forEach(IValidatorComponentListener::onValidationEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCancelEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class)).forEach(IValidatorComponentListener::onCancelEvent);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.account;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.IFXDisplayerComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.listeners.IAccountComponentListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface IFXAccountsDisplayerComponent extends IFXDisplayerComponent<Collection<Account>, IAccountComponentListener> {
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.account.listeners;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.listeners.IDisplayerComponentListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
public interface IAccountComponentListener extends IDisplayerComponentListener<Account>{
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.account.listeners;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.listeners.SimpleDisplayerComponentFirerer;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
public class SimpleAccountComponentFirerer extends SimpleDisplayerComponentFirerer<Account, IAccountComponentListener> {
|
||||
public SimpleAccountComponentFirerer() {
|
||||
super(IAccountComponentListener.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.products;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.IFXDisplayerComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.products.listeners.IStockComponentListener;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface IFXProductsDisplayerComponent extends IFXDisplayerComponent<Collection<Product>, IStockComponentListener> {
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.products.listeners;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.listeners.IDisplayerComponentListener;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
|
||||
public interface IStockComponentListener extends IDisplayerComponentListener<Product> {
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.products.listeners;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.listeners.SimpleDisplayerComponentFirerer;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
|
||||
public class SimpleStockComponentFirerer extends SimpleDisplayerComponentFirerer<Product, IStockComponentListener> {
|
||||
|
||||
public SimpleStockComponentFirerer() {
|
||||
super(IStockComponentListener.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.sale;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.IFXDisplayerComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.sale.listeners.ISaleComponentListener;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
|
||||
public interface IFXSaleDisplayerComponent extends IFXDisplayerComponent<Sale, ISaleComponentListener> {
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.sale.listeners;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.listeners.IDisplayerComponentListener;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import javafx.event.Event;
|
||||
|
||||
public interface ISaleComponentListener extends IDisplayerComponentListener<Sale> {
|
||||
void onComponentClickEvent(Event event, Product product);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.sale.listeners;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.listeners.SimpleDisplayerComponentFirerer;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import javafx.event.Event;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SimpleSaleComponentFirerer extends SimpleDisplayerComponentFirerer<Sale, ISaleComponentListener> {
|
||||
|
||||
public SimpleSaleComponentFirerer() {
|
||||
super(ISaleComponentListener.class);
|
||||
}
|
||||
|
||||
public void fireComponentClickEvent(Event event, Product product) {
|
||||
Arrays.stream(listenerList.getListeners(ISaleComponentListener.class)).forEach(l->l.onComponentClickEvent(event, product));
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.pqt.client.gui.ressources.css;
|
||||
|
||||
public class GUICssTool {
|
||||
public static String getCssFilePath(){
|
||||
//return "/daymode-blue.css";
|
||||
return "/nightmode.css";
|
||||
}
|
||||
|
||||
public static String getMainModulePaneCssClass() {
|
||||
return "main-module-pane";
|
||||
}
|
||||
|
||||
public static String getIntermediaryPaneStyleClass() {
|
||||
return "grey-intermediary-pane";
|
||||
}
|
||||
|
||||
public static String getTitleTextStyleClass() {
|
||||
return "label-header";
|
||||
}
|
||||
}
|
@ -0,0 +1,336 @@
|
||||
package com.pqt.client.gui.ressources.strings;
|
||||
|
||||
import com.pqt.core.entities.product.Category;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.sale.SaleStatus;
|
||||
import com.pqt.core.entities.sale.SaleType;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.EnumSet;
|
||||
|
||||
//TODO faire ça un peu mieux
|
||||
public class GUIStringTool {
|
||||
|
||||
public static String getValidationButtonLabel() {
|
||||
return "Valider";
|
||||
}
|
||||
|
||||
public static String getConfirmationValidationButtonLabel() {
|
||||
return "Confirmer";
|
||||
}
|
||||
|
||||
public static String getCancelButtonLabel() {
|
||||
return "Annuler";
|
||||
}
|
||||
|
||||
public static String getConfirmationCancelButtonLabel() {
|
||||
return "Confirmer";
|
||||
}
|
||||
|
||||
public static String getCategorytabStockDisplayerTitle() {
|
||||
return "Produits";
|
||||
}
|
||||
|
||||
public static IObjectStringRenderer<Product> getDetailledProductStringRenderer(){
|
||||
return product->{
|
||||
if(product!=null){
|
||||
String amountStr;
|
||||
if(product.getAmountRemaining()<=0){
|
||||
amountStr = "OUT OF STOCK";
|
||||
}else if(product.getAmountRemaining()>=30){
|
||||
amountStr = "30+";
|
||||
}else{
|
||||
amountStr = Integer.toString(product.getAmountRemaining());
|
||||
}
|
||||
return String.format("%s - %.2f€ (%s)", product.getName(), product.getPrice(), amountStr);
|
||||
}else
|
||||
return "null";
|
||||
};
|
||||
}
|
||||
|
||||
public static IObjectStringRenderer<Product> getSimpleProductStringRenderer(){
|
||||
return product->{
|
||||
if(product!=null)
|
||||
return String.format("%s - %.2f€", product.getName(), product.getPrice());
|
||||
else
|
||||
return "null";
|
||||
};
|
||||
}
|
||||
|
||||
public static String getCommandComposerTitleLabel() {
|
||||
return "Commande";
|
||||
}
|
||||
|
||||
public static IObjectWithQuantityStringRenderer<Product> getSaleItemStringRenderer(){
|
||||
return (product, qte)->String.format("%dx %s", qte, product.getName());
|
||||
}
|
||||
|
||||
public static String getPasswordFieldPromptText() {
|
||||
return "mot de passe";
|
||||
}
|
||||
|
||||
public static StringConverter<Account> getAccountStringConverter() {
|
||||
return new StringConverter<Account>() {
|
||||
@Override
|
||||
public String toString(Account object) {
|
||||
if(object!=null)
|
||||
return String.format("%s - (%s)", object.getUsername(), object.getPermissionLevel());
|
||||
|
||||
return "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account fromString(String string) {
|
||||
Account reply = new Account();
|
||||
|
||||
String[] pieces = string.split(" - ");
|
||||
reply.setUsername(pieces[0]);
|
||||
if(pieces.length>1)
|
||||
for(AccountLevel al : EnumSet.allOf(AccountLevel.class)){
|
||||
if(al.name().equals(pieces[1]))
|
||||
reply.setPermissionLevel(al);
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static String getLogoutButtonLabel() {
|
||||
return "Déconnexion";
|
||||
}
|
||||
|
||||
public static String getLoginButtonLabel() {
|
||||
return "Connexion";
|
||||
}
|
||||
|
||||
public static IObjectStringRenderer<Double> getPriceRenderer() {
|
||||
return price -> NumberFormat.getCurrencyInstance().format(price);
|
||||
}
|
||||
|
||||
public static String getSaleMakerTextFieldPromptText() {
|
||||
return "Auteur";
|
||||
}
|
||||
|
||||
public static String getSaleMakerTextFieldLabel() {
|
||||
return "Fait par : ";
|
||||
}
|
||||
|
||||
public static String getSaleBeneficiaryTextFieldLabel() {
|
||||
return "Fait pour : ";
|
||||
}
|
||||
|
||||
public static String getSaleTypeTextFieldLabel() {
|
||||
return "Type de paiement : ";
|
||||
}
|
||||
|
||||
public static String getSalePriceTextFieldLabel() {
|
||||
return "Prix de la commande : ";
|
||||
}
|
||||
|
||||
public static StringConverter<SaleType> getSaleTypeStringConverter() {
|
||||
return new StringConverter<SaleType>() {
|
||||
@Override
|
||||
public String toString(SaleType object) {
|
||||
return object.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaleType fromString(String string) {
|
||||
return EnumSet.allOf(SaleType.class).stream().filter(type->type.name().equals(string)).findFirst().orElse(null);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static String getSalePriceTextFieldPromptText() {
|
||||
return getPriceRenderer().render(0d);
|
||||
}
|
||||
|
||||
public static String getCommandValidationErrorMessage() {
|
||||
return "La commande n'a pas pu être validée";
|
||||
}
|
||||
|
||||
public static String getCommandValidationErrorMessage(Throwable cause) {
|
||||
return "La commande n'a pas pu être validée : "+cause.getMessage();
|
||||
}
|
||||
|
||||
public static String getSaleIdLabel() {
|
||||
return "Numéro de commande : ";
|
||||
}
|
||||
|
||||
public static String getSaleStatusLabel() {
|
||||
return "Etat actuel";
|
||||
}
|
||||
|
||||
public static IObjectStringRenderer<SaleStatus> getSaleStatusRenderer() {
|
||||
return Enum::name;
|
||||
}
|
||||
|
||||
public static String getOkButtonLabel() {
|
||||
return "OK";
|
||||
}
|
||||
|
||||
public static String getAppTitle() {
|
||||
return "Client PQT - Gargotte";
|
||||
}
|
||||
|
||||
public static String getSideBarCollapseButtonLabel() {
|
||||
return "Réduire";
|
||||
}
|
||||
|
||||
public static String getSideBarExpandButtonLabel() {
|
||||
return "Menu";
|
||||
}
|
||||
|
||||
public static String getSaleGuiModuleName() {
|
||||
return "Vente";
|
||||
}
|
||||
|
||||
public static String getAddButtonLabel() {
|
||||
return "Ajouter";
|
||||
}
|
||||
|
||||
public static String getDetailButtonLabel() {
|
||||
return "Détail";
|
||||
}
|
||||
|
||||
public static String getRemoveButtonLabel() {
|
||||
return "Supprimer";
|
||||
}
|
||||
|
||||
public static String getRefreshButtonLabel() {
|
||||
return "Rafraichir";
|
||||
}
|
||||
|
||||
public static String getProductNameColumnHeader() {
|
||||
return "Nom";
|
||||
}
|
||||
|
||||
public static String getProductCategoryColumnHeader() {
|
||||
return "Catégorie";
|
||||
}
|
||||
|
||||
public static String getProductAmountRemainingColumnHeader() {
|
||||
return "Stock";
|
||||
}
|
||||
|
||||
public static String getProductAmountSoldColumnHeader() {
|
||||
return "Vendu";
|
||||
}
|
||||
|
||||
public static String getProductPriceColumnHeader() {
|
||||
return "Prix";
|
||||
}
|
||||
|
||||
public static String getProductIsSellableColumnHeader() {
|
||||
return "Vendable";
|
||||
}
|
||||
|
||||
public static IObjectStringRenderer<Boolean> getBooleanRenderer() {
|
||||
return bool->bool?"Oui":"Non";
|
||||
}
|
||||
|
||||
public static String getStatGuiModuleName() {
|
||||
return "Statistiques";
|
||||
}
|
||||
|
||||
public static String getProductNameLabel() {
|
||||
return "Nom : ";
|
||||
}
|
||||
|
||||
public static String getProductCategoryLabel() {
|
||||
return "Catégorie : ";
|
||||
}
|
||||
|
||||
public static String getProductAmountRemainingLabel() {
|
||||
return "En stock : ";
|
||||
}
|
||||
|
||||
public static String getProductAmountSoldLabel() {
|
||||
return "Vendu : ";
|
||||
}
|
||||
|
||||
public static String getProductSellableLabel() {
|
||||
return "Vendable : ";
|
||||
}
|
||||
|
||||
public static String getProductPriceLabel() {
|
||||
return "Prix : ";
|
||||
}
|
||||
|
||||
public static StringConverter<Category> getCategoryStringConverter() {
|
||||
return new StringConverter<Category>() {
|
||||
@Override
|
||||
public String toString(Category object) {
|
||||
if(object!=null)
|
||||
return object.getName();
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Category fromString(String string) {
|
||||
if(string!=null)
|
||||
return new Category(-1, string);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static String getComponentListTitleLabel() {
|
||||
return "Composants";
|
||||
}
|
||||
|
||||
public static String getAccountGuiModuleName() {
|
||||
return "Utilisateurs";
|
||||
}
|
||||
|
||||
public static IObjectStringRenderer<AccountLevel> getAccountLevelStringRenderer() {
|
||||
return level->{
|
||||
switch (level){
|
||||
case LOWEST:
|
||||
return "autre";
|
||||
case GUEST:
|
||||
return "Invité";
|
||||
case STAFF:
|
||||
return "Staff";
|
||||
case WAITER:
|
||||
return "Caissier";
|
||||
case MASTER:
|
||||
return "Chef";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static String getAccountListTitleLabel() {
|
||||
return "Utilisateurs";
|
||||
}
|
||||
|
||||
public static String getUsernameLabel() {
|
||||
return "Nom :";
|
||||
}
|
||||
|
||||
public static String getPasswordLabel() {
|
||||
return "Mot de passe : ";
|
||||
}
|
||||
|
||||
public static String getUserLevelLabel() {
|
||||
return "Niveau d'accréditation : ";
|
||||
}
|
||||
|
||||
public static String getAccountNameColumnHeaderLabel() {
|
||||
return "Nom d'utilisateur";
|
||||
}
|
||||
|
||||
public static String getAccountLevelColumnHeaderLabel() {
|
||||
return "Niveau d'accréditation";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
package com.pqt.client.gui.ressources.strings;
|
||||
|
||||
public interface IObjectStringRenderer<T> {
|
||||
String render(T obj);
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.pqt.client.gui.ressources.strings;
|
||||
|
||||
public interface IObjectWithQuantityStringRenderer<T> {
|
||||
String render(T obj, int quantity);
|
||||
}
|
@ -18,7 +18,7 @@ public class AccountService {
|
||||
|
||||
}
|
||||
|
||||
public boolean isAccountLoggedIn(Account account) {
|
||||
public boolean isCurrentAccountLoggedIn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ public class AccountService {
|
||||
|
||||
}
|
||||
|
||||
public void logOutCurrentAccount(String password) {
|
||||
public void logOutCurrentAccount() {
|
||||
|
||||
}
|
||||
|
||||
@ -42,4 +42,7 @@ public class AccountService {
|
||||
|
||||
}
|
||||
|
||||
public List<Account> getAllAccounts() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,16 @@ public class AccountListenerAdapter implements IAccountListener {
|
||||
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.account.listeners.IAccountListener#onAccountStatusChanged(boolean)
|
||||
* @see com.pqt.client.module.account.listeners.IAccountListener#onAccountStatusChangedEvent(boolean)
|
||||
*/
|
||||
public void onAccountStatusChanged(boolean status) {
|
||||
public void onAccountStatusChangedEvent(boolean status) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.account.listeners.IAccountListener#onAccountListChangedEvent()
|
||||
*/
|
||||
public void onAccountListChangedEvent() {
|
||||
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,6 @@ import java.util.EventListener;
|
||||
|
||||
public interface IAccountListener extends EventListener {
|
||||
|
||||
public void onAccountStatusChanged(boolean status);
|
||||
|
||||
void onAccountStatusChangedEvent(boolean status);
|
||||
void onAccountListChangedEvent();
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
package com.pqt.client.module.sale;
|
||||
|
||||
import com.pqt.core.entities.client.Client;
|
||||
import com.pqt.client.module.stock.StockDao;
|
||||
import com.pqt.core.entities.members.Client;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.core.entities.sale.SaleStatus;
|
||||
import com.pqt.core.entities.sale.SaleType;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
//TODO écrire javadoc
|
||||
public class SaleBuilder {
|
||||
@ -26,18 +25,40 @@ public class SaleBuilder {
|
||||
}
|
||||
|
||||
public SaleBuilder addProduct(Product product) {
|
||||
if(products.containsKey(product)){
|
||||
//Check for sufficient stock
|
||||
if(product.getAmountRemaining()<products.get(product)) {
|
||||
products.replace(product, products.get(product) + 1);
|
||||
//Check for sufficient stock
|
||||
if(isAmountRemainingSufficient(product, 1)) {
|
||||
if(products.containsKey(product)){
|
||||
products.replace(product, products.get(product) + 1);
|
||||
}else{
|
||||
products.put(product, 1);
|
||||
}
|
||||
}else{
|
||||
products.put(product, 1);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean isAmountRemainingSufficient(Product newProduct, int requiredAmount){
|
||||
Map<Product, Integer> rank0Products = new HashMap<>();
|
||||
collectRank0Products(newProduct, requiredAmount, rank0Products);
|
||||
products.keySet().forEach(oldProduct->collectRank0Products(oldProduct, products.get(oldProduct), rank0Products));
|
||||
|
||||
return rank0Products.keySet()
|
||||
.stream()
|
||||
.filter(rank0Product->rank0Product.getAmountRemaining()<rank0Products.get(rank0Product))
|
||||
.count()==0;
|
||||
}
|
||||
|
||||
private void collectRank0Products(Product rootProduct, Integer rootProductAmount, Map<Product, Integer> collector){
|
||||
if(rootProduct.getComponents().isEmpty()){
|
||||
if(collector.containsKey(rootProduct))
|
||||
collector.replace(rootProduct, collector.get(rootProduct)+rootProductAmount);
|
||||
else
|
||||
collector.put(rootProduct, rootProductAmount);
|
||||
}else{
|
||||
rootProduct.getComponents().forEach(product->collectRank0Products(product, rootProductAmount, collector));
|
||||
}
|
||||
}
|
||||
|
||||
public SaleBuilder removeProduct(Product product) {
|
||||
if(products.containsKey(product)) {
|
||||
if (products.get(product) == 1)
|
||||
|
@ -6,6 +6,9 @@ import com.pqt.client.module.query.query_callback.IIdQueryCallback;
|
||||
import com.pqt.client.module.sale.listeners.ISaleFirerer;
|
||||
import com.pqt.client.module.sale.listeners.ISaleListener;
|
||||
import com.pqt.client.module.sale.listeners.SimpleSaleFirerer;
|
||||
import com.pqt.core.entities.sale.SaleType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//TODO écrire javadoc
|
||||
//TODO add log lines
|
||||
@ -55,4 +58,8 @@ public class SaleService {
|
||||
eventFirerer.removeListener(listener);
|
||||
}
|
||||
|
||||
public List<SaleType> getSaleTypes() {
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,13 @@
|
||||
package com.pqt.client.module.sale.listeners;
|
||||
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface ISaleListener extends EventListener {
|
||||
|
||||
public abstract void onSaleValidationSuccess(long saleId);
|
||||
void onSaleValidationSuccess(long saleId);
|
||||
|
||||
public abstract void onSaleValidationError(long saleId, Throwable cause);
|
||||
void onSaleValidationError(long saleId, Throwable cause);
|
||||
|
||||
public abstract void onSaleValidationRefused(long saleId, Throwable cause);
|
||||
void onSaleValidationRefused(long saleId, Throwable cause);
|
||||
|
||||
}
|
||||
|
@ -33,12 +33,8 @@ public class StockDao {
|
||||
}
|
||||
|
||||
public synchronized Product getProduct(final int id) {
|
||||
Optional<Product> match = products.stream().filter((product->product.getId()==id)).findFirst();
|
||||
if(match.isPresent())
|
||||
return match.get();
|
||||
|
||||
return null;
|
||||
}
|
||||
return products.stream().filter((product->product.getId()==id)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public void refreshProductList() {
|
||||
QueryExecutor.INSTANCE.execute(QueryFactory.newStockQuery(), new IStockQueryCallback() {
|
||||
|
@ -13,7 +13,7 @@ public class StockService {
|
||||
|
||||
private StockDao dao;
|
||||
|
||||
private StockService() {
|
||||
public StockService() {
|
||||
dao = new StockDao();
|
||||
}
|
||||
|
||||
@ -39,7 +39,8 @@ public class StockService {
|
||||
/**
|
||||
* Accesseur de la liste des produits actuellement en vente.
|
||||
* <p/>
|
||||
* La liste peut être obsolète, voir {@link #getLastRefreshTimestamp()} pour la date du dernier refresh et {@link #refreshProductList()} pour la mettre à jour.
|
||||
* La liste peut être obsolète, voir {@link #getLastRefreshTimestamp()} pour la date du dernier refresh et
|
||||
* {@link #refreshProductList()} pour la mettre à jour.
|
||||
*
|
||||
* @return Liste des produits en vente.
|
||||
*/
|
||||
@ -47,6 +48,35 @@ public class StockService {
|
||||
return dao.getProducts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère la liste des produits n'étant pas {@code product} et n'étant pas composé de {@code product}.
|
||||
* Les composants sont récursivements vérifiés pour que ces derniers valident aussi ces deux conditions.
|
||||
* <p/>
|
||||
* La liste peut être obsolète, voir {@link #getLastRefreshTimestamp()} pour la date du dernier refresh et
|
||||
* {@link #refreshProductList()} pour la mettre à jour.
|
||||
*
|
||||
* @param product produit à exclure des résultats.
|
||||
* @return Liste de produit n'étant pas et ne contenant pas {@code product}.
|
||||
*/
|
||||
public List<Product> getProductsExcluding(Product product) {
|
||||
return dao.getProducts();
|
||||
}
|
||||
|
||||
private boolean contains(Product container, Product contained){
|
||||
if(container==null || contained==null)
|
||||
return false;
|
||||
if(container.equals(contained))
|
||||
return true;
|
||||
|
||||
if(container.getComponents()!=null)
|
||||
return container.getComponents()
|
||||
.stream()
|
||||
.filter(component->contains(component, contained))
|
||||
.count()>0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accesseur récupérant un unique produit présent dans les stocks en se basant sur son id.
|
||||
*
|
||||
@ -100,5 +130,4 @@ public class StockService {
|
||||
public void removeListener(IStockListener listener) {
|
||||
dao.removeListener(listener);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,20 +16,23 @@ public class UpdateBuilder {
|
||||
toModify = new HashMap<>();
|
||||
}
|
||||
|
||||
public void addProduct(Product product) {
|
||||
public UpdateBuilder addProduct(Product product) {
|
||||
if(!toAdd.contains(product)){
|
||||
toAdd.add(product);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void removeProduct(Product product) {
|
||||
public UpdateBuilder removeProduct(Product product) {
|
||||
if(toRemove.contains(product)){
|
||||
toRemove.remove(product);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void modifyProduct(Product oldVersion, Product newVersion) {
|
||||
public UpdateBuilder modifyProduct(Product oldVersion, Product newVersion) {
|
||||
toModify.put(oldVersion, newVersion);
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<ProductUpdate> build() {
|
||||
|
235
Workspace/client/src/main/resources/nightmode.css
Normal file
235
Workspace/client/src/main/resources/nightmode.css
Normal file
@ -0,0 +1,235 @@
|
||||
.root {
|
||||
-fx-background-color: #1d1d1d;
|
||||
}
|
||||
|
||||
.label {
|
||||
-fx-font-size: 11pt;
|
||||
-fx-font-family: "Segoe UI Semibold";
|
||||
-fx-text-fill: white;
|
||||
-fx-opacity: 0.8;
|
||||
}
|
||||
|
||||
.label-bright {
|
||||
-fx-font-size: 11pt;
|
||||
-fx-font-family: "Segoe UI Semibold";
|
||||
-fx-text-fill: white;
|
||||
-fx-opacity: 1;
|
||||
}
|
||||
|
||||
.label-header {
|
||||
-fx-font-size: 25pt;
|
||||
-fx-font-family: "Segoe UI";
|
||||
-fx-text-fill: white;
|
||||
-fx-opacity: 1;
|
||||
}
|
||||
|
||||
.tab {
|
||||
-fx-background-color: #3a3a3a;
|
||||
}
|
||||
|
||||
.tab-label {
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
|
||||
.tab:selected {
|
||||
-fx-background-color: #4d4d4d;
|
||||
}
|
||||
|
||||
.tab-pane *.tab-header-background {
|
||||
-fx-background-color: #1d1d1d;
|
||||
}
|
||||
|
||||
.list-view {
|
||||
-fx-control-inner-background: #1d1d1d;
|
||||
-fx-control-inner-background-alt: #333333;
|
||||
-fx-padding: 5;
|
||||
-fx-border-width: 0px;
|
||||
}
|
||||
|
||||
.list-view .list-cell .label{
|
||||
-fx-font-size: 20pt;
|
||||
-fx-font-family: "Segoe UI Light";
|
||||
-fx-text-fill: white;
|
||||
-fx-alignment: center-left;
|
||||
}
|
||||
|
||||
.list-view:focused .list-cell:filled:focused:selected {
|
||||
-fx-background-color: -fx-focus-color;
|
||||
}
|
||||
.list-cell:highlighted{
|
||||
-fx-text-fill: #cc7a00;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-color: white;
|
||||
}
|
||||
|
||||
.table-view {
|
||||
-fx-base: #1d1d1d;
|
||||
-fx-control-inner-background: #1d1d1d;
|
||||
-fx-control-inner-background-alt: #333333;
|
||||
-fx-table-cell-border-color: transparent;
|
||||
-fx-table-header-border-color: transparent;
|
||||
-fx-padding: 5;
|
||||
}
|
||||
|
||||
.table-view .column-header-background {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.table-view .column-header, .table-view .filler {
|
||||
-fx-size: 35px;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-color:
|
||||
transparent
|
||||
transparent
|
||||
derive(-fx-base, 80%)
|
||||
transparent;
|
||||
-fx-border-insets: 0 10 1 0;
|
||||
}
|
||||
|
||||
.table-view .column-header .label {
|
||||
-fx-font-size: 20pt;
|
||||
-fx-font-family: "Segoe UI Light";
|
||||
-fx-text-fill: white;
|
||||
-fx-alignment: center-left;
|
||||
-fx-opacity: 1;
|
||||
}
|
||||
|
||||
.table-view .table-row-cell {
|
||||
-fx-control-inner-background: #1d1d1d;
|
||||
-fx-control-inner-background-alt: #333333;
|
||||
}
|
||||
|
||||
.table-view .table-row-cell:stock-out {
|
||||
-fx-control-inner-background: #4d0000;
|
||||
-fx-control-inner-background-alt: #4d0000;
|
||||
}
|
||||
|
||||
.table-view .table-row-cell:stock-low {
|
||||
-fx-control-inner-background: #4d2e00;
|
||||
-fx-control-inner-background-alt: #4d2e00;
|
||||
}
|
||||
|
||||
.table-view .table-row-cell:stock-high {
|
||||
-fx-control-inner-background: #1a3300;
|
||||
-fx-control-inner-background-alt: #1a3300;
|
||||
}
|
||||
|
||||
.table-view:focused .table-row-cell:filled:focused:selected {
|
||||
-fx-background-color: -fx-focus-color;
|
||||
}
|
||||
|
||||
.grid-pane {
|
||||
-fx-hgap: 10;
|
||||
-fx-vgap: 10;
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
-fx-background-color: derive(#1d1d1d,5%);
|
||||
}
|
||||
.text-field, .password-field, .choice-box, .text-area, .combo-box, .button {
|
||||
-fx-font-size: 12pt;
|
||||
-fx-font-family: "Segoe UI Semibold";
|
||||
-fx-pref-width: 150;
|
||||
-fx-pref-height: 30;
|
||||
-fx-background-color: #1d1d1d;
|
||||
-fx-border-color: #e2e2e2;
|
||||
-fx-border-width: 2;
|
||||
-fx-text-fill: #d8d8d8;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
-fx-background-color: #3a3a3a;
|
||||
}
|
||||
|
||||
.button:pressed, .button:default:hover:pressed {
|
||||
-fx-background-color: white;
|
||||
-fx-text-fill: #1d1d1d;
|
||||
}
|
||||
|
||||
.button:focused {
|
||||
-fx-border-color: white, white;
|
||||
-fx-border-width: 1, 1;
|
||||
-fx-border-style: solid;
|
||||
-fx-border-radius: 0, 0;
|
||||
-fx-border-insets: 1 1 1 1, 0;
|
||||
}
|
||||
|
||||
.button:disabled, .button:default:disabled {
|
||||
-fx-opacity: 0.4;
|
||||
-fx-background-color: #1d1d1d;
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
|
||||
.button:default {
|
||||
-fx-background-color: -fx-focus-color;
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
|
||||
.button:default:hover {
|
||||
-fx-background-color: derive(-fx-focus-color,30%);
|
||||
}
|
||||
|
||||
.text-area .content {
|
||||
-fx-background-color: #1d1d1d;
|
||||
-fx-padding: 15 15 15 15;
|
||||
}
|
||||
|
||||
#stat-screen-text-area {
|
||||
-fx-border-width: 0;
|
||||
}
|
||||
|
||||
.progress-indicator {
|
||||
-fx-pref-width: 50;
|
||||
-fx-pref-height: 50;
|
||||
}
|
||||
|
||||
.grey-intermediary-pane {
|
||||
-fx-background-color: #1d1d1d;
|
||||
-fx-opacity: 85%;
|
||||
}
|
||||
|
||||
.main-module-pane {
|
||||
-fx-padding: 10 10 10 10;
|
||||
}
|
||||
|
||||
.validator {
|
||||
-fx-padding: 10 10 10 10;
|
||||
-fx-hgap: 10;
|
||||
-fx-vgap: 10;
|
||||
}
|
||||
.validator .button{
|
||||
-fx-pref-width: 150;
|
||||
-fx-pref-height: 50;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
-fx-background-color: #2e2e2e;
|
||||
-fx-padding: 5 22 5 22;
|
||||
-fx-border-color: whitesmoke;
|
||||
-fx-border-width: 2;
|
||||
-fx-background-radius: 0;
|
||||
-fx-background-insets: 0 0 0 0, 0, 1, 2;
|
||||
-pqt-expanded-width : 195px;
|
||||
}
|
||||
|
||||
.tool-bar {
|
||||
-fx-background-color: #2e2e2e;
|
||||
-fx-padding: 5 5 5 5;
|
||||
-fx-background-radius: 0;
|
||||
-fx-background-insets: 0 0 0 0, 0, 1, 2;
|
||||
}
|
||||
|
||||
.toast-text{
|
||||
-fx-font: 50px "Impact";
|
||||
-fx-fill: whitesmoke;
|
||||
}
|
||||
|
||||
.toast-pane {
|
||||
-fx-background-radius: 10px;
|
||||
-fx-background-color: rgba(0, 0, 0, 0.4);
|
||||
-fx-border-width: 2px;
|
||||
-fx-border-color: whitesmoke;
|
||||
-fx-border-radius: 6px;
|
||||
-fx-padding: 25px;
|
||||
}
|
@ -1,5 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="hibernate" name="Hibernate">
|
||||
<configuration>
|
||||
<datasource-map />
|
||||
<naming-strategy-map />
|
||||
<deploymentDescriptor name="hibernate.cfg.xml" url="file://$MODULE_DIR$/src/main/resources/hibernate.cfg.xml" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
@ -11,5 +20,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
</component>
|
||||
</module>
|
@ -12,4 +12,14 @@
|
||||
<artifactId>core</artifactId>
|
||||
|
||||
|
||||
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,32 @@
|
||||
package com.pqt.core.communication;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
//TODO écrire Javadoc
|
||||
public class GSonMessageToolFactory implements IMessageToolFactory {
|
||||
private Gson gson;
|
||||
|
||||
public GSonMessageToolFactory() {
|
||||
gson = new GsonBuilder().create();
|
||||
}
|
||||
|
||||
public <T> IObjectFormatter<T> getObjectFormatter(Class<T> clazz){
|
||||
return (obj)->gson.toJson(obj);
|
||||
}
|
||||
public <T> IObjectParser<T> getObjectParser(Class<T> clazz){
|
||||
return (str)->gson.fromJson(str, clazz);
|
||||
}
|
||||
public <T> IObjectFormatter<List<T>> getListFormatter(Class<T> clazz){
|
||||
return (obj)->gson.toJson(obj);
|
||||
}
|
||||
public <T> IObjectParser<List<T>> getListParser(Class<T> clazz){
|
||||
Type listType = new TypeToken<ArrayList<T>>(){}.getType();
|
||||
return (str)->gson.fromJson(str, listType);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.pqt.core.communication;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.pqt.core.entities.members.PqtMember;
|
||||
import com.pqt.core.entities.members.PqtMemberType;
|
||||
import com.pqt.core.entities.messages.Message;
|
||||
import com.pqt.core.entities.messages.MessageType;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.product.ProductUpdate;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public interface IMessageToolFactory {
|
||||
|
||||
<T> IObjectFormatter<T> getObjectFormatter(Class<T> clazz);
|
||||
|
||||
<T> IObjectParser<T> getObjectParser(Class<T> clazz);
|
||||
|
||||
<T> IObjectFormatter<List<T>> getListFormatter(Class<T> clazz);
|
||||
|
||||
<T> IObjectParser<List<T>> getListParser(Class<T> clazz);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.core.communication;
|
||||
|
||||
public interface IObjectFormatter<T> {
|
||||
|
||||
String format(T obj);
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.pqt.core.communication;
|
||||
|
||||
public interface IObjectParser<T> {
|
||||
|
||||
T parse(String str);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.pqt.core.entities.client;
|
||||
|
||||
import com.pqt.core.entities.log.ILoggable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by Notmoo on 18/07/2017.
|
||||
*/
|
||||
public class Client implements ILoggable, Serializable {
|
||||
|
||||
private int id;
|
||||
private String address;
|
||||
private Date lastUpdate;
|
||||
|
||||
public Client() {
|
||||
}
|
||||
|
||||
public Client(int id, String address, Date lastUpdate) {
|
||||
this.id = id;
|
||||
this.address = address;
|
||||
this.lastUpdate = lastUpdate;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Date getLastUpdate() {
|
||||
return lastUpdate;
|
||||
}
|
||||
|
||||
public void setLastUpdate(Date lastUpdate) {
|
||||
this.lastUpdate = lastUpdate;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.pqt.core.entities.members;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Created by Notmoo on 18/07/2017.
|
||||
*/
|
||||
public class Client extends PqtMember{
|
||||
|
||||
private String address;
|
||||
|
||||
public Client() {
|
||||
super(-1, PqtMemberType.CLIENT);
|
||||
}
|
||||
|
||||
public Client(long id, String address) {
|
||||
super(id, PqtMemberType.CLIENT);
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(this == obj)
|
||||
return true;
|
||||
|
||||
if(!this.getClass().isInstance(obj))
|
||||
return false;
|
||||
|
||||
Client other = Client.class.cast(obj);
|
||||
return super.equals(obj)
|
||||
&& Objects.equals(this.address, other.address);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user