Kelompok E Kelas B
Dosen Pengampu: Bayutama Isnaini. S.Si., M.Si.
Anggota Kelompok:
| Nama | NIM |
|---|---|
| Febi Atika Sari | 21108062610037 |
| Ghaniya Qolbi Uswatun Hasanah | 21108062610041 |
| Habibi Aldrich Putra Prabaswara | 21108062610043 |
| Irkhas Safira | 21108062610050 |
| Keyza Sani Maulida | 21108062610057 |
Dalam bisnis ritel, diskon digunakan untuk menarik pelanggan, mendorong pembelian dalam jumlah besar, dan menjaga loyalitas anggota. Aturan diskon umumnya berlapis: nilai belanja, status keanggotaan, dan waktu transaksi masing-masing dapat memberikan potongan tersendiri. Jika dihitung secara manual, kasir mudah keliru menjumlahkan potongan, melewatkan batas maksimum diskon, atau lupa menambahkan biaya layanan sesuai metode pembayaran.
Kesalahan kecil pada setiap transaksi dapat berdampak besar pada keuntungan toko dan kepercayaan pelanggan. Oleh karena itu, perhitungan perlu diotomatisasi dengan program yang konsisten dan mudah diperiksa. Bagi mahasiswa, kasus ini melatih kemampuan mengubah aturan bisnis menjadi logika program menggunakan vektor, factor, operator logika, fungsi, dan percabangan (if, ifelse(), if_else(), case_when()) tanpa pengulangan.
Setelah mempelajari modul ini, pembaca mampu:
Sebuah toko ingin membuat sistem sederhana untuk menentukan jumlah diskon dan total pembayaran pelanggan. Besar diskon ditentukan oleh tiga faktor, yaitu total belanja, status member (Non-member, Silver, Gold, Platinum), dan hari transaksi (hari kerja, Sabtu, atau Minggu). Ketiganya dijumlahkan dengan batas maksimum diskon sebesar 25%. Setelah diskon ditetapkan, sistem menambahkan biaya layanan sesuai metode pembayaran (Tunai, Transfer, E-wallet, atau Kartu kredit).
Data yang diolah berupa 15 transaksi pelanggan (Andi hingga Olivia). Untuk setiap pelanggan, program harus menghasilkan:
Selain itu, program menyajikan ringkasan seluruh transaksi dan pencarian transaksi berdasarkan nama. Kasus Intan (total diskon awal 26% yang dibatasi menjadi 25%) digunakan sebagai contoh utama untuk memverifikasi penerapan batas diskon. Seluruh logika utama diselesaikan tanpa for, while, atau repeat.
| Total Belanja | Diskon |
|---|---|
| < Rp200.000 | 0% |
| Rp200.000 - Rp499.999 | 5% |
| Rp500.000 - Rp999.999 | 10% |
| ≥ Rp1.000.000 | 15% |
| Status Member | Tambahan Diskon |
|---|---|
| Non-member | 0% |
| Silver | 2% |
| Gold | 5% |
| Platinum | 8% |
| Hari Transaksi | Tambahan Diskon |
|---|---|
| Senin - Jumat | 0% |
| Sabtu | 3% |
| Minggu | 5% |
| Metode Pembayaran | Biaya Layanan |
|---|---|
| Tunai | Rp0 |
| Transfer | Rp2.000 |
| E-wallet | Rp1.000 |
| Kartu kredit | Rp5.000 |
Total diskon = diskon dasar + tambahan member + tambahan hari. Jika hasilnya lebih dari 25%, diskon yang digunakan tetap 25%.
Data transaksi disimpan dalam beberapa vektor. Setiap posisi pada vektor mewakili satu transaksi.
nama <- c('Andi', 'Budi', 'Citra', 'Dinda', 'Eko', 'Fajar', 'Gita', 'Hadi', 'Intan', 'Joko', 'Karin', 'Luthfi', 'Maya', 'Nanda', 'Olivia')
belanja <- c(175000, 325000, 475000, 625000, 780000, 950000, 1100000, 1350000, 1750000, 250000, 540000, 890000, 1020000, 1480000, 410000)
member <- c('Non-member', 'Silver', 'Gold', 'Non-member', 'Silver', 'Gold', 'Platinum', 'Gold', 'Platinum', 'Silver', 'Gold', 'Platinum', 'Silver', 'Platinum', 'Non-member')
hari <- c('Senin', 'Selasa', 'Sabtu', 'Minggu', 'Rabu', 'Sabtu', 'Kamis', 'Minggu', 'Sabtu', 'Jumat', 'Minggu', 'Senin', 'Sabtu', 'Minggu', 'Rabu')
pembayaran <- c('Tunai', 'Transfer', 'E-wallet', 'Tunai', 'E-wallet', 'Transfer', 'Kartu kredit', 'E-wallet', 'Kartu kredit', 'Tunai', 'Transfer', 'E-wallet', 'Transfer', 'Kartu kredit', 'Tunai')
Operator && dan || dapat digunakan untuk memeriksa kondisi pada satu transaksi.
idx <- 9
if (belanja[idx] >= 1000000 && member[idx] == 'Platinum') {
print('Belanja besar dan member Platinum')
} else if (belanja[idx] >= 1000000 || member[idx] == 'Platinum') {
print('Salah satu syarat terpenuhi')
} else {
print('Tidak memenuhi syarat')
}
## [1] "Belanja besar dan member Platinum"
ifelse() cocok untuk memberikan hasil berdasarkan suatu kondisi, sedangkan case_when() memudahkan pengolahan beberapa kondisi secara berurutan.
# ---- 0. PACKAGES ----
if (!requireNamespace('dplyr', quietly = TRUE)) install.packages('dplyr')
library(dplyr) # untuk if_else() dan case_when()
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# ---- 1. OBJEK & VEKTOR ----
# Objek = nama yang menyimpan data; vektor = kumpulan elemen sejenis
nama <- c('Andi', 'Budi', 'Citra', 'Dinda', 'Eko', 'Fajar', 'Gita', 'Hadi', 'Intan', 'Joko', 'Karin', 'Luthfi', 'Maya', 'Nanda', 'Olivia')
belanja <- c(175000, 325000, 475000, 625000, 780000, 950000, 1100000, 1350000,
1750000, 250000, 540000, 890000, 1020000, 1480000, 410000)
member <- c('Non-member', 'Silver', 'Gold', 'Non-member', 'Silver', 'Gold', 'Platinum', 'Gold', 'Platinum', 'Silver', 'Gold', 'Platinum', 'Silver', 'Platinum', 'Non-member')
hari <- c('Senin', 'Selasa', 'Sabtu', 'Minggu', 'Rabu', 'Sabtu', 'Kamis', 'Minggu', 'Sabtu', 'Jumat', 'Minggu', 'Senin', 'Sabtu', 'Minggu', 'Rabu')
pembayaran <- c('Tunai', 'Transfer', 'E-wallet', 'Tunai', 'E-wallet', 'Transfer', 'Kartu kredit', 'E-wallet', 'Kartu kredit', 'Tunai', 'Transfer', 'E-wallet', 'Transfer', 'Kartu kredit', 'Tunai')
# ---- 2. FACTOR ----
# Data kategorik diubah menjadi factor dengan urutan level yang jelas
member <- factor(member, levels = c('Non-member', 'Silver', 'Gold', 'Platinum'))
hari<- factor(hari, levels = c('Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu'))
pembayaran <- factor(pembayaran, levels = c('Tunai', 'Transfer', 'E-wallet', 'Kartu kredit'))
# ---- 3. OPERATOR LOGIKA & IF (satu transaksi) ----
# && dan || dipakai untuk satu nilai
idx <- 9 # Intan
if (belanja[idx] >= 1000000 && member[idx] == 'Platinum') {
print('Belanja besar dan member Platinum')
} else if (belanja[idx] >= 1000000 || member[idx] == 'Platinum') {
print('Salah satu syarat terpenuhi')
} else {
print('Tidak memenuhi syarat')
}
## [1] "Belanja besar dan member Platinum"
# ---- 4. FUNGSI ----
# 4a. Fungsi dengan if untuk SATU nilai belanja
hitung_dasar_1 <- function(b) {
if (b >= 1000000) {
0.15
} else if (b >= 500000) {
0.10
} else if (b >= 200000) {
0.05
} else {
0
}
}
# 4b. Fungsi total diskon dengan batas maksimum (memakai ifelse)
hitung_total_diskon <- function(dasar, tambah_member, tambah_hari, batas = 0.25) {
total <- round(dasar + tambah_member + tambah_hari, 4) # round untuk menghindari error desimal
ifelse(total > batas, batas, total)
}
# ---- 5. CASE_WHEN: nilai dari banyak kondisi ----
# Kondisi dicek berurutan, kecocokan pertama yang dipakai
diskon_dasar <- case_when(
belanja >= 1000000 ~ 0.15,
belanja >= 500000 ~ 0.10,
belanja >= 200000 ~ 0.05,
TRUE ~ 0
)
tambahan_member <- case_when(
member == 'Silver' ~ 0.02,
member == 'Gold' ~ 0.05,
member == 'Platinum' ~ 0.08,
TRUE ~ 0
)
tambahan_hari <- case_when(
hari == 'Sabtu' ~ 0.03,
hari == 'Minggu' ~ 0.05,
TRUE ~ 0
)
biaya_layanan <- case_when(
pembayaran == 'Tunai' ~ 0,
pembayaran == 'Transfer' ~ 2000,
pembayaran == 'E-wallet' ~ 1000,
pembayaran == 'Kartu kredit' ~ 5000
)
# ---- 6. OPERATOR & PERHITUNGAN ----
# Total diskon sebelum batas maksimum 25%
total_mentah <- round(diskon_dasar + tambahan_member + tambahan_hari, 4)
# Total diskon setelah batas maksimum (fungsi dari bagian 4b)
total_diskon <- hitung_total_diskon(diskon_dasar, tambahan_member, tambahan_hari)
# ---- 7. IFELSE dan IF_ELSE ----
# ifelse (base R): keterangan ada atau tidaknya diskon
ada_diskon <- ifelse(total_diskon > 0, 'Dapat diskon', 'Tanpa diskon')
# if_else (dplyr): menandai transaksi yang kena batas 25%
kena_batas <- if_else(total_mentah > 0.25, 'Ya', 'Tidak', missing = 'Tidak ada data')
# ---- 8. POTONGAN DAN TOTAL PEMBAYARAN ----
potongan <- round(total_diskon * belanja, 0)
total_bayar <- belanja - potongan + biaya_layanan
# ---- 9. DATA FRAME: hasil lengkap ----
hasil <- data.frame(
nama = nama,
belanja = belanja,
member = member,
hari = hari,
pembayaran = pembayaran,
dasar_persen = round(diskon_dasar * 100, 2),
tambahan_member_persen = round(tambahan_member * 100, 2),
tambahan_hari_persen = round(tambahan_hari * 100, 2),
total_diskon_persen = round(total_diskon * 100, 2),
kena_batas = kena_batas,
potongan = potongan,
biaya_layanan = biaya_layanan,
total_bayar = total_bayar
)
# ---- 10. LIST: ringkasan seluruh transaksi ----
ringkasan <- list(
jumlah_transaksi = nrow(hasil),
total_belanja = sum(belanja),
total_potongan = sum(potongan),
total_biaya_layanan = sum(biaya_layanan),
total_pembayaran = sum(total_bayar),
jumlah_kena_batas = sum(kena_batas == 'Ya')
)
# ---- 11. FUNGSI: mencari transaksi berdasarkan nama ----
cari_transaksi <- function(nama_cari) {
hasil[hasil$nama == nama_cari, ]
}
# =====================================================================
# LAMPIRAN: MATRIKS DAN ARRAY
# Sesuai batasan kasus, bagian ini TIDAK dipakai dalam logika utama.
# =====================================================================
# Matriks: menggabungkan kolom angka dengan cbind()
m_ringkas <- cbind(belanja, potongan, total_bayar)
rownames(m_ringkas) <- nama
# Array: data dengan lebih dari dua dimensi
arr <- array(1:12, dim = c(2, 3, 2))
library(knitr)
kable(hasil, caption = "Hasil Perhitungan Diskon dan Total Pembayaran")
| nama | belanja | member | hari | pembayaran | dasar_persen | tambahan_member_persen | tambahan_hari_persen | total_diskon_persen | kena_batas | potongan | biaya_layanan | total_bayar |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Andi | 175000 | Non-member | Senin | Tunai | 0 | 0 | 0 | 0 | Tidak | 0 | 0 | 175000 |
| Budi | 325000 | Silver | Selasa | Transfer | 5 | 2 | 0 | 7 | Tidak | 22750 | 2000 | 304250 |
| Citra | 475000 | Gold | Sabtu | E-wallet | 5 | 5 | 3 | 13 | Tidak | 61750 | 1000 | 414250 |
| Dinda | 625000 | Non-member | Minggu | Tunai | 10 | 0 | 5 | 15 | Tidak | 93750 | 0 | 531250 |
| Eko | 780000 | Silver | Rabu | E-wallet | 10 | 2 | 0 | 12 | Tidak | 93600 | 1000 | 687400 |
| Fajar | 950000 | Gold | Sabtu | Transfer | 10 | 5 | 3 | 18 | Tidak | 171000 | 2000 | 781000 |
| Gita | 1100000 | Platinum | Kamis | Kartu kredit | 15 | 8 | 0 | 23 | Tidak | 253000 | 5000 | 852000 |
| Hadi | 1350000 | Gold | Minggu | E-wallet | 15 | 5 | 5 | 25 | Tidak | 337500 | 1000 | 1013500 |
| Intan | 1750000 | Platinum | Sabtu | Kartu kredit | 15 | 8 | 3 | 25 | Ya | 437500 | 5000 | 1317500 |
| Joko | 250000 | Silver | Jumat | Tunai | 5 | 2 | 0 | 7 | Tidak | 17500 | 0 | 232500 |
| Karin | 540000 | Gold | Minggu | Transfer | 10 | 5 | 5 | 20 | Tidak | 108000 | 2000 | 434000 |
| Luthfi | 890000 | Platinum | Senin | E-wallet | 10 | 8 | 0 | 18 | Tidak | 160200 | 1000 | 730800 |
| Maya | 1020000 | Silver | Sabtu | Transfer | 15 | 2 | 3 | 20 | Tidak | 204000 | 2000 | 818000 |
| Nanda | 1480000 | Platinum | Minggu | Kartu kredit | 15 | 8 | 5 | 25 | Ya | 370000 | 5000 | 1115000 |
| Olivia | 410000 | Non-member | Rabu | Tunai | 5 | 0 | 0 | 5 | Tidak | 20500 | 0 | 389500 |
Batas maksimum diskon. Total diskon awal Intan (26%) dan Nanda (28%) melebihi batas sehingga diturunkan menjadi 25%. Tanpa batas ini, toko akan memberi potongan tambahan Rp17.500 untuk Intan dan Rp44.400 untuk Nanda, atau Rp61.900 secara keseluruhan. Hadi tepat berada di 25% (15% + 5% + 5%) sehingga tidak terpengaruh, sedangkan Gita (23%) masih di bawah batas.
Pengaruh nilai belanja. Diskon dasar menjadi komponen paling dominan. Lima pelanggan dengan belanja minimal Rp1.000.000 (Gita, Hadi, Intan, Maya, Nanda) menyumbang sekitar 55% dari total belanja, tetapi menerima sekitar 68% dari seluruh potongan, yaitu Rp1.602.000. Artinya, aturan diskon bertingkat lebih menguntungkan pelanggan yang berbelanja besar.
Pengaruh status member dan hari transaksi. Hari akhir pekan dapat mengalahkan keunggulan belanja. Dinda (non-member, Rp625.000, Minggu) memperoleh diskon 15%, lebih tinggi daripada Eko (Silver, Rp780.000, Rabu) yang hanya 12%. Delapan dari 15 transaksi terjadi pada Sabtu atau Minggu, sehingga tambahan diskon hari berperan cukup besar pada total potongan.
Pengaruh biaya layanan. Biaya layanan hanya sekitar 1,1% dari total potongan sehingga tidak mengubah urutan besar pembayaran secara berarti. Dampaknya paling terasa pada belanja kecil, misalnya Budi yang potongannya Rp22.750 sebagian terserap biaya transfer Rp2.000 (sekitar 8,8%). Metode kartu kredit (Gita, Intan, Nanda) memberi biaya terbesar, yaitu Rp5.000 per transaksi.
Catatan implementasi. Urutan kondisi pada case_when() harus dimulai dari ambang tertinggi dan memakai operator >= agar belanja tepat Rp200.000, Rp500.000, atau Rp1.000.000 masuk kategori yang benar. Karena data diproses tanpa for, while, atau repeat, perhitungan dilakukan sekaligus pada vektor. Cara ini ringkas untuk 15 transaksi, tetapi data baru tetap harus ditambahkan secara manual ke setiap vektor.
Berdasarkan penyelesaian kasus penentuan diskon belanja menggunakan RStudio, dapat disimpulkan bahwa program berhasil mengolah 15 transaksi pelanggan tanpa menggunakan perulangan for, while, maupun repeat pada logika utama. Program memanfaatkan objek, vektor, factor, operator logika, fungsi, percabangan if, ifelse(), if_else(), case_when(), serta data frame untuk melakukan pengolahan data secara sistematis.
Program berhasil menentukan diskon dasar berdasarkan nominal belanja, tambahan diskon berdasarkan status member dan hari transaksi. Program juga menerapkan batas maksimum diskon sebesar 25% serta menghitung biaya layanan sesuai metode pembayaran yang digunakan.
Penerapan batas maksimum diskon sebesar 25% juga berhasil dilakukan. Hal ini ditunjukkan pada transaksi Intan, yang memiliki total diskon awal sebesar 26% sehingga diskon yang digunakan menjadi 25% dan total pembayarannya sebesar Rp1.317.500. Dengan demikian, program dapat membantu proses perhitungan diskon dan pembayaran secara lebih terstruktur, konsisten, dan mudah diperiksa.