Changes
Specific Folder FTP Upload / ftp-deploy (push) Successful in 1m20s Details

This commit is contained in:
Ravi Gulhane 2026-11-04 11:34:48 +05:30
parent 3fde14a13a
commit dd766836ab
5 changed files with 861 additions and 48 deletions

View File

@ -995,8 +995,6 @@ class FormController extends Controller
]);
}
// Create contact only on new enrolments (not edits)
if ($currentSubmissionId === '') {
$doctorName = trim((string) ($post['contact_id'] ?? ($post['doctor_name'] ?? '')));
if ($doctorName === '') {
return response()->json([
@ -1006,6 +1004,16 @@ class FormController extends Controller
]);
}
$avgPatients = preg_replace('/\D+/', '', (string) ($post['average_no_of_patients'] ?? ''));
$post['average_no_of_patients'] = $avgPatients;
if ($avgPatients === '') {
return response()->json([
'status' => 'error',
'message' => 'Average No. of Patients is required.',
'description' => 'Please enter a valid number for Average No. of Patients.',
]);
}
$contactdata = [
'domain' => $domain,
'application' => $application,
@ -1029,13 +1037,19 @@ class FormController extends Controller
if (!empty($post['qualification'])) {
$contactdata['qualification'] = $post['qualification'];
}
if (!empty($post['other_qualification'])) {
$contactdata['other_qualification'] = $post['other_qualification'];
}
if (!empty($post['years_of_practice'])) {
$contactdata['years_of_practice'] = $post['years_of_practice'];
}
if (!empty($post['type_of_practice'])) {
$contactdata['type_of_practice'] = $post['type_of_practice'];
}
$contactdata['average_no_of_patients'] = $avgPatients;
// Create contact on new enrolments; update linked contact on edits
if ($currentSubmissionId === '') {
$cont = LambdaRequest::postrequest('contact', 'contact/create', $contactdata, $accessToken);
if (!isset($cont->status) || $cont->status !== 'success' || empty($cont->data->item->id)) {
return response()->json([
@ -1045,6 +1059,17 @@ class FormController extends Controller
]);
}
$post['tgics_contact_id'] = $cont->data->item->id;
} elseif ($linkedContactId !== '') {
$contactdata['id'] = $linkedContactId;
$cont = LambdaRequest::postrequest('contact', 'contact/update', $contactdata, $accessToken);
if (!isset($cont->status) || $cont->status !== 'success') {
return response()->json([
'status' => 'error',
'message' => 'Unable to update doctor contact.',
'description' => $cont->message ?? 'Please try again after some time.',
]);
}
$post['tgics_contact_id'] = $linkedContactId;
}
}

View File

@ -1415,9 +1415,11 @@ class NeblogisticreportController extends Controller
'current_status' => $record->status,
'allowed_statuses' => $allowedStatuses
]);
$hoMessage = $this->napHoFinalStatusMessage($record->status);
return view('neblogisticreport.abmapprovereject')->with([
'success' => false,
'message' => 'Current status "' . $record->status . '" does not allow approval or rejection',
'message' => $hoMessage
?: ('Current status "' . $record->status . '" does not allow approval or rejection'),
'submission_id' => $submission_id,
'record' => $record
]);
@ -1505,9 +1507,11 @@ class NeblogisticreportController extends Controller
'current_status' => $record->status,
'allowed_statuses' => $allowedStatuses
]);
$hoMessage = $this->napHoFinalStatusMessage($record->status);
return view('neblogisticreport.napapprovalstatus')->with([
'success' => false,
'message' => 'Current status "' . $record->status . '" does not allow approval or rejection',
'message' => $hoMessage
?: ('Current status "' . $record->status . '" does not allow approval or rejection'),
'submission_id' => $submission_id,
'record' => $record
]);
@ -1566,7 +1570,12 @@ class NeblogisticreportController extends Controller
$allowedStatuses = ['Requested', 'L1 Approved'];
if (!in_array($record->status, $allowedStatuses)) {
Log::warning('ABM approval/rejection AJAX failed: Invalid status', [ 'submission_id' => $submission_id, 'current_status' => $record->status, 'allowed_statuses' => $allowedStatuses ]);
return response()->json([ 'success' => false, 'message' => 'Current status "' . $record->status . '" does not allow approval or rejection' ], 400);
$hoMessage = $this->napHoFinalStatusMessage($record->status);
return response()->json([
'success' => false,
'message' => $hoMessage
?: ('Current status "' . $record->status . '" does not allow approval or rejection'),
], 400);
}
if ($action === 'approve') {
@ -1592,9 +1601,14 @@ class NeblogisticreportController extends Controller
'user_id' => $user_id,
'response' => $response,
]);
$apiMessage = is_string($response->message ?? null) ? $response->message : null;
if (!$apiMessage && is_string($response->data ?? null)) {
$apiMessage = $response->data;
}
return response()->json([
'success' => false,
'message' => 'Form approval failed. MySQL status was not updated. Please try again.',
'message' => $apiMessage
?: 'Form approval failed. MySQL status was not updated. Please try again.',
], 502);
}
@ -1670,9 +1684,14 @@ class NeblogisticreportController extends Controller
'user_id' => $user_id,
'response' => $response,
]);
$apiMessage = is_string($response->message ?? null) ? $response->message : null;
if (!$apiMessage && is_string($response->data ?? null)) {
$apiMessage = $response->data;
}
return response()->json([
'success' => false,
'message' => 'Form rejection failed. MySQL status was not updated. Please try again.',
'message' => $apiMessage
?: 'Form rejection failed. MySQL status was not updated. Please try again.',
], 502);
}
@ -2064,8 +2083,19 @@ class NeblogisticreportController extends Controller
}
/**
* Neblogistic NAP approval: resolve acting approver when email link has vacant/missing user_id.
* NAP email approve/reject: message when HO has already finalized Approved/Rejected.
*/
protected function napHoFinalStatusMessage(?string $status): ?string
{
if ($status === 'Approved') {
return 'This request has already been approved by HO';
}
if ($status === 'Rejected') {
return 'This request has already been rejected by HO';
}
return null;
}
protected function isFormApiSuccess($response): bool
{
return is_object($response) && ($response->status ?? '') === 'success';

File diff suppressed because one or more lines are too long

580
public/js/tgics-india-geo.js vendored Normal file
View File

@ -0,0 +1,580 @@
window.TGICS_INDIA_GEO = {
"Andaman and Nicobar Islands": [
"Port Blair",
"Diglipur",
"Mayabunder"
],
"Andhra Pradesh": [
"Visakhapatnam",
"Vijayawada",
"Guntur",
"Nellore",
"Kurnool",
"Rajahmundry",
"Tirupati",
"Kakinada",
"Anantapur",
"Eluru",
"Ongole",
"Chittoor",
"Kadapa",
"Srikakulam",
"Vizianagaram",
"Machilipatnam",
"Proddatur",
"Hindupur",
"Madanapalle",
"Nandyal"
],
"Arunachal Pradesh": [
"Itanagar",
"Naharlagun",
"Pasighat",
"Tawang",
"Ziro",
"Bomdila",
"Tezu",
"Along"
],
"Assam": [
"Guwahati",
"Silchar",
"Dibrugarh",
"Jorhat",
"Nagaon",
"Tinsukia",
"Tezpur",
"Bongaigaon",
"Dhubri",
"Sivasagar",
"Goalpara",
"Barpeta",
"Karimganj",
"Diphu",
"North Lakhimpur"
],
"Bihar": [
"Patna",
"Gaya",
"Bhagalpur",
"Muzaffarpur",
"Purnia",
"Darbhanga",
"Bihar Sharif",
"Arrah",
"Begusarai",
"Katihar",
"Munger",
"Chhapra",
"Sasaram",
"Hajipur",
"Samastipur",
"Bettiah",
"Motihari",
"Siwan",
"Saharsa",
"Dehri"
],
"Chandigarh": [
"Chandigarh"
],
"Chhattisgarh": [
"Raipur",
"Bhilai",
"Bilaspur",
"Korba",
"Durg",
"Rajnandgaon",
"Raigarh",
"Jagdalpur",
"Ambikapur",
"Dhamtari",
"Mahasamund",
"Kanker"
],
"Dadra and Nagar Haveli and Daman and Diu": [
"Silvassa",
"Daman",
"Diu"
],
"Delhi": [
"New Delhi",
"Central Delhi",
"East Delhi",
"North Delhi",
"North East Delhi",
"North West Delhi",
"Shahdara",
"South Delhi",
"South East Delhi",
"South West Delhi",
"West Delhi"
],
"Goa": [
"Panaji",
"Margao",
"Vasco da Gama",
"Mapusa",
"Ponda",
"Bicholim",
"Curchorem"
],
"Gujarat": [
"Ahmedabad",
"Surat",
"Vadodara",
"Rajkot",
"Bhavnagar",
"Jamnagar",
"Junagadh",
"Gandhinagar",
"Anand",
"Morbi",
"Nadiad",
"Surendranagar",
"Gandhidham",
"Bharuch",
"Mehsana",
"Bhuj",
"Porbandar",
"Palanpur",
"Valsad",
"Vapi",
"Navsari",
"Godhra",
"Patan",
"Veraval"
],
"Haryana": [
"Gurugram",
"Faridabad",
"Panipat",
"Ambala",
"Yamunanagar",
"Rohtak",
"Hisar",
"Karnal",
"Sonipat",
"Panchkula",
"Bhiwani",
"Sirsa",
"Bahadurgarh",
"Jind",
"Thanesar",
"Kaithal",
"Rewari",
"Palwal",
"Fatehabad"
],
"Himachal Pradesh": [
"Shimla",
"Dharamshala",
"Solan",
"Mandi",
"Palampur",
"Baddi",
"Nahan",
"Kullu",
"Hamirpur",
"Una",
"Bilaspur",
"Chamba",
"Kangra"
],
"Jammu and Kashmir": [
"Srinagar",
"Jammu",
"Anantnag",
"Baramulla",
"Sopore",
"Kathua",
"Udhampur",
"Pulwama",
"Rajouri",
"Poonch",
"Kupwara",
"Budgam"
],
"Jharkhand": [
"Ranchi",
"Jamshedpur",
"Dhanbad",
"Bokaro",
"Deoghar",
"Hazaribagh",
"Giridih",
"Ramgarh",
"Phusro",
"Medininagar",
"Chaibasa",
"Dumka",
"Godda"
],
"Karnataka": [
"Bengaluru",
"Mysuru",
"Hubballi",
"Mangaluru",
"Belagavi",
"Kalaburagi",
"Davangere",
"Ballari",
"Vijayapura",
"Shivamogga",
"Tumakuru",
"Raichur",
"Bidar",
"Hospet",
"Gadag",
"Udupi",
"Chikkamagaluru",
"Hassan",
"Chitradurga",
"Kolar",
"Mandya",
"Bagalkot"
],
"Kerala": [
"Thiruvananthapuram",
"Kochi",
"Kozhikode",
"Thrissur",
"Kollam",
"Kannur",
"Alappuzha",
"Kottayam",
"Palakkad",
"Malappuram",
"Pathanamthitta",
"Idukki",
"Kasaragod",
"Waynad"
],
"Ladakh": [
"Leh",
"Kargil"
],
"Lakshadweep": [
"Kavaratti",
"Agatti",
"Minicoy"
],
"Madhya Pradesh": [
"Bhopal",
"Indore",
"Jabalpur",
"Gwalior",
"Ujjain",
"Sagar",
"Dewas",
"Satna",
"Ratlam",
"Rewa",
"Murwara",
"Singrauli",
"Burhanpur",
"Khandwa",
"Bhind",
"Chhindwara",
"Guna",
"Shivpuri",
"Vidisha",
"Damoh",
"Mandsaur",
"Neemuch",
"Hoshangabad"
],
"Maharashtra": [
"Mumbai",
"Pune",
"Nagpur",
"Thane",
"Nashik",
"Aurangabad",
"Solapur",
"Amravati",
"Kolhapur",
"Navi Mumbai",
"Sangli",
"Malegaon",
"Jalgaon",
"Akola",
"Latur",
"Dhule",
"Ahmednagar",
"Chandrapur",
"Parbhani",
"Ichalkaranji",
"Jalna",
"Bhusawal",
"Nanded",
"Satara",
"Beed",
"Yavatmal",
"Kamptee",
"Gondia",
"Barshi",
"Achalpur",
"Osmanabad",
"Nandurbar",
"Wardha",
"Udgir",
"Hinganghat"
],
"Manipur": [
"Imphal",
"Thoubal",
"Bishnupur",
"Churachandpur",
"Ukhrul",
"Kakching",
"Senapati"
],
"Meghalaya": [
"Shillong",
"Tura",
"Nongpoh",
"Jowai",
"Baghmara",
"Williamnagar"
],
"Mizoram": [
"Aizawl",
"Lunglei",
"Champhai",
"Serchhip",
"Kolasib",
"Saiha"
],
"Nagaland": [
"Kohima",
"Dimapur",
"Mokokchung",
"Tuensang",
"Wokha",
"Zunheboto",
"Mon"
],
"Odisha": [
"Bhubaneswar",
"Cuttack",
"Rourkela",
"Berhampur",
"Sambalpur",
"Puri",
"Balasore",
"Bhadrak",
"Baripada",
"Jharsuguda",
"Jeypore",
"Bargarh",
"Rayagada",
"Angul",
"Dhenkanal",
"Kendujhar"
],
"Puducherry": [
"Puducherry",
"Karaikal",
"Mahe",
"Yanam"
],
"Punjab": [
"Ludhiana",
"Amritsar",
"Jalandhar",
"Patiala",
"Bathinda",
"Mohali",
"Hoshiarpur",
"Batala",
"Pathankot",
"Moga",
"Abohar",
"Malerkotla",
"Khanna",
"Phagwara",
"Firozpur",
"Kapurthala",
"Muktsar",
"Rajpura"
],
"Rajasthan": [
"Jaipur",
"Jodhpur",
"Kota",
"Bikaner",
"Ajmer",
"Udaipur",
"Bhilwara",
"Alwar",
"Bharatpur",
"Sikar",
"Pali",
"Sri Ganganagar",
"Kishangarh",
"Beawar",
"Hanumangarh",
"Dausa",
"Tonk",
"Churu",
"Jhunjhunu",
"Banswara",
"Barmer",
"Nagaur"
],
"Sikkim": [
"Gangtok",
"Namchi",
"Gyalshing",
"Mangan",
"Rangpo"
],
"Tamil Nadu": [
"Chennai",
"Coimbatore",
"Madurai",
"Tiruchirappalli",
"Salem",
"Tirunelveli",
"Tiruppur",
"Erode",
"Vellore",
"Thoothukudi",
"Dindigul",
"Thanjavur",
"Ranipet",
"Sivakasi",
"Karur",
"Udhagamandalam",
"Hosur",
"Nagercoil",
"Kanchipuram",
"Kumarapalayam",
"Karaikudi",
"Neyveli",
"Cuddalore",
"Kumbakonam",
"Tiruvannamalai",
"Pollachi",
"Rajapalayam",
"Gudiyatham"
],
"Telangana": [
"Hyderabad",
"Warangal",
"Nizamabad",
"Khammam",
"Karimnagar",
"Ramagundam",
"Mahbubnagar",
"Nalgonda",
"Adilabad",
"Suryapet",
"Miryalaguda",
"Siddipet",
"Jagtial"
],
"Tripura": [
"Agartala",
"Udaipur",
"Dharmanagar",
"Kailashahar",
"Belonia",
"Ambassa"
],
"Uttar Pradesh": [
"Lucknow",
"Kanpur",
"Ghaziabad",
"Agra",
"Varanasi",
"Meerut",
"Prayagraj",
"Bareilly",
"Aligarh",
"Moradabad",
"Saharanpur",
"Gorakhpur",
"Noida",
"Firozabad",
"Jhansi",
"Muzaffarnagar",
"Mathura",
"Ayodhya",
"Shahjahanpur",
"Rampur",
"Modinagar",
"Hapur",
"Etawah",
"Mirzapur",
"Bulandshahr",
"Sambhal",
"Amroha",
"Hardoi",
"Fatehpur",
"Raebareli",
"Orai",
"Sitapur",
"Bahraich",
"Unnao",
"Jaunpur",
"Lakhimpur",
"Hathras",
"Banda",
"Pilibhit",
"Barabanki",
"Khurja",
"Gonda",
"Mainpuri",
"Lalitpur",
"Etah",
"Deoria",
"Azamgarh",
"Ghazipur",
"Sultanpur"
],
"Uttarakhand": [
"Dehradun",
"Haridwar",
"Roorkee",
"Haldwani",
"Rudrapur",
"Kashipur",
"Rishikesh",
"Kotdwar",
"Pithoragarh",
"Almora",
"Nainital",
"Mussoorie"
],
"West Bengal": [
"Kolkata",
"Howrah",
"Durgapur",
"Asansol",
"Siliguri",
"Bardhaman",
"Malda",
"Baharampur",
"Habra",
"Kharagpur",
"Shantipur",
"Dankuni",
"Dhulian",
"Ranaghat",
"Haldia",
"Raiganj",
"Krishnanagar",
"Naihati",
"Bhatpara",
"Medinipur",
"Jalpaiguri",
"Balurghat",
"Bankura",
"Cooch Behar",
"Purulia",
"Alipurduar",
"Darjeeling"
]
};

View File

@ -419,11 +419,99 @@
</style>
@include('layouts.shared/footer-script')
<script src="{{ asset('assets/libs/sweetalert2/sweetalert2.min.js') }}"></script>
<script src="{{ asset('js/tgics-india-geo.js') }}"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('#form-wrapper').hide()
$('#execution-form-wrapper').hide()
var indiaGeo = window.TGICS_INDIA_GEO || {};
var indiaStates = Object.keys(indiaGeo).sort();
function fillSelectOptions($sel, values, selected, placeholder) {
$sel.empty();
$sel.append($('<option></option>').attr('value', '').text(placeholder || ' -- Select -- '));
(values || []).forEach(function(v) {
var $opt = $('<option></option>').attr('value', v).text(v);
if (selected && String(selected) === String(v)) {
$opt.prop('selected', true);
}
$sel.append($opt);
});
if (selected && values && values.indexOf(selected) === -1 && String(selected).trim() !== '') {
$sel.append(
$('<option></option>').attr('value', selected).text(selected + ' (current)').prop('selected', true)
);
}
}
function ensureAvgPatientsField(prefix) {
if ($('#' + prefix + '-average_no_of_patients').length) {
return;
}
var $years = $('#' + prefix + '-years_of_practice').closest('.col-md-12.mb-2');
if (!$years.length) {
return;
}
var html =
'<div class="col-md-12 mb-2">' +
'<label for="' + prefix + '-average_no_of_patients" class="form-label">' +
'Average No. of Patients <span class="text-danger">*</span></label>' +
'<input type="number" min="0" max="999999" step="1" id="' + prefix +
'-average_no_of_patients" name="average_no_of_patients" class="form-control" required value="">' +
'</div>';
$years.after(html);
}
function convertTextToSelect(prefix, code, values, placeholder) {
var $input = $('#' + prefix + '-' + code);
if (!$input.length || $input.is('select')) {
return $input;
}
var current = $input.val() || '';
var required = $input.prop('required');
var $sel = $('<select></select>')
.attr('id', prefix + '-' + code)
.attr('name', code)
.addClass('form-control');
if (required) {
$sel.prop('required', true);
}
fillSelectOptions($sel, values, current, placeholder);
$input.replaceWith($sel);
return $sel;
}
function refreshCityOptions(prefix, keepCity) {
var state = $('#' + prefix + '-state').val() || '';
var cities = indiaGeo[state] || [];
var $city = $('#' + prefix + '-city_town');
if (!$city.length) {
return;
}
var current = keepCity != null ? keepCity : ($city.val() || '');
if (!$city.is('select')) {
$city = convertTextToSelect(prefix, 'city_town', cities, ' -- Select City -- ');
}
fillSelectOptions($city, cities, current, ' -- Select City -- ');
}
function setupGeoFields(prefix) {
ensureAvgPatientsField(prefix);
convertTextToSelect(prefix, 'state', indiaStates, ' -- Select State -- ');
convertTextToSelect(prefix, 'city_town', [], ' -- Select City -- ');
refreshCityOptions(prefix);
$('#' + prefix + '-state').off('change.tgicsGeo').on('change.tgicsGeo', function() {
refreshCityOptions(prefix, '');
});
$('#' + prefix + '-average_no_of_patients').off('input.tgicsAvg').on('input.tgicsAvg', function() {
this.value = String(this.value || '').replace(/[^0-9]/g, '');
});
}
setupGeoFields('field');
setupGeoFields('execution');
function copyTgicsLink(text) {
function fallbackCopy() {
return new Promise(function(resolve, reject) {
@ -522,7 +610,7 @@
// console.log($("#execution-contact_id option:contains(" + selected[k] + ")").attr('value'))
$('#execution-contact_id').val($("#execution-contact_id option:contains(" +
selected[k] + ")").attr('value'));
} else if (k == 'upload_photo_1' || k == 'upload_photo_2') {
} else if (k == 'upload_photo_1' || k == 'upload_photo_2' || k == 'city_town' || k == 'state') {
continue;
} else {
$('#execution-' + k).val(selected[k]);
@ -532,6 +620,20 @@
// $('#execution-'+k).val(selected[k]);
}
if (selected['state']) {
$('#execution-state').val(selected['state']);
if (!$('#execution-state').val() && selected['state']) {
$('#execution-state').append(
$('<option></option>').attr('value', selected['state'])
.text(selected['state'] + ' (current)').prop('selected', true)
);
}
}
refreshCityOptions('execution', selected['city_town'] || '');
if (selected['average_no_of_patients'] != null && selected['average_no_of_patients'] !== '') {
$('#execution-average_no_of_patients').val(selected['average_no_of_patients']);
}
/* let docid = $('#execution-contact_id option').map(function() {
if ($(this).text().trim() == selected['contact_id'] || $(this).val().trim() == selected['cont_id']) return this;
}).attr('value')
@ -611,7 +713,7 @@
});
$('#field-contact_id,#field-city_town,#field-state,#field-other_qualification').on('input', function () {
$('#field-contact_id,#field-other_qualification').on('input', function () {
this.value = this.value.replace(/[^a-zA-Z\s]/g, '');
});