FIX_Changes and Additional Requirements1

This commit is contained in:
sanjeev.p 2026-03-23 16:29:48 +05:30
parent d98a50c5c2
commit d9f533ac74
6 changed files with 468 additions and 7 deletions

View File

@ -178,6 +178,23 @@ $routes->group('api', ['filter' => ["jwtAuth:1,2,3,4,agent","appSignature"] ], f
$routes->get('reports/endorsement-excel', 'ExcelExportController::downloadExcelEndorsement');
// DASHBOARD Season 6 — Partner Portal
// GET /partner/{id}/details
$routes->get('partner/(:num)/details', 'DashboardController::partnerDetails/$1');
// GET /partner/{id}/policies
$routes->get('partner/(:num)/policies', 'DashboardController::partnerPolicies/$1');
// GET /partner/{id}/renewals?days=N
$routes->get('partner/(:num)/renewals', 'DashboardController::partnerRenewals/$1');
// GET /partner/{id}/earnings
$routes->get('partner/(:num)/earnings', 'DashboardController::partnerEarnings/$1');
//invoice
@ -203,7 +220,7 @@ $routes->group('api', ['filter' => ["jwtAuth:1,2,3,4,agent","appSignature"] ], f
$routes->get('audit/history', 'MasterController::getHistory');
});
});
// common

View File

@ -1172,5 +1172,413 @@ class DashboardController extends ResourceController
return array_values($final);
}
// ─────────────────────────────────────────────────────────────────────────────
// DashboardController.php — Partner Portal API methods
// Routes:
// GET partner/(:num)/details → partnerDetails($id)
// GET partner/(:num)/policies → partnerPolicies($id)
// GET partner/(:num)/renewals → partnerRenewals($id) ?days=20
// GET partner/(:num)/earnings → partnerEarnings($id)
// ─────────────────────────────────────────────────────────────────────────────
// ══════════════════════════════════════════════════════════════════════════════
// GET partner/{id}/details
// agent_id = partner_agent.id
// Joins: partner_policy (agent_id), partner_enquiry (agent_id),
// partner_endorsement_request (agent_id)
// ══════════════════════════════════════════════════════════════════════════════
public function partnerDetails($id)
{
$ref = [];
try {
if (empty($id)) {
return $this->respond([
'status' => 'error',
'code' => 400,
'data' => [],
'message' => 'Missing required parameter: id',
], 200);
}
// ── 1. Agent profile (partner_agent.id = $id)
$agent = $this->db->table('partner_agent pa')
->select('
pa.id,
pa.name AS agent_name,
pa.agent_code,
pa.mobile,
pa.email,
pa.is_active,
ps.name AS manager_name
')
->join('partner_staff ps', 'ps.id = pa.manager_id', 'left')
->where('pa.id', $id)
->get()->getRowArray();
if (empty($agent)) {
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
$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
')
->where('pp.agent_id', $id)
->get()->getRowArray();
// ── 3. Enquiry counts
// enquiry_status enum: To be assigned | Assigned | In progress | Completed
$enquiryStats = $this->db->table('partner_enquiry pe')
->select('
COUNT(pe.id) AS enquiry_total,
SUM(CASE WHEN pe.enquiry_status = "Completed" THEN 1 ELSE 0 END) AS enquiry_completed,
SUM(CASE WHEN pe.enquiry_status != "Completed" THEN 1 ELSE 0 END) AS enquiry_pending
')
->where('pe.agent_id', $id)
->where('pe.is_active', 1)
->get()->getRowArray();
// ── 4. Endorsement counts
// status is varchar(20) — adjust "Completed" to match your actual values
$endorseStats = $this->db->table('partner_endorsement_request per')
->select('
COUNT(per.id) AS endorsement_total,
SUM(CASE WHEN per.status = "Completed" THEN 1 ELSE 0 END) AS endorsement_done,
SUM(CASE WHEN per.status != "Completed" THEN 1 ELSE 0 END) AS endorsement_pending
')
->where('per.agent_id', $id)
->where('per.is_active', 1)
->get()->getRowArray();
// ── Merge everything
$data = array_merge(
$agent,
[
'status' => $agent['is_active'] ? 'Active' : 'Inactive',
'commission_rate' => 15,
],
$policyStats ?? [],
$enquiryStats ?? [],
$endorseStats ?? [],
);
$ref['message'] = 'Partner details retrieved successfully.';
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => $data,
'ref' => $ref,
], 200);
} catch (\Throwable $e) {
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
$ref['message'] = 'No Data Found';
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => [],
'message' => 'No Data Found',
'ref' => $ref,
], 200);
}
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|| $e instanceof \mysqli_sql_exception
|| $e instanceof \PDOException;
if ($isDbError) {
$ref['debug_info'] = $e->getFile() . ' / LN : ' . $e->getLine();
$ref['message'] = 'Database Error Occurred.';
} else {
$ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
}
return $this->respond([
'status' => 'error',
'code' => 500,
'data' => [],
'ref' => $ref,
], 200);
}
}
// ══════════════════════════════════════════════════════════════════════════════
// GET partner/{id}/policies
// partner_policy.agent_id = $id
// holder_name → pp.insured_name (the actual insured person, NOT agent)
// product → pp.product (varchar 50), falls back to pp.vehicle_type
// policy_no → pp.policy_number
// ══════════════════════════════════════════════════════════════════════════════
public function partnerPolicies($id)
{
$ref = [];
try {
if (empty($id)) {
return $this->respond([
'status' => 'error',
'code' => 400,
'data' => [],
'message' => 'Missing required parameter: id',
], 200);
}
$results = $this->db->table('partner_policy pp')
->select('
pp.policy_number AS policy_no,
pp.insured_name AS holder_name,
COALESCE(NULLIF(pp.product, ""), pp.vehicle_type) AS product,
pp.premium_amount AS premium,
DATE_FORMAT(pp.issued_date, "%d-%m-%Y") AS issued_date,
DATE_FORMAT(pp.end_date, "%d-%m-%Y") AS expiry_date
')
->where('pp.agent_id', $id)
->where('pp.policy_number IS NOT NULL')
->where('pp.premium_amount IS NOT NULL')
->where('pp.is_active', 1)
->orderBy('pp.issued_date', 'DESC')
->get()->getResultArray();
$ref['total_records'] = count($results);
if (empty($results)) {
throw new \RuntimeException('No policies found for this partner.', 404);
}
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => $results,
'ref' => $ref,
], 200);
} catch (\Throwable $e) {
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
$ref['message'] = 'No Data Found';
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => [],
'message' => 'No Data Found',
'ref' => $ref,
], 200);
}
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|| $e instanceof \mysqli_sql_exception
|| $e instanceof \PDOException;
if ($isDbError) {
$ref['debug_info'] = $e->getFile() . ' / LN : ' . $e->getLine();
$ref['message'] = 'Database Error Occurred.';
} else {
$ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
}
return $this->respond([
'status' => 'error',
'code' => 500,
'data' => [],
'ref' => $ref,
], 200);
}
}
// ══════════════════════════════════════════════════════════════════════════════
// GET partner/{id}/renewals?days=20
// partner_policy.agent_id = $id
// holder_name → pp.insured_name
// premium → pp.premium_amount
// ══════════════════════════════════════════════════════════════════════════════
public function partnerRenewals($id)
{
$ref = [];
$days = (int) ($this->request->getGet('days') ?? 20);
try {
if (empty($id)) {
return $this->respond([
'status' => 'error',
'code' => 400,
'data' => [],
'message' => 'Missing required parameter: id',
], 200);
}
$results = $this->db->table('partner_policy pp')
->select('
pp.policy_number AS policy_no,
pp.insured_name AS holder_name,
pp.premium_amount AS premium,
DATE_FORMAT(pp.end_date, "%d-%m-%Y") AS end_date,
DATEDIFF(pp.end_date, CURDATE()) AS days_left
')
->where('pp.agent_id', $id)
->where('pp.is_active', 1)
->where('pp.policy_number IS NOT NULL')
->where('pp.premium_amount IS NOT NULL')
->where('pp.end_date >= CURDATE()', null, false)
->where("pp.end_date <= DATE_ADD(CURDATE(), INTERVAL {$days} DAY)", null, false)
->orderBy('pp.end_date', 'ASC')
->get()->getResultArray();
$ref['days_filter'] = $days;
$ref['total_records'] = count($results);
if (empty($results)) {
throw new \RuntimeException('No renewals due within ' . $days . ' days.', 404);
}
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => $results,
'ref' => $ref,
], 200);
} catch (\Throwable $e) {
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
$ref['message'] = 'No Data Found';
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => [],
'message' => 'No Data Found',
'ref' => $ref,
], 200);
}
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|| $e instanceof \mysqli_sql_exception
|| $e instanceof \PDOException;
if ($isDbError) {
$ref['debug_info'] = $e->getFile() . ' / LN : ' . $e->getLine();
$ref['message'] = 'Database Error Occurred.';
} else {
$ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
}
return $this->respond([
'status' => 'error',
'code' => 500,
'data' => [],
'ref' => $ref,
], 200);
}
}
// ══════════════════════════════════════════════════════════════════════════════
// 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)
// ══════════════════════════════════════════════════════════════════════════════
public function partnerEarnings($id)
{
$ref = [];
$monthKey = $this->request->getGet('month_key') ?? null;
try {
if (empty($id)) {
return $this->respond([
'status' => 'error',
'code' => 400,
'data' => [],
'message' => 'Missing required parameter: id',
], 200);
}
$builder = $this->db->table('partner_policy pp');
$builder->select("
DATE_FORMAT(pp.issued_date, '%Y-%m') AS month_key,
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
");
$builder->where('pp.agent_id', $id);
$builder->where('pp.is_active', 1);
$builder->where('pp.policy_number IS NOT NULL');
$builder->where('pp.premium_amount IS NOT NULL');
if (!empty($monthKey)) {
$builder->where("DATE_FORMAT(pp.issued_date, '%Y-%m')", $monthKey);
}
$builder->groupBy("DATE_FORMAT(pp.issued_date, '%Y-%m')");
$builder->orderBy('month_key', 'ASC');
$results = $builder->get()->getResultArray();
$ref['month_filter'] = $monthKey ?? 'all';
$ref['total_records'] = count($results);
if (empty($results)) {
throw new \RuntimeException('No earning data found for this partner.', 404);
}
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => $results,
'ref' => $ref,
], 200);
} catch (\Throwable $e) {
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
$ref['message'] = 'No Data Found';
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => [],
'message' => 'No Data Found',
'ref' => $ref,
], 200);
}
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|| $e instanceof \mysqli_sql_exception
|| $e instanceof \PDOException;
if ($isDbError) {
$ref['debug_info'] = $e->getFile() . ' / LN : ' . $e->getLine();
$ref['message'] = 'Database Error Occurred.';
} else {
$ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
}
return $this->respond([
'status' => 'error',
'code' => 500,
'data' => [],
'ref' => $ref,
], 200);
}
}
}

View File

@ -139,8 +139,14 @@ class EndorsementController extends ResourceController
foreach ($data as $key => $row) {
$data[$key]['created_at'] = date('d-m-Y h:i A', strtotime($row['created_at']));
$data[$key]['updated_at'] = date('d-m-Y h:i A', strtotime($row['updated_at']));
$data[$key]['policy_start_date'] = date('d-m-Y', strtotime($row['policy_start_date']));
$data[$key]['policy_end_date'] = date('d-m-Y', strtotime($row['policy_end_date']));
// ✅ NULL-safe date formatting
$data[$key]['policy_start_date'] = (!empty($row['policy_start_date']) && $row['policy_start_date'] !== '0000-00-00')
? date('d-m-Y', strtotime($row['policy_start_date']))
: null;
$data[$key]['policy_end_date'] = (!empty($row['policy_end_date']) && $row['policy_end_date'] !== '0000-00-00')
? date('d-m-Y', strtotime($row['policy_end_date']))
: null;
}
return $this->respond(['status' => 'success','code' => 200,'data' => $data], 200);

View File

@ -186,11 +186,13 @@ class EnquiryController extends ResourceController
}
//Get enquiry details
$enquiry = $this->enquiryModel->select('partner_enquiry.* , I.name as insurer_name , I.short_name , VT.vehicle_type as vehicle_type ,PB.name as broker_name ,PA.name as agent_name,PA.agent_code')
$enquiry = $this->enquiryModel->select('partner_enquiry.* , I.name as insurer_name , I.short_name , VT.vehicle_type as vehicle_type ,PB.name as broker_name ,PA.name as agent_name,PA.agent_code,PPMM.value as payment_mode_value')
->join('insurers I', 'I.id = partner_enquiry.insurer_id', 'left')
->join('vehicle_type VT', 'VT.id = partner_enquiry.vehicle_type_id', 'left')
->join('partner_brokers PB', 'PB.id = partner_enquiry.broker_id', 'left')
->join('partner_agent PA', 'PA.id = partner_enquiry.agent_id', 'left')
->join('partner_quotation PQ', 'PQ.enquiry_id = partner_enquiry.id', 'left')
->join('partner_payment_mode_master PPMM', 'PPMM.id = PQ.payment_mode_id', 'left')
->where('partner_enquiry.id', $enquiry_id)
->where('partner_enquiry.is_active', 1)
->first();
@ -834,7 +836,7 @@ class EnquiryController extends ResourceController
try {
$data = $this->request->getJSON(true);
print_r($data);die;
// print_r($data);die;
if (!isset($data['id'])) {
return $this->respond(['status' => 'failed', 'code' => 200, 'error' => 'ID Required'], 200);

View File

@ -41,7 +41,33 @@ class InvoiceController extends ResourceController
pos.name as pos_name,
FORMAT(partner_invoice.invoice_amount, 2, "en_IN") AS invoice_amount_indian_format,
DATE_FORMAT(partner_invoice.invoice_date, "%d-%m-%Y") AS invoice_date_ui_format,
')
(
SELECT GROUP_CONCAT(pa.name ORDER BY pa.id SEPARATOR ", ")
FROM partner_agent pa
WHERE JSON_SEARCH(partner_invoice.agent_id, "one", CAST(pa.id AS CHAR)) IS NOT NULL
) AS partner_names,
(
SELECT GROUP_CONCAT(piu.utr_no ORDER BY piu.id SEPARATOR ", ")
FROM partner_invoice_utr piu
WHERE piu.invoice_id = partner_invoice.id
AND piu.is_active = 1
) AS utr_numbers,
partner_invoice.invoice_amount AS invoiced_amount,
COALESCE((
SELECT SUM(piu.amount)
FROM partner_invoice_utr piu
WHERE piu.invoice_id = partner_invoice.id
AND piu.is_active = 1
), 0.00) AS payout_amount,
(
partner_invoice.invoice_amount - COALESCE((
SELECT SUM(piu.amount)
FROM partner_invoice_utr piu
WHERE piu.invoice_id = partner_invoice.id
AND piu.is_active = 1
), 0.00)
) AS balance_amount',
false)
->join('partner_brokers PB', 'PB.id = partner_invoice.broker_id', 'left')
->join('partner_pos pos', 'pos.id = partner_invoice.pos_id', 'left')
->where('partner_invoice.is_active', 1)
@ -193,6 +219,7 @@ class InvoiceController extends ResourceController
private function generateInvoiceNo($pos_id)
{
$pos_id = !empty($pos_id) ? $pos_id : 0;
$year = date('Y');
$prefix = "NIIB/$pos_id/$year/";

View File

@ -181,8 +181,9 @@ if (!function_exists('createBDS')) {
if (!function_exists('format_date_for_database')) {
function format_date_for_database(string $date): ?string
function format_date_for_database(?string $date): ?string
{
if (empty($date)) return null; // ✅ handle null/empty
$dt = DateTime::createFromFormat('d-m-Y', $date);
if ($dt) {
return $dt->format('Y-m-d');