initial project
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\Backend;
|
||||
|
||||
use CodeIgniter\RESTful\ResourceController;
|
||||
use App\Models\Orders;
|
||||
use App\Models\TopupModel;
|
||||
use App\Models\CustomerWallet;
|
||||
use App\Models\CustomerVoucherList;
|
||||
use App\Models\CustomerPoint;
|
||||
use App\Models\LogCustomerCheckin; // Add LogCustomerCheckin model
|
||||
|
||||
class CustomerDashboardController extends ResourceController
|
||||
{
|
||||
private $orders;
|
||||
private $topups;
|
||||
private $wallets;
|
||||
private $vouchers;
|
||||
private $points;
|
||||
private $checkins; // Add checkins model
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->orders = new Orders();
|
||||
$this->topups = new TopupModel();
|
||||
$this->wallets = new CustomerWallet();
|
||||
$this->vouchers = new CustomerVoucherList();
|
||||
$this->points = new CustomerPoint();
|
||||
$this->checkins = new LogCustomerCheckin(); // Initialize checkins model
|
||||
}
|
||||
|
||||
public function show($customerId = null)
|
||||
{
|
||||
if (!$customerId) {
|
||||
return $this->fail('Customer ID is required', 400);
|
||||
}
|
||||
|
||||
$orderSummary = $this->orders
|
||||
->select('customer_id, COUNT(id) as total_orders, SUM(grand_total) as total_grand')
|
||||
->where('customer_id', $customerId)
|
||||
->groupBy('customer_id')
|
||||
->first();
|
||||
|
||||
$topupSummary = $this->topups
|
||||
->select('customer_id, COUNT(id) as total_topups, SUM(amount) as total_topup_amount')
|
||||
->where('customer_id', $customerId)
|
||||
->groupBy('customer_id')
|
||||
->first();
|
||||
|
||||
$pointsSummary = $this->points
|
||||
->select('customer_id,
|
||||
COUNT(id) as total_point_transactions,
|
||||
SUM(`in`) as total_point_in,
|
||||
SUM(`out`) as total_point_out,
|
||||
MAX(balance) as current_points')
|
||||
->where('customer_id', $customerId)
|
||||
->groupBy('customer_id')
|
||||
->first();
|
||||
|
||||
$walletSummary = $this->wallets
|
||||
->select('customer_id, SUM(`in`) as total_in, SUM(`out`) as total_out, MAX(balance) as current_balance')
|
||||
->where('customer_id', $customerId)
|
||||
->groupBy('customer_id')
|
||||
->first();
|
||||
|
||||
$voucherSummary = $this->vouchers
|
||||
->select('customer_id,
|
||||
COUNT(id) as total_vouchers,
|
||||
SUM(CASE WHEN voucher_status = "active" THEN 1 ELSE 0 END) as active_vouchers,
|
||||
SUM(CASE WHEN voucher_status = "used" THEN 1 ELSE 0 END) as used_vouchers,
|
||||
SUM(CASE WHEN voucher_status = "expired" THEN 1 ELSE 0 END) as expired_vouchers')
|
||||
->where('customer_id', $customerId)
|
||||
->groupBy('customer_id')
|
||||
->first();
|
||||
|
||||
$activeVouchers = $this->vouchers
|
||||
->where('customer_id', $customerId)
|
||||
->where('voucher_status', 'active')
|
||||
->where('voucher_expiry_date >=', date('Y-m-d H:i:s'))
|
||||
->orderBy('voucher_expiry_date', 'ASC')
|
||||
->findAll();
|
||||
|
||||
// Get check-in data
|
||||
$checkinData = $this->checkins
|
||||
->select('customer_id,
|
||||
COUNT(id) as total_checkins,
|
||||
MAX(streak_count) as highest_streak,
|
||||
MAX(checkin_date) as last_checkin_date')
|
||||
->where('customer_id', $customerId)
|
||||
->groupBy('customer_id')
|
||||
->first();
|
||||
|
||||
$recentCheckins = $this->checkins
|
||||
->where('customer_id', $customerId)
|
||||
->orderBy('checkin_date', 'DESC')
|
||||
->limit(7) // Get last 7 check-ins
|
||||
->findAll();
|
||||
|
||||
$orderLifecycle = $this->orders
|
||||
->select('MIN(created_at) as first_order_date, MAX(created_at) as last_order_date')
|
||||
->where('customer_id', $customerId)
|
||||
->where('status !=', 'cancelled')
|
||||
->first();
|
||||
|
||||
$topupLifecycle = $this->topups
|
||||
->select('MIN(created_at) as first_topup_date, MAX(created_at) as last_topup_date')
|
||||
->where('customer_id', $customerId)
|
||||
->where('status', 'success')
|
||||
->first();
|
||||
|
||||
$pointsLifecycle = $this->points
|
||||
->select('MIN(created_at) as first_point_date, MAX(created_at) as last_point_date')
|
||||
->where('customer_id', $customerId)
|
||||
->first();
|
||||
|
||||
// Get check-in lifecycle
|
||||
$checkinLifecycle = $this->checkins
|
||||
->select('MIN(checkin_date) as first_checkin_date, MAX(checkin_date) as last_checkin_date')
|
||||
->where('customer_id', $customerId)
|
||||
->first();
|
||||
|
||||
$customerStatus = $this->calculateCustomerStatus($orderLifecycle, $topupLifecycle, $pointsLifecycle, $checkinLifecycle);
|
||||
|
||||
$lifecycleData = [
|
||||
'first_activity' => $this->getEarliestDate([
|
||||
$orderLifecycle['first_order_date'] ?? null,
|
||||
$topupLifecycle['first_topup_date'] ?? null,
|
||||
$pointsLifecycle['first_point_date'] ?? null,
|
||||
$checkinLifecycle['first_checkin_date'] ?? null
|
||||
]),
|
||||
'last_activity' => $this->getLatestDate([
|
||||
$orderLifecycle['last_order_date'] ?? null,
|
||||
$topupLifecycle['last_topup_date'] ?? null,
|
||||
$pointsLifecycle['last_point_date'] ?? null,
|
||||
$checkinLifecycle['last_checkin_date'] ?? null
|
||||
]),
|
||||
'first_order' => $orderLifecycle['first_order_date'] ?? null,
|
||||
'last_order' => $orderLifecycle['last_order_date'] ?? null,
|
||||
'first_topup' => $topupLifecycle['first_topup_date'] ?? null,
|
||||
'last_topup' => $topupLifecycle['last_topup_date'] ?? null,
|
||||
'first_point' => $pointsLifecycle['first_point_date'] ?? null,
|
||||
'last_point' => $pointsLifecycle['last_point_date'] ?? null,
|
||||
'first_checkin' => $checkinLifecycle['first_checkin_date'] ?? null,
|
||||
'last_checkin' => $checkinLifecycle['last_checkin_date'] ?? null,
|
||||
'customer_status' => $customerStatus,
|
||||
'days_since_last_activity' => $this->calculateDaysSinceLastActivity(
|
||||
$orderLifecycle['last_order_date'] ?? null,
|
||||
$topupLifecycle['last_topup_date'] ?? null,
|
||||
$pointsLifecycle['last_point_date'] ?? null,
|
||||
$checkinLifecycle['last_checkin_date'] ?? null
|
||||
)
|
||||
];
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Customer dashboard data retrieved successfully',
|
||||
'data' => [
|
||||
'orders' => $orderSummary ?? [
|
||||
'customer_id' => $customerId,
|
||||
'total_orders' => 0,
|
||||
'total_grand' => 0
|
||||
],
|
||||
'topups' => $topupSummary ?? [
|
||||
'customer_id' => $customerId,
|
||||
'total_topups' => 0,
|
||||
'total_topup_amount' => 0
|
||||
],
|
||||
'points' => $pointsSummary ?? [
|
||||
'customer_id' => $customerId,
|
||||
'total_point_transactions' => 0,
|
||||
'total_point_in' => 0,
|
||||
'total_point_out' => 0,
|
||||
'current_points' => 0
|
||||
],
|
||||
'wallet' => $walletSummary ?? [
|
||||
'customer_id' => $customerId,
|
||||
'total_in' => 0,
|
||||
'total_out' => 0,
|
||||
'current_balance' => 0
|
||||
],
|
||||
'vouchers' => [
|
||||
'summary' => $voucherSummary ?? [
|
||||
'customer_id' => $customerId,
|
||||
'total_vouchers' => 0,
|
||||
'active_vouchers' => 0,
|
||||
'used_vouchers' => 0,
|
||||
'expired_vouchers' => 0
|
||||
],
|
||||
'active_vouchers_list' => $activeVouchers
|
||||
],
|
||||
'checkins' => [ // Added checkins section
|
||||
'summary' => $checkinData ?? [
|
||||
'customer_id' => $customerId,
|
||||
'total_checkins' => 0,
|
||||
'highest_streak' => 0,
|
||||
'last_checkin_date' => null
|
||||
],
|
||||
'recent_checkins' => $recentCheckins
|
||||
],
|
||||
'lifecycle' => $lifecycleData
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
private function calculateCustomerStatus($orderLifecycle, $topupLifecycle, $pointsLifecycle, $checkinLifecycle)
|
||||
{
|
||||
$lastOrderDate = $orderLifecycle['last_order_date'] ?? null;
|
||||
$lastTopupDate = $topupLifecycle['last_topup_date'] ?? null;
|
||||
$lastPointDate = $pointsLifecycle['last_point_date'] ?? null;
|
||||
$lastCheckinDate = $checkinLifecycle['last_checkin_date'] ?? null;
|
||||
|
||||
$lastActivity = $this->getLatestDate([$lastOrderDate, $lastTopupDate, $lastPointDate, $lastCheckinDate]);
|
||||
|
||||
if (!$lastActivity) {
|
||||
return 'new';
|
||||
}
|
||||
|
||||
$daysInactive = $this->calculateDaysSince($lastActivity);
|
||||
|
||||
if ($daysInactive <= 30) {
|
||||
return 'active';
|
||||
} elseif ($daysInactive <= 90) {
|
||||
return 'dormant';
|
||||
} else {
|
||||
return 'churned';
|
||||
}
|
||||
}
|
||||
|
||||
private function calculateDaysSinceLastActivity($lastOrderDate, $lastTopupDate, $lastPointDate, $lastCheckinDate)
|
||||
{
|
||||
$lastActivity = $this->getLatestDate([$lastOrderDate, $lastTopupDate, $lastPointDate, $lastCheckinDate]);
|
||||
|
||||
if (!$lastActivity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->calculateDaysSince($lastActivity);
|
||||
}
|
||||
|
||||
private function calculateDaysSince($dateString)
|
||||
{
|
||||
if (!$dateString) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$date = new \DateTime($dateString);
|
||||
$now = new \DateTime();
|
||||
$interval = $now->diff($date);
|
||||
|
||||
return $interval->days;
|
||||
}
|
||||
|
||||
private function getEarliestDate(array $dates)
|
||||
{
|
||||
$validDates = array_filter($dates);
|
||||
if (empty($validDates)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
sort($validDates);
|
||||
return $validDates[0];
|
||||
}
|
||||
|
||||
private function getLatestDate(array $dates)
|
||||
{
|
||||
$validDates = array_filter($dates);
|
||||
if (empty($validDates)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
rsort($validDates);
|
||||
return $validDates[0];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user