<?php
namespace App\Http\Controllers;
use App\Helpers\Helper;
use App\Models\Pelanggan;
use App\Models\RewardPromo;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class PelangganAktifController extends Controller
{
private $sorting_order = "desc";
public function index(Request $request)
{
if ($request->sorting_order == "desc") {
$this->sorting_order = "asc";
}
$sorting_order = $this->sorting_order;
$begin = new DateTime('-1 month');
$end = new DateTime();
$periode = [
$begin->format('d/m/Y'),
$end->format('d/m/Y'),
];
// dd($begin, $end);
// $datas = Pelanggan::with(['riwayat', 'penjualan.detail_penjualan', 'service' => function ($q) {
// $q->where('status_transaksi', 'success')->with('detail');
// }])->withCount("riwayat")->withCount('penjualan')->withCount(['service' => function ($q) {
// $q->where('status_transaksi', 'success');
// }]);
$pelanggans = Pelanggan::query();
$datas = Pelanggan::with(['riwayat', 'penjualan.detail_penjualan', 'service.detail', 'service.sparepart_luar', 'review_pelanggans', 'referral_pelanggans'])
->select([
'pelanggans.*',
])
// Menghitung jumlah transaksi (total penjualan + total service 'success')
->selectRaw(
'(
(SELECT COUNT(*) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL) +
(SELECT COUNT(*) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL)
) as jumlah_transaksi'
)
// Menghitung nominal transaksi (total harga item penjualan + total harga item service 'success')
->selectRaw(
'
COALESCE((SELECT SUM((detail_penjualans.harga_item - detail_penjualans.diskon)*detail_penjualans.qty)
FROM detail_penjualans
JOIN penjualans ON detail_penjualans.penjualan_id = penjualans.id
WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL AND detail_penjualans.deleted_at IS NULL), 0)
+
COALESCE((SELECT SUM(services.biaya)
FROM services
WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL), 0)
+
COALESCE((SELECT SUM(((detail_services.harga_item - detail_services.diskon)*detail_services.jumlah))
FROM detail_services
JOIN services ON detail_services.service_id = services.id
WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL AND detail_services.deleted_at IS NULL), 0)
+
COALESCE((SELECT SUM(((sparepart_luars.harga_jual_SL - sparepart_luars.diskon_SL)*sparepart_luars.jumlah_SL))
FROM sparepart_luars
JOIN services ON sparepart_luars.service_id = services.id
WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL), 0)
as total_nominal'
)
// NEW: Calculate earliest transaction date for durasi_label
->selectRaw(
'
COALESCE(
pelanggans.created_at,
(SELECT MIN(services.created_at) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.deleted_at IS NULL ORDER BY services.id ASC LIMIT 1),
(SELECT MIN(penjualans.created_at) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL ORDER BY penjualans.id ASC LIMIT 1)
) as earliest_date'
)
// NEW: Calculate years difference for durasi calculation
->selectRaw(
'TIMESTAMPDIFF(YEAR,
COALESCE(
pelanggans.created_at,
(SELECT MIN(services.created_at) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.deleted_at IS NULL ORDER BY services.id ASC LIMIT 1),
(SELECT MIN(penjualans.created_at) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL ORDER BY penjualans.id ASC LIMIT 1)
),
NOW()
) as years_diff'
)
->selectRaw(
'TIMESTAMPDIFF(MONTH,
COALESCE(
pelanggans.created_at,
(SELECT MIN(services.created_at) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.deleted_at IS NULL ORDER BY services.id ASC LIMIT 1),
(SELECT MIN(penjualans.created_at) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL ORDER BY penjualans.id ASC LIMIT 1)
),
NOW()
) % 12 as months_diff'
)
->selectRaw(
'TIMESTAMPDIFF(DAY,
DATE_ADD(
COALESCE(
pelanggans.created_at,
(SELECT MIN(services.created_at) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.deleted_at IS NULL ORDER BY services.id ASC LIMIT 1),
(SELECT MIN(penjualans.created_at) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL ORDER BY penjualans.id ASC LIMIT 1)
),
INTERVAL TIMESTAMPDIFF(MONTH,
COALESCE(
pelanggans.created_at,
(SELECT MIN(services.created_at) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.deleted_at IS NULL ORDER BY services.id ASC LIMIT 1),
(SELECT MIN(penjualans.created_at) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL ORDER BY penjualans.id ASC LIMIT 1)
),
NOW()
) MONTH
),
NOW()
) as days_diff'
)
->selectRaw(
'TIMESTAMPDIFF(DAY,
COALESCE(
pelanggans.created_at,
(SELECT MIN(services.created_at) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.deleted_at IS NULL ORDER BY services.id ASC LIMIT 1),
(SELECT MIN(penjualans.created_at) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL ORDER BY penjualans.id ASC LIMIT 1)
),
NOW()
) as times_diff'
)
// NEW: Calculate total review
->selectRaw(
'
CASE
WHEN (SELECT COUNT(*) FROM review_pelanggans WHERE review_pelanggans.pelanggan_id = pelanggans.id) > 0
THEN (SELECT SUM(review_pelanggans.nilai_review) FROM review_pelanggans WHERE review_pelanggans.pelanggan_id = pelanggans.id) /
((SELECT COUNT(*) FROM review_pelanggans WHERE review_pelanggans.pelanggan_id = pelanggans.id) * 5)
ELSE 0
END as total_review'
)
// NEW: Calculate jumlah referral
->selectRaw(
'
COALESCE((
SELECT COUNT(*)
FROM referralables
WHERE referralables.referral_pelanggan_id IN (
SELECT rp.id
FROM referral_pelanggans rp
WHERE rp.pelanggan_id = pelanggans.id
)
), 0) as jumlah_referral'
)
// NEW: Calculate skor loyalitas components
->selectRaw(
'
-- Skor Frekuensi (30%)
(CASE
WHEN (
(SELECT COUNT(*) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL) +
(SELECT COUNT(*) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL)
) > 0
THEN LEAST(5, (
(SELECT COUNT(*) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL) +
(SELECT COUNT(*) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL)
)) / 5
ELSE 0
END * 30) +
-- Skor Pengeluaran (25%)
(CASE
WHEN (
COALESCE((SELECT SUM((detail_penjualans.harga_item - detail_penjualans.diskon)*detail_penjualans.qty)
FROM detail_penjualans
JOIN penjualans ON detail_penjualans.penjualan_id = penjualans.id
WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL AND detail_penjualans.deleted_at IS NULL), 0)
+
COALESCE((SELECT SUM(services.biaya)
FROM services
WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL), 0)
+
COALESCE((SELECT SUM(((detail_services.harga_item - detail_services.diskon)*detail_services.jumlah))
FROM detail_services
JOIN services ON detail_services.service_id = services.id
WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL AND detail_services.deleted_at IS NULL), 0)
+
COALESCE((SELECT SUM(((sparepart_luars.harga_jual_SL - sparepart_luars.diskon_SL)*sparepart_luars.jumlah_SL))
FROM sparepart_luars
JOIN services ON sparepart_luars.service_id = services.id
WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL), 0)
) > 0
THEN LEAST(3000000, (
COALESCE((SELECT SUM((detail_penjualans.harga_item - detail_penjualans.diskon)*detail_penjualans.qty)
FROM detail_penjualans
JOIN penjualans ON detail_penjualans.penjualan_id = penjualans.id
WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL AND detail_penjualans.deleted_at IS NULL), 0)
+
COALESCE((SELECT SUM(services.biaya)
FROM services
WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL), 0)
+
COALESCE((SELECT SUM(((detail_services.harga_item - detail_services.diskon)*detail_services.jumlah))
FROM detail_services
JOIN services ON detail_services.service_id = services.id
WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL AND detail_services.deleted_at IS NULL), 0)
+
COALESCE((SELECT SUM(((sparepart_luars.harga_jual_SL - sparepart_luars.diskon_SL)*sparepart_luars.jumlah_SL))
FROM sparepart_luars
JOIN services ON sparepart_luars.service_id = services.id
WHERE services.pelanggan_id = pelanggans.id AND services.status_transaksi = "success" AND services.deleted_at IS NULL), 0)
)) / 3000000
ELSE 0
END * 25) +
-- Skor Referral (20%)
(CASE
WHEN COALESCE((
SELECT COUNT(*)
FROM referralables
WHERE referralables.referral_pelanggan_id IN (
SELECT rp.id
FROM referral_pelanggans rp
WHERE rp.pelanggan_id = pelanggans.id
)
), 0) > 0
THEN LEAST(3, COALESCE((
SELECT COUNT(*)
FROM referralables
WHERE referralables.referral_pelanggan_id IN (
SELECT rp.id
FROM referral_pelanggans rp
WHERE rp.pelanggan_id = pelanggans.id
)
), 0)) / 3
ELSE 0
END * 20) +
-- Skor Durasi (15%)
(CASE
WHEN TIMESTAMPDIFF(YEAR,
COALESCE(
pelanggans.created_at,
(SELECT MIN(services.created_at) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.deleted_at IS NULL ORDER BY services.id ASC LIMIT 1),
(SELECT MIN(penjualans.created_at) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL ORDER BY penjualans.id ASC LIMIT 1)
),
NOW()
) > 0
THEN LEAST(2, TIMESTAMPDIFF(YEAR,
COALESCE(
pelanggans.created_at,
(SELECT MIN(services.created_at) FROM services WHERE services.pelanggan_id = pelanggans.id AND services.deleted_at IS NULL ORDER BY services.id ASC LIMIT 1),
(SELECT MIN(penjualans.created_at) FROM penjualans WHERE penjualans.pelanggan_id = pelanggans.id AND penjualans.deleted_at IS NULL ORDER BY penjualans.id ASC LIMIT 1)
),
NOW()
)) / 2
ELSE 0
END * 15) +
-- Skor Review (10%)
(CASE
WHEN (
CASE
WHEN (SELECT COUNT(*) FROM review_pelanggans WHERE review_pelanggans.pelanggan_id = pelanggans.id) > 0
THEN (SELECT SUM(review_pelanggans.nilai_review) FROM review_pelanggans WHERE review_pelanggans.pelanggan_id = pelanggans.id) /
((SELECT COUNT(*) FROM review_pelanggans WHERE review_pelanggans.pelanggan_id = pelanggans.id) * 5)
ELSE 0
END
) > 0
THEN LEAST(5, (
CASE
WHEN (SELECT COUNT(*) FROM review_pelanggans WHERE review_pelanggans.pelanggan_id = pelanggans.id) > 0
THEN (SELECT SUM(review_pelanggans.nilai_review) FROM review_pelanggans WHERE review_pelanggans.pelanggan_id = pelanggans.id) /
((SELECT COUNT(*) FROM review_pelanggans WHERE review_pelanggans.pelanggan_id = pelanggans.id) * 5)
ELSE 0
END
)) / 5
ELSE 0
END * 10)
as skor_loyalitas'
)
->groupBy('pelanggans.id');
$jumlahSuperLoyal = (clone $datas)->having('skor_loyalitas','>',80)->count();
$jumlahLoyalAktif = (clone $datas)->having('skor_loyalitas','>',70)->count();
$jumlahPotensiLoyal = (clone $datas)->having('skor_loyalitas','>',40)->count();
$jumlahPasif = (clone $datas)->having('skor_loyalitas','>',20)->count();
$jumlahBaru = (clone $datas)->having('skor_loyalitas','<=',20)->count();
if (request()->periode) {
$periode = explode(" - ", request()->periode);
$begin = DateTime::createFromFormat('d/m/Y', $periode[0])->setTime(0, 0, 0);
$end = DateTime::createFromFormat('d/m/Y', $periode[1])->setTime(23, 59, 59);
if (isset($begin) && isset($end)) {
$datas->tanggal($begin, $end);
$pelanggans->tanggal($begin, $end);
}
}
if (isset($request->kecamatan)) {
$datas->kecamatan($request->kecamatan);
$pelanggans->kecamatan($request->kecamatan);
}
if (isset($request->nama_pelanggan)) {
$datas->cari($request->nama_pelanggan);
$pelanggans->cari($request->nama_pelanggan);
}
$countAll = $pelanggans->count();
$dataKecamatan = Pelanggan::select("kecamatan_pelanggan")->distinct()->get()->sortBy("kecamatan_pelanggan");
if ($request->order) {
$order = $request->order;
if ($order == "nama") {
$datas->orderBy("nama_pelanggan", $sorting_order);
} else if ($order == "telp") {
$datas->orderBy("telp_pelanggan", $sorting_order);
} else if ($order == "alamat") {
$datas->orderBy("alamat_pelanggan", $sorting_order);
} else if ($order == "kecamatan") {
$datas->orderBy("kecamatan_pelanggan", $sorting_order);
} else if ($order == "nominal") {
$datas->orderBy("total_nominal", $sorting_order);
} else if ($order == "waktu") {
$datas->orderBy("created_at", $sorting_order);
} else if ($order == "total") {
$datas->orderBy("jumlah_transaksi", $sorting_order);
} else if ($order == "skor_loyalitas") {
$datas->orderBy("skor_loyalitas", $sorting_order);
} else if ($order == "times_diff") {
$datas->orderBy("times_diff", $sorting_order);
} else if ($order == "total_review") {
$datas->orderBy("total_review", $sorting_order);
} else if ($order == "jumlah_referral") {
$datas->orderBy("jumlah_referral", $sorting_order);
}
} else {
$datas->orderBy("jumlah_transaksi", $sorting_order);
}
if (isset($request->nama_pelanggan)) {
$datas = $datas->cari($request->nama_pelanggan);
}
// dd($datas->get(), $begin, $end);
$datas = $datas->paginate(15);
$promos = RewardPromo::where('otomatis',0)->get();
return response()->view("pelanggan-aktif.index", compact("request", "datas", "sorting_order", "dataKecamatan", "begin", "end", "countAll", "periode","promos","jumlahBaru","jumlahPasif","jumlahPotensiLoyal","jumlahLoyalAktif","jumlahLoyalAktif","jumlahSuperLoyal"));
}
public function kirimAction($id,$action_id){
$data = Pelanggan::findOrFail($id);
$promo = RewardPromo::findOrFail($action_id);
try {
$isi_pesan = $promo->isi;
if($data->telp_pelanggan != null && $data->telp_pelanggan != ""){
Helper::sendWa($data->telp_pelanggan,$isi_pesan);
}
return redirect()->route('pelanggan-aktif.index')->with('success','Berhasil mengirim pesan promo & reward');
} catch (\Throwable $th) {
//throw $th;
Log::error($th);
return redirect()->back()->with('error','Gagal mengirim pesan promo & reward');
}
}
}
Anons79 File Manager Version 1.0, Coded By Anons79
Email: [email protected]