From ec8574993b878f3a5ca7805aba347e2b44e2676a Mon Sep 17 00:00:00 2001 From: VE10-Sanjeev Date: Tue, 18 Jun 2024 06:37:52 +0000 Subject: [PATCH] CHANGE_Bug Fix : ps --- app/Controllers/Customer.php | 142 +++++++++++++--------- app/Controllers/Invoice.php | 11 +- app/Controllers/Notifications.php | 7 +- app/Models/NotificationModel.php | 6 +- app/Views/audit_history.php | 2 +- app/Views/business_form.php | 45 ++++--- app/Views/customer_form.php | 162 +++++++++++++------------- public/import/sample.xlsx | Bin 6791 -> 0 bytes public/import/sample_contributor.xlsx | Bin 6791 -> 6980 bytes 9 files changed, 220 insertions(+), 155 deletions(-) delete mode 100644 public/import/sample.xlsx diff --git a/app/Controllers/Customer.php b/app/Controllers/Customer.php index 0e3b7c4..c9d54f0 100644 --- a/app/Controllers/Customer.php +++ b/app/Controllers/Customer.php @@ -610,14 +610,13 @@ class Customer extends BaseController public function import_donor() { - - $ip_address = $_SERVER['REMOTE_ADDR']; + $ip_address = $_SERVER['REMOTE_ADDR']; helper('session'); $session_uid = get_logged_user_id(); $session_bid = get_business_id(); - $json = []; // Arr - Json For Message FrontEnd + $response = []; // Arr - response For Message FrontEnd $list = []; // Arr - Store on DB $path = ROOTPATH . 'public/import/donor/'; $fileNewName = ""; @@ -627,7 +626,6 @@ class Customer extends BaseController if (!is_dir($path)) { mkdir($path, 0777, true); } - $fileName = $file->getName(); if ($fileName !== "") { if ($file->isValid() && !$file->hasMoved()) { @@ -636,10 +634,9 @@ class Customer extends BaseController $fileNewName = $newName; } } - if (!$fileNewName) { - $json = ['error_message' => "Failed to upload file"]; - return $this->response->setJSON($json); + $response = ['error_message' => "Failed to upload file"]; + return $this->response->setJSON($response); } $arr_file = explode('.', $fileName); @@ -649,59 +646,100 @@ class Customer extends BaseController } else if ('xlsx' == $extension) { $reader = new ReaderXlsx(); } else { - $json = ['error_message' => "Unsupported file type"]; - return $this->response->setJSON($json); + $response = ['error_message' => "Unsupported file type"]; + return $this->response->setJSON($response); } if (!$reader) { - $json = ['error_message' => "Failed to initialize reader"]; - return $this->response->setJSON($json); + $response = ['error_message' => "Failed to initialize reader"]; + return $this->response->setJSON($response); } $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 - ]; + $sheet_data = $spreadsheet->getActiveSheet()->toArray(); + if (!empty($sheet_data)) { + $flag = 0; + $final_notes = []; + $list = []; + foreach ($sheet_data as $key => $val) { + + if ($key != 0 && trim($val[0]) && trim($val[1])) { // key zero - header + $flag = 0; + $notes = []; + if ($val[4]) { + $validate = $this->check_existing($val[4], 'donor', 'mobile_no'); + if ($validate) { $notes[] = $validate; $flag++;} + } + if ($val[5]) { + $validate = $this->check_existing($val[5], 'donor', 'email'); + if ($validate) { $notes[] = $validate; $flag++;} + } + if ($val[6]) { + $validate = $this->check_existing($val[6], 'donor', 'pan_no'); + if ($validate) { $notes[] = $validate; $flag++;} + } + if ($val[7]) { + $validate = $this->check_existing($val[7], 'donor', 'adhar_no'); + if ($validate) { $notes[] = $validate; $flag++;} + } + if ($val[8]) { + $validate = $this->check_existing($val[8], 'donor', 'passport_no'); + if ($validate) { $notes[] = $validate; $flag++;} + } + if ($flag > 0) { + $final_notes[] = $val[0] . ' has duplicate entries: ' . implode(',', $notes); + } else { + $list[] = [ + 'business_id' => $session_bid, + 'first_name' => $val[0], + 'donor_type' => ucfirst(strtolower($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] ? $val[7] : null, + 'passport_no' => $val[8] ? $val[8] : null, + 'address' => $val[9] ? $val[9] : null, + 'country' => $val[10] ? $val[10] : null, + 'state' => $val[11] ? $val[11] : null, + 'city' => $val[12] ? $val[12] : null, + 'postal_code' => $val[13] ? $val[13] : null, + 'created_by' => $session_uid, + 'XL_file_name' => $fileNewName, + 'ip_address' => $ip_address + ]; + } + } } + + + if (count($list) > 0) { + $CustomerModel = new CustomerModel(); + $result = $CustomerModel->bulkInsert($list); + $response = $result ? [ + 'success_message' => count($list) . " Contributors imported successfully. " . implode("\n", $final_notes) + ] : ['error_message' => "Something went wrong. Please try again."]; + } else { + $response = ['error_message' => "No new record is found." . implode("\n", $final_notes)]; + } + } else { + $response = ['error_message' => "There is no record to import"]; } - }else{ - $json = ['error_message' => "There is no record to import"]; - return $this->response->setJSON($json); + return $this->response->setJSON($response); } - - 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."]; + + public function check_existing($value, $table, $field) { + $model = new CustomerModel(); + $model->setTable($table); + $where = [$field => $value]; + $check_existing = $model->where($where)->findAll(); + + $statement_string = ucfirst(str_replace('_', ' ', $field)); + $notes = ''; + if (!empty($check_existing)) { + $notes = $statement_string . " already exists"; + } + return $notes; } - return $this->response->setJSON($json); - } - - } diff --git a/app/Controllers/Invoice.php b/app/Controllers/Invoice.php index d823e3c..9f6ce6a 100644 --- a/app/Controllers/Invoice.php +++ b/app/Controllers/Invoice.php @@ -19,6 +19,9 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Reader\Csv as ReaderCsv; use PhpOffice\PhpSpreadsheet\Reader\Xlsx as ReaderXlsx; +use PhpOffice\PhpSpreadsheet\Cell\DataType; +use PhpOffice\PhpSpreadsheet\Style\NumberFormat; + class Invoice extends BaseController { @@ -148,6 +151,7 @@ class Invoice extends BaseController $data['causes'] = $bmodel->select('*')->where('business_id', (int)get_business_id())->where('isactive',1)->get()->getResult(); $data['campaign'] = $model->getData('campaign', $where); + $data['invoice_number_formatting'] = $model->getData('business', $where); $data['receipt_type'] = "individual"; if ($id === '0') { @@ -798,13 +802,18 @@ class Invoice extends BaseController $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) { + if (is_numeric($value)) { + $sheet->setCellValueExplicit($col . $row, $value, DataType::TYPE_STRING); + $sheet->getStyle($col . $row)->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_NUMBER); + } else { + $sheet->setCellValue($col . $row, $value); + } $sheet->setCellValue($col . $row, $value); $col++; } diff --git a/app/Controllers/Notifications.php b/app/Controllers/Notifications.php index 407790c..00d8a14 100755 --- a/app/Controllers/Notifications.php +++ b/app/Controllers/Notifications.php @@ -195,9 +195,10 @@ class Notifications extends BaseController public function template_creation() { + $session_bid = get_business_id(); $data['page_name'] = 'Template Details'; $model = new NotificationModel(); - $data['template'] = $model->getTemplateDetails(); + $data['template'] = $model->getTemplateDetails($session_bid); $this->render_page('template_creation', $data); // echo "templates";die; } @@ -330,10 +331,10 @@ class Notifications extends BaseController //Campaign Creation public function campaign_creation() - { + { $session_bid = get_business_id(); $data['page_name'] = 'Campaign Details'; $model = new NotificationModel(); - $data['campaign'] = $model->getCampaignDetails(); + $data['campaign'] = $model->getCampaignDetails($session_bid); $this->render_page('campaign_creation', $data); // echo "templates";die; } diff --git a/app/Models/NotificationModel.php b/app/Models/NotificationModel.php index 73c3d04..65a63b2 100644 --- a/app/Models/NotificationModel.php +++ b/app/Models/NotificationModel.php @@ -41,12 +41,13 @@ class NotificationModel extends Model ->get()->getResultArray(); } - public function getTemplateDetails(){ + public function getTemplateDetails($session_bid){ return $this->db->table('templates as T' ) ->join('users as U1', 'U1.user_id = T.created_by', 'left') ->join('users as U2', 'U2.user_id = T.updated_by', 'left') ->select('T.template_id,T.template_name,T.mode,T.created_on,T.created_by,T.updated_on,T.updated_by,DATE_FORMAT(T.created_on, "%d/%m/%Y %h:%i %p") AS formatted_created_on,concat(U1.first_name," ",U1.last_name) as created_by_name,concat(U2.first_name," ",U2.last_name) as updated_by_name,T.isactive') ->whereNotIn('T.template_name',array('EXPIRAY_NOTIFY_TEMPLATE_EMAIL','EXPIRAY_NOTIFY_TEMPLATE_WHATSAPP')) + ->where('U1.business_id =',$session_bid) ->get()->getResultArray(); } @@ -82,13 +83,14 @@ class NotificationModel extends Model return $statement; } -public function getCampaignDetails(){ +public function getCampaignDetails($session_bid){ $result = $this->db->table('notification_campaign as NC' ) ->join('users as U1', 'U1.user_id = NC.created_by', 'left') ->join('users as U2', 'U2.user_id = NC.updated_by', 'left') ->join('templates as T', 'T.template_id = NC.template_id', 'left') ->select('NC.campaign_id,NC.campaign_name,T.template_id,T.template_name,NC.mode,NC.created_on,NC.created_by,NC.updated_on,NC.updated_by,DATE_FORMAT(NC.created_on, "%d/%m/%Y %h:%i %p") AS formatted_created_on,concat(U1.first_name," ",U1.last_name) as created_by_name,concat(U2.first_name," ",U2.last_name) as updated_by_name,NC.isactive,NC.group_id,NC.scheduled_date,if(NC.scheduled_time IS NULL ,"",NC.scheduled_time) as scheduled_time') ->whereNotIn('T.template_name',array('EXPIRAY_NOTIFY_TEMPLATE_EMAIL','EXPIRAY_NOTIFY_TEMPLATE_WHATSAPP')) + ->where('U1.business_id =',$session_bid) ->get()->getResultArray(); if (!empty($result)) { diff --git a/app/Views/audit_history.php b/app/Views/audit_history.php index 7c969ce..d9cfdbd 100644 --- a/app/Views/audit_history.php +++ b/app/Views/audit_history.php @@ -15,8 +15,8 @@ Action Module Key - Old Value New Value + Old Value Updated By Updated On diff --git a/app/Views/business_form.php b/app/Views/business_form.php index d96d89d..1dbc4d4 100644 --- a/app/Views/business_form.php +++ b/app/Views/business_form.php @@ -80,7 +80,7 @@ - +
@@ -160,11 +160,12 @@
- Auto-Text Copied from Buiness title field (First time only) + Auto-text copied from Organization Name field (First time only. If you want to change it means please edit.)
+ Auto-text copied from Organization Name field (First time only. If you want to change it means please edit.)
@@ -241,24 +242,24 @@
- +
Please provide.
- +
Please provide.
- +
Please provide.
- +
Please provide.
@@ -556,20 +557,32 @@ \ No newline at end of file diff --git a/public/import/sample.xlsx b/public/import/sample.xlsx deleted file mode 100644 index 3ff064ac9067bf210d1a99facdd08a8eae42b61b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6791 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 delta 4298 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