FIX_dashboard api
This commit is contained in:
parent
994b0fdbfb
commit
80afc350eb
@ -1221,24 +1221,57 @@ public function partnerDetails($id)
|
||||
throw new \RuntimeException('Partner not found.', 404);
|
||||
}
|
||||
|
||||
// -- 2. Policy counts + premium + commission
|
||||
// mapped_policies = ALL policies under this agent (226)
|
||||
// issued_policies = policy_number IS NOT NULL AND is_active = 1 (217)
|
||||
// pending_policies = policy_number IS NULL (9 — raised but not yet issued)
|
||||
// total_premium / commission = from issued policies only
|
||||
// -- 2. Overview = current Indian financial year (Apr–Mar, Asia/Kolkata)
|
||||
$fy = $this->indianFinancialYearBounds(null);
|
||||
$fyStart = $fy['start'];
|
||||
$fyEnd = $fy['end'];
|
||||
$overviewFy = $fy['label'];
|
||||
|
||||
$policyStats = $this->db->table('partner_policy pp')
|
||||
->select('
|
||||
COUNT(pp.id) AS mapped_policies,
|
||||
SUM(CASE WHEN pp.policy_number IS NOT NULL AND pp.is_active = 1 AND pp.premium_amount IS NOT NULL THEN 1 ELSE 0 END) AS issued_policies,
|
||||
SUM(CASE WHEN pp.policy_number IS NULL THEN 1 ELSE 0 END) AS pending_policies,
|
||||
COALESCE(SUM(CASE WHEN pp.policy_number IS NOT NULL THEN pp.premium_amount ELSE 0 END), 0) AS total_premium,
|
||||
COALESCE(SUM(CASE WHEN pp.policy_number IS NOT NULL THEN pp.premium_amount * 0.15 ELSE 0 END), 0) AS commission_earned
|
||||
')
|
||||
->select("
|
||||
SUM(CASE WHEN pp.policy_number IS NOT NULL AND pp.issued_date >= '{$fyStart}' AND pp.issued_date <= '{$fyEnd}' THEN 1 ELSE 0 END) AS issued_policies,
|
||||
SUM(CASE WHEN pp.policy_number IS NULL AND DATE(pp.created_on) >= '{$fyStart}' AND DATE(pp.created_on) <= '{$fyEnd}' THEN 1 ELSE 0 END) AS pending_policies,
|
||||
COALESCE(SUM(CASE WHEN pp.policy_number IS NOT NULL AND pp.issued_date >= '{$fyStart}' AND pp.issued_date <= '{$fyEnd}' THEN pp.premium_amount ELSE 0 END), 0) AS total_premium,
|
||||
COALESCE(SUM(CASE WHEN pp.policy_number IS NOT NULL AND pp.issued_date >= '{$fyStart}' AND pp.issued_date <= '{$fyEnd}' THEN COALESCE(pp.commission_amount, 0) ELSE 0 END), 0) AS commission_earned
|
||||
", false)
|
||||
->where('pp.agent_id', $id)
|
||||
->get()->getRowArray();
|
||||
|
||||
// ── 3. Enquiry counts
|
||||
// enquiry_status enum: To be assigned | Assigned | In progress | Completed
|
||||
$policyStats['mapped_policies'] = (int) ($policyStats['issued_policies'] ?? 0) + (int) ($policyStats['pending_policies'] ?? 0);
|
||||
|
||||
$agentId = (int) $id;
|
||||
|
||||
$paidRow = $this->db->table('partner_invoice_items pii')
|
||||
->select('COALESCE(SUM(COALESCE(pii.commission_amount, 0)), 0) AS commission_paid', false)
|
||||
->join('partner_policy pp', 'pp.id = pii.policy_id', 'inner')
|
||||
->join('partner_invoice pi', 'pi.id = pii.invoice_id AND pi.is_active = 1', 'inner')
|
||||
->where('pp.agent_id', $agentId)
|
||||
->where('pii.is_active', 1)
|
||||
->where('pp.is_active', 1)
|
||||
->where('pp.policy_number IS NOT NULL')
|
||||
->where('pp.issued_date >=', $fyStart)
|
||||
->where('pp.issued_date <=', $fyEnd)
|
||||
->where(
|
||||
'JSON_SEARCH(pi.agent_id, \'one\', CAST(' . $agentId . ' AS CHAR)) IS NOT NULL',
|
||||
null,
|
||||
false
|
||||
)
|
||||
->where(
|
||||
'EXISTS (SELECT 1 FROM partner_invoice_utr piu WHERE piu.invoice_id = pi.id AND piu.is_active = 1 AND piu.amount > 0)',
|
||||
null,
|
||||
false
|
||||
)
|
||||
->get()->getRowArray();
|
||||
|
||||
$commissionEarned = (float) ($policyStats['commission_earned'] ?? 0);
|
||||
$commissionPaidRaw = (float) ($paidRow['commission_paid'] ?? 0);
|
||||
$commissionPaid = min($commissionPaidRaw, $commissionEarned);
|
||||
$commissionUnpaid = max(0, $commissionEarned - $commissionPaid);
|
||||
|
||||
$policyStats['commission_paid'] = $commissionPaid;
|
||||
$policyStats['commission_unpaid'] = $commissionUnpaid;
|
||||
|
||||
// ── 3. Enquiry counts (created in current FY)
|
||||
$enquiryStats = $this->db->table('partner_enquiry pe')
|
||||
->select('
|
||||
COUNT(pe.id) AS enquiry_total,
|
||||
@ -1247,10 +1280,11 @@ public function partnerDetails($id)
|
||||
')
|
||||
->where('pe.agent_id', $id)
|
||||
->where('pe.is_active', 1)
|
||||
->where('pe.created_on >=', $fyStart . ' 00:00:00')
|
||||
->where('pe.created_on <=', $fyEnd . ' 23:59:59')
|
||||
->get()->getRowArray();
|
||||
|
||||
// ── 4. Endorsement counts
|
||||
// status is varchar(20) — adjust "Completed" to match your actual values
|
||||
// ── 4. Endorsement counts (created in current FY)
|
||||
$endorseStats = $this->db->table('partner_endorsement_request per')
|
||||
->select('
|
||||
COUNT(per.id) AS endorsement_total,
|
||||
@ -1259,14 +1293,16 @@ public function partnerDetails($id)
|
||||
')
|
||||
->where('per.agent_id', $id)
|
||||
->where('per.is_active', 1)
|
||||
->where('per.created_at >=', $fyStart . ' 00:00:00')
|
||||
->where('per.created_at <=', $fyEnd . ' 23:59:59')
|
||||
->get()->getRowArray();
|
||||
|
||||
// ── Merge everything
|
||||
$data = array_merge(
|
||||
$agent,
|
||||
[
|
||||
'status' => $agent['is_active'] ? 'Active' : 'Inactive',
|
||||
'commission_rate' => 15,
|
||||
'status' => $agent['is_active'] ? 'Active' : 'Inactive',
|
||||
'overview_financial_year' => $overviewFy,
|
||||
],
|
||||
$policyStats ?? [],
|
||||
$enquiryStats ?? [],
|
||||
@ -1490,13 +1526,17 @@ public function partnerRenewals($id)
|
||||
// GET partner/{id}/earnings
|
||||
// partner_policy.agent_id = $id
|
||||
// Groups by issued_date month → month_key (YYYY-MM), month_label (Month YYYY)
|
||||
// paid = MAX(is_data_accuracy_checked) — 1 if all policies in month are checked
|
||||
// No month_key param → returns ALL months (FY filtering done client-side in Dart)
|
||||
// payout = SUM(partner_policy.commission_amount) — total commission for the month
|
||||
// payout_paid = SUM(partner_invoice_items.commission_amount) where policy belongs to agent,
|
||||
// invoice lists this agent in agent_id JSON, and invoice has UTR payment (amount > 0)
|
||||
// payout_unpaid = payout − payout_paid (floored at 0)
|
||||
// FY filter is client-side
|
||||
// ══════════════════════════════════════════════════════════════════════════════
|
||||
public function partnerEarnings($id)
|
||||
{
|
||||
$ref = [];
|
||||
$monthKey = $this->request->getGet('month_key') ?? null;
|
||||
$fyParam = $this->request->getGet('financial_year') ?? null;
|
||||
|
||||
try {
|
||||
if (empty($id)) {
|
||||
@ -1508,6 +1548,13 @@ public function partnerEarnings($id)
|
||||
], 200);
|
||||
}
|
||||
|
||||
$agentId = (int) $id;
|
||||
|
||||
$fyBounds = null;
|
||||
if (!empty($fyParam)) {
|
||||
$fyBounds = $this->indianFinancialYearBounds($fyParam);
|
||||
}
|
||||
|
||||
$builder = $this->db->table('partner_policy pp');
|
||||
|
||||
$builder->select("
|
||||
@ -1515,17 +1562,19 @@ public function partnerEarnings($id)
|
||||
DATE_FORMAT(pp.issued_date, '%M %Y') AS month_label,
|
||||
COUNT(pp.id) AS policies,
|
||||
COALESCE(SUM(pp.premium_amount), 0) AS premium,
|
||||
COALESCE(SUM(pp.premium_amount * 0.15), 0) AS commission,
|
||||
COALESCE(SUM(pp.premium_amount * 0.15 * 0.10), 0) AS tds,
|
||||
COALESCE(SUM(pp.premium_amount * 0.15 * 0.90), 0) AS net_payout,
|
||||
MAX(pp.is_data_accuracy_checked) AS paid
|
||||
COALESCE(SUM(COALESCE(pp.commission_amount, 0)), 0) AS payout
|
||||
");
|
||||
|
||||
$builder->where('pp.agent_id', $id);
|
||||
$builder->where('pp.agent_id', $agentId);
|
||||
$builder->where('pp.is_active', 1);
|
||||
$builder->where('pp.policy_number IS NOT NULL');
|
||||
$builder->where('pp.premium_amount IS NOT NULL');
|
||||
|
||||
if ($fyBounds !== null) {
|
||||
$builder->where('pp.issued_date >=', $fyBounds['start']);
|
||||
$builder->where('pp.issued_date <=', $fyBounds['end']);
|
||||
}
|
||||
|
||||
if (!empty($monthKey)) {
|
||||
$builder->where("DATE_FORMAT(pp.issued_date, '%Y-%m')", $monthKey);
|
||||
}
|
||||
@ -1535,13 +1584,63 @@ public function partnerEarnings($id)
|
||||
|
||||
$results = $builder->get()->getResultArray();
|
||||
|
||||
$ref['month_filter'] = $monthKey ?? 'all';
|
||||
$ref['total_records'] = count($results);
|
||||
// Paid commission: invoice line items tied to this agent’s policies, invoice includes agent, UTR settled
|
||||
$paidBuilder = $this->db->table('partner_invoice_items pii');
|
||||
$paidBuilder->select("
|
||||
DATE_FORMAT(pp.issued_date, '%Y-%m') AS month_key,
|
||||
COALESCE(SUM(COALESCE(pii.commission_amount, 0)), 0) AS payout_paid
|
||||
", false);
|
||||
$paidBuilder->join('partner_policy pp', 'pp.id = pii.policy_id', 'inner');
|
||||
$paidBuilder->join('partner_invoice pi', 'pi.id = pii.invoice_id AND pi.is_active = 1', 'inner');
|
||||
$paidBuilder->where('pp.agent_id', $agentId);
|
||||
$paidBuilder->where('pii.is_active', 1);
|
||||
$paidBuilder->where('pp.is_active', 1);
|
||||
$paidBuilder->where('pp.policy_number IS NOT NULL');
|
||||
$paidBuilder->where('pp.premium_amount IS NOT NULL');
|
||||
$paidBuilder->where(
|
||||
'JSON_SEARCH(pi.agent_id, \'one\', CAST(' . $agentId . ' AS CHAR)) IS NOT NULL',
|
||||
null,
|
||||
false
|
||||
);
|
||||
$paidBuilder->where(
|
||||
'EXISTS (SELECT 1 FROM partner_invoice_utr piu WHERE piu.invoice_id = pi.id AND piu.is_active = 1 AND piu.amount > 0)',
|
||||
null,
|
||||
false
|
||||
);
|
||||
|
||||
if (empty($results)) {
|
||||
throw new \RuntimeException('No earning data found for this partner.', 404);
|
||||
if ($fyBounds !== null) {
|
||||
$paidBuilder->where('pp.issued_date >=', $fyBounds['start']);
|
||||
$paidBuilder->where('pp.issued_date <=', $fyBounds['end']);
|
||||
}
|
||||
|
||||
if (!empty($monthKey)) {
|
||||
$paidBuilder->where("DATE_FORMAT(pp.issued_date, '%Y-%m')", $monthKey);
|
||||
}
|
||||
|
||||
$paidBuilder->groupBy("DATE_FORMAT(pp.issued_date, '%Y-%m')");
|
||||
$paidRows = $paidBuilder->get()->getResultArray();
|
||||
|
||||
$paidMap = [];
|
||||
foreach ($paidRows as $pr) {
|
||||
$paidMap[$pr['month_key']] = (float) $pr['payout_paid'];
|
||||
}
|
||||
|
||||
foreach ($results as &$row) {
|
||||
$mk = $row['month_key'];
|
||||
$payout = (float) $row['payout'];
|
||||
$payoutPaid = min((float) ($paidMap[$mk] ?? 0), $payout);
|
||||
$row['payout'] = $payout;
|
||||
$row['payout_paid'] = $payoutPaid;
|
||||
$row['payout_unpaid'] = max(0, $payout - $payoutPaid);
|
||||
$row['premium'] = (float) $row['premium'];
|
||||
$row['policies'] = (int) $row['policies'];
|
||||
}
|
||||
unset($row);
|
||||
|
||||
$ref['month_filter'] = $monthKey ?? 'all';
|
||||
$ref['financial_year'] = ($fyBounds !== null) ? $fyBounds['label'] : 'all';
|
||||
$ref['total_records'] = count($results);
|
||||
|
||||
return $this->respond([
|
||||
'status' => 'success',
|
||||
'code' => 200,
|
||||
@ -1581,4 +1680,45 @@ public function partnerEarnings($id)
|
||||
], 200);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indian financial year Apr 1 (Y) → Mar 31 (Y+1).
|
||||
*
|
||||
* @param string|null $fyStr e.g. "2025-2026" (first year is the April year)
|
||||
* @return array{start: string, end: string, label: string} Y-m-d bounds + label "2025-2026"
|
||||
*/
|
||||
private function indianFinancialYearBounds(?string $fyStr = null): array
|
||||
{
|
||||
if ($fyStr !== null && preg_match('/^(\d{4})-(\d{4})$/', trim($fyStr), $m)) {
|
||||
$y1 = (int) $m[1];
|
||||
$y2 = (int) $m[2];
|
||||
if ($y2 !== $y1 + 1) {
|
||||
$y1 = $y1 - 1;
|
||||
$y2 = $y1 + 1;
|
||||
}
|
||||
$start = sprintf('%04d-04-01', $y1);
|
||||
$end = sprintf('%04d-03-31', $y2);
|
||||
|
||||
return [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'label' => $y1 . '-' . $y2,
|
||||
];
|
||||
}
|
||||
|
||||
$tz = new \DateTimeZone('Asia/Kolkata');
|
||||
$now = new \DateTime('now', $tz);
|
||||
$y = (int) $now->format('Y');
|
||||
$mo = (int) $now->format('n');
|
||||
$y1 = $mo >= 4 ? $y : $y - 1;
|
||||
$y2 = $y1 + 1;
|
||||
$start = sprintf('%04d-04-01', $y1);
|
||||
$end = sprintf('%04d-03-31', $y2);
|
||||
|
||||
return [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'label' => $y1 . '-' . $y2,
|
||||
];
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user