SQL Schema Sistem Inventory Walet
CREATE TABLE roles (
id BIGSERIAL PRIMARY KEY,
code VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
role_id BIGINT NOT NULL REFERENCES roles(id),
name VARCHAR(150) NOT NULL,
email VARCHAR(150),
phone VARCHAR(50),
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE suppliers (
id BIGSERIAL PRIMARY KEY,
code VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(150) NOT NULL,
phone VARCHAR(50),
email VARCHAR(150),
bank_name VARCHAR(100),
bank_account_number VARCHAR(100),
address TEXT,
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE customers (
id BIGSERIAL PRIMARY KEY,
code VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(150) NOT NULL,
phone VARCHAR(50),
email VARCHAR(150),
bank_name VARCHAR(100),
bank_account_number VARCHAR(100),
address TEXT,
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE units (
id BIGSERIAL PRIMARY KEY,
code VARCHAR(20) NOT NULL UNIQUE,
name VARCHAR(50) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE item_types (
id BIGSERIAL PRIMARY KEY,
code VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
description TEXT,
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE item_grades (
id BIGSERIAL PRIMARY KEY,
code VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
rank_order INT,
description TEXT,
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE warehouses (
id BIGSERIAL PRIMARY KEY,
code VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
address TEXT,
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE warehouse_locations (
id BIGSERIAL PRIMARY KEY,
warehouse_id BIGINT NOT NULL REFERENCES warehouses(id),
code VARCHAR(50) NOT NULL,
name VARCHAR(100) NOT NULL,
location_type VARCHAR(50),
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
UNIQUE (warehouse_id, code)
);
CREATE TABLE adjustment_reasons (
id BIGSERIAL PRIMARY KEY,
code VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
category VARCHAR(50) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE purchases (
id BIGSERIAL PRIMARY KEY,
purchase_no VARCHAR(50) NOT NULL UNIQUE,
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
purchase_date DATE NOT NULL,
supplier_invoice_no VARCHAR(100),
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
notes TEXT,
created_by BIGINT NOT NULL REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE purchase_lines (
id BIGSERIAL PRIMARY KEY,
purchase_id BIGINT NOT NULL REFERENCES purchases(id) ON DELETE CASCADE,
item_type_id BIGINT NOT NULL REFERENCES item_types(id),
item_grade_id BIGINT REFERENCES item_grades(id),
qty_ordered NUMERIC(18,3) NOT NULL,
unit_id BIGINT NOT NULL REFERENCES units(id),
unit_price NUMERIC(18,2) NOT NULL,
subtotal NUMERIC(18,2) NOT NULL,
classification_status VARCHAR(20) NOT NULL DEFAULT 'FINAL',
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE receipts (
id BIGSERIAL PRIMARY KEY,
receipt_no VARCHAR(50) NOT NULL UNIQUE,
purchase_id BIGINT NOT NULL REFERENCES purchases(id),
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
receipt_date DATE NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
notes TEXT,
received_by BIGINT NOT NULL REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE receipt_lines (
id BIGSERIAL PRIMARY KEY,
receipt_id BIGINT NOT NULL REFERENCES receipts(id) ON DELETE CASCADE,
purchase_line_id BIGINT NOT NULL REFERENCES purchase_lines(id),
item_type_id BIGINT NOT NULL REFERENCES item_types(id),
item_grade_id BIGINT REFERENCES item_grades(id),
qty_received NUMERIC(18,3) NOT NULL,
qty_accepted NUMERIC(18,3) NOT NULL,
qty_rejected NUMERIC(18,3) NOT NULL DEFAULT 0,
unit_id BIGINT NOT NULL REFERENCES units(id),
unit_cost NUMERIC(18,2) NOT NULL,
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE inventory_lots (
id BIGSERIAL PRIMARY KEY,
lot_code VARCHAR(100) NOT NULL UNIQUE,
parent_lot_id BIGINT REFERENCES inventory_lots(id),
source_type VARCHAR(30) NOT NULL,
source_ref_id BIGINT,
supplier_id BIGINT REFERENCES suppliers(id),
purchase_id BIGINT REFERENCES purchases(id),
purchase_line_id BIGINT REFERENCES purchase_lines(id),
receipt_id BIGINT REFERENCES receipts(id),
receipt_line_id BIGINT REFERENCES receipt_lines(id),
item_type_id BIGINT NOT NULL REFERENCES item_types(id),
item_grade_id BIGINT NOT NULL REFERENCES item_grades(id),
warehouse_id BIGINT NOT NULL REFERENCES warehouses(id),
warehouse_location_id BIGINT REFERENCES warehouse_locations(id),
original_qty NUMERIC(18,3) NOT NULL,
available_qty NUMERIC(18,3) NOT NULL,
reserved_qty NUMERIC(18,3) NOT NULL DEFAULT 0,
damaged_qty NUMERIC(18,3) NOT NULL DEFAULT 0,
shrinkage_qty NUMERIC(18,3) NOT NULL DEFAULT 0,
unit_id BIGINT NOT NULL REFERENCES units(id),
unit_cost NUMERIC(18,2) NOT NULL,
received_at TIMESTAMP NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
qr_code_value VARCHAR(255),
barcode_value VARCHAR(255),
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_inventory_lots_item_grade_wh ON inventory_lots(item_type_id, item_grade_id, warehouse_id);
CREATE INDEX idx_inventory_lots_supplier_item_grade ON inventory_lots(supplier_id, item_type_id, item_grade_id);
CREATE TABLE sorting_sessions (
id BIGSERIAL PRIMARY KEY,
sorting_no VARCHAR(50) NOT NULL UNIQUE,
source_lot_id BIGINT NOT NULL REFERENCES inventory_lots(id),
sorting_date TIMESTAMP NOT NULL,
input_qty NUMERIC(18,3) NOT NULL,
output_qty NUMERIC(18,3) NOT NULL,
shrinkage_qty NUMERIC(18,3) NOT NULL DEFAULT 0,
notes TEXT,
sorted_by BIGINT NOT NULL REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE sorting_results (
id BIGSERIAL PRIMARY KEY,
sorting_session_id BIGINT NOT NULL REFERENCES sorting_sessions(id) ON DELETE CASCADE,
result_lot_id BIGINT NOT NULL REFERENCES inventory_lots(id),
item_type_id BIGINT NOT NULL REFERENCES item_types(id),
item_grade_id BIGINT NOT NULL REFERENCES item_grades(id),
qty_result NUMERIC(18,3) NOT NULL,
unit_cost NUMERIC(18,2) NOT NULL,
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE sales (
id BIGSERIAL PRIMARY KEY,
sales_no VARCHAR(50) NOT NULL UNIQUE,
customer_id BIGINT NOT NULL REFERENCES customers(id),
sales_date DATE NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
notes TEXT,
created_by BIGINT NOT NULL REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE sales_lines (
id BIGSERIAL PRIMARY KEY,
sales_id BIGINT NOT NULL REFERENCES sales(id) ON DELETE CASCADE,
item_type_id BIGINT NOT NULL REFERENCES item_types(id),
item_grade_id BIGINT NOT NULL REFERENCES item_grades(id),
qty_sold NUMERIC(18,3) NOT NULL,
unit_id BIGINT NOT NULL REFERENCES units(id),
selling_price NUMERIC(18,2) NOT NULL,
subtotal NUMERIC(18,2) NOT NULL,
costing_total NUMERIC(18,2) NOT NULL DEFAULT 0,
gross_margin NUMERIC(18,2) NOT NULL DEFAULT 0,
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE sales_allocations (
id BIGSERIAL PRIMARY KEY,
sales_line_id BIGINT NOT NULL REFERENCES sales_lines(id) ON DELETE CASCADE,
inventory_lot_id BIGINT NOT NULL REFERENCES inventory_lots(id),
qty_allocated NUMERIC(18,3) NOT NULL,
unit_cost NUMERIC(18,2) NOT NULL,
total_cost NUMERIC(18,2) NOT NULL,
allocated_at TIMESTAMP NOT NULL,
allocated_by BIGINT NOT NULL REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE inventory_movements (
id BIGSERIAL PRIMARY KEY,
movement_no VARCHAR(50) NOT NULL UNIQUE,
movement_type VARCHAR(30) NOT NULL,
inventory_lot_id BIGINT NOT NULL REFERENCES inventory_lots(id),
related_lot_id BIGINT REFERENCES inventory_lots(id),
warehouse_id BIGINT NOT NULL REFERENCES warehouses(id),
warehouse_location_id BIGINT REFERENCES warehouse_locations(id),
qty_in NUMERIC(18,3) NOT NULL DEFAULT 0,
qty_out NUMERIC(18,3) NOT NULL DEFAULT 0,
balance_after NUMERIC(18,3) NOT NULL,
unit_cost NUMERIC(18,2) NOT NULL,
reference_type VARCHAR(30) NOT NULL,
reference_id BIGINT NOT NULL,
reason_id BIGINT REFERENCES adjustment_reasons(id),
movement_date TIMESTAMP NOT NULL,
created_by BIGINT NOT NULL REFERENCES users(id),
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE sales_returns (
id BIGSERIAL PRIMARY KEY,
sales_id BIGINT NOT NULL REFERENCES sales(id),
customer_id BIGINT NOT NULL REFERENCES customers(id),
return_date DATE NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE sales_return_lines (
id BIGSERIAL PRIMARY KEY,
sales_return_id BIGINT NOT NULL REFERENCES sales_returns(id) ON DELETE CASCADE,
sales_line_id BIGINT NOT NULL REFERENCES sales_lines(id),
inventory_lot_id BIGINT REFERENCES inventory_lots(id),
item_type_id BIGINT NOT NULL REFERENCES item_types(id),
item_grade_id BIGINT NOT NULL REFERENCES item_grades(id),
qty_returned NUMERIC(18,3) NOT NULL,
return_condition VARCHAR(50),
resolution VARCHAR(50),
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE purchase_returns (
id BIGSERIAL PRIMARY KEY,
purchase_id BIGINT NOT NULL REFERENCES purchases(id),
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
return_date DATE NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE purchase_return_lines (
id BIGSERIAL PRIMARY KEY,
purchase_return_id BIGINT NOT NULL REFERENCES purchase_returns(id) ON DELETE CASCADE,
inventory_lot_id BIGINT NOT NULL REFERENCES inventory_lots(id),
qty_returned NUMERIC(18,3) NOT NULL,
unit_cost NUMERIC(18,2) NOT NULL,
notes TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE stock_adjustments (
id BIGSERIAL PRIMARY KEY,
adjustment_no VARCHAR(50) NOT NULL UNIQUE,
inventory_lot_id BIGINT NOT NULL REFERENCES inventory_lots(id),
adjustment_type VARCHAR(30) NOT NULL,
reason_id BIGINT NOT NULL REFERENCES adjustment_reasons(id),
qty_before NUMERIC(18,3) NOT NULL,
qty_change NUMERIC(18,3) NOT NULL,
qty_after NUMERIC(18,3) NOT NULL,
cost_impact NUMERIC(18,2) NOT NULL DEFAULT 0,
adjustment_date TIMESTAMP NOT NULL,
notes TEXT,
created_by BIGINT NOT NULL REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE TABLE lot_labels (
id BIGSERIAL PRIMARY KEY,
inventory_lot_id BIGINT NOT NULL REFERENCES inventory_lots(id) ON DELETE CASCADE,
label_type VARCHAR(20) NOT NULL,
label_value VARCHAR(255) NOT NULL,
printed_at TIMESTAMP,
printed_by BIGINT REFERENCES users(id),
print_count INT NOT NULL DEFAULT 0,
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);