mirror of
https://github.com/klmp200/PQT_Gestionnaire_vente_stock.git
synced 2024-12-22 15:31:08 +00:00
Module Client, écran stock : ajout des classes de l'écran stocks; diverses modifications annexes
This commit is contained in:
parent
651f976601
commit
aaaa45039e
@ -1,6 +1,8 @@
|
||||
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.stock.StockService;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
@ -11,9 +13,10 @@ public class StockScreen implements IGuiModule {
|
||||
public StockScreen(StockService stockService) {
|
||||
StockScreenModel model = new StockScreenModel(stockService);
|
||||
StockScreenController ctrl = new StockScreenController(model);
|
||||
view = new StockScreenView(ctrl);
|
||||
view = new StockScreenView(ctrl, new ProductManagerScreenFactory(stockService));
|
||||
|
||||
ctrl.setView(view);
|
||||
ctrl.refreshView();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,6 +3,8 @@ 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;
|
||||
|
||||
@ -24,11 +26,33 @@ class StockScreenController implements IStockScreenModelListener{
|
||||
}
|
||||
|
||||
void onDetailProductRequest() {
|
||||
detailProduct(view.getSelectedProduct());
|
||||
if(view.getSelectedProduct()!=null)
|
||||
detailProduct(view.getSelectedProduct());
|
||||
}
|
||||
|
||||
private void detailProduct(Product product){
|
||||
//TODO à faire
|
||||
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() {
|
||||
@ -55,7 +79,7 @@ class StockScreenController implements IStockScreenModelListener{
|
||||
return this::detailProduct;
|
||||
}
|
||||
|
||||
private void refreshView(){
|
||||
void refreshView(){
|
||||
view.display(model.getProductCollection());
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
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;
|
||||
@ -10,34 +13,37 @@ import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
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 Pane mainPane;
|
||||
private StackPane mainPane;
|
||||
private BorderPane mainPaneContent;
|
||||
private TableView<Product> stockTableView;
|
||||
private ProductManagerScreenFactory productManagerScreenFactory;
|
||||
private ProductManagerScreen currentDetailScreen;
|
||||
|
||||
StockScreenView(StockScreenController ctrl) {
|
||||
StockScreenView(StockScreenController ctrl, ProductManagerScreenFactory productManagerScreenFactory) {
|
||||
this.ctrl = ctrl;
|
||||
this.productManagerScreenFactory = productManagerScreenFactory;
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui() {
|
||||
mainPane = new Pane();
|
||||
mainPane.getStyleClass().add("main-module-pane");
|
||||
BorderPane mainPaneContent = new BorderPane();
|
||||
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());
|
||||
@ -46,7 +52,9 @@ class StockScreenView implements IFXComponent {
|
||||
addProductButton.setOnMouseClicked(event -> ctrl.onAddProductRequest());
|
||||
Button detailProductButton = new Button(GUIStringTool.getDetailButtonLabel());
|
||||
detailProductButton.setOnMouseClicked(event -> ctrl.onDetailProductRequest());
|
||||
detailProductButton.setDisable(true);
|
||||
Button removeProductButton = new Button(GUIStringTool.getRemoveButtonLabel());
|
||||
removeProductButton.setDisable(true);
|
||||
removeProductButton.setOnMouseClicked(event -> ctrl.onDeleteProductRequest());
|
||||
Button refreshProductButton = new Button(GUIStringTool.getRefreshButtonLabel());
|
||||
refreshProductButton.setOnMouseClicked(event -> ctrl.onRefreshProductsRequest());
|
||||
@ -75,6 +83,10 @@ class StockScreenView implements IFXComponent {
|
||||
return row;
|
||||
});
|
||||
stockTableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
|
||||
stockTableView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal)->{
|
||||
detailProductButton.setDisable(newVal==null);
|
||||
removeProductButton.setDisable(newVal==null);
|
||||
});
|
||||
List<TableColumn<Product, ?>> columns = new ArrayList<>();
|
||||
|
||||
columns.add(createNewTableColumn(String.class,
|
||||
@ -99,7 +111,7 @@ class StockScreenView implements IFXComponent {
|
||||
));
|
||||
columns.add(createNewTableColumn(Double.class,
|
||||
GUIStringTool.getProductPriceColumnHeader(),
|
||||
param -> new SimpleDoubleProperty(param.getValue().getAmountSold()).asObject(),
|
||||
param -> new SimpleDoubleProperty(param.getValue().getPrice()).asObject(),
|
||||
GUIStringTool.getPriceRenderer()
|
||||
));
|
||||
columns.add(createNewTableColumn(Boolean.class,
|
||||
@ -154,4 +166,50 @@ class StockScreenView implements IFXComponent {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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,213 @@
|
||||
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.getStyleClass().add(GUICssTool.getContainerStyleClass());
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.pqt.client.module.sale;
|
||||
|
||||
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;
|
||||
@ -7,9 +8,7 @@ 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)
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,6 +43,9 @@
|
||||
.list-view:focused .list-cell:filled:focused:selected {
|
||||
-fx-background-color: -fx-focus-color;
|
||||
}
|
||||
.list-cell-highlighted{
|
||||
-fx-background-color: #4d4d4d;
|
||||
}
|
||||
|
||||
.table-view {
|
||||
-fx-base: #1d1d1d;
|
||||
@ -231,6 +234,7 @@
|
||||
-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";
|
||||
@ -245,4 +249,9 @@
|
||||
-fx-border-radius: 6px;
|
||||
-fx-padding: 25px;
|
||||
}
|
||||
|
||||
.pqt-container {
|
||||
-fx-border-width: 2px;
|
||||
-fx-border-color: whitesmoke;
|
||||
-fx-padding: 5 5 5 5;
|
||||
}
|
Loading…
Reference in New Issue
Block a user