Module Client, écran stock : ajout des classes de l'écran stocks; diverses modifications annexes

This commit is contained in:
Notmoo 2017-08-17 23:51:58 +02:00
parent 651f976601
commit aaaa45039e
12 changed files with 650 additions and 31 deletions

View File

@ -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

View File

@ -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());
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
});
}
}

View File

@ -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)

View File

@ -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() {

View File

@ -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);
}
}

View File

@ -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;
}