This commit is contained in:
sanjeev.p 2026-03-27 20:05:32 +05:30
parent 08e296e3fd
commit 914a068e33
2 changed files with 176 additions and 106 deletions

View File

@ -206,11 +206,14 @@ $routes->group('api', ['filter' => ["jwtAuth:1,2,3,4,agent","appSignature"] ], f
$routes->get('invoice/details', 'InvoiceController::findInvoiceWithItems'); $routes->get('invoice/details', 'InvoiceController::findInvoiceWithItems');
$routes->post('invoice/create-or-update', 'InvoiceController::createOrUpdateInvoice'); $routes->post('invoice/create-or-update', 'InvoiceController::createOrUpdateInvoice');
$routes->post('invoice/add-payment', 'InvoiceController::addInvoicePayment'); $routes->post('invoice/add-payment', 'InvoiceController::addInvoicePayment');
$routes->get('invoice/add-payment-history', 'InvoiceController::addPaymentHistory');
$routes->get('invoice/delete', 'InvoiceController::deleteInvoice'); $routes->get('invoice/delete', 'InvoiceController::deleteInvoice');
$routes->post('invoice/commission-rate-list', 'InvoiceController::getCommissionRateList'); $routes->post('invoice/commission-rate-list', 'InvoiceController::getCommissionRateList');
$routes->get('invoice/getAgentUnusedCommissionList', 'InvoiceController::getAgentUnusedCommissionList'); $routes->get('invoice/getAgentUnusedCommissionList', 'InvoiceController::getAgentUnusedCommissionList');
$routes->post('invoice/bulk-upload-commission', 'InvoiceController::bulkUploadCommission'); $routes->post('invoice/bulk-upload-commission', 'InvoiceController::bulkUploadCommission');
$routes->post('invoice/bulk-upload-commission/proceed', 'InvoiceController::bulkUploadCommissionProceed'); $routes->post('invoice/bulk-upload-commission/proceed', 'InvoiceController::bulkUploadCommissionProceed');
$routes->post('invoice/bulk-upload-commission', 'InvoiceController::bulkUploadCommission');
$routes->post('invoice/bulk-upload-commission/proceed', 'InvoiceController::bulkUploadCommissionProceed');
// SALES EXECUTIVE // SALES EXECUTIVE

View File

@ -9,9 +9,9 @@ use App\Models\InvoiceModel;
use App\Models\InvoiceItemModel; use App\Models\InvoiceItemModel;
use App\Models\InvoiceUtrModel; use App\Models\InvoiceUtrModel;
use App\Models\PartnerAccountHistoryModel; use App\Models\PartnerAccountHistoryModel;
// use App\Models\AgentIncentiveFileModel; use App\Models\AgentIncentiveFileModel;
use CodeIgniter\Database\Exceptions\DataException; use CodeIgniter\Database\Exceptions\DataException;
// use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\IOFactory;
class InvoiceController extends ResourceController class InvoiceController extends ResourceController
{ {
@ -22,7 +22,7 @@ class InvoiceController extends ResourceController
protected $InvoiceItemModel; protected $InvoiceItemModel;
protected $InvoiceUtrModel; protected $InvoiceUtrModel;
protected $PartnerAccountHistoryModel; protected $PartnerAccountHistoryModel;
// protected $AgentIncentiveFileModel; protected $AgentIncentiveFileModel;
protected $db; protected $db;
public function __construct() public function __construct()
@ -34,7 +34,7 @@ class InvoiceController extends ResourceController
$this->InvoiceItemModel = new InvoiceItemModel(); $this->InvoiceItemModel = new InvoiceItemModel();
$this->InvoiceUtrModel = new InvoiceUtrModel(); $this->InvoiceUtrModel = new InvoiceUtrModel();
$this->PartnerAccountHistoryModel = new PartnerAccountHistoryModel(); $this->PartnerAccountHistoryModel = new PartnerAccountHistoryModel();
// $this->AgentIncentiveFileModel = new AgentIncentiveFileModel(); $this->AgentIncentiveFileModel = new AgentIncentiveFileModel();
$this->db = \Config\Database::connect(); $this->db = \Config\Database::connect();
} }
@ -197,7 +197,7 @@ class InvoiceController extends ResourceController
if (!$invoiceId) { if (!$invoiceId) {
// Generate invoice number only for CREATE // Generate invoice number only for CREATE
$invoiceData['invoice_no'] = $this->generateInvoiceNo($input['pos_id'] ?? 0); $invoiceData['invoice_no'] = $this->generateInvoiceNo($input['pos_id']);
$invoiceData['created_at'] = date('Y-m-d H:i:s'); $invoiceData['created_at'] = date('Y-m-d H:i:s');
$invoiceData['created_by'] = $input['created_by'] ?? 0; $invoiceData['created_by'] = $input['created_by'] ?? 0;
@ -270,8 +270,9 @@ class InvoiceController extends ResourceController
private function generateInvoiceNo($pos_id) private function generateInvoiceNo($pos_id)
{ {
$pos_id = !empty($pos_id) ? $pos_id : 0;
$year = date('Y'); $year = date('Y');
$prefix = !empty($pos_id) & $pos_id != 0 ? "NIIB/$pos_id/$year/" : "MIG/$year/"; $prefix = "NIIB/$pos_id/$year/";
// Get last invoice of current year // Get last invoice of current year
$lastInvoice = $this->InvoiceModel $lastInvoice = $this->InvoiceModel
@ -595,116 +596,181 @@ class InvoiceController extends ResourceController
} }
} }
// public function bulkUploadCommission() public function addPaymentHistory()
// { {
// $this->db->transBegin(); try {
// try { $invoiceId = (int)($this->request->getGet('invoice_id') ?? 0);
// $input = $this->request->getJSON(true); if ($invoiceId <= 0) {
// if (!is_array($input)) { return $this->respond([
// $input = []; 'status' => 'failed',
// } 'code' => 400,
'message'=> 'invoice_id is required'
], 400);
}
// $post = $this->request->getPost(); $invoice = $this->InvoiceModel
// if (!is_array($post)) { ->select('id, invoice_no, invoice_amount')
// $post = []; ->where('id', $invoiceId)
// } ->where('is_active', 1)
->first();
// $rows = $input['rows'] ?? []; if (empty($invoice)) {
// $updatedBy = (int)($input['updated_by'] ?? ($post['created_by'] ?? 0)); return $this->respond([
'status' => 'failed',
'code' => 404,
'message'=> 'Invoice not found'
], 404);
}
// // Multipart flow: read excel on backend and store upload metadata. $history = $this->db->table('partner_account_history pah')
// $file = $this->request->getFile('file_name'); ->select('
// if ($file && $file->isValid()) { pah.id,
// $month = date('Y-m-d'); pah.invoice_id,
// $uploadPath = WRITEPATH . 'uploads/agent/incentive_file/'; pi.invoice_no,
// if (!is_dir($uploadPath)) { pi.invoice_amount AS total_amount,
// mkdir($uploadPath, 0777, true); pah.paid_amount,
// } pah.paid_date,
pah.created_at,
COALESCE(ps.name, "-") AS createdby_name,
(
pi.invoice_amount - COALESCE((
SELECT SUM(pah2.paid_amount)
FROM partner_account_history pah2
WHERE pah2.invoice_id = pah.invoice_id
AND pah2.is_active = 1
AND pah2.id <= pah.id
), 0)
) AS balance_amount
', false)
->join('partner_invoice pi', 'pi.id = pah.invoice_id', 'inner')
->join('partner_staff ps', 'ps.id = pah.created_by', 'left')
->where('pah.invoice_id', $invoiceId)
->where('pah.is_active', 1)
->orderBy('pah.id', 'DESC')
->get()
->getResultArray();
// $storedFileName = time() . '_' . $file->getRandomName(); return $this->respond([
// $file->move($uploadPath, $storedFileName); 'status' => 'success',
'code' => 200,
// $this->AgentIncentiveFileModel->insert([ 'data' => $history,
// 'incentive_month' => $month, 'invoice'=> [
// 'incentive_file_name' => $storedFileName, 'invoice_id' => (int)$invoice['id'],
// 'file_type' => 'invoice', 'invoice_no' => $invoice['invoice_no'],
// 'is_active' => 1, 'total_amount' => (float)$invoice['invoice_amount'],
// 'created_by' => $updatedBy > 0 ? $updatedBy : null, ],
// ], true); ], 200);
} catch (\Exception $e) {
// $spreadsheet = IOFactory::load($uploadPath . $storedFileName); return $this->respond([
// $excelRows = $spreadsheet->getActiveSheet()->toArray(null, true, true, false); 'status' => 'failed',
'code' => 500,
// if (empty($excelRows)) { 'message'=> $e->getMessage()
// return $this->respond([ ], 500);
// 'status' => 'failed', }
// 'code' => 400, }
// 'message' => 'Uploaded file is empty',
// ], 400);
// }
// $headerRow = $excelRows[0] ?? [];
// $headerIndex = [];
// foreach ($headerRow as $idx => $headerValue) {
// $normalized = preg_replace('/[^a-z0-9]/', '', strtolower(trim((string)$headerValue)));
// if (!empty($normalized)) {
// $headerIndex[$normalized] = (int)$idx;
// }
// }
// $policyIdx = $headerIndex['policynumber'] ?? null;
// $invoiceIdx = $headerIndex['invoicenumber'] ?? null;
// $commissionIdx = $headerIndex['commission'] ?? ($headerIndex['commissionamount'] ?? null);
// if ($policyIdx === null || $commissionIdx === null) {
// return $this->respond([
// 'status' => 'failed',
// 'code' => 400,
// 'message' => 'Expected columns: Policy Number, Invoice Number, Commission or Commission Amount',
// ], 400);
// }
// $fallbackInvoiceNo = trim((string)($post['invoice_number'] ?? ''));
// $rows = [];
// foreach ($excelRows as $index => $row) {
// if ($index === 0) {
// continue;
// }
// $policyNo = trim((string)($row[$policyIdx] ?? ''));
// $invoiceNoFromFile = $invoiceIdx !== null ? trim((string)($row[$invoiceIdx] ?? '')) : '';
// $invoiceNo = $invoiceNoFromFile !== '' ? $invoiceNoFromFile : $fallbackInvoiceNo;
// $commissionRaw = trim((string)($row[$commissionIdx] ?? ''));
// if ($policyNo === '' && $invoiceNo === '' && $commissionRaw === '') {
// continue;
// }
// $commission = (float)str_replace(',', '', $commissionRaw);
// if ($policyNo === '' || $invoiceNo === '' || !is_numeric(str_replace(',', '', $commissionRaw))) {
// return $this->respond([
// 'status' => 'failed',
// 'code' => 400,
// 'message' => 'Invalid data at line ' . ($index + 1),
// ], 400);
// }
// $rows[] = [
// 'line_no' => $index + 1,
// 'policy_number' => $policyNo,
// 'invoice_no' => $invoiceNo,
// 'commission_amount' => $commission,
// ];
// }
// }
public function bulkUploadCommission() public function bulkUploadCommission()
{ {
$this->db->transBegin(); $this->db->transBegin();
try { try {
$input = $this->request->getJSON(true); $input = $this->request->getJSON(true);
if (!is_array($input)) {
$input = [];
}
$post = $this->request->getPost();
if (!is_array($post)) {
$post = [];
}
$rows = $input['rows'] ?? []; $rows = $input['rows'] ?? [];
$updatedBy = (int)($input['updated_by'] ?? 0); $updatedBy = (int)($input['updated_by'] ?? ($post['created_by'] ?? 0));
// Multipart flow: read excel on backend and store upload metadata.
$file = $this->request->getFile('file_name');
if ($file && $file->isValid()) {
$month = date('Y-m-d');
$uploadPath = WRITEPATH . 'uploads/agent/incentive_file/';
if (!is_dir($uploadPath)) {
mkdir($uploadPath, 0777, true);
}
$storedFileName = time() . '_' . $file->getRandomName();
$file->move($uploadPath, $storedFileName);
$this->AgentIncentiveFileModel->insert([
'incentive_month' => $month,
'incentive_file_name' => $storedFileName,
'file_type' => 'invoice',
'is_active' => 1,
'created_by' => $updatedBy > 0 ? $updatedBy : null,
], true);
$spreadsheet = IOFactory::load($uploadPath . $storedFileName);
$excelRows = $spreadsheet->getActiveSheet()->toArray(null, true, true, false);
if (empty($excelRows)) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'message' => 'Uploaded file is empty',
], 400);
}
$headerRow = $excelRows[0] ?? [];
$headerIndex = [];
foreach ($headerRow as $idx => $headerValue) {
$normalized = preg_replace('/[^a-z0-9]/', '', strtolower(trim((string)$headerValue)));
if (!empty($normalized)) {
$headerIndex[$normalized] = (int)$idx;
}
}
$policyIdx = $headerIndex['policynumber'] ?? null;
$invoiceIdx = $headerIndex['invoicenumber'] ?? null;
$commissionIdx = $headerIndex['commission'] ?? ($headerIndex['commissionamount'] ?? null);
if ($policyIdx === null || $commissionIdx === null) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'message' => 'Expected columns: Policy Number, Invoice Number, Commission or Commission Amount',
], 400);
}
$fallbackInvoiceNo = trim((string)($post['invoice_number'] ?? ''));
$rows = [];
foreach ($excelRows as $index => $row) {
if ($index === 0) {
continue;
}
$policyNo = trim((string)($row[$policyIdx] ?? ''));
$invoiceNoFromFile = $invoiceIdx !== null ? trim((string)($row[$invoiceIdx] ?? '')) : '';
$invoiceNo = $invoiceNoFromFile !== '' ? $invoiceNoFromFile : $fallbackInvoiceNo;
$commissionRaw = trim((string)($row[$commissionIdx] ?? ''));
if ($policyNo === '' && $invoiceNo === '' && $commissionRaw === '') {
continue;
}
$commission = (float)str_replace(',', '', $commissionRaw);
if ($policyNo === '' || $invoiceNo === '' || !is_numeric(str_replace(',', '', $commissionRaw))) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'message' => 'Invalid data at line ' . ($index + 1),
], 400);
}
$rows[] = [
'line_no' => $index + 1,
'policy_number' => $policyNo,
'invoice_no' => $invoiceNo,
'commission_amount' => $commission,
];
}
}
if (empty($rows) || !is_array($rows)) { if (empty($rows) || !is_array($rows)) {
return $this->respond([ return $this->respond([
@ -798,7 +864,8 @@ class InvoiceController extends ResourceController
'is_active' => 1, 'is_active' => 1,
]); ]);
$this->db->transRollback(); // Keep staged token/payload so proceed API can continue later.
$this->db->transCommit();
return $this->respond([ return $this->respond([
'status' => 'partner_mismatch', 'status' => 'partner_mismatch',
'code' => 200, 'code' => 200,