Files
studiobeve.no/application/views/pages/manage-booking.php
T
UbuntuandClaude Opus 5 ce7400578a Apply the worker capability filter to the manage-booking flow
The per-worker service allow-list was only enforced on the new-booking form.
On the guest manage-booking page a worker could still be offered for services
they do not perform:

- manage_booking() branched on $firstService, which was never assigned - the
  resolve loop above it used $resolvedService - so the guarded branch was dead
  and the worker list fell through to getActiveWorkers(), filtered by vertical
  only. Assigning it activates both the category filter and the capability
  check, and with it the $isOtherCategory checkbox disabling in the view.
- The page's own getAvailableWorkersByServiceCategorySlug() never sent
  service_ids, so re-picking services asked for a category-only worker list.
  It now mirrors the booking form, including the empty-result message.
- setWorker() clears any time already chosen: changing worker or services left
  a stale selection with the submit button still enabled.

manage_booking_process() did re-check capability server-side, but every
rejection there answered with raw JSON, which this non-AJAX form renders as an
unstyled blob in the guest's browser. All eight rejections, plus the
cancellation cutoff, now go through _booking_error(), which takes an optional
back URL so the guest returns to their own manage page rather than an empty
booking form. Adds the cutoff_passed message in all three languages and makes
the error title and button label reflect which flow failed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TYGSbK1erKv7VG1pvdPEjG
2026-08-24 17:06:08 +00:00

680 lines
31 KiB
PHP
Executable File

<?php
// Skeleton comes from the vertical registry so a new vertical needs no
// edit here. barber/beauty still resolve to their own skeleton files.
$vertical = isset($vertical) ? $vertical : vertical_get($subpage);
if(!$vertical){
$vertical = vertical_get('barber');
}
include(getcwd().'/application/views/includes/'.$vertical['skeleton'].'-skeleton-top.php');
$lang = $selectedLang;
$labels = array(
'no' => array(
'title' => 'Administrer bestilling',
'current' => 'Din nåværende bestilling',
'date' => 'Dato',
'time' => 'Tid',
'worker' => 'Arbeider',
'services' => 'Tjenester',
'total' => 'Totalpris',
'cancel_btn' => 'Avbestill bestillingen',
'cancel_confirm' => 'Er du sikker på at du vil avbestille bestillingen?',
'modify_title' => 'Endre bestilling',
'step1' => 'TRINN 1',
'step2' => 'TRINN 2',
'step3' => 'TRINN 3',
'services_label' => 'Tjenester',
'choose_worker' => 'Velg en arbeider',
'next' => 'Neste',
'back' => 'Tilbake',
'send' => 'Bekreft endring',
'no_times' => 'Ingen ledige tider denne dagen!',
'no_workers' => 'Ingen medarbeidere utfører alle de valgte tjenestene.',
'expired_msg' => 'Denne bestillingen er allerede passert og kan ikke endres.',
'cutoff_msg' => 'Bestillingen er innen 24 timer og kan ikke endres eller avbestilles.',
),
'hu' => array(
'title' => 'Foglalás kezelése',
'current' => 'Jelenlegi foglalásod',
'date' => 'Dátum',
'time' => 'Időpont',
'worker' => 'Dolgozó',
'services' => 'Szolgáltatás(ok)',
'total' => 'Összesen',
'cancel_btn' => 'Foglalás törlése',
'cancel_confirm' => 'Biztosan törölni szeretnéd a foglalást?',
'modify_title' => 'Foglalás módosítása',
'step1' => '1. LÉPÉS',
'step2' => '2. LÉPÉS',
'step3' => '3. LÉPÉS',
'services_label' => 'Szolgáltatások',
'choose_worker' => 'Válassz dolgozót',
'next' => 'Tovább',
'back' => 'Vissza',
'send' => 'Módosítás megerősítése',
'no_times' => 'Ezen a napon nincs szabad időpont!',
'no_workers' => 'Egyik kolléga sem végzi el az összes kiválasztott szolgáltatást.',
'expired_msg' => 'Ez a foglalás már elmúlt, nem módosítható.',
'cutoff_msg' => 'A foglalás 24 órán belül van, nem módosítható vagy törölhető.',
),
'en' => array(
'title' => 'Manage Booking',
'current' => 'Your current booking',
'date' => 'Date',
'time' => 'Time',
'worker' => 'Worker',
'services' => 'Services',
'total' => 'Total price',
'cancel_btn' => 'Cancel booking',
'cancel_confirm' => 'Are you sure you want to cancel your booking?',
'modify_title' => 'Modify booking',
'step1' => 'STEP 1',
'step2' => 'STEP 2',
'step3' => 'STEP 3',
'services_label' => 'Services',
'choose_worker' => 'Choose a worker',
'next' => 'Next',
'back' => 'Back',
'send' => 'Confirm changes',
'no_times' => 'There is no available time on this day!',
'no_workers' => 'No staff member performs all of the selected services.',
'expired_msg' => 'This booking has already passed and cannot be modified.',
'cutoff_msg' => 'Your booking is within 24 hours and can no longer be changed or cancelled.',
),
);
$l = isset($labels[$lang]) ? $labels[$lang] : $labels['en'];
?>
<style>
/* ── Manage-booking overrides ───────────────────────────────────────────── */
/* Navigation buttons: use normal flow instead of position:absolute */
#manageForm .bookingButtonContainer {
position: static;
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 10px 10px;
height: auto;
}
#manageForm .bookingButton,
#manageForm .leftButton,
#manageForm .rightButton {
position: static;
}
/* Worker table: allow natural height for pre-rendered workers */
#manageForm .workerTable {
height: auto;
margin-bottom: 20px;
width: 100%;
max-width: 500px;
}
/* Step 3: overflow:auto creates a BFC that contains floated children */
#manageForm #bookingStep3 {
overflow: auto;
}
/* Summary table */
.manage-summary-table {
width: 100%;
max-width: 540px;
margin: 0 auto;
border-collapse: collapse;
}
.manage-summary-table td {
padding: 8px 12px;
border: 1px solid #e0c5bb;
vertical-align: top;
}
.manage-summary-table td:first-child {
font-weight: bold;
white-space: nowrap;
width: 130px;
background: #fdf5f2;
}
.manage-summary-box {
background: #fdf5f2;
border-radius: 6px;
padding: 20px;
margin: 15px auto;
max-width: 580px;
text-align: left;
}
.manage-summary-title {
text-align: center;
font-size: 1.1em;
color: #a5705b;
margin-bottom: 14px;
letter-spacing: 0.05em;
text-transform: uppercase;
}
.manage-cancel-bar {
text-align: center;
margin: 20px auto;
max-width: 580px;
}
.manage-cancel-btn {
background: #7a3a2a;
color: #fff;
border: none;
padding: 11px 28px;
border-radius: 4px;
cursor: pointer;
font-size: 0.85em;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.manage-cancel-btn:hover {
background: #5e2a1a;
}
.manage-divider {
border: none;
border-top: 1px solid #d9b8ac;
margin: 30px auto;
max-width: 580px;
}
.manage-modify-title {
font-size: 1em;
text-align: center;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #a5705b;
margin-bottom: 20px;
}
/* ─────────────────────────────────────────────────────────────────────── */
</style>
<div class="bookingContainer">
<div class="bookingTitle"><?php echo $l['title']; ?></div>
<?php if($status == 'expired'): ?>
<p style="color:#c0392b; text-align:center; margin-top:30px; padding:20px;"><?php echo $l['expired_msg']; ?></p>
<?php elseif($status == 'cutoff'): ?>
<p style="color:#c0392b; text-align:center; margin-top:30px; padding:20px;"><?php echo $l['cutoff_msg']; ?></p>
<?php else: ?>
<!-- Current booking summary -->
<div class="manage-summary-box">
<div class="manage-summary-title"><?php echo $l['current']; ?></div>
<table class="manage-summary-table">
<tr>
<td><?php echo $l['date']; ?></td>
<td><?php echo $booking->booking_date; ?></td>
</tr>
<tr>
<td><?php echo $l['time']; ?></td>
<td><?php echo date('H:i', strtotime($booking->booking_start_time)); ?> &ndash; <?php echo date('H:i', strtotime($booking->booking_finish_time)); ?></td>
</tr>
<tr>
<td><?php echo $l['worker']; ?></td>
<td><?php echo htmlspecialchars($worker->worker_name); ?></td>
</tr>
<tr>
<td><?php echo $l['services']; ?></td>
<td>
<?php
$totalPrice = 0;
$serviceIds = unserialize($booking->service_ids);
if(is_array($serviceIds)){
echo '<ul style="margin:0; padding-left:16px;">';
foreach($serviceIds as $sid){
$svc = $this->Service_model->getServiceById($sid);
if($svc){
$name = ($lang == 'hu') ? $svc->service_name_hu : (($lang == 'no') ? $svc->service_name_no : $svc->service_name_en);
$totalPrice += $svc->service_price;
echo '<li>'.htmlspecialchars($name).' &mdash; '.$svc->service_price.' kr</li>';
}
}
echo '</ul>';
}
?>
</td>
</tr>
<tr>
<td><?php echo $l['total']; ?></td>
<td><strong><?php echo $totalPrice; ?> kr</strong></td>
</tr>
</table>
</div>
<!-- Cancel -->
<div class="manage-cancel-bar">
<form method="post" action="<?php echo SITEURL; ?>manage-booking-cancel"
onsubmit="return confirm('<?php echo addslashes($l['cancel_confirm']); ?>');">
<input type="hidden" name="token" value="<?php echo htmlspecialchars($token); ?>">
<input type="hidden" name="lang" value="<?php echo htmlspecialchars($lang); ?>">
<input type="hidden" name="subpage" value="<?php echo htmlspecialchars($subpage); ?>">
<button type="submit" class="manage-cancel-btn"><?php echo $l['cancel_btn']; ?></button>
</form>
</div>
<hr class="manage-divider">
<!-- Modify section -->
<div class="manage-modify-title"><?php echo $l['modify_title']; ?></div>
<ul class="steps-indicator steps-3">
<li>
<div class="stepTitleContainer">
<div class="stepLine"></div>
<div class="stepCircle activeStep" id="stepCircle1"></div>
<div class="stepTitle"><?php echo $l['step1']; ?></div>
</div>
</li>
<li>
<div class="stepTitleContainer">
<div class="stepLine"></div>
<div class="stepCircle" id="stepCircle2"></div>
<div class="stepTitle"><?php echo $l['step2']; ?></div>
</div>
</li>
<li>
<div class="stepTitleContainer">
<div class="stepCircle" id="stepCircle3"></div>
<div class="stepTitle"><?php echo $l['step3']; ?></div>
</div>
</li>
</ul>
<div class="totalPanelContainer">
<div id="totalPanel" style="display:none;">
<div class="serviceBookingDateContainer">
<div id="serviceBookingDate"></div>
<div id="serviceBookingTime"></div>
</div>
<div class="serviceBookingWorkerContainer"></div>
<div class="serviceContent"></div>
<div class="totalSelectedTime"></div>
<div class="totalPrice"></div>
</div>
<div id="totalPanelBtnContainer">
<div id="totalPanelBtn" style="display:none;"><i class="fas fa-caret-right"></i></div>
</div>
</div>
<form method="post" action="<?php echo SITEURL; ?>manage-booking-process" id="manageForm">
<input type="hidden" name="token" value="<?php echo htmlspecialchars($token); ?>">
<input type="hidden" name="lang" value="<?php echo htmlspecialchars($lang); ?>">
<input type="hidden" name="subpage" value="<?php echo htmlspecialchars($subpage); ?>">
<input type="hidden" name="sendBooking" value="1">
<!-- Step 1: Services -->
<div class="BookingStepContainer" id="bookingStep1">
<div class="totalTime"><input type="time" id="servicelength" name="servicelength" value="00:00"></div>
<div class="bookingTable">
<div class="panel panel-primary">
<div class="panel-heading"><?php echo $l['services_label']; ?></div>
</div>
</div>
<div class="serviceTable">
<div class="serviceHeader">
<div class="serviceCol serviceNameCol">Service name</div>
<div class="serviceCol"></div>
<div class="serviceCol servicePriceCol">Price</div>
<div class="serviceCol serviceInfoCol"></div>
<div class="serviceCol serviceCheckCol"></div>
</div>
<?php
function manage_canon_cat($s) {
$s = html_entity_decode((string)$s, ENT_QUOTES | ENT_HTML5, 'UTF-8');
$s = strip_tags($s);
return trim($s);
}
if(is_array($services) && count($services) > 0){
$groups = array();
$order = array();
foreach($services as $serviceItem){
$label = manage_canon_cat($serviceItem->service_category ?? '');
if($label === '') $label = 'Other';
if(!isset($groups[$label])){ $groups[$label] = array(); $order[] = $label; }
$groups[$label][] = $serviceItem;
}
foreach($order as $label){
?>
<div class="serviceRow">
<div class="serviceCol" style="width:100%"><h4><?php echo htmlspecialchars($label); ?></h4></div>
</div>
<?php
foreach($groups[$label] as $serviceItem){
$isChecked = in_array($serviceItem->service_id, $selectedServiceIds);
$isOtherCategory = ($categorySlug !== '' && $serviceItem->serv_cat_slug !== $categorySlug);
?>
<div class="serviceRow">
<div class="serviceCol serviceNameCol" id="serviceName_<?php echo $serviceItem->service_id; ?>" data-service-name="<?php echo htmlspecialchars($serviceItem->service_name, ENT_QUOTES, 'UTF-8'); ?>">
<?php echo htmlspecialchars(vertical_service_label(isset($vertical) ? $vertical : NULL, $serviceItem)); ?>
</div>
<div class="serviceCol">
<input type="time" class="serviceTime" id="time_<?php echo $serviceItem->service_id; ?>" value="<?php echo $serviceItem->service_time; ?>"/>
</div>
<div class="serviceCol servicePriceCol" id="servicePrice_<?php echo $serviceItem->service_id; ?>">
<?php echo $serviceItem->service_price; ?>
</div>
<div class="serviceCol serviceInfoCol">
<div class="serviceInfoIcon">
<i class="fas fa-info-circle"></i>
<div class="serviceInfoLabel"><?php echo htmlspecialchars($serviceItem->service_description); ?></div>
</div>
</div>
<div class="serviceCol serviceCheckCol">
<input type="hidden" name="service_<?php echo $serviceItem->service_id; ?>" value="0"/>
<input type="checkbox"
class="service <?php echo $serviceItem->serv_cat_slug; ?>"
id="<?php echo $serviceItem->service_id; ?>"
name="service_<?php echo $serviceItem->service_id; ?>"
value="1"
<?php echo $isChecked ? 'checked' : ''; ?>
<?php echo $isOtherCategory ? 'disabled' : ''; ?>/>
</div>
</div>
<?php
}
}
}
?>
</div>
<div class="bookingButtonContainer">
<span></span>
<input type="button" class="rightButton bookingButton" onclick="goToStep(2);" value="<?php echo $l['next']; ?>"/>
</div>
</div>
<!-- Step 2: Worker -->
<div class="BookingStepContainer" id="bookingStep2" style="display:none;">
<input type="hidden" name="worker_id" id="worker_id" value="<?php echo $booking->worker_id; ?>">
<div class="bookingHeader"><?php echo $l['choose_worker']; ?></div>
<div class="workerTable" id="workerTable">
<?php
if(is_array($workers)){
foreach($workers as $workerItem){
$isSelected = ($workerItem->worker_id == $booking->worker_id);
?>
<label for="worker_<?php echo $workerItem->worker_id; ?>">
<div class="profileRow">
<div class="profileCell profileRadioBtn">
<input type="radio" name="worker_radio" class="workers"
id="worker_<?php echo $workerItem->worker_id; ?>"
onclick="setWorker(<?php echo $workerItem->worker_id; ?>)"
<?php echo $isSelected ? 'checked' : ''; ?>>
</div>
<div class="profileCell profileImage">
<img src="<?php echo SITEURL; ?>assets/img/<?php echo $workerItem->worker_profile_img; ?>" style="width:65px;height:65px;border-radius:50%;object-fit:cover;">
</div>
<div class="profileCell">
<div class="profileName"><?php echo htmlspecialchars($workerItem->worker_name); ?></div>
<div class="profileDescription"><?php echo htmlspecialchars($workerItem->worker_info); ?></div>
</div>
</div>
</label>
<?php
}
}
?>
</div>
<div class="bookingButtonContainer">
<input type="button" class="leftButton bookingButton" onclick="goToStep(1);" value="<?php echo $l['back']; ?>"/>
<input type="button" class="rightButton bookingButton" onclick="goToStep(3);" value="<?php echo $l['next']; ?>"/>
</div>
</div>
<!-- Step 3: Date & time -->
<div class="BookingStepContainer" id="bookingStep3" style="display:none;">
<div class="bookingCalendar">
<div id="datepicker"></div>
</div>
<div class="bookingResultsWrapper">
<div class="availableTimesContainerTitle"></div>
<div class="availableTimesContainer" style="padding:5px;">
<input type="hidden" name="booking_date" id="booking_date" value="<?php echo date('Y-m-d'); ?>">
<input type="hidden" name="booking_start_time" id="booking_time" value="">
<div class="availableTimes"></div>
</div>
</div>
<div style="clear:both;"></div>
<div class="bookingButtonContainer">
<input type="button" class="leftButton bookingButton" onclick="goToStep(2);" value="<?php echo $l['back']; ?>"/>
<input type="submit" class="rightButton bookingButton" id="sendManageBtn" name="sendBooking" value="<?php echo $l['send']; ?>" disabled/>
</div>
</div>
</form>
<?php endif; ?>
</div>
<script>
var noTimesMsg = '<?php echo addslashes($l['no_times']); ?>';
var noWorkersMsg = '<?php echo addslashes($l['no_workers']); ?>';
$(document).ready(function(){
recalcServices();
$('#totalPanelBtn').click(function(){
if($('#totalPanel').is(':visible')){
$('#totalPanelBtn').html('<i class="fas fa-caret-left"></i>');
$('#totalPanel').hide();
$('#totalPanelBtn').css('border-top-left-radius','5px');
$('#totalPanelBtn').css('border-bottom-left-radius','5px');
} else {
$('#totalPanelBtn').html('<i class="fas fa-caret-right"></i>');
$('#totalPanel').show();
$('#totalPanelBtn').css('border-top-left-radius','0px');
$('#totalPanelBtn').css('border-bottom-left-radius','0px');
}
});
$('.service').click(function(){
<?php if ( ! empty($vertical['single_service_booking'])): ?>
/* See booking-form-*.php: one treatment at a time for this vertical. */
if($(this).is(':checked')){
$('.service').not(this)
.prop('checked', false)
.prop('disabled', true)
.closest('.serviceRow').addClass('serviceRowDisabled');
}
else{
$('.service').prop('disabled', false);
$('.serviceRow').removeClass('serviceRowDisabled');
}
<?php endif; ?>
recalcServices();
if($('.service').is(':checked')){
var selectedClasses = $(this).attr('class');
var selectedclassesArray = selectedClasses.split(' ');
$('.service').each(function(){
var actualElementArray = $(this).attr('class').split(' ');
if(selectedclassesArray[1] !== actualElementArray[1]){
$(this).attr('disabled', true);
}
});
getAvailableWorkersByServiceCategorySlug(selectedclassesArray[1]);
} else {
$('.service').attr('disabled', false);
}
});
$('#booking_time').change(function(){
if($(this).val() !== ''){
$('#sendManageBtn').prop('disabled', false);
} else {
$('#sendManageBtn').prop('disabled', true);
}
});
});
function recalcServices(){
var totalPrice = 0;
var classIsChecked = 0;
$('#servicelength').val('00:00');
var selectedServices = '<div class="selectedServiceTable">';
selectedServices += '<div class="totalServiceRow serviceHeader"><div class="selectedServiceCol totalSelectedServiceName">Service name</div><div class="selectedServiceCol totalSelectedServicePrice">Price</div></div>';
$('.service').each(function(){
if($(this).is(':checked')){
classIsChecked = 1;
var selected_id = $(this).attr('id');
var priceEl = document.getElementById('servicePrice_'+selected_id).innerHTML.trim();
totalPrice += parseInt(priceEl);
var nameNode = document.getElementById('serviceName_'+selected_id);
// Prefer the full name; the visible label may be abbreviated.
var nameEl = (nameNode.getAttribute('data-service-name') || nameNode.innerHTML).trim();
selectedServices += '<div class="totalServiceRow"><div class="selectedServiceCol totalSelectedServiceName">'+nameEl+'</div><div class="selectedServiceCol totalSelectedServicePrice">'+priceEl+' kr</div></div>';
var currentTotal = $('#servicelength').val();
var svcDT = new Date('<?php echo date('Y-m-d'); ?> ' + $('#time_'+selected_id).val());
var subH = moment.utc(currentTotal,'HH:mm').add(svcDT.getHours(),'hour').format('HH:mm');
var subM = moment.utc(subH,'HH:mm').add(svcDT.getMinutes(),'minutes').format('HH:mm');
$('#servicelength').val(subM);
}
});
selectedServices += '</div>';
$('.serviceContent').html(selectedServices);
$('.totalPrice').html('<span class="totalTitle">Total:</span> <span>'+totalPrice+'</span><span class="totalTitle"> kr</span>');
$('.totalSelectedTime').html('<span class="totalTitle">Total time:</span> <span>'+$('#servicelength').val()+'</span>');
if(classIsChecked){
$('#totalPanelBtn').show();
$('#totalPanel').show();
} else {
$('#totalPanelBtn').hide();
$('#totalPanel').hide();
}
}
function getAvailableWorkersByServiceCategorySlug(categorySlug){
// Same rule as the new-booking form: only workers who can perform EVERY
// ticked service may be offered. The checkbox id IS the service_id.
var selectedServiceIds = $('.service:checked').map(function(){
return this.id;
}).get();
$.ajax({
url: '<?php echo base_url(); ?>ajax',
type: 'POST',
data: {
action: 'getAvailableWorkersByServiceCategory',
serv_cat_slug: categorySlug,
service_ids: selectedServiceIds
},
dataType: 'json',
}).done(function(result){
if(result.workers && result.workers.length > 0){
$('#workerTable').html(result.workerListShow);
setWorker(result.workers[0].worker_id);
}
else{
$('#workerTable').html('<div class="noWorkerMessage">' + noWorkersMsg + '</div>');
setWorker('');
}
});
}
$(function(){
$('#datepicker').datepicker({
firstDay: 1,
defaultDate: new Date(),
dateFormat: 'yy-mm-dd',
onSelect: function(dateText){
$('#booking_date').val(this.value);
$('#sendManageBtn').prop('disabled', true);
$('#booking_time').val('');
getAvailableTimesOfTheDay(this.value);
}
});
});
function getAvailableTimesOfTheDay(selectedDate){
$('.bookingResultsWrapper').show();
$('#serviceBookingDate').html(selectedDate).show();
$.ajax({
url: '<?php echo base_url(); ?>ajax',
type: 'POST',
data: {
action: 'getAvailableTimes',
worker_id: $('#worker_id').val(),
servicelength: $('#servicelength').val(),
selectedDate: selectedDate,
manage_token: '<?php echo $token; ?>'
},
}).done(function(result){
if(result != 0){
$('.availableTimes').html(result);
} else {
$('.availableTimes').html(noTimesMsg);
}
});
}
function setSelectedTime(time, id){
$('#booking_time').val(time).trigger('change');
$('#serviceBookingTime').html(time).show();
$('.availableBookingTime').removeClass('selectedTime');
$('#bookingTime_'+id).addClass('selectedTime');
}
function goToStep(stepNumber){
if(canGotoNextStep(stepNumber)){
$('.stepCircle').removeClass('activeStep');
$('.BookingStepContainer').hide();
$('#bookingStep'+stepNumber).show();
if(stepNumber >= 3){
$('#stepCircle1, #stepCircle2, #stepCircle3').addClass('activeStep');
if(stepNumber == 3 && $('#datepicker').val() !== ''){
getAvailableTimesOfTheDay($('#datepicker').val());
}
$('.bookingSummaryContainer').show();
} else if(stepNumber == 2){
$('#stepCircle1, #stepCircle2').addClass('activeStep');
$('.bookingResultsWrapper').hide();
$('.bookingSummaryContainer').hide();
} else {
$('#stepCircle1').addClass('activeStep');
$('.bookingResultsWrapper').hide();
$('.bookingSummaryContainer').hide();
}
$('html').scrollTop(0);
} else {
alert('<?php echo ($lang == "no") ? "Vennligst fyll ut de påkrevde feltene!" : (($lang == "hu") ? "Kérjük töltsd ki a kötelező mezőket!" : "Please fill in the required fields!"); ?>');
}
}
function canGotoNextStep(stepNumber){
if(stepNumber == 1 || stepNumber == 4) return 1;
if(stepNumber == 2){
var checked = 0;
$('.service').each(function(){ if($(this).is(':checked')) checked = 1; });
return checked;
}
if(stepNumber == 3){
var checked = 0;
$('.workers').each(function(){ if($(this).is(':checked')) checked = 1; });
return checked;
}
return 1;
}
function setWorker(worker_id){
$('#worker_id').val(worker_id);
$('.serviceBookingWorkerContainer').hide().html('');
// The worker (or the service set that produced this list) has changed, so
// a time picked for the previous one is stale. Clearing it also disables
// the submit button via the #booking_time change handler.
$('#booking_time').val('').trigger('change');
$('#serviceBookingTime').html('').hide();
$('.availableBookingTime').removeClass('selectedTime');
}
</script>
<?php
include(getcwd().'/application/views/includes/'.$vertical['skeleton'].'-skeleton-bottom.php');
?>