├── stockmanagementsystem-frontend ├── src │ ├── configs │ │ ├── index.ts │ │ ├── service.ts │ │ └── api.ts │ ├── components │ │ ├── atoms │ │ │ └── index.tsx │ │ ├── molecules │ │ │ ├── index.tsx │ │ │ └── SpecialButton.tsx │ │ ├── template │ │ │ └── index.tsx │ │ └── organism │ │ │ ├── menu │ │ │ ├── index.ts │ │ │ └── ToggleMenu.tsx │ │ │ ├── expansion_panel │ │ │ ├── index.tsx │ │ │ └── SimpleExpansionPanel.tsx │ │ │ ├── dialog │ │ │ ├── index.tsx │ │ │ ├── ResponsiveDialog.tsx │ │ │ └── AlertDialog.tsx │ │ │ ├── index.tsx │ │ │ ├── form │ │ │ ├── index.ts │ │ │ ├── PayTypeForm.tsx │ │ │ ├── CustomerForm.tsx │ │ │ └── TransactionDetailForm.tsx │ │ │ ├── snackbar │ │ │ └── Snackbar.tsx │ │ │ └── sidebar │ │ │ └── SidebarList.tsx │ ├── data │ │ ├── interfaces │ │ │ ├── ILogin.ts │ │ │ ├── paymentTypes │ │ │ │ └── IPaymentType.ts │ │ │ ├── ICRUD.ts │ │ │ ├── items │ │ │ │ ├── IDeleteItem.ts │ │ │ │ ├── IIndexItem.ts │ │ │ │ ├── IItem.ts │ │ │ │ └── IUpsertItem.ts │ │ │ ├── productions │ │ │ │ ├── IUpsertProduction.ts │ │ │ │ ├── IProduction.ts │ │ │ │ └── IIndexProduction.ts │ │ │ ├── customers │ │ │ │ ├── ICustomer.ts │ │ │ │ ├── IIndexCustomer.ts │ │ │ │ └── IUpsertCustomer.ts │ │ │ ├── transactions │ │ │ │ ├── IUpsertTransaction.ts │ │ │ │ ├── IIndexTransaction.ts │ │ │ │ └── ITransaction.ts │ │ │ └── index.ts │ │ └── services │ │ │ ├── LoginService.ts │ │ │ ├── PaymentTypeService.ts │ │ │ ├── ProductionService.ts │ │ │ ├── CustomerService.ts │ │ │ ├── index.ts │ │ │ ├── ItemService.ts │ │ │ └── TransaactionService.ts │ ├── assets │ │ └── imgs │ │ │ └── josephlogo.png │ ├── pages │ │ ├── About.tsx │ │ ├── Post.tsx │ │ └── Home.tsx │ └── index.tsx ├── .env ├── .babelrc ├── server.js ├── .gitignore ├── webpack.config.js ├── index.html └── package.json ├── StockManagementSystem ├── system.properties ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.properties │ │ │ ├── db │ │ │ │ └── migration │ │ │ │ │ ├── V3__InitializePayments.sql │ │ │ │ │ ├── V1__InitializeCustomers.sql │ │ │ │ │ ├── V2__InitializeItems.sql │ │ │ │ │ ├── V4__InitializeProductions.sql │ │ │ │ │ ├── V6__InitializeTransactionDetails.sql │ │ │ │ │ ├── V5__InitializeTransactionHeaders.sql │ │ │ │ │ └── V7__InitializeUsers.sql │ │ │ ├── application.yml │ │ │ ├── ItemPDF.hbs │ │ │ └── TransactionPDF.hbs │ │ └── java │ │ │ └── com │ │ │ └── joshua │ │ │ └── StockManagementSystem │ │ │ ├── joseph_impl │ │ │ ├── domain │ │ │ │ ├── HandlebarsHelper.java │ │ │ │ ├── ReportEngine.java │ │ │ │ ├── PaymentServiceImpl.java │ │ │ │ └── ProductionServiceImpl.java │ │ │ ├── infrastructure │ │ │ │ ├── HttpStatus.java │ │ │ │ ├── flushout │ │ │ │ │ ├── JosephDataEntity.java │ │ │ │ │ ├── PaymentDataEntity.java │ │ │ │ │ ├── CustomerDataEntity.java │ │ │ │ │ ├── ProductionDataEntity.java │ │ │ │ │ ├── ItemDataEntity.java │ │ │ │ │ ├── TransactionDetailDataEntity.java │ │ │ │ │ ├── TransactionHeaderDataEntity.java │ │ │ │ │ └── UserDataEntity.java │ │ │ │ ├── dao │ │ │ │ │ ├── PostgresDataSource.java │ │ │ │ │ ├── spec │ │ │ │ │ │ └── TransactionSpec.java │ │ │ │ │ ├── PaymentDataAccessService.java │ │ │ │ │ ├── ItemDataAccessService.java │ │ │ │ │ ├── CustomerDataAccessService.java │ │ │ │ │ └── ProductionDataService.java │ │ │ │ ├── adapter │ │ │ │ │ ├── PaymentAdapter.java │ │ │ │ │ ├── UserAdapter.java │ │ │ │ │ ├── CustomerAdapter.java │ │ │ │ │ ├── ItemAdapter.java │ │ │ │ │ └── ProductionAdapter.java │ │ │ │ └── PostgresHelper.java │ │ │ └── api │ │ │ │ ├── PaymentAPIControllerImpl.java │ │ │ │ ├── CustomerAPIControllerImpl.java │ │ │ │ ├── ItemAPIControllerImpl.java │ │ │ │ └── TransactionAPIControllerImpl.java │ │ │ ├── auth │ │ │ ├── UserDAO.java │ │ │ ├── UserService.java │ │ │ ├── UserPostgresDataService.java │ │ │ ├── UserDataAccessService.java │ │ │ └── User.java │ │ │ ├── StockManagementSystemApplication.java │ │ │ ├── util │ │ │ └── Pair.java │ │ │ ├── joseph_api │ │ │ ├── api │ │ │ │ ├── payload │ │ │ │ │ ├── index │ │ │ │ │ │ ├── IndexItemResponsePayload.java │ │ │ │ │ │ ├── IndexCustomerResponsePayload.java │ │ │ │ │ │ ├── IndexPayTypeResponsePayload.java │ │ │ │ │ │ ├── IndexProductionRequestPayload.java │ │ │ │ │ │ ├── IndexTransactionResponsePayload.java │ │ │ │ │ │ ├── IndexItemRequestPayload.java │ │ │ │ │ │ └── IndexTransactionRequestPayload.java │ │ │ │ │ ├── upsert │ │ │ │ │ │ ├── UpsertPaymentRequestPayload.java │ │ │ │ │ │ ├── UpsertTransactionDetailRequestPayload.java │ │ │ │ │ │ ├── UpsertCustomerRequestPayload.java │ │ │ │ │ │ ├── UpsertProductionRequestPayload.java │ │ │ │ │ │ ├── UpsertItemRequestPayload.java │ │ │ │ │ │ └── UpsertTransactionHeaderRequestPayload.java │ │ │ │ │ └── ResponsePayload.java │ │ │ │ ├── ProductionAPIController.java │ │ │ │ ├── PaymentAPIController.java │ │ │ │ ├── CustomerAPIController.java │ │ │ │ ├── ItemAPIController.java │ │ │ │ └── TransactionAPIController.java │ │ │ ├── infrastructure │ │ │ │ └── dao │ │ │ │ │ ├── ItemDAO.java │ │ │ │ │ ├── PaymentDAO.java │ │ │ │ │ ├── ProductionDAO.java │ │ │ │ │ ├── CustomerDAO.java │ │ │ │ │ └── TransactionDAO.java │ │ │ ├── model │ │ │ │ ├── Payment.java │ │ │ │ ├── Customer.java │ │ │ │ ├── Production.java │ │ │ │ ├── TransactionDetail.java │ │ │ │ ├── Item.java │ │ │ │ └── TransactionHeader.java │ │ │ └── domain │ │ │ │ ├── ProductionService.java │ │ │ │ ├── CustomerService.java │ │ │ │ ├── PaymentService.java │ │ │ │ ├── ItemService.java │ │ │ │ └── TransactionService.java │ │ │ ├── security │ │ │ ├── PasswordConfig.java │ │ │ ├── UserPermission.java │ │ │ └── UserRole.java │ │ │ └── jwt │ │ │ ├── UsernamePasswordAuthRequestPayload.java │ │ │ ├── JwtSecretKey.java │ │ │ ├── JwtConfig.java │ │ │ ├── JwtTokenVerifier.java │ │ │ └── JwtUsernamePasswordAuthFilter.java │ └── test │ │ └── java │ │ └── com │ │ └── joshua │ │ └── StockManagementSystem │ │ └── StockManagementSystemApplicationTests.java ├── Procfile ├── web │ └── generatedpdf │ │ ├── ItemReport.pdf │ │ └── TransactionReport.pdf ├── target │ ├── classes │ │ └── com │ │ │ └── joshua │ │ │ └── StockManagementSystem │ │ │ └── StockManagementSystemApplication.class │ └── test-classes │ │ └── com │ │ └── joshua │ │ └── StockManagementSystem │ │ └── StockManagementSystemApplicationTests.class ├── .gitignore └── HELP.md ├── StockManagementSystem_v2.png ├── .gitignore ├── .github └── workflows │ ├── frontend-heroku.yml │ └── backend-heroku.yml ├── README.md └── StockManagementSystem.sql /stockmanagementsystem-frontend/src/configs/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /StockManagementSystem/system.properties: -------------------------------------------------------------------------------- 1 | maven.version=3.6.2 -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/.env: -------------------------------------------------------------------------------- 1 | # NODE_ENV=production -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/atoms/index.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/molecules/index.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=${PORT:8080} 2 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/template/index.tsx: -------------------------------------------------------------------------------- 1 | export { Dashboard } from './Dashboard'; -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/menu/index.ts: -------------------------------------------------------------------------------- 1 | export { ToggleMenu } from './ToggleMenu' -------------------------------------------------------------------------------- /StockManagementSystem/Procfile: -------------------------------------------------------------------------------- 1 | web: java $JAVA_OPTS -jar jars/StockManagementSystem-0.0.1-SNAPSHOT.jar -Dserver.port=$PORT -------------------------------------------------------------------------------- /StockManagementSystem_v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshEvan/StockManagementSystem/HEAD/StockManagementSystem_v2.png -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/expansion_panel/index.tsx: -------------------------------------------------------------------------------- 1 | export { SimpleExpansionPanel } from './SimplExpansionPanel'; -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/ILogin.ts: -------------------------------------------------------------------------------- 1 | export interface ILoginRequest{ 2 | username: string, 3 | password: string 4 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/paymentTypes/IPaymentType.ts: -------------------------------------------------------------------------------- 1 | export interface IPayemntType{ 2 | id: string, 3 | paymentType: string 4 | } -------------------------------------------------------------------------------- /StockManagementSystem/web/generatedpdf/ItemReport.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshEvan/StockManagementSystem/HEAD/StockManagementSystem/web/generatedpdf/ItemReport.pdf -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/dialog/index.tsx: -------------------------------------------------------------------------------- 1 | export { AlertDialog } from './AlertDialog'; 2 | export { ResponsiveDialog } from './ResponsiveDialog'; -------------------------------------------------------------------------------- /StockManagementSystem/web/generatedpdf/TransactionReport.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshEvan/StockManagementSystem/HEAD/StockManagementSystem/web/generatedpdf/TransactionReport.pdf -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/assets/imgs/josephlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshEvan/StockManagementSystem/HEAD/stockmanagementsystem-frontend/src/assets/imgs/josephlogo.png -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/ICRUD.ts: -------------------------------------------------------------------------------- 1 | import { HTTPCallStatus } from "."; 2 | 3 | export interface ICRUDResponse{ 4 | status: HTTPCallStatus, 5 | data:string[] 6 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/items/IDeleteItem.ts: -------------------------------------------------------------------------------- 1 | import { HTTPCallStatus } from ".."; 2 | 3 | export interface IDeleteItemResponse{ 4 | status: HTTPCallStatus, 5 | data:string[] 6 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/productions/IUpsertProduction.ts: -------------------------------------------------------------------------------- 1 | import { ICRUDResponse } from "../ICRUD"; 2 | 3 | export interface IUpsertProductionResponse extends ICRUDResponse{ 4 | 5 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/env","@babel/react","@babel/typescript"], 3 | "plugins": ["transform-class-properties"] 4 | } 5 | // plugin yg dibutuhkan, khusus ini harus " ga bisa ' -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/domain/HandlebarsHelper.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.domain; 2 | 3 | public class HandlebarsHelper { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/customers/ICustomer.ts: -------------------------------------------------------------------------------- 1 | export interface ICustomer{ 2 | id: string, 3 | name:string, 4 | description:string, 5 | contact:string, 6 | totalAmountSpend:number 7 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/customers/IIndexCustomer.ts: -------------------------------------------------------------------------------- 1 | import { ICustomer } from './ICustomer' 2 | 3 | export interface IIndexCustomerResponse{ 4 | data: { 5 | customers:ICustomer[] 6 | } 7 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/productions/IProduction.ts: -------------------------------------------------------------------------------- 1 | export interface IProduction{ 2 | id: string, 3 | itemCode: string, 4 | producer: string, 5 | productionDate: Date, 6 | quantity: number 7 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/HttpStatus.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure; 2 | 3 | public enum HttpStatus{ 4 | SUCCESS, 5 | FAIL 6 | } 7 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/productions/IIndexProduction.ts: -------------------------------------------------------------------------------- 1 | import { IProduction } from "./IProduction"; 2 | 3 | export interface IIndexProductionResponse { 4 | data :{ 5 | productions:IProduction[] 6 | } 7 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/configs/service.ts: -------------------------------------------------------------------------------- 1 | export const serviceConfigCommon = { 2 | withCredentials: false, 3 | headers:{ 4 | 'Content-Type':'application/json', 5 | 'Authorization':'Bearer '+localStorage.getItem("JWT") 6 | }, 7 | } -------------------------------------------------------------------------------- /StockManagementSystem/target/classes/com/joshua/StockManagementSystem/StockManagementSystemApplication.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshEvan/StockManagementSystem/HEAD/StockManagementSystem/target/classes/com/joshua/StockManagementSystem/StockManagementSystemApplication.class -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/db/migration/V3__InitializePayments.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE if not exists payments( 2 | id varchar PRIMARY KEY NOT NULL, 3 | payment_type VARCHAR, 4 | timestamp timestamp default current_timestamp, 5 | is_active boolean DEFAULT TRUE 6 | ); -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/index.tsx: -------------------------------------------------------------------------------- 1 | export { mainListItems, secondaryListItems} from './sidebar/SidebarList'; 2 | export { CustomTable } from './CustomTable'; 3 | export { AlertDialog } from './dialog'; 4 | export { CustomizedSnackbars } from './snackbar/Snackbar'; -------------------------------------------------------------------------------- /StockManagementSystem/target/test-classes/com/joshua/StockManagementSystem/StockManagementSystemApplicationTests.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshEvan/StockManagementSystem/HEAD/StockManagementSystem/target/test-classes/com/joshua/StockManagementSystem/StockManagementSystemApplicationTests.class -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/form/index.ts: -------------------------------------------------------------------------------- 1 | export { ItemForm } from './ItemForm'; 2 | export { CustomerForm } from './CustomerForm'; 3 | export { ProductionForm } from './ProductionForm'; 4 | export { PayTypeForm } from './PayTypeForm'; 5 | export { TransactionForm } from './TransactionForm'; -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/db/migration/V1__InitializeCustomers.sql: -------------------------------------------------------------------------------- 1 | create table customers( 2 | id varchar PRIMARY KEY NOT NULL, 3 | name varchar, 4 | description varchar, 5 | contact varchar, 6 | timestamp timestamp default current_timestamp, 7 | is_active boolean DEFAULT TRUE 8 | ); -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/auth/UserDAO.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.auth; 2 | 3 | import org.springframework.stereotype.Repository; 4 | 5 | import java.util.Optional; 6 | 7 | public interface UserDAO { 8 | public Optional selectUserByUsername(String username); 9 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/items/IIndexItem.ts: -------------------------------------------------------------------------------- 1 | import { IItem } from "./IItem"; 2 | 3 | export interface IIndexItemRequest{ 4 | sortByItemCode:number, 5 | sortByAmountIncome:number, 6 | sortByAmountSold:number 7 | } 8 | 9 | export interface IIndexItemResponse{ 10 | data:{items:IItem[]} 11 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/items/IItem.ts: -------------------------------------------------------------------------------- 1 | interface IItem{ 2 | itemCode:string, 3 | name:string, 4 | description:string, 5 | price:string, 6 | stock:number, 7 | capacity:number, 8 | totalSold:number, 9 | incomeAmountDec:any, 10 | incomeAmount:string, 11 | priceDec:any 12 | } 13 | 14 | export { IItem }; -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/customers/IUpsertCustomer.ts: -------------------------------------------------------------------------------- 1 | import { HTTPCallStatus } from ".."; 2 | 3 | export interface IUpsertCustomerRequest{ 4 | id:string, 5 | name:string, 6 | description:string, 7 | contact:string 8 | } 9 | 10 | export interface IUpsertCustomerResponse{ 11 | status: HTTPCallStatus, 12 | data:string[] 13 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/db/migration/V2__InitializeItems.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE if not exists items( 2 | item_code varchar NOT NULL PRIMARY KEY, 3 | name varchar(100), 4 | description varchar, 5 | price numeric, 6 | stock int, 7 | capacity int, 8 | timestamp timestamp default current_timestamp, 9 | is_active boolean DEFAULT TRUE 10 | ); 11 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/db/migration/V4__InitializeProductions.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE if not exists productions( 2 | id varchar NOT NULL PRIMARY KEY, 3 | item_code varchar REFERENCES items(item_code), 4 | production_date DATE, 5 | producer varchar, 6 | quantity int, 7 | timestamp timestamp default current_timestamp, 8 | is_active boolean DEFAULT TRUE 9 | ); -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | app: 2 | datasource: 3 | jdbc-url: ${JDBC_DATABASE_URL} 4 | username: ${JDBC_DATABASE_USERNAME} 5 | password: ${JDBC_DATABASE_PASSWORD} 6 | pool-size: 30 7 | 8 | application: 9 | jwt: 10 | secretKey: ${JWT_SECRET} 11 | tokenPrefix: Bearer 12 | tokenExpirationAfterDays: 1 13 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/items/IUpsertItem.ts: -------------------------------------------------------------------------------- 1 | import { HTTPCallStatus } from ".."; 2 | 3 | export interface IUpsertItemRequest{ 4 | itemCode:string, 5 | name:string, 6 | description:string, 7 | price:number, 8 | stock:number, 9 | capacity:number 10 | } 11 | 12 | export interface IUpsertItemResponse{ 13 | status: HTTPCallStatus, 14 | data:string[] 15 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/test/java/com/joshua/StockManagementSystem/StockManagementSystemApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class StockManagementSystemApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/flushout/JosephDataEntity.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout; 2 | 3 | public abstract class JosephDataEntity { 4 | public final String SCHEMA = "joseph_user,public"; 5 | public String TABLE; 6 | public int numColumns; 7 | public static String ISACTIVE = "is_active"; 8 | } 9 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/db/migration/V6__InitializeTransactionDetails.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE if not exists transaction_details( 2 | transaction_header_id varchar NOT NULL REFERENCES transaction_headers(id), 3 | item_code varchar NOT NULL REFERENCES items(item_code), 4 | price numeric, 5 | quantity int, 6 | note varchar, 7 | timestamp timestamp default current_timestamp, 8 | is_active boolean DEFAULT TRUE 9 | ); -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/db/migration/V5__InitializeTransactionHeaders.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE if not exists transaction_headers( 2 | id varchar PRIMARY KEY NOT NULL, 3 | customer_id varchar REFERENCES customers(id), 4 | payment_id varchar REFERENCES payments(id), 5 | transaction_date DATE, 6 | payment_status varchar, 7 | note varchar, 8 | timestamp timestamp default current_timestamp, 9 | is_active boolean DEFAULT TRUE 10 | ); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/transactions/IUpsertTransaction.ts: -------------------------------------------------------------------------------- 1 | export interface IUpsertTransactionRequest{ 2 | id:string, 3 | customerId:string, 4 | paymentId:string, 5 | transactionDate:string, 6 | paymentStatus:string, 7 | note:string, 8 | transactionDetails:IUpsertTransactionDetailRequest[] 9 | } 10 | 11 | export interface IUpsertTransactionDetailRequest{ 12 | itemCode:string, 13 | quantity:number, 14 | note:string 15 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/StockManagementSystemApplication.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class StockManagementSystemApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(StockManagementSystemApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/pages/About.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router-dom'; 3 | 4 | interface Props {}; 5 | 6 | const postId = 5; 7 | export default class About extends React.Component { 8 | render(){ 9 | return ( 10 |
11 |
12 | about 13 |
14 | go to post {{postId}} 15 |
16 | )} 17 | }; 18 | 19 | export { About }; -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/db/migration/V7__InitializeUsers.sql: -------------------------------------------------------------------------------- 1 | DROP TYPE IF EXISTS user_role; 2 | CREATE TYPE user_role AS ENUM('STRANGER', 'MEMBER', 'ADMIN'); 3 | 4 | CREATE TABLE if not exists users( 5 | username varchar NOT NULL PRIMARY KEY, 6 | password varchar, 7 | role user_role, 8 | is_account_non_expired boolean DEFAULT TRUE, 9 | is_account_non_locked boolean DEFAULT TRUE, 10 | is_credential_non_expired boolean DEFAULT TRUE, 11 | is_enabled boolean DEFAULT TRUE 12 | ); 13 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/molecules/SpecialButton.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { withRouter } from 'react-router-dom' 3 | 4 | interface Props {} 5 | 6 | // pake history, location, match dari parent component nya 7 | 8 | export const SpecialButton = withRouter(({history}) => { 9 | return ( 10 |
11 | 16 |
17 | ); 18 | }); 19 | -------------------------------------------------------------------------------- /StockManagementSystem/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | !target/StockManagementSystem-0.0.1-SNAPSHOT-exec.jar 3 | target/ 4 | !.mvn/wrapper/maven-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | .env** 8 | 9 | ### STS ### 10 | .apt_generated 11 | .classpath 12 | .factorypath 13 | .project 14 | .settings 15 | .springBeans 16 | .sts4-cache 17 | 18 | ### IntelliJ IDEA ### 19 | .idea 20 | *.iws 21 | *.iml 22 | *.ipr 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/util/Pair.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.util; 2 | 3 | public class Pair { 4 | private K key; 5 | private V value; 6 | 7 | public Pair(K key, V value) { 8 | this.key = key; 9 | this.value = value; 10 | } 11 | public K getKey() { 12 | return key; 13 | } 14 | 15 | public void setKey(K key) { 16 | this.key = key; 17 | } 18 | 19 | public V getValue() { 20 | return value; 21 | } 22 | 23 | public void setValue(V value) { 24 | this.value = value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/index/IndexItemResponsePayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.index; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.model.Item; 4 | 5 | import java.util.List; 6 | 7 | public class IndexItemResponsePayload { 8 | List items; 9 | 10 | public List getItems() { 11 | return items; 12 | } 13 | 14 | public IndexItemResponsePayload setItems(List items) { 15 | this.items = items;return this; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/transactions/IIndexTransaction.ts: -------------------------------------------------------------------------------- 1 | export interface IIndexTransactionRequest{ 2 | customerFilter: string[], 3 | itemFilter:string[], 4 | paymentFilter: string[], 5 | dateFilter:string, 6 | endDateFilter:string, 7 | sortByDate:number, 8 | sortByTotal:number 9 | } 10 | 11 | export const getInitIndexTransactionRequest = () : IIndexTransactionRequest => ({ 12 | customerFilter: [], 13 | itemFilter:[], 14 | paymentFilter: [], 15 | dateFilter:"", 16 | endDateFilter:"", 17 | sortByDate:0, 18 | sortByTotal:0 19 | }) 20 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/infrastructure/dao/ItemDAO.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.infrastructure.dao; 2 | 3 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.ItemDataEntity; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | public interface ItemDAO { 9 | Integer insert(ItemDataEntity itemDataEntity); 10 | List index(); 11 | Optional show(String id); 12 | Integer update(ItemDataEntity itemDataEntity); 13 | Integer delete(String idItem); 14 | } 15 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/pages/Post.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { RouteComponentProps } from 'react-router' 3 | 4 | // <{objparam}> 5 | interface Props extends RouteComponentProps<{id:string}>{}; 6 | 7 | export const Post: React.FC = ({ match }) => { 8 | console.log(match); 9 | // contoh: 10 | // React.useEffect(() =>{ 11 | // fetch(`api.example.com/posts/${match.params.id}`) 12 | // }, 13 | // [match.params.id] 14 | // ) 15 | 16 | return ( 17 |
18 | rendering post {match.params.id} 19 |
20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/model/Payment.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.model; 2 | 3 | public class Payment { 4 | private String id, paymentType; 5 | 6 | public String getId() { 7 | return id; 8 | } 9 | 10 | public Payment setId(String id) { 11 | this.id = id;return this; 12 | } 13 | 14 | public String getPaymentType() { 15 | return paymentType; 16 | } 17 | 18 | public Payment setPaymentType(String paymentType) { 19 | this.paymentType = paymentType;return this; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/index/IndexCustomerResponsePayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.index; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.model.Customer; 4 | 5 | import java.util.List; 6 | 7 | public class IndexCustomerResponsePayload { 8 | List customers; 9 | 10 | public List getCustomers() { 11 | return customers; 12 | } 13 | 14 | public IndexCustomerResponsePayload setCustomers(List customers) { 15 | this.customers = customers;return this; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/security/PasswordConfig.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.security; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 6 | import org.springframework.security.crypto.password.PasswordEncoder; 7 | 8 | @Configuration 9 | public class PasswordConfig { 10 | 11 | @SuppressWarnings("deprecation") 12 | @Bean 13 | public PasswordEncoder passwordEncoder(){ 14 | return new BCryptPasswordEncoder(10); 15 | } 16 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/index/IndexPayTypeResponsePayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.index; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.model.Payment; 4 | 5 | import java.util.List; 6 | 7 | public class IndexPayTypeResponsePayload { 8 | List paymentTypes; 9 | 10 | public List getPaymentTypes() { 11 | return paymentTypes; 12 | } 13 | 14 | public IndexPayTypeResponsePayload setPaymentTypes(List paymentTypes) { 15 | this.paymentTypes = paymentTypes;return this; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/infrastructure/dao/PaymentDAO.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.infrastructure.dao; 2 | 3 | 4 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.PaymentDataEntity; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | public interface PaymentDAO { 10 | Integer insert(PaymentDataEntity paymentDataEntity); 11 | List index(); 12 | Optional show(String id); 13 | Integer update(PaymentDataEntity paymentDataEntity); 14 | Integer delete(String idItem); 15 | } 16 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/services/LoginService.ts: -------------------------------------------------------------------------------- 1 | import { Observable, BehaviorSubject } from "rxjs"; 2 | import Axios from "axios-observable"; 3 | import { getLoginUrl } from "../../configs/api"; 4 | import { ILoginRequest } from "../interfaces"; 5 | 6 | // const currentUserSubject = new BehaviorSubject(JSON.parse(localStorage.getItem('loggedInUser'))); 7 | 8 | export const serviceLogin = (dataPayload: ILoginRequest): Observable => { 9 | return Axios.post( 10 | getLoginUrl(), 11 | dataPayload 12 | ) 13 | } 14 | 15 | export const setBehaviorSubject = (user) => { 16 | // currentUserSubject.next(user) 17 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/index/IndexProductionRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.index; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.model.Production; 4 | 5 | import java.util.List; 6 | 7 | public class IndexProductionRequestPayload { 8 | List productions; 9 | 10 | public List getProductions() { 11 | return productions; 12 | } 13 | 14 | public IndexProductionRequestPayload setProductions(List productions) { 15 | this.productions = productions;return this; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/infrastructure/dao/ProductionDAO.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.infrastructure.dao; 2 | 3 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.ProductionDataEntity; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | public interface ProductionDAO { 9 | Integer insert(ProductionDataEntity productionDataEntity); 10 | List index(); 11 | Optional show(String id); 12 | Integer update(ProductionDataEntity productionDataEntity); 13 | Integer delete(String idItem); 14 | } 15 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/jwt/UsernamePasswordAuthRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.jwt; 2 | 3 | public class UsernamePasswordAuthRequestPayload { 4 | private String username, password; 5 | 6 | public UsernamePasswordAuthRequestPayload() { 7 | } 8 | 9 | public String getUsername() { 10 | return username; 11 | } 12 | 13 | public void setUsername(String username) { 14 | this.username = username; 15 | } 16 | 17 | public String getPassword() { 18 | return password; 19 | } 20 | 21 | public void setPassword(String password) { 22 | this.password = password; 23 | } 24 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/index/IndexTransactionResponsePayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.index; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.model.TransactionHeader; 4 | 5 | import java.util.List; 6 | 7 | public class IndexTransactionResponsePayload { 8 | List transactions; 9 | 10 | public List getTransactions() { 11 | return transactions; 12 | } 13 | 14 | public IndexTransactionResponsePayload setTransactions(List transactions) { 15 | this.transactions = transactions; return this; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/upsert/UpsertPaymentRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.upsert; 2 | 3 | public class UpsertPaymentRequestPayload { 4 | private String id, paymentType; 5 | 6 | public String getId() { 7 | return id; 8 | } 9 | 10 | public UpsertPaymentRequestPayload setId(String id) { 11 | this.id = id;return this; 12 | } 13 | 14 | public String getPaymentType() { 15 | return paymentType; 16 | } 17 | 18 | public UpsertPaymentRequestPayload setPaymentType(String paymentType) { 19 | this.paymentType = paymentType;return this; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/ResponsePayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload; 2 | 3 | import java.util.List; 4 | 5 | public class ResponsePayload { 6 | private String status; 7 | private List message; 8 | 9 | public String getStatus() { 10 | return status; 11 | } 12 | 13 | public ResponsePayload setStatus(String status) { 14 | this.status = status;return this; 15 | } 16 | 17 | public List getMessage() { 18 | return message; 19 | } 20 | 21 | public ResponsePayload setMessage(List message) { 22 | this.message = message;return this; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/infrastructure/dao/CustomerDAO.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.infrastructure.dao; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.model.Customer; 4 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.CustomerDataEntity; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | public interface CustomerDAO { 10 | Integer insert(CustomerDataEntity customer); 11 | List index(); 12 | Optional show(String id); 13 | Integer update(CustomerDataEntity customer); 14 | Integer delete(String idCust); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const path = require('path'); 3 | const port = process.env.PORT || 5001; 4 | const app = express(); 5 | 6 | // require('dotenv').config(); // not working 7 | 8 | api_url = process.env.NODE_ENV 9 | const _env = app.get('env'); 10 | 11 | // the __dirname is the current directory from where the script is running 12 | app.use(express.static(__dirname)); 13 | 14 | // send the user to index html page inspite of the url 15 | app.get('*', (req, res) => { 16 | res.sendFile(path.resolve(__dirname, 'index.html')); 17 | }); 18 | 19 | app.listen(port, () => { 20 | console.log(`Server is running on port ${port}. ${api_url} ${_env}`) 21 | }); 22 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/jwt/JwtSecretKey.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.jwt; 2 | 3 | import io.jsonwebtoken.security.Keys; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | import javax.crypto.SecretKey; 9 | 10 | @Configuration 11 | public class JwtSecretKey { 12 | 13 | private final JwtConfig jwtConfig; 14 | 15 | @Autowired 16 | public JwtSecretKey(JwtConfig jwtConfig) { 17 | this.jwtConfig = jwtConfig; 18 | } 19 | 20 | @Bean 21 | public SecretKey secretKey(){ 22 | return Keys.hmacShaKeyFor(jwtConfig.getSecretKey().getBytes()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/security/UserPermission.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.security; 2 | 3 | public enum UserPermission { 4 | TRANS_WRITE("transaction:write"), 5 | TRANS_READ("transaction:read"), 6 | PROD_READ("production:read"), 7 | PROD_WRITE("production:write"), 8 | CUST_READ("customer:read"), 9 | CUST_WRITE("customer:write"), 10 | ITEM_READ("item:read"), 11 | ITEM_WRITE("item:write"), 12 | PAYTYPE_READ("paytype:read"), 13 | PAYTYPE_WRITE("paytype:write"); 14 | 15 | private final String permission; 16 | 17 | UserPermission(String permission) { 18 | this.permission = permission; 19 | } 20 | 21 | public String getPermission() { 22 | return permission; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/domain/ProductionService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.domain; 2 | 3 | 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertProductionRequestPayload; 5 | import com.joshua.StockManagementSystem.joseph_api.model.Production; 6 | import com.joshua.StockManagementSystem.util.Pair; 7 | 8 | import java.util.List; 9 | 10 | public interface ProductionService { 11 | Pair> insert(UpsertProductionRequestPayload upsertProductionRequestPayload); 12 | List index(); 13 | Production show(String id); 14 | Pair> update(UpsertProductionRequestPayload upsertProductionRequestPayload); 15 | Pair> delete(String id); 16 | } 17 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/domain/CustomerService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.domain; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertCustomerRequestPayload; 4 | import com.joshua.StockManagementSystem.joseph_api.model.Customer; 5 | import com.joshua.StockManagementSystem.util.Pair; 6 | 7 | import java.util.List; 8 | 9 | public interface CustomerService { 10 | Pair> insertCustomer(UpsertCustomerRequestPayload upsertCustomerRequestPayload); 11 | List indexCustomer(); 12 | Customer showCustomer(String id); 13 | Pair> updateCustomer(UpsertCustomerRequestPayload upsertCustomerRequestPayload); 14 | Pair> deleteCustomer(String id); 15 | } 16 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/domain/PaymentService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.domain; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertPaymentRequestPayload; 4 | import com.joshua.StockManagementSystem.joseph_api.model.Payment; 5 | import com.sun.org.apache.xpath.internal.operations.Bool; 6 | import com.joshua.StockManagementSystem.util.Pair; 7 | 8 | import java.util.List; 9 | 10 | public interface PaymentService { 11 | Pair> insert(UpsertPaymentRequestPayload upsertPaymentRequestPayload); 12 | List index(); 13 | Payment show(String id); 14 | Pair> update(UpsertPaymentRequestPayload upsertPaymentRequestPayload); 15 | Pair> delete(String id); 16 | } 17 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/dao/PostgresDataSource.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.dao; 2 | 3 | import com.zaxxer.hikari.HikariDataSource; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.boot.jdbc.DataSourceBuilder; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | public class PostgresDataSource { 11 | @Bean 12 | @ConfigurationProperties("app.datasource") 13 | public HikariDataSource hikariDataSource(){ 14 | return DataSourceBuilder 15 | .create() 16 | .type(HikariDataSource.class) 17 | .build(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/flushout/PaymentDataEntity.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout; 2 | 3 | public class PaymentDataEntity extends JosephDataEntity { 4 | private String id, payment_type; 5 | public static String ID = "id", TYPE = "payment_type"; 6 | 7 | public PaymentDataEntity() { 8 | TABLE = "payments"; 9 | numColumns = 2; 10 | } 11 | 12 | public String getId() { 13 | return id; 14 | } 15 | 16 | public PaymentDataEntity setId(String id) { 17 | this.id = id;return this; 18 | } 19 | 20 | public String getPayment_type() { 21 | return payment_type; 22 | } 23 | 24 | public PaymentDataEntity setPayment_type(String payment_type) { 25 | this.payment_type = payment_type;return this; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/upsert/UpsertTransactionDetailRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.upsert; 2 | 3 | public class UpsertTransactionDetailRequestPayload { 4 | private String itemCode; 5 | private Integer quantity; 6 | private String note; 7 | 8 | public String getItemCode() { 9 | return itemCode; 10 | } 11 | 12 | public void setItemCode(String itemCode) { 13 | this.itemCode = itemCode; 14 | } 15 | 16 | public Integer getQuantity() { 17 | return quantity; 18 | } 19 | 20 | public UpsertTransactionDetailRequestPayload setQuantity(Integer quantity) { 21 | this.quantity = quantity;return this; 22 | } 23 | 24 | public String getNote() { 25 | return note; 26 | } 27 | 28 | public UpsertTransactionDetailRequestPayload setNote(String note) { 29 | this.note = note;return this; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | node_modules 3 | scripts/flow/*/.flowconfig 4 | .flowconfig 5 | *~ 6 | *.pyc 7 | .grunt 8 | _SpecRunner.html 9 | __benchmarks__ 10 | build/ 11 | remote-repo/ 12 | coverage/ 13 | .module-cache 14 | fixtures/dom/public/react-dom.js 15 | fixtures/dom/public/react.js 16 | test/the-files-to-test.generated.js 17 | *.log* 18 | chrome-user-data 19 | *.sublime-project 20 | *.sublime-workspace 21 | .idea 22 | *.iml 23 | .vscode 24 | *.swp 25 | *.swo 26 | 27 | packages/react-devtools-core/dist 28 | packages/react-devtools-extensions/chrome/build 29 | packages/react-devtools-extensions/chrome/*.crx 30 | packages/react-devtools-extensions/chrome/*.pem 31 | packages/react-devtools-extensions/firefox/build 32 | packages/react-devtools-extensions/firefox/*.xpi 33 | packages/react-devtools-extensions/firefox/*.pem 34 | packages/react-devtools-extensions/shared/build 35 | packages/react-devtools-inline/dist 36 | packages/react-devtools-shell/dist -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/domain/ItemService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.domain; 2 | 3 | 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexItemRequestPayload; 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertItemRequestPayload; 6 | import com.joshua.StockManagementSystem.joseph_api.model.Item; 7 | import com.joshua.StockManagementSystem.util.Pair; 8 | 9 | import java.util.List; 10 | 11 | public interface ItemService { 12 | Pair> insert(UpsertItemRequestPayload upsertCustomerRequestPayload); 13 | List index(IndexItemRequestPayload indexItemRequestPayload); 14 | Item show(String id); 15 | Pair> update(UpsertItemRequestPayload upsertCustomerRequestPayload); 16 | Pair> delete(String itemCode); 17 | void generateReport(IndexItemRequestPayload indexItemRequestPayload); 18 | } 19 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/services/PaymentTypeService.ts: -------------------------------------------------------------------------------- 1 | import { getBaseUrl, JOSEPH_URL } from "../../configs/api"; 2 | import Axios from "axios-observable"; 3 | import { Observable } from "rxjs"; 4 | import { IPayemntType } from "../interfaces/paymentTypes/IPaymentType"; 5 | 6 | const usingBaseUrl = getBaseUrl() 7 | 8 | export const serviceIndexPaymentType = () : Observable=> { 9 | return Axios.get( 10 | usingBaseUrl+JOSEPH_URL.PAYTYPE.INDEX 11 | ) 12 | } 13 | 14 | export const serviceAddPayType = (dataPayload: IPayemntType) : Observable=> { 15 | return Axios.post( 16 | usingBaseUrl+JOSEPH_URL.PAYTYPE.ADD, 17 | dataPayload 18 | ) 19 | } 20 | 21 | export const serviceDeletePayType = (dataPayload: string) : Observable => { 22 | return Axios.delete( 23 | usingBaseUrl+JOSEPH_URL.PAYTYPE.DELETE+dataPayload 24 | ) 25 | } 26 | 27 | export const serviceEditPayType = (dataPayload:IPayemntType): Observable => { 28 | return Axios.put( 29 | usingBaseUrl+JOSEPH_URL.PAYTYPE.EDIT, 30 | dataPayload 31 | ) 32 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/index/IndexItemRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.index; 2 | 3 | public class IndexItemRequestPayload { 4 | Integer sortByItemCode = 0; 5 | Integer sortByAmountSold = 0; 6 | Integer sortByAmountIncome = 0; 7 | 8 | public Integer getSortByAmountSold() { 9 | return sortByAmountSold; 10 | } 11 | 12 | public IndexItemRequestPayload setSortByAmountSold(Integer sortByAmountSold) { 13 | this.sortByAmountSold = sortByAmountSold;return this; 14 | } 15 | 16 | public Integer getSortByAmountIncome() { 17 | return sortByAmountIncome; 18 | } 19 | 20 | public IndexItemRequestPayload setSortByAmountIncome(Integer sortByAmountIncome) { 21 | this.sortByAmountIncome = sortByAmountIncome;return this; 22 | } 23 | 24 | public Integer getSortByItemCode() { 25 | return sortByItemCode; 26 | } 27 | 28 | public IndexItemRequestPayload setSortByItemCode(Integer sortByItemCode) { 29 | this.sortByItemCode = sortByItemCode;return this; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/transactions/ITransaction.ts: -------------------------------------------------------------------------------- 1 | export interface ITransaction{ 2 | id : string, 3 | customerId: string, 4 | paymentId: string, 5 | transactionDate: Date, 6 | paymentStatus: string, 7 | transactionDetails: ITransactionDetail[], 8 | timestamp: Date, 9 | note:string, 10 | total:string, 11 | totalDec: number 12 | } 13 | 14 | export interface ITransactionDetail{ 15 | transactionHeaderId: string, 16 | itemCode: string, 17 | price: string, 18 | quantity: number, 19 | note: string, 20 | timestamp: Date, 21 | subTotal: string, 22 | subTotalDec: number 23 | } 24 | 25 | export const getInitTransaction = () => { 26 | return {id : "", 27 | customerId: "", 28 | paymentId: "", 29 | transactionDate: Date.now(), 30 | paymentStatus: "", 31 | transactionDetails: [], 32 | timestamp: Date.now(), 33 | note:"", 34 | total:"", 35 | totalDec: 0} 36 | } 37 | 38 | export const initTransactionDetail = { 39 | transactionHeaderId: "", 40 | itemCode: "", 41 | price: "", 42 | quantity: 0, 43 | note: "", 44 | timestamp: Date.now(), 45 | subTotal: "", 46 | subTotalDec: 0 47 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/services/ProductionService.ts: -------------------------------------------------------------------------------- 1 | import { getBaseUrl, JOSEPH_URL } from "../../configs/api"; 2 | import { Observable } from "rxjs"; 3 | import { IIndexProductionResponse, IProduction } from '../interfaces' 4 | import Axios from "axios-observable"; 5 | const usingBaseUrl = getBaseUrl() 6 | 7 | export const serviceIndexProduction = (): Observable => { 8 | return Axios.get( 9 | usingBaseUrl+JOSEPH_URL.PRODUCTION.INDEX 10 | ) 11 | } 12 | 13 | export const serviceAddProduction = (dataPayload:IProduction) : Observable => { 14 | return Axios.post( 15 | usingBaseUrl+JOSEPH_URL.PRODUCTION.ADD, 16 | dataPayload 17 | ) 18 | } 19 | 20 | export const serviceDeleteProduction = (dataPayload:string) : Observable => { 21 | return Axios.delete( 22 | usingBaseUrl+JOSEPH_URL.PRODUCTION.DELETE+dataPayload 23 | ) 24 | } 25 | 26 | export const serviceEditProduction = (dataPayload:IProduction) : Observable => { 27 | return Axios.put( 28 | usingBaseUrl+JOSEPH_URL.PRODUCTION.EDIT, 29 | dataPayload 30 | ) 31 | } -------------------------------------------------------------------------------- /.github/workflows/frontend-heroku.yml: -------------------------------------------------------------------------------- 1 | name: Frontend Deployment 2 | 3 | on: 4 | push: 5 | branches: 6 | - release** 7 | paths: 8 | - stockmanagementsystem-frontend/** 9 | - .github/workflows/frontend** 10 | 11 | jobs: 12 | deploy_to_heroku_frontend: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: checkout 16 | uses: actions/checkout@v2 17 | 18 | - name: Extract branch name 19 | shell: bash 20 | run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" 21 | id: extract_branch 22 | 23 | - name: Deploy branch ${{ steps.extract_branch.outputs.branch }} to Heroku 24 | uses: akhileshns/heroku-deploy@v3.12.12 25 | with: 26 | heroku_api_key: ${{secrets.HEROKU_API_KEY}} 27 | heroku_app_name: ${{secrets.HEROKU_APP_NAME_FE}} 28 | heroku_email: ${{secrets.HEROKU_EMAIL}} 29 | appdir: stockmanagementsystem-frontend 30 | branch: ${{ steps.extract_branch.outputs.branch }} 31 | remote_branch: "main" 32 | procfile: "web: npm install && npm run-script build && npm start" 33 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/upsert/UpsertCustomerRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.upsert; 2 | 3 | 4 | public class UpsertCustomerRequestPayload { 5 | private String id, name, description,contact; 6 | 7 | public String getId() { 8 | return id; 9 | } 10 | 11 | public UpsertCustomerRequestPayload setId(String id) { 12 | this.id = id;return this; 13 | } 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | public UpsertCustomerRequestPayload setName(String name) { 20 | this.name = name;return this; 21 | } 22 | 23 | public String getDescription() { 24 | return description; 25 | } 26 | 27 | public UpsertCustomerRequestPayload setDescription(String description) { 28 | this.description = description;return this; 29 | } 30 | 31 | public String getContact() { 32 | return contact; 33 | } 34 | 35 | public UpsertCustomerRequestPayload setContact(String contact) { 36 | this.contact = contact;return this; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # StockManagementSystem 2 | Live deployment: https://joseph-mansys.herokuapp.com/ 3 | 4 | project status: **ongoing**, haven't done yet 5 | 6 | *Fullstack Web to manage stock, transaction history, generate pdf report, tailored and design based on specific local business* 7 | 8 | `Backend: Java Spring-Boot, Spring Dependency Injection, maven, PostgreSQL, Domain-Driven-Design, flying-saucer, handlebars` 9 | 10 | `Frontend: Reactjs, webpack, babel, Typescript, Atomic-Design` 11 | 12 | ## use case 13 | 1. user can Create, Read, Update, Delete most recent transactions, 14 | and sort based on the transaction date, total amount transaction, filter by product(multiple), the customer (multiple), payment type (multiple), date range (from until) 15 | 2. user can Create, Read, Update, Delete every in and out the history of items 16 | 3. user can Create, Read, Update, Delete transaction history of customers 17 | 4. user can download automatically generated pdf report of transactions and item's stocks 18 | 19 | 20 | https://dbdiagram.io/d/5e88a5724495b02c3b893fc2 21 | 22 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/domain/TransactionService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.domain; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexTransactionRequestPayload; 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertTransactionHeaderRequestPayload; 5 | import com.joshua.StockManagementSystem.joseph_api.model.TransactionHeader; 6 | import com.sun.org.apache.xpath.internal.operations.Bool; 7 | import com.joshua.StockManagementSystem.util.Pair; 8 | 9 | import java.util.List; 10 | 11 | public interface TransactionService { 12 | Pair> insert(UpsertTransactionHeaderRequestPayload upsertTransactionHeaderRequestPayload); 13 | List index(IndexTransactionRequestPayload indexTransactionRequestPayload); 14 | TransactionHeader show(String id); 15 | Pair> update(UpsertTransactionHeaderRequestPayload upsertTransactionHeaderRequestPayload); 16 | Pair> delete(String id); 17 | void generateReport(IndexTransactionRequestPayload indexTransactionRequestPayload); 18 | } 19 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | // ini diatas(ES5) sama aja kaya import path from 'path'(ES6) 3 | // node blom bisa baca import 4 | 5 | const rules = [ 6 | { 7 | // smua file yg end dengan tsx 8 | // kecuali dari file node_module 9 | // pake babel loader untuk load 10 | test: /\.tsx?/, 11 | exclude: /node_module/, 12 | loader: 'babel-loader' 13 | } 14 | ] 15 | 16 | module.exports = { 17 | target: 'web', 18 | mode:'development', 19 | entry:'./src/index.tsx', //main code 20 | output:{ 21 | // untuk kasih tau tempat exported, compiled code nya kemana, ke folder build di root dir 22 | path: path.resolve(__dirname,'build'), 23 | filename:"bundle.js", // nama file di index.html 24 | publicPath: '/' 25 | }, 26 | module: {rules}, // {rules} sama kaya {rules:rules} 27 | // resolve extension file wktu import 28 | resolve:{extensions: ['.ts','.tsx','.js']}, 29 | devServer:{ 30 | contentBase: './', // ambil content dari root, export ke port 5001 31 | port: process.env.PORT || 5001, 32 | historyApiFallback: true 33 | } 34 | } -------------------------------------------------------------------------------- /StockManagementSystem/HELP.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ### Reference Documentation 4 | For further reference, please consider the following sections: 5 | 6 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) 7 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/maven-plugin/) 8 | * [Spring Web](https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications) 9 | * [Spring Security](https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/reference/htmlsingle/#boot-features-security) 10 | 11 | ### Guides 12 | The following guides illustrate how to use some features concretely: 13 | 14 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) 15 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) 16 | * [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/) 17 | * [Securing a Web Application](https://spring.io/guides/gs/securing-web/) 18 | * [Spring Boot and OAuth2](https://spring.io/guides/tutorials/spring-boot-oauth2/) 19 | * [Authenticating a User with LDAP](https://spring.io/guides/gs/authenticating-ldap/) 20 | 21 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/auth/UserService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.auth; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Qualifier; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.web.bind.annotation.CrossOrigin; 10 | 11 | @CrossOrigin(origins = "*", allowedHeaders = "*") 12 | @Service 13 | public class UserService implements UserDetailsService { 14 | 15 | private final UserDAO userDAO; 16 | 17 | @Autowired 18 | public UserService(@Qualifier("postgresUser") UserDAO userDAO) { 19 | this.userDAO = userDAO; 20 | } 21 | 22 | @Override 23 | public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { 24 | return userDAO.selectUserByUsername(s) 25 | .orElseThrow( 26 | () -> 27 | new UsernameNotFoundException("Username "+s+"Not Found")); 28 | } 29 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/services/CustomerService.ts: -------------------------------------------------------------------------------- 1 | import { getBaseUrl, JOSEPH_URL } from "../../configs/api"; 2 | import { Observable, from } from "rxjs"; 3 | import { IIndexCustomerResponse,IUpsertCustomerRequest,IUpsertCustomerResponse } from "../interfaces"; 4 | import Axios from "axios-observable"; 5 | 6 | const usingBaseUrl = getBaseUrl() 7 | 8 | export const serviceIndexCustomer = (): Observable => { 9 | // from method rxjs convert Promise to Observable (Axios.get return a Promise) 10 | return Axios.get( 11 | usingBaseUrl+JOSEPH_URL.CUSTOMER.INDEX 12 | ) 13 | } 14 | 15 | export const serviceAddCustomer = (dataPayload:IUpsertCustomerRequest): Observable => { 16 | return Axios.post( 17 | usingBaseUrl+JOSEPH_URL.CUSTOMER.ADD, 18 | dataPayload 19 | ) 20 | } 21 | 22 | export const serviceEditCustomer = (dataPayload:IUpsertCustomerRequest): Observable => { 23 | return Axios.put( 24 | usingBaseUrl+JOSEPH_URL.CUSTOMER.EDIT, 25 | dataPayload 26 | ) 27 | } 28 | 29 | export const serviceDeleteCustomer = (dataPayload:string): Observable => { 30 | return Axios.delete( 31 | usingBaseUrl+JOSEPH_URL.CUSTOMER.DELETE+dataPayload 32 | ) 33 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/services/index.ts: -------------------------------------------------------------------------------- 1 | import Axios from 'axios-observable'; 2 | 3 | Axios.defaults.headers["Authorization"] = 'Bearer '+localStorage.getItem("JWT") 4 | 5 | export { serviceIndexItem,serviceDeleteItem as serviceDeletetem, serviceEditItem, serviceDownloadPdfItem} from './ItemService'; 6 | 7 | export { serviceIndexCustomer,serviceEditCustomer, serviceAddCustomer, serviceDeleteCustomer } from './CustomerService'; 8 | 9 | export { serviceIndexProduction, serviceDeleteProduction, serviceAddProduction, serviceEditProduction } from './ProductionService'; 10 | 11 | export { serviceIndexPaymentType, serviceAddPayType, serviceDeletePayType, serviceEditPayType } from './PaymentTypeService'; 12 | 13 | export { serviceIndexTransaction, serviceDeleteTransaction, serviceAddTransaction, serviceEditTransaction, serviceDownloadPdfTransaction } from './TransaactionService'; 14 | 15 | export { serviceLogin } from './LoginService'; 16 | 17 | export function getCurrentDate(separator=''){ 18 | let currDate = new Date() 19 | let date = currDate.getDate(); 20 | let month = currDate.getMonth() + 1; 21 | let year = currDate.getFullYear(); 22 | 23 | return `${year}${separator}${month<10?`0${month}`:`${month}`}${separator}${date}` 24 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/flushout/CustomerDataEntity.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout; 2 | 3 | public class CustomerDataEntity extends JosephDataEntity { 4 | 5 | private String id, name, description,contact; 6 | public static String ID = "id", NAME = "name", DESCRIPTION = "description", 7 | CONTACT = "contact"; 8 | public CustomerDataEntity() { 9 | TABLE = "customers"; 10 | numColumns = 4; 11 | } 12 | 13 | public String getId() { 14 | return id; 15 | } 16 | 17 | public CustomerDataEntity setId(String id) { 18 | this.id = id;return this; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public CustomerDataEntity setName(String name) { 26 | this.name = name;return this; 27 | } 28 | 29 | public String getDescription() { 30 | return description; 31 | } 32 | 33 | public CustomerDataEntity setDescription(String description) { 34 | this.description = description;return this; 35 | } 36 | 37 | public String getContact() { 38 | return contact; 39 | } 40 | 41 | public CustomerDataEntity setContact(String contact) { 42 | this.contact = contact;return this; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/model/Customer.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.model; 2 | 3 | public class Customer { 4 | private String id, name, description,contact, totalAmountSpend; 5 | 6 | public String getId() { 7 | return id; 8 | } 9 | 10 | public Customer setId(String id) { 11 | this.id = id;return this; 12 | } 13 | 14 | public String getName() { 15 | return name; 16 | } 17 | 18 | public Customer setName(String name) { 19 | this.name = name;return this; 20 | } 21 | 22 | public String getDescription() { 23 | return description; 24 | } 25 | 26 | public Customer setDescription(String description) { 27 | this.description = description;return this; 28 | } 29 | 30 | public String getContact() { 31 | return contact; 32 | } 33 | 34 | public Customer setContact(String contact) { 35 | this.contact = contact;return this; 36 | } 37 | 38 | public String getTotalAmountSpend() { 39 | return totalAmountSpend; 40 | } 41 | 42 | public Customer setTotalAmountSpend(String totalAmountSpend) { 43 | this.totalAmountSpend = totalAmountSpend;return this; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export enum HTTPCallStatus{ 2 | Success = 'SUCCESS', 3 | Failed = 'FAILED' 4 | } 5 | export interface BaseResponse{ 6 | status:HTTPCallStatus, 7 | data:{} 8 | } 9 | 10 | export { ICRUDResponse } from './ICRUD' 11 | 12 | export { IItem } from './items/IItem'; 13 | export { IIndexItemRequest, IIndexItemResponse } from './items/IIndexItem'; 14 | export { IDeleteItemResponse } from './items/IDeleteItem'; 15 | export { IUpsertItemRequest,IUpsertItemResponse } from './items/IUpsertItem'; 16 | 17 | export { ICustomer } from './customers/ICustomer' 18 | export { IIndexCustomerResponse } from './customers/IIndexCustomer' 19 | export { IUpsertCustomerRequest,IUpsertCustomerResponse } from './customers/IUpsertCustomer' 20 | 21 | export { IProduction } from './productions/IProduction' 22 | export { IIndexProductionResponse } from './productions/IIndexProduction' 23 | 24 | export { ITransaction, ITransactionDetail, initTransaction, initTransactionDetail } from './transactions/ITransaction' 25 | export { IIndexTransactionRequest, getInitIndexTransactionRequest } from './transactions/IIndexTransaction' 26 | export { IUpsertTransactionRequest,IUpsertTransactionDetailRequest } from './transactions/IUpsertTransaction' 27 | 28 | export { ILoginRequest } from './ILogin'; -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/dao/spec/TransactionSpec.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.dao.spec; 2 | 3 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.TransactionDetailDataEntity; 4 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.TransactionHeaderDataEntity; 5 | 6 | import java.util.List; 7 | 8 | public class TransactionSpec { 9 | private TransactionHeaderDataEntity transactionHeaderDataEntity; 10 | private List transactionDetailDataEntityList; 11 | 12 | public TransactionHeaderDataEntity getTransactionHeaderDataEntity() { 13 | return transactionHeaderDataEntity; 14 | } 15 | 16 | public TransactionSpec setTransactionHeaderDataEntity(TransactionHeaderDataEntity transactionHeaderDataEntity) { 17 | this.transactionHeaderDataEntity = transactionHeaderDataEntity;return this; 18 | } 19 | 20 | public List getTransactionDetailDataEntityList() { 21 | return transactionDetailDataEntityList; 22 | } 23 | 24 | public TransactionSpec setTransactionDetailDataEntityList(List transactionDetailDataEntityList) { 25 | this.transactionDetailDataEntityList = transactionDetailDataEntityList;return this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.github/workflows/backend-heroku.yml: -------------------------------------------------------------------------------- 1 | name: Backend Deployment 2 | 3 | on: 4 | push: 5 | branches: 6 | - release** 7 | paths: 8 | - StockManagementSystem/** 9 | - .github/workflows/backend** 10 | 11 | jobs: 12 | deploy_to_heroku: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: checkout 16 | uses: actions/checkout@v2 17 | 18 | - name: Extract branch name 19 | shell: bash 20 | run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" 21 | id: extract_branch 22 | 23 | - name: Set up JDK 1.8 24 | uses: actions/setup-java@v1 25 | with: 26 | java-version: 1.8 27 | distribution: 'adopt' 28 | 29 | - name: Build with Maven 30 | run: cd StockManagementSystem && mvn -B package --file pom.xml && mkdir jars && cp target/*.jar jars && ls -la 31 | 32 | - name: Deploy branch ${{ steps.extract_branch.outputs.branch }} to Heroku 33 | uses: akhileshns/heroku-deploy@v3.12.12 34 | with: 35 | heroku_api_key: ${{secrets.HEROKU_API_KEY}} 36 | heroku_app_name: ${{secrets.HEROKU_APP_NAME_BE}} 37 | heroku_email: ${{secrets.HEROKU_EMAIL}} 38 | appdir: StockManagementSystem 39 | branch: ${{ steps.extract_branch.outputs.branch }} 40 | remote_branch: "main" 41 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | JOSEPH | StockManagementSystem 7 | 8 | 10 | 11 | 28 | 29 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/model/Production.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.model; 2 | 3 | import java.util.Date; 4 | 5 | public class Production { 6 | private String id, itemCode, producer; 7 | private Date productionDate; 8 | private int quantity; 9 | 10 | public Production() { 11 | } 12 | 13 | public String getId() { 14 | return id; 15 | } 16 | 17 | public Production setId(String id) { 18 | this.id = id;return this; 19 | } 20 | 21 | public String getItemCode() { 22 | return itemCode; 23 | } 24 | 25 | public Production setItemCode(String itemCode) { 26 | this.itemCode = itemCode;return this; 27 | } 28 | 29 | public String getProducer() { 30 | return producer; 31 | } 32 | 33 | public Production setProducer(String producer) { 34 | this.producer = producer;return this; 35 | } 36 | 37 | public Date getProductionDate() { 38 | return productionDate; 39 | } 40 | 41 | public Production setProductionDate(Date productionDate) { 42 | this.productionDate = productionDate;return this; 43 | } 44 | 45 | public int getQuantity() { 46 | return quantity; 47 | } 48 | 49 | public Production setQuantity(int quantity) { 50 | this.quantity = quantity;return this; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/infrastructure/dao/TransactionDAO.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.infrastructure.dao; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexTransactionRequestPayload; 4 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.dao.spec.TransactionSpec; 5 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.ProductionDataEntity; 6 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.TransactionDetailDataEntity; 7 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.TransactionHeaderDataEntity; 8 | 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Optional; 12 | 13 | public interface TransactionDAO { 14 | Integer insert(TransactionHeaderDataEntity transactionHeaderDataEntity, List details); 15 | List index(IndexTransactionRequestPayload indexTransactionRequestPayload); 16 | List indexDetails(IndexTransactionRequestPayload indexTransactionRequestPayload, HashMap indexOfId); 17 | Optional show(String id); 18 | Integer update(TransactionHeaderDataEntity transactionHeaderDataEntity, List details); 19 | Integer delete(String idItem); 20 | } 21 | -------------------------------------------------------------------------------- /StockManagementSystem.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE "items" ( 2 | "item_code" varchar PRIMARY KEY, 3 | "name" varchar, 4 | "description" varchar, 5 | "price" float8, 6 | "stock" int, 7 | "capacity" int 8 | ); 9 | 10 | CREATE TABLE "customers" ( 11 | "id" serial PRIMARY KEY, 12 | "name" varchar, 13 | "description" varchar, 14 | "contact" varchar 15 | ); 16 | 17 | CREATE TABLE "transaction_headers" ( 18 | "id" varchar PRIMARY KEY, 19 | "customer_id" int, 20 | "payment_id" int, 21 | "transaction_date" date, 22 | "payment_status" varchar 23 | ); 24 | 25 | CREATE TABLE "payments" ( 26 | "id" serial, 27 | "payment_type" varchar 28 | ); 29 | 30 | CREATE TABLE "transaction_details" ( 31 | "id" varchar, 32 | "item_code" varchar, 33 | "price" float8, 34 | "quantity" int 35 | ); 36 | 37 | CREATE TABLE "productions" ( 38 | "id" int, 39 | "item_id" varchar, 40 | "production_date" date, 41 | "producer_name" varchar, 42 | "quantity" int 43 | ); 44 | 45 | ALTER TABLE "transaction_headers" ADD FOREIGN KEY ("customer_id") REFERENCES "customers" ("id"); 46 | 47 | ALTER TABLE "transaction_headers" ADD FOREIGN KEY ("payment_id") REFERENCES "payments" ("id"); 48 | 49 | ALTER TABLE "transaction_details" ADD FOREIGN KEY ("id") REFERENCES "transaction_headers" ("id"); 50 | 51 | ALTER TABLE "transaction_details" ADD FOREIGN KEY ("item_code") REFERENCES "items" ("item_code"); 52 | 53 | ALTER TABLE "productions" ADD FOREIGN KEY ("item_id") REFERENCES "items" ("item_code"); 54 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/upsert/UpsertProductionRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.upsert; 2 | 3 | import java.util.Date; 4 | 5 | public class UpsertProductionRequestPayload { 6 | private String id, itemCode, producer; 7 | private Date productionDate; 8 | private int quantity; 9 | 10 | public UpsertProductionRequestPayload() { 11 | } 12 | 13 | public String getId() { 14 | return id; 15 | } 16 | 17 | public UpsertProductionRequestPayload setId(String id) { 18 | this.id = id;return this; 19 | } 20 | 21 | public String getItemCode() { 22 | return itemCode; 23 | } 24 | 25 | public UpsertProductionRequestPayload setItemCode(String itemCode) { 26 | this.itemCode = itemCode;return this; 27 | } 28 | 29 | public String getProducer() { 30 | return producer; 31 | } 32 | 33 | public UpsertProductionRequestPayload setProducer(String producer) { 34 | this.producer = producer;return this; 35 | } 36 | 37 | public Date getProductionDate() { 38 | return productionDate; 39 | } 40 | 41 | public UpsertProductionRequestPayload setProductionDate(Date productionDate) { 42 | this.productionDate = productionDate;return this; 43 | } 44 | 45 | public int getQuantity() { 46 | return quantity; 47 | } 48 | 49 | public UpsertProductionRequestPayload setQuantity(int quantity) { 50 | this.quantity = quantity;return this; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/snackbar/Snackbar.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { makeStyles, Theme, createStyles } from "@material-ui/core/styles"; 3 | import Alert from "@material-ui/lab/Alert"; 4 | import IconButton from "@material-ui/core/IconButton"; 5 | import Collapse from "@material-ui/core/Collapse"; 6 | import CloseIcon from "@material-ui/icons/Close"; 7 | 8 | const useStyles = makeStyles((theme: Theme) => 9 | createStyles({ 10 | root: { 11 | width: "100%", 12 | "& > * + *": { 13 | marginTop: theme.spacing(2) 14 | } 15 | } 16 | }) 17 | ); 18 | 19 | export function CustomizedSnackbars(props:any) { 20 | const classes = useStyles(); 21 | const [open, setOpen] = React.useState(true); 22 | 23 | // {{console.log("snackbar") 24 | // console.log(props.msg) 25 | // console.log(typeof props.msg)}} 26 | 27 | return ( 28 |
29 | 30 | { 38 | setOpen(false); 39 | props.parentCallback(); 40 | }} 41 | > 42 | 43 | 44 | }> 45 |
    46 | { 47 | props.msg.map( 48 | (e:string) => { 49 | return (
  • {e}
  • ); 50 | }) 51 | } 52 |
53 | 54 |
55 |
56 |
57 | ); 58 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/expansion_panel/SimpleExpansionPanel.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Theme, createStyles, makeStyles } from '@material-ui/core/styles'; 3 | import ExpansionPanel from '@material-ui/core/ExpansionPanel'; 4 | import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary'; 5 | import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails'; 6 | import Typography from '@material-ui/core/Typography'; 7 | import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; 8 | 9 | const useStyles = makeStyles((theme: Theme) => 10 | createStyles({ 11 | root: { 12 | width: '100%', 13 | }, 14 | heading: { 15 | fontSize: theme.typography.pxToRem(15), 16 | fontWeight: theme.typography.fontWeightRegular, 17 | }, 18 | }), 19 | ); 20 | 21 | export function SimpleExpansionPanel(props:any) { 22 | const classes = useStyles(); 23 | 24 | return ( 25 |
26 | 27 | } 29 | aria-controls="panel1a-content" 30 | id="panel1a-header" 31 | > 32 | {props.title} 33 | 34 | 35 | 36 | {props.content} 37 | 38 | 39 | 40 |
41 | ); 42 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/services/ItemService.ts: -------------------------------------------------------------------------------- 1 | import { getBaseUrl, JOSEPH_URL } from "../../configs/api"; 2 | import Axios from 'axios-observable'; 3 | import { Observable } from "rxjs"; 4 | import { IIndexItemRequest, IIndexItemResponse, IDeleteItemResponse, IUpsertItemRequest } from "../interfaces"; 5 | 6 | const usingBaseUrl = getBaseUrl() 7 | 8 | const serviceIndexItem = (dataPayload:IIndexItemRequest): Observable => { 9 | return Axios.post( 10 | usingBaseUrl+JOSEPH_URL.ITEM.INDEX, 11 | dataPayload 12 | ) 13 | } 14 | 15 | export const serviceDeleteItem = (dataPayload:string): Observable => { 16 | return Axios.delete( 17 | usingBaseUrl+JOSEPH_URL.ITEM.DELETE+dataPayload 18 | ) 19 | } 20 | 21 | export const serviceAddItem = (dataPayload:IUpsertItemRequest): Observable => { 22 | return Axios.post( 23 | usingBaseUrl+JOSEPH_URL.ITEM.ADD, 24 | dataPayload 25 | ) 26 | } 27 | 28 | export const serviceEditItem = (dataPayload:IUpsertItemRequest): Observable => { 29 | return Axios.put( 30 | usingBaseUrl+JOSEPH_URL.ITEM.EDIT, 31 | dataPayload 32 | ) 33 | } 34 | 35 | export const serviceDownloadPdfItem = (dataPayload:IIndexItemRequest): Observable => { 36 | return Axios.request( 37 | { 38 | method:'post', 39 | url: usingBaseUrl+JOSEPH_URL.ITEM.DOWNLOAD_PDF, 40 | data: dataPayload, 41 | responseType:'blob' // very important, else corrupted file 42 | } 43 | ) 44 | } 45 | 46 | export {serviceIndexItem}; -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/upsert/UpsertItemRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.upsert; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class UpsertItemRequestPayload { 6 | private String itemCode, name, description; 7 | private BigDecimal price; 8 | private Integer stock, capacity; 9 | 10 | public String getItemCode() { 11 | return itemCode; 12 | } 13 | 14 | public UpsertItemRequestPayload setItemCode(String itemCode) { 15 | this.itemCode = itemCode;return this; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public UpsertItemRequestPayload setName(String name) { 23 | this.name = name;return this; 24 | } 25 | 26 | public String getDescription() { 27 | return description; 28 | } 29 | 30 | public UpsertItemRequestPayload setDescription(String description) { 31 | this.description = description;return this; 32 | } 33 | 34 | public BigDecimal getPrice() { 35 | return price; 36 | } 37 | 38 | public UpsertItemRequestPayload setPrice(BigDecimal price) { 39 | this.price = price;return this; 40 | } 41 | 42 | public Integer getStock() { 43 | return stock; 44 | } 45 | 46 | public UpsertItemRequestPayload setStock(Integer stock) { 47 | this.stock = stock;return this; 48 | } 49 | 50 | public Integer getCapacity() { 51 | return capacity; 52 | } 53 | 54 | public UpsertItemRequestPayload setCapacity(Integer capacity) { 55 | this.capacity = capacity;return this; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/jwt/JwtConfig.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.jwt; 2 | 3 | import com.google.common.net.HttpHeaders; 4 | import io.jsonwebtoken.security.Keys; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.crypto.SecretKey; 10 | 11 | /** 12 | * ini baca dari application.yml 13 | */ 14 | @ConfigurationProperties(prefix = "application.jwt") 15 | @Component 16 | public class JwtConfig { 17 | private String secretKey, tokenPrefix; 18 | private Integer tokenExpirationAfterDays; 19 | 20 | public JwtConfig() { 21 | } 22 | 23 | public String getSecretKey() { 24 | return secretKey; 25 | } 26 | 27 | public void setSecretKey(String secretKey) { 28 | this.secretKey = secretKey; 29 | } 30 | 31 | public String getTokenPrefix() { 32 | return tokenPrefix+" "; 33 | } 34 | 35 | public void setTokenPrefix(String tokenPrefix) { 36 | this.tokenPrefix = tokenPrefix; 37 | } 38 | 39 | public Integer getTokenExpirationAfterDays() { 40 | return tokenExpirationAfterDays; 41 | } 42 | 43 | public void setTokenExpirationAfterDays(Integer tokenExpirationAfterDays) { 44 | this.tokenExpirationAfterDays = tokenExpirationAfterDays; 45 | } 46 | 47 | @Bean 48 | public SecretKey getSecretKeyForLogIn(){ 49 | return Keys.hmacShaKeyFor(secretKey.getBytes()); 50 | } 51 | 52 | public String getAuthorizationHeader(){ 53 | return HttpHeaders.AUTHORIZATION; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-ts-webpack-babel", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "set NODE_ENV=production && node server.js", 8 | "dev": "webpack && webpack-dev-server --open", 9 | "build-development": "webpack", 10 | "build": "webpack -p --define process.env.NODE_ENV='\"production\"' --progress --colors" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@babel/core": "^7.9.6", 17 | "@babel/preset-env": "^7.9.6", 18 | "@babel/preset-react": "^7.9.4", 19 | "@babel/preset-typescript": "^7.9.0", 20 | "babel-plugin-transform-class-properties": "^6.24.1", 21 | "@material-ui/core": "^4.9.13", 22 | "@material-ui/icons": "^4.9.1", 23 | "@material-ui/lab": "^4.0.0-alpha.52", 24 | "@types/react": "^16.9.34", 25 | "@types/react-dom": "^16.9.7", 26 | "@types/react-router-dom": "^5.1.5", 27 | "@types/reactstrap": "^8.4.2", 28 | "axios": "^0.21.1", 29 | "axios-observable": "^1.1.3", 30 | "babel-loader": "^8.1.0", 31 | "dotenv": "^8.2.0", 32 | "express": "^4.17.1", 33 | "formik": "^2.1.4", 34 | "jwt-decode": "^2.2.0", 35 | "react": "^16.13.1", 36 | "react-dom": "^16.13.1", 37 | "react-router-dom": "^5.1.2", 38 | "reactstrap": "^8.4.1", 39 | "rxjs": "^6.5.5", 40 | "webpack": "^4.43.0", 41 | "webpack-cli": "^3.3.11", 42 | "yup": "^0.28.5" 43 | }, 44 | "devDependencies": { 45 | "@types/reactstrap": "^8.4.2", 46 | "bootstrap": "^4.4.1", 47 | "webpack-dev-server": "^3.10.3" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/dialog/ResponsiveDialog.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Button from '@material-ui/core/Button'; 3 | import Dialog from '@material-ui/core/Dialog'; 4 | import DialogActions from '@material-ui/core/DialogActions'; 5 | import DialogContent from '@material-ui/core/DialogContent'; 6 | import DialogTitle from '@material-ui/core/DialogTitle'; 7 | import useMediaQuery from '@material-ui/core/useMediaQuery'; 8 | import { useTheme } from '@material-ui/core/styles'; 9 | 10 | export function ResponsiveDialog(props:any) { 11 | const [open, setOpen] = React.useState(true); 12 | const theme = useTheme(); 13 | 14 | const fullScreen = useMediaQuery(theme.breakpoints.down('sm')); 15 | 16 | const handleClose = (isYes:boolean = false) => { 17 | // setOpen(false); 18 | if(!props.usingAction) props.parentCallbackClose(); 19 | else props.parentCallbackClose(isYes); 20 | }; 21 | 22 | return ( 23 |
24 | 30 | {props.dialogTitle} 31 | 32 | {props.dialogContent} 33 | 34 | 35 | {(props.usingAction && 36 | 37 | 40 | 43 | )} 44 | 45 |
46 | ); 47 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/flushout/ProductionDataEntity.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout; 2 | 3 | import java.util.Date; 4 | 5 | public class ProductionDataEntity extends JosephDataEntity{ 6 | private String id, itemCode; 7 | private Date productionDate; 8 | private String producer; 9 | private Integer quantity; 10 | 11 | public static String ID = "id", ITEMCODE = "item_code", PRODDATE = "production_date", PRODUCER = "producer", QTY = "quantity"; 12 | 13 | public ProductionDataEntity() { 14 | TABLE = "productions"; 15 | numColumns = 5; 16 | } 17 | 18 | public String getId() { 19 | return id; 20 | } 21 | 22 | public ProductionDataEntity setId(String id) { 23 | this.id = id;return this; 24 | } 25 | 26 | public String getItemCode() { 27 | return itemCode; 28 | } 29 | 30 | public ProductionDataEntity setItemCode(String itemCode) { 31 | this.itemCode = itemCode;return this; 32 | } 33 | 34 | public Date getProductionDate() { 35 | return productionDate; 36 | } 37 | 38 | public ProductionDataEntity setProductionDate(Date productionDate) { 39 | this.productionDate = productionDate;return this; 40 | } 41 | 42 | public String getProducer() { 43 | return producer; 44 | } 45 | 46 | public ProductionDataEntity setProducer(String producer) { 47 | this.producer = producer;return this; 48 | } 49 | 50 | public Integer getQuantity() { 51 | return quantity; 52 | } 53 | 54 | public ProductionDataEntity setQuantity(Integer quantity) { 55 | this.quantity = quantity;return this; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/configs/api.ts: -------------------------------------------------------------------------------- 1 | 2 | const API_URL = { 3 | DEV: { 4 | BASE_URL: 'http://localhost:8080/api/v1/joseph' 5 | }, 6 | PROD: { 7 | BASE_URL: process.env.BACKEND_URL+process.env.BACKEND_API 8 | } 9 | } 10 | 11 | export const JOSEPH_URL={ 12 | ITEM: { 13 | INDEX: '/item/', 14 | DELETE:'/item/delete/', 15 | ADD:'/item/insert/', 16 | EDIT:'/item/update', 17 | DOWNLOAD_PDF:'/item/report' 18 | }, 19 | CUSTOMER: { 20 | INDEX: '/customer/', 21 | DELETE:'/customer/delete/', 22 | ADD:'/customer/insert/', 23 | EDIT:'/customer/update', 24 | }, 25 | PRODUCTION: { 26 | INDEX: '/production/', 27 | DELETE:'/production/delete/', 28 | ADD:'/production/insert/', 29 | EDIT:'/production/update', 30 | }, 31 | PAYTYPE:{ 32 | INDEX: '/payment/', 33 | DELETE:'/payment/delete/', 34 | ADD:'/payment/insert/', 35 | EDIT:'/payment/update', 36 | }, 37 | TRANSACTION:{ 38 | INDEX: '/transaction/', 39 | DELETE:'/transaction/delete/', 40 | ADD:'/transaction/insert/', 41 | EDIT:'/transaction/update', 42 | DOWNLOAD_PDF:'/transaction/report' 43 | } 44 | } 45 | 46 | export const getBaseUrl = () =>{ 47 | let URL: string; 48 | if(process.env.NODE_ENV === 'production'){ 49 | URL = API_URL.PROD.BASE_URL; 50 | }else URL = API_URL.DEV.BASE_URL; 51 | return URL; 52 | } 53 | 54 | export const getLoginUrl = () => { 55 | if(process.env.NODE_ENV === 'production'){ 56 | return `${process.env.BACKEND_URL}/login` 57 | } 58 | return 'http://localhost:8080/login' 59 | } 60 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/data/services/TransaactionService.ts: -------------------------------------------------------------------------------- 1 | import { getBaseUrl, JOSEPH_URL } from "../../configs/api"; 2 | import { Observable } from "rxjs"; 3 | import Axios from "axios-observable"; 4 | import { IIndexTransactionRequest, IUpsertTransactionRequest } from "../interfaces"; 5 | import { serviceConfigCommon } from "../../configs/service"; 6 | 7 | const baseUrl = getBaseUrl() 8 | 9 | export const serviceIndexTransaction = (dataPayload: IIndexTransactionRequest) : Observable=> { 10 | return Axios.post( 11 | baseUrl+JOSEPH_URL.TRANSACTION.INDEX, 12 | dataPayload, 13 | serviceConfigCommon 14 | ) 15 | } 16 | 17 | export const serviceDeleteTransaction = (dataPayload:string) : Observable => { 18 | return Axios.delete( 19 | baseUrl+JOSEPH_URL.TRANSACTION.DELETE+dataPayload, 20 | serviceConfigCommon 21 | ) 22 | } 23 | 24 | export const serviceAddTransaction = (dataPayload:IUpsertTransactionRequest) : Observable => { 25 | return Axios.post( 26 | baseUrl+JOSEPH_URL.TRANSACTION.ADD, 27 | dataPayload, 28 | serviceConfigCommon 29 | ) 30 | } 31 | 32 | export const serviceEditTransaction = (dataPayload:IUpsertTransactionRequest) : Observable => { 33 | return Axios.put( 34 | baseUrl+JOSEPH_URL.TRANSACTION.EDIT, 35 | dataPayload, 36 | serviceConfigCommon 37 | ) 38 | } 39 | 40 | export const serviceDownloadPdfTransaction = (dataPayload: IIndexTransactionRequest) : Observable => { 41 | return Axios.request({ 42 | method:'post', 43 | url:baseUrl+JOSEPH_URL.TRANSACTION.DOWNLOAD_PDF, 44 | data: dataPayload, 45 | responseType:'blob' 46 | }) 47 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/auth/UserPostgresDataService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.auth; 2 | 3 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter.UserAdapter; 4 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.UserDataEntity; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.jdbc.core.JdbcTemplate; 7 | import org.springframework.security.crypto.password.PasswordEncoder; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.Arrays; 11 | import java.util.Collections; 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | @Repository("postgresUser") 16 | public class UserPostgresDataService implements UserDAO{ 17 | 18 | private final JdbcTemplate jdbcTemplate; 19 | private final PasswordEncoder passwordEncoder; 20 | 21 | @Autowired 22 | public UserPostgresDataService(PasswordEncoder passwordEncoder, JdbcTemplate jdbcTemplate) { 23 | this.jdbcTemplate = jdbcTemplate; 24 | this.passwordEncoder = passwordEncoder; 25 | } 26 | 27 | @Override 28 | public Optional selectUserByUsername(String username){ 29 | final String sql = "SELECT * FROM "+ UserDataEntity.TABLE+ " WHERE " + UserDataEntity.USERNAME+ " = ?"; 30 | User user = null; 31 | UserDataEntity u = jdbcTemplate.queryForObject(sql,new Object[]{username}, 32 | ((resultSet, i) -> {return UserAdapter.resulltSetToDataEntity(resultSet);}) 33 | ); 34 | if (u != null) { 35 | List users = UserAdapter.dataEntitiesToModels(Arrays.asList(u)); 36 | if (users.size() > 0) { 37 | user = users.get(0); 38 | } 39 | } 40 | return Optional.ofNullable(user); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/security/UserRole.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.security; 2 | 3 | import com.google.common.collect.Sets; 4 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 5 | 6 | import java.util.Set; 7 | import java.util.stream.Collectors; 8 | 9 | public enum UserRole { 10 | /** 11 | * Sets.newHashSet() -> comes from Google Guava 12 | */ 13 | STRANGER(Sets.newHashSet()), 14 | 15 | MEMBER(Sets.newHashSet( 16 | UserPermission.PROD_READ, 17 | UserPermission.PROD_WRITE)), 18 | 19 | ADMIN(Sets.newHashSet( 20 | UserPermission.TRANS_READ, 21 | UserPermission.TRANS_WRITE, 22 | UserPermission.ITEM_READ, 23 | UserPermission.ITEM_WRITE, 24 | UserPermission.PROD_READ, 25 | UserPermission.PROD_WRITE, 26 | UserPermission.CUST_READ, 27 | UserPermission.CUST_WRITE, 28 | UserPermission.PAYTYPE_READ, 29 | UserPermission.PAYTYPE_WRITE)); 30 | 31 | /** 32 | * must be unique therefore using Set 33 | */ 34 | private final Set permissions; 35 | 36 | UserRole(Set permissions) { 37 | this.permissions = permissions; 38 | } 39 | 40 | public Set getPermissions() { 41 | return permissions; 42 | } 43 | 44 | public Set getGrantedAuthorities() { 45 | Set permissions = getPermissions().stream() 46 | .map(p -> new SimpleGrantedAuthority(p.getPermission())) 47 | .collect(Collectors.toSet()); 48 | permissions.add(new SimpleGrantedAuthority("ROLE_"+this.name())); 49 | return permissions; 50 | } 51 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/ProductionAPIController.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.ResponsePayload; 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexProductionRequestPayload; 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertProductionRequestPayload; 6 | import com.joshua.StockManagementSystem.joseph_api.model.Production; 7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import javax.validation.constraints.NotNull; 12 | import java.util.List; 13 | 14 | @CrossOrigin(origins = "*", allowedHeaders = "*") 15 | @RequestMapping("api/v1/joseph/production") 16 | @RestController 17 | @EnableAutoConfiguration 18 | @Component("productionV1API") 19 | public interface ProductionAPIController { 20 | @PostMapping("/insert") 21 | public ResponsePayload insert(@NotNull @RequestBody UpsertProductionRequestPayload upsertProductionRequestPayload); 22 | 23 | @GetMapping(value = "/", produces = "application/json") 24 | public @ResponseBody IndexProductionRequestPayload index(); 25 | 26 | @GetMapping(value = "/show/{id}", produces = "application/json") 27 | public @ResponseBody Production show(@NotNull @PathVariable("id") String id); 28 | 29 | @PutMapping("/update") 30 | public ResponsePayload update(@NotNull @RequestBody UpsertProductionRequestPayload upsertProductionRequestPayload); 31 | 32 | @DeleteMapping("/delete/{id}") 33 | public ResponsePayload delete(@NotNull @PathVariable("id") String id); 34 | } 35 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/PaymentAPIController.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.ResponsePayload; 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexPayTypeResponsePayload; 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertPaymentRequestPayload; 6 | import com.joshua.StockManagementSystem.joseph_api.model.Payment; 7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import javax.validation.constraints.NotNull; 12 | import javax.xml.ws.Response; 13 | import java.util.List; 14 | 15 | @CrossOrigin(origins = "*",allowedHeaders = "*") 16 | @RequestMapping("api/v1/joseph/payment") 17 | @RestController 18 | @EnableAutoConfiguration 19 | @Component("paymentV1API") 20 | public interface PaymentAPIController { 21 | @PostMapping("/insert") 22 | public ResponsePayload insert(@NotNull @RequestBody UpsertPaymentRequestPayload upsertPaymentRequestPayload); 23 | 24 | @GetMapping(value = "/", produces = "application/json") 25 | public @ResponseBody 26 | IndexPayTypeResponsePayload index(); 27 | 28 | @GetMapping(value = "/show/{id}", produces = "application/json") 29 | public @ResponseBody 30 | Payment show(@NotNull @PathVariable("id") String id); 31 | 32 | @PutMapping("/update") 33 | public ResponsePayload update(@NotNull @RequestBody UpsertPaymentRequestPayload upsertPaymentRequestPayload); 34 | 35 | @DeleteMapping("/delete/{id}") 36 | public ResponsePayload delete(@NotNull @PathVariable("id") String id); 37 | } 38 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/CustomerAPIController.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.ResponsePayload; 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexCustomerResponsePayload; 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertCustomerRequestPayload; 6 | import com.joshua.StockManagementSystem.joseph_api.model.Customer; 7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import javax.validation.constraints.NotNull; 12 | import java.util.List; 13 | 14 | @CrossOrigin(origins = "*", allowedHeaders = "*") 15 | @RequestMapping("api/v1/joseph/customer") 16 | @RestController 17 | @EnableAutoConfiguration 18 | @Component("custAPIV1") 19 | public interface CustomerAPIController { 20 | @PostMapping("/insert") 21 | public ResponsePayload insertCustomer(@NotNull @RequestBody UpsertCustomerRequestPayload upsertCustomerRequestPayload); 22 | 23 | @GetMapping(value = "/", produces = "application/json") 24 | public @ResponseBody 25 | IndexCustomerResponsePayload indexCustomer(); 26 | 27 | @GetMapping(value = "/show/{id}", produces = "application/json") 28 | public @ResponseBody Customer showCustomer(@NotNull @PathVariable("id") String id); 29 | 30 | @PutMapping("/update") 31 | public ResponsePayload updateCustomer(@NotNull @RequestBody UpsertCustomerRequestPayload upsertCustomerRequestPayload); 32 | 33 | @DeleteMapping("/delete/{id}") 34 | public ResponsePayload deleteCustomer(@NotNull @PathVariable("id") String id); 35 | } 36 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/adapter/PaymentAdapter.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertPaymentRequestPayload; 4 | import com.joshua.StockManagementSystem.joseph_api.model.Payment; 5 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.PaymentDataEntity; 6 | 7 | import java.sql.ResultSet; 8 | import java.sql.SQLException; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | public class PaymentAdapter { 13 | public static PaymentDataEntity convertResultSetToDataEntity(ResultSet resultSet) { 14 | try { 15 | return new PaymentDataEntity() 16 | .setId(resultSet.getString(PaymentDataEntity.ID)) 17 | .setPayment_type(resultSet.getString(PaymentDataEntity.TYPE)); 18 | } catch (SQLException throwables) { 19 | return new PaymentDataEntity(); 20 | } 21 | } 22 | 23 | public static PaymentDataEntity convertUpsertPayloadToDataEntity(UpsertPaymentRequestPayload upsertPaymentRequestPayload) { 24 | 25 | return new PaymentDataEntity() 26 | .setId(upsertPaymentRequestPayload.getId()) 27 | .setPayment_type(upsertPaymentRequestPayload.getPaymentType()); 28 | } 29 | 30 | public static List convertDataEntitiesToModels(List dataEntities){ 31 | return dataEntities.stream() 32 | .map( 33 | paymentDataEntity -> new Payment() 34 | .setId(paymentDataEntity.getId()) 35 | .setPaymentType(paymentDataEntity.getPayment_type()) 36 | ).collect(Collectors.toList()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/flushout/ItemDataEntity.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class ItemDataEntity extends JosephDataEntity{ 6 | private String itemCode, name, description; 7 | private BigDecimal price; 8 | private Integer stock, capacity; 9 | 10 | public static String ITEMCODE = "item_code", NAME = "name", DESCRIPTION = "description", 11 | PRICE = "price",STOCK = "stock",CAPACITY = "capacity"; 12 | 13 | public ItemDataEntity() { 14 | TABLE = "items"; 15 | numColumns = 6; 16 | } 17 | 18 | public String getItemCode() { 19 | return itemCode; 20 | } 21 | 22 | public ItemDataEntity setItemCode(String itemCode) { 23 | this.itemCode = itemCode;return this; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public ItemDataEntity setName(String name) { 31 | this.name = name;return this; 32 | } 33 | 34 | public String getDescription() { 35 | return description; 36 | } 37 | 38 | public ItemDataEntity setDescription(String description) { 39 | this.description = description;return this; 40 | } 41 | 42 | public BigDecimal getPrice() { 43 | return price; 44 | } 45 | 46 | public ItemDataEntity setPrice(BigDecimal price) { 47 | this.price = price;return this; 48 | } 49 | 50 | public Integer getStock() { 51 | return stock; 52 | } 53 | 54 | public ItemDataEntity setStock(Integer stock) { 55 | this.stock = stock;return this; 56 | } 57 | 58 | public Integer getCapacity() { 59 | return capacity; 60 | } 61 | 62 | public ItemDataEntity setCapacity(Integer capacity) { 63 | this.capacity = capacity;return this; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/pages/Home.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link, RouteComponentProps } from 'react-router-dom'; 3 | import { SpecialButton } from '../components/molecules/SpecialButton'; 4 | import { Dashboard } from '../components/template/Dashboard'; 5 | import { Typography } from '@material-ui/core'; 6 | 7 | interface Props extends RouteComponentProps{}; 8 | 9 | // history itu didapet dari props 10 | // kalo pake Link nya react-router ga perlu props history 11 | // history di pass dari Route nya react-router-dom 12 | export const Home: React.FC = ({ history,location,match }) => { 13 | 14 | console.log(location); 15 | // location.search bisa kaya buat ambil pathvariable 16 | console.log(match); 17 | return ( 18 |
19 | 23 |
24 |
25 |
26 | 27 |
28 |
29 | 30 | Hello, Welcome to Joseph 31 | 32 | 33 | Stock Management System 34 | 35 |
36 |
37 |
} 38 | 39 | /> 40 | {/* 41 | go to about 42 | 43 | 48 | 49 | */} 50 | 51 | ) 52 | }; 53 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/dialog/AlertDialog.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Button from '@material-ui/core/Button'; 3 | import Dialog from '@material-ui/core/Dialog'; 4 | import DialogActions from '@material-ui/core/DialogActions'; 5 | import DialogContent from '@material-ui/core/DialogContent'; 6 | import DialogContentText from '@material-ui/core/DialogContentText'; 7 | import DialogTitle from '@material-ui/core/DialogTitle'; 8 | 9 | export function AlertDialog(props:any) { 10 | const [open, setOpen] = React.useState(false); 11 | 12 | const handleClickOpen = () => { 13 | setOpen(true); 14 | console.log(open+"_"+props.parentAllowance) 15 | props.parentCallbackOpen(); 16 | }; 17 | 18 | const handleClose = (isYes:boolean) => { 19 | if(props.usingAction) props.parentCallback(isYes, props.param); 20 | setOpen(false); 21 | }; 22 | 23 | return ( 24 |
25 | 28 | handleClose(false)} 31 | aria-labelledby="alert-dialog-title" 32 | aria-describedby="alert-dialog-description" 33 | > 34 | {props.dialogTitle} 35 | 36 | 37 | {props.dialogContent} 38 | 39 | 40 | { 41 | (props.usingAction) && 42 | ( 43 | 46 | 49 | )} 50 | 51 |
52 | ); 53 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/adapter/UserAdapter.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter; 2 | 3 | import com.joshua.StockManagementSystem.auth.User; 4 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.UserDataEntity; 5 | import com.joshua.StockManagementSystem.security.UserRole; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.sql.ResultSet; 10 | import java.sql.SQLException; 11 | import java.util.List; 12 | import java.util.stream.Collectors; 13 | 14 | public class UserAdapter { 15 | private final static Logger logger = LoggerFactory.getLogger(UserAdapter.class); 16 | 17 | public static UserDataEntity resulltSetToDataEntity(ResultSet resultSet) { 18 | try{ 19 | return new UserDataEntity( 20 | resultSet.getString(UserDataEntity.USERNAME), 21 | resultSet.getString(UserDataEntity.PASSWORD), 22 | resultSet.getString(UserDataEntity.ROLE), 23 | resultSet.getBoolean(UserDataEntity.ACC_NON_EXP), 24 | resultSet.getBoolean(UserDataEntity.ACC_NON_LOCKED), 25 | resultSet.getBoolean(UserDataEntity.CRED_NON_EXP), 26 | resultSet.getBoolean(UserDataEntity.IS_ENABLED) 27 | ); 28 | } catch (SQLException throwable) { 29 | logger.error(String.valueOf(throwable)); 30 | return new UserDataEntity(); 31 | } 32 | } 33 | 34 | public static List dataEntitiesToModels(List userDataEntities) { 35 | return userDataEntities.stream().map( 36 | userDataEntity -> new User( 37 | UserRole.valueOf(userDataEntity.getRole()).getGrantedAuthorities(), 38 | userDataEntity.getPassword(), 39 | userDataEntity.getUsername(), 40 | userDataEntity.getAccNonExp(), 41 | userDataEntity.getAccNonLocked(), 42 | userDataEntity.getCredNonExp(), 43 | userDataEntity.getEnabled() 44 | ) 45 | ).collect(Collectors.toList()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/upsert/UpsertTransactionHeaderRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.upsert; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | public class UpsertTransactionHeaderRequestPayload { 7 | private String id, customerId, paymentId; 8 | private Date transactionDate; 9 | private String paymentStatus, note; 10 | 11 | List transactionDetails; 12 | 13 | public String getId() { 14 | return id; 15 | } 16 | 17 | public void setId(String id) { 18 | this.id = id; 19 | } 20 | 21 | public String getCustomerId() { 22 | return customerId; 23 | } 24 | 25 | public void setCustomerId(String customerId) { 26 | this.customerId = customerId; 27 | } 28 | 29 | public String getPaymentId() { 30 | return paymentId; 31 | } 32 | 33 | public void setPaymentId(String paymentId) { 34 | this.paymentId = paymentId; 35 | } 36 | 37 | public Date getTransactionDate() { 38 | return transactionDate; 39 | } 40 | 41 | public void setTransactionDate(Date transactionDate) { 42 | this.transactionDate = transactionDate; 43 | } 44 | 45 | public String getPaymentStatus() { 46 | return paymentStatus; 47 | } 48 | 49 | public void setPaymentStatus(String paymentStatus) { 50 | this.paymentStatus = paymentStatus; 51 | } 52 | 53 | public List getTransactionDetails() { 54 | return transactionDetails; 55 | } 56 | 57 | public UpsertTransactionHeaderRequestPayload setTransactionDetails(List transactionDetails) { 58 | this.transactionDetails = transactionDetails;return this; 59 | } 60 | 61 | public String getNote() { 62 | return note; 63 | } 64 | 65 | public UpsertTransactionHeaderRequestPayload setNote(String note) { 66 | this.note = note;return this; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/auth/UserDataAccessService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.auth; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.joshua.StockManagementSystem.security.UserPermission; 5 | import com.joshua.StockManagementSystem.security.UserRole; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.crypto.password.PasswordEncoder; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | import java.util.Optional; 12 | 13 | @Repository("inMemoryUser") 14 | public class UserDataAccessService implements UserDAO{ 15 | private final PasswordEncoder passwordEncoder; 16 | 17 | @Autowired 18 | public UserDataAccessService(PasswordEncoder passwordEncoder) { 19 | this.passwordEncoder = passwordEncoder; 20 | } 21 | 22 | @Override 23 | public Optional selectUserByUsername(String username) { 24 | List users = getAppUsers(); 25 | Optional found = users 26 | .stream() 27 | .filter( 28 | appUser -> username.equals(appUser.getUsername()) 29 | ).findFirst(); 30 | return found; 31 | } 32 | 33 | private List getAppUsers(){ 34 | List users = Lists.newArrayList( 35 | new User( 36 | UserRole.MEMBER.getGrantedAuthorities(), 37 | passwordEncoder.encode("member1"), 38 | "member1", 39 | true,true,true,true 40 | ), 41 | new User( 42 | UserRole.ADMIN.getGrantedAuthorities(), 43 | passwordEncoder.encode("admin1"), 44 | "admin1", 45 | true,true,true,true 46 | ),new User( 47 | UserRole.STRANGER.getGrantedAuthorities(), 48 | passwordEncoder.encode("stranger1"), 49 | "stranger1", 50 | true,true,true,true 51 | ) 52 | ); 53 | return users; 54 | } 55 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/ItemAPIController.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.ResponsePayload; 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexItemRequestPayload; 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexItemResponsePayload; 6 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertItemRequestPayload; 7 | import com.joshua.StockManagementSystem.joseph_api.model.Item; 8 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import javax.servlet.http.HttpServletResponse; 13 | import javax.validation.constraints.NotNull; 14 | import java.io.IOException; 15 | 16 | @CrossOrigin(origins = "*", allowedHeaders = "*") 17 | @RequestMapping("api/v1/joseph/item") 18 | @RestController 19 | @EnableAutoConfiguration 20 | @Component("itemAPIV1") 21 | public interface ItemAPIController { 22 | @PostMapping("/insert") 23 | public ResponsePayload insertItem(@NotNull @RequestBody UpsertItemRequestPayload upsertItemRequestPayload); 24 | 25 | @PostMapping(value = "/", produces = "application/json") 26 | public @ResponseBody 27 | IndexItemResponsePayload indexItem(@NotNull @RequestBody IndexItemRequestPayload indexItemRequestPayload); 28 | 29 | @GetMapping(value = "/show/{id}", produces = "application/json") 30 | public @ResponseBody 31 | Item showIndex(@NotNull @PathVariable("id") String id); 32 | 33 | @PutMapping("/update") 34 | public ResponsePayload updateItem(@NotNull @RequestBody UpsertItemRequestPayload upsertItemRequestPayload); 35 | 36 | @DeleteMapping("/delete/{id}") 37 | public ResponsePayload deleteItem(@NotNull @PathVariable("id") String id); 38 | 39 | @PostMapping("/report") 40 | public void generateReport( 41 | HttpServletResponse response, 42 | @NotNull @RequestBody IndexItemRequestPayload indexItemRequestPayload) throws IOException; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/adapter/CustomerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertCustomerRequestPayload; 4 | import com.joshua.StockManagementSystem.joseph_api.model.Customer; 5 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.CustomerDataEntity; 6 | 7 | import java.sql.ResultSet; 8 | import java.sql.SQLException; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | public class CustomerAdapter { 13 | public static CustomerDataEntity convertResultSetToDataEntity(ResultSet resultSet) { 14 | try { 15 | return new CustomerDataEntity() 16 | .setId(resultSet.getString(CustomerDataEntity.ID)) 17 | .setName(resultSet.getString(CustomerDataEntity.NAME)) 18 | .setContact(resultSet.getString(CustomerDataEntity.CONTACT)) 19 | .setDescription(resultSet.getString(CustomerDataEntity.DESCRIPTION)); 20 | } catch (SQLException throwables) { 21 | return new CustomerDataEntity(); 22 | } 23 | } 24 | 25 | public static CustomerDataEntity convertUpsertPayloadToDataEntity(UpsertCustomerRequestPayload upsertCustomerRequestPayload) { 26 | 27 | return new CustomerDataEntity() 28 | .setId(upsertCustomerRequestPayload.getId()) 29 | .setName(upsertCustomerRequestPayload.getName()) 30 | .setContact(upsertCustomerRequestPayload.getDescription()) 31 | .setDescription(upsertCustomerRequestPayload.getContact()); 32 | } 33 | 34 | public static List convertDataEntitiesToModels(List dataEntities){ 35 | return dataEntities.stream() 36 | .map( 37 | customerDataEntity -> new Customer().setId(customerDataEntity.getId()) 38 | .setName(customerDataEntity.getName()) 39 | .setContact(customerDataEntity.getContact()) 40 | .setDescription(customerDataEntity.getDescription()) 41 | ).collect(Collectors.toList()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/flushout/TransactionDetailDataEntity.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout; 2 | 3 | import java.math.BigDecimal; 4 | import java.sql.Timestamp; 5 | 6 | public class TransactionDetailDataEntity extends JosephDataEntity{ 7 | private String transactionHeaderId, itemCode; 8 | private BigDecimal price; 9 | private Integer quantity; 10 | private String note; 11 | private Timestamp timestamp; 12 | 13 | public static final String TRANSHID = "transaction_header_id", 14 | ITEMCODE = "item_code", PRICE = "price", 15 | QTY = "quantity", 16 | NOTE = "note", 17 | TIMESTAMP = "timestamp"; 18 | 19 | public TransactionDetailDataEntity() { 20 | TABLE = "transaction_details"; 21 | numColumns = 5; 22 | } 23 | 24 | public String getTransactionHeaderId() { 25 | return transactionHeaderId; 26 | } 27 | 28 | public TransactionDetailDataEntity setTransactionHeaderId(String transactionHeaderId) { 29 | this.transactionHeaderId = transactionHeaderId;return this; 30 | } 31 | 32 | public String getItemCode() { 33 | return itemCode; 34 | } 35 | 36 | public TransactionDetailDataEntity setItemCode(String itemCode) { 37 | this.itemCode = itemCode;return this; 38 | } 39 | 40 | public BigDecimal getPrice() { 41 | return price; 42 | } 43 | 44 | public TransactionDetailDataEntity setPrice(BigDecimal price) { 45 | this.price = price;return this; 46 | } 47 | 48 | public Integer getQuantity() { 49 | return quantity; 50 | } 51 | 52 | public TransactionDetailDataEntity setQuantity(Integer quantity) { 53 | this.quantity = quantity;return this; 54 | } 55 | 56 | public String getNote() { 57 | return note; 58 | } 59 | 60 | public TransactionDetailDataEntity setNote(String note) { 61 | this.note = note;return this; 62 | } 63 | 64 | public Timestamp getTimestamp() { 65 | return timestamp; 66 | } 67 | 68 | public TransactionDetailDataEntity setTimestamp(Timestamp timestamp) { 69 | this.timestamp = timestamp;return this; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/auth/User.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.auth; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | 6 | import java.util.Collection; 7 | import java.util.Set; 8 | 9 | public class User implements UserDetails { 10 | 11 | private final Set grantedAuthorities; 12 | private final String password, username; 13 | private final boolean isAccountNonExpired, 14 | isAccountNonLocked, 15 | isCredentialNonExpired, 16 | isEnabled; 17 | 18 | /** 19 | * 20 | * @param grantedAuthorities 21 | * @param password 22 | * @param username 23 | * @param isAccountNonExpired 24 | * @param isAccountNonLocked 25 | * @param isCredentialNonExpired 26 | * @param isEnabled 27 | */ 28 | public User(Set grantedAuthorities, String password, String username, boolean isAccountNonExpired, boolean isAccountNonLocked, boolean isCredentialNonExpired, boolean isEnabled) { 29 | this.grantedAuthorities = grantedAuthorities; 30 | this.password = password; 31 | this.username = username; 32 | this.isAccountNonExpired = isAccountNonExpired; 33 | this.isAccountNonLocked = isAccountNonLocked; 34 | this.isCredentialNonExpired = isCredentialNonExpired; 35 | this.isEnabled = isEnabled; 36 | } 37 | 38 | @Override 39 | public Collection getAuthorities() { 40 | return grantedAuthorities; 41 | } 42 | 43 | @Override 44 | public String getPassword() { 45 | return password; 46 | } 47 | 48 | @Override 49 | public String getUsername() { 50 | return username; 51 | } 52 | 53 | @Override 54 | public boolean isAccountNonExpired() { 55 | return isAccountNonExpired; 56 | } 57 | 58 | @Override 59 | public boolean isAccountNonLocked() { 60 | return isAccountNonLocked; 61 | } 62 | 63 | @Override 64 | public boolean isCredentialsNonExpired() { 65 | return isCredentialNonExpired; 66 | } 67 | 68 | @Override 69 | public boolean isEnabled() { 70 | return isEnabled; 71 | } 72 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/TransactionAPIController.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.ResponsePayload; 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexTransactionRequestPayload; 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexTransactionResponsePayload; 6 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertTransactionHeaderRequestPayload; 7 | import com.joshua.StockManagementSystem.joseph_api.model.TransactionHeader; 8 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import javax.servlet.http.HttpServletResponse; 13 | import javax.validation.constraints.NotNull; 14 | import java.io.IOException; 15 | import java.util.List; 16 | 17 | 18 | @CrossOrigin(origins = "*", allowedHeaders = "*") 19 | @RequestMapping("api/v1/joseph/transaction") 20 | @RestController 21 | @EnableAutoConfiguration 22 | @Component("transactionV1API") 23 | public interface TransactionAPIController { 24 | @PostMapping("/insert") 25 | public ResponsePayload insert(@NotNull @RequestBody UpsertTransactionHeaderRequestPayload upsertTransactionHeaderRequestPayload); 26 | 27 | @PostMapping(value = "/", produces = "application/json") 28 | public @ResponseBody 29 | IndexTransactionResponsePayload index(@NotNull @RequestBody IndexTransactionRequestPayload indexTransactionRequestPayload); 30 | 31 | @GetMapping(value = "/show/{id}", produces = "application/json") 32 | public @ResponseBody TransactionHeader show(@NotNull @PathVariable("id") String id); 33 | 34 | @PutMapping("/update") 35 | public ResponsePayload update(@NotNull @RequestBody UpsertTransactionHeaderRequestPayload upsertTransactionHeaderRequestPayload); 36 | 37 | @DeleteMapping("/delete/{id}") 38 | public ResponsePayload delete(@NotNull @PathVariable("id") String id); 39 | 40 | @PostMapping("/report") 41 | public @ResponseBody void generateReport( 42 | HttpServletResponse response, 43 | @NotNull @RequestBody IndexTransactionRequestPayload indexTransactionRequestPayload) throws IOException; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/ItemPDF.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 38 | 39 | 40 |

STOCK MANAGEMENT SYSTEM

41 | 45 | 46 |

ITEM LIST

47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {{#items}} 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {{/items}} 73 |
NUMITEM CODENAMESTOCKPRICETOTAL SOLDGENERATED REVENUECAPACITYDESCRIPTION
{{@index}}{{itemCode}}{{name}}{{stock}}{{price}}{{totalSold}}{{incomeAmount}}{{capacity}}{{description}}
74 | 75 | 76 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/flushout/TransactionHeaderDataEntity.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout; 2 | 3 | import java.sql.Timestamp; 4 | import java.util.Date; 5 | 6 | public class TransactionHeaderDataEntity extends JosephDataEntity{ 7 | private String id, customerId, 8 | paymentId; 9 | private Date transactionDate; 10 | private String paymentStatus, note; 11 | private Timestamp timestamp; 12 | 13 | public static final String ID = "id", 14 | CUSTID = "customer_id", PAYID = "payment_id", 15 | TRANDATE = "transaction_date", 16 | PAYSTAT = "payment_status", 17 | NOTE = "note", 18 | TIMESTAMP = "timestamp"; 19 | 20 | public TransactionHeaderDataEntity() { 21 | TABLE = "transaction_headers"; 22 | numColumns = 6; 23 | } 24 | 25 | public String getId() { 26 | return id; 27 | } 28 | 29 | public TransactionHeaderDataEntity setId(String id) { 30 | this.id = id;return this; 31 | } 32 | 33 | public String getCustomerId() { 34 | return customerId; 35 | } 36 | 37 | public TransactionHeaderDataEntity setCustomerId(String customerId) { 38 | this.customerId = customerId;return this; 39 | } 40 | 41 | public String getPaymentId() { 42 | return paymentId; 43 | } 44 | 45 | public TransactionHeaderDataEntity setPaymentId(String paymentId) { 46 | this.paymentId = paymentId;return this; 47 | } 48 | 49 | public Date getTransactionDate() { 50 | return transactionDate; 51 | } 52 | 53 | public TransactionHeaderDataEntity setTransactionDate(Date transactionDate) { 54 | this.transactionDate = transactionDate;return this; 55 | } 56 | 57 | public String getPaymentStatus() { 58 | return paymentStatus; 59 | } 60 | 61 | public TransactionHeaderDataEntity setPaymentStatus(String paymentStatus) { 62 | this.paymentStatus = paymentStatus;return this; 63 | } 64 | 65 | public String getNote() { 66 | return note; 67 | } 68 | 69 | public TransactionHeaderDataEntity setNote(String note) { 70 | this.note = note;return this; 71 | } 72 | 73 | public Date getTimestamp() { 74 | return timestamp; 75 | } 76 | 77 | public TransactionHeaderDataEntity setTimestamp(Timestamp timestamp) { 78 | this.timestamp = timestamp;return this; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/flushout/UserDataEntity.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout; 2 | 3 | import com.joshua.StockManagementSystem.security.UserRole; 4 | 5 | public class UserDataEntity { 6 | public final String SCHEMA = "joseph_user,public"; 7 | public static final String TABLE = "users"; 8 | public final int numColumns = 7; 9 | public static String USERNAME="username", PASSWORD="password", ROLE="role", ACC_NON_EXP="is_account_non_expired", ACC_NON_LOCKED = "is_account_non_locked", CRED_NON_EXP = "is_credential_non_expired", IS_ENABLED="is_enabled"; 10 | private String username, password; 11 | private String role; 12 | private Boolean accNonExp, accNonLocked, credNonExp, isEnabled; 13 | public UserDataEntity() { 14 | } 15 | 16 | public UserDataEntity(String username, String password, String role, Boolean accNonExp, Boolean accNonLocked, Boolean credNonExp, Boolean isEnabled) { 17 | this.username = username; 18 | this.password = password; 19 | this.role = role; 20 | this.accNonExp = accNonExp; 21 | this.accNonLocked = accNonLocked; 22 | this.credNonExp = credNonExp; 23 | this.isEnabled = isEnabled; 24 | } 25 | 26 | public String getUsername() { 27 | return username; 28 | } 29 | 30 | public void setUsername(String username) { 31 | this.username = username; 32 | } 33 | 34 | public String getPassword() { 35 | return password; 36 | } 37 | 38 | public void setPassword(String password) { 39 | this.password = password; 40 | } 41 | 42 | public String getRole() { 43 | return role; 44 | } 45 | 46 | public void setRole(String role) { 47 | this.role = role; 48 | } 49 | 50 | public Boolean getAccNonExp() { 51 | return accNonExp; 52 | } 53 | 54 | public void setAccNonExp(Boolean accNonExp) { 55 | this.accNonExp = accNonExp; 56 | } 57 | 58 | public Boolean getAccNonLocked() { 59 | return accNonLocked; 60 | } 61 | 62 | public void setAccNonLocked(Boolean accNonLocked) { 63 | this.accNonLocked = accNonLocked; 64 | } 65 | 66 | public Boolean getCredNonExp() { 67 | return credNonExp; 68 | } 69 | 70 | public void setCredNonExp(Boolean credNonExp) { 71 | this.credNonExp = credNonExp; 72 | } 73 | 74 | public Boolean getEnabled() { 75 | return isEnabled; 76 | } 77 | 78 | public void setEnabled(Boolean enabled) { 79 | isEnabled = enabled; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/domain/ReportEngine.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.domain; 2 | 3 | import com.github.jknack.handlebars.Handlebars; 4 | import com.github.jknack.handlebars.Template; 5 | import com.lowagie.text.DocumentException; 6 | import org.w3c.dom.Document; 7 | import org.xhtmlrenderer.pdf.ITextRenderer; 8 | import org.xml.sax.SAXException; 9 | 10 | import javax.xml.parsers.DocumentBuilder; 11 | import javax.xml.parsers.DocumentBuilderFactory; 12 | import javax.xml.parsers.ParserConfigurationException; 13 | import java.io.*; 14 | import java.nio.charset.StandardCharsets; 15 | import java.util.Map; 16 | 17 | public class ReportEngine { 18 | private Handlebars handlebars; 19 | // nice source: https://andreldm.com/2017/04/15/flying-saucer-handlebars.html 20 | 21 | public ReportEngine(){ 22 | handlebars = new Handlebars(); 23 | handlebars.registerHelpers(new HandlebarsHelper()); 24 | } 25 | 26 | public void generate(String templateFile, String outputFile, Map data){ 27 | try(OutputStream outputStream = new FileOutputStream(new File("web/generatedpdf/"+outputFile))){ 28 | Template template = handlebars.compile(templateFile); 29 | 30 | String mergedTemplate = template.apply(data); 31 | 32 | Document doc = getDocumentBuilder().parse(new ByteArrayInputStream(mergedTemplate.getBytes("UTF-8"))); 33 | 34 | ITextRenderer renderer = new ITextRenderer(); 35 | renderer.setDocument(doc,null); 36 | renderer.layout(); 37 | renderer.createPDF(outputStream); 38 | renderer.finishPDF(); 39 | }catch (IOException | ParserConfigurationException | SAXException | DocumentException e){ 40 | e.printStackTrace(); 41 | } 42 | } 43 | 44 | // we use this method to create a DocumentBuild not so fanatic about XHTML 45 | private DocumentBuilder getDocumentBuilder() throws ParserConfigurationException { 46 | DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance(); 47 | fac.setNamespaceAware(false); 48 | fac.setValidating(false); 49 | fac.setFeature("http://xml.org/sax/features/namespaces", false); 50 | fac.setFeature("http://xml.org/sax/features/validation", false); 51 | fac.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); 52 | fac.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 53 | return fac.newDocumentBuilder(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/model/TransactionDetail.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.model; 2 | 3 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper; 4 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.TransactionDetailDataEntity; 5 | import org.joda.money.BigMoney; 6 | import org.joda.money.CurrencyUnit; 7 | import org.joda.money.Money; 8 | 9 | import java.math.BigDecimal; 10 | import java.util.Date; 11 | 12 | public class TransactionDetail { 13 | private String transactionHeaderId, itemCode; 14 | private BigDecimal price; 15 | private Integer quantity; 16 | private String note; 17 | private Date timestamp; 18 | private BigDecimal subTotal; 19 | 20 | public String getTransactionHeaderId() { 21 | return transactionHeaderId; 22 | } 23 | 24 | public TransactionDetail setTransactionHeaderId(String transactionHeaderId) { 25 | this.transactionHeaderId = transactionHeaderId;return this; 26 | } 27 | 28 | public String getItemCode() { 29 | return itemCode; 30 | } 31 | 32 | public TransactionDetail setItemCode(String itemCode) { 33 | this.itemCode = itemCode;return this; 34 | } 35 | 36 | public String getPrice() { 37 | return PostgresHelper.formatCurrency(price); 38 | } 39 | 40 | public TransactionDetail setPrice(BigDecimal price) { 41 | this.price = price;return this; 42 | } 43 | 44 | public Integer getQuantity() { 45 | return quantity; 46 | } 47 | 48 | public TransactionDetail setQuantity(Integer quantity) { 49 | this.quantity = quantity;return this; 50 | } 51 | 52 | public String getNote() { 53 | return note; 54 | } 55 | 56 | public TransactionDetail setNote(String note) { 57 | this.note = note;return this; 58 | } 59 | 60 | public Date getTimestamp() { 61 | return timestamp; 62 | } 63 | 64 | public TransactionDetail setTimestamp(Date timestamp) { 65 | this.timestamp = timestamp;return this; 66 | } 67 | 68 | public String getSubTotal() { 69 | return PostgresHelper.formatCurrency(getSubTotalDec()); 70 | } 71 | 72 | public BigDecimal getSubTotalDec() { 73 | return BigDecimal.valueOf(quantity).multiply(price); 74 | } 75 | 76 | public TransactionDetail setSubTotal(BigDecimal subTotal) { 77 | this.subTotal = subTotal;return this; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/adapter/ItemAdapter.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertItemRequestPayload; 4 | import com.joshua.StockManagementSystem.joseph_api.model.Item; 5 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.ItemDataEntity; 6 | 7 | import java.sql.ResultSet; 8 | import java.sql.SQLException; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | public class ItemAdapter { 13 | public static ItemDataEntity convertResultSetToDataEntity(ResultSet resultSet) { 14 | try { 15 | return new ItemDataEntity() 16 | .setItemCode(resultSet.getString(ItemDataEntity.ITEMCODE)) 17 | .setName(resultSet.getString(ItemDataEntity.NAME)) 18 | .setDescription(resultSet.getString(ItemDataEntity.DESCRIPTION)) 19 | .setPrice(resultSet.getBigDecimal(ItemDataEntity.PRICE)) 20 | .setStock(resultSet.getInt(ItemDataEntity.STOCK)) 21 | .setCapacity(resultSet.getInt(ItemDataEntity.CAPACITY)) 22 | ; 23 | } catch (SQLException throwables) { 24 | return null; 25 | } 26 | } 27 | 28 | public static ItemDataEntity convertUpsertPayloadToDataEntity(UpsertItemRequestPayload upsertItemRequestPayload) { 29 | 30 | return new ItemDataEntity() 31 | .setItemCode(upsertItemRequestPayload.getItemCode()) 32 | .setName(upsertItemRequestPayload.getName()) 33 | .setDescription(upsertItemRequestPayload.getDescription()) 34 | .setPrice(upsertItemRequestPayload.getPrice()) 35 | .setStock(upsertItemRequestPayload.getStock()) 36 | .setCapacity(upsertItemRequestPayload.getCapacity()); 37 | } 38 | 39 | public static List convertDataEntitiesToModels(List dataEntities){ 40 | return dataEntities.stream() 41 | .map( 42 | itemDataEntity -> new Item() 43 | .setItemCode(itemDataEntity.getItemCode()) 44 | .setName(itemDataEntity.getName()) 45 | .setDescription(itemDataEntity.getDescription()) 46 | .setPrice(itemDataEntity.getPrice()) 47 | .setStock(itemDataEntity.getStock()) 48 | .setCapacity(itemDataEntity.getCapacity()) 49 | ).collect(Collectors.toList()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/model/Item.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.model; 2 | 3 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper; 4 | 5 | import java.math.BigDecimal; 6 | 7 | public class Item { 8 | private String itemCode, name,description; 9 | private BigDecimal price; 10 | private Integer stock, capacity; 11 | private Integer totalSold = 0; 12 | private BigDecimal incomeAmountDec = BigDecimal.valueOf(0); 13 | private String incomeAmount = PostgresHelper.formatCurrency(BigDecimal.valueOf(0)); 14 | 15 | public String getItemCode() { 16 | return itemCode; 17 | } 18 | 19 | public Item setItemCode(String itemCode) { 20 | this.itemCode = itemCode;return this; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public Item setName(String name) { 28 | this.name = name;return this; 29 | } 30 | 31 | public String getDescription() { 32 | return description; 33 | } 34 | 35 | public Item setDescription(String description) { 36 | this.description = description;return this; 37 | } 38 | 39 | public BigDecimal getPriceDec() { 40 | return price; 41 | } 42 | 43 | public String getPrice() { 44 | return PostgresHelper.formatCurrency(price); 45 | } 46 | 47 | public Item setPrice(BigDecimal price) { 48 | this.price = price;return this; 49 | } 50 | 51 | public Integer getStock() { 52 | return stock; 53 | } 54 | 55 | public Item setStock(Integer stock) { 56 | this.stock = stock;return this; 57 | } 58 | 59 | public Integer getCapacity() { 60 | return capacity; 61 | } 62 | 63 | public Item setCapacity(Integer capacity) { 64 | this.capacity = capacity;return this; 65 | } 66 | 67 | public Integer getTotalSold() { 68 | return totalSold; 69 | } 70 | 71 | public Item setTotalSold(Integer totalSold) { 72 | this.totalSold = totalSold;return this; 73 | } 74 | 75 | public String getIncomeAmount() { 76 | return PostgresHelper.formatCurrency(incomeAmountDec); 77 | } 78 | 79 | public Item setIncomeAmount(String incomeAmount) { 80 | this.incomeAmount = incomeAmount;return this; 81 | } 82 | 83 | public BigDecimal getIncomeAmountDec() { 84 | return incomeAmountDec; 85 | } 86 | 87 | public Item setIncomeAmountDec(BigDecimal incomeAmountDec) { 88 | this.incomeAmountDec = incomeAmountDec;return this; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/api/payload/index/IndexTransactionRequestPayload.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.api.payload.index; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | public class IndexTransactionRequestPayload { 7 | private List customerFilter = new LinkedList<>(); 8 | private List itemFilter = new LinkedList<>(); 9 | private List paymentFilter = new LinkedList<>(); 10 | private List transactionIdFilter = new LinkedList<>(); 11 | private Integer sortByDate = 0, sortByTotal = 0; 12 | 13 | 14 | private String dateFilter = ""; 15 | private String endDateFilter = ""; 16 | 17 | public List getCustomerFilter() { 18 | return customerFilter; 19 | } 20 | 21 | public IndexTransactionRequestPayload setCustomerFilter(List customerFilter) { 22 | this.customerFilter = customerFilter;return this; 23 | } 24 | 25 | public List getItemFilter() { 26 | return itemFilter; 27 | } 28 | 29 | public IndexTransactionRequestPayload setItemFilter(List itemFilter) { 30 | this.itemFilter = itemFilter;return this; 31 | } 32 | 33 | public List getPaymentFilter() { 34 | return paymentFilter; 35 | } 36 | 37 | public IndexTransactionRequestPayload setPaymentFilter(List paymentFilter) { 38 | this.paymentFilter = paymentFilter;return this; 39 | } 40 | 41 | public String getDateFilter() { 42 | return dateFilter; 43 | } 44 | 45 | public IndexTransactionRequestPayload setDateFilter(String dateFilter) { 46 | this.dateFilter = dateFilter;return this; 47 | } 48 | 49 | public String getEndDateFilter() { 50 | return endDateFilter; 51 | } 52 | 53 | public IndexTransactionRequestPayload setEndDateFilter(String endDateFilter) { 54 | this.endDateFilter = endDateFilter;return this; 55 | } 56 | 57 | public List getTransactionIdFilter() { 58 | return transactionIdFilter; 59 | } 60 | 61 | public IndexTransactionRequestPayload setTransactionIdFilter(List transactionIdFilter) { 62 | this.transactionIdFilter = transactionIdFilter;return this; 63 | } 64 | 65 | public Integer getSortByDate() { 66 | return sortByDate; 67 | } 68 | 69 | public IndexTransactionRequestPayload setSortByDate(Integer sortByDate) { 70 | this.sortByDate = sortByDate;return this; 71 | } 72 | 73 | public Integer getSortByTotal() { 74 | return sortByTotal; 75 | } 76 | 77 | public IndexTransactionRequestPayload setSortByTotal(Integer sortByTotal) { 78 | this.sortByTotal = sortByTotal;return this; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/form/PayTypeForm.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Formik, Field, useField, FieldAttributes, FieldArray } from 'formik'; 3 | import { TextField, Button, Checkbox, Radio, Select, MenuItem, TextareaAutosize, Typography, FormControl, InputLabel } from '@material-ui/core'; 4 | import * as yup from 'yup'; 5 | import { serviceIndexItem } from '../../../data/services'; 6 | import { IItem } from '../../../data/interfaces'; 7 | 8 | const validationSchema = yup.object({ 9 | id: yup.string().required("Production Id must be filled"), 10 | paymentType: yup.string().required("Payment Type Name must be filled"), 11 | }) 12 | 13 | const TextFieldWValidation:any = ({placeholder,type,...props}) => { 14 | const [field, meta] = useField<{}>(props); 15 | const errorText = meta.error && meta.touched ? meta.error : ""; 16 | return( 17 | 19 | ) 20 | } 21 | 22 | export class PayTypeForm extends React.Component{ 23 | render(){ 24 | return ( 25 |
26 | 27 | { 34 | setSubmitting(true) 35 | console.log(data); 36 | console.log("SUBMITTING") 37 | 38 | this.props.submitData(data); 39 | 40 | setSubmitting(false); 41 | console.log("done submit add data") 42 | }} 43 | 44 | validationSchema = {validationSchema} 45 | 46 | > 47 | { 48 | ({ errors, values, isSubmitting, /*handleChange, handleBlur, */handleSubmit }) => ( 49 | 50 |
51 | 52 | 53 | {!this.props.isEdit &&
54 | 59 |
} 60 | 61 |
62 | 68 |
69 | 70 | 74 | 75 |
76 | ) 77 | } 78 |
79 |
80 | ) 81 | } 82 | } -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/adapter/ProductionAdapter.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter; 2 | 3 | 4 | 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertProductionRequestPayload; 6 | import com.joshua.StockManagementSystem.joseph_api.model.Production; 7 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.ProductionDataEntity; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.sql.ResultSet; 12 | import java.sql.SQLException; 13 | import java.util.List; 14 | import java.util.stream.Collectors; 15 | 16 | public class ProductionAdapter { 17 | private final static Logger log = LoggerFactory.getLogger(ProductionAdapter.class); 18 | public static ProductionDataEntity convertResultSetToDataEntity(ResultSet resultSet) { 19 | try { 20 | return new ProductionDataEntity() 21 | .setId(resultSet.getString(ProductionDataEntity.ID)) 22 | .setItemCode(resultSet.getString(ProductionDataEntity.ITEMCODE)) 23 | .setProducer(resultSet.getString(ProductionDataEntity.PRODUCER)) 24 | .setProductionDate(resultSet.getDate(ProductionDataEntity.PRODDATE)) 25 | .setQuantity(resultSet.getInt(ProductionDataEntity.QTY)); 26 | } catch (SQLException throwables) { 27 | log.error("error covertResultSet ",throwables); 28 | return null; 29 | } 30 | } 31 | 32 | public static ProductionDataEntity convertUpsertPayloadToDataEntity(UpsertProductionRequestPayload upsertProductionRequestPayload) { 33 | 34 | return new ProductionDataEntity() 35 | .setId(upsertProductionRequestPayload.getId()) 36 | .setItemCode(upsertProductionRequestPayload.getItemCode()) 37 | .setProducer(upsertProductionRequestPayload.getProducer()) 38 | .setProductionDate(upsertProductionRequestPayload.getProductionDate()) 39 | .setQuantity(upsertProductionRequestPayload.getQuantity()); 40 | } 41 | 42 | public static List convertDataEntitiesToModels(List dataEntities){ 43 | return dataEntities.stream() 44 | .map( 45 | productionDataEntity -> new Production() 46 | .setId(productionDataEntity.getId()) 47 | .setItemCode(productionDataEntity.getItemCode()) 48 | .setProducer(productionDataEntity.getProducer()) 49 | .setProductionDate(productionDataEntity.getProductionDate()) 50 | .setQuantity(productionDataEntity.getQuantity()) 51 | ).collect(Collectors.toList()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/api/PaymentAPIControllerImpl.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.api; 2 | 3 | 4 | import com.joshua.StockManagementSystem.joseph_api.api.PaymentAPIController; 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.ResponsePayload; 6 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexPayTypeResponsePayload; 7 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertPaymentRequestPayload; 8 | import com.joshua.StockManagementSystem.joseph_api.domain.PaymentService; 9 | import com.joshua.StockManagementSystem.joseph_api.model.Payment; 10 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.HttpStatus; 11 | import com.joshua.StockManagementSystem.util.Pair; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.beans.factory.annotation.Qualifier; 14 | import org.springframework.stereotype.Component; 15 | 16 | import javax.validation.constraints.NotNull; 17 | import java.util.List; 18 | 19 | @Component("paymentV1API") 20 | public class PaymentAPIControllerImpl implements PaymentAPIController { 21 | 22 | private final PaymentService paymentService; 23 | 24 | @Autowired 25 | public PaymentAPIControllerImpl(@Qualifier("paymentV1Service") PaymentService paymentService) { 26 | this.paymentService = paymentService; 27 | } 28 | 29 | @Override 30 | public ResponsePayload insert(@NotNull UpsertPaymentRequestPayload upsertPaymentRequestPayload) { 31 | Pair> ret = paymentService.insert(upsertPaymentRequestPayload); 32 | return new ResponsePayload().setStatus((ret.getKey() ? HttpStatus.SUCCESS : HttpStatus.FAIL).toString()) 33 | .setMessage(ret.getValue()); 34 | } 35 | 36 | @Override 37 | public IndexPayTypeResponsePayload index() { 38 | return new IndexPayTypeResponsePayload().setPaymentTypes(paymentService.index()); 39 | } 40 | 41 | @Override 42 | public Payment show(@NotNull String id) { 43 | return paymentService.show(id); 44 | } 45 | 46 | @Override 47 | public ResponsePayload update(@NotNull UpsertPaymentRequestPayload upsertPaymentRequestPayload) { 48 | Pair> ret = paymentService.update(upsertPaymentRequestPayload); 49 | return new ResponsePayload().setStatus((ret.getKey() ? HttpStatus.SUCCESS : HttpStatus.FAIL).toString()) 50 | .setMessage(ret.getValue()); 51 | } 52 | 53 | @Override 54 | public ResponsePayload delete(@NotNull String id) { 55 | Pair> ret = paymentService.delete(id); 56 | return new ResponsePayload().setStatus((ret.getKey() ? HttpStatus.SUCCESS : HttpStatus.FAIL).toString()).setMessage(ret.getValue()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/resources/TransactionPDF.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 38 | 39 | 40 |

STOCK MANAGEMENT SYSTEM

41 | 45 | 46 |

TRANSACTIONS FROM {{startDate}} TO {{endDate}}

47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {{#transactions}} 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 88 | 89 | 90 | 91 | 92 | {{/transactions}} 93 |
NUMIDCUSTOMER IDPAYMENT IDDATEPAYMENT STATUSDETAILSTOTALNOTEDATA LAST UPDATED
{{@index}}{{id}}{{customerId}}{{paymentId}}{{transactionDate}}{{paymentStatus}} 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | {{#transactionDetails}} 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | {{/transactionDetails}} 86 |
ITEM CODEPRICEQUANTITYSUBTOTALNOTE
{{itemCode}}{{price}}{{quantity}}{{subTotal}}{{note}}
87 |
{{total}}{{note}}{{timestamp}}
94 | 95 | 96 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/api/CustomerAPIControllerImpl.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.api; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.CustomerAPIController; 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.ResponsePayload; 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexCustomerResponsePayload; 6 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertCustomerRequestPayload; 7 | import com.joshua.StockManagementSystem.joseph_api.domain.CustomerService; 8 | import com.joshua.StockManagementSystem.joseph_api.model.Customer; 9 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.HttpStatus; 10 | import com.joshua.StockManagementSystem.util.Pair; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.beans.factory.annotation.Qualifier; 13 | import org.springframework.stereotype.Component; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.ResponseBody; 16 | 17 | import javax.validation.constraints.NotNull; 18 | import java.util.List; 19 | 20 | @Component("custAPIV1") 21 | public class CustomerAPIControllerImpl implements CustomerAPIController { 22 | private final CustomerService customerService; 23 | 24 | @Autowired 25 | public CustomerAPIControllerImpl(@Qualifier("custV1Service") CustomerService customerService) { 26 | this.customerService = customerService; 27 | } 28 | 29 | @Override 30 | public ResponsePayload insertCustomer(@NotNull @RequestBody UpsertCustomerRequestPayload upsertCustomerRequestPayload) { 31 | Pair> res =customerService.insertCustomer(upsertCustomerRequestPayload); 32 | return new ResponsePayload().setMessage(res.getValue()).setStatus(res.getKey() ? HttpStatus.SUCCESS.toString() : HttpStatus.FAIL.toString()); 33 | } 34 | 35 | @Override 36 | public @ResponseBody 37 | IndexCustomerResponsePayload indexCustomer() { 38 | return new IndexCustomerResponsePayload().setCustomers(customerService.indexCustomer()); 39 | } 40 | 41 | @Override 42 | public Customer showCustomer(String id) { 43 | return customerService.showCustomer(id); 44 | } 45 | 46 | @Override 47 | public ResponsePayload updateCustomer(@NotNull UpsertCustomerRequestPayload upsertCustomerRequestPayload) { 48 | Pair> res = customerService.updateCustomer(upsertCustomerRequestPayload); 49 | return new ResponsePayload().setStatus(res.getKey() ? HttpStatus.SUCCESS.toString() : HttpStatus.FAIL.toString()).setMessage(res.getValue()); 50 | } 51 | 52 | @Override 53 | public ResponsePayload deleteCustomer(@NotNull String id) { 54 | Pair> res = customerService.deleteCustomer(id); 55 | return new ResponsePayload().setStatus(res.getKey() ? HttpStatus.SUCCESS.toString() : HttpStatus.FAIL.toString()).setMessage(res.getValue()); 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/domain/PaymentServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.domain; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertPaymentRequestPayload; 4 | import com.joshua.StockManagementSystem.joseph_api.domain.PaymentService; 5 | import com.joshua.StockManagementSystem.joseph_api.infrastructure.dao.PaymentDAO; 6 | import com.joshua.StockManagementSystem.joseph_api.model.Payment; 7 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper; 8 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.PaymentDataEntity; 9 | import com.joshua.StockManagementSystem.util.Pair; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.beans.factory.annotation.Qualifier; 12 | import org.springframework.stereotype.Component; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.Collections; 16 | import java.util.LinkedList; 17 | import java.util.List; 18 | 19 | import static com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper.*; 20 | import static com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter.PaymentAdapter.*; 21 | 22 | @Component("paymentV1Service") 23 | @Service 24 | public class PaymentServiceImpl implements PaymentService { 25 | private final PaymentDAO paymentDAO; 26 | 27 | @Autowired 28 | public PaymentServiceImpl(@Qualifier("postgresPayment") PaymentDAO paymentDAO) { 29 | this.paymentDAO = paymentDAO; 30 | } 31 | 32 | @Override 33 | public Pair> insert(UpsertPaymentRequestPayload upsertPaymentRequestPayload) { 34 | Integer flag = paymentDAO.insert(convertUpsertPayloadToDataEntity(upsertPaymentRequestPayload)); 35 | return new Pair<>( 36 | (flag ==1 ), 37 | Collections.singletonList(PAYTYPE+ upsertPaymentRequestPayload.getPaymentType()+ ((flag == 1) ? SUCCESS : FAIL)+ PostgresHelper.INSERTED) 38 | ); 39 | } 40 | 41 | @Override 42 | public List index() { 43 | return convertDataEntitiesToModels(paymentDAO.index()); 44 | } 45 | 46 | @Override 47 | public Payment show(String id) { 48 | PaymentDataEntity dataEntity = paymentDAO.show(id).orElse(null); 49 | return (dataEntity == null) ? null : 50 | convertDataEntitiesToModels(Collections.singletonList(dataEntity)).get(0); 51 | 52 | } 53 | 54 | @Override 55 | public Pair> update(UpsertPaymentRequestPayload upsertPaymentRequestPayload) { 56 | Integer flag = paymentDAO.update(convertUpsertPayloadToDataEntity(upsertPaymentRequestPayload)); 57 | return new Pair<>( 58 | (flag ==1 ), 59 | Collections.singletonList(PAYTYPE+ upsertPaymentRequestPayload.getPaymentType()+ ((flag == 1) ? SUCCESS : FAIL)+ UPDATED) 60 | ); 61 | } 62 | 63 | @Override 64 | public Pair> delete(String id) { 65 | Integer flag = paymentDAO.delete(id); 66 | return new Pair<>( 67 | (flag ==1 ), 68 | Collections.singletonList(PAYTYPE+ id+ ((flag == 1) ? SUCCESS : FAIL)+ REMOVED) 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/domain/ProductionServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.domain; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertProductionRequestPayload; 4 | import com.joshua.StockManagementSystem.joseph_api.domain.ProductionService; 5 | import com.joshua.StockManagementSystem.joseph_api.infrastructure.dao.ProductionDAO; 6 | import com.joshua.StockManagementSystem.joseph_api.model.Production; 7 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper; 8 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.ProductionDataEntity; 9 | import com.joshua.StockManagementSystem.util.Pair; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.beans.factory.annotation.Qualifier; 12 | import org.springframework.stereotype.Component; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.Collections; 16 | import java.util.LinkedList; 17 | import java.util.List; 18 | 19 | import static com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper.*; 20 | import static com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter.ProductionAdapter.*; 21 | 22 | @Component("productionV1Service") 23 | @Service 24 | public class ProductionServiceImpl implements ProductionService { 25 | private final ProductionDAO productionDAO; 26 | 27 | @Autowired 28 | public ProductionServiceImpl(@Qualifier("postgresProduction") ProductionDAO productionDAO) { 29 | this.productionDAO = productionDAO; 30 | } 31 | 32 | @Override 33 | public Pair> insert(UpsertProductionRequestPayload upsertProductionRequestPayload) { 34 | Integer flag = productionDAO.insert(convertUpsertPayloadToDataEntity(upsertProductionRequestPayload)); 35 | return new Pair<>(flag == 1, Collections.singletonList( 36 | PRODUCTION+ upsertProductionRequestPayload.getId()+ (flag == 1? SUCCESS : FAIL )+" "+ PostgresHelper.INSERTED)); 37 | } 38 | 39 | @Override 40 | public List index() { 41 | return convertDataEntitiesToModels(productionDAO.index()); 42 | } 43 | 44 | @Override 45 | public Production show(String id) { 46 | ProductionDataEntity dataEntity = productionDAO.show(id).orElse(null); 47 | return (dataEntity == null) ? null : 48 | convertDataEntitiesToModels(Collections.singletonList(dataEntity)).get(0); 49 | 50 | } 51 | 52 | @Override 53 | public Pair> update(UpsertProductionRequestPayload upsertProductionRequestPayload) { 54 | List stats = new LinkedList<>(); 55 | Integer flag =productionDAO.update(convertUpsertPayloadToDataEntity(upsertProductionRequestPayload)); 56 | return new Pair<>( 57 | (flag == 1 ), 58 | Collections.singletonList(PRODUCTION+ upsertProductionRequestPayload.getId()+(flag == 1 ? SUCCESS : FAIL)+UPDATED) 59 | ); 60 | } 61 | 62 | @Override 63 | public Pair >delete(String id) { 64 | Integer flag = productionDAO.delete(id); 65 | return new Pair<>((flag == 1), Collections.singletonList( 66 | PRODUCTION+ id + ((flag == 1)? SUCCESS : FAIL )+PostgresHelper.REMOVED)); 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/jwt/JwtTokenVerifier.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.jwt; 2 | 3 | import com.google.common.base.Strings; 4 | import io.jsonwebtoken.Claims; 5 | import io.jsonwebtoken.Jws; 6 | import io.jsonwebtoken.JwtException; 7 | import io.jsonwebtoken.Jwts; 8 | import io.jsonwebtoken.security.Keys; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 12 | import org.springframework.security.core.Authentication; 13 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 14 | import org.springframework.security.core.context.SecurityContextHolder; 15 | import org.springframework.web.filter.OncePerRequestFilter; 16 | 17 | import javax.crypto.SecretKey; 18 | import javax.servlet.FilterChain; 19 | import javax.servlet.ServletException; 20 | import javax.servlet.http.HttpServletRequest; 21 | import javax.servlet.http.HttpServletResponse; 22 | import java.io.IOException; 23 | import java.util.List; 24 | import java.util.Map; 25 | import java.util.stream.Collectors; 26 | 27 | public class JwtTokenVerifier extends OncePerRequestFilter { 28 | 29 | private Logger logger = LoggerFactory.getLogger(JwtTokenVerifier.class); 30 | private final SecretKey secretKey; 31 | private final JwtConfig jwtConfig; 32 | 33 | public JwtTokenVerifier(SecretKey secretKey, JwtConfig jwtConfig) { 34 | this.secretKey = secretKey; 35 | this.jwtConfig = jwtConfig; 36 | } 37 | 38 | @Override 39 | protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { 40 | 41 | String authHeader = httpServletRequest.getHeader(jwtConfig.getAuthorizationHeader()); 42 | if (Strings.isNullOrEmpty(authHeader) || 43 | !authHeader.startsWith( jwtConfig.getTokenPrefix() ) 44 | ) { 45 | 46 | logger.error("invalid JWT Token"); 47 | filterChain.doFilter(httpServletRequest,httpServletResponse); 48 | return; 49 | } 50 | 51 | String token = authHeader.replace("Bearer ",""); 52 | try{ 53 | 54 | Jws claimsJws = Jwts.parser() 55 | .setSigningKey(secretKey) 56 | .parseClaimsJws(token); 57 | // jws -> hasil compact jwt, kita mau balikin jws jadi jwt lagi 58 | 59 | Claims body = claimsJws.getBody(); 60 | String username = body.getSubject(); 61 | List> authorities = 62 | (List>)body.get("authorities"); 63 | 64 | Authentication auth = new UsernamePasswordAuthenticationToken( 65 | username, 66 | null, 67 | authorities.stream().map( 68 | m -> new SimpleGrantedAuthority(m.get("authority")) 69 | ).collect(Collectors.toSet()) 70 | ); 71 | SecurityContextHolder.getContext().setAuthentication(auth); 72 | }catch(JwtException e){ 73 | logger.error("Token "+token+" cannot be trusted (modified or expired)"); 74 | e.printStackTrace(); 75 | } 76 | 77 | // sambungin ke filter selanjutnya, ini penting unutk di tulis, kalo ga ga muncul json nya 78 | filterChain.doFilter(httpServletRequest,httpServletResponse); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/jwt/JwtUsernamePasswordAuthFilter.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.jwt; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import io.jsonwebtoken.Jwts; 5 | import io.jsonwebtoken.security.Keys; 6 | import org.springframework.security.authentication.AuthenticationManager; 7 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 8 | import org.springframework.security.core.Authentication; 9 | import org.springframework.security.core.AuthenticationException; 10 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 11 | 12 | import javax.crypto.SecretKey; 13 | import javax.servlet.FilterChain; 14 | import javax.servlet.ServletException; 15 | import javax.servlet.http.HttpServletRequest; 16 | import javax.servlet.http.HttpServletResponse; 17 | import java.io.IOException; 18 | import java.time.LocalDate; 19 | import java.util.Date; 20 | 21 | public class JwtUsernamePasswordAuthFilter extends UsernamePasswordAuthenticationFilter { 22 | 23 | private final AuthenticationManager authenticationManager; 24 | private final JwtConfig jwtConfig; 25 | private final SecretKey secretKey; 26 | 27 | public JwtUsernamePasswordAuthFilter(AuthenticationManager authenticationManager, JwtConfig jwtConfig, SecretKey secretKey) { 28 | this.authenticationManager = authenticationManager; 29 | this.jwtConfig = jwtConfig; 30 | this.secretKey = secretKey; 31 | } 32 | 33 | @Override 34 | public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 35 | try { 36 | UsernamePasswordAuthRequestPayload authRequest = new ObjectMapper() 37 | .readValue(request.getInputStream(), UsernamePasswordAuthRequestPayload.class); 38 | 39 | Authentication authentication = new UsernamePasswordAuthenticationToken( 40 | authRequest.getUsername(), // principal 41 | authRequest.getPassword() // credential 42 | ); 43 | 44 | // cek user exists? username , password correct? 45 | Authentication auth = authenticationManager.authenticate(authentication); 46 | return auth; 47 | 48 | } catch (IOException e) { 49 | e.printStackTrace(); 50 | } 51 | return super.attemptAuthentication(request, response); 52 | } 53 | 54 | /** 55 | * invoked when succesfuly authenticated, create token 56 | * @param request 57 | * @param response 58 | * @param chain 59 | * @param authResult 60 | * @throws IOException 61 | * @throws ServletException 62 | */ 63 | @Override 64 | protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { 65 | 66 | // generate token 67 | String token = Jwts.builder() 68 | .setSubject(authResult.getName()) // get username 69 | .claim("authorities",authResult.getAuthorities()) 70 | .setIssuedAt(new Date()) 71 | .setExpiration(java.sql.Date.valueOf(LocalDate.now().plusDays(jwtConfig.getTokenExpirationAfterDays()))) // exp each 1 week 72 | .signWith(secretKey) 73 | .compact(); 74 | 75 | // send token to client 76 | response.addHeader(jwtConfig.getAuthorizationHeader(),jwtConfig.getTokenPrefix()+token); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { BrowserRouter,Route, Switch } from "react-router-dom"; 4 | import { Home } from './pages/Home'; 5 | import { About } from './pages/About'; 6 | import { Post } from './pages/Post'; 7 | import { ItemPage } from './pages/ItemPage'; 8 | import { CustomerPage } from './pages/CustomerPage'; 9 | import { ProductionPage } from './pages/ProductionPage'; 10 | import { PaymentTypePage } from './pages/PaymentTypePage'; 11 | import { TransactionPage } from './pages/TransactionPage'; 12 | import { LoginPage } from './pages/LoginPage'; 13 | import { MuiThemeProvider, ThemeProvider, createMuiTheme } from '@material-ui/core'; 14 | import createTypography from '@material-ui/core/styles/createTypography'; 15 | import createPalette from '@material-ui/core/styles/createPalette'; 16 | 17 | export default function App(): JSX.Element { 18 | const THEME = (() => { 19 | const palette = createPalette({ 20 | type: 'light', 21 | }); 22 | 23 | const typography = createTypography(palette, { 24 | fontFamily: '"Quicksand"', 25 | }); 26 | 27 | return createMuiTheme({ 28 | palette: palette, 29 | typography: typography, 30 | }); 31 | })(); 32 | 33 | return ( 34 | 35 | 36 | {/* Route ini akan coba cocokin path jadi /about karena ada / maka dianggap Home juga mau dipanggil 37 | , 38 | 39 | 42 | untuk atasi nya di kasih exact spy cocokin nya sama persis aja 43 | dengan exact /about/me ga mau, tanpa exact mau*/} 44 | 45 | {/* Switch make sure cuman 1 route yg di display once, pilih salah 1 aja 46 | kalo pake Switch ga kasih exact, dia lgsg bakal render first route path yg macth, jadi misal kalo /about lgsg ke render yg home (karena / dluan match) 47 | */} 48 | 49 | 52 | 55 | 58 | 61 | 64 | 67 | 70 | 73 |
404 - page not found
} 75 | /> 76 |
77 | 78 |
79 |
80 | 81 | ) 82 | } 83 | 84 | const root = document.getElementById('app-root') 85 | 86 | ReactDOM.render(, root) -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_api/model/TransactionHeader.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_api.model; 2 | 3 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper; 4 | import org.joda.money.BigMoney; 5 | import org.joda.money.CurrencyUnit; 6 | 7 | import java.math.BigDecimal; 8 | import java.sql.Timestamp; 9 | import java.text.DecimalFormat; 10 | import java.text.DecimalFormatSymbols; 11 | import java.text.NumberFormat; 12 | import java.util.Date; 13 | import java.util.List; 14 | 15 | public class TransactionHeader { 16 | private String id, customerId, paymentId; 17 | private Date transactionDate; 18 | private String paymentStatus; 19 | private List transactionDetails; 20 | private Date timestamp; 21 | private String note; 22 | private BigDecimal total; 23 | 24 | public String getId() { 25 | return id; 26 | } 27 | 28 | public TransactionHeader setId(String id) { 29 | this.id = id;return this; 30 | } 31 | 32 | public String getCustomerId() { 33 | return customerId; 34 | } 35 | 36 | public TransactionHeader setCustomerId(String customerId) { 37 | this.customerId = customerId;return this; 38 | } 39 | 40 | public String getPaymentId() { 41 | return paymentId; 42 | } 43 | 44 | public TransactionHeader setPaymentId(String paymentId) { 45 | this.paymentId = paymentId;return this; 46 | } 47 | 48 | public Date getTransactionDate() { 49 | return transactionDate; 50 | } 51 | 52 | public TransactionHeader setTransactionDate(Date transactionDate) { 53 | this.transactionDate = transactionDate;return this; 54 | } 55 | 56 | public String getPaymentStatus() { 57 | return paymentStatus; 58 | } 59 | 60 | public TransactionHeader setPaymentStatus(String paymentStatus) { 61 | this.paymentStatus = paymentStatus;return this; 62 | } 63 | 64 | public List getTransactionDetails() { 65 | return transactionDetails; 66 | } 67 | 68 | public TransactionHeader setTransactionDetails(List transactionDetails) { 69 | this.transactionDetails = transactionDetails;return this; 70 | } 71 | 72 | public Date getTimestamp() { 73 | return timestamp; 74 | } 75 | 76 | public TransactionHeader setTimestamp(Date timestamp) { 77 | this.timestamp = timestamp;return this; 78 | } 79 | 80 | public String getNote() { 81 | return note; 82 | } 83 | 84 | public TransactionHeader setNote(String note) { 85 | this.note = note;return this; 86 | } 87 | 88 | public String getTotal() { 89 | total =BigDecimal.valueOf(0); 90 | for(TransactionDetail detail: transactionDetails){ 91 | total = total.add(detail.getSubTotalDec()); 92 | } 93 | return PostgresHelper.formatCurrency(total); 94 | } 95 | 96 | public BigDecimal getTotalDec() { 97 | total =BigDecimal.valueOf(0); 98 | for(TransactionDetail detail: transactionDetails){ 99 | total = total.add(detail.getSubTotalDec()); 100 | } 101 | return total; 102 | } 103 | 104 | public TransactionHeader setTotal(BigDecimal total) { 105 | this.total = total;return this; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/PostgresHelper.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure; 2 | 3 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.JosephDataEntity; 4 | 5 | import java.lang.reflect.Field; 6 | import java.math.BigDecimal; 7 | import java.text.DecimalFormat; 8 | import java.text.DecimalFormatSymbols; 9 | import java.util.Date; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | public class PostgresHelper { 15 | 16 | public static final String SUCCESS = " SUCCESSFULLY "; 17 | public static final String FAIL = " FAILED TO BE"; 18 | public static final String INSERTED = " INSERTED "; 19 | public static final String UPDATED = " UPDATED "; 20 | public static final String REMOVED = " REMOVED "; 21 | public static final String ITEM = "ITEM "; 22 | public static final String PRODUCTION = "PRODUCTION "; 23 | public static final String CUSTOMER = "CUSTOMER "; 24 | public static final String PAYTYPE = "PAYMENT TYPE "; 25 | public static final String TRANHEAD = " TRANSACTION "; 26 | public static final String NOTFOUND = " is not exist"; 27 | public static final String PDF_PATH = "/web/generatedpdf/"; 28 | public static final String TRANS_PDF_FILENAME = "TransactionReport.pdf"; 29 | public static final String ITEM_PDF_FILENAME = "ItemReport.pdf"; 30 | 31 | public static String insertOperation(JosephDataEntity dataEntity){ 32 | String sql = "INSERT INTO " 33 | + dataEntity.TABLE 34 | + " VALUES ( "; 35 | // for(int i = 0;i0) sql+=", "; 37 | // sql+="?"; 38 | // } 39 | int j = 0; 40 | for (Field field : dataEntity.getClass().getDeclaredFields()) { 41 | //field.setAccessible(true); // if you want to modify private fields 42 | if(j >= dataEntity.numColumns) break; 43 | System.out.println(field.getName() 44 | + " - " + field.getType()); 45 | if(j > 0) sql+=", "; 46 | if(field.getType() == Date.class){ 47 | sql+="?::date"; 48 | }else sql+="?"; 49 | 50 | j++; 51 | } 52 | sql+=" )"; 53 | return sql; 54 | } 55 | 56 | public static String selectOperation(JosephDataEntity dataEntity){ 57 | String sql = "SELECT * FROM " 58 | + dataEntity.TABLE; 59 | return sql; 60 | } 61 | 62 | public static String updateOperation(JosephDataEntity dataEntity, HashMap params, String comparator){ 63 | String sql = "UPDATE " 64 | + dataEntity.TABLE 65 | + " SET"; 66 | int i = 0; 67 | for(Map.Entry param : params.entrySet()){ 68 | if(i++ > 0) sql+=","; 69 | sql+=" "+param.getKey()+" = \'"+param.getValue()+"\'"; 70 | } 71 | sql+=" WHERE "+comparator; 72 | return sql; 73 | } 74 | 75 | public static String deleteOperation(JosephDataEntity dataEntity, String condition){ 76 | return "DELETE FROM "+dataEntity.TABLE+ " "+condition; 77 | } 78 | 79 | public static String formatCurrency(BigDecimal amount){ 80 | if(amount == null) amount = BigDecimal.ZERO; 81 | DecimalFormat kursIndo = (DecimalFormat) DecimalFormat.getCurrencyInstance(); 82 | DecimalFormatSymbols rp = new DecimalFormatSymbols(); 83 | rp.setCurrencySymbol("IDR "); 84 | rp.setMonetaryDecimalSeparator(','); 85 | rp.setGroupingSeparator('.'); 86 | kursIndo.setDecimalFormatSymbols(rp); 87 | return kursIndo.format(amount); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/dao/PaymentDataAccessService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.dao; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.infrastructure.dao.PaymentDAO; 4 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper; 5 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.ItemDataEntity; 6 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.PaymentDataEntity; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | import org.springframework.stereotype.Repository; 10 | 11 | import java.util.HashMap; 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | import static com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter.PaymentAdapter.convertResultSetToDataEntity; 16 | 17 | @Repository("postgresPayment") 18 | public class PaymentDataAccessService implements PaymentDAO { 19 | private final JdbcTemplate jdbcTemplate; 20 | 21 | @Autowired 22 | public PaymentDataAccessService(JdbcTemplate jdbcTemplate) { 23 | this.jdbcTemplate = jdbcTemplate; 24 | } 25 | 26 | @Override 27 | public Integer insert(PaymentDataEntity payment) { 28 | if(show(payment.getId()) != null){ 29 | return update(payment); 30 | } 31 | final String sql = PostgresHelper.insertOperation(payment); 32 | return jdbcTemplate.update(sql 33 | ,payment.getId() 34 | ,payment.getPayment_type() 35 | ); 36 | } 37 | 38 | @Override 39 | public List index() { 40 | final String sql = PostgresHelper.selectOperation(new PaymentDataEntity()) 41 | + " WHERE "+ItemDataEntity.ISACTIVE+" = true"; 42 | return jdbcTemplate.query( 43 | sql, ((resultSet, i) -> { 44 | PaymentDataEntity dataEntity = convertResultSetToDataEntity(resultSet); 45 | return dataEntity; 46 | }) 47 | ); 48 | } 49 | 50 | @Override 51 | public Optional show(String id) { 52 | final String sql = PostgresHelper.selectOperation(new PaymentDataEntity()) 53 | + " WHERE "+PaymentDataEntity.ID +" = ?"; 54 | 55 | try{ 56 | PaymentDataEntity paymentDataEntity = jdbcTemplate.queryForObject(sql, new Object[]{id}, ((resultSet, i) -> { 57 | return convertResultSetToDataEntity(resultSet); 58 | })); 59 | return Optional.ofNullable(paymentDataEntity); 60 | }catch (Exception e){ 61 | return null; 62 | } 63 | } 64 | 65 | @Override 66 | public Integer update(PaymentDataEntity paymentDataEntity) { 67 | HashMap setter = new HashMap<>(); 68 | setter.put(PaymentDataEntity.ID, paymentDataEntity.getId()); 69 | setter.put(PaymentDataEntity.TYPE, paymentDataEntity.getPayment_type()); 70 | setter.put(ItemDataEntity.ISACTIVE, true); 71 | final String sql = PostgresHelper.updateOperation(paymentDataEntity, 72 | setter,PaymentDataEntity.ID+" = \'" +paymentDataEntity.getId()+"\'"); 73 | return jdbcTemplate.update(sql); 74 | } 75 | 76 | @Override 77 | public Integer delete(String id) { 78 | PaymentDataEntity paymentDataEntity = show(id).orElse(null); 79 | if(paymentDataEntity == null) return 0; 80 | HashMap setter = new HashMap<>(); 81 | setter.put(ItemDataEntity.ISACTIVE, false); 82 | final String sql = PostgresHelper.updateOperation(paymentDataEntity, 83 | setter,PaymentDataEntity.ID+" = \'" +paymentDataEntity.getId()+"\'"); 84 | return jdbcTemplate.update(sql); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/form/CustomerForm.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Formik, Field, useField, FieldAttributes, FieldArray } from 'formik'; 3 | import { TextField, Button, Checkbox, Radio, Select, MenuItem, TextareaAutosize, Typography } from '@material-ui/core'; 4 | import * as yup from 'yup'; 5 | 6 | 7 | const validationSchema = yup.object({ 8 | id: yup.string().required("Customer Id must be filled"), 9 | name: yup.string().required("Customer Name must be filled") 10 | }) 11 | 12 | const TextFieldWValidation:React.FC> = ({placeholder,type,...props}) => { 13 | const [field, meta] = useField<{}>(props); // hook dari formik 14 | const errorText = meta.error && meta.touched ? meta.error : ""; 15 | // kalo ada error dan udah diiisi/ disentuh 16 | return( 17 | 19 | ) 20 | } 21 | 22 | 23 | const TextAreaWValidation:React.FC> = ({placeholder,...props}) => { 24 | const [field, meta] = useField<{}>(props); // hook dari formik 25 | const errorText = meta.error && meta.touched ? meta.error : ""; 26 | // kalo ada error dan udah diiisi/ disentuh 27 | return( 28 | 29 | 31 | ) 32 | } 33 | 34 | 35 | export class CustomerForm extends React.Component{ 36 | render(){ 37 | return ( 38 |
39 | {/* formik punya 2 props, (initstate && fgsi onSubmit ketika submit) 40 | onSubmit ada 2 param data form, object 41 | */} 42 | { 51 | // setSubmitting itu untuk async request ke server dan sembari disable button (ini function) 52 | setSubmitting(true) 53 | console.log(data); 54 | 55 | this.props.submitData(data); 56 | 57 | setSubmitting(false); 58 | console.log("done submit add data") 59 | }} 60 | 61 | validationSchema = {validationSchema} 62 | 63 | > 64 | { 65 | ({ errors, values, isSubmitting, /*handleChange, handleBlur, */handleSubmit }) => ( 66 | 67 |
68 | 69 | 70 | {!this.props.isEdit &&
71 | 76 |
} 77 | 78 |
79 | 84 |
85 | 86 |
87 | 92 |
93 | 94 |
95 | 101 |
102 | 103 | 107 | 108 |
109 | ) 110 | } 111 |
112 |
113 | ) 114 | } 115 | } -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/sidebar/SidebarList.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ListItem from '@material-ui/core/ListItem'; 3 | import ListItemIcon from '@material-ui/core/ListItemIcon'; 4 | import ListItemText from '@material-ui/core/ListItemText'; 5 | import ListSubheader from '@material-ui/core/ListSubheader'; 6 | import DashboardIcon from '@material-ui/icons/Dashboard'; 7 | import ShoppingCartIcon from '@material-ui/icons/ShoppingCart'; 8 | import PeopleIcon from '@material-ui/icons/People'; 9 | import BarChartIcon from '@material-ui/icons/BarChart'; 10 | import LayersIcon from '@material-ui/icons/Layers'; 11 | import ReceiptIcon from '@material-ui/icons/Receipt'; 12 | import LocalAtmIcon from '@material-ui/icons/LocalAtm'; 13 | import AssignmentIcon from '@material-ui/icons/Assignment'; 14 | import { Link } from 'react-router-dom'; 15 | import { makeStyles } from '@material-ui/core/styles' 16 | import CSS from 'csstype' 17 | 18 | // const useStyles = makeStyles(theme => ({ 19 | // plainLink:{ 20 | // textDecoration: "none", 21 | // color:'#000' 22 | // }}) 23 | // ); 24 | 25 | 26 | const plainLinkStyle: CSS.Properties = { 27 | textDecoration: "none", 28 | color:'#000' 29 | } 30 | 31 | export const mainListItems = ( 32 |
33 | { 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
} 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | {/* 85 | 86 | 87 | 88 | 89 | */} 90 |
91 | ); 92 | 93 | export const secondaryListItems = ( 94 |
95 | {/* Saved reports 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | */} 114 |
115 | ); -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/infrastructure/dao/ItemDataAccessService.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.infrastructure.dao; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.infrastructure.dao.ItemDAO; 4 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper; 5 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.flushout.ItemDataEntity; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Optional; 13 | import static com.joshua.StockManagementSystem.joseph_impl.infrastructure.adapter.ItemAdapter.convertResultSetToDataEntity; 14 | 15 | @Repository("postgresItem") 16 | public class ItemDataAccessService implements ItemDAO { 17 | private final JdbcTemplate jdbcTemplate; 18 | 19 | @Autowired 20 | public ItemDataAccessService(JdbcTemplate jdbcTemplate) { 21 | this.jdbcTemplate = jdbcTemplate; 22 | } 23 | 24 | @Override 25 | public Integer insert(ItemDataEntity itemDataEntity) { 26 | if(show(itemDataEntity.getItemCode()) != null){ 27 | return update(itemDataEntity); 28 | } 29 | final String sql = PostgresHelper.insertOperation(itemDataEntity); 30 | return jdbcTemplate.update(sql 31 | ,itemDataEntity.getItemCode() 32 | ,itemDataEntity.getName() 33 | ,itemDataEntity.getDescription() 34 | ,itemDataEntity.getPrice() 35 | ,itemDataEntity.getStock() 36 | ,itemDataEntity.getCapacity() 37 | ); 38 | } 39 | 40 | @Override 41 | public List index() { 42 | final String sql = PostgresHelper.selectOperation(new ItemDataEntity()) 43 | + " WHERE "+ItemDataEntity.ISACTIVE+" = true"; 44 | return jdbcTemplate.query( 45 | sql, ((resultSet, i) -> { 46 | ItemDataEntity dataEntity = convertResultSetToDataEntity(resultSet); 47 | return dataEntity; 48 | }) 49 | ); 50 | } 51 | 52 | @Override 53 | public Optional show(String id) { 54 | final String sql = PostgresHelper.selectOperation(new ItemDataEntity()) 55 | + " WHERE "+ItemDataEntity.ITEMCODE +" = ?"; 56 | try { 57 | ItemDataEntity itemDataEntity = jdbcTemplate.queryForObject(sql, new Object[]{id}, 58 | ((resultSet, i) -> { 59 | return convertResultSetToDataEntity(resultSet); 60 | })); 61 | return Optional.ofNullable(itemDataEntity); 62 | }catch(Exception e){ 63 | return null; 64 | } 65 | } 66 | 67 | @Override 68 | public Integer update(ItemDataEntity itemDataEntity) { 69 | HashMap setter = new HashMap<>(); 70 | setter.put(ItemDataEntity.NAME, itemDataEntity.getName()); 71 | setter.put(ItemDataEntity.DESCRIPTION, itemDataEntity.getDescription()); 72 | setter.put(ItemDataEntity.PRICE, itemDataEntity.getPrice()); 73 | setter.put(ItemDataEntity.STOCK, itemDataEntity.getStock()); 74 | setter.put(ItemDataEntity.CAPACITY, itemDataEntity.getCapacity()); 75 | setter.put(ItemDataEntity.ISACTIVE, true); 76 | final String sql = PostgresHelper.updateOperation(itemDataEntity, 77 | setter,ItemDataEntity.ITEMCODE+" = \'" +itemDataEntity.getItemCode()+"\'"); 78 | return jdbcTemplate.update(sql); 79 | } 80 | 81 | @Override 82 | public Integer delete(String idItem) { 83 | ItemDataEntity itemDataEntity = show(idItem).orElse(null); 84 | if(itemDataEntity == null) return 0; 85 | HashMap setter = new HashMap<>(); 86 | setter.put(ItemDataEntity.ISACTIVE, false); 87 | final String sql = PostgresHelper.updateOperation(itemDataEntity, 88 | setter,ItemDataEntity.ITEMCODE+" = \'" +itemDataEntity.getItemCode()+"\'"); 89 | return jdbcTemplate.update(sql); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /StockManagementSystem/src/main/java/com/joshua/StockManagementSystem/joseph_impl/api/ItemAPIControllerImpl.java: -------------------------------------------------------------------------------- 1 | package com.joshua.StockManagementSystem.joseph_impl.api; 2 | 3 | import com.joshua.StockManagementSystem.joseph_api.api.ItemAPIController; 4 | import com.joshua.StockManagementSystem.joseph_api.api.payload.ResponsePayload; 5 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexItemRequestPayload; 6 | import com.joshua.StockManagementSystem.joseph_api.api.payload.index.IndexItemResponsePayload; 7 | import com.joshua.StockManagementSystem.joseph_api.api.payload.upsert.UpsertItemRequestPayload; 8 | import com.joshua.StockManagementSystem.joseph_api.domain.ItemService; 9 | import com.joshua.StockManagementSystem.joseph_api.model.Item; 10 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.HttpStatus; 11 | import com.joshua.StockManagementSystem.joseph_impl.infrastructure.PostgresHelper; 12 | import com.joshua.StockManagementSystem.util.Pair; 13 | import org.flywaydb.core.internal.util.FileCopyUtils; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.beans.factory.annotation.Qualifier; 16 | import org.springframework.stereotype.Component; 17 | 18 | import javax.servlet.http.HttpServletResponse; 19 | import javax.validation.constraints.NotNull; 20 | import java.io.*; 21 | import java.net.URL; 22 | import java.util.List; 23 | 24 | @Component("itemAPIV1") 25 | public class ItemAPIControllerImpl implements ItemAPIController { 26 | private final ItemService itemService; 27 | 28 | @Autowired 29 | public ItemAPIControllerImpl(@Qualifier("itemV1Service") ItemService itemService) { 30 | this.itemService = itemService; 31 | } 32 | 33 | @Override 34 | public ResponsePayload insertItem(@NotNull UpsertItemRequestPayload upsertItemRequestPayload) { 35 | Pair> resp = itemService.insert(upsertItemRequestPayload); 36 | return new ResponsePayload().setMessage(resp.getValue()) 37 | .setStatus((resp.getKey() ? HttpStatus.SUCCESS : HttpStatus.FAIL).toString()); 38 | } 39 | 40 | @Override 41 | public IndexItemResponsePayload indexItem(IndexItemRequestPayload indexItemRequestPayload) { 42 | return new IndexItemResponsePayload().setItems(itemService.index(indexItemRequestPayload)); 43 | } 44 | 45 | @Override 46 | public Item showIndex(@NotNull String id) { 47 | return itemService.show(id); 48 | } 49 | 50 | @Override 51 | public ResponsePayload updateItem(@NotNull UpsertItemRequestPayload upsertItemRequestPayload) { 52 | Pair> resp = itemService.update(upsertItemRequestPayload); 53 | return new ResponsePayload() 54 | .setMessage(resp.getValue()) 55 | .setStatus(resp.getKey() ? HttpStatus.SUCCESS.toString() : HttpStatus.FAIL.toString()); 56 | } 57 | 58 | @Override 59 | public ResponsePayload deleteItem(@NotNull String id) { 60 | Pair> resp = itemService.delete(id); 61 | return new ResponsePayload() 62 | .setMessage(resp.getValue()) 63 | .setStatus(resp.getKey() ? HttpStatus.SUCCESS.toString() : HttpStatus.FAIL.toString()); 64 | } 65 | 66 | @Override 67 | public void generateReport( 68 | HttpServletResponse response, 69 | @NotNull IndexItemRequestPayload indexItemRequestPayload) throws IOException { 70 | itemService.generateReport(indexItemRequestPayload); 71 | URL res = getClass().getClassLoader().getResource(PostgresHelper.PDF_PATH+ PostgresHelper.ITEM_PDF_FILENAME); 72 | 73 | File file = new File(System.getProperty("user.dir")+PostgresHelper.PDF_PATH+ PostgresHelper.ITEM_PDF_FILENAME); 74 | InputStream in = new FileInputStream(file); 75 | 76 | response.setContentType("application/pdf"); 77 | response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); 78 | response.setHeader("Content-Length", String.valueOf(file.length())); 79 | FileCopyUtils.copy(in, response.getOutputStream()); 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /stockmanagementsystem-frontend/src/components/organism/form/TransactionDetailForm.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Formik, useField } from 'formik'; 3 | import { TextField, Button, Select,FormControl, InputLabel } from '@material-ui/core'; 4 | import * as yup from 'yup'; 5 | 6 | 7 | const validationSchema = yup.object({ 8 | itemCode: yup.string().required("Item Code must be filled"), 9 | quantity: yup.number().positive("Produced Quantity must be more than 0"), 10 | }) 11 | 12 | const TextFieldWValidation:any = ({placeholder,type,...props}) => { 13 | const [field, meta] = useField<{}>(props); 14 | const errorText = meta.error && meta.touched ? meta.error : ""; 15 | return( 16 | 18 | ) 19 | } 20 | 21 | const SelectWValidation:any = ({...props}) => { 22 | const [field, meta] = useField<{}>(props); 23 | const errorText = meta.error && meta.touched ? meta.error : ""; 24 | console.log(meta, "METAFROMCONTROL"); 25 | return( 26 |