{source}<!-- PrettyCalendar include style -->{/source}
{source}<!-- PrettyCalendar include javascript -->{/source}
{source}<!-- FullCalendar include style -->{/source}
{source}<!-- FullCalendar include javascript -->
<script src="https://cdn.jsdelivr.net/npm/
{/source}
{source}
<style type="text/css">
body.modal-open {
overflow: hidden;
height: 100vh;
}
</style>
<script type="text/javascript">
var events = [];
var weekday = [];
</script>
<?php
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http")
. "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
echo '<form id="appointmentsForm" action="'.$url.'" method="POST">';
echo '<input type="hidden" id="hdnSaveEvent" name="hdnSaveEvent" value="0" />';
echo '<input type="hidden" id="hdnEventDate" name="hdnEventDate" />';
echo '<input type="hidden" id="hdnSlot" name="hdnSlot" />';
$baseUrl = 'https://test4.icmed.ro/api/';
global $subOfficeId;
$subOfficeId=0;
function GetToken(){
$postData = array(
'grant_type' => 'password',
'client_id'=>'8059A0D2-3287-43DA-8B6E-EA0EF243FE08',
'client_secret'=>'a7d91866-1197-404a-1b36-098926b31fd1',
'username' => 'api.bc.spital.comanesti',
'password' => 'nDyUT9JZ%',
'scope' => 'openid appointments_anon',
);
$ch = curl_init('https://id.icmed.ro/connect/token');
curl_setopt_array($ch, array(
CURLOPT_POST => TRUE,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/x-www-form-urlencoded'
),
CURLOPT_POSTFIELDS => http_build_query($postData)
));
$response = curl_exec($ch);
if($response === FALSE){
die(curl_error($ch));
}
curl_close($ch);
$obj = json_decode($response);
$_SESSION['api2token']=$obj->{'access_token'};
$data = new DateTime();
$data->modify("+{$obj->{'expires_in'}} seconds");
$_SESSION['api2expire']=$data;
}
function GetWorkplaces(){
$token=$_SESSION['api2token'];
$ch= curl_init();
curl_setopt_array($ch, [
CURLOPT_URL=>'https://test4.icmed.ro/api/workplaces',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPGET => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token"
]
]);
$response = curl_exec($ch);
if($response === FALSE){
die(curl_error($ch));
}
//echo $response;
curl_close($ch);
$obj = json_decode($response, true);
$wp=(isset($_REQUEST['wp']) && is_numeric($_REQUEST['wp']))?$_REQUEST['wp']:$obj[0]['id'];
echo '<div style="clear:both; padding:5px;">';
echo '<div style="float:left; width:85px;">Locatie: </div>';
echo '<div style="float:left; width:400px;">';
if(count($obj)>1){
echo '<select name="wp" id="wp" onChange="javascript:ChangeWorkplace();">';
foreach ($obj as $item) {
echo '<option value="' . htmlspecialchars($item['id']) . '" '.($item['id']==$wp?'selected':'').' >'
. htmlspecialchars($item['name']) .
'</option>';
}
echo '</select>';
}else{
echo $obj[0]['name'];
echo '<input type="hidden" name="wp" id="wp" value="'.$obj[0]['id'].'" />';
}
echo '</div>';
echo '</div>';
return $wp;
}
function GetSpecialities($wp){
$token=$_SESSION['api2token'];
$ch= curl_init();
curl_setopt_array($ch, [
CURLOPT_URL=>'https://test4.icmed.ro/api/specialities?workplaceId='.$wp.'&haveSchedule=1',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPGET => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token"
]
]);
$response = curl_exec($ch);
if($response === FALSE){
die(curl_error($ch));
}
//echo $response;
curl_close($ch);
$obj = json_decode($response, true);
$sp=(isset($_REQUEST['sp']) && is_numeric($_REQUEST['sp']))?$_REQUEST['sp']:$obj[0]['id'];
echo '<div style="clear:both; padding:5px;">';
echo '<div style="float:left; width:85px;">Specialitate: </div>';
echo '<div style="float:left; width:400px;">';
if(count($obj)>1){
echo '<select name="sp" id="sp" onChange="javascript:ChangeSpeciality();">';
foreach ($obj as $item) {
echo '<option value="' . htmlspecialchars($item['id']) . '" '.($item['id']==$sp?'selected':'').'>'
. htmlspecialchars($item['name']) .
'</option>';
}
echo '</select>';
}else{
echo $obj[0]['name'];
echo '<input type="hidden" name="sp" id="sp" value="'.$obj[0]['id'].'" />';
}
echo '</div>';
echo '</div>';
return $sp;
}
function GetPhysicians($wp, $sp){
global $subOfficeId;
$token=$_SESSION['api2token'];
$ch= curl_init();
curl_setopt_array($ch, [
CURLOPT_URL=>'https://test4.icmed.ro/api/physicians?workplaceId='.$wp.'&specialityId='.$sp.'&haveSchedule=1',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPGET => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token"
]
]);
$response = curl_exec($ch);
// Check for errors
if($response === FALSE){
die(curl_error($ch));
}
curl_close($ch);
$obj = json_decode($response, true);
//print_r($obj);
$ph=(isset($_REQUEST['ph']) && is_numeric($_REQUEST['ph']))?$_REQUEST['ph']:$obj[0]['id'];
$subOfficeId=$obj[0]['subOfficeId'];
//echo $subOfficeId;
echo '<div style="clear:both; padding:5px;">';
echo '<div style="float:left; width:85px;">Medic: </div>';
echo '<div style="float:left; width:400px;">';
if(count($obj)>1){
echo '<select name="ph" id="ph" onChange="javascript: ChangePhysician();">';
foreach ($obj as $item) {
if($item['id']==$ph){
$subOfficeId=$item['subOfficeId'];//$obj[0]['subOfficeId'];
}
echo '<option value="' . htmlspecialchars($item['id']) . '"'.($item['id']==$ph?'selected':'').'>'
. htmlspecialchars($item['firstName']) .' '. htmlspecialchars($item['lastName']) .
'</option>';
}
echo '</select>';
}else{
$subOfficeId=$obj[0]['subOfficeId'];
echo $obj[0]['firstName'].' '.$obj[0]['lastName'];
echo '<input type="hidden" name="ph" id="ph" value="'.$obj[0]['id'].'" />';
}
echo '</div>';
echo '</div>';
return $ph;
}
function SaveEvent(){
global $subOfficeId;
$hdnEventDate = $_REQUEST['hdnEventDate'];
$fromSec = (new DateTime())->setTimestamp($hdnEventDate/1000);
$slotSec = $_REQUEST['hdnSlot'] * 60;
$toSec = (new DateTime())->setTimestamp($slotSec + $hdnEventDate/1000);
$data = [
"FirstName" => $_REQUEST['patientFirstName'],
"LastName" => $_REQUEST['patientLastName'],
"PhoneNo" => $_REQUEST['patientPhone'],
"From" =>$fromSec->format('Y-m-dTH:i:s'),
"To" =>$toSec->format('Y-m-dTH:i:s'),
"IsActive" => true,
"OfficeId" =>'',
"SubOfficeId" => $subOfficeId,
"SpecialityId" => $_REQUEST['sp'],
"WorkplaceId" => $_REQUEST['wp'],
"PhysicianId" => $_REQUEST['ph']
];
$payload = json_encode($data);
print_r($payload);
return;
$token=$_SESSION['api2token'];
$ch= curl_init();
curl_setopt_array($ch, [
CURLOPT_URL=>'https://test4.icmed.ro/api/AppointmentsA',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token",
"Content-Type: application/json",
"Content-Length: " . strlen($payload)
]
]);
$response = curl_exec($ch);
if($response === FALSE){
die(curl_error($ch));
}
//echo $response;
curl_close($ch);
$obj = json_decode($response, true);
}
function GetSchedule($ph,$so, $epc){
echo 'GetSchedule('.$ph.', '.$so.', '.$epc.')';
$token=$_SESSION['api2token'];
$ch= curl_init();
curl_setopt_array($ch, [
CURLOPT_URL=>'https://test4.icmed.ro/api/physicians/'.$ph.'/schedule/'.$epc.'?subOfficeId='.$so.'¤tView=week',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPGET => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token"
]
]);
$response = curl_exec($ch);
// Check for errors
if($response === FALSE){
die(curl_error($ch));
}
curl_close($ch);
$obj = json_decode($response, true);
print_r($obj);
//echo '<div>Orar: </div>';
date_default_timezone_set('Europe/Bucharest');
if(count($obj['available'])>0){
?>
<script type="text/javascript">
function openModalForEvent(slot) {
document.getElementById("eventOverlay").style.display = "block";
document.body.classList.add("modal-open");
document.getElementById("addEventModal").style.display = "block";
var sel=document.getElementById("ph");
document.getElementById("eventPhysician").innerHTML=sel.options[sel.selectedIndex].text;
document.getElementById("eventDate").innerHTML=slot.toLocaleString();
var objMsg=document.getElementById("validationMessage");
objMsg.innerHTML = "";
var objNume=document.getElementById("patientLastName");
objNume.value="";
objNume.focus();
var objPrenume=document.getElementById("patientFirstName");
objPrenume.value="";
var objTel=document.getElementById("patientPhone");
objTel.value="";
var objhdnEventDate=document.getElementById("hdnEventDate");
objhdnEventDate.value=slot.getTime();
}
function closeModalForEvent() {
document.getElementById("eventOverlay").style.display = "none";
document.body.classList.remove("modal-open");
document.getElementById("addEventModal").style.display = "none";
}
function isValidMobile(phone) {
phone = phone.replace(/[^0-9]/g, '');
if (phone.startsWith("0040")) phone = "0" + phone.substring(4);
if (phone.startsWith("40") && phone.length === 11) phone = "0" + phone.substring(2);
var regex = /^07[0-8]\d{7}$/;
return regex.test(phone);
}
function saveEvent(){
var objMsg=document.getElementById("validationMessage");
var objNume=document.getElementById("patientLastName");
var objPrenume=document.getElementById("patientFirstName");
var objTel=document.getElementById("patientPhone");
if(objNume.value.trim().length==0){
objMsg.innerHTML = "Numele este obligatoriu";
return;
}
if(objPrenume.value.trim().length==0){
objMsg.innerHTML = "Prenumele este obligatoriu";
return;
}
if(!isValidMobile(objTel.value.trim())){
objMsg.innerHTML = "Numar de telefon invalid";
return;
}
// save programare
var objhdnSaveEvent=document.getElementById("hdnSaveEvent");
objhdnSaveEvent.value="1";
document.getElementById("appointmentsForm").submit();
}
function isWithinBusinessHours(businessHours, date) {
var day = date.getDay();
var hour = date.getHours();
var minute = date.getMinutes();
var totalMinutes = hour * 60 + minute;
var foundInterval=false;
for(var i=0;i<businessHours.length; i++){
if(businessHours[i].daysOfWeek.includes(day)){
var timeStart=businessHours[i].startTime.split(":").map(Number);
var minStart = timeStart[0] * 60 + timeStart[1];
var timeEnd=businessHours[i].endTime.split(":").map(Number);
var minEnd = timeEnd[0] * 60 + timeEnd[1];
if(minStart<=totalMinutes && totalMinutes<minEnd){
foundInterval=true;
}
}
}
return foundInterval;
}
var objhdnSlot=document.getElementById("hdnSlot");
objhdnSlot.value="<?php echo $obj['slotSpan']; ?>";
var calendar;
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('myCal');
calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'timeGridWeek' ,
slotDuration: '00:<?php echo $obj['slotSpan']; ?>:00',
allDaySlot: false,
locale:'ro',
firstDay:1,
dateClick: function(info) {
if (!isWithinBusinessHours(calendar.getOption('businessHours'), info.date)) {
alert("Slot in afara programului.");
return;
}
openModalForEvent(info.date);
},
/*
datesSet: function(info) {
// intervalul nou afișat
var epoch = document.getElementById('epc');
epoch.value = info.start.getTime();
//SubmitForm();
console.log('Start:', info.start.getTime());
console.log('End:', info.end);
// view-ul curent
console.log('View:', info.view.type);
},
*/
customButtons: {
myPrev: {
text: '<',
click() {
var epochObj = document.getElementById('epc');
var epoch = parseFloat(epochObj.value) - 604800000;
epochObj.value = epoch;
SubmitForm();
}
},
myNext: {
text: '>',
click() {
var epochObj = document.getElementById('epc');
var epoch = parseFloat(epochObj.value) + 604800000;
epochObj.value = epoch;
SubmitForm();
}
},
myToday: {
text: 'azi',
click() {
var epochObj = document.getElementById('epc');
epochObj.value = "";
SubmitForm();
}
}
},
headerToolbar: {
left:"",
right: 'myPrev myNext myToday',
center: 'title',
},
<?php
$minEpoch=2554117001000;
$maxEpoch=0;
echo 'businessHours: [';
for ($i=0; $i<count($obj['available']); $i++) {
if($obj['available'][$i]['startTime']<$minEpoch){
$minEpoch=$obj['available'][$i]['startTime'];
}
if($obj['available'][$i]['endTime']>$maxEpoch){
$maxEpoch=$obj['available'][$i]['endTime'];
}
if($i>0){
echo ',';
}
echo '{';
echo 'daysOfWeek: ['.(date('N', $obj['available'][$i]['date']/1000)==7?0:date('N', $obj['available'][$i]['date']/1000)).'],';
echo 'startTime:"'.date('H:i', $obj['available'][$i]['startTime']/1000).'",';
echo 'endTime:"'.date('H:i', $obj['available'][$i]['endTime']/1000).'"';
echo '}';
}
echo '],';
if(count($obj['unavailable'])>0){
echo 'events: [';
for ($i=0; $i<count($obj['unavailable']); $i++) {
if($i>0){
echo ',';
}
echo '{';
echo 'title: "indisponibil",';
echo 'start:"'.date('Y-m-d H:i:s', $obj['unavailable'][$i]['startTime']/1000).'",';
echo 'end:"'.date('Y-m-d H:i:s', $obj['unavailable'][$i]['endTime']/1000).'"';
echo '}';
}
echo '],';
}
if($maxEpoch>0){
echo 'slotMinTime: "'.date('H:i:s', $minEpoch/1000).'",';
echo 'slotMaxTime: "'.date('H:i:s', $maxEpoch/1000).'",';
echo 'initialDate: "'.date('Y-m-d', $minEpoch/1000).'",';
}
?>
});
calendar.render();
/*
eventAllow: function(dropInfo, draggedEvent) {
return calendar.getCurrentData().businessHoursGenerator.isSlotAllowed(dropInfo.start);
}
*/
});
</script>
<?php
}
//print_r($response);
}
if(!isset($_SESSION['api2expire']) || $_SESSION['api2expire'] <= new DateTime()){
GetToken();
}
$wp=GetWorkplaces();
$sp=GetSpecialities($wp);
$ph=GetPhysicians($wp, $sp);
$data = new DateTime();
$epc = (isset($_REQUEST['epc']) && is_numeric($_REQUEST['epc']))?$_REQUEST['epc']:$data->getTimestamp() * 1000;
echo '<input type="hidden" name="epc" id="epc" value="'.$epc.'" />';
if($subOfficeId!=0){
if(isset($_REQUEST['hdnSaveEvent']) && $_REQUEST['hdnSaveEvent']=='1'){
SaveEvent();
}
GetSchedule($ph,$subOfficeId,$epc);
}
?>
<div style="clear:both;">
<div id="myCal"></div>
</div>
<div id="eventOverlay" style="display: none;
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.5);
z-index: 99998;"></div>
<div id="addEventModal" style="
display:none;
position:fixed;
top:50%; left:50%;
transform:translate(-50%, -50%);
background:white;
padding:20px;
border:1px solid #ccc;
border-radius:6px;
box-shadow:0 0 20px rgba(0,0,0,0.3);
z-index:99999;
">
<div id="dlgHeader">
<h2>Programare noua</h2>
<div id="eventPhysician"></div>
<div id="eventDate"></div>
</div>
<div>
<input id="patientLastName" name="patientLastName" style="margin:10px" class="e-input e-error" type="text" placeholder="Introduceti numele" aria-invalid="true" aria-describedby="patientLastName-info" aria-required="true">
<input id="patientFirstName" name="patientFirstName" style="margin:10px" class="e-input e-error" type="text" placeholder="Introduceti prenumele" aria-invalid="true" aria-describedby="patientFirstName-info" aria-required="true">
<input id="patientPhone" name="patientPhone" style="margin:10px" class="e-input e-error" type="text" placeholder="Introduceti numarul de telefon" aria-placeholder="Introduceti numarul de telefon" role="textbox" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" aria-live="assertive" aria-valuenow="____ ___ ___" aria-invalid="true" aria-describedby="patientPhone-info">
<span id="validationMessage" class="e-error" style="display: block; color:#ff0000;"></span>
</div>
<button onclick="Javascript: saveEvent(); return false;">Salveaza</button>
<button onclick="Javascript: closeModalForEvent(); return false;">Renunta</button>
</div>
</form>
<script type="text/javascript">
function SubmitForm(){
document.getElementById("appointmentsForm").submit();
}
function ChangeWorkplace(){
var objSp = document.getElementById("sp");
if(objSp.tagName.toLowerCase()=='select'){
objSp.selectedIndex=-1;
}else{
objSp.value="";
}
var objPh = document.getElementById("ph");
if(objPh.tagName.toLowerCase()=='select'){
objPh.selectedIndex=-1;
}else{
objPh.value="";
}
var epochObj = document.getElementById('epc');
epochObj.value = "";
SubmitForm();
}
function ChangeSpeciality(){
var objPh = document.getElementById("ph");
if(objPh.tagName.toLowerCase()=='select'){
objPh.selectedIndex=-1;
}else{
objPh.value="";
}
var epochObj = document.getElementById('epc');
epochObj.value = "";
SubmitForm();
}
function ChangePhysician(){
var epochObj = document.getElementById('epc');
epochObj.value = "";
SubmitForm();
}
</script>
{/source}



