tstat_be/app/Models/ReportsModel.php

782 lines
30 KiB
PHP

<?php
namespace App\Models;
use CodeIgniter\Model;
class ReportsModel extends Model
{
// hardcoded values in sql for testing purposes
public function advancePurchaseReport($fromDate, $toDate): array
{
$fromDate = date("Y-m-d", strtotime($fromDate));
$toDate = date("Y-m-d", strtotime($toDate) );
$sql = "SELECT
m_plan.plan_id,
m_users.employee_code,
CONCAT(m_users.first_name, ' ', m_users.last_name) AS traveller_name,
m_plan.so_number,
m_cost_center.name AS cost_center,
CASE
WHEN m_plan.trip_type = 1 THEN 'domestic'
WHEN m_plan.trip_type = 2 THEN 'international'
ELSE 'unknown'
END AS plan_trip_type,
al.Service,
DATE_FORMAT(m_plan.created_on, '%d-%m-%Y') AS created_on,
DATE_FORMAT(m_plan.created_on, '%H:%i:%s') AS created_time,
DATE_FORMAT(al.FirstTravelDt, '%d-%m-%Y') AS FirstTravelDt,
DATEDIFF(al.FirstTravelDt, m_plan.created_on) AS AdvPurch
FROM
m_plan
JOIN m_users ON m_plan.user_id = m_users.user_id
JOIN m_travel_statuses mts ON m_plan.status = mts.id
JOIN m_cost_center ON m_plan.cost_center_id = m_cost_center.cost_center_id
LEFT JOIN (
SELECT
plan_id,Service,
MIN(dt) AS FirstTravelDt
FROM (
SELECT 'Air' AS Service,bb.plan_id, MIN(b.date) AS dt
FROM cc_flight_trips b
JOIN c_flight bb ON b.flight_id = bb.flight_id
GROUP BY bb.plan_id
UNION
SELECT 'Hotel' AS Service,c.plan_id, MIN(c.checkin_date)
FROM c_accomodation c
GROUP BY c.plan_id
UNION
SELECT 'Bus' AS Service,d.plan_id, MIN(d.date)
FROM c_bus d
GROUP BY d.plan_id
UNION
SELECT 'Train' AS Service,e.plan_id, MIN(e.date)
FROM c_train e
GROUP BY e.plan_id
UNION
SELECT 'Forex' AS Service,f.plan_id, MIN(f.start_date)
FROM c_forex f
GROUP BY f.plan_id
) AS unioned_travel
GROUP BY plan_id
) AS al ON m_plan.plan_id = al.plan_id
WHERE
mts.is_active = 1
AND mts.status_value = 'Approved'
AND m_plan.is_active = 1
AND DATE(m_plan.created_on) >= ?
AND DATE(m_plan.created_on) <= ?
;
";
$binds = [$fromDate, $toDate ];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result;
}
public function misServicesAnalysis($fromDate, $toDate)
{
$fromDate = date("Y-m-d", strtotime($fromDate));
$toDate = date("Y-m-d", strtotime($toDate));
$mergedResults = [];
for ($serviceId = 1; $serviceId <= 9; $serviceId++) {
// Determine service table based on serviceId
switch ($serviceId) {
case 1: $serviceTable = 'c_flight'; break;
case 2: $serviceTable = 'c_train'; break;
case 3: $serviceTable = 'c_bus'; break;
case 4: $serviceTable = 'c_taxi'; break;
case 5: $serviceTable = 'c_accomodation'; break;
case 6: $serviceTable = 'c_forex'; break;
case 7: $serviceTable = 'c_insurance'; break;
case 8: $serviceTable = 'c_visa'; break;
case 9: $serviceTable = 'c_miscellaneous'; break;
default: $serviceTable = 'c_flight'; break;
}
// Alias for the dynamic table to prevent ambiguous column references
$serviceAlias = preg_replace('/^c_/', '', $serviceTable);
$sql = "SELECT
'{$serviceAlias}' As 'Service',
COUNT(*) AS service_count,
CASE
WHEN m_plan.trip_type = 1 THEN 'domestic'
WHEN m_plan.trip_type = 2 THEN 'international'
ELSE 'unknown'
END AS plan_trip_type
FROM
{$serviceTable} AS {$serviceAlias}
JOIN m_plan ON m_plan.plan_id = {$serviceAlias}.plan_id
JOIN m_travel_statuses mts ON m_plan.status = mts.id
WHERE
mts.is_active = 1
AND mts.status_value = 'Approved'
AND m_plan.is_active = 1
AND DATE(m_plan.created_on) >= ?
AND DATE(m_plan.created_on) <= ?
GROUP BY
m_plan.trip_type
";
$binds = [$fromDate, $toDate];
$result = $this->db->query($sql, $binds)->getResultArray();
$mergedResults [] = $result;
}
return $mergedResults;
}
public function misAirReport($fromDate, $toDate)
{
$fromDate = date("Y-m-d", strtotime($fromDate));
$toDate = date("Y-m-d", strtotime($toDate));
$sql = "SELECT
m_plan.plan_id,
m_users.employee_code,
Concat(m_users.first_name,' ',m_users.last_name) As customer_name,
m_plan.so_number,
m_cost_center.name AS cost_center,
c_flight.trip_type AS flight_trip_type,
CASE
WHEN m_plan.trip_type = 1 THEN 'domestic'
WHEN m_plan.trip_type = 2 THEN 'international'
ELSE 'unknown'
END AS plan_trip_type,
-- CONCAT_WS(' - ',
-- -- CONCAT(acsf.Airport, ' (', acsf.City, ')'),
-- -- CONCAT(acst.Airport, ' (', acst.City, ')')
-- CONCAT(acsf.Code, ' - ', acst.Code)
-- ) AS sector,
-- m_dropdown.dropdown_value as flight_class,
-- DATE_FORMAT(cc_flight_trips.date, '%d-%m-%Y') AS flight_travel_date
GROUP_CONCAT(CONCAT(acsf.Code, '-', acst.Code) SEPARATOR ' / ') AS sector,
GROUP_CONCAT(m_dropdown.dropdown_value SEPARATOR ' / ') AS flight_class,
GROUP_CONCAT(DATE_FORMAT(cc_flight_trips.date, '%d-%m-%Y') SEPARATOR ' / ') AS flight_travel_date
FROM
m_plan
JOIN m_users ON m_plan.user_id = m_users.user_id
JOIN m_travel_statuses mts ON m_plan.status = mts.id
JOIN m_cost_center ON m_plan.cost_center_id = m_cost_center.cost_center_id
JOIN c_flight ON m_plan.plan_id = c_flight.plan_id
JOIN cc_flight_trips ON cc_flight_trips.flight_id = c_flight.flight_id
JOIN m_dropdown ON m_dropdown.dropdown_key = cc_flight_trips.class and m_dropdown.dropdown = 'flight_class'
JOIN Airport_Code_State acsf ON cc_flight_trips.from_place = acsf.Code
JOIN Airport_Code_State acst ON cc_flight_trips.to_place = acst.Code
WHERE
mts.is_active = 1
AND mts.status_value = 'Approved'
AND m_plan.is_active = 1
AND DATE(m_plan.created_on) >= ?
AND DATE(m_plan.created_on) <= ?
GROUP BY
m_plan.plan_id,
c_flight.trip_type,
m_plan.trip_type;
";
$binds = [$fromDate, $toDate];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result;
}
public function misHotelReport($fromDate, $toDate)
{
$fromDate = date("Y-m-d", strtotime($fromDate));
$toDate = date("Y-m-d", strtotime($toDate));
$sql = "SELECT
m_plan.plan_id,
m_users.employee_code,
Concat(m_users.first_name,' ',m_users.last_name) As employee_name,
m_plan.so_number,
m_cost_center.name AS cost_center,
CASE
WHEN m_plan.trip_type = 1 THEN 'domestic'
WHEN m_plan.trip_type = 2 THEN 'international'
ELSE 'unknown'
END AS plan_trip_type,
c_accomodation.hotel_name AS hotel_name,
DATE_FORMAT(c_accomodation.checkin_date, '%d-%m-%Y') check_in_date,
DATE_FORMAT(c_accomodation.checkout_date, '%d-%m-%Y') check_out_date,
c_accomodation.destination_city AS hotel_city
FROM
m_plan
JOIN m_users ON m_plan.user_id = m_users.user_id
JOIN m_travel_statuses mts ON m_plan.status = mts.id
JOIN m_cost_center ON m_plan.cost_center_id = m_cost_center.cost_center_id
JOIN c_accomodation ON m_plan.plan_id = c_accomodation.plan_id
WHERE
mts.is_active = 1
AND mts.status_value = 'Approved'
AND m_plan.is_active = 1
AND DATE(m_plan.created_on) >= ?
AND DATE(m_plan.created_on) <= ?
;
";
$binds = [$fromDate, $toDate];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result;
}
public function misForexReport($fromDate, $toDate)
{
$fromDate = date("Y-m-d", strtotime($fromDate));
$toDate = date("Y-m-d", strtotime($toDate));
$sql = "SELECT
m_plan.plan_id,
m_users.employee_code,
Concat(m_users.first_name,' ',m_users.last_name) As passenger_name,
m_plan.so_number,
m_cost_center.name AS cost_center,
m_country.country_name As visiting_country,
DATE_FORMAT(c_forex.start_date, '%d-%m-%Y') As forex_from_date,
DATE_FORMAT(c_forex.end_date, '%d-%m-%Y') As forex_to_date,
(
c_forex.perdiem_amount +
c_forex.transport +
c_forex.telephone +
c_forex.accommodation
) As amount
FROM
m_plan
JOIN m_users ON m_plan.user_id = m_users.user_id
JOIN m_travel_statuses mts ON m_plan.status = mts.id
JOIN m_cost_center ON m_plan.cost_center_id = m_cost_center.cost_center_id
JOIN c_forex ON m_plan.plan_id = c_forex.plan_id
JOIN m_country ON c_forex.country_code = m_country.country_code
WHERE
mts.is_active = 1
AND mts.status_value = 'Approved'
AND m_plan.is_active = 1
AND DATE(m_plan.created_on) >= ?
AND DATE(m_plan.created_on) <= ?
;
";
$binds = [$fromDate, $toDate];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result;
}
public function guestHouseReport($fromDate, $toDate)
{
$fromDate = date("Y-m-d", strtotime($fromDate));
$toDate = date("Y-m-d", strtotime($toDate));
$sql = "SELECT
m_plan.plan_id,
m_users.employee_code,
Concat(m_users.first_name,' ',m_users.last_name) As customer_name,
m_plan.so_number,
m_cost_center.name AS cost_center,
c_flight.trip_type AS flight_trip_type,
CASE
WHEN m_plan.trip_type = 1 THEN 'domestic'
WHEN m_plan.trip_type = 2 THEN 'international'
ELSE 'unknown'
END AS plan_trip_type,
CONCAT_WS(' - ',
CONCAT(acsf.Airport, ' (', acsf.City, ')'),
CONCAT(acst.Airport, ' (', acst.City, ')')
) AS sector,
m_dropdown.dropdown_value as flight_class,
cc_flight_trips.date AS flight_travel_date
FROM
m_plan
JOIN m_users ON m_plan.user_id = m_users.user_id
JOIN m_travel_statuses mts ON m_plan.status = mts.id
JOIN m_cost_center ON m_plan.cost_center_id = m_cost_center.cost_center_id
JOIN c_flight ON m_plan.plan_id = c_flight.plan_id
JOIN cc_flight_trips ON cc_flight_trips.flight_id = c_flight.flight_id
JOIN m_dropdown ON m_dropdown.dropdown_key = cc_flight_trips.class and m_dropdown.dropdown = 'flight_class'
JOIN Airport_Code_State acsf ON cc_flight_trips.from_place = acsf.Code
JOIN Airport_Code_State acst ON cc_flight_trips.to_place = acst.Code
WHERE
mts.is_active = 1
AND mts.status_value = 'Approved'
AND m_plan.is_active = 1
AND DATE(m_plan.created_on) >= ?
AND DATE(m_plan.created_on) <= ?
;
";
$binds = [$fromDate, $toDate];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result;
}
public function flightServiceDashboardWeekly(){
$sql = "SELECT
COALESCE(t.count, 0) AS count,
s.trip_type,
s.status_label AS Status
FROM (
SELECT trip_type, status_label
FROM (
SELECT 'International' AS trip_type
UNION
SELECT 'Domestic'
) trip_types
CROSS JOIN (
SELECT 'Pending Approval' AS status_label
UNION SELECT 'Partially Approved'
UNION SELECT 'Approved'
UNION SELECT 'Rejected'
UNION SELECT 'Cancelled'
) statuses
) s
-- Step 2: Left join real data
LEFT JOIN (
SELECT
COUNT(cf.flight_id) as count,
case
when mp.trip_type = 1 then 'Domestic'
when mp.trip_type = 2 then 'International'
END AS trip_type ,
case
when mp.status = 1 then 'Pending Approval'
when mp.status = 2 then 'Partially Approved'
when mp.status = 3 then 'Approved'
when mp.status = 4 then 'Rejected'
when mp.status = 7 then 'Cancelled'
END AS Status
FROM c_flight cf
JOIN m_plan mp ON cf.plan_id = mp.plan_id
WHERE cf.created_on >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
AND cf.created_on < DATE_ADD(CURDATE(), INTERVAL 1 DAY)
-- WHERE cf.created_on >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
-- AND cf.created_on < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
-- previous week
-- WHERE cf.created_on >= DATE_SUB(CURDATE(), INTERVAL (WEEKDAY(CURDATE()) + 7) DAY)
-- AND cf.created_on < DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY);
AND mp.is_active = 1
GROUP BY mp.status,mp.trip_type
) t ON s.trip_type = t.trip_type AND s.status_label = t.Status
";
$binds = [];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result ;
}
public function accomodationServiceDashboardWeekly(){
$sql = "SELECT
COALESCE(t.count, 0) AS count,
s.trip_type,
s.status_label AS Status
FROM (
SELECT trip_type, status_label
FROM (
SELECT 'International' AS trip_type
UNION ALL
SELECT 'Domestic'
) trip_types
CROSS JOIN (
SELECT 'Pending Approval' AS status_label
UNION ALL SELECT 'Partially Approved'
UNION ALL SELECT 'Approved'
UNION ALL SELECT 'Rejected'
UNION ALL SELECT 'Cancelled'
) statuses
) s
-- Step 2: Left join real data
LEFT JOIN (
SELECT
COUNT(ca.accomodation_id) as count,
case
when mp.trip_type = 1 then 'Domestic'
when mp.trip_type = 2 then 'International'
END AS trip_type ,
case
when mp.status = 1 then 'Pending Approval'
when mp.status = 2 then 'Partially Approved'
when mp.status = 3 then 'Approved'
when mp.status = 4 then 'Rejected'
when mp.status = 7 then 'Cancelled'
END AS Status
FROM c_accomodation ca
JOIN m_plan mp ON ca.plan_id = mp.plan_id
WHERE ca.created_on >= DATE_SUB(CURDATE(), INTERVAL 6 DAY)
AND ca.created_on < DATE_ADD(CURDATE(), INTERVAL 1 DAY)
-- WHERE ca.created_on >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
-- AND ca.created_on < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
-- previous week
-- WHERE cf.created_on >= DATE_SUB(CURDATE(), INTERVAL (WEEKDAY(CURDATE()) + 7) DAY)
-- AND cf.created_on < DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY);
AND mp.is_active = 1
GROUP BY mp.status,mp.trip_type
) t ON s.trip_type = t.trip_type AND s.status_label = t.Status
";
$binds = [];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result ;
}
public function forexServiceDashboardWeekly(){
$sql = "SELECT
COALESCE(t.count, 0) AS count,
s.trip_type,
s.status_label AS Status
FROM (
SELECT trip_type, status_label
FROM (
SELECT 'International' AS trip_type
UNION ALL
SELECT 'Domestic'
) trip_types
CROSS JOIN (
SELECT 'Pending Approval' AS status_label
UNION ALL SELECT 'Partially Approved'
UNION ALL SELECT 'Approved'
UNION ALL SELECT 'Rejected'
UNION ALL SELECT 'Cancelled'
) statuses
) s
-- Step 2: Left join real data
LEFT JOIN (
SELECT
COUNT(cf.forex_id) as count,
case
when mp.trip_type = 1 then 'Domestic'
when mp.trip_type = 2 then 'International'
END AS trip_type ,
case
when mp.status = 1 then 'Pending Approval'
when mp.status = 2 then 'Partially Approved'
when mp.status = 3 then 'Approved'
when mp.status = 4 then 'Rejected'
when mp.status = 7 then 'Cancelled'
END AS Status
FROM c_forex cf
JOIN m_plan mp ON cf.plan_id = mp.plan_id
WHERE cf.created_on >= DATE_SUB(CURDATE(), INTERVAL 6 DAY)
AND cf.created_on < DATE_ADD(CURDATE(), INTERVAL 1 DAY)
-- WHERE cf.created_on >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
-- AND cf.created_on < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
-- previous week
-- WHERE cf.created_on >= DATE_SUB(CURDATE(), INTERVAL (WEEKDAY(CURDATE()) + 7) DAY)
-- AND cf.created_on < DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY);
AND mp.is_active = 1
GROUP BY mp.status,mp.trip_type
) t ON s.trip_type = t.trip_type AND s.status_label = t.Status
";
$binds = [];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result ;
}
public function flightServiceDashboardDaily(){
$sql = "SELECT
COALESCE(t.count, 0) AS count,
s.trip_type,
s.status_label AS Status
FROM (
SELECT trip_type, status_label
FROM (
SELECT 'International' AS trip_type
UNION ALL
SELECT 'Domestic'
) trip_types
CROSS JOIN (
SELECT 'Pending Approval' AS status_label
UNION ALL SELECT 'Partially Approved'
UNION ALL SELECT 'Approved'
UNION ALL SELECT 'Rejected'
UNION ALL SELECT 'Cancelled'
) statuses
) s
-- Step 2: Left join real data
LEFT JOIN (
SELECT
COUNT(cf.flight_id) as count,
case
when mp.trip_type = 1 then 'Domestic'
when mp.trip_type = 2 then 'International'
END AS trip_type ,
case
when mp.status = 1 then 'Pending Approval'
when mp.status = 2 then 'Partially Approved'
when mp.status = 3 then 'Approved'
when mp.status = 4 then 'Rejected'
when mp.status = 7 then 'Cancelled'
END AS Status
FROM c_flight cf
JOIN m_plan mp ON cf.plan_id = mp.plan_id
WHERE DATE(cf.created_on) = CURDATE()
AND mp.is_active = 1
GROUP BY mp.status,mp.trip_type
) t ON s.trip_type = t.trip_type AND s.status_label = t.Status
";
$binds = [];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result ;
}
public function accomodationServiceDashboardDaily(){
$sql = "SELECT
COALESCE(t.count, 0) AS count,
s.trip_type,
s.status_label AS Status
FROM (
SELECT trip_type, status_label
FROM (
SELECT 'International' AS trip_type
UNION ALL
SELECT 'Domestic'
) trip_types
CROSS JOIN (
SELECT 'Pending Approval' AS status_label
UNION ALL SELECT 'Partially Approved'
UNION ALL SELECT 'Approved'
UNION ALL SELECT 'Rejected'
UNION ALL SELECT 'Cancelled'
) statuses
) s
-- Step 2: Left join real data
LEFT JOIN (
SELECT
COUNT(ca.accomodation_id) as count,
case
when mp.trip_type = 1 then 'Domestic'
when mp.trip_type = 2 then 'International'
END AS trip_type ,
case
when mp.status = 1 then 'Pending Approval'
when mp.status = 2 then 'Partially Approved'
when mp.status = 3 then 'Approved'
when mp.status = 4 then 'Rejected'
when mp.status = 7 then 'Cancelled'
END AS Status
FROM c_accomodation ca
JOIN m_plan mp ON ca.plan_id = mp.plan_id
WHERE DATE(ca.created_on) = CURDATE()
AND mp.is_active = 1
GROUP BY mp.status,mp.trip_type
) t ON s.trip_type = t.trip_type AND s.status_label = t.Status
";
$binds = [];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result ;
}
public function forexServiceDashboardDaily(){
$sql = "SELECT
COALESCE(t.count, 0) AS count,
s.trip_type,
s.status_label AS Status
FROM (
SELECT trip_type, status_label
FROM (
SELECT 'International' AS trip_type
UNION ALL
SELECT 'Domestic'
) trip_types
CROSS JOIN (
SELECT 'Pending Approval' AS status_label
UNION ALL SELECT 'Partially Approved'
UNION ALL SELECT 'Approved'
UNION ALL SELECT 'Rejected'
UNION ALL SELECT 'Cancelled'
) statuses
) s
-- Step 2: Left join real data
LEFT JOIN (
SELECT
COUNT(cf.forex_id) as count,
case
when mp.trip_type = 1 then 'Domestic'
when mp.trip_type = 2 then 'International'
END AS trip_type ,
case
when mp.status = 1 then 'Pending Approval'
when mp.status = 2 then 'Partially Approved'
when mp.status = 3 then 'Approved'
when mp.status = 4 then 'Rejected'
when mp.status = 7 then 'Cancelled'
END AS Status
FROM c_forex cf
JOIN m_plan mp ON cf.plan_id = mp.plan_id
WHERE DATE(cf.created_on) = CURDATE()
AND mp.is_active = 1
GROUP BY mp.status,mp.trip_type
) t ON s.trip_type = t.trip_type AND s.status_label = t.Status
";
$binds = [];
$result = $this->db->query($sql,$binds)->getResultArray();
return $result ;
}
}