CHANGE_User + Nhance Partner

This commit is contained in:
venba-Inspriron-3558 2025-09-04 18:41:09 +05:30
parent 9682865454
commit 33581a37a5
9 changed files with 1251 additions and 97 deletions

View File

@ -73,6 +73,9 @@ $routes->group("/user", ["filter" => "authMVC"], function ($routes) {
$routes->get("deactive/(:hash)", "UserController::deactive/$1");
$routes->get("rolesandteams", "UserController::getRolesAndTeams");
$routes->get("getUserActivityHistory", "UserController::getUserActivityHistory");
$routes->match(['get','post','put'], 'partner', 'UserController::partner');
$routes->match(['get','post','put'], 'partnerIncentive', 'UserController::partnerIncentive');
$routes->get("download-incentive-file/(:any)", "UserController::downloadIncentivesFile/$1");
});
$routes->group("/dashboard", ["filter" => "authMVC"], function ($routes) {

View File

@ -18,6 +18,8 @@ use App\Models\UserTeamsModel;
use App\Helpers\BookStackUserHelper;
use App\Models\AuthHistoryModel;
use App\Models\UserActivityHistoryModel;
use App\Models\PartnerStaffModel;
use App\Models\PartnerManagerIncentiveFileModel;
class UserController extends AdminController
@ -32,6 +34,8 @@ class UserController extends AdminController
protected $bookStack;
protected $authHistoryModel;
protected $userActivityHistoryModel;
protected $partnerStaffModel;
protected $partnerManagerIncentiveFileModel;
public function __construct()
{
@ -45,6 +49,8 @@ class UserController extends AdminController
$this->bookStack = new BookStackUserHelper();
$this->authHistoryModel = new AuthHistoryModel();
$this->userActivityHistoryModel = new UserActivityHistoryModel();
$this->partnerStaffModel = new PartnerStaffModel();
$this->partnerManagerIncentiveFileModel = new PartnerManagerIncentiveFileModel();
}
public function list()
@ -563,4 +569,211 @@ class UserController extends AdminController
}
}
public function partner()
{
$method = $this->request->getMethod(); // get, post
try{
// Listing
if ($method === 'get') {
$types = $this->partnerStaffModel->findAll();
if (empty($types)) {
return $this->response->setJSON(['status' => 'error','message' => 'No Staff found'])->setStatusCode(404);
}
return $this->response->setJSON(['status' => 'success','data' => $types])->setStatusCode(200);
}
// add/update
if ($method === 'post') {
$data = $this->request->getPost();
if (!empty($data['id'])) {
$text = "update";
$result = $this->partnerStaffModel->update($data['id'], $data);
$updateID = $data['id'];
} else {
$text = "create";
$data['role_id'] = 1;
$data['created_by'] = get_session_userid();
$insertID = $this->partnerStaffModel->insert($data);
$result = true;
}
$id = isset($insertID) && !empty($insertID) ? $insertID : ($updateID ?? null);
return $this->response->setJSON([
'status' => $id ? 'success' : 'error',
'message' => $id ? "Staff {$text}d successfully" : "Unable to {$text} staff. Please try again.",
'id' => $id
])->setStatusCode($id ? 200 : 400);
}
// delete
if ($method === 'put') {
$data = $this->request->getRawInput();
$id = $data['id'] ?? null;
if (!$id) {
return $this->response->setJSON(['status' => 'error', 'message' => 'ID is required'])->setStatusCode(400);
}
$staff = $this->partnerStaffModel->find($id);
if (!$staff) {
return $this->response->setJSON(['status' => 'error','message' => 'Staff not found'])->setStatusCode(404);
}
if ($staff['is_active'] == 1) {
$result = $this->partnerStaffModel->update($id, ['is_active' => 0]);
$message = "Staff deleted successfully";
} else {
return $this->response->setJSON(['status' => 'error','message' => 'Staff already deleted'])->setStatusCode(400);
}
return $this->response->setJSON([
'status' => $result ? 'success' : 'error',
'message' => $result ? $message : "Unable to delete staff. Please try again.",
'id' => $id
])->setStatusCode($result ? 200 : 400);
}
return $this->response->setJSON([ 'status' => 'error', 'message' => 'Invalid request method' ])->setStatusCode(405);
}
catch (\Throwable $e) {
$code = ($e->getCode() && $e->getCode() >= 100 && $e->getCode() < 600) ? $e->getCode() : 500;
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|| $e instanceof \mysqli_sql_exception
|| $e instanceof \PDOException;
$context = ['title' => get_class($e),'type' => get_class($e),'code' => $code,'message' => $e->getMessage(),'file' => $e->getFile(),'line' => $e->getLine()];
$this->myLogger->logme('error', "Exception: {message} in {file} on line {line}", $context, 0);
return $this->response->setJSON([ 'status' => 'error', 'message' => $isDbError ? 'Data Access Error' : $e->getMessage(),
'ref' => $isDbError ? 'database - ' : 'application - ' . $code . ' - ' . $e->getLine()
])->setStatusCode($code);
}
}
public function partnerIncentive()
{
$method = $this->request->getMethod(); // get, post
try{
// Listing
if ($method === 'get') {
$manager_id = $this->request->getGet('manager_id');
$files = $this->partnerManagerIncentiveFileModel->where('manager_id', $manager_id)->findAll();
if (empty($files)) {
return $this->response->setJSON(['status' => 'error','message' => 'No Records found'])->setStatusCode(404);
}
return $this->response->setJSON(['status' => 'success','data' => $files])->setStatusCode(200);
}
// add/update
if ($method === 'post') {
$file = $this->request->getFile('incentive_file_name');
$month = $this->request->getPost('incentive_month');
$managerId = $this->request->getPost('manager_id');
$fileId = $this->request->getPost('id');
if ($file && $file->isValid() && !$file->hasMoved()) {
$fileName = $file->getName();
$path = WRITEPATH.'uploads/incentives';
$file->move($path, $fileName);
$data = [
'manager_id' => $managerId,
'incentive_month' => date('Y-m-d', strtotime($month)),
'incentive_file_name' => $fileName,
'created_by' => get_session_userid()
];
if ($fileId) {
$text = "update";
$this->partnerManagerIncentiveFileModel->update($fileId, $data);
$updateID = $data['id'];
} else {
$text = "create";
$insertID = $this->partnerManagerIncentiveFileModel->insert($data);
$result = true;
}
$id = isset($insertID) && !empty($insertID) ? $insertID : ($updateID ?? null);
return $this->response->setJSON([
'status' => $id ? 'success' : 'error',
'message' => $id ? "File {$text}d successfully" : "Unable to {$text} file. Please try again.",
'id' => $id
])->setStatusCode($id ? 200 : 400);
}
return $this->response->setJSON([
'status' => 'error',
'message' => "Unable to Upload file. Please try again.",
'id' => ''
])->setStatusCode(400);
}
// delete
if ($method === 'put') {
$data = $this->request->getRawInput();
$id = $data['id'] ?? null;
if (!$id) {
return $this->response->setJSON(['status' => 'error', 'message' => 'ID is required'])->setStatusCode(400);
}
$files = $this->partnerManagerIncentiveFileModel->find($id);
if (!$files) {
return $this->response->setJSON(['status' => 'error','message' => 'No Records found'])->setStatusCode(404);
}
if ($files['is_active'] == 1) {
$result = $this->partnerManagerIncentiveFileModel->update($id, ['is_active' => 0]);
$message = "Files deleted successfully";
} else {
return $this->response->setJSON(['status' => 'error','message' => 'files already deleted'])->setStatusCode(400);
}
return $this->response->setJSON([
'status' => $result ? 'success' : 'error',
'message' => $result ? $message : "Unable to delete staff. Please try again.",
'id' => $id
])->setStatusCode($result ? 200 : 400);
}
return $this->response->setJSON([ 'status' => 'error', 'message' => 'Invalid request method' ])->setStatusCode(405);
}
catch (\Throwable $e) {
$code = ($e->getCode() && $e->getCode() >= 100 && $e->getCode() < 600) ? $e->getCode() : 500;
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|| $e instanceof \mysqli_sql_exception
|| $e instanceof \PDOException;
$context = ['title' => get_class($e),'type' => get_class($e),'code' => $code,'message' => $e->getMessage(),'file' => $e->getFile(),'line' => $e->getLine()];
$this->myLogger->logme('error', "Exception: {message} in {file} on line {line}", $context, 0);
return $this->response->setJSON([ 'status' => 'error', 'message' => $isDbError ? 'Data Access Error' : $e->getMessage(),
'ref' => $isDbError ? 'database - ' : 'application - ' . $code . ' - ' . $e->getLine()
])->setStatusCode($code);
}
}
public function downloadIncentivesFile($file_name)
{
$file_name = basename($file_name);
$filePath = WRITEPATH . 'uploads/incentives/' . $file_name;
try {
if (file_exists($filePath)) {
return $this->response->download($filePath, null);
} else {
$data['message'] = 'File Not Found';
echo view('errors/404', $data);
}
} catch (\Exception $e) {
// Handle any exceptions
$errorMessage = $e->getMessage();
$this->myLogger->logme('error', $errorMessage);
// You can return an error response here
echo $errorMessage;
}
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace App\Models;
use CodeIgniter\Model;
class PartnerManagerIncentiveFileModel extends Model
{
protected $table = 'partner_manager_incentive_file';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = 'array'; // or 'object'
protected $useSoftDeletes = false;
protected $allowedFields = [
'manager_id',
'incentive_month',
'incentive_file_name',
'is_active',
'created_by',
'created_on',
'updated_by',
'updated_on'
];
// Timestamps
protected $useTimestamps = true;
protected $createdField = 'created_on';
protected $updatedField = 'updated_on';
protected $dateFormat = 'datetime'; // can be 'date' or 'int'
// Validation Rules (optional, can add more)
// protected $validationRules = [
// 'manager_id' => 'required|integer',
// 'incentive_month' => 'required|valid_date',
// 'incentive_file_name'=> 'required|string|max_length[150]',
// ];
// protected $validationMessages = [
// 'manager_id' => [
// 'required' => 'Manager ID is required',
// 'integer' => 'Manager ID must be a number',
// ],
// 'incentive_month' => [
// 'required' => 'Incentive Month is required',
// 'valid_date' => 'Incentive Month must be a valid date (Y-m-d)',
// ],
// 'incentive_file_name' => [
// 'required' => 'File name is required',
// 'max_length' => 'File name cannot exceed 150 characters',
// ],
// ];
// protected $skipValidation = false;
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Models;
use CodeIgniter\Model;
class PartnerStaffModel extends Model
{
protected $table = 'partner_staff'; // table name
protected $primaryKey = 'id'; // primary key
protected $useAutoIncrement = true;
// return results as array
protected $returnType = 'array';
protected $useSoftDeletes = false;
// allowed fields for insert/update
protected $allowedFields = ['name','email','mobile','emp_id','role_id','email_otp','is_active','created_by','updated_by','manager_id'];
// automatic timestamps
protected $useTimestamps = true;
protected $createdField = 'created_on';
protected $updatedField = 'updated_on';
protected $dateFormat = 'datetime';
// validation rules
// protected $validationRules = [
// 'name' => 'required|min_length[2]|max_length[150]',
// 'email' => 'permit_empty|valid_email|max_length[150]',
// 'mobile' => 'permit_empty|regex_match[/^[0-9]{10,20}$/]',
// ];
// protected $validationMessages = [
// 'name' => [
// 'required' => 'Name is required',
// 'min_length' => 'Name must have at least 2 characters',
// 'max_length' => 'Name cannot exceed 150 characters'
// ],
// 'email' => [
// 'valid_email' => 'Please provide a valid email address',
// 'max_length' => 'Email cannot exceed 150 characters'
// ],
// 'mobile' => [
// 'regex_match' => 'Mobile number must be 1020 digits only'
// ]
// ];
// protected $skipValidation = false;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,4 @@
<style>
.input-icon {
position: relative;
display: block;
width: 100%;
}
.input-icon .form-control {
width: 100%;
box-sizing: border-box;
}
.input-icon .additional-icon {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
pointer-events: none;
font-size: 18px;
}
</style>
<!-- modal content -->
<div id="con-close-modal" class="modal fade app-font-family" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
<div class="modal-dialog modal-dialog-centered modal-lg" <?= !isset($CD_Master_Data) ? 'style="max-width: 35% !important; margin:5px auto!important;"' : '' ?>>

View File

@ -61,37 +61,6 @@ input:checked + .slider:before {
}
</style>
<style>
.form-input-icon {
position: relative;
width: 100%; /* match Bootstrap's width */
}
.form-input-icon input[type="file"].form-control {
padding-right: 40px; /* space for the icon */
cursor: pointer;
}
.form-input-icon input[type="file"].form-control::file-selector-button {
display: none;
}
.form-input-icon .form-additional-icon {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
font-size: 18px;
color: #555;
pointer-events: none;
}
input[type="radio"] {
accent-color: #40B2B6; /* sets the checked color */
}
</style>
<div class="tab-pane fade active show" id="general-q-tab">
@ -190,10 +159,10 @@ input:checked + .slider:before {
<div class="form-group row">
<label for="insurer_logo" class="col-md-4 col-form-label">Insurer Logo</label>
<div class="col-md-5">
<div class="form-input-icon">
<div class="input-icon">
<input type="file" class="form-control" id="insurer_logo" name="insurer_logo"
accept="image/jpeg, image/jpg, image/png" onchange="PreviewImage();">
<i class="mdi mdi-upload form-additional-icon"></i>
<i class="mdi mdi-upload additional-icon"></i>
</div>
</div>
<div class="col-md-3">

View File

@ -1124,7 +1124,59 @@ a.app-badge-secondary:focus, a.app-badge-secondary.focus {
padding-top: 0px;
padding-left: 5px;
}
.btn-custom {
font-weight: 500;
font-style: normal;
font-size: 12px;
line-height: 1;
letter-spacing: 0;
text-align: center;
}
</style>
<style>
/* Common wrapper (works for text/file inputs) */
.input-icon {
position: relative;
display: block;
width: 100%;
}
/* All form controls inside */
.input-icon .form-control {
width: 100%;
box-sizing: border-box;
padding-right: 40px; /* always keep space for icon */
cursor: pointer;
}
/* Hide default file button */
.input-icon .form-control[type="file"]::file-selector-button {
display: none;
}
.input-icon input[type="file"].form-control {
padding-right: 40px; /* space for the icon */
cursor: pointer;
}
/* Common icon class */
.input-icon .additional-icon {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
font-size: 18px;
color: #555;
pointer-events: none;
}
input[type="radio"] {
accent-color: #40B2B6; /* sets the checked color */
}
</style>
</head>

View File

@ -32,21 +32,6 @@ table.dataTable td.wrap {
word-break: break-word;
}
.btn-custom {
font-weight: 500;
font-style: normal;
font-size: 12px;
line-height: 1;
letter-spacing: 0;
text-align: center;
}
</style>