CHANGE_5point : ps

This commit is contained in:
VE10-Sanjeev 2024-06-01 05:30:03 +00:00
parent 5e16aa99f6
commit 2392cb082a
19 changed files with 2415 additions and 348 deletions

View File

@ -76,6 +76,8 @@ $routes->get('Customer/getReceiptDetails/(:num)', 'Customer::getReceiptDetails/$
$routes->post("insert_donor", "Customer::insert_donor");
$routes->post("insert_ajaxdonor", "Customer::insert_ajaxdonor");
$routes->get("delete_donor/(:any)", "Customer::delete_donor/$1");
$routes->get("export_Donor", "Customer::export_donor");
$routes->post("import_Donor", "Customer::import_donor");
#Donor group Routes (renamed as contributor group : 20/03/2024)
$routes->get('contributor_group/', 'Customer::donor_group');
@ -103,6 +105,8 @@ $routes->post("get_donor_details", "Invoice::get_donor_details");
$routes->post("save_invoice/", "Invoice::save_invoice/");
$routes->add('approve_invoice/(:num)', 'Invoice::approve_invoice/$1');
$routes->get('generate_invoice_pdf/(:num)', 'Invoice::generate_invoice_pdf/$1');
$routes->get("export_receipt", "Invoice::export_receipt");
$routes->post("import_receipt", "Invoice::import_receipt");
#Report Routes
$routes->match(['get','post'],'/general_inv_rp','Invoice::general_inv_rp');

View File

@ -85,6 +85,10 @@ abstract class BaseController extends Controller
$mergedData['browser_title']= $mergedData['company_name'] . ' | ' . $mergedData['company_short_name'] . ' ' . $mergedData['page_name'];
$mergedData['heading']= $mergedData['page_name'] === "Dashboard" ? 'Welcome to ' . $mergedData['company_name'] : "";
$reminder = $this->reminderMessage();
if((int)count($reminder['reminder']) > 0){
session()->setFlashdata('reminder', $reminder['reminder']);
}
echo view('template/header.php', $mergedData );
echo view('template/topbar.php', $mergedData);
echo view($viewpage, $mergedData);
@ -161,4 +165,41 @@ abstract class BaseController extends Controller
}
public function reminderMessage(){
helper('session');
$session_bid = get_business_id();
// $reminderMessage = "";
$reminderMessage = [];
// $c = 0; //count
$am = new AuthenticationModel();
$bwhere = ['business_id'=> $session_bid,'isactive'=> 1];
$getreminder = $am->getreminder($bwhere);
$reminderThreshold = 30; // Set the reminder days (e.g., 30 days before expiration)
if (!empty($getreminder['80G_vaildupto'])) {
$expirationDate1 = strtotime($getreminder['80G_vaildupto']);
$daysUntilExpiration1 = ($expirationDate1 - time()) / (60 * 60 * 24);
if ($daysUntilExpiration1 <= $reminderThreshold && $daysUntilExpiration1 >= 0) {
// $reminderMessage .= "Reminder: The 80G registration will expire in " . ceil($daysUntilExpiration1) . " days.";
array_push($reminderMessage, "Reminder: The 80G registration will expire in " . ceil($daysUntilExpiration1) . " days.");
// $c++;
}
}
if (!empty($getreminder['12AA_vaildupto'])) {
$expirationDate2 = strtotime($getreminder['12AA_vaildupto']);
$daysUntilExpiration2 = ($expirationDate2 - time()) / (60 * 60 * 24);
if ($daysUntilExpiration2 <= $reminderThreshold && $daysUntilExpiration2 >= 0) {
// $reminderMessage .= "<br> Reminder: The 12AA registration will expire in " . ceil($daysUntilExpiration2) . " days.";
array_push($reminderMessage, "Reminder: The 12AA registration will expire in " . ceil($daysUntilExpiration2) . " days.");
// $c++;
}
}
return ["reminder"=>$reminderMessage];//,"count"=>$c];
}
}

View File

@ -141,6 +141,9 @@ class Business extends BaseController
'org_reg_no' => $this->request->getPost('org_reg_no'),
'terms' => $this->request->getPost('bterms'),
'80G' => $this->request->getPost('80G'),
'12AA' => $this->request->getPost('12AA'),
'80G_vaildupto' => $this->request->getPost('80G_vaildupto'),
'12AA_vaildupto' => $this->request->getPost('12AA_vaildupto'),
'site_name' => $this->request->getPost('site_name'),
'site_title' => $this->request->getPost('site_title'),
'admin_email' => $this->request->getPost('admin_email'),
@ -228,7 +231,6 @@ class Business extends BaseController
if (!empty($missingValues)) {
$where = ['isactive' => 1, 'business_id'=>$bid];
$model->inactiveMissingBuinessBranchDetails($where, $missingValues);
echo
$this->logger->info("BuinessBranch: Inactived Missing Count = " . count($missingValues)." That Primary ID = ".implode(",",$BBprimaryid));
}
}

View File

@ -5,6 +5,12 @@ namespace App\Controllers;
use App\Models\CustomerModel;
use App\Models\SubscriptionModel;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Csv as ReaderCsv;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as ReaderXlsx;
class Customer extends BaseController
{
@ -510,16 +516,183 @@ class Customer extends BaseController
}
return redirect()->route('donor_group');
}
// Example in your controller
public function getReceiptDetails($donorId)
{
$CustomerModel = new CustomerModel();
// Fetch receipt details from the model based on $donorId
$receiptDetails = $CustomerModel->getReceiptDetailsByDonorId($donorId);
// Return the details as JSON
return $this->response->setJSON($receiptDetails);
}
public function getReceiptDetails($donorId)
{
$CustomerModel = new CustomerModel();
$receiptDetails = $CustomerModel->getReceiptDetailsByDonorId($donorId);
return $this->response->setJSON($receiptDetails);
}
public function export_donor()
{
helper('session');
$session_bid = get_business_id();
$CustomerModel = new CustomerModel();
$data = $CustomerModel->export_excel($session_bid);
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->mergeCells('B3:P3');
$sheet->getStyle('B3')->getAlignment()->setHorizontal('center');
$sheet->setTitle('Contributor details');
$headers = [
'B3' => 'Contributor Details',
'A5' => 'Contributor Name',
'B5' => 'Contributor Type',
'C5' => 'Organization Name',
'D5' => 'Organization Reg Details',
'E5' => 'Contact Number',
'F5' => 'Email Address',
'G5' => 'PAN',
'H5' => 'Aadhaar Number',
'I5' => 'Passport Number',
'J5' => 'Address',
'K5' => 'Country',
'L5' => 'State',
'M5' => 'City',
'N5' => 'Postal Code',
'O5' => 'CreatedBy',
'P5' => 'UpdatedBy',
'Q5' => 'CreatedAt',
'R5' => 'UpdatedAt',
'S5' => 'IsActive'
];
foreach ($headers as $cell => $value) {
$sheet->setCellValue($cell, $value);
$sheet->getStyle($cell)->getFont()->setSize($cell == 'B3' ? 14 : 12);
$sheet->getStyle($cell)->getFont()->setBold(true);
}
if ($data) {
$row = 6;
foreach ($data as $d) {
$col = 'A'; // Start from column A
foreach ($d as $value) {
$sheet->setCellValue($col . $row, $value);
$col++;
}
$row++;
}
}
ob_clean();
$writer = new Xlsx($spreadsheet);
$filename = 'exportDonor.xlsx';
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'. $filename .'"');
header('Cache-Control: max-age=0');
header('Expires: 0');
header('Pragma: public');
$writer->save('php://output');
exit;
}
public function import_donor()
{
$ip_address = $_SERVER['REMOTE_ADDR'];
helper('session');
$session_uid = get_logged_user_id();
$session_bid = get_business_id();
$json = []; // Arr - Json For Message FrontEnd
$list = []; // Arr - Store on DB
$path = ROOTPATH . 'public/import/donor/';
$fileNewName = "";
$file = $this->request->getFile('file');
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
$fileName = $file->getName();
if ($fileName !== "") {
if ($file->isValid() && !$file->hasMoved()) {
$newName = $file->getRandomName();
$file->move($path, $newName);
$fileNewName = $newName;
}
}
if (!$fileNewName) {
$json = ['error_message' => "Failed to upload file"];
return $this->response->setJSON($json);
}
$arr_file = explode('.', $fileName);
$extension = $arr_file[1];
if ('csv' == $extension) {
$reader = new ReaderCsv();
} else if ('xlsx' == $extension) {
$reader = new ReaderXlsx();
} else {
$json = ['error_message' => "Unsupported file type"];
return $this->response->setJSON($json);
}
if (!$reader) {
$json = ['error_message' => "Failed to initialize reader"];
return $this->response->setJSON($json);
}
$spreadsheet = $reader->load($path.$fileNewName);
$sheet_data = $spreadsheet->getActiveSheet()->toArray();
if(!empty($sheet_data)){
foreach ($sheet_data as $key => $val) {
if ($key != 0) { // key zero - header
$list[] = [
'business_id' => $session_bid,
'first_name' => $val[0],
'donor_type' => $val[1],
'org_name' => $val[2] ? $val[2] : null ,
'org_reg_details' => $val[3] ? $val[3] : null,
'mobile_no' => $val[4] ? $val[4] : null,
'email' => $val[5],
'pan_no' => $val[6],
'adhar_no' => $val[7],
'passport_no' => $val[8] ? $val[8] : null ,
'address' => $val[9],
'country' => $val[10],
'state' => $val[11],
'city' => $val[12],
'postal_code' => $val[13],
'created_by' => $session_uid,
'XL_file_name' => $fileNewName,
'ip_address' => $ip_address
];
}
}
}else{
$json = ['error_message' => "There is no record to import"];
return $this->response->setJSON($json);
}
if (count($list) > 0) {
$CustomerModel = new CustomerModel();
$result = $CustomerModel->bulkInsert($list);
($result) ? ['success_message' => "All Entries are imported successfully."]
: ['error_message' => "Something went wrong. Please try again."];
} else {
$json = ['error_message' => "No new record is found."];
}
return $this->response->setJSON($json);
}
}

View File

@ -15,6 +15,10 @@ use Mpdf\Mpdf;
use Dompdf\Dompdf;
use Dompdf\Options;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Csv as ReaderCsv;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as ReaderXlsx;
class Invoice extends BaseController
{
@ -509,7 +513,7 @@ class Invoice extends BaseController
$where = ['business_id' => (int)get_business_id()];
$currency_data = $model->setTable('business')->select('currency')->where($where)->findAll();
$terms_data = $this->BusinessModel->select('terms,signature')->where($where)->findAll();
$terms_data = $this->BusinessModel->select('terms,signature,80G,12AA,80G_vaildupto,12AA_vaildupto')->where($where)->findAll();
$data = $model->getInvoiceData($id);
// print_r($data);die;
// Check if data is empty
@ -544,6 +548,7 @@ class Invoice extends BaseController
}
$digits = strlen((string)$data[0]->amount);
$amount_in_words = $digits <= 9 ? $this->convertNumberToWords($data[0]->amount) : $data[0]->amount;
;
$html = view('invoice_pdf_template', [
'data' => $data[0],
'currency' => $data[0]->currency,
@ -551,7 +556,11 @@ class Invoice extends BaseController
'baseurl' => $baseurl,
'signature' => $data[0]->signature,
'staff_name' => $user[0]['first_name'] . ' ' .$user[0]['last_name'],
'Notes' => $terms_data[0]['terms']
'Notes' => $terms_data[0]['terms'],
'eightyG' => $terms_data[0]['80G'] ? '<div><strong style="float: left;">80G Registration No: </strong><span>'.$terms_data[0]['80G'].'</span><strong style="float: right;">Valid Upto : </strong><span>'. $terms_data[0]['80G_validupto'].'</span></div>'
: '',
'twelveAA' => $terms_data[0]['12AA'] ? '<div><strong style="float: left;">12AA Registration No: </strong><span>'.$terms_data[0]['12AA'].'</span><strong style="float: right;">Valid Upto : </strong><span>'. $terms_data[0]['12AA_validupto'].'</span></div>'
: '',
]);
// echo $html;die;
@ -679,6 +688,234 @@ class Invoice extends BaseController
return $this->response->setJSON(['data' => $data]);
}
public function export_receipt(){
helper('session');
$session_bid = (int)get_business_id();
$model = new InvoiceModel();
$where = ['business_id' => $session_bid];
$receipt = $model->where($where)->findAll();
$alldonors = $model->getData('donor', ['business_id' => $session_bid , 'isactive' => 1]);
$export = [];
if(!empty($receipt)){
foreach ($receipt as $key => $value) {
$export[$key]['receipt_number'] = $receipt[$key]['receipt_number'] ;
$export[$key]['receipt_date'] = (isset($receipt[$key]['receipt_date']) && !empty($receipt[$key]['receipt_date']) && strtotime($receipt[$key]['receipt_date']) !== false)
? date("d-m-Y", strtotime($receipt[$key]['receipt_date']))
: '-';
$export[$key]['receipt_type'] = $receipt[$key]['receipt_type'];
$export[$key]['donor'] = '';
foreach ($alldonors as $DonorData) {
if ($receipt[$key]['donor_id'] === $DonorData->donor_id) {
$suffix = "";
if ($receipt[$key]['receipt_type'] == "organization" && !empty($DonorData->org_name)) {
$suffix = !empty($DonorData->org_name) ? " (" . $DonorData->org_name . ")" : " (-)";
}
$export[$key]['donor'] = $DonorData->first_name . ' ' . $DonorData->last_name . $suffix;
break;
}
}
$currencySymbol = '';
switch (strtoupper($receipt[$key]['currency'])) {
case 'RS':
case 'INR': $currencySymbol = '₹'; break;
case 'USD': $currencySymbol = '$'; break;
case 'EUR': $currencySymbol = '€'; break;
default: $currencySymbol = ''; break;
}
$export[$key]['amount'] = $currencySymbol . ' ' . $receipt[$key]['amount'];
$paymentMode = '';
switch (strtoupper($receipt[$key]['payment_mode'])) {
case 'DEBIT': $paymentMode = 'Debit Card'; break;
case 'CREDIT': $paymentMode = 'Credit Card'; break;
case 'CASH': $paymentMode = 'Cash'; break;
case 'UPI': $paymentMode = 'UPI'; break;
default: $paymentMode = $receipt[$key]['payment_mode']; break;
}
$status = '';
switch (strtoupper($receipt[$key]['receipt_header'])) {
case 'TEMPORARY RECEIPT ': $status = 'Draft'; break;
case 'RECEIPT': $status = 'Completed'; break;
case 'REJECTED': $status = 'Rejected'; break;
default: $status = $receipt[$key]['receipt_header']; break;
}
$export[$key]['status'] = $status;
$export[$key]['payment_mode'] = $paymentMode;
$export[$key]['payment_ref_no'] = $receipt[$key]['payment_ref_no'];
$export[$key]['notes'] = $receipt[$key]['notes'] == null ? '-' : $receipt[$key]['notes'];
$export[$key]['reason'] = ($receipt[$key]['reason'] == null) ? '-' :$receipt[$key]['reason'];
$export[$key]['created_by'] = $this->UserModel->where('user_id', $receipt[$key]['created_by'])->get()->getRow()->first_name;// 2
$export[$key]['updated_by'] = (isset($receipt[$key]['updated_by']) && !empty($receipt[$key]['updated_by']) && $receipt[$key]['updated_by'] !== null)
? $this->UserModel->where('user_id', $receipt[$key]['updated_by'])->get()->getRow()->first_name
: '-';// 2
$export[$key]['created_on'] = (isset($receipt[$key]['created_on']) && !empty($receipt[$key]['created_on']) && strtotime($receipt[$key]['created_on']) !== false)
? date("d-m-Y", strtotime($receipt[$key]['created_on']))
: '-';
$export[$key]['updated_on'] = (isset($receipt[$key]['updated_on']) && !empty($receipt[$key]['updated_on']) && strtotime($receipt[$key]['updated_on']) !== false)
? date("d-m-Y", strtotime($receipt[$key]['updated_on']))
: '-';
$export[$key]['isactive'] = (int)$receipt[$key]['isactive'] == 1 ? 'Active' : 'Inactive';
}
}
$this->fetch_receipt($export);
}
public function fetch_receipt($export){
$spreadsheet = new Spreadsheet(); // instantiate Spreadsheet
$sheet = $spreadsheet->getActiveSheet();
$sheet->mergeCells('B3:R3');
$sheet->getStyle('B3')->getAlignment()->setHorizontal('center');
$sheet->setTitle('Receipt details');
$headers = [
'B3' => 'Receipt Details',
'A5' => 'Receipt Number',
'B5' => 'Receipt Date',
'C5' => 'Receipt Type',
'D5' => 'Contributor Name',
'E5' => 'Amount',
'F5' => 'Status',
'G5' => 'Payment Mode',
'H5' => 'Payment Ref no',
'I5' => 'Notes',
'J5' => 'Reason',
'K5' => 'CreatedBy',
'L5' => 'UpdatedBy',
'M5' => 'CreatedAt',
'N5' => 'UpdatedAt',
'O5' => 'IsActive'
];
foreach ($headers as $cell => $value) {
$sheet->setCellValue($cell, $value);
$sheet->getStyle($cell)->getFont()->setSize($cell == 'B3' ? 14 : 12);
$sheet->getStyle($cell)->getFont()->setBold(true);
}
if($export){
$row = 6; // Start from row 6
foreach ($export as $d) {
$col = 'A'; // Start from column A
foreach ($d as $value) {
$sheet->setCellValue($col . $row, $value);
$col++;
}
$row++;
}
}
// Clear the output buffer to prevent any other output
ob_clean();
$writer = new Xlsx($spreadsheet);
$filename = 'exportReceipt.xlsx';
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'. $filename .'"');
header('Cache-Control: max-age=0');
header('Expires: 0');
header('Pragma: public');
$writer->save('php://output');
exit;
}
public function import_receipt()
{
$ip_address = $_SERVER['REMOTE_ADDR'];
$InvoiceModel = new InvoiceModel();
helper('session');
$session_uid = get_logged_user_id();
$session_bid = get_business_id();
$json = []; // Arr - Json For Message FrontEnd
$list = []; // Arr - Store on DB
$path = ROOTPATH . 'public/import/receipt/';
$fileNewName = "";
$file = $this->request->getFile('file');
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
$fileName = $file->getName();
if ($fileName !== "") {
if ($file->isValid() && !$file->hasMoved()) {
$newName = $file->getRandomName();
$file->move($path, $newName);
$fileNewName = $newName;
}
}
if (!$fileNewName) {
$json = ['error_message' => "Failed to upload file"];
return $this->response->setJSON($json);
}
$arr_file = explode('.', $fileName);
$extension = $arr_file[1];
if ('csv' == $extension) {
$reader = new ReaderCsv();
} else if ('xlsx' == $extension) {
$reader = new ReaderXlsx();
} else {
$json = ['error_message' => "Unsupported file type"];
return $this->response->setJSON($json);
}
if (!$reader) {
$json = ['error_message' => "Failed to initialize reader"];
return $this->response->setJSON($json);
}
$spreadsheet = $reader->load($path.$fileNewName);
$sheet_data = $spreadsheet->getActiveSheet()->toArray();
if(!empty($sheet_data)){
foreach ($sheet_data as $key => $val) {
if ($key != 0) { // key zero - header
$list[] = [
'business_id' => $session_bid,
'first_name' => $val[0],
'donor_type' => $val[1],
'org_name' => $val[2] ? $val[2] : null ,
'org_reg_details' => $val[3] ? $val[3] : null,
'mobile_no' => $val[4] ? $val[4] : null,
'email' => $val[5],
'pan_no' => $val[6],
'adhar_no' => $val[7],
'passport_no' => $val[8] ? $val[8] : null ,
'address' => $val[9],
'country' => $val[10],
'state' => $val[11],
'city' => $val[12],
'postal_code' => $val[13],
'created_by' => $session_uid,
'XL_file_name' => $fileNewName,
'ip_address' => $ip_address
];
}
}
}else{
$json = ['error_message' => "There is no record to import"];
return $this->response->setJSON($json);
}
if (count($list) > 0) {
$result = $InvoiceModel->bulkInsert($list);
($result) ? ['success_message' => "All Entries are imported successfully."]
: ['error_message' => "Something went wrong. Please try again."];
} else {
$json = ['error_message' => "No new record is found."];
}
return $this->response->setJSON($json);
}
}

View File

@ -30,5 +30,17 @@ class AuthenticationModel extends Model
return $query->getResultArray();
}
public function getreminder($bwhere){
$query = $this->db->table('business');
$result = $query->where($bwhere)->get()->getResultArray();
if (count($result) > 0) {
$reminder = $result[0];
} else {
$reminder = [];
}
return $reminder;
}
}

View File

@ -9,7 +9,7 @@ class BusinessModel extends Model
{
protected $table = 'business';
protected $primaryKey = 'business_id';
protected $allowedFields = ['business_id','title','email','mobile_no','terms','address','city','state','postal_code' ,'business_logo','isactive', 'pan_no', 'org_reg_no', '80G', 'signature','favicon','start_no','left_pad','prefix_format','site_name','site_title','site_mobile','site_info','admin_email','terms_service','footer_about','copyright','pagination_limit','about_info','currency'];
protected $allowedFields = ['business_id','title','email','mobile_no','terms','address','city','state','postal_code' ,'business_logo','isactive', 'pan_no', 'org_reg_no', '80G', 'signature','favicon','start_no','left_pad','prefix_format','site_name','site_title','site_mobile','site_info','admin_email','terms_service','footer_about','copyright','pagination_limit','about_info','currency','12AA','80G_vaildupto','12AA_vaildupto'];
public function insertBusiness($data)
{

View File

@ -10,7 +10,7 @@ class CustomerModel extends Model
protected $table = 'donor';
protected $primaryKey = 'donor_id ';
// protected $allowedFields = ['donor_id ','first_name','city','last_name','email','mobile_no','country','state','postal_code' ,'address','profile_picture','date_of_birth','gender','mode','isactive','business_id'];
protected $allowedFields = ['donor_id ','first_name','city','last_name','email','mobile_no','country','state','postal_code' ,'address','org_name','date_of_birth','pan_no','adhar_no','org_reg_details','donor_type','isactive','business_id','created_by','updated_by'];
protected $allowedFields = ['donor_id ','first_name','city','last_name','email','mobile_no','country','state','postal_code' ,'address','org_name','date_of_birth','pan_no','adhar_no','org_reg_details','donor_type','isactive','business_id','created_by','updated_by','XL_file_name','ip_address'];
public function insertCustomer($data)
{
@ -81,7 +81,27 @@ public function getData($table, $where = null)
return $query->get()->getResult();
}
function export_excel($business_id)
{
$builder = $this->db->table('donor')
->select('CONCAT_WS(" ", donor.first_name, donor.last_name) AS full_name')
->select('donor.donor_type,donor.org_name,donor.org_reg_details,donor.mobile_no,donor.email,donor.pan_no,donor.adhar_no,donor.passport_no,donor.address,donor.country,donor.state,donor.city,donor.postal_code')
->select('CONCAT_WS(" ", creator.first_name, creator.last_name) AS creator_name')
->select('CONCAT_WS(" ", updater.first_name, updater.last_name) AS updater_name')
->select('IFNULL(DATE_FORMAT(donor.created_on, "%d-%m-%Y"), "-") AS formatted_created_on')
->select('IFNULL(DATE_FORMAT(donor.updated_on, "%d-%m-%Y"), "-") AS formatted_updated_on')
->select('CASE WHEN donor.isactive = 1 THEN "Active" ELSE "Inactive" END AS active_status', false)
->join('users as creator', ' donor.created_by = creator.user_id', 'left')
->join('users as updater', ' donor.updated_by = updater.user_id', 'left')
->where('donor.business_id', $business_id);
$query = $builder->get();
return $query->getResultArray();
}
public function bulkInsert($data) {
return $this->db->table('donor')->insertBatch($data);
}
}
?>

View File

@ -42,4 +42,25 @@ protected $allowedFields = ['receipt_id', 'receipt_number', 'donor_id','notes','
}
function export_excel($business_id)
{
$builder = $this->db->table('donor')
->select('CONCAT_WS(" ", donor.first_name, donor.last_name) AS full_name')
->select('donor.donor_type,donor.org_name,donor.org_reg_details,donor.mobile_no,donor.email,donor.pan_no,donor.adhar_no,donor.passport_no,donor.address,donor.country,donor.state,donor.city,donor.postal_code')
->select('CONCAT_WS(" ", creator.first_name, creator.last_name) AS creator_name')
->select('CONCAT_WS(" ", updater.first_name, updater.last_name) AS updater_name')
->select('IFNULL(DATE_FORMAT(donor.created_on, "%d-%m-%Y"), "-") AS formatted_created_on')
->select('IFNULL(DATE_FORMAT(donor.updated_on, "%d-%m-%Y"), "-") AS formatted_updated_on')
->select('CASE WHEN donor.isactive = 1 THEN "Active" ELSE "Inactive" END AS active_status', false)
->join('users as creator', ' donor.created_by = creator.user_id', 'left')
->join('users as updater', ' donor.updated_by = updater.user_id', 'left')
->where('donor.business_id', $business_id);
$query = $builder->get();
return $query->getResultArray();
}
public function bulkInsert($data) {
return $this->db->table('donor')->insertBatch($data);
}
}

View File

@ -79,6 +79,28 @@
<div class="invalid-feedback"> Please provide. </div>
</div>
</div>
<?php if($loged_user === 'sadmin'){ ?>
<div class="form-row">
<div class="form-group col-md-3">
<label for="80G" class="col-form-label">80G</label>
<input type="text" class="form-control" id="80G" name="80G" value="<?= isset($organzations['80G']) ? htmlspecialchars($organzations['80G']) : '' ?>" placeholder="80G Tax Free / Registration number" onchange="checkValidityAndSetRequired()"/>
</div>
<div class="form-group col-md-3">
<label for="80G_vaildupto" class="col-form-label">80G Vaild Upto<span class="text-danger 80G-text-danger" style="display:none;">*</span></label>
<input type="date" class="form-control" id="80G_vaildupto" name="80G_vaildupto" value="<?= !empty($organzations['80G_vaildupto']) ? htmlspecialchars($organzations['80G_vaildupto']) : null ?>" min="<?= date('Y-m-d') ?>">
</div>
<div class="form-group col-md-3">
<label for="12AA" class="col-form-label">12AA</label>
<input type="text" class="form-control" id="12AA" name="12AA" value="<?= isset($organzations['12AA']) ? htmlspecialchars($organzations['12AA']) : null ?>" placeholder="12AA Tax Free / Registration number" onchange="checkValidityAndSetRequired()"/>
</div>
<div class="form-group col-md-3">
<label for="12AA_vaildupto" class="col-form-label">12AA Vaild Upto<span class="text-danger 12AA-text-danger" style="display:none;">*</span></label>
<input type="date" class="form-control" id="12AA_vaildupto" name="12AA_vaildupto" value="<?= !empty($organzations['12AA_vaildupto']) ? htmlspecialchars($organzations['12AA_vaildupto']) : null ?>" min="<?= date('Y-m-d') ?>">
</div>
</div>
<?php } ?>
<div class="form-row">
<div class="form-group col-md-4">
<label for="bmobile" class="col-form-label">Organization Mobile Number<span class="text-danger">*</span></label>
@ -86,18 +108,11 @@
<span id="bmobileValidationMessage"></span>
<div class="invalid-feedback"> Please provide. </div>
</div>
<div class="form-group col-md-4">
<div class="form-group col-md-8">
<label for="baddress" class="col-form-label">Organization Address<span class="text-danger">*</span></label>
<input type="text" class="form-control" name="baddress" value="<?= isset($organzations['address']) ? $organzations['address'] : '' ?>" placeholder="Address (eg : 1234 Main St)" required />
<div class="invalid-feedback"> Please provide. </div>
</div>
<?php if (isset($organzations['loged_user'])) { ?>
<div class="form-group col-md-4">
<label for="80G" class="col-form-label">80G</label>
<input type="text" class="form-control" name="80G" value="<?= isset($organzations['80G']) ? $organzations['80G'] : '' ?>" placeholder="80G Tax Free" />
</div>
<?php } ?>
</div>
<div class="form-row">
<div class="form-group col-md-4">
@ -394,13 +409,34 @@
</div> <!-- end col-->
</div><!-- end row -->
<script>
function checkValidityAndSetRequired() {
if (document.getElementById('80G').value.trim() !== "") {
document.getElementById('80G_vaildupto').setAttribute('required', 'required');
} else {
document.getElementById('80G_vaildupto').removeAttribute('required');
}
if (document.getElementById('12AA').value.trim() !== "") {
document.getElementById('12AA_vaildupto').setAttribute('required', 'required');
} else {
document.getElementById('12AA_vaildupto').removeAttribute('required');
}
}
document.getElementById('myForm').addEventListener('submit', function(event) {
var form = event.target;
var role = <?php echo json_encode($loged_user); ?>;
if(role === 'sadmin'){checkValidityAndSetRequired();}
if (form.checkValidity() === false) {
form.reportValidity(); // Display validation error messages
event.preventDefault(); // Prevent form submission if it's not valid
var invalidFields = form.querySelectorAll(':invalid');
if (invalidFields.length > 0) {
invalidFields[0].focus();
}
$('#submitBtn').prop('disabled', false);
} else {

View File

@ -79,17 +79,23 @@
<label for="dob" class="col-form-label">Date Of Birth</label>
<input type="date" class="form-control" name="dob" value="" placeholder="Date Of Birth" />
</div> -->
<div class="form-group col-md-4">
<label for="csname" class="col-form-label"><span class="contactPerson">Organization </span> PAN Number <i class="text-danger contactPerson"> *</i> </label>
<input type="text" class="form-control" id="pan_no"name="pan_no" required value="<?= isset($customer['pan_no']) ? $customer['pan_no'] : '' ?>" placeholder="PAN Number" onchange="checkExisting(this,'pan_no','pan_no')"/>
<span id="panValidationMessage"></span>
<span id="errorMessage" style="color: red;"></span>
</div>
<div class="form-group col-md-4" id="adhar_no_individual">
<label for="csname" class="col-form-label"><span class="contactPerson"> </span>Aadhaar Number</label>
<input type="text" class="form-control" id="adhar_no" name="adhar_no" value="<?= isset($customer['adhar_no']) ? $customer['adhar_no'] : '' ?>" placeholder="Aadhaar Number" onchange="checkExisting(this,'adhar_no','adhar_no')"/>
<span id="adharValidationMessage"></span>
</div>
<div class="form-group col-md-4" id="passport_no_individual">
<label for="csname" class="col-form-label"><span class="contactPerson"> </span>Passport Number <i class="text-danger contactPerson"> *</i> </label>
<input type="text" class="form-control" id="passport_no"name="passport_no" value="<?= isset($customer['passport_no']) ? $customer['passport_no'] : '' ?>" placeholder="Passport Number" onchange="checkExisting(this,'passport_no','passport_no')"/>
<span id="passportValidationMessage"></span>
<span id="errorMessage" style="color: red;"></span>
</div>
</div>
@ -165,10 +171,90 @@
<script>
function checkValidityAndSetRequired() {
var type = document.getElementById('DonorType').value;
var panInput = document.getElementById('pan_no');
var passportInput = document.getElementById('passport_no');
var errorMessage = document.getElementById('errorMessage');
if (type === 'organization') {
panInput.setAttribute('required', 'required');
passportInput.removeAttribute('required');
errorMessage.textContent = ""; // Clear any existing error message
} else if (type === 'individual') {
if (panInput.value === "" && passportInput.value === "") {
// If both PAN and Passport are empty, require either one
panInput.setAttribute('required', 'required');
passportInput.setAttribute('required', 'required');
errorMessage.textContent = "Either PAN or Passport is required.";
} else {
// If either PAN or Passport is filled, reset requirements
panInput.removeAttribute('required');
passportInput.removeAttribute('required');
errorMessage.textContent = ""; // Clear error message
}
} else {
// For other type, set PAN or Passport as required based on the default logic
panInput.removeAttribute('required');
passportInput.removeAttribute('required');
errorMessage.textContent = ""; // Clear any existing error message
}
}
document.getElementById('myForm').addEventListener('submit', function(event) {
var form = event.target;
checkValidityAndSetRequired();
var invalidFields = form.querySelectorAll('.is-invalid');
console.log("*** Invalid Fields ***");
invalidFields.forEach(function(field) {
console.log(field);
});
if (invalidFields.length > 0) {
invalidFields[0].focus();
console.log("**"+invalidFields[0]);
}
if (form.checkValidity() === false) {
var type = document.getElementById('DonorType').value;
var aadharValue = document.getElementById('adhar_no').value.trim();
var panValue = document.getElementById('pan_no').value.trim();
var passportValue = document.getElementById('passport_no').value.trim();
if (type === 'organization') {
if (panValue !== '') {
if (!validatePANNumber(panValue)) {
event.preventDefault(); // Prevent form submission if it's not valid
$('#submitBtn').prop('disabled', false);
}
}
}
if (type === 'individual') {
if (aadharValue !== '') {
if (!validateAdharNumber(aadharValue)) {
event.preventDefault(); // Prevent form submission
return;
}
}
if (panValue !== '') {
if (!validatePANNumber(panValue)) {
event.preventDefault(); // Prevent form submission
return;
}
}
if (passportValue !== '') {
if (!validatePassport(passportValue)) {
event.preventDefault(); // Prevent form submission
return;
}
}
}
if (form.checkValidity() === true) {
form.reportValidity(); // Display validation error messages
event.preventDefault(); // Prevent form submission if it's not valid
@ -232,6 +318,10 @@
$('#pan_no').on('input', function(){
validatePANNumber($(this).val());
});
$('#passport_no').on('input', function(){
validatePassport($(this).val());
});
function updateDonorTypeFields() {
let DonorType = $('#DonorType').val();
@ -242,6 +332,7 @@
$('#org_reg').show();
$('.contactPerson').show();
$('#adhar_no_individual').hide();
$('#passport_no_individual').hide();
$('#org_name_field').prop('required', true);
$('#org_reg_details').prop('required', true);
$('#pan_no').prop('required', true);
@ -249,6 +340,7 @@
// Individual type selected
else {
$('#adhar_no_individual').show();
$('#passport_no_individual').show();
$('#org_name').hide();
$('#org_reg').hide();
$('.contactPerson').hide();
@ -261,20 +353,49 @@
if (!adharPattern.test(adharNumber)) {
$('#adhar_no').addClass('is-invalid');
return false;
} else {
$('#adhar_no').removeClass('is-invalid');
return true;
}
}
function validatePANNumber(panNumber) {
let panPattern = /^[A-Z]{5}[0-9]{4}[A-Z]$/;
if (!panPattern.test(panNumber)) {
$('#pan_no').addClass('is-invalid');
return false;
} else {
$('#pan_no').removeClass('is-invalid');
return true;
}
}
function validatePassport(passport) {
// Check length (8 to 12 characters)
if (passport.length < 8 || passport.length > 12) {
$('#passport_no').addClass('is-invalid');
return false;
}
// Check first character for type of passport (P, D, S)
const type = passport.charAt(0);
if (!['P', 'D', 'S'].includes(type)) {
$('#passport_no').addClass('is-invalid');
return false;
}
// Check that the rest of the characters are alphanumeric
const rest = passport.slice(1);
const alphanumericRegex = /^[a-zA-Z0-9]+$/;
if (!alphanumericRegex.test(rest)) {
$('#passport_no').addClass('is-invalid');
return false;
}
$('#passport_no').removeClass('is-invalid');
return true;
}
});
</script>
<script>
@ -322,6 +443,8 @@
spanid = "mobileValidationMessage"; break;
case 'adhar_no' :
spanid = "adharValidationMessage"; break;
case 'passport_no':
spanid = "passportValidationMessage"; break;
}
var validationMessage = document.getElementById(spanid);
var value = input.value.trim();
@ -339,7 +462,7 @@
},
success: function(response) {
console.log("check existing " + elementId + "--" + response['data']['message']);
console.log("check existing " + elementid + "--" + response['data']['message']);
validationMessage.style.display = response['data']['status'] ? 'block' : 'none';
validationMessage.innerText = response['data']['message'];
validationMessage.style.color = "red";
@ -347,7 +470,7 @@
if (response['data']['status']) input.value = '';
},
error: function(xhr, status, error) {
console.error("check existing " + elementId + " -- " + status + ": " + error);
console.error("check existing " + elementid + " -- " + status + ": " + error);
}
});
}

View File

@ -4,6 +4,9 @@
<div class="card-body">
<div class="float-right">
<a href="<?= base_url() . "new_Donor/0"; ?>" class="btn btn-primary"><i class="ri-map-pin-user-fill"></i> Add Contributor </a>
<a href="<?= base_url() . "export_Donor"; ?>" class="btn btn-info"><i class="ri-file-excel-2-fill"></i> Export Contributor </a>
<!-- <a href="<?= base_url() . "import_Donor"; ?>" class="btn btn-secondary"><i class="ri-file-excel-2-line"></i> Import Contributor </a> -->
<button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#standard-modal"><i class="ri-file-excel-2-line"></i> Import Contributor</button>
</div><!-- end col-->
<br>
<h4 class="header-title mb-3"><?= $page_name; ?></h4>
@ -210,4 +213,74 @@ $(document).on('click', '.view-receipts', function(e) {
});
}
});
</script>
<div id="standard-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="standard-modalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="standard-modalLabel">Import Contributor</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<form id="form-upload">
<div class="modal-body">
<div class="form-group col-md-12">
<label for="control-label">Choose File <small class="text-danger">*</small></label>
<input type="file" class="form-control" style="border: 0px !important; " id="file" name="file" placeholder="csv,xlsx files" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
application/vnd.ms-excel" required />
<span class="help-block"><small>Upload xlsx or csv file only.</small></span>
</div>
<div class="form-group">
<div class="text-center">
<div class="upload-loader" style="display: none; ">
<i class="fa fa-spinner fa-spin"></i> <small>Please wait ...</small>
</div>
<div class="result"></div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" id="btn-upload">Upload</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script>
$(document).ready(function(){
$('#form-upload').on('submit', function(event) {
event.preventDefault(); // Prevent default form submission
var formData = new FormData($('#form-upload')[0]);
$.ajax({
type: "POST",
url: "<?= base_url() . 'import_Donor' ?>",
data: formData,
contentType: false,
processData: false,
beforeSend: function() {
$("#btn-upload").prop('disabled', true);
$(".upload-loader").show();
},
success: function(result) {
$("#btn-upload").prop('disabled', false);
if($.isEmptyObject(result.error_message)) {
$(".result").html(result.success_message).css("color", "green");
} else {
$(".result").html(result.error_message).css("color", "red");
}
$("#form-upload")[0].reset();
$(".upload-loader").hide();
setTimeout(function() {
$("#standard-modal").dialog("close");
refreshPage();
}, 10000); // 10000 milliseconds = 10 seconds
}
});
});
});
</script>

View File

@ -1,3 +1,21 @@
<?php if (session()->getFlashdata('reminder')) :
$messages = session()->getFlashdata('reminder'); ?>
<div class="alert remainder alert-info alert-dismissible fade show" role="alert">
<div class="row">
<div class="col-md-1" style="display: flex; align-items: center; justify-content: center;">
<i class="fas fa-duotone fa-bell fa-2x" style="color: darksalmon;"></i>
</div>
<div class="col-md-10">
<?php $allMessages = implode('<br>', $messages); ?>
<?=$allMessages?>
</div>
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<?php endif; ?>
<?php if ($loggedin_person_role === 'auditor' || $loggedin_person_role === 'admin') : ?>
<div class="row justify-content-center">
<div class="col-xl-3 col-md-6">

View File

@ -16,6 +16,8 @@
<div id="addDonorBtn">
<?php if(get_user_role() != 'accounts') { ?>
<a href="<?= base_url() . "new_receipt/0"; ?>" class="btn btn-primary"><i class="ri-currency-line"></i> Add Receipt </a>
<a href="<?= base_url() . "export_receipt"; ?>" class="btn btn-info"><i class="ri-file-excel-2-fill"></i> Export Receipt </a>
<!-- <button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#import-receipt-modal"><i class="ri-file-excel-2-line"></i> Import Receipt</button> -->
<?php } ?>
</div>
</div>
@ -68,14 +70,18 @@
<td><?= $row['receipt_number']; ?></td>
<td><?= date("d-m-Y", strtotime($row['receipt_date'])); ?> </td>
<td><?= $row['created_name']; ?></td>
<td>
<?php foreach ($Donors as $DonorData) :
$suffix = "";
if($row['receipt_type'] == "organization"){ $suffix = " (".$DonorData->org_name.")"; } ?>
<?= $row['donor_id'] === $DonorData->donor_id ? $DonorData->first_name . $DonorData->last_name.$suffix : ''; ?>
<?php
endforeach; ?>
</td>
<?php $donor = '';
foreach ($Donors as $DonorData) {
if ($row['donor_id'] === $DonorData->donor_id) {
$suffix = "";
if ($row['receipt_type'] == "organization" ) {
$suffix = !empty($DonorData->org_name) ? " (" . $DonorData->org_name . ")" : " (-)";
}
$donor = $DonorData->first_name . ' ' . $DonorData->last_name . $suffix;
break;
}
} ?>
<td><?= $donor; ?></td>
<td id="<?= $row['receipt_id'] ?>">
<?php
@ -390,4 +396,76 @@ $(document).ready(function() {
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div><!-- /.modal -->
<!-- import modal -->
<div id="import-receipt-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="import-receipt-label" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="import-receipt-label">Import Receipt</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<form id="form-upload">
<div class="modal-body">
<div class="form-group col-md-12">
<label for="control-label">Choose File <small class="text-danger">*</small></label>
<input type="file" class="form-control" style="border: 0px !important; " id="file" name="file" placeholder="csv,xlsx files" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
application/vnd.ms-excel" required />
<span class="help-block"><small>Upload xlsx or csv file only.</small></span>
</div>
<div class="form-group">
<div class="text-center">
<div class="upload-loader" style="display: none; ">
<i class="fa fa-spinner fa-spin"></i> <small>Please wait ...</small>
</div>
<div class="result"></div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" id="btn-upload">Upload</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script>
$(document).ready(function(){
$('#form-upload').on('submit', function(event) {
event.preventDefault(); // Prevent default form submission
var formData = new FormData($('#form-upload')[0]);
$.ajax({
type: "POST",
url: "<?= base_url() . 'import_receipt' ?>",
data: formData,
contentType: false,
processData: false,
beforeSend: function() {
$("#btn-upload").prop('disabled', true);
$(".upload-loader").show();
},
success: function(result) {
$("#btn-upload").prop('disabled', false);
if($.isEmptyObject(result.error_message)) {
$(".result").html(result.success_message).css("color", "green");
} else {
$(".result").html(result.error_message).css("color", "red");
}
$("#form-upload")[0].reset();
$(".upload-loader").hide();
setTimeout(function() {
$("#import-receipt-modal").dialog("close");
refreshPage();
}, 10000); // 10000 milliseconds = 10 seconds
}
});
});
});
</script>

View File

@ -105,7 +105,10 @@
<tr>
</tr><td style="width: 30.5118%; height: 18px;"></td></tr>
<tr style="height: 18px;">
<td style="width: 100%; height: 18px; text-align: center;border: none;padding:30px 0px 0px 0px;font-size: 9px;border-top: 1px solid #ccc;" colspan="2"><strong>Note:</strong>&nbsp;<?= $Notes ?></td>
<td style="width: 100%; text-align: center;border: none;padding:30px 0px 0px 0px;font-size: 9px;border-top: 1px solid #ccc;" colspan="2">
<?php if($eightyG != "") { ?> <?= $eightyG ?><br> <?php } ?>
<?php if($twelveAA != "") { ?> <?= $twelveAA ?><br> <?php } ?>
<strong>Note:</strong>&nbsp;<?= $Notes ?></td>
</tr>
</tbody>
</table>

View File

@ -147,7 +147,10 @@
// Automatically close both success and error messages after 5 seconds (5000 milliseconds)
setTimeout(function() {
document.querySelectorAll('.alert').forEach(function(alert) {
alert.classList.add('d-none');
// alert.classList.add('d-none');
if (!alert.classList.contains('remainder')) { // Exclude alerts with the class "remainder"
alert.classList.add('d-none');
}
});
}, 5000); // Adjust the time (in milliseconds) as needed

View File

@ -14,7 +14,15 @@
</form>
</div>
</li>
<!-- <li class="dropdown d-none d-lg-inline-block">
<a class="nav-link dropdown-toggle waves-effect waves-light" href="#" role="button" aria-haspopup="false" aria-expanded="false">
<?php $reminder_count = session()->getFlashdata('count');
if($reminder_count>1){ ?>
<span class="badge badge-danger rounded-circle noti-icon-badge"><?php echo $reminder_count; ?></span>
<?php }?>
</a>
</li> -->
<!-- <li class="dropdown d-none d-lg-inline-block">
<a class="nav-link dropdown-toggle arrow-none waves-effect waves-light" data-toggle="fullscreen" href="#">
<i class="fe-maximize noti-icon"></i>
@ -56,6 +64,60 @@
</div>
</li>
<li class="dropdown notification-list topbar-dropdown">
<!-- <a class="nav-link dropdown-toggle waves-effect waves-light" data-toggle="dropdown" href="#" role="button" aria-haspopup="false" aria-expanded="false">
<i class="fe-bell noti-icon"></i>
<?php $reminder_messages = session()->getFlashdata('reminder');
$reminder_count = count($reminder_messages);
if((int)$reminder_count > 0){ ?>
<span class="badge badge-danger rounded-circle noti-icon-badge"><?php echo $reminder_count; ?></span>
<?php } ?>
</a> -->
<div class="dropdown-menu dropdown-menu-right dropdown-lg">
<!-- item-->
<div class="dropdown-item noti-title">
<h5 class="m-0">
<!-- <span class="float-right">
<a href="" class="text-dark">
<small>Clear All</small>
</a>
</span>Notification -->
Reminder
</h5>
</div>
<div class="noti-scroll" data-simplebar>
<?php
$reminder_messages = session()->getFlashdata('reminder');
if(!empty($reminder_messages)): ?>
<?php foreach ($reminder_messages as $message): ?>
<a href="javascript:void(0);" class="dropdown-item notify-item active">
<div class="notify-icon bg-soft-primary text-primary">
<i class="mdi mdi-comment-processing-outline"></i>
</div>
<p class="notify-details"></p>
<p class="text-muted mb-0 user-msg">
<small class="text-muted"><?=$message?></small>
</p>
</a>
<?php endforeach; ?>
<?php else: ?>
<a href="javascript:void(0);" class="dropdown-item notify-item active">
<small class="text-muted"><center><?php echo "No Reminder Message Available :) "?></center></small>
</a>
<?php endif; ?>
</div>
<!-- All-->
<a href="javascript:void(0);" class="dropdown-item text-center text-primary notify-item notify-all">
<!-- View all
<i class="fe-arrow-right"></i> -->
</a>
</div>
</li>
<li class="dropdown notification-list topbar-dropdown">
<a class="nav-link dropdown-toggle nav-user mr-0 waves-effect waves-light" data-toggle="dropdown" href="#" role="button" aria-haspopup="false" aria-expanded="false">

View File

@ -12,6 +12,7 @@
"dompdf/dompdf": "^2.0",
"laminas/laminas-escaper": "^2.9",
"mpdf/mpdf": "^8.2",
"phpoffice/phpspreadsheet": "^2.0",
"psr/log": "^1.1"
},
"require-dev": {

1778
composer.lock generated

File diff suppressed because it is too large Load Diff