├── InvMan.sqlite3 ├── src ├── main │ ├── java │ │ ├── net │ │ │ └── vatri │ │ │ │ └── inventory │ │ │ │ ├── libs │ │ │ │ ├── IMainPane.java │ │ │ │ ├── BaseController.java │ │ │ │ ├── FxPage.java │ │ │ │ ├── FxView.java │ │ │ │ └── FxPageSwitcher.java │ │ │ │ ├── controllers │ │ │ │ ├── MenuController.java │ │ │ │ ├── LoginController.java │ │ │ │ ├── StockController.java │ │ │ │ ├── GroupsController.java │ │ │ │ ├── ProductsController.java │ │ │ │ ├── DashboardController.java │ │ │ │ ├── OrdersController.java │ │ │ │ ├── AddEditProductController.java │ │ │ │ ├── AddEditGroupController.java │ │ │ │ └── AddEditOrderController.java │ │ │ │ ├── models │ │ │ │ ├── StockModel.java │ │ │ │ ├── GroupVariant.java │ │ │ │ ├── Product.java │ │ │ │ ├── OrderItem.java │ │ │ │ ├── User.java │ │ │ │ ├── ProductGroup.java │ │ │ │ └── Order.java │ │ │ │ ├── services │ │ │ │ ├── InventoryService.java │ │ │ │ └── InventoryServiceHibernate.java │ │ │ │ └── App.java │ │ └── org │ │ │ └── hibernate │ │ │ └── dialect │ │ │ ├── identity │ │ │ └── SQLiteDialectIdentityColumnSupport.java │ │ │ └── SQLiteDialect.java │ └── resources │ │ ├── views │ │ ├── StockView.fxml │ │ ├── GroupsView.fxml │ │ ├── ProductsView.fxml │ │ ├── LoginView.fxml │ │ ├── Menu.fxml │ │ ├── OrdersView.fxml │ │ ├── AddEditProductView.fxml │ │ ├── DashBoardView.fxml │ │ ├── AddEditGroupView.fxml │ │ └── AddEditOrderView.fxml │ │ └── hibernate.cfg.xml └── test │ └── java │ └── net │ └── vatri │ └── inventory │ └── services │ └── InventoryServiceHibernateTest.java ├── README.md └── pom.xml /InvMan.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vatri/InvMan/HEAD/InvMan.sqlite3 -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/libs/IMainPane.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.libs; 2 | 3 | import javafx.scene.Node; 4 | 5 | public interface IMainPane{ 6 | public void setPage(Node view); 7 | } -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/libs/BaseController.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.libs; 2 | 3 | import net.vatri.inventory.App; 4 | import net.vatri.inventory.services.InventoryService; 5 | import net.vatri.inventory.services.InventoryServiceHibernate; 6 | 7 | public abstract class BaseController { 8 | public InventoryService inventoryService = new InventoryServiceHibernate(App.getInstance().getSessionFactory()); 9 | } -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/libs/FxPage.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.libs; 2 | 3 | public class FxPage{ 4 | 5 | private String pageName, pageFile; 6 | 7 | public FxPage(String name, String file){ 8 | this.pageName = name; 9 | this.pageFile = file; 10 | } 11 | 12 | public String getPageName() { 13 | return pageName; 14 | } 15 | 16 | public void setPageName(String pageName) { 17 | this.pageName = pageName; 18 | } 19 | 20 | public String getPageFile() { 21 | return pageFile; 22 | } 23 | 24 | public void setPageFile(String pageFile) { 25 | this.pageFile = pageFile; 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/controllers/MenuController.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.controllers; 2 | 3 | import net.vatri.inventory.App; 4 | 5 | import javafx.event.ActionEvent; 6 | import javafx.fxml.FXML; 7 | 8 | public class MenuController { 9 | @FXML 10 | protected void openProducts(ActionEvent event) { 11 | App.showPage("products"); 12 | } 13 | 14 | @FXML 15 | protected void dashboardAction(ActionEvent event) { 16 | App.showPage("dashboard"); 17 | } 18 | 19 | @FXML 20 | protected void openGroups() { 21 | App.showPage("groups"); 22 | } 23 | 24 | @FXML 25 | protected void openOrders() { 26 | App.showPage("orders"); 27 | } 28 | 29 | @FXML 30 | protected void openStock() { 31 | App.showPage("stock"); 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/libs/FxView.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.libs; 2 | 3 | import javafx.fxml.FXMLLoader; 4 | import javafx.scene.layout.Pane; 5 | import net.vatri.inventory.App; 6 | 7 | import java.net.URL; 8 | 9 | public class FxView extends Pane { 10 | 11 | private Pane fxElement = null; 12 | 13 | public FxView(String fileName){ 14 | 15 | try { 16 | URL fileUrl = App.class.getResource("/views/" + fileName + ".fxml"); 17 | if(fileUrl == null){ 18 | throw new java.io.FileNotFoundException("FXML file can't be found"); 19 | } 20 | fxElement = new FXMLLoader().load(fileUrl); 21 | } catch (Exception e) { 22 | System.out.println(e.getMessage()); 23 | // System.out.println(e.printStackTrace()); 24 | // e.printStackTrace(); 25 | } 26 | } 27 | 28 | public Pane get(){ 29 | return fxElement; 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/controllers/LoginController.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.controllers; 2 | 3 | import javafx.event.ActionEvent; 4 | import javafx.fxml.FXML; 5 | import javafx.scene.control.Label; 6 | import javafx.scene.control.TextField; 7 | import javafx.scene.control.PasswordField; 8 | import net.vatri.inventory.App; 9 | import net.vatri.inventory.libs.BaseController; 10 | import net.vatri.inventory.models.User; 11 | 12 | 13 | public class LoginController extends BaseController { 14 | 15 | @FXML 16 | private TextField emailField; 17 | @FXML 18 | private PasswordField passwordField; 19 | @FXML 20 | private Label errorLabel; 21 | 22 | @FXML 23 | protected void btnLoginPressed(ActionEvent event) { 24 | User user = inventoryService.getUserByEmail(emailField.getText()); 25 | if (user.getPassword().equals(passwordField.getText())) { 26 | App.showPage("dashboard"); 27 | } else { 28 | errorLabel.setVisible(true); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/models/StockModel.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.models; 2 | 3 | public class StockModel { 4 | 5 | public String product_name = ""; 6 | public String variant_name = ""; 7 | public String stock = "0"; 8 | 9 | public StockModel(String product_name, String variant_name, String stock) { 10 | this.setProductName(product_name); 11 | this.setVariantName(variant_name); 12 | this.setStock(stock); 13 | } 14 | 15 | public String getProductName() { 16 | return product_name; 17 | } 18 | 19 | public void setProductName(String product_name) { 20 | this.product_name = product_name; 21 | } 22 | 23 | public String getVariantName() { 24 | return variant_name; 25 | } 26 | 27 | public void setVariantName(String variant_name) { 28 | this.variant_name = variant_name; 29 | } 30 | 31 | public String getStock() { 32 | return stock; 33 | } 34 | 35 | public void setStock(String stock) { 36 | this.stock = stock; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/models/GroupVariant.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.models; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | @Table(name = "group_variants") 7 | public class GroupVariant { 8 | 9 | private Integer id; 10 | private String variantName; 11 | private ProductGroup group; 12 | 13 | @Id 14 | @GeneratedValue(strategy = GenerationType.IDENTITY) 15 | public Integer getId() { 16 | return id; 17 | } 18 | 19 | public void setId(Integer id) { 20 | this.id = id; 21 | } 22 | 23 | @Column(name = "variant_name") 24 | public String getVariantName() { 25 | return variantName; 26 | } 27 | 28 | public void setVariantName(String variantName) { 29 | this.variantName = variantName; 30 | } 31 | 32 | @ManyToOne 33 | public ProductGroup getGroup() { 34 | return group; 35 | } 36 | 37 | public void setGroup(ProductGroup group) { 38 | this.group = group; 39 | } 40 | 41 | public String toString() { 42 | return getVariantName(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/libs/FxPageSwitcher.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.libs; 2 | 3 | import javafx.scene.layout.Pane; 4 | import java.util.List; 5 | 6 | public class FxPageSwitcher{ 7 | 8 | private List pages; 9 | 10 | private String currentPage; 11 | 12 | private IMainPane pane; 13 | 14 | public FxPageSwitcher(IMainPane pane, List pages){ 15 | this.pane = pane; 16 | this.pages = pages; 17 | } 18 | 19 | public void showPage(String page){ 20 | 21 | try { 22 | FxPage selectedPage = pages.stream() 23 | .filter((pg) -> pg.getPageName() == page) 24 | .findFirst() 25 | .get(); 26 | 27 | if(selectedPage == null){ 28 | System.out.println("Can't find page " + page); 29 | return ; 30 | } 31 | String viewFile = selectedPage.getPageFile(); 32 | Pane view = new FxView(viewFile).get(); 33 | pane.setPage(view); 34 | } catch (Exception e){ 35 | System.out.println("No page " + page + " please check FxPageSwitcher."); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/resources/views/StockView.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/services/InventoryService.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.services; 2 | 3 | import net.vatri.inventory.models.*; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public interface InventoryService { 9 | 10 | public User getUserByEmail(String email); 11 | 12 | // todo: offset?! 13 | public List getProducts(); 14 | 15 | public Product getProduct(String id); 16 | 17 | public boolean saveProduct(Product product); 18 | 19 | // Todo: offset + limit 20 | public List getGroups(); 21 | 22 | public ProductGroup getGroup(String id); 23 | 24 | public boolean saveGroup(ProductGroup group); 25 | 26 | public List getVariants(); 27 | 28 | public GroupVariant getVariant(String id); 29 | 30 | public boolean saveVariant(GroupVariant variant); 31 | 32 | public List getOrders(); 33 | 34 | public List getOrders(Map params); 35 | 36 | public Order getOrder(String id); 37 | 38 | public boolean saveOrder(Order order); 39 | 40 | public void removeOrderItem(OrderItem orderItem); 41 | 42 | public List getStock(); 43 | 44 | public Map getStats(); 45 | } -------------------------------------------------------------------------------- /src/main/java/org/hibernate/dialect/identity/SQLiteDialectIdentityColumnSupport.java: -------------------------------------------------------------------------------- 1 | package org.hibernate.dialect.identity; 2 | 3 | public class SQLiteDialectIdentityColumnSupport extends IdentityColumnSupportImpl { 4 | @Override 5 | public boolean supportsIdentityColumns() { 6 | return true; 7 | } 8 | 9 | /* 10 | public boolean supportsInsertSelectIdentity() { 11 | return true; // As specified in NHibernate dialect 12 | } 13 | */ 14 | 15 | @Override 16 | public boolean hasDataTypeInIdentityColumn() { 17 | // As specified in NHibernate dialect 18 | // FIXME true 19 | return false; 20 | } 21 | 22 | /* 23 | public String appendIdentitySelectToInsert(String insertString) { 24 | return new StringBuffer(insertString.length()+30). // As specified in NHibernate dialect 25 | append(insertString). 26 | append("; ").append(getIdentitySelectString()). 27 | toString(); 28 | } 29 | */ 30 | 31 | @Override 32 | public String getIdentitySelectString(String table, String column, int type) { 33 | return "select last_insert_rowid()"; 34 | } 35 | 36 | @Override 37 | public String getIdentityColumnString(int type) { 38 | // return "integer primary key autoincrement"; 39 | // FIXME "autoincrement" 40 | return "integer"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/resources/hibernate.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | org.hibernate.dialect.SQLiteDialect 8 | org.sqlite.JDBC 9 | jdbc:sqlite:InvMan.sqlite3 10 | 11 | 12 | 13 | false 14 | false 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/controllers/StockController.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.controllers; 2 | 3 | import net.vatri.inventory.models.StockModel; 4 | 5 | import net.vatri.inventory.libs.BaseController; 6 | 7 | import javafx.collections.FXCollections; 8 | import javafx.fxml.FXML; 9 | import javafx.fxml.Initializable; 10 | import javafx.scene.control.TableColumn; 11 | import javafx.scene.control.TableView; 12 | import javafx.scene.control.cell.PropertyValueFactory; 13 | 14 | import java.net.URL; 15 | import java.util.ResourceBundle; 16 | 17 | public class StockController extends BaseController implements Initializable { 18 | 19 | @FXML 20 | private TableView tblStock; 21 | @FXML 22 | private TableColumn colProduct; 23 | @FXML 24 | private TableColumn colVariant; 25 | @FXML 26 | private TableColumn colStock; 27 | 28 | public void initialize(URL url, ResourceBundle rb) { 29 | 30 | colProduct.setCellValueFactory(new PropertyValueFactory<>("productName")); 31 | colVariant.setCellValueFactory(new PropertyValueFactory<>("variantName")); 32 | colStock.setCellValueFactory(new PropertyValueFactory<>("stock")); 33 | 34 | tblStock.setItems(FXCollections.observableArrayList( 35 | inventoryService.getStock() 36 | )); 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/models/Product.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.models; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | @Table(name = "products") 7 | public class Product { 8 | 9 | private Integer id; 10 | private String name; 11 | private String created; 12 | private String price; 13 | private ProductGroup group; 14 | 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.IDENTITY) 17 | 18 | public Integer getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Integer id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name; 32 | } 33 | 34 | public String getCreated() { 35 | return created; 36 | } 37 | 38 | public void setCreated(String created) { 39 | this.created = created; 40 | } 41 | 42 | public String getPrice() { 43 | return price; 44 | } 45 | 46 | public void setPrice(String price) { 47 | this.price = price; 48 | } 49 | 50 | @ManyToOne 51 | @JoinColumn(name = "group_id") 52 | public ProductGroup getGroup() { 53 | return group; 54 | } 55 | 56 | public void setGroup(ProductGroup group) { 57 | this.group = group; 58 | } 59 | 60 | public String toString() { 61 | return getName(); 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # InvMan 2 | 3 | Simple desktop multi-platform JavaFX inventory management application. 4 | 5 | ## MIT LICENCE 6 | 7 | https://opensource.org/licenses/MIT 8 | 9 | Totaly free to use, modify, sell, etc. 10 | 11 | ## FEATURES 12 | 13 | - Dashboard/stats 14 | - Manage products 15 | - Manage product groups 16 | - Manage product group variants 17 | - Manage orders 18 | - Sell and buy type of order 19 | - Stock preview 20 | 21 | ## SCREENSHOTS 22 | 23 | See here: https://drive.google.com/drive/folders/0BxIbA3Gdn5AQa1ZMa2FHTlRPRms?resourcekey=0-_nDXwaHRV7ZtLQY9lU7vIg&usp=sharing 24 | 25 | ## INSTALL 26 | 27 | ### REQUIREMENTS 28 | 29 | - Maven 30 | - Java 1.8 (not tested in older versions yet) 31 | 32 | ### DOWNLOAD, COMPILE AND RUN (using Maven) 33 | 34 | ``` 35 | git clone [this repo URL] 36 | cd [cloned-dir] 37 | mvn compile 38 | mvn exec:java 39 | ``` 40 | ### LOGIN 41 | 42 | The credentials for login are defined in users table in the SQL file placed in the root directory. 43 | By default use following: 44 | 45 | ``` 46 | username: b 47 | pass: b 48 | ``` 49 | 50 | ## CHANGELOG 51 | 52 | ### 1.2.1 53 | 54 | - Added Hibernate ORM 55 | 56 | 57 | ## ROADMAP 58 | 59 | ### PHASE 1 60 | 61 | - [x] Basic dashboard 62 | - [x] Product management 63 | - [x] Product group management 64 | - [x] Orders management 65 | - [x] Stock list 66 | 67 | ### PHASE 2 68 | 69 | - [ ] Unit tests 70 | - [x] Use Hibernate ORM 71 | - [ ] Speed improvement 72 | - [ ] ??? 73 | -------------------------------------------------------------------------------- /src/main/resources/views/GroupsView.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 26 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/resources/views/Menu.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 25 | 30 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/main/java/net/vatri/inventory/controllers/GroupsController.java: -------------------------------------------------------------------------------- 1 | package net.vatri.inventory.controllers; 2 | 3 | import javafx.fxml.Initializable; 4 | import javafx.fxml.FXML; 5 | import javafx.scene.control.TableView; 6 | 7 | import java.net.URL; 8 | import java.util.ResourceBundle; 9 | 10 | import javafx.scene.control.TableColumn; 11 | 12 | import javafx.scene.control.Button; 13 | import javafx.collections.ObservableList; 14 | import javafx.collections.FXCollections; 15 | import javafx.scene.control.cell.PropertyValueFactory; 16 | 17 | import net.vatri.inventory.App; 18 | import net.vatri.inventory.libs.BaseController; 19 | import net.vatri.inventory.models.ProductGroup; 20 | 21 | public class GroupsController extends BaseController implements Initializable { 22 | 23 | @FXML 24 | private TableView tblGroups; 25 | @FXML 26 | private TableColumn idCol; 27 | @FXML 28 | private TableColumn groupCol; 29 | @FXML 30 | private TableColumn priceCol; 31 | @FXML 32 | private Button btnAddGroup; 33 | 34 | public void initialize(URL url, ResourceBundle rb) { 35 | 36 | ObservableList tblData = FXCollections.observableArrayList( 37 | inventoryService.getGroups() 38 | ); 39 | 40 | idCol.setCellValueFactory(new PropertyValueFactory<>("id")); 41 | groupCol.setCellValueFactory(new PropertyValueFactory<>("groupName")); 42 | priceCol.setCellValueFactory(new PropertyValueFactory<>("price")); 43 | 44 | tblGroups.setItems(tblData); 45 | }// all() 46 | 47 | @FXML 48 | protected void openGroup() { 49 | ProductGroup group = tblGroups.getSelectionModel().getSelectedItem(); 50 | if (group != null) { 51 | App.getInstance().repository.put("selectedGroupId", group.getId().toString()); 52 | App.showPage("addEditGroup"); 53 | } 54 | } 55 | 56 | @FXML 57 | protected void handleAddGroup() { 58 | // Since we are adding group, set selected ID to null 59 | App.getInstance().repository.put("selectedGroupId", null); 60 | App.showPage("addEditGroup"); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/resources/views/OrdersView.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 28 | 32 |