Pendidikan
Pengalaman Organisasi
Pengalaman Kerja
Pendidikan
Pengalaman Organisasi
Pengalaman Kerja
username : nim@bsi.ac.id
password : nim
contoh
username : 12080879@bsi.ac.id
password : 12080879
Database client adalah aplikasi yang digunakan untuk berkomunikasi dengan DBMS
Biasanya DBMS sudah menyediakan database client sederhana yang bisa kita gunakan untuk berkomunikasi dengan DBMS agar lebih mudah
Beberapa database client yang sering digunakan diantaranya : phpmyadmin, mysql workbench, Sql Server Management Studio, Dbeaver, Heidi Sql, Mysql Yog, Navicat Mysql, TablePlus
Saya rekomendasikan menggunakan DBeaver Community untuk latihan pada workshop kali ini.
https://dbeaver.io/download/
Teknik yang digunakan untuk memodelkan kebutuhan data, biasanya oleh System Analys dalam tahap analisis persyaratan proyek pengembangan system. Sementara seolah-olah teknik diagram atau alat peraga memberikan dasar untuk desain database relasional yang mendasari sistem informasi yang dikembangkan. ERD bersama-sama dengan detail pendukung merupakan model data yang pada gilirannya digunakan sebagai spesifikasi untuk database.
Objek atau konsep yang dapat diidentifikasi dan memiliki atribut yang mendefinisikan karakteristiknya
karakteristik atau properti yang dimiliki oleh sebuah entitas
keterkaitan atau asosiasi antara entitas atau tabel dalam sebuah sistem basis data relasional
sebuah platform untuk merancang dan memodelkan basis data secara visual. Ini adalah alat yang sangat berguna untuk menggambar diagram skema basis data dengan mudah dan cepat menggunakan antarmuka yang intuitif dan fitur kolaboratifnya.
Table users {
id bigint [primary key]
name varchar(255)
email varchar(50)
password varchar(25)
roles enum('admin','staff','user')
created_at timestamp
updated_at timestamp
}Table products {
id bigint [primary key]
name varchar(255)
description text
price int
stock int
category enum('food','drink','snack')
image varchar(255)
is_best_seller tinyint
created_at timestamp
updated_at timestamp
}Table orders {
id bigint [primary key]
kasir_id bigint
transaction_time timestamp
total_price int
total_item int
payment_method enum('Tunai','QRIS')
created_at timestamp
updated_at timestamp
}Table order_details {
id bigint [primary key]
order_id bigint
product_id bigint
quantity int
total_price int
created_at timestamp
updated_at timestamp
}Ref: users.id < orders.kasir_id
Ref: orders.id < order_details.order_id
Ref: products.id < order_details.order_idData Definition Language adalah perintah SQL yang digunakan untuk mendefinisikan dan mengelola struktur database. Perintah DDL mencakup:
DDL berfokus pada pembuatan dan modifikasi struktur database daripada manipulasi data.
CREATE TABLE `users` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`email` varchar(50) NOT NULL,
`phone` varchar(25) DEFAULT NULL,
`roles` enum('admin','staff','user') NOT NULL DEFAULT 'user',
`password` varchar(255) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`)
);CREATE TABLE `products` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`description` text,
`price` int NOT NULL DEFAULT '0',
`stock` int NOT NULL DEFAULT '0',
`category` enum('food','drink','snack') NOT NULL,
`image` varchar(255) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`is_best_seller` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
);CREATE TABLE `orders` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`transaction_time` timestamp NOT NULL,
`total_price` int NOT NULL,
`total_item` int NOT NULL,
`kasir_id` bigint unsigned NOT NULL,
`payment_method` enum('Tunai','QRIS') NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `orders_kasir_id_foreign` (`kasir_id`),
CONSTRAINT `orders_kasir_id_foreign` FOREIGN KEY (`kasir_id`) REFERENCES `users` (`id`)
);CREATE TABLE `order_items` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`order_id` bigint unsigned NOT NULL,
`product_id` bigint unsigned NOT NULL,
`quantity` int NOT NULL,
`total_price` int NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `order_items_order_id_foreign` (`order_id`),
KEY `order_items_product_id_foreign` (`product_id`),
CONSTRAINT `order_items_order_id_foreign` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`),
CONSTRAINT `order_items_product_id_foreign` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`)
);Data Manipulation Language adalah perintah SQL yang digunakan untuk mengelola dan memanipulasi data di dalam tabel database. Perintah DML mencakup:
DML berfokus pada operasi yang dilakukan terhadap data yang tersimpan dalam struktur database.
INSERT INTO `users`
(name, email, phone, roles, password, created_at, updated_at)
VALUES
('Budi', 'budi@gmail.com', '085644445555', 'user', SHA2('budi123', 256), NOW(), NOW()),
('Ayu', 'ayu@gmail.com', '085655556666', 'user', SHA2('ayu123', 256), NOW(), NOW()),
('Rina', 'rina@gmail.com', '085666667777', 'user', SHA2('rina123', 256), NOW(), NOW());INSERT INTO `products` (name, description, price, stock, category, image, created_at, updated_at, is_best_seller)
VALUES
('Nasi Goreng', 'Nasi goreng dengan campuran sayuran dan daging ayam.', 25000, 50, 'food', 'nasi_goreng.jpg', NOW(), NOW(), 1),
('Es Teh Manis', 'Teh manis dingin yang segar.', 5000, 100, 'drink', 'es_teh_manis.jpg', NOW(), NOW(), 0),
('Keripik Kentang', 'Keripik kentang renyah dengan rasa gurih.', 15000, 30, 'snack', 'keripik_kentang.jpg', NOW(), NOW(), 0);
INSERT INTO `orders` (transaction_time, total_price, total_item, kasir_id, payment_method, created_at, updated_at)
VALUES
('2024-06-24 10:00:00', 40000, 2, 1, 'Tunai', NOW(), NOW()),
('2024-06-24 11:00:00', 20000, 1, 2, 'QRIS', NOW(), NOW()),
('2024-06-24 12:00:00', 30000, 3, 1, 'Tunai', NOW(), NOW());
INSERT INTO `order_items` (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES
(1, 1, 1, 25000, NOW(), NOW()),
(1, 2, 1, 15000, NOW(), NOW());
INSERT INTO `order_items` (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES
(2, 3, 1, 20000, NOW(), NOW());
INSERT INTO `order_items` (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES
(3, 1, 1, 25000, NOW(), NOW()),
(3, 3, 1, 15000, NOW(), NOW()),
(3, 2, 1, 10000, NOW(), NOW());
SELECT
a.id AS order_id,
a.transaction_time,
a.total_price AS order_total_price,
a.total_item AS order_total_item,
b.name AS kasir_name,
a.payment_method,
d.name AS product_name,
d.description AS product_description,
d.price AS product_price,
c.quantity,
c.total_price AS item_total_price
FROM orders a
LEFT JOIN users b ON a.kasir_id = b.id
LEFT JOIN order_items c ON a.id = c.order_id
LEFT JOIN products d ON c.product_id = d.id
ORDER BY a.id;UPDATE order_items oi
JOIN products p ON oi.product_id = p.id
SET oi.quantity = 5,
oi.total_price = 5 * p.price,
oi.updated_at = NOW()
WHERE oi.order_id = 3
AND oi.product_id = 3;
DELETE FROM order_items WHERE order_id = 3;
DELETE FROM orders WHERE id = 3;CREATE VIEW order_details_view AS
SELECT
a.id AS order_id,
a.transaction_time,
a.total_price AS order_total_price,
a.total_item AS order_total_item,
b.name AS kasir_name,
a.payment_method,
d.name AS product_name,
d.description AS product_description,
d.price AS product_price,
c.quantity,
c.total_price AS item_total_price
FROM orders a
LEFT JOIN users b ON a.kasir_id = b.id
LEFT JOIN order_items c ON a.id = c.order_id
LEFT JOIN products d ON c.product_id = d.id;
CREATE VIEW product_sales_view AS
SELECT
p.id AS product_id,
p.name AS product_name,
SUM(oi.quantity) AS total_quantity_sold,
SUM(oi.total_price) AS total_revenue
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.id, p.name;
CREATE VIEW daily_sales_summary_view AS
SELECT
DATE(a.transaction_time) AS transaction_date,
COUNT(a.id) AS total_orders,
SUM(a.total_price) AS total_sales_amount,
SUM(a.total_item) AS total_items_sold
FROM orders a
GROUP BY DATE(a.transaction_time);
CREATE VIEW user_orders_view AS
SELECT
u.id AS user_id,
u.name AS user_name,
COUNT(o.id) AS total_orders
FROM users u
LEFT JOIN orders o ON u.id = o.kasir_id
GROUP BY u.id, u.name;
CREATE VIEW best_seller_products_view AS
SELECT
p.id AS product_id,
p.name AS product_name,
SUM(oi.quantity) AS total_quantity_sold
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.id, p.name
ORDER BY SUM(oi.quantity) DESC;
CREATE PROCEDURE `cafe_db`.`spProductList`(
IN search_name VARCHAR(255),
IN search_category ENUM('food', 'drink', 'snack'),
IN page INT,
IN page_size INT
)
BEGIN
DECLARE offset_val INT DEFAULT 0;
SET offset_val = (page - 1) * page_size;
SELECT *
FROM products
WHERE (search_name IS NULL OR name LIKE CONCAT('%', search_name, '%'))
AND (search_category IS NULL OR search_category = '' OR category = search_category)
ORDER BY id
LIMIT page_size OFFSET offset_val;
END;
CREATE PROCEDURE `cafe_db`.`spProductDetail`(
IN product_id BIGINT UNSIGNED
)
BEGIN
SELECT *
FROM products
WHERE id = product_id;
ENDCREATE PROCEDURE `cafe_db`.`spProductAdd`(
IN p_name VARCHAR(255),
IN p_description TEXT,
IN p_price INT,
IN p_stock INT,
IN p_category ENUM('food', 'drink', 'snack'),
IN p_image VARCHAR(255)
)
BEGIN
DECLARE result_code INT;
DECLARE error_message VARCHAR(1000);
-- Check if name or category is empty
IF p_name = '' OR p_name IS NULL OR p_category = '' OR p_category IS NULL THEN
SET result_code = 39999;
SET error_message = 'Semua kolom (nama, kategori) harus diisi.';
SELECT result_code, error_message;
ELSE
-- Check if product name already exists
IF EXISTS (SELECT 1 FROM products WHERE name = p_name LIMIT 1) THEN
SET result_code = 39998;
SET error_message = 'Nama produk sudah ada dalam database.';
SELECT result_code, error_message;
ELSE
-- Insert new product
INSERT INTO products (name, description, price, stock, category, image, created_at, updated_at)
VALUES (p_name, p_description, p_price, p_stock, p_category, p_image, NOW(), NOW());
SET result_code = 1;
SET error_message = '';
SELECT result_code, error_message;
END IF;
END IF;
END
CREATE PROCEDURE `cafe_db`.`spProductEdit`(
IN p_id BIGINT UNSIGNED,
IN p_name VARCHAR(255),
IN p_description TEXT,
IN p_price INT,
IN p_stock INT,
IN p_category ENUM('food', 'drink', 'snack'),
IN p_image VARCHAR(255)
)
begin
DECLARE result_code INT;
DECLARE error_message VARCHAR(1000);
DECLARE product_count INT;
-- Check if the product exists
SELECT COUNT(*) INTO product_count
FROM products
WHERE id = p_id;
IF product_count = 0 THEN
SET result_code = 39999;
SET error_message = 'Produk dengan ID yang diberikan tidak ditemukan.';
SELECT result_code, error_message;
ELSE
IF p_name = '' OR p_name IS NULL OR p_category = '' OR p_category IS NULL THEN
SET result_code = 39999;
SET error_message = 'Semua kolom (nama, kategori) harus diisi.';
SELECT result_code, error_message;
ELSE
UPDATE products
SET name = p_name,
description = p_description,
price = p_price,
stock = p_stock,
category = p_category,
image = p_image,
updated_at = NOW()
WHERE id = p_id;
SET result_code = 1;
SET error_message = '';
SELECT result_code, error_message;
END IF;
END IF;
END;
CREATE PROCEDURE `cafe_db`.`spProductDelete`(
IN p_id BIGINT UNSIGNED
)
BEGIN
DECLARE item_count INT;
DECLARE result_code INT;
DECLARE error_message VARCHAR(1000);
-- Cek apakah produk dengan ID p_id ada dalam tabel products
SELECT COUNT(*) INTO item_count
FROM products
WHERE id = p_id;
IF item_count = 0 THEN
SET result_code = 39998;
SET error_message = 'Produk dengan ID tersebut tidak ditemukan dalam database.';
SELECT result_code, error_message;
ELSE
-- Cek apakah produk masih ada di order_items
SELECT COUNT(*) INTO item_count
FROM order_items
WHERE product_id = p_id;
IF item_count > 0 THEN
SET result_code = 39999;
SET error_message = 'Produk tidak dapat dihapus karena masih terdapat data di tabel order_items.';
SELECT result_code, error_message;
ELSE
DELETE FROM products WHERE id = p_id;
SET result_code = 1;
SET error_message = '';
SELECT result_code, error_message;
END IF;
END IF;
END
CREATE PROCEDURE `cafe_db`.`spProductStockAdd`(
IN p_product_id BIGINT UNSIGNED,
IN p_add_stock INT
)
BEGIN
DECLARE result_code INT;
DECLARE error_message VARCHAR(1000);
DECLARE current_stock INT;
-- Check if the product exists
IF NOT EXISTS (SELECT 1 FROM products WHERE id = p_product_id) THEN
SET result_code = 0;
SET error_message = 'Product ID does not exist';
ELSE
-- Get the current stock
SELECT stock INTO current_stock FROM products WHERE id = p_product_id;
-- Add the new stock
UPDATE products SET stock = current_stock + p_add_stock, updated_at = NOW() WHERE id = p_product_id;
SET result_code = 1;
SET error_message = '';
END IF;
SELECT result_code, error_message;
ENDCALL spProductList('', null, 1, 10);
CALL spProductList('', 'food', 1, 10);
CALL spProductDetail(1);
CALL spProductAdd(null, 'Deskripsi Produk', 10000, 50, 'food', 'gambar.jpg');
CALL spProductAdd('', 'Deskripsi Produk', 10000, 50, 'food', 'gambar.jpg');
CALL spProductAdd('Nama Produk2', 'Deskripsi Produk', 10000, 50, 'food', 'gambar.jpg');
CALL spProductEdit(12, '', 'Nama Produk', 12000, 60, 'drink', 'gambar_baru.jpg');
CALL spProductEdit(11, null, 'Deskripsi Produk Baru', 12000, 60, 'drink', 'gambar_baru.jpg');
CALL spProductEdit(11, '', 'Deskripsi Produk Baru', 12000, 60, 'drink', 'gambar_baru.jpg');
CALL spProductEdit(14, 'Nama Produk', 'Nama Produk', 12000, 60, 'drink', 'gambar_baru.jpg');
CALL spProductDelete(1);
CALL spProductDelete(13);CALL spProductStockAdd(1, 10);
CALL spProductStockAdd(1, 10);CREATE PROCEDURE `cafe_db`.`spOrderAdd`(
IN p_transaction_time TIMESTAMP,
IN p_total_price INT,
IN p_total_item INT,
IN p_kasir_id BIGINT UNSIGNED,
IN p_payment_method ENUM('Tunai', 'QRIS')
)
begin
DECLARE result_code INT;
DECLARE error_message VARCHAR(1000);
INSERT INTO orders (transaction_time, total_price, total_item, kasir_id, payment_method, created_at, updated_at)
VALUES (p_transaction_time, p_total_price, p_total_item, p_kasir_id, p_payment_method, NOW(), NOW());
SET result_code = 1;
SET error_message = '';
SELECT result_code, error_message;
ENDCREATE PROCEDURE `cafe_db`.`spOrderItemAdd`(
IN p_order_id BIGINT UNSIGNED,
IN p_product_id BIGINT UNSIGNED,
IN p_quantity INT,
IN p_total_price INT
)
BEGIN
DECLARE result_code INT;
DECLARE error_message VARCHAR(1000);
DECLARE product_stock INT;
-- Check if the order exists
IF NOT EXISTS (SELECT 1 FROM orders WHERE id = p_order_id) THEN
SET result_code = 0;
SET error_message = 'Order ID does not exist';
-- Check if the product exists
ELSEIF NOT EXISTS (SELECT 1 FROM products WHERE id = p_product_id) THEN
SET result_code = 0;
SET error_message = 'Product ID does not exist';
-- Check if the stock is sufficient
ELSE
SELECT stock INTO product_stock FROM products WHERE id = p_product_id;
IF product_stock < p_quantity THEN
SET result_code = 0;
SET error_message = 'Insufficient stock';
ELSE
-- Insert the order item
INSERT INTO order_items (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES (p_order_id, p_product_id, p_quantity, p_total_price, NOW(), NOW());
-- Update the product stock
UPDATE products SET stock = stock - p_quantity WHERE id = p_product_id;
SET result_code = 1;
SET error_message = '';
END IF;
END IF;
SELECT result_code, error_message;
ENDCALL spOrderAdd('2024-06-24 14:00:00', 50000, 3, 1, 'Tunai');
CALL spOrderItemAdd(9,1, 1, 10000);
CALL spProductStockAdd(1, 10);CREATE PROCEDURE `cafe_db`.`spRegister`(
IN p_name VARCHAR(255),
IN p_email VARCHAR(50),
IN p_phone VARCHAR(25),
IN p_roles ENUM('admin','staff','user'),
IN p_password VARCHAR(255)
)
BEGIN
DECLARE result_code INT;
DECLARE error_message VARCHAR(1000);
-- Check if the email already exists
IF EXISTS (SELECT 1 FROM users WHERE email = p_email) THEN
SET result_code = 0;
SET error_message = 'Email already exists';
ELSE
-- Insert the new user with hashed password
INSERT INTO users (name, email, phone, roles, password, created_at, updated_at)
VALUES (p_name, p_email, p_phone, p_roles, SHA2(p_password, 256), NOW(), NOW());
SET result_code = 1;
SET error_message = '';
END IF;
SELECT result_code, error_message;
ENDCREATE PROCEDURE `cafe_db`.`spLogin`(
IN p_email VARCHAR(50),
IN p_password VARCHAR(255)
)
BEGIN
DECLARE result_code INT;
DECLARE error_message VARCHAR(1000);
DECLARE user_id BIGINT UNSIGNED;
DECLARE user_name VARCHAR(255);
DECLARE user_roles ENUM('admin','staff','user');
-- Check if the email and hashed password match
IF EXISTS (SELECT 1 FROM users WHERE email = p_email AND password = SHA2(p_password, 256)) THEN
-- Get user details
SELECT id, name, roles INTO user_id, user_name, user_roles FROM users WHERE email = p_email AND password = SHA2(p_password, 256);
SET result_code = 1;
SET error_message = '';
SELECT result_code, error_message;
SELECT user_id, user_name, user_roles;
ELSE
SET result_code = 0;
SET error_message = 'Invalid email or password';
SELECT result_code, error_message;
END IF;
ENDselect * from users;
CALL spRegister('John Doe', 'johndoe@example.com', '123456789', 'user', 'budi123');
CALL spLogin('johndoe@example.com', 'budi123');CREATE PROCEDURE spOrderTotalUpdate(IN p_order_id BIGINT UNSIGNED)
BEGIN
DECLARE v_total_price INT DEFAULT 0;
DECLARE v_total_item INT DEFAULT 0;
-- Menghitung total harga dan total item dari order_items
SELECT SUM(total_price), SUM(quantity)
INTO v_total_price, v_total_item
FROM order_items
WHERE order_id = p_order_id;
-- Mengupdate kolom total_price dan total_item pada tabel orders
UPDATE orders
SET total_price = v_total_price, total_item = v_total_item, updated_at = NOW()
WHERE id = p_order_id;
ENDCREATE TRIGGER trg_after_insert_order_items
AFTER INSERT ON order_items
FOR EACH ROW
BEGIN
CALL spOrderTotalUpdate(NEW.order_id);
ENDCREATE TRIGGER trg_after_update_order_items
AFTER UPDATE ON order_items
FOR EACH ROW
BEGIN
CALL spOrderTotalUpdate(NEW.order_id);
ENDCREATE TRIGGER trg_after_delete_order_items
AFTER DELETE ON order_items
FOR EACH ROW
BEGIN
CALL spOrderTotalUpdate(OLD.order_id);
ENDCREATE TABLE order_report (
order_id BIGINT UNSIGNED NOT NULL,
transaction_time TIMESTAMP NOT NULL,
order_total_price INT NOT NULL,
order_total_item INT NOT NULL,
kasir_name VARCHAR(255) NOT NULL,
payment_method ENUM('Tunai', 'QRIS') NOT NULL,
product_name VARCHAR(255) NOT NULL,
product_description TEXT,
product_price INT NOT NULL,
quantity INT NOT NULL,
item_total_price INT NOT NULL,
INDEX idx_transaction_time (transaction_time),
INDEX idx_kasir_name (kasir_name),
INDEX idx_payment_method (payment_method),
INDEX idx_product_name (product_name)
);CREATE PROCEDURE`cafe_db`.spOrderReportAdd()
BEGIN
-- Insert data into order_report if it doesn't already exist
INSERT INTO order_report (
order_id,
transaction_time,
order_total_price,
order_total_item,
kasir_name,
payment_method,
product_name,
product_description,
product_price,
quantity,
item_total_price
)
SELECT
v.order_id,
v.transaction_time,
v.order_total_price,
v.order_total_item,
v.kasir_name,
v.payment_method,
v.product_name,
v.product_description,
v.product_price,
v.quantity,
v.item_total_price
FROM
cafe_db.order_details_view v
WHERE NOT EXISTS (
SELECT 1
FROM order_report r
WHERE r.order_id = v.order_id
AND r.product_name = v.product_name
AND r.quantity = v.quantity
)
AND v.kasir_name IS NOT NULL
AND v.payment_method IS NOT NULL
AND v.product_name IS NOT NULL
AND v.product_description IS NOT NULL
AND v.product_price IS NOT NULL
AND v.quantity IS NOT NULL
AND v.item_total_price IS NOT NULL;
ENDCREATE EVENT IF NOT EXISTS move_data_to_order_report
ON SCHEDULE EVERY 1 MINUTE
STARTS CURRENT_TIMESTAMP
ON COMPLETION NOT PRESERVE
ENABLE
DO
CALL spOrderReportAdd();SELECT
EVENT_NAME,
STATUS,
LAST_EXECUTED
FROM
information_schema.EVENTS
WHERE
EVENT_SCHEMA = 'cafe_db'
AND EVENT_NAME = 'move_data_to_order_report';SET GLOBAL event_scheduler = ON;
SHOW VARIABLES LIKE 'event_scheduler';
SELECT NOW();Buka Command Line
jalankan Perintah
mysqldump -u root -p --routines cafe_db > cafe_db_backup20240701.sql
Buka Command Line
jalankan Perintah
mysql -u root -p cafe_db3 < cafe_db_backup20240701.sql
composer create-project --prefer-dist laravel/laravel cafe-project
cd cafe-project
code .
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('phone')->nullable();
$table->enum('roles', ['admin', 'staff', 'user'])->default('user');
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});Database / Migrations / 0001_01_01_000000_create_users_table.phpSchema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description')->nullable();
$table->integer('price')->default(0);
$table->integer('stock')->default(0);
$table->enum('category', ['food', 'drink', 'snack']);
$table->string('image')->nullable();
$table->boolean('is_best_seller')->default(false);
$table->timestamps();
});php artisan make:migration create_products_table
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->timestamp('transaction_time');
$table->integer('total_price');
$table->integer('total_item');
$table->foreignId('kasir_id')->constrained('users');
$table->enum('payment_method', ['Tunai', 'QRIS']);
$table->timestamps();
});php artisan make:migration create_orders_table
Schema::create('order_items', function (Blueprint $table) {
$table->id();
$table->foreignId('order_id')->constrained('orders');
$table->foreignId('product_id')->constrained('products');
$table->integer('quantity');
$table->integer('total_price');
$table->timestamps();
});php artisan make:migration create_order_items_table
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=cafe_db4
DB_USERNAME=root
DB_PASSWORD=Buat Database di mysql dengan nama : cafe_db4php artisan migrate:freshJalankan perintah
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(50) NOT NULL UNIQUE,
phone VARCHAR(25),
roles VARCHAR(5) CHECK (roles IN ('admin', 'staff', 'user')) NOT NULL DEFAULT 'user',
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP
);CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
price INT NOT NULL DEFAULT 0,
stock INT NOT NULL DEFAULT 0,
category VARCHAR(5) CHECK (category IN ('food', 'drink', 'snack')) NOT NULL,
image VARCHAR(255),
created_at TIMESTAMP,
updated_at TIMESTAMP,
is_best_seller BOOLEAN NOT NULL DEFAULT FALSE
);
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
transaction_time TIMESTAMP NOT NULL,
total_price INT NOT NULL,
total_item INT NOT NULL,
kasir_id BIGINT NOT NULL,
payment_method VARCHAR(5) CHECK (payment_method IN ('Tunai', 'QRIS')) NOT NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP,
CONSTRAINT orders_kasir_id_foreign FOREIGN KEY (kasir_id) REFERENCES users(id)
);
CREATE TABLE order_items (
id BIGSERIAL PRIMARY KEY,
order_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
quantity INT NOT NULL,
total_price INT NOT NULL,
created_at TIMESTAMP,
updated_at TIMESTAMP,
CONSTRAINT order_items_order_id_foreign FOREIGN KEY (order_id) REFERENCES orders(id),
CONSTRAINT order_items_product_id_foreign FOREIGN KEY (product_id) REFERENCES products(id)
);
CREATE EXTENSION IF NOT EXISTS pgcrypto;
INSERT INTO users
(name, email, phone, roles, password, created_at, updated_at)
VALUES
('Budi', 'budi@gmail.com', '085644445555', 'user', crypt('budi123', gen_salt('bf')), NOW(), NOW()),
('Ayu', 'ayu@gmail.com', '085655556666', 'user', crypt('ayu123', gen_salt('bf')), NOW(), NOW()),
('Rina', 'rina@gmail.com', '085666667777', 'user', crypt('rina123', gen_salt('bf')), NOW(), NOW());
INSERT INTO products (name, description, price, stock, category, image, created_at, updated_at, is_best_seller)
VALUES
('Nasi Goreng', 'Nasi goreng dengan campuran sayuran dan daging ayam.', 25000, 50, 'food', 'nasi_goreng.jpg', NOW(), NOW(), TRUE),
('Es Teh Manis', 'Teh manis dingin yang segar.', 5000, 100, 'drink', 'es_teh_manis.jpg', NOW(), NOW(), FALSE),
('Keripik Kentang', 'Keripik kentang renyah dengan rasa gurih.', 15000, 30, 'snack', 'keripik_kentang.jpg', NOW(), NOW(), FALSE);
INSERT INTO orders (transaction_time, total_price, total_item, kasir_id, payment_method, created_at, updated_at)
VALUES
('2024-06-24 10:00:00', 40000, 2, 1, 'Tunai', NOW(), NOW()),
('2024-06-24 11:00:00', 20000, 1, 2, 'QRIS', NOW(), NOW()),
('2024-06-24 12:00:00', 30000, 3, 1, 'Tunai', NOW(), NOW());
INSERT INTO order_items (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES
(1, 1, 1, 25000, NOW(), NOW()),
(1, 2, 1, 15000, NOW(), NOW());
INSERT INTO order_items (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES
(2, 3, 1, 20000, NOW(), NOW());
INSERT INTO order_items (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES
(3, 1, 1, 25000, NOW(), NOW()),
(3, 3, 1, 15000, NOW(), NOW()),
(3, 2, 1, 10000, NOW(), NOW());
SELECT
a.id AS order_id,
a.transaction_time,
a.total_price AS order_total_price,
a.total_item AS order_total_item,
b.name AS kasir_name,
a.payment_method,
d.name AS product_name,
d.description AS product_description,
d.price AS product_price,
c.quantity,
c.total_price AS item_total_price
FROM orders a
LEFT JOIN users b ON a.kasir_id = b.id
LEFT JOIN order_items c ON a.id = c.order_id
LEFT JOIN products d ON c.product_id = d.id;
UPDATE order_items oi
SET quantity = 5,
total_price = 5 * p.price,
updated_at = CURRENT_TIMESTAMP
FROM products p
WHERE oi.order_id = 3
AND oi.product_id = 3
AND oi.product_id = p.id;
DELETE FROM order_items WHERE order_id = 3;
DELETE FROM orders WHERE id = 3;
CREATE OR REPLACE VIEW order_details_view AS
SELECT
a.id AS order_id,
a.transaction_time,
a.total_price AS order_total_price,
a.total_item AS order_total_item,
u.name AS kasir_name,
a.payment_method,
p.name AS product_name,
p.description AS product_description,
p.price AS product_price,
oi.quantity,
oi.total_price AS item_total_price
FROM orders a
LEFT JOIN users u ON a.kasir_id = u.id
LEFT JOIN order_items oi ON a.id = oi.order_id
LEFT JOIN products p ON oi.product_id = p.id;
CREATE OR REPLACE VIEW product_sales_view AS
SELECT
p.id AS product_id,
p.name AS product_name,
COALESCE(SUM(oi.quantity), 0) AS total_quantity_sold,
COALESCE(SUM(oi.total_price), 0) AS total_revenue
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.id, p.name;
CREATE OR REPLACE VIEW daily_sales_summary_view AS
SELECT
DATE_TRUNC('day', a.transaction_time) AS transaction_date,
COUNT(a.id) AS total_orders,
SUM(a.total_price) AS total_sales_amount,
SUM(a.total_item) AS total_items_sold
FROM orders a
GROUP BY DATE_TRUNC('day', a.transaction_time);
CREATE OR REPLACE VIEW user_orders_view AS
SELECT
u.id AS user_id,
u.name AS user_name,
COUNT(o.id) AS total_orders
FROM users u
LEFT JOIN orders o ON u.id = o.kasir_id
GROUP BY u.id, u.name;
CREATE OR REPLACE VIEW best_seller_products_view AS
SELECT
p.id AS product_id,
p.name AS product_name,
COALESCE(SUM(oi.quantity), 0) AS total_quantity_sold
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.id, p.name
ORDER BY COALESCE(SUM(oi.quantity), 0) DESC; -- Memastikan penanganan nilai NULL dengan COALESCE
CREATE TABLE users (
id bigint IDENTITY(1,1) NOT NULL PRIMARY KEY,
name varchar(255) NOT NULL,
email varchar(50) NOT NULL UNIQUE,
phone varchar(25) NULL,
roles varchar(10) NOT NULL CHECK (roles IN ('admin', 'staff', 'user')) DEFAULT 'user',
password varchar(255) NOT NULL,
created_at datetime NULL,
updated_at datetime NULL
);
CREATE TABLE products (
id bigint IDENTITY(1,1) NOT NULL PRIMARY KEY,
name varchar(255) NOT NULL,
description text NULL,
price int NOT NULL DEFAULT 0,
stock int NOT NULL DEFAULT 0,
category varchar(10) NOT NULL CHECK (category IN ('food', 'drink', 'snack')),
image varchar(255) NULL,
created_at datetime NULL,
updated_at datetime NULL,
is_best_seller bit NOT NULL DEFAULT 0
);
CREATE TABLE orders (
id bigint IDENTITY(1,1) NOT NULL PRIMARY KEY,
transaction_time datetime NOT NULL,
total_price int NOT NULL,
total_item int NOT NULL,
kasir_id bigint NOT NULL,
payment_method varchar(10) NOT NULL CHECK (payment_method IN ('Tunai', 'QRIS')),
created_at datetime NULL,
updated_at datetime NULL,
CONSTRAINT fk_orders_kasir_id FOREIGN KEY (kasir_id) REFERENCES users(id)
);
CREATE TABLE order_items (
id bigint IDENTITY(1,1) NOT NULL PRIMARY KEY,
order_id bigint NOT NULL,
product_id bigint NOT NULL,
quantity int NOT NULL,
total_price int NOT NULL,
created_at datetime NULL,
updated_at datetime NULL,
CONSTRAINT fk_order_items_order_id FOREIGN KEY (order_id) REFERENCES orders(id),
CONSTRAINT fk_order_items_product_id FOREIGN KEY (product_id) REFERENCES products(id)
);
INSERT INTO users (name, email, phone, roles, password, created_at, updated_at)
VALUES
('Budi', 'budi@gmail.com', '085644445555', 'user', HASHBYTES('SHA2_256', 'budi123'), GETDATE(), GETDATE()),
('Ayu', 'ayu@gmail.com', '085655556666', 'user', HASHBYTES('SHA2_256', 'ayu123'), GETDATE(), GETDATE()),
('Rina', 'rina@gmail.com', '085666667777', 'user', HASHBYTES('SHA2_256', 'rina123'), GETDATE(), GETDATE());
INSERT INTO products (name, description, price, stock, category, image, created_at, updated_at, is_best_seller)
VALUES
('Nasi Goreng', 'Nasi goreng dengan campuran sayuran dan daging ayam.', 25000, 50, 'food', 'nasi_goreng.jpg', GETDATE(), GETDATE(), 1),
('Es Teh Manis', 'Teh manis dingin yang segar.', 5000, 100, 'drink', 'es_teh_manis.jpg', GETDATE(), GETDATE(), 0),
('Keripik Kentang', 'Keripik kentang renyah dengan rasa gurih.', 15000, 30, 'snack', 'keripik_kentang.jpg', GETDATE(), GETDATE(), 0);
INSERT INTO orders (transaction_time, total_price, total_item, kasir_id, payment_method, created_at, updated_at)
VALUES
('2024-06-24 10:00:00', 40000, 2, 1, 'Tunai', GETDATE(), GETDATE()),
('2024-06-24 11:00:00', 20000, 1, 2, 'QRIS', GETDATE(), GETDATE()),
('2024-06-24 12:00:00', 30000, 3, 1, 'Tunai', GETDATE(), GETDATE());
INSERT INTO order_items (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES
(1, 1, 1, 25000, GETDATE(), GETDATE()),
(1, 2, 1, 15000, GETDATE(), GETDATE());
INSERT INTO order_items (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES
(2, 3, 1, 20000, GETDATE(), GETDATE());
INSERT INTO order_items (order_id, product_id, quantity, total_price, created_at, updated_at)
VALUES
(3, 1, 1, 25000, GETDATE(), GETDATE()),
(3, 3, 1, 15000, GETDATE(), GETDATE()),
(3, 2, 1, 10000, GETDATE(), GETDATE());
SELECT
a.id AS order_id,
a.transaction_time,
a.total_price AS order_total_price,
a.total_item AS order_total_item,
b.name AS kasir_name,
a.payment_method,
d.name AS product_name,
d.description AS product_description,
d.price AS product_price,
c.quantity,
c.total_price AS item_total_price
FROM orders a
LEFT JOIN users b ON a.kasir_id = b.id
LEFT JOIN order_items c ON a.id = c.order_id
LEFT JOIN products d ON c.product_id = d.id;
UPDATE oi
SET oi.quantity = 5,
oi.total_price = 5 * p.price,
oi.updated_at = GETDATE()
FROM order_items oi
JOIN products p ON oi.product_id = p.id
WHERE oi.order_id = 3
AND oi.product_id = 3;
DELETE FROM order_items WHERE order_id = 3;
DELETE FROM orders WHERE id = 3;
CREATE VIEW order_details_view AS
SELECT
a.id AS order_id,
a.transaction_time,
a.total_price AS order_total_price,
a.total_item AS order_total_item,
b.name AS kasir_name,
a.payment_method,
d.name AS product_name,
d.description AS product_description,
d.price AS product_price,
c.quantity,
c.total_price AS item_total_price
FROM orders a
LEFT JOIN users b ON a.kasir_id = b.id
LEFT JOIN order_items c ON a.id = c.order_id
LEFT JOIN products d ON c.product_id = d.id;
CREATE VIEW product_sales_view AS
SELECT
p.id AS product_id,
p.name AS product_name,
SUM(oi.quantity) AS total_quantity_sold,
SUM(oi.total_price) AS total_revenue
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.id, p.name;
CREATE VIEW daily_sales_summary_view AS
SELECT
CONVERT(date, a.transaction_time) AS transaction_date,
COUNT(a.id) AS total_orders,
SUM(a.total_price) AS total_sales_amount,
SUM(a.total_item) AS total_items_sold
FROM orders a
GROUP BY CONVERT(date, a.transaction_time);
CREATE VIEW user_orders_view AS
SELECT
u.id AS user_id,
u.name AS user_name,
COUNT(o.id) AS total_orders
FROM users u
LEFT JOIN orders o ON u.id = o.kasir_id
GROUP BY u.id, u.name;
CREATE VIEW best_seller_products_view AS
SELECT
p.id AS product_id,
p.name AS product_name,
SUM(oi.quantity) AS total_quantity_sold
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.id, p.name;
CREATE PROCEDURE dbo.spProductList
@search_name NVARCHAR(255),
@search_category NVARCHAR(50),
@page INT,
@page_size INT
AS
BEGIN
DECLARE @offset_val INT;
SET @offset_val = (@page - 1) * @page_size;
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (ORDER BY id) AS row_num
FROM products
WHERE (@search_name IS NULL OR name LIKE '%' + @search_name + '%')
AND (@search_category IS NULL OR @search_category = '' OR category = @search_category)
) AS numbered_products
WHERE row_num > @offset_val
AND row_num <= @offset_val + @page_size;
END;
CREATE PROCEDURE dbo.spProductDetail
@product_id BIGINT
AS
BEGIN
SELECT *
FROM products
WHERE id = @product_id;
END;
CREATE PROCEDURE dbo.spProductAdd
@p_name NVARCHAR(255),
@p_description NVARCHAR(MAX),
@p_price INT,
@p_stock INT,
@p_category NVARCHAR(50),
@p_image NVARCHAR(255)
AS
BEGIN
DECLARE @result_code INT;
DECLARE @error_message NVARCHAR(1000);
-- Check if name or category is empty
IF @p_name IS NULL OR @p_name = '' OR @p_category IS NULL OR @p_category = '' BEGIN
SET @result_code = 39999;
SET @error_message = 'Semua kolom (nama, kategori) harus diisi.';
SELECT @result_code AS result_code, @error_message AS error_message;
END
ELSE BEGIN
-- Check if product name already exists
IF EXISTS (SELECT 1 FROM products WHERE name = @p_name) BEGIN
SET @result_code = 39998;
SET @error_message = 'Nama produk sudah ada dalam database.';
SELECT @result_code AS result_code, @error_message AS error_message;
END
ELSE BEGIN
-- Insert new product
INSERT INTO products (name, description, price, stock, category, image, created_at, updated_at)
VALUES (@p_name, @p_description, @p_price, @p_stock, @p_category, @p_image, GETDATE(), GETDATE());
SET @result_code = 1;
SET @error_message = '';
SELECT @result_code AS result_code, @error_message AS error_message;
END
END
END;
CREATE PROCEDURE dbo.spProductEdit
@p_id BIGINT,
@p_name NVARCHAR(255),
@p_description NVARCHAR(MAX),
@p_price INT,
@p_stock INT,
@p_category NVARCHAR(50),
@p_image NVARCHAR(255)
AS
BEGIN
DECLARE @result_code INT;
DECLARE @error_message NVARCHAR(1000);
DECLARE @product_count INT;
-- Check if the product exists
SELECT @product_count = COUNT(*)
FROM products
WHERE id = @p_id;
IF @product_count = 0 BEGIN
SET @result_code = 39999;
SET @error_message = 'Produk dengan ID yang diberikan tidak ditemukan.';
SELECT @result_code AS result_code, @error_message AS error_message;
END
ELSE BEGIN
IF @p_name IS NULL OR @p_name = '' OR @p_category IS NULL OR @p_category = '' BEGIN
SET @result_code = 39999;
SET @error_message = 'Semua kolom (nama, kategori) harus diisi.';
SELECT @result_code AS result_code, @error_message AS error_message;
END
ELSE BEGIN
-- Update product
UPDATE products
SET name = @p_name,
description = @p_description,
price = @p_price,
stock = @p_stock,
category = @p_category,
image = @p_image,
updated_at = GETDATE()
WHERE id = @p_id;
SET @result_code = 1;
SET @error_message = '';
SELECT @result_code AS result_code, @error_message AS error_message;
END
END
END;
CREATE PROCEDURE dbo.spProductStockAdd
@p_product_id BIGINT,
@p_add_stock INT
AS
BEGIN
DECLARE @result_code INT;
DECLARE @error_message NVARCHAR(1000);
DECLARE @current_stock INT;
-- Check if the product exists
IF NOT EXISTS (SELECT 1 FROM products WHERE id = @p_product_id) BEGIN
SET @result_code = 0;
SET @error_message = 'Product ID does not exist';
END
ELSE BEGIN
-- Get the current stock
SELECT @current_stock = stock FROM products WHERE id = @p_product_id;
-- Add the new stock
UPDATE products SET stock = @current_stock + @p_add_stock, updated_at = GETDATE() WHERE id = @p_product_id;
SET @result_code = 1;
SET @error_message = '';
END
SELECT @result_code AS result_code, @error_message AS error_message;
END;
CREATE PROCEDURE dbo.spProductDelete
@p_id BIGINT
AS
BEGIN
DECLARE @item_count INT;
DECLARE @result_code INT;
DECLARE @error_message NVARCHAR(1000);
-- Check if the product exists in the products table
SELECT @item_count = COUNT(*)
FROM products
WHERE id = @p_id;
IF @item_count = 0 BEGIN
SET @result_code = 39998;
SET @error_message = 'Produk dengan ID tersebut tidak ditemukan dalam database.';
SELECT @result_code AS result_code, @error_message AS error_message;
END
ELSE BEGIN
-- Check if the product is still in order_items
SELECT @item_count = COUNT(*)
FROM order_items
WHERE product_id = @p_id;
IF @item_count > 0 BEGIN
SET @result_code = 39999;
SET @error_message = 'Produk tidak dapat dihapus karena masih terdapat data di tabel order_items.';
SELECT @result_code AS result_code, @error_message AS error_message;
END
ELSE BEGIN
DELETE FROM products WHERE id = @p_id;
SET @result_code = 1;
SET @error_message = '';
SELECT @result_code AS result_code, @error_message AS error_message;
END
END
END;
EXEC dbo.spProductList
@search_name = '',
@search_category = 'food',
@page = 1,
@page_size = 10;
EXEC dbo.spProductDetail @product_id=1;
EXEC dbo.spProductAdd
@p_name = 'Nama Produk',
@p_description = 'Deskripsi produk',
@p_price = 25000,
@p_stock = 50,
@p_category = 'food',
@p_image = 'nama_file_gambar.jpg';
EXEC dbo.spProductEdit
@p_id = 1,
@p_name = 'Nama Produk Baru',
@p_description = 'Deskripsi produk baru',
@p_price = 30000,
@p_stock = 100,
@p_category = 'drink',
@p_image = 'nama_file_gambar_baru.jpg';
EXEC dbo.spProductStockAdd
@p_product_id = 1,
@p_add_stock = 20;
EXEC dbo.spProductDelete
@p_id = 1;
Setiap kelompok mengambil 1 tema yang disediakan
Dari tema yang dipilih, buatmodel ERD
Pilih database yang digunakan (mysql, sql server, postgre sql)
Buat database dengan database dan tema yang sudah dipilih dengan kriteria mengandung