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

This commit is contained in:
Ravi Gulhane 2026-11-04 13:15:24 +05:30
parent fd5b3d93e0
commit a8af1a13d7
4 changed files with 276 additions and 5 deletions

View File

@ -2,6 +2,8 @@
namespace App\Helpers;
use App\Http\Requests\LambdaRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
@ -58,4 +60,89 @@ class TgicsHelper
return ['counts' => array_fill_keys($ids, 0), 'total' => 0];
}
}
/**
* Resolve a Rapport contact access token for a domain (e.g. lifemankind).
*/
public static function resolveContactAccessToken(string $domain): string
{
$domain = trim($domain);
if ($domain === '') {
return '';
}
$tokenRows = DB::table('users')
->select('access_token')
->where('domain', $domain)
->where('permissions', 'like', '%contact_create%')
->orderBy('updated_at', 'desc')
->skip(0)
->take(1)
->get();
if ($tokenRows->isEmpty() || empty($tokenRows[0]->access_token)) {
return '';
}
return (string) $tokenRows[0]->access_token;
}
public static function isWhatsappValidatedFlag($value): bool
{
if ($value === true || $value === 1 || $value === '1') {
return true;
}
return strtolower(trim((string) $value)) === 'yes';
}
/**
* Map contact_id => whether WhatsApp is validated for TGICS.
*
* @param array<int, string> $contactIds
* @return array<string, bool>
*/
public static function getWhatsappValidationStatus(array $contactIds, string $domain = 'lifemankind'): array
{
$ids = array_values(array_unique(array_filter(array_map(static function ($id) {
return trim((string) $id);
}, $contactIds))));
if (count($ids) === 0) {
return [];
}
$accessToken = self::resolveContactAccessToken($domain);
if ($accessToken === '') {
Log::warning('TGICS WhatsApp validation: no contact access token for domain '.$domain);
return array_fill_keys($ids, false);
}
$status = array_fill_keys($ids, false);
foreach ($ids as $id) {
try {
$resp = LambdaRequest::getrequest('contact', 'contact/get_one', ['id' => $id], $accessToken);
$item = $resp->data->item ?? null;
if ($item && self::isWhatsappValidatedFlag($item->tgics_whatsapp_validated ?? '')) {
$status[$id] = true;
}
} catch (\Throwable $e) {
Log::warning('TGICS WhatsApp validation lookup failed for '.$id.': '.$e->getMessage());
}
}
return $status;
}
/**
* Single-contact validation check for poll endpoint.
*/
public static function isContactWhatsappValidated(string $contactId, string $domain = 'lifemankind'): bool
{
$contactId = trim($contactId);
if ($contactId === '') {
return false;
}
$map = self::getWhatsappValidationStatus([$contactId], $domain);
return !empty($map[$contactId]);
}
}

View File

@ -1050,6 +1050,7 @@ class FormController extends Controller
// Create contact on new enrolments; update linked contact on edits
if ($currentSubmissionId === '') {
$contactdata['tgics_whatsapp_validated'] = 'No';
$cont = LambdaRequest::postrequest('contact', 'contact/create', $contactdata, $accessToken);
if (!isset($cont->status) || $cont->status !== 'success' || empty($cont->data->item->id)) {
return response()->json([
@ -1061,6 +1062,21 @@ class FormController extends Controller
$post['tgics_contact_id'] = $cont->data->item->id;
} elseif ($linkedContactId !== '') {
$contactdata['id'] = $linkedContactId;
$existingContact = LambdaRequest::getrequest('contact', 'contact/get_one', ['id' => $linkedContactId], $accessToken);
$existingItem = $existingContact->data->item ?? null;
$existingPhone = '';
if ($existingItem && !empty($existingItem->phone)) {
$existingPhone = preg_replace('/\D+/', '', (string) $existingItem->phone);
if (strlen($existingPhone) > 10) {
$existingPhone = substr($existingPhone, -10);
}
}
if ($existingPhone !== '' && $existingPhone !== $whatsapp) {
$contactdata['tgics_whatsapp_validated'] = 'No';
} elseif ($existingItem && isset($existingItem->tgics_whatsapp_validated)) {
$contactdata['tgics_whatsapp_validated'] = $existingItem->tgics_whatsapp_validated;
}
$cont = LambdaRequest::postrequest('contact', 'contact/update', $contactdata, $accessToken);
if (!isset($cont->status) || $cont->status !== 'success') {
return response()->json([
@ -13513,4 +13529,35 @@ class FormController extends Controller
return $labels;
}
/**
* Poll endpoint: TGICS WhatsApp validation status for a contact.
*/
public function tgicsWhatsappStatus(Request $request)
{
$contactId = trim((string) $request->input('contact_id', ''));
$partition = trim((string) $request->input('partition', 'rapport-lifemankind'));
$domain = 'lifemankind';
if (strpos($partition, '-') !== false) {
$parts = explode('-', $partition, 2);
$domain = $parts[1] ?? $domain;
}
if ($contactId === '') {
return response()->json([
'status' => 'error',
'message' => 'contact_id is required.',
], 400);
}
$validated = \App\Helpers\TgicsHelper::isContactWhatsappValidated($contactId, $domain);
return response()->json([
'status' => 'success',
'data' => [
'contact_id' => $contactId,
'validated' => $validated,
],
]);
}
}

View File

@ -62,6 +62,10 @@
$tgicsSurveyData = \App\Helpers\TgicsHelper::getSurveyCounts($tgicsContactIds);
$tgicsSurveyCounts = $tgicsSurveyData['counts'] ?? [];
$totalSurveysDone = (int) ($tgicsSurveyData['total'] ?? 0);
$tgicsWhatsappValidated = \App\Helpers\TgicsHelper::getWhatsappValidationStatus(
$tgicsContactIds,
'lifemankind'
);
$tgicsCommonUserId = trim((string) ($form->user_id ?? ''));
$tgicsCommonLink = $tgicsCommonUserId !== ''
@ -135,23 +139,41 @@
$surveysDone = $tgicsContactId !== ''
? (int) ($tgicsSurveyCounts[$tgicsContactId] ?? 0)
: 0;
$whatsappValidated = $tgicsContactId !== ''
&& !empty($tgicsWhatsappValidated[$tgicsContactId]);
$whatsappText = "Dear Doctor" . ($doctorName !== '' ? ' ' . $doctorName : '') . ",\nThank you for participating in TGICS (The Great Indian Cough Study).\nPlease open the link and enter your WhatsApp mobile number to continue:\n" . $doctorLink;
$whatsappLink = ($whatsappDigits !== '' && $doctorLink !== '')
? 'https://api.whatsapp.com/send?phone=' . $whatsappDigits . '&text=' . rawurlencode($whatsappText)
: '';
$validateToken = $tgicsContactId !== ''
? 'CREST_VERIFY_TGICS_' . $tgicsContactId
: '';
$validateWaUrl = $validateToken !== ''
? 'https://wa.me/918142061298?text=' . rawurlencode($validateToken)
: '';
@endphp
<tr>
<td>
@if ($isApproved)
@if ($whatsappLink !== '')
@if ($doctorLink === '')
<span class="text-muted">Link unavailable</span>
@elseif ($whatsappDigits === '')
<span class="text-muted">No WhatsApp number</span>
@elseif ($whatsappValidated && $whatsappLink !== '')
<a href="{{ $whatsappLink }}" target="_blank" rel="noopener noreferrer"
class="btn btn-xs btn-success">
<i class="mdi mdi-whatsapp"></i> Send WhatsApp
<i class="mdi mdi-whatsapp"></i> Send
</a>
@elseif ($doctorLink === '')
<span class="text-muted">Link unavailable</span>
@elseif ($validateWaUrl !== '')
<button type="button"
class="btn btn-xs btn-warning tgics-validate-wa-btn"
data-contact-id="{{ $tgicsContactId }}"
data-validate-url="{{ $validateWaUrl }}"
data-doctor-name="{{ $doctorName }}">
<i class="mdi mdi-qrcode"></i> Validate
</button>
@else
<span class="text-muted">No WhatsApp number</span>
<span class="text-muted">Validation unavailable</span>
@endif
@else
<button type="button" class="btn btn-xs btn-info edit-btn"
@ -399,6 +421,30 @@
<!-- end container -->
</div>
<!-- end page -->
<div class="modal fade" id="tgics-validate-wa-modal" tabindex="-1" role="dialog" aria-labelledby="tgics-validate-wa-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="tgics-validate-wa-title">Validate WhatsApp</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center">
<p class="mb-2" id="tgics-validate-wa-doctor"></p>
<p class="text-muted small">Ask the doctor to scan this QR with the enrolled WhatsApp number and send the pre-filled message without changing it.</p>
<div id="tgics-validate-wa-qr" class="d-flex justify-content-center my-3"></div>
<p class="small mb-1" id="tgics-validate-wa-status">Waiting for validation…</p>
<a href="#" id="tgics-validate-wa-open" target="_blank" rel="noopener noreferrer" class="btn btn-sm btn-outline-success">
Open link instead
</a>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<style type="text/css">
#pageloader {
background: rgba(255, 255, 255, 0.8);
@ -416,9 +462,16 @@
position: absolute;
top: 50%;
}
#tgics-validate-wa-qr canvas,
#tgics-validate-wa-qr img {
max-width: 220px;
height: auto;
}
</style>
@include('layouts.shared/footer-script')
<script src="{{ asset('assets/libs/sweetalert2/sweetalert2.min.js') }}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
<script src="{{ asset('js/tgics-india-geo.js') }}"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
@ -762,6 +815,89 @@
$('#field-contact_id').trigger('change');
});
var tgicsWaPollTimer = null;
var tgicsWaPollStartedAt = 0;
function stopTgicsWaPoll() {
if (tgicsWaPollTimer) {
clearInterval(tgicsWaPollTimer);
tgicsWaPollTimer = null;
}
}
function startTgicsWaPoll(contactId) {
stopTgicsWaPoll();
tgicsWaPollStartedAt = Date.now();
$('#tgics-validate-wa-status').text('Waiting for validation…');
tgicsWaPollTimer = setInterval(function() {
if (Date.now() - tgicsWaPollStartedAt > 120000) {
stopTgicsWaPoll();
$('#tgics-validate-wa-status').text('Still waiting. Close and try Validate again after the doctor sends the message.');
return;
}
$.ajax({
type: 'GET',
url: '/form/tgicswhatsappstatus',
data: {
contact_id: contactId,
partition: 'rapport-lifemankind'
},
success: function(res) {
if (res && res.status === 'success' && res.data && res.data.validated) {
stopTgicsWaPoll();
$('#tgics-validate-wa-status').text('Validated!');
Swal.fire({
icon: 'success',
title: 'WhatsApp validated',
text: 'You can now send the survey link to this doctor.',
timer: 1800,
showConfirmButton: false
}).then(function() {
window.location.reload();
});
}
}
});
}, 3000);
}
$(document).on('click', '.tgics-validate-wa-btn', function() {
var contactId = $(this).attr('data-contact-id') || '';
var validateUrl = $(this).attr('data-validate-url') || '';
var doctorName = $(this).attr('data-doctor-name') || 'Doctor';
if (!contactId || !validateUrl) {
return;
}
$('#tgics-validate-wa-doctor').text(doctorName);
$('#tgics-validate-wa-open').attr('href', validateUrl);
$('#tgics-validate-wa-qr').empty();
if (typeof QRCode !== 'undefined') {
new QRCode(document.getElementById('tgics-validate-wa-qr'), {
text: validateUrl,
width: 200,
height: 200
});
} else {
$('#tgics-validate-wa-qr').html('<p class="text-danger small">Unable to render QR. Use Open link instead.</p>');
}
var $modal = $('#tgics-validate-wa-modal');
if (typeof bootstrap !== 'undefined' && bootstrap.Modal) {
bootstrap.Modal.getOrCreateInstance($modal[0]).show();
} else if ($modal.modal) {
$modal.modal('show');
} else {
$modal.show();
}
startTgicsWaPoll(contactId);
});
$('#tgics-validate-wa-modal').on('hidden.bs.modal hide.bs.modal', function() {
stopTgicsWaPoll();
});
$('#execution-form').on('submit', function(event) {
event.preventDefault();
$("#pageloader").fadeIn();

View File

@ -332,6 +332,7 @@ Route::get('/form/nebmitraverification', [FormController::class, 'nebmitraverifi
Route::get('/form/respidoctorsearch', [FormController::class, 'respidoctorsearch']);
Route::get('/form/addrespidoctor', [FormController::class, 'addrespidoctor']);
Route::get('/form/tgicswhatsappstatus', [FormController::class, 'tgicsWhatsappStatus']);
Route::post('/form/getformfielddata', [FormController::class, 'getformfielddata']);
Route::post('/form/submit', [FormController::class, 'submit']);