From 8dce28e29b3dfddfb2612b5949d244db67e5b0e1 Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller <45882981+Hystepik@users.noreply.github.com> Date: Thu, 23 Nov 2023 14:58:00 +0100 Subject: [PATCH] Fix bookcal public page 2 (#26827) * fix bookcal public page * fx booking link with calendar * booking list on calendar_card * fix display on wrong values --------- Co-authored-by: Hystepik --- htdocs/bookcal/booking_list.php | 247 ++++++++++++++++++++ htdocs/bookcal/lib/bookcal_calendar.lib.php | 8 + htdocs/comm/action/index.php | 12 +- htdocs/langs/en_US/agenda.lang | 1 + htdocs/public/bookcal/bookcalAjax.php | 91 ++++---- htdocs/public/bookcal/index.php | 12 +- 6 files changed, 319 insertions(+), 52 deletions(-) create mode 100644 htdocs/bookcal/booking_list.php diff --git a/htdocs/bookcal/booking_list.php b/htdocs/bookcal/booking_list.php new file mode 100644 index 00000000000..95a0b95d96c --- /dev/null +++ b/htdocs/bookcal/booking_list.php @@ -0,0 +1,247 @@ + + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2010-2014 Juanjo Menent + * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/compta/facture/prelevement.php + * \ingroup facture + * \brief Management of direct debit order or credit tranfer of invoices + */ + +// Load Dolibarr environment +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +dol_include_once('/bookcal/lib/bookcal_calendar.lib.php'); + +// load module libraries +require_once __DIR__.'/class/calendar.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("bookcal@bookcal", "other")); + +$id = (GETPOST('id', 'int') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility +$ref = GETPOST('ref', 'alpha'); +$socid = GETPOST('socid', 'int'); +$action = GETPOST('action', 'aZ09'); +$type = GETPOST('type', 'aZ09'); + +$fieldid = (!empty($ref) ? 'ref' : 'rowid'); +if ($user->socid) { + $socid = $user->socid; +} + +$moreparam = ''; + +$object = new Calendar($db); + +// Load object +if ($id > 0 || !empty($ref)) { + $ret = $object->fetch($id, $ref); + $isdraft = (($object->status == Calendar::STATUS_DRAFT) ? 1 : 0); + if ($ret > 0) { + $object->fetch_thirdparty(); + } +} + +// There is several ways to check permission. +// Set $enablepermissioncheck to 1 to enable a minimum low level of checks +$enablepermissioncheck = 0; +if ($enablepermissioncheck) { + $permissiontoread = $user->hasRight('bookcal', 'calendar', 'read'); + $permissiontoadd = $user->hasRight('bookcal', 'calendar', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php + $permissiontodelete = $user->hasRight('bookcal', 'calendar', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); + $permissionnote = $user->hasRight('bookcal', 'calendar', 'write'); // Used by the include of actions_setnotes.inc.php + $permissiondellink = $user->hasRight('bookcal', 'calendar', 'write'); // Used by the include of actions_dellink.inc.php +} else { + $permissiontoread = 1; + $permissiontoadd = 1; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php + $permissiontodelete = 1; + $permissionnote = 1; + $permissiondellink = 1; +} + +if (!isModEnabled("bookcal")) { + accessforbidden(); +} +if (!$permissiontoread) { + accessforbidden(); +} + +/* + * Actions + */ + +$parameters = ''; +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + + +/* + * View + */ + +$form = new Form($db); + +$now = dol_now(); +$title = $langs->trans('Calendar')." - ".$langs->trans('Bookings'); + +llxHeader('', $title, $helpurl); + + +if ($object->id > 0) { + $head = calendarPrepareHead($object); + + print dol_get_fiche_head($head, 'booking', $langs->trans("Calendar"), -1, $object->picto, 0, '', '', 0, '', 1); + + $formconfirm = ''; + + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; + + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
'; + $morehtmlref .= '
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + print '
'; + print '
'; + print ''."\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + + // Other attributes. Fields from hook formObjectOptions and Extrafields. + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; + + // Link to public page + print ''; + print ''; + + print '
LinkPublic page'; + print '
'; + print '
'; + print '
'; + + print '
'; + + print dol_get_fiche_end(); + + + /* + * Bookings + */ + + print '
'; + print ''; + + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + + $sql = "SELECT ac.id, ac.ref, ac.datep as date_start, ac.datep2 as date_end, ac.label, acr.fk_element"; + $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as ac"; + $sql .= " JOIN ".MAIN_DB_PREFIX."actioncomm_resources as acr on acr.fk_actioncomm = ac.id"; + $sql .= " WHERE ac.fk_bookcal_calendar = ".((int) $object->id); + $sql .= " AND ac.code = 'AC_RDV'"; + $sql .= " AND acr.element_type = 'socpeople'"; + $resql = $db->query($sql); + + $num = 0; + if ($resql) { + $i = 0; + + $tmpcontact = new Contact($db); + $tmpactioncomm = new Actioncomm($db); + + $num = $db->num_rows($result); + while ($i < $num) { + $obj = $db->fetch_object($resql); + $tmpcontact->fetch($obj->fk_element); + $tmpactioncomm->fetch($obj->id); + + print ''; + + // Ref + print '\n"; + + // Title + print ''; + + // Amount + print ''; + + // Date process + print ''; + + // Link to make payment now + print ''; + + + print "\n"; + $i++; + } + + $db->free($resql); + } else { + dol_print_error($db); + } + + print "
'.$langs->trans("Ref").''.$langs->trans("Title").''.$langs->trans("DateStart").''.$langs->trans("DateEnd").''.$langs->trans("Contact").'
'.$tmpactioncomm->getNomUrl(1, -1)."'; + print $obj->label; + print ''.dol_print_date($db->jdate($obj->date_start), "dayhour").''.dol_print_date($db->jdate($obj->date_end), "dayhour").''; + print $tmpcontact->getNomUrl(1, -1); + print '
"; + print '
'; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/bookcal/lib/bookcal_calendar.lib.php b/htdocs/bookcal/lib/bookcal_calendar.lib.php index 65c8a38a64a..f586c8845df 100644 --- a/htdocs/bookcal/lib/bookcal_calendar.lib.php +++ b/htdocs/bookcal/lib/bookcal_calendar.lib.php @@ -46,6 +46,14 @@ function calendarPrepareHead($object) $head[$h][2] = 'card'; $h++; + if ($object->status == Calendar::STATUS_VALIDATED) { + $head[$h][0] = dol_buildpath("/bookcal/booking_list.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Bookings"); + $head[$h][2] = 'booking'; + $h++; + } + + if ($showtabofpagecontact) { $head[$h][0] = dol_buildpath("/bookcal/calendar_contact.php", 1).'?id='.$object->id; $head[$h][1] = $langs->trans("Contacts"); diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 99b0b21d20a..9d7e698cc2b 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -716,7 +716,7 @@ $sql .= ' a.datep2,'; $sql .= ' a.percent,'; $sql .= ' a.fk_user_author,a.fk_user_action,'; $sql .= ' a.transparency, a.priority, a.fulldayevent, a.location,'; -$sql .= ' a.fk_soc, a.fk_contact, a.fk_project, a.fk_bookcal_availability,'; +$sql .= ' a.fk_soc, a.fk_contact, a.fk_project, a.fk_bookcal_calendar,'; $sql .= ' a.fk_element, a.elementtype,'; $sql .= ' ca.code as type_code, ca.libelle as type_label, ca.color as type_color, ca.type as type_type, ca.picto as type_picto'; $sql .= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; @@ -905,8 +905,8 @@ if ($resql) { $event->socid = $obj->fk_soc; $event->contact_id = $obj->fk_contact; - $event->fk_bookcal_availability = $obj->fk_bookcal_availability; - if (!empty($event->fk_bookcal_availability)) { + $event->fk_bookcal_calendar = $obj->fk_bookcal_calendar; + if (!empty($event->fk_bookcal_calendar)) { $event->type = "bookcal_calendar"; } @@ -1868,7 +1868,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } elseif ($event->type == 'bookcal_calendar') { $numbirthday++; $colorindex = 3; - $cssclass = 'family_bookcal_calendar_'.(!empty($bookcalcalendarsarray["availabilitieslink"]) ? $bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_availability] : ""); + $cssclass = 'family_bookcal_calendar_'.(!empty($bookcalcalendarsarray["availabilitieslink"]) ? $bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_calendar] : ""); $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]); } else { $numother++; @@ -1957,7 +1957,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($event->type == 'holiday' && !GETPOST('check_holiday')) { $morecss = 'hidden'; } - if ($event->type == 'bookcal_calendar' && !GETPOST('check_bookcal_calendar_'.$bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_availability])) { + if ($event->type == 'bookcal_calendar' && !GETPOST('check_bookcal_calendar_'.$bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_calendar])) { $morecss = 'hidden'; } if ($morecss != 'hidden') { @@ -1968,7 +1968,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } //var_dump($event->type.' - '.$morecss.' - '.$cssclass.' - '.$i.' - '.$ireallyshown.' - '.$itoshow); if (isModEnabled("bookcal") && $event->type == 'bookcal_calendar') { - print '
fk_bookcal_availability].' '.$cssclass.($morecss ? ' '.$morecss : '').'"'; + print '
fk_bookcal_calendar].' '.$cssclass.($morecss ? ' '.$morecss : '').'"'; } else { print '
startHour; + $endHourstring = $obj->endHour; + if ($startHourstring <= 0) { + $startHourstring = 0; + } + if ($endHourstring >= 24) { + $endHourstring = 24; + } $offsethour = round($obj->duration / 60); // Creation of array of availabilties range - if ($datetocheckbooking >= $starttime && $datetocheckbooking < $endtime) { - for ($hour=$obj->startHour; $hour < $obj->endHour; $hour+= $offsethour) { + if ($datetocheckbooking >= $starttime && $datetocheckbooking <= $endtime) { + for ($hour=$startHourstring; $hour < $endHourstring; $hour+= $offsethour) { for ($min=0; $min < 60; $min += $offsetmin) { $hourstring = $hour; $minstring = $min; @@ -123,50 +131,47 @@ if ($action == 'verifyavailability') { } $i++; } - $response["code"] = "SUCCESS"; - } - - // TODO Select also all not available ranges - // Build the list of hours available (key = hour, value = duration) - } - - // Now get ranges already reserved - // TODO Remove this - /*if (!$error) { - $datetocheckbooking_end = dol_time_plus_duree($datetocheckbooking, 1, 'd'); - - $sql = "SELECT b.datep, b.id"; - $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as b"; - $sql .= " WHERE b.datep >= '".$db->idate($datetocheckbooking)."'"; - $sql .= " AND b.datep < '".$db->idate($datetocheckbooking_end)."'"; - $sql .= " AND fk_bookcal_availability IN (SELECT rowid FROM ".MAIN_DB_PREFIX."bookcal_availabilities WHERE fk_bookcal_calendar = ".((int) $id).")"; - //$sql .= " AND b.transparency" - $resql = $db->query($sql); - if ($resql) { - $num = $db->num_rows($resql); - $i = 0; - $response = array(); - $response["content"] = array(); - while ($i < $num) { - $obj = $db->fetch_object($resql); - $dateobject = $obj->datep; - $dateobject = explode(" ", $dateobject)[1]; - $dateobject = explode(":", $dateobject); - - $dateobjectstring = $dateobject[0].$dateobject[1]; - - $response["content"][] = $dateobjectstring; - $i++; - } - if ($i == 0) { - $response["code"] = "NO_DATA_FOUND"; - } else { + if ($i == $num) { $response["code"] = "SUCCESS"; + } else { + $response["code"] = "ERROR"; + $error ++; } - } else { - dol_print_error($db); } - }*/ + + // Select also all not available ranges + if (!$error) { + $datetocheckbooking_end = dol_time_plus_duree($datetocheckbooking, 1, 'd'); + + $sql = "SELECT b.datep, b.id"; + $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as b"; + $sql .= " WHERE b.datep >= '".$db->idate($datetocheckbooking)."'"; + $sql .= " AND b.datep < '".$db->idate($datetocheckbooking_end)."'"; + $sql .= " AND b.code = 'AC_RDV'"; + $sql .= " AND b.status = 0"; + $sql .= " AND b.fk_bookcal_calendar = ".((int) $id); + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) { + $obj = $db->fetch_object($resql); + $datebooking = $db->jdate($obj->datep); + $datebookingarray = dol_getdate($datebooking); + $hourstring = $datebookingarray["hours"]; + $minstring = $datebookingarray["minutes"]; + if ($hourstring < 10) { + $hourstring = "0".$hourstring; + } + if ($minstring < 10) { + $minstring = "0".$minstring; + } + $response["availability"][$hourstring.":".$minstring] *= -1; + $i++; + } + } + } + } $result = $response; } diff --git a/htdocs/public/bookcal/index.php b/htdocs/public/bookcal/index.php index 0aba257d73d..f6fec0ceb2e 100644 --- a/htdocs/public/bookcal/index.php +++ b/htdocs/public/bookcal/index.php @@ -233,14 +233,14 @@ if ($action == 'add') { if (!$error) { $dateend = dol_time_plus_duree(GETPOST("datetimebooking", 'int'), GETPOST("durationbooking"), 'i'); - $actioncomm->label = "test"; + $actioncomm->label = $langs->trans("BookcalBookingTitle"); $actioncomm->type = 'AC_RDV'; $actioncomm->type_id = 5; $actioncomm->datep = GETPOST("datetimebooking", 'int'); $actioncomm->datef = $dateend; $actioncomm->note_private = GETPOST("description"); $actioncomm->percentage = -1; - $actioncomm->fk_bookcal_availability = GETPOST("id_availability", 'int'); + $actioncomm->fk_bookcal_calendar = $id; $actioncomm->userownerid = $calendar->visibility; $actioncomm->contact_id = $contact->id; $actioncomm->socpeopleassigned = $contact->id; @@ -521,13 +521,18 @@ if ($action == 'afteradd') { for(index in timearray){ let hour = new Date("2000-01-01T" + index + ":00"); duration = timearray[index]; + isalreadybooked = false; + if (duration < 0) { + duration *= -1; + isalreadybooked = true; + } hour.setMinutes(hour.getMinutes() + duration); let hours = hour.getHours().toString().padStart(2, "0"); // Formater pour obtenir deux chiffres let mins = hour.getMinutes().toString().padStart(2, "0"); // Formater pour obtenir deux chiffres timerange = index + " - " + `${hours}:${mins}`; - str += "
"; + str += "
"; } $("#buttonlistbooking").html(str); $(".btnsubmitbooking").on("click", function(){ @@ -558,6 +563,7 @@ if ($action == 'afteradd') { timearray = data["availability"]; console.log(timearray); generateBookingButtons(timearray, datestring); + $(".btnbookcalbooked").prop("disabled", true); } else { if(data["code"] == "NO_DATA_FOUND"){ console.log("No booking to hide");