From 543e571e8260a3ae5e1c1262015f3af195f66bac Mon Sep 17 00:00:00 2001 From: Notmoo Date: Sun, 13 Aug 2017 21:57:03 +0200 Subject: [PATCH] =?UTF-8?q?Module=20Client,=20packg=20"client.gui.modules"?= =?UTF-8?q?=20:=20ajout=20classes=20gui=20=C3=A9cran=20composition=20comma?= =?UTF-8?q?ndes=20(PRE-TEST)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gui/modules/sale_screen/SaleScreen.java | 27 +++ .../sale_screen/SaleScreenController.java | 169 ++++++++++++++ .../modules/sale_screen/SaleScreenModel.java | 184 +++++++++++++++ .../modules/sale_screen/SaleScreenView.java | 215 ++++++++++++++++++ .../listeners/ISaleScreenModelListener.java | 12 + 5 files changed, 607 insertions(+) create mode 100644 Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreen.java create mode 100644 Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenController.java create mode 100644 Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenModel.java create mode 100644 Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenView.java create mode 100644 Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/listeners/ISaleScreenModelListener.java diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreen.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreen.java new file mode 100644 index 00000000..82a8b8ca --- /dev/null +++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreen.java @@ -0,0 +1,27 @@ +package com.pqt.client.gui.modules.sale_screen; + +import com.pqt.client.gui.ressources.generics.IFXComponent; +import com.pqt.client.module.account.AccountService; +import com.pqt.client.module.sale.SaleService; +import com.pqt.client.module.stock.StockService; +import javafx.scene.layout.Pane; + +public class SaleScreen implements IFXComponent { + + private SaleScreenModel model; + private SaleScreenController ctrl; + private SaleScreenView view; + + public SaleScreen(AccountService accountService, StockService stockService, SaleService saleService) { + model = new SaleScreenModel(accountService, stockService, saleService); + ctrl = new SaleScreenController(model); + view = new SaleScreenView(ctrl); + + ctrl.setView(view); + } + + @Override + public Pane getPane() { + return view.getPane(); + } +} diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenController.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenController.java new file mode 100644 index 00000000..d907084c --- /dev/null +++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenController.java @@ -0,0 +1,169 @@ +package com.pqt.client.gui.modules.sale_screen; + +import com.pqt.client.gui.modules.sale_screen.listeners.ISaleScreenModelListener; +import com.pqt.client.gui.ressources.components.sale_validation_screen.listeners.ISaleValidationScreenListener; +import com.pqt.client.gui.ressources.specifics.products.listeners.IStockComponentListener; +import com.pqt.client.gui.ressources.generics.validators.listeners.IValidatorComponentListener; +import com.pqt.client.gui.ressources.specifics.sale.listeners.ISaleComponentListener; +import com.pqt.client.gui.ressources.strings.GUIStringTool; +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 javafx.scene.control.Alert; + +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) { + SaleScreenController.this.onSaleValidationError(status, cause); + } + + @Override + public void onStockUpdatedEvent() { + view.setProducts(model.getProductList()); + } + + @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(); + } + + void updateView(){ + view.setProducts(fetchProductList()); + view.setSaleTypes(fetchSaleTypeList()); + view.setAccounts(fetchAccountList()); + + view.setSale(getCurrentSale()); + } + + private List fetchProductList(){ + return model.getProductList(); + } + private List fetchAccountList(){ + return model.getAccountList(); + } + private List fetchSaleTypeList(){ + return model.getSaleTypeList(); + } + + ISaleComponentListener getSaleDisplayerListener() { + return new ISaleComponentListener() { + @Override + public void onComponentClickEvent(Event event, Product product) { + model.removeProductFromSale(product); + SaleScreenController.this.updateView(); + } + + @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) { + model.addProductToSale(eventTarget); + SaleScreenController.this.updateView(); + } + + @Override + public void onAddContentRequestEvent() {} + + @Override + public void onRemoveContentRequestEvent(Product content) {} + + @Override + public void onDetailContentRequestEvent(Product content) {} + }; + } + + Account getDefaultAccount() { + return new Account(" - ", null, AccountLevel.getLowest()); + } + + IValidatorComponentListener getValidatorListener() { + return new IValidatorComponentListener() { + @Override + public void onValidationEvent() { + 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(); + }; + } +} diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenModel.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenModel.java new file mode 100644 index 00000000..1bb32666 --- /dev/null +++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenModel.java @@ -0,0 +1,184 @@ +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 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) { + 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) { + + } + + @Override + public void onAccountListChangedEvent() { + fireAccountListUpdatedEvent(); + } + }); + } + + 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); + } + + List getAccountList() { + return accountService.getAllAccounts(); + } + + List getSaleTypeList() { + return saleService.getSaleTypes(); + } + + Sale getCurrentSale() { + return currentSaleBuilder.build(); + } + + List getProductList() { + return stockService.getProducts().stream().filter(Product::isSellable).collect(Collectors.toList()); + } + + void clearSale() { + currentSaleBuilder = saleService.getNewSaleBuilder(); + currentSaleBuilder.orderedBy(accountService.getCurrentAccount()); + currentSaleBuilder.saleType(SaleType.CASH); + + tempSaleId = -1; + } + + void commitSale() { + tempSaleId = saleService.commitSale(currentSaleBuilder); + } + + long getTempSaleId(){ + return tempSaleId; + } + + void addProductToSale(Product product) { + currentSaleBuilder.addProduct(product); + } + + void removeProductFromSale(Product product) { + currentSaleBuilder.removeProduct(product); + } + + void setSaleType(SaleType saleType) { + currentSaleBuilder.saleType(saleType); + } + + void setSaleBeneficiary(Account saleBeneficiary) { + currentSaleBuilder.orderedFor(saleBeneficiary); + } + + void addListener(ISaleScreenModelListener listener){ + listeners.add(ISaleScreenModelListener.class, listener); + } + + void removeListener(ISaleScreenModelListener listener){ + listeners.remove(ISaleScreenModelListener.class, listener); + } +} \ No newline at end of file diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenView.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenView.java new file mode 100644 index 00000000..e35cb17f --- /dev/null +++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenView.java @@ -0,0 +1,215 @@ +package com.pqt.client.gui.modules.sale_screen; + +import com.pqt.client.gui.ressources.components.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.css.GUICssTool; +import com.pqt.client.gui.ressources.generics.IFXComponent; +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.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 saleBeneficiaryAccountDisplayer; + private ChoiceBox saleTypeDisplayer; + private TextField salePriceDisplayer; + + SaleScreenView(SaleScreenController ctrl) { + this.ctrl = ctrl; + initGui(); + } + + private void initGui() { + mainPane = new StackPane(); + + mainPaneContent = new BorderPane(); + + /* + -----------------------CENTER PANE----------------------- + */ + { + mainPane.getChildren().add(mainPaneContent); + 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----------------------- + */ + { + AnchorPane mainContentBottomPane = new AnchorPane(); + // 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 mainContentBottomLeftPane = new GridPane(); + mainContentBottomLeftPane.add(new Label(GUIStringTool.getSaleMakerTextFieldLabel()), 0, 0); + mainContentBottomLeftPane.add(saleMakerAccountDisplayer, 1, 0); + mainContentBottomLeftPane.add(new Label(GUIStringTool.getSaleBeneficiaryTextFieldLabel()), 0, 1); + mainContentBottomLeftPane.add(saleBeneficiaryAccountDisplayer, 1, 1); + mainContentBottomLeftPane.add(new Label(GUIStringTool.getSaleTypeTextFieldLabel()), 0, 2); + mainContentBottomLeftPane.add(saleTypeDisplayer, 1, 2); + mainContentBottomLeftPane.add(new Label(GUIStringTool.getSalePriceTextFieldLabel()), 0, 3); + mainContentBottomLeftPane.add(salePriceDisplayer, 1, 3); + + mainContentBottomPane.getChildren().add(mainContentBottomLeftPane); + AnchorPane.setBottomAnchor(mainContentBottomLeftPane, 0d); + AnchorPane.setTopAnchor(mainContentBottomLeftPane, 0d); + AnchorPane.setLeftAnchor(mainContentBottomLeftPane, 0d); + } + //Sale Validator + { + SimpleValidator validator = new SimpleValidator(true); + validator.addListener(ctrl.getValidatorListener()); + + mainContentBottomPane.getChildren().add(validator.getPane()); + AnchorPane.setBottomAnchor(validator.getPane(), 0d); + AnchorPane.setTopAnchor(validator.getPane(), 0d); + AnchorPane.setRightAnchor(validator.getPane(), 0d); + } + mainPaneContent.setBottom(mainContentBottomPane); + } + /* + ------------------------MAIN PANE------------------------ + */ + mainPane.getChildren().add(mainPaneContent); + + /* + -------------------------UPDATE-------------------------- + */ + ctrl.updateView(); + } + + @Override + public Pane getPane() { + return mainPane; + } + + void switchToSaleValidationWaitingMode(long saleId, Sale sale){ + boolean clearChildren = mainPane.getChildren().size()>1; + + Pane greyIntermediaryPane = new Pane(); + greyIntermediaryPane.setId(GUICssTool.getGreyIntermediaryPaneCssId()); + + saleValidationScreen = new SaleValidationScreen(saleId, sale); + saleValidationScreen.addListener(ctrl.getSaleValidationScreenListener()); + Platform.runLater(()->{ + if(clearChildren){ + mainPane.getChildren().clear(); + mainPane.getChildren().add(mainPaneContent); + } + + 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 products) { + stockDisplayer.display(products); + } + + void setSaleTypes(List saleTypes) { + Platform.runLater(()->{ + saleTypeDisplayer.getItems().clear(); + saleTypeDisplayer.getItems().addAll(saleTypes); + }); + } + + void setAccounts(List accounts) { + Platform.runLater(()->{ + saleBeneficiaryAccountDisplayer.getItems().clear(); + saleBeneficiaryAccountDisplayer.getItems().add(ctrl.getDefaultAccount()); + saleBeneficiaryAccountDisplayer.getItems().addAll(accounts); + }); + } + + void setSale(Sale sale) { + 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 void selectElement(ChoiceBox 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); + } +} diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/listeners/ISaleScreenModelListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/listeners/ISaleScreenModelListener.java new file mode 100644 index 00000000..bfec4762 --- /dev/null +++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/listeners/ISaleScreenModelListener.java @@ -0,0 +1,12 @@ +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 onAccountListUpdatedEvent(); +}