diff --git a/.gitignore b/.gitignore
index 687c4d1d..9777fe96 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,6 @@
 #Ignoring Intellij workspace specific folders and files
 /**/.idea/workspace.xml
 /**/tasks.xml
-/**/*.iml
 
 /**/.idea/libraries
 
diff --git a/Workspace/client/client.iml b/Workspace/client/client.iml
new file mode 100644
index 00000000..b561a70c
--- /dev/null
+++ b/Workspace/client/client.iml
@@ -0,0 +1,18 @@
+
+
+  
+    
+    
+    
+      
+      
+      
+      
+    
+    
+    
+    
+    
+    
+  
+
\ No newline at end of file
diff --git a/Workspace/client/src/main/java/com/pqt/client/Main.java b/Workspace/client/src/main/java/com/pqt/client/Main.java
new file mode 100644
index 00000000..c7240576
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/Main.java
@@ -0,0 +1,50 @@
+package com.pqt.client;
+
+import com.pqt.client.gui.main_frame.MainFrame;
+import com.pqt.client.gui.modules.account_screen.AccountScreen;
+import com.pqt.client.gui.modules.sale_screen.SaleScreen;
+import com.pqt.client.gui.modules.stat_screen.StatScreen;
+import com.pqt.client.gui.modules.stock_screen.StockScreen;
+import com.pqt.client.gui.ressources.components.generics.others.SideBar;
+import com.pqt.client.gui.ressources.components.generics.others.listeners.ISideBarListener;
+import com.pqt.client.gui.ressources.components.generics.toast.ToastFactory;
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.client.module.account.AccountService;
+import com.pqt.client.module.sale.SaleService;
+import com.pqt.client.module.stat.StatService;
+import com.pqt.client.module.stock.StockService;
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class Main extends Application{
+
+    public static void main(String[] args){
+        launch(args);
+    }
+
+    @Override
+    public void start(Stage primaryStage) throws Exception {
+        SaleService saleService = new SaleService();
+        StockService stockService = new StockService();
+        AccountService accountService = new AccountService();
+        StatService statService = new StatService();
+
+        MainFrame mainFrame = new MainFrame(accountService);
+        mainFrame.addModule(new SaleScreen(accountService, stockService, saleService), true);
+        mainFrame.addModule(new StockScreen(stockService, accountService));
+        mainFrame.addModule(new StatScreen(statService));
+        mainFrame.addModule(new AccountScreen(accountService));
+
+
+        Scene scene = new Scene(mainFrame.getPane(), 800, 600);
+        scene.getStylesheets().clear();
+        scene.getStylesheets().addAll(getClass().getResource(GUICssTool.getCssFilePath()).toExternalForm());
+
+        ToastFactory.init(primaryStage);
+        primaryStage.setTitle(GUIStringTool.getAppTitle());
+        primaryStage.setScene(scene);
+        primaryStage.show();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrame.java b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrame.java
new file mode 100644
index 00000000..4ded52f6
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrame.java
@@ -0,0 +1,35 @@
+package com.pqt.client.gui.main_frame;
+
+import com.pqt.client.gui.modules.IGuiModule;
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.module.account.AccountService;
+import javafx.scene.layout.Pane;
+
+public class MainFrame implements IFXComponent {
+
+    private MainFrameView view;
+    private MainFrameController ctrl;
+
+    public MainFrame(AccountService accountService) {
+        MainFrameModel model = new MainFrameModel(accountService);
+        ctrl = new MainFrameController(model);
+        model.addListener(ctrl);
+
+        view = new MainFrameView(ctrl);
+        ctrl.setView(view);
+        ctrl.updateView();
+    }
+
+    public void addModule(IGuiModule module, boolean setActive){
+        ctrl.addModule(module, setActive);
+    }
+
+    public void addModule(IGuiModule module){
+        ctrl.addModule(module, false);
+    }
+
+    @Override
+    public Pane getPane() {
+        return view.getPane();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrameController.java b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrameController.java
new file mode 100644
index 00000000..180f7802
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrameController.java
@@ -0,0 +1,94 @@
+package com.pqt.client.gui.main_frame;
+
+import com.pqt.client.gui.main_frame.listeners.IMainFrameModelListener;
+import com.pqt.client.gui.modules.IGuiModule;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
+import com.pqt.client.gui.ressources.components.specifics.account.listeners.IAccountComponentListener;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.event.Event;
+
+class MainFrameController implements IMainFrameModelListener {
+
+    private MainFrameModel model;
+    private MainFrameView view;
+    private IValidatorComponentListener accountManagerAccountListener;
+
+    MainFrameController(MainFrameModel model) {
+        this.model = model;
+    }
+
+    void setView(MainFrameView view) {
+        this.view = view;
+    }
+
+    void updateView(){
+        view.feedAccountCollectionToManager(model.getAccounts());
+        view.setCurrentAccount(model.getCurrentAccount());
+        if(model.getCurrentAccount()!=null)
+            view.updateModuleButtonLock(model.getCurrentAccount().getPermissionLevel());
+        else
+            view.updateModuleButtonLock(AccountLevel.getLowest());
+    }
+
+    void addModule(IGuiModule module, boolean activationRequired) {
+        boolean activate = activationRequired
+                && model.getCurrentAccount()!=null
+                && model.getCurrentAccount().getPermissionLevel().compareTo(module.getLowestRequiredAccountLevel())>=0;
+        this.view.addGuiModule(module.getModuleName(),module.getPane(), module.getLowestRequiredAccountLevel(), activate);
+    }
+
+    IValidatorComponentListener getAccountManagerValidatorListener() {
+        return new IValidatorComponentListener() {
+            @Override
+            public void onValidationEvent() {
+                if(view.isAccountCreationPossible())
+                    model.connectAccount(view.create());
+            }
+
+            @Override
+            public void onCancelEvent() {
+                model.disconnectCurrentAccount();
+            }
+        };
+    }
+
+    IAccountComponentListener getAccountManagerAccountListener() {
+        return new IAccountComponentListener() {
+            @Override
+            public void onRefreshContentRequestEvent() {
+
+            }
+
+            @Override
+            public void onContentClickEvent(Event event, Account eventTarget) {
+
+            }
+
+            @Override
+            public void onAddContentRequestEvent() {
+
+            }
+
+            @Override
+            public void onRemoveContentRequestEvent(Account content) {
+
+            }
+
+            @Override
+            public void onDetailContentRequestEvent(Account content) {
+
+            }
+        };
+    }
+
+    @Override
+    public void onAccountStatusChangedEvent(boolean status) {
+        updateView();
+    }
+
+    @Override
+    public void onAccountCollectionChangedEvent() {
+        updateView();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrameModel.java b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrameModel.java
new file mode 100644
index 00000000..c8cb5fc7
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrameModel.java
@@ -0,0 +1,65 @@
+package com.pqt.client.gui.main_frame;
+
+import com.pqt.client.gui.main_frame.listeners.IMainFrameModelListener;
+import com.pqt.client.module.account.AccountService;
+import com.pqt.client.module.account.listeners.IAccountListener;
+import com.pqt.core.entities.user_account.Account;
+
+import javax.swing.event.EventListenerList;
+import java.util.Arrays;
+import java.util.Collection;
+
+class MainFrameModel {
+
+    private EventListenerList listenerList;
+    private AccountService accountService;
+
+    MainFrameModel(AccountService accountService) {
+        listenerList = new EventListenerList();
+        this.accountService = accountService;
+        this.accountService.addListener(new IAccountListener() {
+            @Override
+            public void onAccountStatusChangedEvent(boolean status) {
+                MainFrameModel.this.fireAccountStatusChangedEvent(status);
+            }
+
+            @Override
+            public void onAccountListChangedEvent() {
+                MainFrameModel.this.fireAccountCollectionChangedEvent();
+            }
+        });
+    }
+
+    private void fireAccountCollectionChangedEvent() {
+        Arrays.stream(listenerList.getListeners(IMainFrameModelListener.class)).forEach(IMainFrameModelListener::onAccountCollectionChangedEvent);
+    }
+
+    private void fireAccountStatusChangedEvent(boolean status) {
+        Arrays.stream(listenerList.getListeners(IMainFrameModelListener.class)).forEach(l->l.onAccountStatusChangedEvent(status));
+    }
+
+    void connectAccount(Account account) {
+        accountService.setCurrentAccount(account);
+        accountService.logInCurrentAccount(account.getPassword());
+    }
+
+    void disconnectCurrentAccount() {
+        accountService.logOutCurrentAccount();
+    }
+
+    Collection getAccounts(){
+        return accountService.getAllAccounts();
+    }
+
+    void addListener(IMainFrameModelListener listener){
+        listenerList.add(IMainFrameModelListener.class, listener);
+    }
+
+    void removeListener(IMainFrameModelListener listener){
+        listenerList.remove(IMainFrameModelListener.class, listener);
+    }
+
+    Account getCurrentAccount() {
+        return accountService.getCurrentAccount();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrameView.java b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrameView.java
new file mode 100644
index 00000000..7b951581
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/MainFrameView.java
@@ -0,0 +1,142 @@
+package com.pqt.client.gui.main_frame;
+
+import com.pqt.client.gui.ressources.components.AccountManager;
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.components.generics.others.SideBar;
+import com.pqt.client.gui.ressources.components.generics.others.listeners.ISideBarListener;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.application.Platform;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Orientation;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.ToolBar;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.MouseButton;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+
+import java.util.Collection;
+
+class MainFrameView implements IFXComponent{
+
+    private final MainFrameController ctrl;
+
+    private BorderPane mainPane;
+    private AccountManager accountManager;
+    private VBox buttonHolder;
+    private ObjectProperty currentAccountLevel;
+
+    MainFrameView(MainFrameController ctrl) {
+        this.ctrl = ctrl;
+        currentAccountLevel = new SimpleObjectProperty<>(AccountLevel.getLowest());
+        initGui();
+    }
+
+    private void initGui(){
+        mainPane = new BorderPane();
+        mainPane.getStyleClass().addAll("main-module-pane", "main-frame");
+
+        buttonHolder = new VBox();
+
+        SideBar sidebar = new SideBar();
+        sidebar.setFillWidth(true);
+        SideBar.setVgrow(buttonHolder, Priority.ALWAYS);
+        buttonHolder.prefWidthProperty().bind(sidebar.widthProperty());
+        sidebar.getChildren().add(buttonHolder);
+
+        accountManager = new AccountManager();
+        accountManager.addListener(ctrl.getAccountManagerValidatorListener());
+        accountManager.addListener(ctrl.getAccountManagerAccountListener());
+        accountManager.getPane().prefWidthProperty().bind(sidebar.widthProperty());
+        sidebar.getChildren().add(accountManager.getPane());
+
+        mainPane.setLeft(sidebar);
+
+        Button sidebarCtrl = new Button();
+        if(sidebar.isExpanded())
+            sidebarCtrl.setText(GUIStringTool.getSideBarCollapseButtonLabel());
+        else
+            sidebarCtrl.setText(GUIStringTool.getSideBarExpandButtonLabel());
+        sidebarCtrl.setOnMouseClicked(event -> {
+            if(sidebar.isExpanded())
+                sidebar.collapse();
+            else if(sidebar.isCollapsed())
+                sidebar.expand();
+        });
+        sidebar.addListener(new ISideBarListener() {
+            @Override
+            public void onCollapsedFinished() {
+                sidebarCtrl.setText(GUIStringTool.getSideBarExpandButtonLabel());
+            }
+
+            @Override
+            public void onExpandFinished() {
+                sidebarCtrl.setText(GUIStringTool.getSideBarCollapseButtonLabel());
+            }
+        });
+        mainPane.setTop(sidebarCtrl);
+    }
+
+    @Override
+    public Pane getPane() {
+        return mainPane;
+    }
+
+    void addGuiModule(String moduleName, Pane moduleContent, AccountLevel requiredLevel, boolean setActive){
+        Button button = new Button(moduleName);
+        button.getStyleClass().add("menu-button");
+
+        Runnable buttonActivationCode = ()->{
+            buttonHolder.getChildren()
+                    .stream()
+                    .filter(Button.class::isInstance)
+                    .map(Button.class::cast)
+                    .forEach(b-> b.getStyleClass().remove("menu-button-selected"));
+            button.getStyleClass().add("menu-button-selected");
+            Platform.runLater(()->{
+                buttonHolder.getChildren().forEach(Node::applyCss);
+                mainPane.setCenter(moduleContent);
+            });
+        };
+        button.setOnMouseClicked(event-> {
+            if(event.getButton().equals(MouseButton.PRIMARY))
+                buttonActivationCode.run();
+        });
+        button.setOnKeyTyped(event->{
+            if (event.getCode().equals(KeyCode.ENTER))
+                buttonActivationCode.run();
+        });
+        currentAccountLevel.addListener((obs, oldVal, newVal)->button.setDisable(requiredLevel.compareTo(newVal)>0));
+        button.setDisable(requiredLevel.compareTo(currentAccountLevel.get())>0);
+        if(setActive)
+            buttonActivationCode.run();
+        buttonHolder.getChildren().add(button);
+    }
+
+    boolean isAccountCreationPossible(){
+        return accountManager.isCreationPossible();
+    }
+
+    Account create(){
+        return accountManager.create();
+    }
+
+    void setCurrentAccount(Account account){
+        accountManager.setCurrentAccount(account);
+    }
+
+    void feedAccountCollectionToManager(Collection accounts){
+        accountManager.display(accounts);
+    }
+
+    void updateModuleButtonLock(AccountLevel level) {
+        currentAccountLevel.setValue(level);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/listeners/IMainFrameModelListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/listeners/IMainFrameModelListener.java
new file mode 100644
index 00000000..5c876e26
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/main_frame/listeners/IMainFrameModelListener.java
@@ -0,0 +1,8 @@
+package com.pqt.client.gui.main_frame.listeners;
+
+import java.util.EventListener;
+
+public interface IMainFrameModelListener extends EventListener{
+    void onAccountStatusChangedEvent(boolean status);
+    void onAccountCollectionChangedEvent();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/IGuiModule.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/IGuiModule.java
new file mode 100644
index 00000000..e4dfa3d2
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/IGuiModule.java
@@ -0,0 +1,9 @@
+package com.pqt.client.gui.modules;
+
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.core.entities.user_account.AccountLevel;
+
+public interface IGuiModule extends IFXComponent{
+    String getModuleName();
+    AccountLevel getLowestRequiredAccountLevel();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreen.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreen.java
new file mode 100644
index 00000000..ceee3d9e
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreen.java
@@ -0,0 +1,36 @@
+package com.pqt.client.gui.modules.account_screen;
+
+import com.pqt.client.gui.modules.IGuiModule;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.client.module.account.AccountService;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.scene.layout.Pane;
+
+public class AccountScreen implements IGuiModule {
+
+    private AccountScreenView view;
+
+    public AccountScreen(AccountService accountService) {
+        AccountScreenModel model = new AccountScreenModel(accountService);
+        AccountScreenController ctrl = new AccountScreenController(model);
+        view = new AccountScreenView(ctrl);
+
+        ctrl.setView(view);
+        ctrl.updateView();
+    }
+
+    @Override
+    public String getModuleName() {
+        return GUIStringTool.getAccountGuiModuleName();
+    }
+
+    @Override
+    public AccountLevel getLowestRequiredAccountLevel() {
+        return AccountLevel.WAITER;
+    }
+
+    @Override
+    public Pane getPane() {
+        return view.getPane();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreenController.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreenController.java
new file mode 100644
index 00000000..4cb8f15f
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreenController.java
@@ -0,0 +1,83 @@
+package com.pqt.client.gui.modules.account_screen;
+
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+
+class AccountScreenController {
+
+    private AccountScreenModel model;
+    private AccountScreenView view;
+
+    AccountScreenController(AccountScreenModel model) {
+        this.model = model;
+    }
+
+    void setView(AccountScreenView view) {
+        this.view = view;
+    }
+
+    void updateView() {
+        updateViewAccountCollection();
+        updateViewActionLock();
+    }
+
+    private void updateViewAccountCollection(){
+        view.setAccountCollection(model.getAccountCollection());
+    }
+
+    private void updateViewActionLock() {
+        if (model.getCurrentAccount() != null) {
+            view.setAddAccountActionLocked(AccountLevel.MASTER.compareTo(model.getCurrentAccount().getPermissionLevel()) > 0);
+            view.setDetailAccountActionLocked(!view.isItemSelected() || AccountLevel.MASTER.compareTo(model.getCurrentAccount().getPermissionLevel()) > 0);
+            view.setRemoveAccountActionLocked(!view.isItemSelected() || AccountLevel.MASTER.compareTo(model.getCurrentAccount().getPermissionLevel()) > 0);
+        }else{
+            view.setAddAccountActionLocked(true);
+            view.setDetailAccountActionLocked(true);
+            view.setRemoveAccountActionLocked(true);
+        }
+    }
+
+    IValidatorComponentListener getDetailScreenValidationListener(){
+        return new IValidatorComponentListener() {
+            @Override
+            public void onValidationEvent() {
+                if(view.isDetailCreationPossible()){
+                    if(view.getDetailScreenInitialValue()!=null){
+                        model.modifyAccount(view.getDetailScreenInitialValue(), view.getDetailScreenCreatedValue());
+                    }else{
+                        model.addAccount(view.getDetailScreenCreatedValue());
+                    }
+                    view.hideDetailScreen();
+                }
+            }
+
+            @Override
+            public void onCancelEvent() {
+                view.hideDetailScreen();
+            }
+        };
+    }
+
+    void onAddAccountRequested() {
+        view.showDetailScreen(null, model.getLevels());
+    }
+
+    void onDetailAccountRequested() {
+        if(view.isItemSelected())
+            view.showDetailScreen(view.getSelectedItem(), model.getLevels());
+    }
+
+    void onRemoveAccountRequested() {
+        if(view.isItemSelected())
+            model.removeAccount(view.getSelectedItem());
+    }
+
+    void onRefreshAccountRequested() {
+        this.updateView();
+    }
+
+    void onSelectedAccountChanged(Account oldVal, Account newVal) {
+        updateViewActionLock();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreenModel.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreenModel.java
new file mode 100644
index 00000000..a1a129a0
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreenModel.java
@@ -0,0 +1,44 @@
+package com.pqt.client.gui.modules.account_screen;
+
+import com.pqt.client.module.account.AccountService;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+
+import java.util.Collection;
+import java.util.EnumSet;
+
+//TODO MAJ les méthds modif, add et remove une fois que l'accountService prend en compte les modifs
+class AccountScreenModel {
+
+    private AccountService accountService;
+
+    AccountScreenModel(AccountService accountService) {
+        this.accountService = accountService;
+    }
+
+    void modifyAccount(Account oldVal, Account newVal) {
+        //accountService.submitAccountUpdate(oldVal, newVal);
+    }
+
+    void addAccount(Account newVal) {
+        //accountService.submitAccountUpdate(null, newVal);
+    }
+
+    void removeAccount(Account oldVal) {
+        //accountService.submitAccountUpdate(oldVal, null);
+    }
+
+    Collection getAccountCollection() {
+        return accountService.getAllAccounts();
+    }
+
+    Account getCurrentAccount() {
+        return accountService.getCurrentAccount();
+    }
+
+    Collection getLevels() {
+        //TODO régler ça aussi
+        //return accountService.getAvailableLevels();
+        return EnumSet.allOf(AccountLevel.class);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreenView.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreenView.java
new file mode 100644
index 00000000..71a067fc
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/AccountScreenView.java
@@ -0,0 +1,178 @@
+package com.pqt.client.gui.modules.account_screen;
+
+import com.pqt.client.gui.modules.account_screen.account_manager_screen.AccountManagerScreen;
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.application.Platform;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.scene.Node;
+import javafx.scene.control.*;
+import javafx.scene.input.MouseButton;
+import javafx.scene.layout.*;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+class AccountScreenView implements IFXComponent{
+
+    private AccountScreenController ctrl;
+    private StackPane mainPane;
+    private BorderPane mainPaneContent;
+    private TableView tableView;
+    private AccountManagerScreen accountManagerScreen;
+
+    private Button addAccountButton, detailAccountButton, removeAccountButton;
+
+
+    AccountScreenView(AccountScreenController ctrl) {
+        this.ctrl = ctrl;
+        initGui();
+    }
+
+    private void initGui() {
+        mainPane = new StackPane();
+        mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
+
+        mainPaneContent = new BorderPane();
+
+        tableView = new TableView<>();
+
+        tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
+        tableView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal)-> ctrl.onSelectedAccountChanged(oldVal, newVal));
+        TableColumn nameColumn = new TableColumn<>(GUIStringTool.getAccountNameColumnHeaderLabel());
+        nameColumn.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().getUsername()));
+        tableView.getColumns().add(nameColumn);
+
+        TableColumn levelColumn = new TableColumn<>(GUIStringTool.getAccountLevelColumnHeaderLabel());
+        levelColumn.setCellValueFactory(param -> new SimpleStringProperty(
+                            GUIStringTool.getAccountLevelStringRenderer().render(param.getValue().getPermissionLevel())
+        ));
+        tableView.getColumns().add(levelColumn);
+        mainPaneContent.setCenter(tableView);
+
+        HBox mainPaneTopContent = new HBox();
+        mainPaneTopContent.setFillHeight(true);
+
+        Label label = new Label(GUIStringTool.getAccountListTitleLabel());
+        label.getStyleClass().add(GUICssTool.getTitleTextStyleClass());
+        mainPaneTopContent.getChildren().add(label);
+
+        HBox separator = new HBox();
+        ToolBar buttonToolbar = new ToolBar();
+        addAccountButton = new Button(GUIStringTool.getAddButtonLabel());
+        addAccountButton.setOnMouseClicked(event->{
+            if (event.getButton().equals(MouseButton.PRIMARY))
+                ctrl.onAddAccountRequested();
+        });
+        buttonToolbar.getItems().add(addAccountButton);
+        detailAccountButton = new Button(GUIStringTool.getDetailButtonLabel());
+        detailAccountButton.setOnMouseClicked(event->{
+            if (event.getButton().equals(MouseButton.PRIMARY))
+                ctrl.onDetailAccountRequested();
+        });
+        buttonToolbar.getItems().add(detailAccountButton);
+        removeAccountButton = new Button(GUIStringTool.getRemoveButtonLabel());
+        removeAccountButton.setOnMouseClicked(event->{
+            if (event.getButton().equals(MouseButton.PRIMARY))
+                ctrl.onRemoveAccountRequested();
+        });
+        buttonToolbar.getItems().add(removeAccountButton);
+        Button refreshAccountButton = new Button(GUIStringTool.getRefreshButtonLabel());
+        refreshAccountButton.setOnMouseClicked(event->{
+            if (event.getButton().equals(MouseButton.PRIMARY))
+                ctrl.onRefreshAccountRequested();
+        });
+        buttonToolbar.getItems().add(refreshAccountButton);
+
+        mainPaneTopContent.getChildren().addAll(separator, buttonToolbar);
+        HBox.setHgrow(separator, Priority.ALWAYS);
+
+        mainPaneContent.setTop(mainPaneTopContent);
+        mainPane.getChildren().add(mainPaneContent);
+    }
+
+    boolean isItemSelected(){
+        return tableView.getSelectionModel().getSelectedItem()!=null;
+    }
+
+    Account getSelectedItem(){
+        return tableView.getSelectionModel().getSelectedItem();
+    }
+
+    @Override
+    public Pane getPane() {
+        return mainPane;
+    }
+
+    boolean isDetailCreationPossible() {
+        return accountManagerScreen!=null && accountManagerScreen.isCreationPossible();
+    }
+
+    Account getDetailScreenInitialValue() {
+        if(accountManagerScreen!=null)
+            return accountManagerScreen.getInitialValue();
+        return null;
+    }
+
+    Account getDetailScreenCreatedValue() {
+        if(accountManagerScreen!=null)
+            return accountManagerScreen.create();
+        return null;
+    }
+
+    boolean isDetailScreenShown(){
+        return accountManagerScreen!=null;
+    }
+
+    void showDetailScreen(Account initialValue, Collection availableLevels){
+        if(!isDetailScreenShown()){
+            Pane separator = new Pane();
+            separator.getStyleClass().add(GUICssTool.getIntermediaryPaneStyleClass());
+            accountManagerScreen = new AccountManagerScreen(initialValue, availableLevels);
+            accountManagerScreen.addListener(ctrl.getDetailScreenValidationListener());
+
+            Platform.runLater(()->{
+                mainPane.getChildren().addAll(separator, accountManagerScreen.getPane());
+            });
+        }
+    }
+
+    void hideDetailScreen(){
+        if(isDetailScreenShown()){
+            List toRemove = mainPane.getChildren()
+                    .stream()
+                    .filter(node->!node.equals(mainPaneContent))
+                    .collect(Collectors.toList());
+
+            Platform.runLater(()->{
+                mainPane.getChildren().removeAll(toRemove);
+                accountManagerScreen = null;
+            });
+
+        }
+    }
+
+    void setAccountCollection(Collection accountCollection) {
+        Platform.runLater(()->{
+            tableView.getItems().clear();
+            if(accountCollection!=null)
+                tableView.getItems().addAll(accountCollection);
+        });
+    }
+
+    void setAddAccountActionLocked(boolean locked) {
+        addAccountButton.setDisable(locked);
+    }
+
+    void setDetailAccountActionLocked(boolean locked) {
+        detailAccountButton.setDisable(locked);
+    }
+
+    void setRemoveAccountActionLocked(boolean locked) {
+        removeAccountButton.setDisable(locked);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreen.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreen.java
new file mode 100644
index 00000000..26cd33e2
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreen.java
@@ -0,0 +1,56 @@
+package com.pqt.client.gui.modules.account_screen.account_manager_screen;
+
+import com.pqt.client.gui.ressources.components.generics.creators.IFXCreatorComponent;
+import com.pqt.client.gui.ressources.components.generics.validators.IFXValidatorComponent;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.scene.layout.Pane;
+
+import java.util.Collection;
+
+//TODO à faire
+public class AccountManagerScreen implements IFXValidatorComponent, IFXCreatorComponent{
+
+    private AccountManagerScreenModel model;
+    private AccountManagerScreenView view;
+    private AccountManagerScreenController ctrl;
+
+    public AccountManagerScreen(Account initialValue, Collection availableLevels) {
+        model = new AccountManagerScreenModel(initialValue, availableLevels);
+        ctrl = new AccountManagerScreenController(model);
+        view = new AccountManagerScreenView(ctrl);
+
+        ctrl.setView(view);
+        ctrl.updateView();
+    }
+
+    public Account getInitialValue(){
+        return model.getInitialValue();
+    }
+
+    @Override
+    public Account create() {
+        return model.getCurrentValue();
+    }
+
+    @Override
+    public boolean isCreationPossible() {
+        return model.isCurrentValueValid();
+    }
+
+    @Override
+    public void addListener(IValidatorComponentListener l) {
+        ctrl.addListener(l);
+    }
+
+    @Override
+    public void removeListener(IValidatorComponentListener l) {
+        ctrl.removeListener(l);
+    }
+
+    @Override
+    public Pane getPane() {
+        return view.getPane();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreenController.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreenController.java
new file mode 100644
index 00000000..e3b6e000
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreenController.java
@@ -0,0 +1,58 @@
+package com.pqt.client.gui.modules.account_screen.account_manager_screen;
+
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
+import com.pqt.core.entities.user_account.AccountLevel;
+
+import javax.swing.event.EventListenerList;
+import java.util.Arrays;
+
+class AccountManagerScreenController {
+
+    private EventListenerList listenerList;
+    private AccountManagerScreenView view;
+    private AccountManagerScreenModel model;
+
+    AccountManagerScreenController(AccountManagerScreenModel model) {
+        listenerList = new EventListenerList();
+        this.model = model;
+    }
+
+    void setView(AccountManagerScreenView view) {
+        this.view = view;
+    }
+
+    void updateView() {
+        view.setLevelCollection(model.getAccountLevelCollection());
+        view.setData(model.getCurrentValue());
+    }
+
+    void addListener(IValidatorComponentListener l) {
+        listenerList.add(IValidatorComponentListener.class, l);
+    }
+
+    void removeListener(IValidatorComponentListener l) {
+        listenerList.remove(IValidatorComponentListener.class, l);
+    }
+
+    void onNameChanged(String oldVal, String newVal) {
+        model.changeName(newVal);
+    }
+
+    void onPasswordChanged(String oldVal, String newVal) {
+        model.changePassword(newVal);
+    }
+
+    void onLevelChanged(AccountLevel oldVal, AccountLevel newVal) {
+        model.changeLevel(newVal);
+    }
+
+    void onValidationEvent() {
+        Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class))
+                .forEach(IValidatorComponentListener::onValidationEvent);
+    }
+
+    void onCancelEvent() {
+        Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class))
+                .forEach(IValidatorComponentListener::onCancelEvent);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreenModel.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreenModel.java
new file mode 100644
index 00000000..e0dd15d0
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreenModel.java
@@ -0,0 +1,61 @@
+package com.pqt.client.gui.modules.account_screen.account_manager_screen;
+
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+class AccountManagerScreenModel {
+    private Account currentValue;
+    private Account initialValue;
+    private Set levels;
+
+    AccountManagerScreenModel(Account initialValue, Collection availableLevels) {
+        levels = new HashSet<>();
+        if(availableLevels!=null)
+            levels.addAll(availableLevels);
+        this.initialValue = initialValue;
+        this.currentValue = (initialValue!=null?new Account(initialValue):getNewAccount());
+    }
+
+    Account getCurrentValue() {
+        return currentValue;
+    }
+
+    Account getInitialValue() {
+        return initialValue;
+    }
+
+    boolean isCurrentValueValid() {
+        return !currentValue.equals(initialValue)
+                && currentValue.getUsername()!=null
+                && !currentValue.getUsername().isEmpty()
+                && currentValue.getPermissionLevel()!=null;
+    }
+
+    Collection getAccountLevelCollection(){
+        return levels;
+    }
+
+    void changeName(String username) {
+        currentValue.setUsername(username);
+    }
+
+    void changePassword(String password) {
+        currentValue.setPassword(password);
+    }
+
+    void changeLevel(AccountLevel level) {
+        currentValue.setPermissionLevel(level);
+    }
+
+    private Account getNewAccount() {
+        Account account = new Account();
+        account.setUsername("");
+        account.setPassword("");
+        account.setPermissionLevel(levels.stream().min(Enum::compareTo).orElse(AccountLevel.getLowest()));
+        return account;
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreenView.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreenView.java
new file mode 100644
index 00000000..3d9d6410
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/account_screen/account_manager_screen/AccountManagerScreenView.java
@@ -0,0 +1,107 @@
+package com.pqt.client.gui.modules.account_screen.account_manager_screen;
+
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.application.Platform;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.input.MouseButton;
+import javafx.scene.layout.*;
+
+import java.util.Collection;
+
+
+class AccountManagerScreenView implements IFXComponent{
+
+    private StackPane mainPane;
+    private AccountManagerScreenController ctrl;
+
+    private ChoiceBox levelChoiceBox;
+    private TextField nameTextField;
+    private PasswordField passwordField;
+
+    AccountManagerScreenView(AccountManagerScreenController ctrl) {
+        this.ctrl = ctrl;
+        initGui();
+    }
+
+    private void initGui() {
+        mainPane = new StackPane();
+
+        BorderPane mainPaneContent = new BorderPane();
+
+
+        GridPane mainPaneCenterContent = new GridPane();
+        mainPaneCenterContent.setAlignment(Pos.CENTER);
+        Label nameLabel = new Label(GUIStringTool.getUsernameLabel());
+        nameTextField = new TextField();
+        nameTextField.textProperty().addListener((obs, oldVal, newVal)->ctrl.onNameChanged(oldVal, newVal));
+        mainPaneCenterContent.add(nameLabel, 0, 0);
+        mainPaneCenterContent.add(nameTextField, 1,0);
+
+        Label passwordLabel = new Label(GUIStringTool.getPasswordLabel());
+        passwordField = new PasswordField();
+        passwordField.textProperty().addListener((obs, oldVal, newVal)->ctrl.onPasswordChanged(oldVal, newVal));
+        mainPaneCenterContent.add(passwordLabel, 0, 1);
+        mainPaneCenterContent.add(passwordField, 1,1);
+
+        Label levelLabel = new Label(GUIStringTool.getUserLevelLabel());
+        levelChoiceBox = new ChoiceBox<>();
+        levelChoiceBox.valueProperty().addListener((obs, oldVal, newVal)->ctrl.onLevelChanged(oldVal, newVal));
+        mainPaneCenterContent.add(levelLabel, 0, 2);
+        mainPaneCenterContent.add(levelChoiceBox, 1,2);
+
+        mainPaneContent.setCenter(mainPaneCenterContent);
+
+        HBox mainPaneBottomContent = new HBox();
+        mainPaneBottomContent.setFillHeight(true);
+        Button validationButton = new Button(GUIStringTool.getValidationButtonLabel());
+        validationButton.setOnMouseClicked(event -> {
+            if (event.getButton().equals(MouseButton.PRIMARY))
+                ctrl.onValidationEvent();
+        });
+        Button cancelButton = new Button(GUIStringTool.getCancelButtonLabel());
+        cancelButton.setOnMouseClicked(event -> {
+            if (event.getButton().equals(MouseButton.PRIMARY))
+                ctrl.onCancelEvent();
+        });
+        HBox separator = new HBox();
+
+        mainPaneBottomContent.getChildren().addAll(separator, validationButton, cancelButton);
+        HBox.setHgrow(separator, Priority.ALWAYS);
+
+        mainPaneContent.setBottom(mainPaneBottomContent);
+        mainPane.getChildren().add(mainPaneContent);
+    }
+
+    @Override
+    public Pane getPane() {
+        return mainPane;
+    }
+
+    void setLevelCollection(Collection levelCollection) {
+        Platform.runLater(()->{
+            levelChoiceBox.getItems().clear();
+            levelChoiceBox.getItems().addAll(levelCollection);
+        });
+    }
+
+    void setData(Account data) {
+        Platform.runLater(()->{
+            if(data!=null){
+                nameTextField.setText(data.getUsername());
+                passwordField.setText(data.getPassword());
+                levelChoiceBox.setValue(data.getPermissionLevel());
+            }else{
+                nameTextField.setText("");
+                passwordField.setText("");
+                levelChoiceBox.setValue(levelChoiceBox.getItems()
+                        .stream()
+                        .min(Enum::compareTo)
+                        .orElse(AccountLevel.getLowest()));
+            }
+        });
+    }
+}
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..c1e72268
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreen.java
@@ -0,0 +1,39 @@
+package com.pqt.client.gui.modules.sale_screen;
+
+import com.pqt.client.gui.modules.IGuiModule;
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.client.module.account.AccountService;
+import com.pqt.client.module.sale.SaleService;
+import com.pqt.client.module.stock.StockService;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.scene.layout.Pane;
+
+public class SaleScreen implements IGuiModule {
+
+    private SaleScreenView view;
+
+    public SaleScreen(AccountService accountService, StockService stockService, SaleService saleService) {
+        SaleScreenModel model = new SaleScreenModel(accountService, stockService, saleService);
+        SaleScreenController ctrl = new SaleScreenController(model);
+        view = new SaleScreenView(ctrl);
+
+        ctrl.setView(view);
+        ctrl.updateView();
+    }
+
+    @Override
+    public Pane getPane() {
+        return view.getPane();
+    }
+
+    @Override
+    public String getModuleName() {
+        return GUIStringTool.getSaleGuiModuleName();
+    }
+
+    @Override
+    public AccountLevel getLowestRequiredAccountLevel() {
+        return AccountLevel.WAITER;
+    }
+}
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..6640d324
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenController.java
@@ -0,0 +1,191 @@
+package com.pqt.client.gui.modules.sale_screen;
+
+import com.pqt.client.gui.modules.sale_screen.listeners.ISaleScreenModelListener;
+import com.pqt.client.gui.modules.sale_screen.sale_validation_screen.listeners.ISaleValidationScreenListener;
+import com.pqt.client.gui.ressources.components.specifics.products.listeners.IStockComponentListener;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
+import com.pqt.client.gui.ressources.components.specifics.sale.listeners.ISaleComponentListener;
+import com.pqt.core.entities.product.Product;
+import com.pqt.core.entities.sale.Sale;
+import com.pqt.core.entities.sale.SaleStatus;
+import com.pqt.core.entities.sale.SaleType;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.event.Event;
+
+import java.util.List;
+
+class SaleScreenController {
+
+    private SaleScreenModel model;
+    private SaleScreenView view;
+
+    SaleScreenController(SaleScreenModel model) {
+        this.model = model;
+        this.model.addListener(new ISaleScreenModelListener() {
+            @Override
+            public void onSaleValidatedEvent() {
+                SaleScreenController.this.onSaleValidationSuccess();
+            }
+
+            @Override
+            public void onSaleNotValidatedEvent(SaleStatus status, Throwable cause) {
+                onSaleValidationError(status, cause);
+            }
+
+            @Override
+            public void onStockUpdatedEvent() {
+                view.setProducts(model.getProductList());
+            }
+
+            @Override
+            public void onAccountConnectedStateUpdatedEvent() {
+                updateActionLock();
+            }
+
+            @Override
+            public void onAccountListUpdatedEvent() {
+                view.setAccounts(model.getAccountList());
+            }
+
+
+        });
+    }
+
+    private void onSaleValidationSuccess() {
+        view.setSaleStatus(SaleStatus.ACCEPTED);
+    }
+
+    private void onSaleValidationError(SaleStatus status, Throwable cause) {
+        view.setSaleStatus(status);
+    }
+
+    void setView(SaleScreenView view) {
+        this.view = view;
+    }
+
+    void onAccountSelectedAsBeneficiary(Account account){
+        model.setSaleBeneficiary(account);
+    }
+
+    private Sale getCurrentSale(){
+        return model.getCurrentSale();
+    }
+
+    private void updateSale(){
+        view.setSale(getCurrentSale());
+        updateActionLock();
+    }
+
+    private void updateActionLock() {
+        boolean validationButtonEnabled = model.checkValidity(getCurrentSale())
+                && model.isCurrentAccountConnected()
+                && model.getCurrentAccountLevel().compareTo(AccountLevel.WAITER)>=0;
+        view.setValidationButtonEnabled(validationButtonEnabled);
+    }
+
+    private void updateData(){
+        view.setProducts(fetchProductList());
+        view.setSaleTypes(fetchSaleTypeList());
+        view.setAccounts(fetchAccountList());
+    }
+
+    void updateView(){
+        updateData();
+        updateSale();
+    }
+
+    private List 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.updateSale();
+            }
+
+            @Override
+            public void onRefreshContentRequestEvent() {}
+
+            @Override
+            public void onContentClickEvent(Event event, Sale eventTarget) {}
+
+            @Override
+            public void onAddContentRequestEvent() {}
+
+            @Override
+            public void onRemoveContentRequestEvent(Sale content) {}
+
+            @Override
+            public void onDetailContentRequestEvent(Sale content) {}
+        };
+    }
+
+    IStockComponentListener getStockDisplayerListener() {
+        return new IStockComponentListener() {
+            @Override
+            public void onRefreshContentRequestEvent() {}
+
+            @Override
+            public void onContentClickEvent(Event event, Product eventTarget) {
+                if(eventTarget!=null) {
+                    model.addProductToSale(eventTarget);
+                    SaleScreenController.this.updateSale();
+                }
+            }
+
+            @Override
+            public void onAddContentRequestEvent() {}
+
+            @Override
+            public void onRemoveContentRequestEvent(Product content) {}
+
+            @Override
+            public void onDetailContentRequestEvent(Product content) {}
+        };
+    }
+
+    Account getDefaultAccount() {
+        return new Account(null, null, AccountLevel.getLowest());
+    }
+
+    IValidatorComponentListener getValidatorListener() {
+        return new IValidatorComponentListener() {
+            @Override
+            public void onValidationEvent() {
+                if(model.commitSale())
+                    view.switchToSaleValidationWaitingMode(model.getTempSaleId(), model.getCurrentSale());
+            }
+
+            @Override
+            public void onCancelEvent() {
+                model.clearSale();
+                SaleScreenController.this.updateView();
+            }
+        };
+    }
+
+    void onSaleTypeSelected(SaleType saleType) {
+        model.setSaleType(saleType);
+    }
+
+    ISaleValidationScreenListener getSaleValidationScreenListener() {
+        return saleValidatedSuccessfully -> {
+            view.switchToSaleCompositionMode();
+            if(saleValidatedSuccessfully){
+                model.clearSale();
+            }
+
+            updateView();
+        };
+    }
+}
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..4cfc6d54
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenModel.java
@@ -0,0 +1,225 @@
+package com.pqt.client.gui.modules.sale_screen;
+
+import com.pqt.client.gui.modules.sale_screen.listeners.ISaleScreenModelListener;
+import com.pqt.client.module.account.AccountService;
+import com.pqt.client.module.account.listeners.IAccountListener;
+import com.pqt.client.module.sale.SaleBuilder;
+import com.pqt.client.module.sale.SaleService;
+import com.pqt.client.module.sale.listeners.ISaleListener;
+import com.pqt.client.module.stock.Listeners.IStockListener;
+import com.pqt.client.module.stock.StockService;
+import com.pqt.core.entities.product.Product;
+import com.pqt.core.entities.sale.Sale;
+import com.pqt.core.entities.sale.SaleStatus;
+import com.pqt.core.entities.sale.SaleType;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+
+import javax.swing.event.EventListenerList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+class SaleScreenModel {
+
+    private EventListenerList listeners;
+
+    private AccountService accountService;
+    private StockService stockService;
+    private SaleService saleService;
+
+    private SaleBuilder currentSaleBuilder;
+    private long tempSaleId;
+
+    SaleScreenModel(AccountService accountService, StockService stockService, SaleService saleService) {
+        if(accountService==null || stockService==null || saleService==null)
+            throw new NullPointerException("At least one of the following services is null : account, stock, sale");
+
+        listeners = new EventListenerList();
+        this.accountService = accountService;
+        this.stockService = stockService;
+        this.saleService = saleService;
+
+        saleService.addListener(new ISaleListener() {
+            @Override
+            public void onSaleValidationSuccess(long saleId) {
+                if(saleId == SaleScreenModel.this.tempSaleId){
+                    SaleScreenModel.this.fireSaleValidatedEvent();
+                }
+            }
+
+            @Override
+            public void onSaleValidationError(long saleId, Throwable cause) {
+                if(saleId == SaleScreenModel.this.tempSaleId){
+                    SaleScreenModel.this.fireSaleNotValidatedEvent(SaleStatus.ABORTED, cause);
+                }
+            }
+
+            @Override
+            public void onSaleValidationRefused(long saleId, Throwable cause) {
+                if(saleId == SaleScreenModel.this.tempSaleId){
+                    SaleScreenModel.this.fireSaleNotValidatedEvent(SaleStatus.REFUSED, cause);
+                }
+            }
+        });
+        stockService.addListener(new IStockListener() {
+            @Override
+            public void onGetProductListSuccessEvent() {
+
+            }
+
+            @Override
+            public void onGetProductListErrorEvent(Throwable cause) {
+
+            }
+
+            @Override
+            public void onGetProductListRefusedEvent(Throwable cause) {
+
+            }
+
+            @Override
+            public void onProductListUpdateSuccessEvent(long id) {
+
+            }
+
+            @Override
+            public void onProductListUpdateErrorEvent(long id, Throwable cause) {
+
+            }
+
+            @Override
+            public void onProductListUpdateRefusedEvent(long id, Throwable cause) {
+
+            }
+
+            @Override
+            public void onProductListChangedEvent() {
+                fireStockUpdatedEvent();
+            }
+        });
+        accountService.addListener(new IAccountListener() {
+            @Override
+            public void onAccountStatusChangedEvent(boolean status) {
+                fireAccountConnectedStatusUpdateEvent();
+            }
+
+            @Override
+            public void onAccountListChangedEvent() {
+                fireAccountListUpdatedEvent();
+            }
+        });
+
+        clearSale();
+    }
+
+    private void fireSaleValidatedEvent() {
+        Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
+                .forEach(ISaleScreenModelListener::onSaleValidatedEvent);
+    }
+
+    private void fireSaleNotValidatedEvent(SaleStatus status, Throwable cause) {
+        Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
+                .forEach(l->l.onSaleNotValidatedEvent(status, cause));
+    }
+
+    private void fireStockUpdatedEvent(){
+        Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
+                .forEach(ISaleScreenModelListener::onStockUpdatedEvent);
+    }
+
+    private void fireAccountListUpdatedEvent(){
+        Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
+                .forEach(ISaleScreenModelListener::onAccountListUpdatedEvent);
+    }
+
+    private void fireAccountConnectedStatusUpdateEvent() {
+        Arrays.stream(listeners.getListeners(ISaleScreenModelListener.class))
+                .forEach(ISaleScreenModelListener::onAccountConnectedStateUpdatedEvent);
+    }
+
+    List getAccountList() {
+        return accountService.getAllAccounts();
+    }
+
+    List getSaleTypeList() {
+        return saleService.getSaleTypes();
+    }
+
+    Sale getCurrentSale() {
+        return currentSaleBuilder!=null?currentSaleBuilder.build():null;
+    }
+
+    List getProductList() {
+        return stockService.getProducts().stream().filter(Product::isSellable).collect(Collectors.toList());
+    }
+
+    void clearSale() {
+        currentSaleBuilder = getNewSaleBuilder();
+        tempSaleId = -1;
+    }
+
+    private SaleBuilder getNewSaleBuilder(){
+        SaleBuilder saleBuilder = saleService.getNewSaleBuilder();
+        saleBuilder.orderedBy(accountService.getCurrentAccount());
+        saleBuilder.saleType(SaleType.CASH);
+        return saleBuilder;
+    }
+
+    boolean commitSale() {
+        if(!checkValidity(currentSaleBuilder.build()))
+            return false;
+
+        tempSaleId = saleService.commitSale(currentSaleBuilder);
+        return tempSaleId!=-1;
+    }
+
+    boolean checkValidity(Sale sale) {
+        return sale.getProducts().size()>0
+                && sale.getOrderedBy()!=null
+                && sale.getType()!=null;
+    }
+
+    long getTempSaleId(){
+        return tempSaleId;
+    }
+
+    void addProductToSale(Product product) {
+        if(currentSaleBuilder!=null)
+            currentSaleBuilder.addProduct(product);
+    }
+
+    void removeProductFromSale(Product product) {
+        if(currentSaleBuilder!=null)
+            currentSaleBuilder.removeProduct(product);
+    }
+
+    void setSaleType(SaleType saleType) {
+        if(currentSaleBuilder!=null)
+            currentSaleBuilder.saleType(saleType);
+    }
+
+    void setSaleBeneficiary(Account saleBeneficiary) {
+        if(currentSaleBuilder!=null)
+            currentSaleBuilder.orderedFor(saleBeneficiary);
+    }
+
+    void addListener(ISaleScreenModelListener listener){
+        listeners.add(ISaleScreenModelListener.class, listener);
+    }
+
+    void removeListener(ISaleScreenModelListener listener){
+        listeners.remove(ISaleScreenModelListener.class, listener);
+    }
+
+    boolean isCurrentAccountConnected() {
+        return accountService.isCurrentAccountLoggedIn();
+    }
+
+    AccountLevel getCurrentAccountLevel() {
+        if(accountService.getCurrentAccount()!=null)
+            return accountService.getCurrentAccount().getPermissionLevel();
+        else
+            return AccountLevel.getLowest();
+    }
+}
\ 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..f3595839
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/SaleScreenView.java
@@ -0,0 +1,224 @@
+package com.pqt.client.gui.modules.sale_screen;
+
+import com.pqt.client.gui.modules.sale_screen.sale_validation_screen.SaleValidationScreen;
+import com.pqt.client.gui.ressources.components.CommandComposerSaleDisplayer;
+import com.pqt.client.gui.ressources.components.SimpleValidator;
+import com.pqt.client.gui.ressources.components.generics.javafx_override.CssEnabledGridPane;
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.client.gui.ressources.components.CategoryTabStockDisplayer;
+import com.pqt.core.entities.product.Product;
+import com.pqt.core.entities.sale.Sale;
+import com.pqt.core.entities.sale.SaleStatus;
+import com.pqt.core.entities.sale.SaleType;
+import com.pqt.core.entities.user_account.Account;
+import javafx.application.Platform;
+
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.*;
+import javafx.scene.layout.*;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+class SaleScreenView implements IFXComponent {
+
+    private SaleScreenController ctrl;
+
+    private SaleValidationScreen saleValidationScreen;
+    private StackPane mainPane;
+    private BorderPane mainPaneContent;
+
+    private CategoryTabStockDisplayer stockDisplayer;
+    private CommandComposerSaleDisplayer saleDisplayer;
+    private TextField saleMakerAccountDisplayer;
+    private ChoiceBox saleBeneficiaryAccountDisplayer;
+    private ChoiceBox saleTypeDisplayer;
+    private TextField salePriceDisplayer;
+    private SimpleValidator validator;
+
+    SaleScreenView(SaleScreenController ctrl) {
+        this.ctrl = ctrl;
+        initGui();
+    }
+
+    private void initGui() {
+        mainPane = new StackPane();
+        mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
+
+        mainPaneContent = new BorderPane();
+
+        /*
+        -----------------------CENTER PANE-----------------------
+         */
+        {
+            mainPaneContent.prefWidthProperty().bind(mainPane.widthProperty());
+            mainPaneContent.prefHeightProperty().bind(mainPane.heightProperty());
+
+            stockDisplayer = new CategoryTabStockDisplayer();
+            stockDisplayer.addListener(ctrl.getStockDisplayerListener());
+
+            saleDisplayer = new CommandComposerSaleDisplayer();
+            saleDisplayer.addListener(ctrl.getSaleDisplayerListener());
+
+            HBox mainContentCenterPane = new HBox();
+            mainContentCenterPane.getChildren().addAll(stockDisplayer.getPane(), saleDisplayer.getPane());
+            mainContentCenterPane.setFillHeight(true);
+            stockDisplayer.getPane().prefWidthProperty().bind(mainContentCenterPane.widthProperty().divide(2));
+            saleDisplayer.getPane().prefWidthProperty().bind(mainContentCenterPane.widthProperty().divide(2));
+
+            mainPaneContent.setCenter(mainContentCenterPane);
+        }
+        /*
+        -----------------------BOTTOM PANE-----------------------
+         */
+        {
+            HBox mainContentBottomPane = new HBox();
+            mainContentBottomPane.setFillHeight(true);
+            mainContentBottomPane.setAlignment(Pos.CENTER);
+            // Sale secondary data configuration (author, beneficiary, payment type, etc...
+            {
+                saleMakerAccountDisplayer = new TextField();
+                saleMakerAccountDisplayer.setEditable(false);
+                saleMakerAccountDisplayer.setPromptText(GUIStringTool.getSaleMakerTextFieldPromptText());
+
+                saleBeneficiaryAccountDisplayer = new ChoiceBox<>();
+                saleBeneficiaryAccountDisplayer.setConverter(GUIStringTool.getAccountStringConverter());
+                saleBeneficiaryAccountDisplayer.getSelectionModel()
+                        .selectedItemProperty()
+                        .addListener((observable, oldElem, newElem) -> ctrl.onAccountSelectedAsBeneficiary(newElem));
+
+                saleTypeDisplayer = new ChoiceBox<>();
+                saleTypeDisplayer.setConverter(GUIStringTool.getSaleTypeStringConverter());
+                saleTypeDisplayer.getSelectionModel()
+                        .selectedItemProperty()
+                        .addListener((observable, oldElem, newElem) -> ctrl.onSaleTypeSelected(newElem));
+
+                salePriceDisplayer = new TextField();
+                salePriceDisplayer.setEditable(false);
+                salePriceDisplayer.setPromptText(GUIStringTool.getSalePriceTextFieldPromptText());
+
+
+                GridPane mainContentBottomCenterPane = new CssEnabledGridPane();
+                mainContentBottomCenterPane.add(new Label(GUIStringTool.getSaleMakerTextFieldLabel()), 0, 0);
+                mainContentBottomCenterPane.add(saleMakerAccountDisplayer, 1, 0);
+                mainContentBottomCenterPane.add(new Label(GUIStringTool.getSaleBeneficiaryTextFieldLabel()), 0, 1);
+                mainContentBottomCenterPane.add(saleBeneficiaryAccountDisplayer, 1, 1);
+                mainContentBottomCenterPane.add(new Label(GUIStringTool.getSaleTypeTextFieldLabel()), 0, 2);
+                mainContentBottomCenterPane.add(saleTypeDisplayer, 1, 2);
+                mainContentBottomCenterPane.add(new Label(GUIStringTool.getSalePriceTextFieldLabel()), 0, 3);
+                mainContentBottomCenterPane.add(salePriceDisplayer, 1, 3);
+
+                mainContentBottomPane.getChildren().add(mainContentBottomCenterPane);
+            }
+            //Sale Validator
+            {
+                AnchorPane anchorPane = new AnchorPane();
+                validator = new SimpleValidator(true);
+                validator.addListener(ctrl.getValidatorListener());
+                anchorPane.getChildren().add(validator.getPane());
+                AnchorPane.setRightAnchor(validator.getPane(), 0d);
+                AnchorPane.setBottomAnchor(validator.getPane(), 0d);
+
+                mainContentBottomPane.getChildren().add(anchorPane);
+                HBox.setHgrow(anchorPane, Priority.ALWAYS);
+            }
+            mainPaneContent.setBottom(mainContentBottomPane);
+        }
+        /*
+        ------------------------MAIN PANE------------------------
+         */
+        mainPane.getChildren().add(mainPaneContent);
+    }
+
+    @Override
+    public Pane getPane() {
+        return mainPane;
+    }
+
+    void switchToSaleValidationWaitingMode(long saleId, Sale sale){
+        boolean clearChildren = mainPane.getChildren().size()>1;
+
+        Pane greyIntermediaryPane = new Pane();
+        greyIntermediaryPane.getStyleClass().clear();
+        greyIntermediaryPane.getStyleClass().add(GUICssTool.getIntermediaryPaneStyleClass());
+
+        saleValidationScreen = new SaleValidationScreen(saleId, sale);
+        saleValidationScreen.addListener(ctrl.getSaleValidationScreenListener());
+        Platform.runLater(()->{
+            if(clearChildren){
+                mainPane.getChildren().clear();
+                mainPane.getChildren().add(mainPaneContent);
+            }
+
+            StackPane.setAlignment(saleValidationScreen.getPane(), Pos.CENTER);
+            mainPane.getChildren().addAll(greyIntermediaryPane, saleValidationScreen.getPane());
+        });
+    }
+
+    void switchToSaleCompositionMode(){
+        Node[] childrenToRemove = mainPane.getChildren()
+                                                .stream()
+                                                .filter(child->!child.equals(mainPaneContent))
+                                                .collect(Collectors.toList())
+                                                .toArray(new Node[]{});
+        Platform.runLater(()->mainPane.getChildren().removeAll(childrenToRemove));
+    }
+
+    void setProducts(List products) {
+        stockDisplayer.display(products);
+    }
+
+    void setSaleTypes(List saleTypes) {
+        Platform.runLater(()->{
+            saleTypeDisplayer.getItems().clear();
+            if(saleTypes!=null)
+                saleTypeDisplayer.getItems().addAll(saleTypes);
+        });
+    }
+
+    void setAccounts(List accounts) {
+        Platform.runLater(()->{
+            saleBeneficiaryAccountDisplayer.getItems().clear();
+            saleBeneficiaryAccountDisplayer.getItems().add(ctrl.getDefaultAccount());
+            if(accounts!=null)
+                saleBeneficiaryAccountDisplayer.getItems().addAll(accounts);
+        });
+    }
+
+    void setSale(Sale sale) {
+        if(sale!=null) {
+            saleDisplayer.display(sale);
+
+            String price = GUIStringTool.getPriceRenderer().render(sale.getTotalPrice());
+            String currentAccount = GUIStringTool.getAccountStringConverter().toString(sale.getOrderedBy());
+
+            Platform.runLater(() -> {
+                salePriceDisplayer.setText(price);
+                saleMakerAccountDisplayer.setText(currentAccount);
+
+                selectElement(saleTypeDisplayer, sale.getType());
+                selectElement(saleBeneficiaryAccountDisplayer, sale.getOrderedFor());
+            });
+        }
+    }
+
+    private  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);
+    }
+
+    void setValidationButtonEnabled(boolean validationButtonEnabled) {
+        validator.setValidationButtonEnable(validationButtonEnabled);
+    }
+}
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..02996c3e
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/listeners/ISaleScreenModelListener.java
@@ -0,0 +1,13 @@
+package com.pqt.client.gui.modules.sale_screen.listeners;
+
+import com.pqt.core.entities.sale.SaleStatus;
+
+import java.util.EventListener;
+
+public interface ISaleScreenModelListener extends EventListener {
+    void onSaleValidatedEvent();
+    void onSaleNotValidatedEvent(SaleStatus status, Throwable cause);
+    void onStockUpdatedEvent();
+    void onAccountConnectedStateUpdatedEvent();
+    void onAccountListUpdatedEvent();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/sale_validation_screen/SaleValidationScreen.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/sale_validation_screen/SaleValidationScreen.java
new file mode 100644
index 00000000..93a4b7c8
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/sale_validation_screen/SaleValidationScreen.java
@@ -0,0 +1,97 @@
+package com.pqt.client.gui.modules.sale_screen.sale_validation_screen;
+
+import com.pqt.client.gui.modules.sale_screen.sale_validation_screen.listeners.ISaleValidationScreenListener;
+import com.pqt.client.gui.ressources.components.generics.javafx_override.CssEnabledGridPane;
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.core.entities.sale.Sale;
+import com.pqt.core.entities.sale.SaleStatus;
+import javafx.application.Platform;
+import javafx.geometry.Pos;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ProgressIndicator;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Pane;
+
+import javax.swing.event.EventListenerList;
+import java.util.Arrays;
+
+public class SaleValidationScreen {
+
+    private Pane mainPane;
+
+    private TextField saleStatusTextField;
+    private SaleStatus saleStatus;
+    private ProgressIndicator progressIndicator;
+    private Button validationButton;
+
+    private EventListenerList listeners;
+
+    public SaleValidationScreen(long saleId, Sale sale) {
+        listeners = new EventListenerList();
+        mainPane = new Pane();
+        mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
+
+        saleStatus = sale.getStatus();
+
+        BorderPane mainPaneContent = new BorderPane();
+
+        GridPane centerPane = new CssEnabledGridPane();
+        centerPane.setAlignment(Pos.CENTER);
+
+        Label saleIdLabel = new Label(GUIStringTool.getSaleIdLabel());
+        centerPane.add(saleIdLabel, 0, 0);
+
+        TextField saleIdTextField = new TextField(Long.toString(saleId));
+        saleIdTextField.setEditable(false);
+        centerPane.add(saleIdTextField, 1, 0);
+
+        Label saleStatusLabel = new Label(GUIStringTool.getSaleStatusLabel());
+        centerPane.add(saleStatusLabel, 0, 1);
+
+        saleStatusTextField = new TextField(GUIStringTool.getSaleStatusRenderer().render(saleStatus));
+        saleStatusTextField.setEditable(false);
+        centerPane.add(saleStatusTextField, 1, 1);
+
+        validationButton = new Button(GUIStringTool.getOkButtonLabel());
+        validationButton.setDisable(saleStatus.equals(SaleStatus.PENDING));
+        validationButton.setOnMouseClicked(event->fireScreenClose(saleStatus.equals(SaleStatus.ACCEPTED)));
+        centerPane.add(validationButton, 1,2);
+
+        mainPaneContent.setCenter(centerPane);
+
+        progressIndicator = new ProgressIndicator();
+        mainPaneContent.setLeft(progressIndicator);
+
+        mainPaneContent.prefHeightProperty().bind(mainPane.heightProperty());
+        mainPaneContent.prefWidthProperty().bind(mainPane.widthProperty());
+        mainPane.getChildren().add(mainPaneContent);
+    }
+
+    private void fireScreenClose(boolean saleValidatedSuccessFully) {
+        if(!validationButton.isDisable()){
+            Arrays.stream(listeners.getListeners(ISaleValidationScreenListener.class))
+                    .forEach(listener->listener.onScreenClose(saleValidatedSuccessFully));
+        }
+    }
+
+    public void addListener(ISaleValidationScreenListener listener){
+        listeners.add(ISaleValidationScreenListener.class, listener);
+    }
+
+    public void setSaleStatus(SaleStatus status){
+        saleStatus = status;
+        Platform.runLater(()->{
+            validationButton.setDisable(saleStatus.equals(SaleStatus.PENDING));
+            saleStatusTextField.setText(GUIStringTool.getSaleStatusRenderer().render(status));
+            progressIndicator.setProgress((status.equals(SaleStatus.PENDING)?ProgressIndicator.INDETERMINATE_PROGRESS:1F));
+        });
+    }
+
+    public Pane getPane(){
+        return mainPane;
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/sale_validation_screen/listeners/ISaleValidationScreenListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/sale_validation_screen/listeners/ISaleValidationScreenListener.java
new file mode 100644
index 00000000..e2011357
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/sale_screen/sale_validation_screen/listeners/ISaleValidationScreenListener.java
@@ -0,0 +1,7 @@
+package com.pqt.client.gui.modules.sale_screen.sale_validation_screen.listeners;
+
+import java.util.EventListener;
+
+public interface ISaleValidationScreenListener extends EventListener {
+    void onScreenClose(boolean saleValidatedSuccessfully);
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreen.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreen.java
new file mode 100644
index 00000000..6ef1f98b
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreen.java
@@ -0,0 +1,35 @@
+package com.pqt.client.gui.modules.stat_screen;
+
+import com.pqt.client.gui.modules.IGuiModule;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.client.module.stat.StatService;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.scene.layout.Pane;
+
+public class StatScreen implements IGuiModule {
+
+    private StatScreenView view;
+
+    public StatScreen(StatService statService) {
+        StatScreenModel model = new StatScreenModel(statService);
+        StatScreenController ctrl = new StatScreenController(model);
+        view = new StatScreenView();
+
+        ctrl.setView(view);
+    }
+
+    @Override
+    public String getModuleName() {
+        return GUIStringTool.getStatGuiModuleName();
+    }
+
+    @Override
+    public AccountLevel getLowestRequiredAccountLevel() {
+        return AccountLevel.STAFF;
+    }
+
+    @Override
+    public Pane getPane() {
+        return view.getPane();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreenController.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreenController.java
new file mode 100644
index 00000000..5f2510e3
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreenController.java
@@ -0,0 +1,22 @@
+package com.pqt.client.gui.modules.stat_screen;
+
+import com.pqt.client.gui.modules.stat_screen.listeners.IStatScreenModelListener;
+
+class StatScreenController implements IStatScreenModelListener{
+
+    private StatScreenModel model;
+    private StatScreenView view;
+
+    StatScreenController(StatScreenModel model) {
+        this.model = model;
+    }
+
+    void setView(StatScreenView view) {
+        this.view = view;
+    }
+
+    @Override
+    public void onStatisticsChangedEvent() {
+        view.display(model.getStatistics());
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreenModel.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreenModel.java
new file mode 100644
index 00000000..2add8f38
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreenModel.java
@@ -0,0 +1,38 @@
+package com.pqt.client.gui.modules.stat_screen;
+
+import com.pqt.client.gui.modules.stat_screen.listeners.IStatScreenModelListener;
+import com.pqt.client.module.stat.StatService;
+import com.pqt.client.module.stat.listeners.IStatListener;
+import com.pqt.client.module.stat.listeners.StatListenerAdapter;
+
+import javax.swing.event.EventListenerList;
+import java.util.Arrays;
+import java.util.Map;
+
+class StatScreenModel {
+    private EventListenerList listenerList;
+    private StatService statService;
+
+    StatScreenModel(StatService statService) {
+        this.statService = statService;
+        listenerList = new EventListenerList();
+        this.statService.addListener(new StatListenerAdapter() {
+            @Override
+            public void onGetStatSuccess() {
+                Arrays.stream(listenerList.getListeners(IStatScreenModelListener.class)).forEach(IStatScreenModelListener::onStatisticsChangedEvent);
+            }
+        });
+    }
+
+    Map getStatistics() {
+        return statService.getStats();
+    }
+
+    void addListener(IStatScreenModelListener l){
+        listenerList.add(IStatScreenModelListener.class, l);
+    }
+
+    void removeListener(IStatScreenModelListener l){
+        listenerList.remove(IStatScreenModelListener.class, l);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreenView.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreenView.java
new file mode 100644
index 00000000..a9a79644
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/StatScreenView.java
@@ -0,0 +1,52 @@
+package com.pqt.client.gui.modules.stat_screen;
+
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import javafx.application.Platform;
+import javafx.scene.control.TextArea;
+import javafx.scene.layout.Pane;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+class StatScreenView implements IFXComponent {
+
+    private TextArea statTextArea;
+    private Pane mainPane;
+
+    StatScreenView() {
+        initGui();
+    }
+
+    private void initGui() {
+        mainPane = new Pane();
+        mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
+
+        statTextArea = new TextArea();
+        mainPane.getChildren().add(statTextArea);
+        statTextArea.setId("stat-screen-text-area");
+        statTextArea.setWrapText(true);
+        statTextArea.setEditable(false);
+        statTextArea.prefWidthProperty().bind(mainPane.widthProperty());
+        statTextArea.prefHeightProperty().bind(mainPane.heightProperty());
+    }
+
+    void display(Map statistics){
+        List lines = new ArrayList<>();
+
+        if(statistics!=null)
+            lines.addAll(statistics.keySet()
+                .stream()
+                .map(key->String.format(" * %s : %s", key, statistics.get(key)))
+                .collect(Collectors.toList()));
+
+        Platform.runLater(()->lines.forEach(line -> statTextArea.appendText(line+"\n")));
+    }
+
+    @Override
+    public Pane getPane() {
+        return mainPane;
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/listeners/IStatScreenModelListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/listeners/IStatScreenModelListener.java
new file mode 100644
index 00000000..c02c49f8
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stat_screen/listeners/IStatScreenModelListener.java
@@ -0,0 +1,7 @@
+package com.pqt.client.gui.modules.stat_screen.listeners;
+
+import java.util.EventListener;
+
+public interface IStatScreenModelListener extends EventListener {
+    void onStatisticsChangedEvent();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreen.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreen.java
new file mode 100644
index 00000000..4deb2d97
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreen.java
@@ -0,0 +1,39 @@
+package com.pqt.client.gui.modules.stock_screen;
+
+import com.pqt.client.gui.modules.IGuiModule;
+import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreen;
+import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreenFactory;
+import com.pqt.client.module.account.AccountService;
+import com.pqt.client.module.stock.StockService;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.scene.layout.Pane;
+
+public class StockScreen implements IGuiModule {
+
+    private StockScreenView view;
+
+    public StockScreen(StockService stockService, AccountService accountService) {
+        StockScreenModel model = new StockScreenModel(stockService, accountService);
+        StockScreenController ctrl = new StockScreenController(model);
+        view = new StockScreenView(ctrl, new ProductManagerScreenFactory(stockService));
+
+        model.addListener(ctrl);
+        ctrl.setView(view);
+        ctrl.refreshView();
+    }
+
+    @Override
+    public String getModuleName() {
+        return "Stock";
+    }
+
+    @Override
+    public AccountLevel getLowestRequiredAccountLevel() {
+        return AccountLevel.WAITER;
+    }
+
+    @Override
+    public Pane getPane() {
+        return view.getPane();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreenController.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreenController.java
new file mode 100644
index 00000000..7418e94f
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreenController.java
@@ -0,0 +1,112 @@
+package com.pqt.client.gui.modules.stock_screen;
+
+
+import com.pqt.client.gui.modules.stock_screen.listeners.IStockItemEventListener;
+import com.pqt.client.gui.modules.stock_screen.listeners.IStockScreenModelListener;
+import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreen;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.core.entities.product.Product;
+import com.pqt.core.entities.user_account.AccountLevel;
+
+class StockScreenController implements IStockScreenModelListener{
+
+    private StockScreenModel model;
+    private StockScreenView view;
+
+    StockScreenController(StockScreenModel model) {
+        this.model = model;
+    }
+
+    void setView(StockScreenView view) {
+        this.view = view;
+    }
+
+    void onAddProductRequest() {
+        detailProduct(null);
+    }
+
+    void onDetailProductRequest() {
+        if(view.getSelectedProduct()!=null)
+            detailProduct(view.getSelectedProduct());
+    }
+
+    private void detailProduct(Product product){
+        view.switchToDetailMode(product);
+    }
+
+    IValidatorComponentListener getDetailScreenValidationListener(){
+        return new IValidatorComponentListener() {
+            @Override
+            public void onValidationEvent() {
+                if(view.isDetailScreenCreationPossible()) {
+                    if (view.hasDetailScreenInitialValue()){
+                        modifyProduct(view.getDetailScreenInitialValue(), view.getDetailScreenCreation());
+                    }else{
+                        addProduct(view.getDetailScreenCreation());
+                    }
+                    view.switchToGeneralMode();
+                }
+            }
+
+            @Override
+            public void onCancelEvent() {
+                view.switchToGeneralMode();
+            }
+        };
+    }
+
+    void onDeleteProductRequest() {
+        deleteProduct(view.getSelectedProduct());
+    }
+
+    private void addProduct(Product product){
+        model.commitProductAddition(product);
+    }
+
+    private void modifyProduct(Product oldProduct, Product newProduct){
+        model.commitProductModification(oldProduct, newProduct);
+    }
+
+    private void deleteProduct(Product product){
+        model.commitProductDeletion(product);;
+    }
+
+    void onRefreshProductsRequest() {
+        refreshView();
+    }
+
+    IStockItemEventListener getProductActivationListener() {
+        return this::detailProduct;
+    }
+
+    void refreshView(){
+        view.display(model.getProductCollection());
+    }
+
+    @Override
+    public void onStockUpdatedEvent() {
+        refreshView();
+    }
+
+    @Override
+    public void onAcccountConnectedStatusUpdatedEvent() {
+        updateViewActionLock();
+    }
+
+    void updateViewActionLock(){
+        if(model.isAccountConnected() && model.getConnectedAccountLevel().compareTo(AccountLevel.MASTER)>=0){
+            view.setAddProductActionLocked(false);
+            view.setEditProductActionLocked(view.getSelectedProduct()==null);
+            view.setRemoveProductActionLocked(view.getSelectedProduct()==null);
+        }else{
+            view.setAddProductActionLocked(true);
+            view.setEditProductActionLocked(true);
+            view.setRemoveProductActionLocked(true);
+        }
+    }
+
+    void onProductSelectedChange(){
+        updateViewActionLock();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreenModel.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreenModel.java
new file mode 100644
index 00000000..365c0648
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreenModel.java
@@ -0,0 +1,88 @@
+package com.pqt.client.gui.modules.stock_screen;
+
+import com.pqt.client.gui.modules.stock_screen.listeners.IStockScreenModelListener;
+import com.pqt.client.module.account.AccountService;
+import com.pqt.client.module.account.listeners.IAccountListener;
+import com.pqt.client.module.stock.Listeners.StockListenerAdapter;
+import com.pqt.client.module.stock.StockService;
+import com.pqt.core.entities.product.Product;
+import com.pqt.core.entities.user_account.AccountLevel;
+
+import javax.swing.event.EventListenerList;
+import java.util.Arrays;
+import java.util.Collection;
+
+class StockScreenModel {
+
+    private StockService stockService;
+    private AccountService accountService;
+    private EventListenerList listenerList;
+
+    StockScreenModel(StockService stockService, AccountService accountService) {
+        listenerList = new EventListenerList();
+        this.stockService = stockService;
+        this.stockService.addListener(new StockListenerAdapter(){
+            @Override
+            public void onProductListChangedEvent() {
+                StockScreenModel.this.fireProductCollectionChanged();
+            }
+        });
+        this.accountService = accountService;
+        this.accountService.addListener(new IAccountListener() {
+            @Override
+            public void onAccountStatusChangedEvent(boolean status) {
+                StockScreenModel.this.fireConnectedStatusChanged();
+            }
+
+            @Override
+            public void onAccountListChangedEvent() {
+
+            }
+        });
+    }
+
+    private void fireConnectedStatusChanged() {
+        Arrays.stream(listenerList.getListeners(IStockScreenModelListener.class))
+                .forEach(IStockScreenModelListener::onAcccountConnectedStatusUpdatedEvent);
+    }
+
+    private void fireProductCollectionChanged() {
+        Arrays.stream(listenerList.getListeners(IStockScreenModelListener.class))
+                .forEach(IStockScreenModelListener::onStockUpdatedEvent);
+    }
+
+    Collection getProductCollection() {
+        return stockService.getProducts();
+    }
+
+    void commitProductDeletion(Product product) {
+        stockService.commitUpdate(stockService.getNewUpdateBuilder().removeProduct(product));
+    }
+
+    void commitProductModification(Product oldProduct, Product newProduct) {
+        stockService.commitUpdate(stockService.getNewUpdateBuilder().modifyProduct(oldProduct, newProduct));
+    }
+
+    void commitProductAddition(Product product) {
+        stockService.commitUpdate(stockService.getNewUpdateBuilder().addProduct(product));
+    }
+
+    void addListener(IStockScreenModelListener l){
+        listenerList.add(IStockScreenModelListener.class, l);
+    }
+
+    void removeListener(IStockScreenModelListener l){
+        listenerList.remove(IStockScreenModelListener.class, l);
+    }
+
+    boolean isAccountConnected() {
+        return accountService.isCurrentAccountLoggedIn();
+    }
+
+    AccountLevel getConnectedAccountLevel() {
+        if(accountService.getCurrentAccount()!=null)
+            return accountService.getCurrentAccount().getPermissionLevel();
+        else
+            return AccountLevel.getLowest();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreenView.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreenView.java
new file mode 100644
index 00000000..83034d8d
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/StockScreenView.java
@@ -0,0 +1,242 @@
+package com.pqt.client.gui.modules.stock_screen;
+
+import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreen;
+import com.pqt.client.gui.modules.stock_screen.product_manager_screen.ProductManagerScreenFactory;
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.client.gui.ressources.strings.IObjectStringRenderer;
+import com.pqt.core.entities.product.Product;
+import javafx.application.Platform;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.css.PseudoClass;
+import javafx.scene.Node;
+import javafx.scene.control.*;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.MouseButton;
+import javafx.scene.layout.*;
+import javafx.util.Callback;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+class StockScreenView implements IFXComponent {
+
+    private StockScreenController ctrl;
+    private StackPane mainPane;
+    private BorderPane mainPaneContent;
+    private TableView stockTableView;
+    private ProductManagerScreenFactory productManagerScreenFactory;
+    private ProductManagerScreen currentDetailScreen;
+    private Button addProductButton;
+    private Button detailProductButton;
+    private Button removeProductButton;
+
+    StockScreenView(StockScreenController ctrl, ProductManagerScreenFactory productManagerScreenFactory) {
+        this.ctrl = ctrl;
+        this.productManagerScreenFactory = productManagerScreenFactory;
+        initGui();
+    }
+
+    private void initGui() {
+        mainPane = new StackPane();
+        mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
+        mainPaneContent = new BorderPane();
+        mainPane.getChildren().add(mainPaneContent);
+        mainPaneContent.prefWidthProperty().bind(mainPane.widthProperty());
+        mainPaneContent.prefHeightProperty().bind(mainPane.heightProperty());
+
+        addProductButton = new Button(GUIStringTool.getAddButtonLabel());
+        addProductButton.setOnMouseClicked(event -> ctrl.onAddProductRequest());
+        detailProductButton = new Button(GUIStringTool.getDetailButtonLabel());
+        detailProductButton.setOnMouseClicked(event -> ctrl.onDetailProductRequest());
+        detailProductButton.setDisable(true);
+        removeProductButton = new Button(GUIStringTool.getRemoveButtonLabel());
+        removeProductButton.setDisable(true);
+        removeProductButton.setOnMouseClicked(event -> ctrl.onDeleteProductRequest());
+        Button refreshProductButton = new Button(GUIStringTool.getRefreshButtonLabel());
+        refreshProductButton.setOnMouseClicked(event -> ctrl.onRefreshProductsRequest());
+
+        ToolBar actionToolbar = new ToolBar();
+        actionToolbar.getItems().addAll(addProductButton, detailProductButton, removeProductButton, refreshProductButton);
+
+        HBox mainPaneTopContent = new HBox();
+        HBox separator = new HBox();
+        mainPaneTopContent.getChildren().addAll(separator, actionToolbar);
+        HBox.setHgrow(separator, Priority.ALWAYS);
+        mainPaneContent.setTop(mainPaneTopContent);
+
+        PseudoClass outOfStockPseudoClass = PseudoClass.getPseudoClass("stock-out");
+        PseudoClass lowStockPseudoClass = PseudoClass.getPseudoClass("stock-low");
+        PseudoClass highStockPseudoClass = PseudoClass.getPseudoClass("stock-high");
+        stockTableView = new TableView<>();
+        stockTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
+        stockTableView.setRowFactory(tableView->{
+            TableRow row = new TableRow<>();
+            row.itemProperty().addListener((obs, oldVal, newVal)->{
+                if(newVal!=null){
+                    row.pseudoClassStateChanged(outOfStockPseudoClass, newVal.getAmountRemaining()<=0);
+                    row.pseudoClassStateChanged(lowStockPseudoClass, newVal.getAmountRemaining()>0 && newVal.getAmountRemaining()<30);
+                    row.pseudoClassStateChanged(highStockPseudoClass, newVal.getAmountRemaining()>=30);
+                }else{
+                    row.pseudoClassStateChanged(outOfStockPseudoClass, false);
+                    row.pseudoClassStateChanged(lowStockPseudoClass, false);
+                    row.pseudoClassStateChanged(highStockPseudoClass, false);
+                }
+            });
+            row.setOnMouseClicked(event -> {
+                if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2)
+                    ctrl.getProductActivationListener().onProductActivated(row.getItem());
+            });
+            row.setOnKeyTyped(event -> {
+                if (event.getCode().equals(KeyCode.ENTER))
+                    ctrl.getProductActivationListener().onProductActivated(row.getItem());
+            });
+            return row;
+        });
+        stockTableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
+        stockTableView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal)->ctrl.onProductSelectedChange());
+        List> columns = new ArrayList<>();
+
+        columns.add(createNewTableColumn(String.class,
+                GUIStringTool.getProductNameColumnHeader(),
+                param -> new SimpleStringProperty(param.getValue().getName()),
+                null
+        ));
+        columns.add(createNewTableColumn(String.class,
+                GUIStringTool.getProductCategoryColumnHeader(),
+                param -> new SimpleStringProperty(param.getValue().getCategory().getName()),
+                null
+        ));
+        columns.add(createNewTableColumn(Integer.class,
+                GUIStringTool.getProductAmountRemainingColumnHeader(),
+                param -> new SimpleIntegerProperty(param.getValue().getAmountRemaining()).asObject(),
+                null
+        ));
+        columns.add(createNewTableColumn(Integer.class,
+                GUIStringTool.getProductAmountSoldColumnHeader(),
+                param -> new SimpleIntegerProperty(param.getValue().getAmountSold()).asObject(),
+                null
+        ));
+        columns.add(createNewTableColumn(Double.class,
+                GUIStringTool.getProductPriceColumnHeader(),
+                param -> new SimpleDoubleProperty(param.getValue().getPrice()).asObject(),
+                GUIStringTool.getPriceRenderer()
+        ));
+        columns.add(createNewTableColumn(Boolean.class,
+                GUIStringTool.getProductIsSellableColumnHeader(),
+                param -> new SimpleBooleanProperty(param.getValue().isSellable()),
+                GUIStringTool.getBooleanRenderer()
+        ));
+
+        stockTableView.getColumns().addAll(columns);
+        mainPaneContent.setCenter(stockTableView);
+    }
+
+    private  TableColumn createNewTableColumn(Class clazz,
+                                                             String header,
+                                                             Callback, ObservableValue> cellValueFactory,
+                                                             IObjectStringRenderer renderer){
+        TableColumn column = new TableColumn<>();
+        if(header!=null)
+            column.setText(header);
+        if(cellValueFactory!=null)
+            column.setCellValueFactory(cellValueFactory);
+        if(renderer!=null)
+            column.setCellFactory(table -> new TableCell() {
+                    @Override
+                    protected void updateItem(T item, boolean empty) {
+                        super.updateItem(item, empty);
+                        if (item == null || empty) {
+                            setText(null);
+                            setStyle("");
+                        } else {
+                            setText(renderer.render(item));
+                        }
+                    }
+                }
+            );
+
+        return column;
+    }
+
+    void display(Collection productCollection){
+        Platform.runLater(()->{
+            this.stockTableView.getItems().clear();
+            this.stockTableView.getItems().addAll(productCollection);
+        });
+    }
+
+    @Override
+    public Pane getPane() {
+        return mainPane;
+    }
+
+    Product getSelectedProduct() {
+        return stockTableView.getSelectionModel().getSelectedItem();
+    }
+
+    void switchToDetailMode(Product product) {
+        if(currentDetailScreen==null){
+            currentDetailScreen = productManagerScreenFactory.create(product);
+            currentDetailScreen.addListener(ctrl.getDetailScreenValidationListener());
+            Pane separator = new Pane();
+            separator.getStyleClass().add(GUICssTool.getIntermediaryPaneStyleClass());
+            Platform.runLater(()->mainPane.getChildren().addAll(separator, currentDetailScreen.getPane()));
+        }
+    }
+
+    void switchToGeneralMode() {
+        if(currentDetailScreen!=null){
+            List toRemove = mainPane.getChildren()
+                                                .stream()
+                                                .filter(node->!node.equals(mainPaneContent))
+                                                .collect(Collectors.toList());
+            Platform.runLater(()->{
+                mainPane.getChildren().removeAll(toRemove);
+                currentDetailScreen = null;
+            });
+        }
+    }
+
+    boolean isDetailScreenCreationPossible() {
+        System.out.println("test creation possible : ");
+        return currentDetailScreen!=null && currentDetailScreen.isCreationPossible();
+    }
+
+    boolean hasDetailScreenInitialValue() {
+        return currentDetailScreen!=null && currentDetailScreen.hasInitialValue();
+    }
+
+    Product getDetailScreenInitialValue() {
+        if(currentDetailScreen!=null)
+            return currentDetailScreen.getInitialValueSnapshot();
+        else
+            return null;
+    }
+
+    Product getDetailScreenCreation() {
+        if(currentDetailScreen!=null)
+            return currentDetailScreen.create();
+        else
+            return null;
+    }
+
+    void setAddProductActionLocked(boolean locked){
+        addProductButton.setDisable(locked);
+    }
+
+    void setRemoveProductActionLocked(boolean locked){
+        removeProductButton.setDisable(locked);
+    }
+
+    void setEditProductActionLocked(boolean locked){
+        detailProductButton.setDisable(locked);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/listeners/IStockItemEventListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/listeners/IStockItemEventListener.java
new file mode 100644
index 00000000..08e002eb
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/listeners/IStockItemEventListener.java
@@ -0,0 +1,7 @@
+package com.pqt.client.gui.modules.stock_screen.listeners;
+
+import com.pqt.core.entities.product.Product;
+
+public interface IStockItemEventListener {
+    void onProductActivated(Product product);
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/listeners/IStockScreenModelListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/listeners/IStockScreenModelListener.java
new file mode 100644
index 00000000..54604eec
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/listeners/IStockScreenModelListener.java
@@ -0,0 +1,8 @@
+package com.pqt.client.gui.modules.stock_screen.listeners;
+
+import java.util.EventListener;
+
+public interface IStockScreenModelListener extends EventListener {
+    void onStockUpdatedEvent();
+    void onAcccountConnectedStatusUpdatedEvent();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreen.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreen.java
new file mode 100644
index 00000000..d5aee803
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreen.java
@@ -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, 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());
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenController.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenController.java
new file mode 100644
index 00000000..b948bf82
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenController.java
@@ -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);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenFactory.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenFactory.java
new file mode 100644
index 00000000..c583115c
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenFactory.java
@@ -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);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenModel.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenModel.java
new file mode 100644
index 00000000..962390fb
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenModel.java
@@ -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 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 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;
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenView.java b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenView.java
new file mode 100644
index 00000000..d9118917
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/modules/stock_screen/product_manager_screen/ProductManagerScreenView.java
@@ -0,0 +1,212 @@
+package com.pqt.client.gui.modules.stock_screen.product_manager_screen;
+
+import com.pqt.client.gui.ressources.components.SimpleValidator;
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.components.generics.javafx_override.CssEnabledGridPane;
+import com.pqt.client.gui.ressources.components.generics.javafx_override.HighlightListCell;
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.core.entities.product.Category;
+import com.pqt.core.entities.product.Product;
+import javafx.application.Platform;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.*;
+import javafx.scene.layout.*;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Collection;
+
+class ProductManagerScreenView implements IFXComponent {
+
+    private ProductManagerScreenController ctrl;
+
+    private int gridLines;
+    private StackPane mainPane;
+    private BorderPane mainPaneContent;
+    private TextField productNameTextField,
+            productAmountRemainingTextField,
+            productAmountSoldTextField,
+            productPriceTextField;
+    private ComboBox productCategoryComboBox;
+    private CheckBox productSellableCheckBox;
+    private ListView productComponentsListView;
+
+    ProductManagerScreenView(ProductManagerScreenController ctrl) {
+        this.ctrl = ctrl;
+        initGui();
+    }
+
+    private void initGui() {
+        mainPane = new StackPane();
+        mainPane.getStyleClass().add(GUICssTool.getMainModulePaneCssClass());
+
+        mainPaneContent = new BorderPane();
+
+        GridPane mainPaneCenterContent = new CssEnabledGridPane();
+        mainPaneCenterContent.setAlignment(Pos.CENTER);
+        gridLines = 0;
+        NumberFormat priceFormat = NumberFormat.getNumberInstance();
+        NumberFormat intFormat = NumberFormat.getIntegerInstance();
+
+        Label productNameLabel = new Label(GUIStringTool.getProductNameLabel());
+        productNameTextField = new TextField();
+        productNameTextField.textProperty().addListener((obs, oldVal, newVal)->ctrl.onNameChanged(oldVal,newVal));
+        addLineToGrid(mainPaneCenterContent, productNameLabel, productNameTextField);
+
+        Label productCategoryLabel = new Label(GUIStringTool.getProductCategoryLabel());
+        productCategoryComboBox = new ComboBox<>();
+        productCategoryComboBox.setEditable(true);
+        productCategoryComboBox.setConverter(GUIStringTool.getCategoryStringConverter());
+        productCategoryComboBox.valueProperty().addListener((obs, oldVal, newVal)->ctrl.onCategoryChanged(oldVal, newVal));
+        addLineToGrid(mainPaneCenterContent, productCategoryLabel, productCategoryComboBox);
+
+        Label productAmountRemainingLabel = new Label(GUIStringTool.getProductAmountRemainingLabel());
+        productAmountRemainingTextField = getNumberOnlyTextField(intFormat);
+        productAmountRemainingTextField.textProperty().addListener((obs, oldVal, newVal)->{
+            try{
+                int oldInt = oldVal.isEmpty()?0:Integer.parseInt(oldVal);
+                int newInt = newVal.isEmpty()?0:Integer.parseInt(newVal);
+                ctrl.onAmountRemainingChanged(oldInt, newInt);
+            }catch(NumberFormatException e){
+                e.printStackTrace();
+            }
+        });
+        addLineToGrid(mainPaneCenterContent, productAmountRemainingLabel, productAmountRemainingTextField);
+
+        Label productAmountSoldLabel = new Label(GUIStringTool.getProductAmountSoldLabel());
+        productAmountSoldTextField = getNumberOnlyTextField(intFormat);
+        productAmountSoldTextField.textProperty().addListener((obs, oldVal, newVal)->{
+            try{
+                int oldInt = oldVal.isEmpty()?0:Integer.parseInt(oldVal);
+                int newInt = newVal.isEmpty()?0:Integer.parseInt(newVal);
+                ctrl.onAmountSoldChanged(oldInt, newInt);
+            }catch(NumberFormatException e){
+                e.printStackTrace();
+            }
+        });
+        addLineToGrid(mainPaneCenterContent, productAmountSoldLabel, productAmountSoldTextField);
+
+        Label productSellableLabel = new Label(GUIStringTool.getProductSellableLabel());
+        productSellableCheckBox = new CheckBox();
+        productSellableCheckBox.selectedProperty().addListener((obs, oldVal, newVal)->ctrl.onSellableStateChanged(oldVal,newVal));
+        addLineToGrid(mainPaneCenterContent, productSellableLabel, productSellableCheckBox);
+
+        Label productPriceLabel = new Label(GUIStringTool.getProductPriceLabel());
+        productPriceTextField = getNumberOnlyTextField(priceFormat);
+        productPriceTextField.textProperty().addListener((obs, oldVal, newVal)->{
+            try{
+                ctrl.onPriceChanged((oldVal.isEmpty()?-1:Double.parseDouble(oldVal)), (newVal.isEmpty()?-1:Double.parseDouble(newVal)));
+            }catch(NumberFormatException e){
+                e.printStackTrace();
+            }
+        });
+        addLineToGrid(mainPaneCenterContent, productPriceLabel, productPriceTextField);
+
+        mainPaneContent.setCenter(mainPaneCenterContent);
+
+        VBox mainPaneRightContent = new VBox();
+        mainPaneRightContent.setAlignment(Pos.CENTER);
+        Label title = new Label(GUIStringTool.getComponentListTitleLabel());
+        title.setAlignment(Pos.CENTER);
+        title.getStyleClass().add(GUICssTool.getTitleTextStyleClass());
+        productComponentsListView = new ListView<>();
+        productComponentsListView.setCellFactory(listView->new HighlightListCell(){
+            @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 categoryCollection){
+        Platform.runLater(()->{
+            productCategoryComboBox.getItems().clear();
+            productCategoryComboBox.getItems().addAll(categoryCollection);
+        });
+    }
+
+    void setProductCollection(Collection productCollection){
+        Platform.runLater(()->{
+            productComponentsListView.getItems().clear();
+            productComponentsListView.getItems().addAll(productCollection);
+        });
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/AccountManager.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/AccountManager.java
new file mode 100644
index 00000000..a88fb26c
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/AccountManager.java
@@ -0,0 +1,162 @@
+package com.pqt.client.gui.ressources.components;
+
+import com.pqt.client.gui.ressources.components.generics.creators.IFXCreatorComponent;
+import com.pqt.client.gui.ressources.components.generics.validators.IFXValidatorComponent;
+import com.pqt.client.gui.ressources.components.specifics.account.listeners.IAccountComponentListener;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.SimpleValidatorComponentFirerer;
+import com.pqt.client.gui.ressources.components.specifics.account.IFXAccountsDisplayerComponent;
+import com.pqt.client.gui.ressources.components.specifics.account.listeners.SimpleAccountComponentFirerer;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.scene.control.Button;
+import javafx.scene.control.ChoiceBox;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyCode;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+
+import java.util.Collection;
+
+public class AccountManager implements IFXAccountsDisplayerComponent, IFXValidatorComponent, IFXCreatorComponent {
+
+    private Pane mainPane;
+
+    private VBox mainDisconnectedPane, mainConnectedPane;
+    private TextField connectedUsernameField;
+    private ChoiceBox disconnectedUsernameField;
+    private PasswordField passwordField;
+
+    private SimpleAccountComponentFirerer accountEventFirerer;
+    private SimpleValidatorComponentFirerer validatorEventFirerer;
+
+    private Account currentAccount;
+
+    public AccountManager() {
+        accountEventFirerer = new SimpleAccountComponentFirerer();
+        validatorEventFirerer = new SimpleValidatorComponentFirerer();
+
+        currentAccount = null;
+
+        init();
+    }
+
+    private void init() {
+        mainPane = new Pane();
+
+        mainConnectedPane = new VBox();
+        mainDisconnectedPane = new VBox();
+
+        connectedUsernameField = new TextField();
+        connectedUsernameField.setEditable(false);
+
+        Button disconnectButton = new Button(GUIStringTool.getLogoutButtonLabel());
+        disconnectButton.setOnMouseClicked(event->validatorEventFirerer.fireCancelEvent());
+        disconnectButton.setOnKeyTyped(event->{if(event.getCode().equals(KeyCode.ENTER)) validatorEventFirerer.fireCancelEvent();});
+
+        mainConnectedPane.getChildren().addAll(connectedUsernameField, disconnectButton);
+
+
+        disconnectedUsernameField = new ChoiceBox<>();
+        disconnectedUsernameField.setConverter(GUIStringTool.getAccountStringConverter());
+
+        passwordField = new PasswordField();
+        passwordField.setPromptText(GUIStringTool.getPasswordFieldPromptText());
+
+        Button validationButton = new Button(GUIStringTool.getLoginButtonLabel());
+        validationButton.setOnMouseClicked(event-> validatorEventFirerer.fireValidationEvent());
+        validationButton.setOnKeyTyped(event->{if(event.getCode().equals(KeyCode.ENTER)) validatorEventFirerer.fireValidationEvent();});
+
+        mainDisconnectedPane.getChildren().addAll(disconnectedUsernameField, passwordField, validationButton);
+
+        refreshMainPane();
+        display(null);
+    }
+
+    @Override
+    public void display(Collection content) {
+        Platform.runLater(()->{
+            if(content!=null && content.size()>0)
+                disconnectedUsernameField.setItems(FXCollections.observableArrayList(content));
+            else{
+                disconnectedUsernameField.getItems().clear();
+                disconnectedUsernameField.getItems().add(new Account("null", "", AccountLevel.getLowest()));
+            }
+        });
+    }
+
+    public void setCurrentAccount(Account account){
+        currentAccount = account;
+        Platform.runLater(()->connectedUsernameField.setText(GUIStringTool.getAccountStringConverter().toString(currentAccount)));
+        refreshMainPane();
+    }
+
+    private void refreshMainPane() {
+        if(currentAccount!=null)
+            Platform.runLater(
+                    ()->{
+                        mainPane.getChildren().clear();
+                        mainPane.getChildren().add(mainConnectedPane);
+                    }
+            );
+        else
+            Platform.runLater(
+                    ()->{
+                        mainPane.getChildren().clear();
+                        mainPane.getChildren().add(mainDisconnectedPane);
+                    }
+            );
+    }
+
+    public Account getCurrentAccount() {
+        return currentAccount;
+    }
+
+    @Override
+    public void addListener(IAccountComponentListener l) {
+        accountEventFirerer.addListener(l);
+    }
+
+    @Override
+    public void removeListener(IAccountComponentListener l) {
+        accountEventFirerer.removeListener(l);
+    }
+
+    @Override
+    public Pane getPane() {
+        return mainPane;
+    }
+
+    @Override
+    public void addListener(IValidatorComponentListener l) {
+        validatorEventFirerer.addListener(l);
+    }
+
+    @Override
+    public void removeListener(IValidatorComponentListener l) {
+        validatorEventFirerer.removeListener(l);
+    }
+
+    @Override
+    public Account create() {
+        if(!isCreationPossible())
+            return null;
+
+        return new Account(disconnectedUsernameField.getValue().getUsername(), passwordField.getText(), disconnectedUsernameField.getValue().getPermissionLevel());
+    }
+
+    @Override
+    public boolean isCreationPossible() {
+        return currentAccount==null
+                && disconnectedUsernameField.getAccessibleText()!=null
+                && !disconnectedUsernameField.getAccessibleText().isEmpty()
+                && passwordField.getText()!=null
+                && !passwordField.getText().isEmpty();
+
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/CategoryTabStockDisplayer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/CategoryTabStockDisplayer.java
new file mode 100644
index 00000000..1e95f923
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/CategoryTabStockDisplayer.java
@@ -0,0 +1,129 @@
+package com.pqt.client.gui.ressources.components;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.IFXDisplayerComponent;
+import com.pqt.client.gui.ressources.components.specifics.products.listeners.IStockComponentListener;
+import com.pqt.client.gui.ressources.components.specifics.products.listeners.SimpleStockComponentFirerer;
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.client.gui.ressources.strings.IObjectStringRenderer;
+import com.pqt.core.entities.product.Product;
+import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.input.KeyCode;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class CategoryTabStockDisplayer implements IFXDisplayerComponent, IStockComponentListener> {
+
+    private SimpleStockComponentFirerer firerer;
+    private BorderPane mainPane;
+    private TabPane tabPane;
+
+    public CategoryTabStockDisplayer() {
+        init();
+        firerer = new SimpleStockComponentFirerer();
+    }
+
+    @Override
+    public void display(Collection content) {
+        final ObservableList tabs = FXCollections.observableArrayList();
+        if(content!=null){
+            List categories = content.stream().map(product->product.getCategory().getName()).distinct().collect(Collectors.toList());
+
+            for(String cat : categories){
+                tabs.add(createCategoryTab(cat, content.stream().filter(p->p.getCategory().getName().equals(cat)).collect(Collectors.toList())));
+            }
+
+        }
+
+        Platform.runLater(()->{
+            tabPane.getTabs().clear();
+            tabPane.getTabs().addAll(tabs);
+        });
+    }
+
+    @Override
+    public void addListener(IStockComponentListener l) {
+        firerer.addListener(l);
+    }
+
+    @Override
+    public void removeListener(IStockComponentListener l) {
+        firerer.removeListener(l);
+    }
+
+    @Override
+    public Pane getPane() {
+        return mainPane;
+    }
+
+    private void init(){
+        mainPane = new BorderPane();
+
+        Label title = new Label(GUIStringTool.getCategorytabStockDisplayerTitle());
+        title.setAlignment(Pos.CENTER);
+        title.getStyleClass().add(GUICssTool.getTitleTextStyleClass());
+
+        HBox topPane = new HBox();
+        topPane.setFillHeight(true);
+        topPane.setAlignment(Pos.CENTER);
+        topPane.getChildren().add(title);
+
+        mainPane.setTop(topPane);
+
+        tabPane = new TabPane();
+        mainPane.setCenter(tabPane);
+    }
+
+    private Tab createCategoryTab(String categoryName, Collection products){
+        Tab tab = new Tab(categoryName);
+        tab.closableProperty().setValue(false);
+
+        ListView listView = new ListView<>();
+        listView.setCellFactory(list->new ListCell(){
+
+            @Override
+            protected void updateItem(Product item, boolean empty) {
+                super.updateItem(item, empty);
+
+                if (empty || item == null) {
+                    setText(null);
+                    setGraphic(null);
+                } else {
+                    setText(CategoryTabStockDisplayer.getProductRenderer().render(item));
+                }
+            }
+        });
+
+        listView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
+        listView.setEditable(false);
+        listView.setOnMouseClicked(event->{
+            firerer.fireContentClickEvent(event, listView.getSelectionModel().getSelectedItem());
+            Platform.runLater(()->listView.getSelectionModel().clearSelection(listView.getSelectionModel().getSelectedIndex()));
+        });
+        listView.setOnKeyTyped(event -> {
+            if(event.getCode().equals(KeyCode.ENTER)){
+                firerer.fireContentClickEvent(event, listView.getSelectionModel().getSelectedItem());
+                Platform.runLater(()->listView.getSelectionModel().clearSelection(listView.getSelectionModel().getSelectedIndex()));
+                event.consume();
+            }
+        });
+
+        listView.setItems(FXCollections.observableArrayList(products));
+
+        tab.setContent(listView);
+        return tab;
+    }
+
+    private static IObjectStringRenderer getProductRenderer(){
+        return GUIStringTool.getDetailledProductStringRenderer();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/CommandComposerSaleDisplayer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/CommandComposerSaleDisplayer.java
new file mode 100644
index 00000000..21460ac3
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/CommandComposerSaleDisplayer.java
@@ -0,0 +1,96 @@
+package com.pqt.client.gui.ressources.components;
+
+import com.pqt.client.gui.ressources.components.specifics.sale.IFXSaleDisplayerComponent;
+import com.pqt.client.gui.ressources.components.specifics.sale.listeners.ISaleComponentListener;
+import com.pqt.client.gui.ressources.components.specifics.sale.listeners.SimpleSaleComponentFirerer;
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.core.entities.product.Product;
+import com.pqt.core.entities.sale.Sale;
+import javafx.application.Platform;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.input.KeyCode;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+
+public class CommandComposerSaleDisplayer implements IFXSaleDisplayerComponent {
+
+    private SimpleSaleComponentFirerer firerer;
+    private BorderPane mainPane;
+    private ListView listView;
+
+    private Sale sale;
+
+    public CommandComposerSaleDisplayer() {
+        firerer = new SimpleSaleComponentFirerer();
+        init();
+    }
+
+    private void init() {
+        mainPane = new BorderPane();
+
+        Label title = new Label(GUIStringTool.getCommandComposerTitleLabel());
+        title.setAlignment(Pos.CENTER);
+        title.getStyleClass().add(GUICssTool.getTitleTextStyleClass());
+
+        HBox topPane = new HBox();
+        topPane.setFillHeight(true);
+        topPane.setAlignment(Pos.CENTER);
+        topPane.getChildren().add(title);
+
+        mainPane.setTop(topPane);
+
+        listView = new ListView<>();
+        listView.setCellFactory(list->new ListCell(){
+            @Override
+            protected void updateItem(Product item, boolean empty) {
+                super.updateItem(item, empty);
+
+                if (empty || item == null) {
+                    setText(null);
+                    setGraphic(null);
+                } else {
+                    setText(GUIStringTool.getSaleItemStringRenderer().render(item, sale.getProducts().get(item)));
+                }
+            }
+        });
+        listView.setEditable(false);
+        listView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
+        listView.setOnMouseClicked(event->firerer.fireComponentClickEvent(event, listView.getSelectionModel().getSelectedItem()));
+        listView.setOnKeyTyped(event -> {
+            if(event.getCode().equals(KeyCode.ENTER)){
+                firerer.fireComponentClickEvent(event, listView.getSelectionModel().getSelectedItem());
+            }
+        });
+        mainPane.setCenter(listView);
+    }
+
+    @Override
+    public void display(Sale content) {
+        if(content ==null)
+            return;
+
+        this.sale = content;
+        Platform.runLater(()->{
+            this.listView.getItems().clear();
+            this.listView.getItems().addAll(this.sale.getProducts().keySet());
+        });
+    }
+
+    @Override
+    public void addListener(ISaleComponentListener l) {
+        firerer.addListener(l);
+    }
+
+    @Override
+    public void removeListener(ISaleComponentListener l) {
+        firerer.removeListener(l);
+    }
+
+    @Override
+    public Pane getPane() {
+        return mainPane;
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/SimpleValidator.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/SimpleValidator.java
new file mode 100644
index 00000000..0d895aa4
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/SimpleValidator.java
@@ -0,0 +1,108 @@
+package com.pqt.client.gui.ressources.components;
+
+import com.pqt.client.gui.ressources.components.generics.validators.IFXValidatorComponent;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentFirerer;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
+import com.pqt.client.gui.ressources.strings.GUIStringTool;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.SimpleValidatorComponentFirerer;
+import javafx.application.Platform;
+import javafx.scene.control.Button;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+
+public class SimpleValidator implements IFXValidatorComponent {
+
+    private final IValidatorComponentFirerer firerer;
+    private Pane pane;
+    private boolean askConfirmation;
+    private Button validationButton, cancelButton;
+
+    public SimpleValidator() {
+        this(false);
+    }
+
+    public SimpleValidator(boolean askConfirmation) {
+        firerer = new SimpleValidatorComponentFirerer();
+        this.askConfirmation = askConfirmation;
+    }
+
+    @Override
+    public void addListener(IValidatorComponentListener l) {
+        firerer.addListener(l);
+    }
+
+    @Override
+    public void removeListener(IValidatorComponentListener l) {
+        firerer.removeListener(l);
+    }
+
+    @Override
+    public Pane getPane() {
+        if(pane == null)
+            pane = createPane();
+        return pane;
+    }
+
+    private Pane createPane(){
+        GridPane grid = new GridPane();
+        grid.getStyleClass().add("validator");
+
+        validationButton = new Button(GUIStringTool.getValidationButtonLabel());
+        validationButton.setOnMouseClicked(event->{
+            getValidationButtonProcess().process();
+        });
+        grid.add(validationButton, 0,0);
+
+        cancelButton = new Button(GUIStringTool.getCancelButtonLabel());
+        cancelButton.setOnMouseClicked(event->{
+            getCancelButtonProcess().process();
+        });
+        grid.add(cancelButton, 1, 0);
+
+        return grid;
+    }
+
+    private IButtonProcess getValidationButtonProcess(){
+        return ()->{
+            if(validationButton.getText().equals(GUIStringTool.getValidationButtonLabel())){
+                if(askConfirmation)
+                    Platform.runLater(()->validationButton.setText(GUIStringTool.getConfirmationValidationButtonLabel()));
+                else
+                    firerer.fireValidationEvent();
+            }else{
+                if(validationButton.getText().equals(GUIStringTool.getConfirmationValidationButtonLabel()))
+                    firerer.fireValidationEvent();
+                Platform.runLater(()->validationButton.setText(GUIStringTool.getValidationButtonLabel()));
+            }
+        };
+    }
+
+    private IButtonProcess getCancelButtonProcess(){
+        return ()->{
+            if(cancelButton.getText().equals(GUIStringTool.getCancelButtonLabel())){
+                if(askConfirmation)
+                    Platform.runLater(()->cancelButton.setText(GUIStringTool.getConfirmationCancelButtonLabel()));
+                else
+                    firerer.fireCancelEvent();
+            }else{
+                Platform.runLater(()->cancelButton.setText(GUIStringTool.getCancelButtonLabel()));
+                firerer.fireCancelEvent();
+            }
+        };
+
+
+    }
+
+    private interface IButtonProcess{
+        void process();
+    }
+
+    public void setValidationButtonEnable(boolean enable){
+        this.validationButton.setDisable(!enable);
+    }
+
+    public void setCancelationButtonEnable(boolean enable){
+        this.cancelButton.setDisable(!enable);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/IFXComponent.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/IFXComponent.java
new file mode 100644
index 00000000..d333e909
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/IFXComponent.java
@@ -0,0 +1,7 @@
+package com.pqt.client.gui.ressources.components.generics;
+
+import javafx.scene.layout.Pane;
+
+public interface IFXComponent {
+    Pane getPane();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/creators/IFXCreatorComponent.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/creators/IFXCreatorComponent.java
new file mode 100644
index 00000000..4a79f9d1
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/creators/IFXCreatorComponent.java
@@ -0,0 +1,8 @@
+package com.pqt.client.gui.ressources.components.generics.creators;
+
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+
+public interface IFXCreatorComponent extends IFXComponent{
+    T create();
+    boolean isCreationPossible();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/IFXDisplayerComponent.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/IFXDisplayerComponent.java
new file mode 100644
index 00000000..6d9ea7fb
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/IFXDisplayerComponent.java
@@ -0,0 +1,10 @@
+package com.pqt.client.gui.ressources.components.generics.displayers;
+
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.components.generics.displayers.listeners.IDisplayerComponentListener;
+
+public interface IFXDisplayerComponent extends IFXComponent{
+    void display(T content);
+    void addListener(U l);
+    void removeListener(U l);
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/listeners/IDisplayerComponentFirerer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/listeners/IDisplayerComponentFirerer.java
new file mode 100644
index 00000000..9824dd5f
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/listeners/IDisplayerComponentFirerer.java
@@ -0,0 +1,13 @@
+package com.pqt.client.gui.ressources.components.generics.displayers.listeners;
+
+import javafx.event.Event;
+
+public interface IDisplayerComponentFirerer {
+    void fireRefreshContentRequestEvent();
+    void fireContentClickEvent(Event event, T eventTarget);
+    void fireAddContentRequestEvent();
+    void fireRemoveContentRequestEvent(T content);
+    void fireDetailContentRequestEvent(T content);
+    void addListener(IDisplayerComponentListener l);
+    void removeListener(IDisplayerComponentListener l);
+}
\ No newline at end of file
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/listeners/IDisplayerComponentListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/listeners/IDisplayerComponentListener.java
new file mode 100644
index 00000000..e2c28d07
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/listeners/IDisplayerComponentListener.java
@@ -0,0 +1,13 @@
+package com.pqt.client.gui.ressources.components.generics.displayers.listeners;
+
+import javafx.event.Event;
+
+import java.util.EventListener;
+
+public interface IDisplayerComponentListener extends EventListener {
+    void onRefreshContentRequestEvent();
+    void onContentClickEvent(Event event, T eventTarget);
+    void onAddContentRequestEvent();
+    void onRemoveContentRequestEvent(T content);
+    void onDetailContentRequestEvent(T content);
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/listeners/SimpleDisplayerComponentFirerer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/listeners/SimpleDisplayerComponentFirerer.java
new file mode 100644
index 00000000..c1909ad0
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/displayers/listeners/SimpleDisplayerComponentFirerer.java
@@ -0,0 +1,58 @@
+package com.pqt.client.gui.ressources.components.generics.displayers.listeners;
+
+import javafx.event.Event;
+
+import javax.swing.event.EventListenerList;
+import java.util.Arrays;
+
+public class SimpleDisplayerComponentFirerer> implements IDisplayerComponentFirerer {
+
+    protected EventListenerList listenerList;
+    protected Class clazz;
+
+    public SimpleDisplayerComponentFirerer(Class clazz) {
+        listenerList = new EventListenerList();
+        this.clazz = clazz;
+    }
+
+    @Override
+    public void fireRefreshContentRequestEvent() {
+        Arrays.stream(listenerList.getListeners(clazz)).forEach(IDisplayerComponentListener::onRefreshContentRequestEvent);
+    }
+
+    @Override
+    public void fireContentClickEvent(Event event, T eventTarget) {
+        Arrays.stream(listenerList.getListeners(clazz)).forEach(l->l.onContentClickEvent(event, eventTarget));
+    }
+
+    @Override
+    public void fireAddContentRequestEvent() {
+        Arrays.stream(listenerList.getListeners(clazz)).forEach(IDisplayerComponentListener::onAddContentRequestEvent);
+    }
+
+    @Override
+    public void fireRemoveContentRequestEvent(T content) {
+        Arrays.stream(listenerList.getListeners(clazz)).forEach(l->l.onRemoveContentRequestEvent(content));
+    }
+
+    @Override
+    public void fireDetailContentRequestEvent(T content) {
+        Arrays.stream(listenerList.getListeners(clazz)).forEach(l->l.onDetailContentRequestEvent(content));
+    }
+
+    @Override
+    public void addListener(IDisplayerComponentListener l) throws IllegalArgumentException {
+        if(clazz.isInstance(l)){
+            listenerList.add(clazz, clazz.cast(l));
+        }else{
+            throw new IllegalArgumentException("Listener must implement the following interface : "+clazz.getName());
+        }
+    }
+
+    @Override
+    public void removeListener(IDisplayerComponentListener l) {
+        if (clazz.isInstance(l)) {
+            listenerList.remove(clazz, clazz.cast(l));
+        }
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/javafx_override/CssEnabledGridPane.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/javafx_override/CssEnabledGridPane.java
new file mode 100644
index 00000000..3ef68e26
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/javafx_override/CssEnabledGridPane.java
@@ -0,0 +1,11 @@
+package com.pqt.client.gui.ressources.components.generics.javafx_override;
+
+import javafx.scene.layout.GridPane;
+
+public class CssEnabledGridPane extends GridPane {
+
+    public CssEnabledGridPane() {
+        super();
+        this.getStyleClass().add("grid-pane");
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/javafx_override/HighlightListCell.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/javafx_override/HighlightListCell.java
new file mode 100644
index 00000000..985b058c
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/javafx_override/HighlightListCell.java
@@ -0,0 +1,25 @@
+package com.pqt.client.gui.ressources.components.generics.javafx_override;
+
+import javafx.css.PseudoClass;
+import javafx.scene.control.ListCell;
+
+public class HighlightListCell extends ListCell {
+
+    private PseudoClass highlightPC;
+    private boolean highlighted;
+
+    public HighlightListCell() {
+        super();
+        highlighted = false;
+        highlightPC = PseudoClass.getPseudoClass("highlighted");
+    }
+
+    public void setHighLight(boolean highLight){
+        highlighted = highLight;
+        this.pseudoClassStateChanged(highlightPC, highLight);
+    }
+
+    public boolean isHightlighted(){
+        return highlighted;
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/others/SideBar.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/others/SideBar.java
new file mode 100644
index 00000000..d5c5351a
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/others/SideBar.java
@@ -0,0 +1,119 @@
+package com.pqt.client.gui.ressources.components.generics.others;
+
+import com.pqt.client.gui.ressources.components.generics.others.listeners.ISideBarListener;
+import javafx.animation.Animation;
+import javafx.animation.Transition;
+import javafx.beans.value.ObservableValue;
+import javafx.css.*;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.layout.VBox;
+import javafx.util.Duration;
+
+import javax.swing.event.EventListenerList;
+import java.util.Arrays;
+import java.util.List;
+
+public class SideBar extends VBox {
+
+    private static final StyleablePropertyFactory FACTORY = new StyleablePropertyFactory<>(VBox.getClassCssMetaData());
+
+    private static final CssMetaData EXPANDED_WIDTH =
+            FACTORY.createSizeCssMetaData("-pqt-expanded-width",p->p.expandedWidth, 100, false);
+
+    private StyleableProperty expandedWidth;
+    private EventListenerList listenerList;
+    private Animation collapseSideBar, expandSideBar;
+
+    /** creates a sidebar containing a vertical alignment of the given nodes */
+    public SideBar(Node... children) {
+        listenerList = new EventListenerList();
+        getStyleClass().add("sidebar");
+        this.setMinWidth(0);
+        this.expandedWidth = new SimpleStyleableDoubleProperty(EXPANDED_WIDTH, this, "expanded-width");
+        this.setPrefWidth(expandedWidth.getValue().doubleValue());
+
+        setAlignment(Pos.CENTER);
+        getChildren().addAll(children);
+
+        // create an animation to show a sidebar.
+        expandSideBar = new Transition() {
+            {
+                setCycleDuration(Duration.millis(250));
+            }
+            protected void interpolate(double frac) {
+                SideBar.this.setVisible(true);
+                final double curWidth = expandedWidth.getValue().doubleValue() * frac;
+                setPrefWidth(curWidth);
+                setTranslateX(-expandedWidth.getValue().doubleValue() + curWidth);
+            }
+        };
+        expandSideBar.onFinishedProperty().set(actionEvent ->
+                Arrays.stream(listenerList.getListeners(ISideBarListener.class))
+                        .forEach(ISideBarListener::onExpandFinished)
+        );
+
+
+        // create an animation to hide sidebar.
+        collapseSideBar = new Transition() {
+            {
+                setCycleDuration(Duration.millis(250));
+            }
+            protected void interpolate(double frac) {
+                final double curWidth = expandedWidth.getValue().doubleValue() * (1.0 - frac);
+                setPrefWidth(curWidth);
+                setTranslateX(-expandedWidth.getValue().doubleValue() + curWidth);
+            }
+        };
+        collapseSideBar.onFinishedProperty().set(actionEvent ->{
+            setVisible(false);
+            Arrays.stream(listenerList.getListeners(ISideBarListener.class))
+                    .forEach(ISideBarListener::onCollapsedFinished);
+        });
+        collapse();
+    }
+
+    public void expand(){
+        if (expandSideBar.statusProperty().get() == Animation.Status.STOPPED
+                && collapseSideBar.statusProperty().get() == Animation.Status.STOPPED) {
+            if (!isVisible()) {
+                expandSideBar.play();
+            }
+        }
+    }
+
+    public void collapse(){
+        if (expandSideBar.statusProperty().get() == Animation.Status.STOPPED
+                && collapseSideBar.statusProperty().get() == Animation.Status.STOPPED) {
+            if (isVisible()) {
+                collapseSideBar.play();
+            }
+        }
+    }
+
+    public boolean isExpanded(){
+        return isVisible() && expandSideBar.statusProperty().get().equals(Animation.Status.STOPPED);
+    }
+
+    public boolean isCollapsed() {
+        return !isVisible() && collapseSideBar.statusProperty().get().equals(Animation.Status.STOPPED);
+    }
+
+    public void addListener(ISideBarListener listener){
+        listenerList.add(ISideBarListener.class, listener);
+    }
+
+    public void removeListener(ISideBarListener listener){
+        listenerList.remove(ISideBarListener.class, listener);
+    }
+
+
+    public static  List> getClassCssMetaData() {
+        return FACTORY.getCssMetaData();
+    }
+
+    @Override
+    public List> getCssMetaData() {
+        return FACTORY.getCssMetaData();
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/others/listeners/ISideBarListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/others/listeners/ISideBarListener.java
new file mode 100644
index 00000000..2a1314ff
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/others/listeners/ISideBarListener.java
@@ -0,0 +1,9 @@
+package com.pqt.client.gui.ressources.components.generics.others.listeners;
+
+import java.util.EventListener;
+
+public interface ISideBarListener extends EventListener {
+
+    void onCollapsedFinished();
+    void onExpandFinished();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/toast/Toast.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/toast/Toast.java
new file mode 100644
index 00000000..051cc5ac
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/toast/Toast.java
@@ -0,0 +1,54 @@
+package com.pqt.client.gui.ressources.components.generics.toast;
+
+import com.pqt.client.gui.ressources.css.GUICssTool;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
+import javafx.scene.Scene;
+import javafx.scene.layout.StackPane;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+import javafx.util.Duration;
+
+final class Toast {
+    static void toast(Stage ownerStage, String toastMsg, int toastDelay, int fadeInDelay, int fadeOutDelay) {
+        Stage toastStage = new Stage();
+        toastStage.initOwner(ownerStage);
+        toastStage.setResizable(false);
+        toastStage.initStyle(StageStyle.TRANSPARENT);
+
+        Text text = new Text(toastMsg);
+        text.getStyleClass().add("toast-text");
+
+        StackPane root = new StackPane(text);
+        root.getStyleClass().add("toast-pane");
+        root.setOpacity(0);
+
+        Scene scene = new Scene(root);
+        scene.setFill(Color.TRANSPARENT);
+        scene.getStylesheets().addAll(Toast.class.getResource(GUICssTool.getCssFilePath()).toExternalForm());
+        toastStage.setScene(scene);
+        toastStage.show();
+
+        Timeline fadeInTimeline = new Timeline();
+        KeyFrame fadeInKey1 = new KeyFrame(Duration.millis(fadeInDelay), new KeyValue (toastStage.getScene().getRoot().opacityProperty(), 1));
+        fadeInTimeline.getKeyFrames().add(fadeInKey1);
+        fadeInTimeline.setOnFinished((ae) ->
+                new Thread(() -> {
+                    try {
+                        Thread.sleep(toastDelay);
+                    }
+                    catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    Timeline fadeOutTimeline = new Timeline();
+                    KeyFrame fadeOutKey1 = new KeyFrame(Duration.millis(fadeOutDelay), new KeyValue (toastStage.getScene().getRoot().opacityProperty(), 0));
+                    fadeOutTimeline.getKeyFrames().add(fadeOutKey1);
+                    fadeOutTimeline.setOnFinished((aeb) -> toastStage.close());
+                    fadeOutTimeline.play();
+                }).start());
+        fadeInTimeline.play();
+    }
+}
\ No newline at end of file
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/toast/ToastFactory.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/toast/ToastFactory.java
new file mode 100644
index 00000000..d174244e
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/toast/ToastFactory.java
@@ -0,0 +1,46 @@
+package com.pqt.client.gui.ressources.components.generics.toast;
+
+import javafx.stage.Stage;
+
+public class ToastFactory {
+
+    private static ToastFactory INSTANCE = null;
+
+    private Stage stage;
+    private int delay, fadeInDelay, fadeOutDelay;
+
+    private ToastFactory(Stage stage){
+        this.stage = stage;
+        delay = 3000;
+        fadeInDelay = 250;
+        fadeOutDelay = 250;
+    }
+
+    public void setToastDelay(int msDelay){
+        this.delay = msDelay;
+    }
+
+    public void setToastFadeInDelay(int msDelay){
+        this.fadeInDelay = msDelay;
+    }
+
+    public void setToastFadeOutDelay(int msDelay){
+        this.fadeOutDelay = msDelay;
+    }
+
+    public void toast(String message){
+        Toast.toast(stage, message, delay, fadeInDelay, fadeOutDelay);
+    }
+
+    public static void init(Stage stage){
+        INSTANCE = new ToastFactory(stage);
+    }
+
+    public static boolean isInitialized(){
+        return INSTANCE!=null;
+    }
+
+    public static ToastFactory getINSTANCE(){
+        return INSTANCE;
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/IFXValidatorComponent.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/IFXValidatorComponent.java
new file mode 100644
index 00000000..01f96276
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/IFXValidatorComponent.java
@@ -0,0 +1,9 @@
+package com.pqt.client.gui.ressources.components.generics.validators;
+
+import com.pqt.client.gui.ressources.components.generics.IFXComponent;
+import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
+
+public interface IFXValidatorComponent extends IFXComponent{
+    void addListener(IValidatorComponentListener l);
+    void removeListener(IValidatorComponentListener l);
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/listeners/IValidatorComponentFirerer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/listeners/IValidatorComponentFirerer.java
new file mode 100644
index 00000000..2e44be06
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/listeners/IValidatorComponentFirerer.java
@@ -0,0 +1,9 @@
+package com.pqt.client.gui.ressources.components.generics.validators.listeners;
+
+public interface IValidatorComponentFirerer {
+    void addListener(IValidatorComponentListener l);
+    void removeListener(IValidatorComponentListener l);
+
+    void fireValidationEvent();
+    void fireCancelEvent();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/listeners/IValidatorComponentListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/listeners/IValidatorComponentListener.java
new file mode 100644
index 00000000..c4144f91
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/listeners/IValidatorComponentListener.java
@@ -0,0 +1,8 @@
+package com.pqt.client.gui.ressources.components.generics.validators.listeners;
+
+import java.util.EventListener;
+
+public interface IValidatorComponentListener extends EventListener {
+    void onValidationEvent();
+    void onCancelEvent();
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/listeners/SimpleValidatorComponentFirerer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/listeners/SimpleValidatorComponentFirerer.java
new file mode 100644
index 00000000..cdaa979c
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/generics/validators/listeners/SimpleValidatorComponentFirerer.java
@@ -0,0 +1,33 @@
+package com.pqt.client.gui.ressources.components.generics.validators.listeners;
+
+import javax.swing.event.EventListenerList;
+import java.util.Arrays;
+
+public class SimpleValidatorComponentFirerer implements IValidatorComponentFirerer {
+
+    private EventListenerList listenerList;
+
+    public SimpleValidatorComponentFirerer() {
+        listenerList = new EventListenerList();
+    }
+
+    @Override
+    public void addListener(IValidatorComponentListener l) {
+        listenerList.add(IValidatorComponentListener.class, l);
+    }
+
+    @Override
+    public void removeListener(IValidatorComponentListener l) {
+        listenerList.remove(IValidatorComponentListener.class, l);
+    }
+
+    @Override
+    public void fireValidationEvent() {
+        Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class)).forEach(IValidatorComponentListener::onValidationEvent);
+    }
+
+    @Override
+    public void fireCancelEvent() {
+        Arrays.stream(listenerList.getListeners(IValidatorComponentListener.class)).forEach(IValidatorComponentListener::onCancelEvent);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/account/IFXAccountsDisplayerComponent.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/account/IFXAccountsDisplayerComponent.java
new file mode 100644
index 00000000..1c459115
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/account/IFXAccountsDisplayerComponent.java
@@ -0,0 +1,11 @@
+package com.pqt.client.gui.ressources.components.specifics.account;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.IFXDisplayerComponent;
+import com.pqt.client.gui.ressources.components.specifics.account.listeners.IAccountComponentListener;
+import com.pqt.core.entities.user_account.Account;
+
+import java.util.Collection;
+
+public interface IFXAccountsDisplayerComponent extends IFXDisplayerComponent, IAccountComponentListener> {
+
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/account/listeners/IAccountComponentListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/account/listeners/IAccountComponentListener.java
new file mode 100644
index 00000000..9fe3ff70
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/account/listeners/IAccountComponentListener.java
@@ -0,0 +1,7 @@
+package com.pqt.client.gui.ressources.components.specifics.account.listeners;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.listeners.IDisplayerComponentListener;
+import com.pqt.core.entities.user_account.Account;
+
+public interface IAccountComponentListener extends IDisplayerComponentListener{
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/account/listeners/SimpleAccountComponentFirerer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/account/listeners/SimpleAccountComponentFirerer.java
new file mode 100644
index 00000000..8f06f6a2
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/account/listeners/SimpleAccountComponentFirerer.java
@@ -0,0 +1,10 @@
+package com.pqt.client.gui.ressources.components.specifics.account.listeners;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.listeners.SimpleDisplayerComponentFirerer;
+import com.pqt.core.entities.user_account.Account;
+
+public class SimpleAccountComponentFirerer extends SimpleDisplayerComponentFirerer {
+    public SimpleAccountComponentFirerer() {
+        super(IAccountComponentListener.class);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/products/IFXProductsDisplayerComponent.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/products/IFXProductsDisplayerComponent.java
new file mode 100644
index 00000000..5411b73d
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/products/IFXProductsDisplayerComponent.java
@@ -0,0 +1,10 @@
+package com.pqt.client.gui.ressources.components.specifics.products;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.IFXDisplayerComponent;
+import com.pqt.client.gui.ressources.components.specifics.products.listeners.IStockComponentListener;
+import com.pqt.core.entities.product.Product;
+
+import java.util.Collection;
+
+public interface IFXProductsDisplayerComponent extends IFXDisplayerComponent, IStockComponentListener> {
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/products/listeners/IStockComponentListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/products/listeners/IStockComponentListener.java
new file mode 100644
index 00000000..0dffba47
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/products/listeners/IStockComponentListener.java
@@ -0,0 +1,7 @@
+package com.pqt.client.gui.ressources.components.specifics.products.listeners;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.listeners.IDisplayerComponentListener;
+import com.pqt.core.entities.product.Product;
+
+public interface IStockComponentListener extends IDisplayerComponentListener {
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/products/listeners/SimpleStockComponentFirerer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/products/listeners/SimpleStockComponentFirerer.java
new file mode 100644
index 00000000..5832a288
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/products/listeners/SimpleStockComponentFirerer.java
@@ -0,0 +1,11 @@
+package com.pqt.client.gui.ressources.components.specifics.products.listeners;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.listeners.SimpleDisplayerComponentFirerer;
+import com.pqt.core.entities.product.Product;
+
+public class SimpleStockComponentFirerer extends SimpleDisplayerComponentFirerer {
+
+    public SimpleStockComponentFirerer() {
+        super(IStockComponentListener.class);
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/sale/IFXSaleDisplayerComponent.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/sale/IFXSaleDisplayerComponent.java
new file mode 100644
index 00000000..5f0a0fbc
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/sale/IFXSaleDisplayerComponent.java
@@ -0,0 +1,8 @@
+package com.pqt.client.gui.ressources.components.specifics.sale;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.IFXDisplayerComponent;
+import com.pqt.client.gui.ressources.components.specifics.sale.listeners.ISaleComponentListener;
+import com.pqt.core.entities.sale.Sale;
+
+public interface IFXSaleDisplayerComponent extends IFXDisplayerComponent {
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/sale/listeners/ISaleComponentListener.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/sale/listeners/ISaleComponentListener.java
new file mode 100644
index 00000000..f64fbc7f
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/sale/listeners/ISaleComponentListener.java
@@ -0,0 +1,10 @@
+package com.pqt.client.gui.ressources.components.specifics.sale.listeners;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.listeners.IDisplayerComponentListener;
+import com.pqt.core.entities.product.Product;
+import com.pqt.core.entities.sale.Sale;
+import javafx.event.Event;
+
+public interface ISaleComponentListener extends IDisplayerComponentListener {
+    void onComponentClickEvent(Event event, Product product);
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/sale/listeners/SimpleSaleComponentFirerer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/sale/listeners/SimpleSaleComponentFirerer.java
new file mode 100644
index 00000000..aa83a903
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/components/specifics/sale/listeners/SimpleSaleComponentFirerer.java
@@ -0,0 +1,19 @@
+package com.pqt.client.gui.ressources.components.specifics.sale.listeners;
+
+import com.pqt.client.gui.ressources.components.generics.displayers.listeners.SimpleDisplayerComponentFirerer;
+import com.pqt.core.entities.product.Product;
+import com.pqt.core.entities.sale.Sale;
+import javafx.event.Event;
+
+import java.util.Arrays;
+
+public class SimpleSaleComponentFirerer extends SimpleDisplayerComponentFirerer {
+
+    public SimpleSaleComponentFirerer() {
+        super(ISaleComponentListener.class);
+    }
+
+    public void fireComponentClickEvent(Event event, Product product) {
+        Arrays.stream(listenerList.getListeners(ISaleComponentListener.class)).forEach(l->l.onComponentClickEvent(event, product));
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/css/GUICssTool.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/css/GUICssTool.java
new file mode 100644
index 00000000..a2f283e5
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/css/GUICssTool.java
@@ -0,0 +1,20 @@
+package com.pqt.client.gui.ressources.css;
+
+public class GUICssTool {
+    public static String getCssFilePath(){
+        //return "/daymode-blue.css";
+        return "/nightmode.css";
+    }
+
+    public static String getMainModulePaneCssClass() {
+        return "main-module-pane";
+    }
+
+    public static String getIntermediaryPaneStyleClass() {
+        return "grey-intermediary-pane";
+    }
+
+    public static String getTitleTextStyleClass() {
+        return "label-header";
+    }
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/strings/GUIStringTool.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/strings/GUIStringTool.java
new file mode 100644
index 00000000..af5f1781
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/strings/GUIStringTool.java
@@ -0,0 +1,336 @@
+package com.pqt.client.gui.ressources.strings;
+
+import com.pqt.core.entities.product.Category;
+import com.pqt.core.entities.product.Product;
+import com.pqt.core.entities.sale.SaleStatus;
+import com.pqt.core.entities.sale.SaleType;
+import com.pqt.core.entities.user_account.Account;
+import com.pqt.core.entities.user_account.AccountLevel;
+import javafx.util.StringConverter;
+
+import java.text.NumberFormat;
+import java.util.EnumSet;
+
+//TODO faire ça un peu mieux
+public class GUIStringTool {
+
+    public static String getValidationButtonLabel() {
+        return "Valider";
+    }
+
+    public static String getConfirmationValidationButtonLabel() {
+        return "Confirmer";
+    }
+
+    public static String getCancelButtonLabel() {
+        return "Annuler";
+    }
+
+    public static String getConfirmationCancelButtonLabel() {
+        return "Confirmer";
+    }
+
+    public static String getCategorytabStockDisplayerTitle() {
+        return "Produits";
+    }
+
+    public static IObjectStringRenderer getDetailledProductStringRenderer(){
+        return product->{
+            if(product!=null){
+                String amountStr;
+                if(product.getAmountRemaining()<=0){
+                    amountStr = "OUT OF STOCK";
+                }else if(product.getAmountRemaining()>=30){
+                    amountStr = "30+";
+                }else{
+                    amountStr = Integer.toString(product.getAmountRemaining());
+                }
+                return String.format("%s - %.2f€ (%s)", product.getName(), product.getPrice(), amountStr);
+            }else
+                return "null";
+        };
+    }
+
+    public static IObjectStringRenderer getSimpleProductStringRenderer(){
+        return product->{
+            if(product!=null)
+                return String.format("%s - %.2f€", product.getName(), product.getPrice());
+            else
+                return "null";
+        };
+    }
+
+    public static String getCommandComposerTitleLabel() {
+        return "Commande";
+    }
+
+    public static IObjectWithQuantityStringRenderer getSaleItemStringRenderer(){
+        return (product, qte)->String.format("%dx %s", qte, product.getName());
+    }
+
+    public static String getPasswordFieldPromptText() {
+        return "mot de passe";
+    }
+
+    public static StringConverter getAccountStringConverter() {
+        return new StringConverter() {
+            @Override
+            public String toString(Account object) {
+                if(object!=null)
+                    return String.format("%s - (%s)", object.getUsername(), object.getPermissionLevel());
+
+                return "null";
+            }
+
+            @Override
+            public Account fromString(String string) {
+                Account reply = new Account();
+
+                String[] pieces = string.split(" - ");
+                reply.setUsername(pieces[0]);
+                if(pieces.length>1)
+                    for(AccountLevel al : EnumSet.allOf(AccountLevel.class)){
+                        if(al.name().equals(pieces[1]))
+                            reply.setPermissionLevel(al);
+                    }
+
+                return reply;
+            }
+        };
+    }
+
+    public static String getLogoutButtonLabel() {
+        return "Déconnexion";
+    }
+
+    public static String getLoginButtonLabel() {
+        return "Connexion";
+    }
+
+    public static IObjectStringRenderer getPriceRenderer() {
+        return price -> NumberFormat.getCurrencyInstance().format(price);
+    }
+
+    public static String getSaleMakerTextFieldPromptText() {
+        return "Auteur";
+    }
+
+    public static String getSaleMakerTextFieldLabel() {
+        return "Fait par : ";
+    }
+
+    public static String getSaleBeneficiaryTextFieldLabel() {
+        return "Fait pour : ";
+    }
+
+    public static String getSaleTypeTextFieldLabel() {
+        return "Type de paiement : ";
+    }
+
+    public static String getSalePriceTextFieldLabel() {
+        return "Prix de la commande : ";
+    }
+
+    public static StringConverter getSaleTypeStringConverter() {
+        return new StringConverter() {
+            @Override
+            public String toString(SaleType object) {
+                return object.name();
+            }
+
+            @Override
+            public SaleType fromString(String string) {
+                return EnumSet.allOf(SaleType.class).stream().filter(type->type.name().equals(string)).findFirst().orElse(null);
+            }
+        };
+    }
+
+    public static String getSalePriceTextFieldPromptText() {
+        return getPriceRenderer().render(0d);
+    }
+
+    public static String getCommandValidationErrorMessage() {
+        return "La commande n'a pas pu être validée";
+    }
+
+    public static String getCommandValidationErrorMessage(Throwable cause) {
+        return "La commande n'a pas pu être validée : "+cause.getMessage();
+    }
+
+    public static String getSaleIdLabel() {
+        return "Numéro de commande : ";
+    }
+
+    public static String getSaleStatusLabel() {
+        return "Etat actuel";
+    }
+
+    public static IObjectStringRenderer getSaleStatusRenderer() {
+        return Enum::name;
+    }
+
+    public static String getOkButtonLabel() {
+        return "OK";
+    }
+
+    public static String getAppTitle() {
+        return "Client PQT - Gargotte";
+    }
+
+    public static String getSideBarCollapseButtonLabel() {
+        return "Réduire";
+    }
+
+    public static String getSideBarExpandButtonLabel() {
+        return "Menu";
+    }
+
+    public static String getSaleGuiModuleName() {
+        return "Vente";
+    }
+
+    public static String getAddButtonLabel() {
+        return "Ajouter";
+    }
+
+    public static String getDetailButtonLabel() {
+        return "Détail";
+    }
+
+    public static String getRemoveButtonLabel() {
+        return "Supprimer";
+    }
+
+    public static String getRefreshButtonLabel() {
+        return "Rafraichir";
+    }
+
+    public static String getProductNameColumnHeader() {
+        return "Nom";
+    }
+
+    public static String getProductCategoryColumnHeader() {
+        return "Catégorie";
+    }
+
+    public static String getProductAmountRemainingColumnHeader() {
+        return "Stock";
+    }
+
+    public static String getProductAmountSoldColumnHeader() {
+        return "Vendu";
+    }
+
+    public static String getProductPriceColumnHeader() {
+        return "Prix";
+    }
+
+    public static String getProductIsSellableColumnHeader() {
+        return "Vendable";
+    }
+
+    public static IObjectStringRenderer getBooleanRenderer() {
+        return bool->bool?"Oui":"Non";
+    }
+
+    public static String getStatGuiModuleName() {
+        return "Statistiques";
+    }
+
+    public static String getProductNameLabel() {
+        return "Nom : ";
+    }
+
+    public static String getProductCategoryLabel() {
+        return "Catégorie : ";
+    }
+
+    public static String getProductAmountRemainingLabel() {
+        return "En stock : ";
+    }
+
+    public static String getProductAmountSoldLabel() {
+        return "Vendu : ";
+    }
+
+    public static String getProductSellableLabel() {
+        return "Vendable : ";
+    }
+
+    public static String getProductPriceLabel() {
+        return "Prix : ";
+    }
+
+    public static StringConverter getCategoryStringConverter() {
+        return new StringConverter() {
+            @Override
+            public String toString(Category object) {
+                if(object!=null)
+                   return object.getName();
+                else
+                    return "";
+            }
+
+            @Override
+            public Category fromString(String string) {
+                if(string!=null)
+                    return new Category(-1, string);
+                else
+                    return null;
+            }
+        };
+    }
+
+    public static String getComponentListTitleLabel() {
+        return "Composants";
+    }
+
+    public static String getAccountGuiModuleName() {
+        return "Utilisateurs";
+    }
+
+    public static IObjectStringRenderer getAccountLevelStringRenderer() {
+        return level->{
+            switch (level){
+                case LOWEST:
+                    return "autre";
+                case GUEST:
+                    return "Invité";
+                case STAFF:
+                    return "Staff";
+                case WAITER:
+                    return "Caissier";
+                case MASTER:
+                    return "Chef";
+                default:
+                    return "unknown";
+            }
+        };
+    }
+
+    public static String getAccountListTitleLabel() {
+        return "Utilisateurs";
+    }
+
+    public static String getUsernameLabel() {
+        return "Nom :";
+    }
+
+    public static String getPasswordLabel() {
+        return "Mot de passe : ";
+    }
+
+    public static String getUserLevelLabel() {
+        return "Niveau d'accréditation : ";
+    }
+
+    public static String getAccountNameColumnHeaderLabel() {
+        return "Nom d'utilisateur";
+    }
+
+    public static String getAccountLevelColumnHeaderLabel() {
+        return "Niveau d'accréditation";
+    }
+}
+
+
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/strings/IObjectStringRenderer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/strings/IObjectStringRenderer.java
new file mode 100644
index 00000000..ebbb8c6a
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/strings/IObjectStringRenderer.java
@@ -0,0 +1,5 @@
+package com.pqt.client.gui.ressources.strings;
+
+public interface IObjectStringRenderer {
+    String render(T obj);
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/gui/ressources/strings/IObjectWithQuantityStringRenderer.java b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/strings/IObjectWithQuantityStringRenderer.java
new file mode 100644
index 00000000..52dbbed2
--- /dev/null
+++ b/Workspace/client/src/main/java/com/pqt/client/gui/ressources/strings/IObjectWithQuantityStringRenderer.java
@@ -0,0 +1,5 @@
+package com.pqt.client.gui.ressources.strings;
+
+public interface IObjectWithQuantityStringRenderer {
+    String render(T obj, int quantity);
+}
diff --git a/Workspace/client/src/main/java/com/pqt/client/module/account/AccountService.java b/Workspace/client/src/main/java/com/pqt/client/module/account/AccountService.java
index c3affffa..9f6c76a0 100644
--- a/Workspace/client/src/main/java/com/pqt/client/module/account/AccountService.java
+++ b/Workspace/client/src/main/java/com/pqt/client/module/account/AccountService.java
@@ -18,7 +18,7 @@ public class AccountService {
 
 	}
 
-	public boolean isAccountLoggedIn(Account account) {
+	public boolean isCurrentAccountLoggedIn() {
 		return false;
 	}
 
@@ -26,7 +26,7 @@ public class AccountService {
 
 	}
 
-	public void logOutCurrentAccount(String password) {
+	public void logOutCurrentAccount() {
 
 	}
 
@@ -42,4 +42,7 @@ public class AccountService {
 
 	}
 
+    public List getAllAccounts() {
+        return null;
+    }
 }
diff --git a/Workspace/client/src/main/java/com/pqt/client/module/account/listeners/AccountListenerAdapter.java b/Workspace/client/src/main/java/com/pqt/client/module/account/listeners/AccountListenerAdapter.java
index 50243c75..6abd0649 100644
--- a/Workspace/client/src/main/java/com/pqt/client/module/account/listeners/AccountListenerAdapter.java
+++ b/Workspace/client/src/main/java/com/pqt/client/module/account/listeners/AccountListenerAdapter.java
@@ -6,9 +6,16 @@ public class AccountListenerAdapter implements IAccountListener {
 
 
 	/**
-	 * @see com.pqt.client.module.account.listeners.IAccountListener#onAccountStatusChanged(boolean)
+	 * @see com.pqt.client.module.account.listeners.IAccountListener#onAccountStatusChangedEvent(boolean)
 	 */
-	public void onAccountStatusChanged(boolean status) {
+	public void onAccountStatusChangedEvent(boolean status) {
+
+	}
+
+	/**
+	 * @see com.pqt.client.module.account.listeners.IAccountListener#onAccountListChangedEvent()
+	 */
+	public void onAccountListChangedEvent() {
 
 	}
 
diff --git a/Workspace/client/src/main/java/com/pqt/client/module/account/listeners/IAccountListener.java b/Workspace/client/src/main/java/com/pqt/client/module/account/listeners/IAccountListener.java
index 7fa6dfef..0de33085 100644
--- a/Workspace/client/src/main/java/com/pqt/client/module/account/listeners/IAccountListener.java
+++ b/Workspace/client/src/main/java/com/pqt/client/module/account/listeners/IAccountListener.java
@@ -4,6 +4,6 @@ import java.util.EventListener;
 
 public interface IAccountListener extends EventListener {
 
-	public void onAccountStatusChanged(boolean status);
-
+	void onAccountStatusChangedEvent(boolean status);
+	void onAccountListChangedEvent();
 }
diff --git a/Workspace/client/src/main/java/com/pqt/client/module/sale/SaleBuilder.java b/Workspace/client/src/main/java/com/pqt/client/module/sale/SaleBuilder.java
index 4c550960..a70bac00 100644
--- a/Workspace/client/src/main/java/com/pqt/client/module/sale/SaleBuilder.java
+++ b/Workspace/client/src/main/java/com/pqt/client/module/sale/SaleBuilder.java
@@ -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() 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() 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)
diff --git a/Workspace/client/src/main/java/com/pqt/client/module/sale/SaleService.java b/Workspace/client/src/main/java/com/pqt/client/module/sale/SaleService.java
index cdaf60b9..081df440 100644
--- a/Workspace/client/src/main/java/com/pqt/client/module/sale/SaleService.java
+++ b/Workspace/client/src/main/java/com/pqt/client/module/sale/SaleService.java
@@ -6,6 +6,9 @@ import com.pqt.client.module.query.query_callback.IIdQueryCallback;
 import com.pqt.client.module.sale.listeners.ISaleFirerer;
 import com.pqt.client.module.sale.listeners.ISaleListener;
 import com.pqt.client.module.sale.listeners.SimpleSaleFirerer;
+import com.pqt.core.entities.sale.SaleType;
+
+import java.util.List;
 
 //TODO écrire javadoc
 //TODO add log lines
@@ -55,4 +58,8 @@ public class SaleService {
         eventFirerer.removeListener(listener);
 	}
 
+    public List getSaleTypes() {
+	    //TODO
+        return null;
+    }
 }
diff --git a/Workspace/client/src/main/java/com/pqt/client/module/sale/listeners/ISaleListener.java b/Workspace/client/src/main/java/com/pqt/client/module/sale/listeners/ISaleListener.java
index ddb44c48..8369a112 100644
--- a/Workspace/client/src/main/java/com/pqt/client/module/sale/listeners/ISaleListener.java
+++ b/Workspace/client/src/main/java/com/pqt/client/module/sale/listeners/ISaleListener.java
@@ -1,15 +1,13 @@
 package com.pqt.client.module.sale.listeners;
 
-import com.pqt.core.entities.sale.Sale;
-
 import java.util.EventListener;
 
 public interface ISaleListener extends EventListener {
 
-	public abstract void onSaleValidationSuccess(long saleId);
+	void onSaleValidationSuccess(long saleId);
 
-	public abstract void onSaleValidationError(long saleId, Throwable cause);
+	void onSaleValidationError(long saleId, Throwable cause);
 
-	public abstract void onSaleValidationRefused(long saleId, Throwable cause);
+	void onSaleValidationRefused(long saleId, Throwable cause);
 
 }
diff --git a/Workspace/client/src/main/java/com/pqt/client/module/stock/StockDao.java b/Workspace/client/src/main/java/com/pqt/client/module/stock/StockDao.java
index d682f84f..08439d66 100644
--- a/Workspace/client/src/main/java/com/pqt/client/module/stock/StockDao.java
+++ b/Workspace/client/src/main/java/com/pqt/client/module/stock/StockDao.java
@@ -33,12 +33,8 @@ public class StockDao {
 	}
 
 	public synchronized Product getProduct(final int id) {
-		Optional 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() {
diff --git a/Workspace/client/src/main/java/com/pqt/client/module/stock/StockService.java b/Workspace/client/src/main/java/com/pqt/client/module/stock/StockService.java
index 95644e61..8c2e67aa 100644
--- a/Workspace/client/src/main/java/com/pqt/client/module/stock/StockService.java
+++ b/Workspace/client/src/main/java/com/pqt/client/module/stock/StockService.java
@@ -13,7 +13,7 @@ public class StockService {
 
 	private StockDao dao;
 
-	private StockService() {
+	public StockService() {
 		dao = new StockDao();
 	}
 
@@ -39,7 +39,8 @@ public class StockService {
     /**
      * Accesseur de la liste des produits actuellement en vente.
      *  
-     * 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.
+	 *  
+	 * 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 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);
 	}
-
 }
diff --git a/Workspace/client/src/main/java/com/pqt/client/module/stock/UpdateBuilder.java b/Workspace/client/src/main/java/com/pqt/client/module/stock/UpdateBuilder.java
index 36826f26..f471916b 100644
--- a/Workspace/client/src/main/java/com/pqt/client/module/stock/UpdateBuilder.java
+++ b/Workspace/client/src/main/java/com/pqt/client/module/stock/UpdateBuilder.java
@@ -16,20 +16,23 @@ public class UpdateBuilder {
         toModify = new HashMap<>();
     }
 
-    public void addProduct(Product product) {
+    public UpdateBuilder addProduct(Product product) {
         if(!toAdd.contains(product)){
             toAdd.add(product);
         }
+        return this;
 	}
 
-	public void removeProduct(Product product) {
+	public UpdateBuilder removeProduct(Product product) {
         if(toRemove.contains(product)){
             toRemove.remove(product);
         }
+        return this;
 	}
 
-	public void modifyProduct(Product oldVersion, Product newVersion) {
+	public UpdateBuilder modifyProduct(Product oldVersion, Product newVersion) {
         toModify.put(oldVersion, newVersion);
+        return this;
 	}
 
 	public List build() {
diff --git a/Workspace/client/src/main/resources/nightmode.css b/Workspace/client/src/main/resources/nightmode.css
new file mode 100644
index 00000000..a33217d2
--- /dev/null
+++ b/Workspace/client/src/main/resources/nightmode.css
@@ -0,0 +1,235 @@
+.root {
+    -fx-background-color: #1d1d1d;
+}
+
+.label {
+    -fx-font-size: 11pt;
+    -fx-font-family: "Segoe UI Semibold";
+    -fx-text-fill: white;
+    -fx-opacity: 0.8;
+}
+
+.label-bright {
+    -fx-font-size: 11pt;
+    -fx-font-family: "Segoe UI Semibold";
+    -fx-text-fill: white;
+    -fx-opacity: 1;
+}
+
+.label-header {
+    -fx-font-size: 25pt;
+    -fx-font-family: "Segoe UI";
+    -fx-text-fill: white;
+    -fx-opacity: 1;
+}
+
+.tab {
+    -fx-background-color: #3a3a3a;
+}
+
+.tab-label {
+    -fx-text-fill: white;
+}
+
+.tab:selected {
+    -fx-background-color: #4d4d4d;
+}
+
+.tab-pane *.tab-header-background {
+    -fx-background-color: #1d1d1d;
+}
+
+.list-view {
+    -fx-control-inner-background: #1d1d1d;
+    -fx-control-inner-background-alt: #333333;
+    -fx-padding: 5;
+    -fx-border-width: 0px;
+}
+
+.list-view .list-cell .label{
+    -fx-font-size: 20pt;
+    -fx-font-family: "Segoe UI Light";
+    -fx-text-fill: white;
+    -fx-alignment: center-left;
+}
+
+.list-view:focused .list-cell:filled:focused:selected {
+    -fx-background-color: -fx-focus-color;
+}
+.list-cell:highlighted{
+    -fx-text-fill: #cc7a00;
+    -fx-border-width: 1px;
+    -fx-border-color: white;
+}
+
+.table-view {
+    -fx-base: #1d1d1d;
+    -fx-control-inner-background: #1d1d1d;
+    -fx-control-inner-background-alt: #333333;
+    -fx-table-cell-border-color: transparent;
+    -fx-table-header-border-color: transparent;
+    -fx-padding: 5;
+}
+
+.table-view .column-header-background {
+    -fx-background-color: transparent;
+}
+
+.table-view .column-header, .table-view .filler {
+    -fx-size: 35px;
+    -fx-border-width: 0 0 1 0;
+    -fx-background-color: transparent;
+    -fx-border-color:
+            transparent
+            transparent
+            derive(-fx-base, 80%)
+            transparent;
+    -fx-border-insets: 0 10 1 0;
+}
+
+.table-view .column-header .label {
+    -fx-font-size: 20pt;
+    -fx-font-family: "Segoe UI Light";
+    -fx-text-fill: white;
+    -fx-alignment: center-left;
+    -fx-opacity: 1;
+}
+
+.table-view .table-row-cell {
+    -fx-control-inner-background: #1d1d1d;
+    -fx-control-inner-background-alt: #333333;
+}
+
+.table-view .table-row-cell:stock-out {
+    -fx-control-inner-background: #4d0000;
+    -fx-control-inner-background-alt: #4d0000;
+}
+
+.table-view .table-row-cell:stock-low {
+    -fx-control-inner-background: #4d2e00;
+    -fx-control-inner-background-alt: #4d2e00;
+}
+
+.table-view .table-row-cell:stock-high {
+    -fx-control-inner-background: #1a3300;
+    -fx-control-inner-background-alt: #1a3300;
+}
+
+.table-view:focused .table-row-cell:filled:focused:selected {
+    -fx-background-color: -fx-focus-color;
+}
+
+.grid-pane {
+    -fx-hgap: 10;
+    -fx-vgap: 10;
+}
+
+.context-menu {
+    -fx-background-color: derive(#1d1d1d,5%);
+}
+.text-field, .password-field, .choice-box, .text-area, .combo-box, .button {
+    -fx-font-size: 12pt;
+    -fx-font-family: "Segoe UI Semibold";
+    -fx-pref-width: 150;
+    -fx-pref-height: 30;
+    -fx-background-color: #1d1d1d;
+    -fx-border-color: #e2e2e2;
+    -fx-border-width: 2;
+    -fx-text-fill: #d8d8d8;
+}
+
+.button:hover {
+    -fx-background-color: #3a3a3a;
+}
+
+.button:pressed, .button:default:hover:pressed {
+    -fx-background-color: white;
+    -fx-text-fill: #1d1d1d;
+}
+
+.button:focused {
+    -fx-border-color: white, white;
+    -fx-border-width: 1, 1;
+    -fx-border-style: solid;
+    -fx-border-radius: 0, 0;
+    -fx-border-insets: 1 1 1 1, 0;
+}
+
+.button:disabled, .button:default:disabled {
+    -fx-opacity: 0.4;
+    -fx-background-color: #1d1d1d;
+    -fx-text-fill: white;
+}
+
+.button:default {
+    -fx-background-color: -fx-focus-color;
+    -fx-text-fill: #ffffff;
+}
+
+.button:default:hover {
+    -fx-background-color: derive(-fx-focus-color,30%);
+}
+
+.text-area .content {
+    -fx-background-color: #1d1d1d;
+    -fx-padding: 15 15 15 15;
+}
+
+#stat-screen-text-area {
+    -fx-border-width: 0;
+}
+
+.progress-indicator {
+    -fx-pref-width: 50;
+    -fx-pref-height: 50;
+}
+
+.grey-intermediary-pane {
+    -fx-background-color: #1d1d1d;
+    -fx-opacity: 85%;
+}
+
+.main-module-pane {
+    -fx-padding: 10 10 10 10;
+}
+
+.validator {
+    -fx-padding: 10 10 10 10;
+    -fx-hgap: 10;
+    -fx-vgap: 10;
+}
+.validator .button{
+    -fx-pref-width: 150;
+    -fx-pref-height: 50;
+}
+
+.sidebar {
+    -fx-background-color: #2e2e2e;
+    -fx-padding: 5 22 5 22;
+    -fx-border-color: whitesmoke;
+    -fx-border-width: 2;
+    -fx-background-radius: 0;
+    -fx-background-insets: 0 0 0 0, 0, 1, 2;
+    -pqt-expanded-width : 195px;
+}
+
+.tool-bar {
+    -fx-background-color: #2e2e2e;
+    -fx-padding: 5 5 5 5;
+    -fx-background-radius: 0;
+    -fx-background-insets: 0 0 0 0, 0, 1, 2;
+}
+
+.toast-text{
+    -fx-font: 50px "Impact";
+    -fx-fill: whitesmoke;
+}
+
+.toast-pane {
+    -fx-background-radius: 10px;
+    -fx-background-color: rgba(0, 0, 0, 0.4);
+    -fx-border-width: 2px;
+    -fx-border-color: whitesmoke;
+    -fx-border-radius: 6px;
+    -fx-padding: 25px;
+}
\ No newline at end of file
diff --git a/Workspace/core/core.iml b/Workspace/core/core.iml
new file mode 100644
index 00000000..192d284a
--- /dev/null
+++ b/Workspace/core/core.iml
@@ -0,0 +1,26 @@
+
+
+  
+    
+      
+        
+        
+        
+      
+    
+  
+  
+    
+    
+    
+      
+      
+      
+      
+    
+    
+    
+    
+    
+  
+
\ No newline at end of file
diff --git a/Workspace/core/src/main/java/com/pqt/core/communication/GSonMessageToolFactory.java b/Workspace/core/src/main/java/com/pqt/core/communication/GSonMessageToolFactory.java
index 9eac8abd..939c3bda 100644
--- a/Workspace/core/src/main/java/com/pqt/core/communication/GSonMessageToolFactory.java
+++ b/Workspace/core/src/main/java/com/pqt/core/communication/GSonMessageToolFactory.java
@@ -3,13 +3,6 @@ package com.pqt.core.communication;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.reflect.TypeToken;
-import com.pqt.core.entities.members.PqtMember;
-import com.pqt.core.entities.members.PqtMemberType;
-import com.pqt.core.entities.messages.Message;
-import com.pqt.core.entities.messages.MessageType;
-import com.pqt.core.entities.product.Product;
-import com.pqt.core.entities.product.ProductUpdate;
-import com.pqt.core.entities.sale.Sale;
 
 import java.lang.reflect.Type;
 import java.util.ArrayList;
diff --git a/Workspace/core/src/main/java/com/pqt/core/entities/members/Client.java b/Workspace/core/src/main/java/com/pqt/core/entities/members/Client.java
index a4498012..aaa92a4d 100644
--- a/Workspace/core/src/main/java/com/pqt/core/entities/members/Client.java
+++ b/Workspace/core/src/main/java/com/pqt/core/entities/members/Client.java
@@ -27,21 +27,6 @@ public class Client extends PqtMember{
         this.address = address;
     }
 
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        Client client = (Client) o;
-
-        return address.equals(client.address) && id==client.id && type.equals(client.type);
-    }
-
-    @Override
-    public int hashCode() {
-        return address.hashCode() + type.hashCode() + Integer.class.cast(id);
-    }
-
     @Override
     public int hashCode() {
         return Objects.hash(super.hashCode(), address);
diff --git a/Workspace/core/src/main/java/com/pqt/core/entities/product/Product.java b/Workspace/core/src/main/java/com/pqt/core/entities/product/Product.java
index ec5d5074..6c40e894 100644
--- a/Workspace/core/src/main/java/com/pqt/core/entities/product/Product.java
+++ b/Workspace/core/src/main/java/com/pqt/core/entities/product/Product.java
@@ -6,7 +6,7 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
-
+//TODO faire en sorte que les composés reprennent les qté dispo des composants
 /**
  * Created by Notmoo on 18/07/2017.
  */
@@ -123,6 +123,7 @@ public class Product implements ILoggable, Serializable{
         return this.id == other.id
                 && Objects.equals(this.name, other.name)
                 && Objects.equals(this.components, other.components)
-                && Objects.equals(this.category, other.category);
+                && Objects.equals(this.category, other.category)
+                && Objects.equals(this.price, other.price);
     }
 }
diff --git a/Workspace/core/src/main/java/com/pqt/core/entities/user_account/Account.java b/Workspace/core/src/main/java/com/pqt/core/entities/user_account/Account.java
index be090371..f3d7ad34 100644
--- a/Workspace/core/src/main/java/com/pqt/core/entities/user_account/Account.java
+++ b/Workspace/core/src/main/java/com/pqt/core/entities/user_account/Account.java
@@ -23,6 +23,10 @@ public class Account implements ILoggable, Serializable {
         this.permissionLevel = permissionLevel;
     }
 
+    public Account(Account account) {
+        this(account.getUsername(), account.getPassword(), account.getPermissionLevel());
+    }
+
     public String getUsername() {
         return username;
     }
@@ -49,7 +53,7 @@ public class Account implements ILoggable, Serializable {
 
     @Override
     public int hashCode() {
-        return Objects.hash(id, username, passwordHash, permissionLevel);
+        return Objects.hash(username, password, permissionLevel);
     }
 
     @Override
@@ -61,9 +65,8 @@ public class Account implements ILoggable, Serializable {
             return false;
 
         Account acc = Account.class.cast(obj);
-        return this.id == acc.id
-                && Objects.equals(this.username, acc.username)
-                && Objects.equals(this.passwordHash, acc.passwordHash)
+        return Objects.equals(this.username, acc.username)
+                && Objects.equals(this.password, acc.password)
                 && Objects.equals(this.permissionLevel, acc.permissionLevel);
     }
 }
diff --git a/Workspace/server/server.iml b/Workspace/server/server.iml
new file mode 100644
index 00000000..3284aafa
--- /dev/null
+++ b/Workspace/server/server.iml
@@ -0,0 +1,36 @@
+
+
+  
+    
+      
+        
+          
+        
+        
+          
+        
+      
+    
+  
+  
+    
+    
+    
+      
+      
+      
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+
\ No newline at end of file