Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SuppplierOrder #37

Merged
merged 8 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
// - Supplier
opens org.chainoptim.desktop.features.supplier.controller to javafx.fxml, com.google.guice;
opens org.chainoptim.desktop.features.supplier.service to com.google.guice;
opens org.chainoptim.desktop.features.supplier.model to com.fasterxml.jackson.databind;
opens org.chainoptim.desktop.features.supplier.model to com.fasterxml.jackson.databind, javafx.base;
opens org.chainoptim.desktop.features.supplier.dto to com.fasterxml.jackson.databind;

// - Client
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/org/chainoptim/desktop/AppModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@
import org.chainoptim.desktop.features.scanalysis.productgraph.service.ProductProductionGraphServiceImpl;
import org.chainoptim.desktop.features.scanalysis.resourceallocation.service.ResourceAllocationService;
import org.chainoptim.desktop.features.scanalysis.resourceallocation.service.ResourceAllocationServiceImpl;
import org.chainoptim.desktop.features.supplier.service.SupplierService;
import org.chainoptim.desktop.features.supplier.service.SupplierServiceImpl;
import org.chainoptim.desktop.features.supplier.service.SupplierWriteService;
import org.chainoptim.desktop.features.supplier.service.SupplierWriteServiceImpl;
import org.chainoptim.desktop.features.supplier.service.*;
import org.chainoptim.desktop.features.warehouse.service.WarehouseService;
import org.chainoptim.desktop.features.warehouse.service.WarehouseServiceImpl;
import org.chainoptim.desktop.features.warehouse.service.WarehouseWriteService;
Expand Down Expand Up @@ -102,6 +99,7 @@ protected void configure() {
// - Supplier
bind(SupplierService.class).to(SupplierServiceImpl.class);
bind(SupplierWriteService.class).to(SupplierWriteServiceImpl.class);
bind(SupplierOrdersService.class).to(SupplierOrdersServiceImpl.class);

// - Client
bind(ClientService.class).to(ClientServiceImpl.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
package org.chainoptim.desktop.features.client.controller;

import org.chainoptim.desktop.core.abstraction.ControllerFactory;
import org.chainoptim.desktop.features.client.model.Client;
import org.chainoptim.desktop.features.client.model.ClientOrder;
import org.chainoptim.desktop.features.client.service.ClientOrdersService;
import org.chainoptim.desktop.shared.fallback.FallbackManager;
import org.chainoptim.desktop.shared.util.DataReceiver;
import org.chainoptim.desktop.shared.util.resourceloader.FXMLLoaderService;
import com.google.inject.Inject;

import java.time.LocalDateTime;
import java.util.Collections;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.Node;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import org.chainoptim.desktop.features.client.model.Client;
import org.chainoptim.desktop.features.client.model.ClientOrder;
import org.chainoptim.desktop.features.client.service.ClientOrdersService;
import org.chainoptim.desktop.shared.fallback.FallbackManager;
import org.chainoptim.desktop.shared.util.DataReceiver;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.StackPane;
import javafx.util.Callback;
import javafx.util.converter.FloatStringConverter;
import javafx.util.converter.IntegerStringConverter;

import java.util.List;
import java.util.Optional;
Expand All @@ -23,10 +31,14 @@ public class ClientOrdersController implements DataReceiver<Client> {

private final ClientOrdersService clientOrdersService;
private final FallbackManager fallbackManager;
private final FXMLLoaderService fxmlLoaderService;
private final ControllerFactory controllerFactory;

private Client client;
private List<ClientOrder> clientOrders;

@FXML
private StackPane stackPane;
@FXML
private TableView<ClientOrder> tableView;
@FXML
Expand All @@ -45,27 +57,37 @@ public class ClientOrdersController implements DataReceiver<Client> {
private TableColumn<ClientOrder, LocalDateTime> estimatedDeliveryDateColumn;
@FXML
private TableColumn<ClientOrder, LocalDateTime> deliveryDateColumn;

@FXML
private Label clientName;
private StackPane fallbackContainer;

@Inject
public ClientOrdersController(FallbackManager fallbackManager,
ClientOrdersService clientOrdersService) {
ClientOrdersService clientOrdersService,
FXMLLoaderService fxmlLoaderService,
ControllerFactory controllerFactory) {
this.fallbackManager = fallbackManager;
this.clientOrdersService = clientOrdersService;
this.fxmlLoaderService = fxmlLoaderService;
this.controllerFactory = controllerFactory;
}

@Override
public void setData(Client client) {
loadFallbackManager();
this.client = client;
SorinPopteanu marked this conversation as resolved.
Show resolved Hide resolved
this.clientName.setText(client.getName());
System.out.println("Client received in orders: " + client.getName());

loadClientOrders(client.getId());
}

private void loadFallbackManager() {
Node fallbackView = fxmlLoaderService.loadView(
"/org/chainoptim/desktop/shared/fallback/FallbackManagerView.fxml",
controllerFactory::createController
);
fallbackContainer.getChildren().add(fallbackView);
}

private void loadClientOrders(Integer clientId) {
fallbackManager.reset();
fallbackManager.setLoading(true);

clientOrdersService.getClientOrdersByOrganizationId(clientId)
Expand All @@ -82,12 +104,32 @@ private List<ClientOrder> handleOrdersResponse(Optional<List<ClientOrder>> order
this.clientOrders = orders.get();
fallbackManager.setLoading(false);
System.out.println("Orders received: " + clientOrders);
configureTableView();
bindDataToTableView();
setEditEvents();
});

return clientOrders;
}

private void configureTableView() {
tableView.setEditable(true);
clientIdColumn.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
productIdColumn.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
quantityColumn.setCellFactory(TextFieldTableCell.forTableColumn(new FloatStringConverter()));
statusColumn.setCellFactory(TextFieldTableCell.forTableColumn());

tableView.setMaxHeight(Double.MAX_VALUE);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should identify the configuration that can be taken out of here and reused for the other tables we'll have, perhaps through a static method of a util class.


// Set the column resize policy and their minimum width
tableView.setColumnResizePolicy(new Callback<TableView.ResizeFeatures, Boolean>() {
@Override
public Boolean call(TableView.ResizeFeatures param) {
return TableView.CONSTRAINED_RESIZE_POLICY.call(param) || Boolean.TRUE;
}
});
}

private void bindDataToTableView() {
orderIdColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
clientIdColumn.setCellValueFactory(new PropertyValueFactory<>("clientId"));
Expand All @@ -98,9 +140,37 @@ private void bindDataToTableView() {
estimatedDeliveryDateColumn.setCellValueFactory(new PropertyValueFactory<>("estimatedDeliveryDate"));
deliveryDateColumn.setCellValueFactory(new PropertyValueFactory<>("deliveryDate"));

// Set the items in the table
tableView.getItems().setAll(clientOrders);
}

private void setEditEvents() {
clientIdColumn.setOnEditCommit(event -> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generialize this setOnEditCommit block to not repeat yourself. But more importantly, do not go to the database for every edited value, there should be a save button somewhere (perhaps restricting to updating one order at a time).

ClientOrder order = event.getRowValue();
order.setClientId(event.getNewValue());
updateInDatabase(order);
});

productIdColumn.setOnEditCommit(event -> {
ClientOrder order = event.getRowValue();
order.setProductId(event.getNewValue());
updateInDatabase(order);
});

quantityColumn.setOnEditCommit(event -> {
ClientOrder order = event.getRowValue();
order.setQuantity(event.getNewValue());
updateInDatabase(order);
});

statusColumn.setOnEditCommit(event -> {
ClientOrder order = event.getRowValue();
order.setStatus(event.getNewValue());
updateInDatabase(order);
});
}

private void updateInDatabase(ClientOrder order) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make the update service method and use it here to update. I'll add a Toast system later for confirming successful operation/signaling error.

System.out.println("Change the database with the new value: " + order);
}

private List<ClientOrder> handleOrdersException(Throwable ex) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,175 @@
package org.chainoptim.desktop.features.supplier.controller;

import org.chainoptim.desktop.core.abstraction.ControllerFactory;
import org.chainoptim.desktop.features.supplier.model.Supplier;
import org.chainoptim.desktop.features.supplier.model.SupplierOrder;
import org.chainoptim.desktop.features.supplier.service.SupplierOrdersService;
import org.chainoptim.desktop.shared.fallback.FallbackManager;
import org.chainoptim.desktop.shared.util.DataReceiver;
import org.chainoptim.desktop.shared.util.resourceloader.FXMLLoaderService;

import com.google.inject.Inject;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.StackPane;
import javafx.util.Callback;
import javafx.util.converter.FloatStringConverter;
import javafx.util.converter.IntegerStringConverter;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

public class SupplierOrdersController implements DataReceiver<Supplier> {

private final SupplierOrdersService supplierOrdersService;
private final FallbackManager fallbackManager;
private final FXMLLoaderService fxmlLoaderService;
private final ControllerFactory controllerFactory;

private List<SupplierOrder> supplierOrders;
private Supplier supplier;

@FXML
private StackPane stackPane;
@FXML
private TableView<SupplierOrder> tableView;
@FXML
private TableColumn<SupplierOrder, Integer> orderIdColumn;
@FXML
private TableColumn<SupplierOrder, Integer> supplierIdColumn;
@FXML
private TableColumn<SupplierOrder, Integer> componentIdColumn;
@FXML
private TableColumn<SupplierOrder, Float> quantityColumn;
@FXML
private TableColumn<SupplierOrder, String> statusColumn;
@FXML
private TableColumn<SupplierOrder, LocalDateTime> orderDateColumn;
@FXML
private TableColumn<SupplierOrder, LocalDateTime> estimatedDeliveryDateColumn;
@FXML
private TableColumn<SupplierOrder, LocalDateTime> deliveryDateColumn;
@FXML
private StackPane fallbackContainer;

@Inject
public SupplierOrdersController(SupplierOrdersService supplierOrdersService,
FallbackManager fallbackManager,
FXMLLoaderService fxmlLoaderService,
ControllerFactory controllerFactory) {
this.supplierOrdersService = supplierOrdersService;
this.fallbackManager = fallbackManager;
this.fxmlLoaderService = fxmlLoaderService;
this.controllerFactory = controllerFactory;
}

@Override
public void setData(Supplier supplier) {
System.out.println("Supplier received in orders: " + supplier.getName());
loadFallbackManager();
this.supplier = supplier;
loadSupplierOrders(supplier.getId());
}

private void loadFallbackManager() {
Node fallbackView = fxmlLoaderService.loadView(
"/org/chainoptim/desktop/shared/fallback/FallbackManagerView.fxml",
controllerFactory::createController
);
fallbackContainer.getChildren().add(fallbackView);
}

private void loadSupplierOrders(Integer supplierId) {
fallbackManager.reset();
fallbackManager.setLoading(true);

supplierOrdersService.getSupplierOrdersByOrganizationId(supplierId)
.thenApply(this::handleOrdersResponse)
.exceptionally(this::handleOrdersException);
}

private List<SupplierOrder> handleOrdersResponse(Optional<List<SupplierOrder>> orders) {
Platform.runLater(() -> {
if (orders.isEmpty()) {
fallbackManager.setErrorMessage("No orders found");
return;
}
this.supplierOrders = orders.get();
fallbackManager.setLoading(false);
System.out.println("Orders received: " + supplierOrders);
configureTableView();
bindDataToTableView();
setEditEvents();
});

return supplierOrders;
}

private void configureTableView() {
tableView.setEditable(true);
supplierIdColumn.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
componentIdColumn.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
quantityColumn.setCellFactory(TextFieldTableCell.forTableColumn(new FloatStringConverter()));
statusColumn.setCellFactory(TextFieldTableCell.forTableColumn());

tableView.setMaxHeight(Double.MAX_VALUE);

tableView.setColumnResizePolicy(new Callback<TableView.ResizeFeatures, Boolean>() {
@Override
public Boolean call(TableView.ResizeFeatures param) {
return TableView.CONSTRAINED_RESIZE_POLICY.call(param) || Boolean.TRUE;
}
});
}

private void bindDataToTableView() {
orderIdColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
supplierIdColumn.setCellValueFactory(new PropertyValueFactory<>("supplierId"));
componentIdColumn.setCellValueFactory(new PropertyValueFactory<>("componentId"));
quantityColumn.setCellValueFactory(new PropertyValueFactory<>("quantity"));
// statusColumn.setCellValueFactory(new PropertyValueFactory<>("status"));
orderDateColumn.setCellValueFactory(new PropertyValueFactory<>("orderDate"));
estimatedDeliveryDateColumn.setCellValueFactory(new PropertyValueFactory<>("estimatedDeliveryDate"));
deliveryDateColumn.setCellValueFactory(new PropertyValueFactory<>("deliveryDate"));

tableView.getItems().setAll(supplierOrders);
}

private void setEditEvents() {
supplierIdColumn.setOnEditCommit(event -> {
SupplierOrder order = event.getRowValue();
order.setSupplierId(event.getNewValue());
updateInDatabase(order);
});

componentIdColumn.setOnEditCommit(event -> {
SupplierOrder order = event.getRowValue();
order.setComponentId(event.getNewValue());
updateInDatabase(order);
});

quantityColumn.setOnEditCommit(event -> {
SupplierOrder order = event.getRowValue();
order.setQuantity(event.getNewValue());
updateInDatabase(order);
});
}

private void updateInDatabase(SupplierOrder order) {
System.out.println("Change detected: " + order);
}

private List<SupplierOrder> handleOrdersException(Throwable ex) {
Platform.runLater(() -> fallbackManager.setErrorMessage("Failed to load supplier orders."));
return Collections.emptyList();
}


}

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.chainoptim.desktop.features.supplier.dto;

import lombok.Data;
import org.chainoptim.desktop.features.supplier.model.SupplierOrder;

import java.time.LocalDateTime;

@Data
public class CreateSupplierOrderDTO {

private Integer supplierId;
private Integer componentId;
private Float quantity;
private LocalDateTime orderDate;
private LocalDateTime estimatedDeliveryDate;
private LocalDateTime deliveryDate;
private SupplierOrder.Status status;
}
Loading
Loading