added gitignore
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// ==============================
|
||||
// PATH BASE
|
||||
// ==============================
|
||||
$BASE_PATH = dirname(__DIR__) . '/userarea';
|
||||
|
||||
// ==============================
|
||||
// DB
|
||||
// ==============================
|
||||
require_once $BASE_PATH . '/class/db-functions.php';
|
||||
$db = DBHandlerSelect::getInstance()->getConnection();
|
||||
|
||||
// ==============================
|
||||
// AUTH VANGUARD
|
||||
// ==============================
|
||||
require_once $BASE_PATH . '/../../extra/auth.php';
|
||||
|
||||
// ==============================
|
||||
// AUTH API (TOKEN)
|
||||
// ==============================
|
||||
$user = Auth::guard('api')->user();
|
||||
|
||||
if (!$user) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Unauthorized']);
|
||||
exit;
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* my_lessons.php
|
||||
* --------------------------------------------------------------------------
|
||||
* Endpoint API delle lezioni per l'app Flutter (scuola YogaSoul).
|
||||
*
|
||||
* Posizione prevista sul server: public/api/my_lessons.php
|
||||
* (accanto a _bootstrap.php)
|
||||
*
|
||||
* Autenticazione: gestita da _bootstrap.php (Vanguard, token Bearer).
|
||||
* Dopo il require sono già disponibili:
|
||||
* - $user -> utente autenticato ($user->id == bookingclass.iduser)
|
||||
* - $db -> connessione PDO (da DBHandlerSelect)
|
||||
*
|
||||
* Parametri GET:
|
||||
* - month=YYYY-MM (opzionale, default = mese corrente)
|
||||
*
|
||||
* Logica ricalcata su userpanel.php:
|
||||
* - summary: conteggi utente-globali (acquistate/praticate/prenotate/
|
||||
* da confermare/da programmare/perse)
|
||||
* - lessons: lezioni "booked" del mese selezionato, con regole
|
||||
* can_reschedule / can_delete identiche alla webapp.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/_bootstrap.php';
|
||||
|
||||
// A questo punto $user e $db esistono già (altrimenti _bootstrap ha fatto exit 401).
|
||||
|
||||
$userId = (int) $user->id;
|
||||
|
||||
// Location fissa, come nella webapp (userpanel.php la stampa hardcoded).
|
||||
const LESSON_LOCATION = 'via Valassina 62/B Seregno - Sala Contesto Yoga';
|
||||
|
||||
// ==========================================================================
|
||||
// PARAMETRI: mese
|
||||
// ==========================================================================
|
||||
$month = $_GET['month'] ?? date('Y-m');
|
||||
|
||||
// Validazione: deve essere YYYY-MM, altrimenti fallback al mese corrente.
|
||||
$monthDate = DateTime::createFromFormat('Y-m-d', $month . '-01');
|
||||
if ($monthDate === false) {
|
||||
$month = date('Y-m');
|
||||
$monthDate = new DateTime(date('Y-m') . '-01');
|
||||
}
|
||||
|
||||
// Finestra del mese. Replichiamo la logica di userpanel.php:
|
||||
// se il mese richiesto è quello corrente, si parte da OGGI (non dal giorno 1),
|
||||
// così non si mostrano lezioni già passate del mese in corso.
|
||||
$monthStart = $monthDate->format('Y-m-01');
|
||||
$today = date('Y-m-d');
|
||||
if ($today > $monthStart && date('Y-m') === $month) {
|
||||
$monthStart = $today;
|
||||
}
|
||||
// Fine mese + 1 giorno (bound superiore esclusivo), come nella webapp.
|
||||
$monthEndPlus1 = (clone $monthDate)->modify('first day of next month')->format('Y-m-d');
|
||||
|
||||
// ==========================================================================
|
||||
// SUMMARY: conteggi utente-globali
|
||||
// (tradotti 1:1 dalle query mysqli di userpanel.php in PDO)
|
||||
// ==========================================================================
|
||||
|
||||
// -- Totale biglietti acquistati (SUM nticket sugli ordini dell'utente) -----
|
||||
$stmt = $db->prepare("
|
||||
SELECT COALESCE(SUM(nticket), 0) AS total_tickets
|
||||
FROM orderbook
|
||||
WHERE iduser = :uid
|
||||
");
|
||||
$stmt->execute([':uid' => $userId]);
|
||||
$purchased = (int) $stmt->fetchColumn();
|
||||
|
||||
// -- Stato prenotazioni (passate/future/perse/pending) ----------------------
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$stmt = $db->prepare("
|
||||
SELECT
|
||||
SUM(CASE WHEN ss.dateschedule <= :now1
|
||||
AND bc.status = 'booked'
|
||||
AND bc.lostlesson = 'N' THEN 1 ELSE 0 END) AS passed,
|
||||
SUM(CASE WHEN ss.dateschedule > :now2
|
||||
AND bc.status = 'booked'
|
||||
AND bc.lostlesson = 'N' THEN 1 ELSE 0 END) AS future,
|
||||
SUM(CASE WHEN bc.lostlesson = 'Y'
|
||||
AND bc.status != 'cancelled' THEN 1 ELSE 0 END) AS lost,
|
||||
SUM(CASE WHEN bc.status = 'pending' THEN 1 ELSE 0 END) AS pending
|
||||
FROM bookingclass bc
|
||||
LEFT JOIN serviceschedule ss
|
||||
ON bc.idserviceschedule = ss.idserviceschedule
|
||||
WHERE bc.iduser = :uid
|
||||
AND bc.status != 'cancelled'
|
||||
");
|
||||
$stmt->execute([
|
||||
':now1' => $now,
|
||||
':now2' => $now,
|
||||
':uid' => $userId,
|
||||
]);
|
||||
$counts = $stmt->fetch() ?: [];
|
||||
|
||||
$practiced = (int) ($counts['passed'] ?? 0);
|
||||
$booked = (int) ($counts['future'] ?? 0);
|
||||
$lost = (int) ($counts['lost'] ?? 0);
|
||||
$pending = (int) ($counts['pending'] ?? 0);
|
||||
|
||||
// "Da programmare" = acquistate - praticate - prenotate - da confermare - perse
|
||||
// (identico al calcolo $toprogram di userpanel.php)
|
||||
$toSchedule = $purchased - $practiced - $booked - $pending - $lost;
|
||||
if ($toSchedule < 0) {
|
||||
$toSchedule = 0;
|
||||
}
|
||||
|
||||
$summary = [
|
||||
'purchased' => $purchased,
|
||||
'practiced' => $practiced,
|
||||
'booked' => $booked,
|
||||
'pending' => $pending,
|
||||
'to_schedule' => $toSchedule,
|
||||
'lost' => $lost,
|
||||
];
|
||||
|
||||
// ==========================================================================
|
||||
// LESSONS: lezioni "booked" del mese selezionato
|
||||
// (query principale di userpanel.php, tradotta in PDO)
|
||||
// ==========================================================================
|
||||
$stmt = $db->prepare("
|
||||
SELECT
|
||||
bc.idbookingclass,
|
||||
bc.status,
|
||||
bc.idservice,
|
||||
bc.idorder,
|
||||
bc.lostlesson,
|
||||
ss.dateschedule,
|
||||
s.servicename,
|
||||
s.colorclass,
|
||||
ob.expireon,
|
||||
ob.maxreschedule,
|
||||
ob.reprogrammed
|
||||
FROM bookingclass bc
|
||||
LEFT JOIN service s ON bc.idservice = s.idservice
|
||||
LEFT JOIN serviceschedule ss ON bc.idserviceschedule = ss.idserviceschedule
|
||||
LEFT JOIN orderbook ob ON bc.idorder = ob.idorderbook
|
||||
WHERE bc.iduser = :uid
|
||||
AND bc.status = 'booked'
|
||||
AND ss.dateschedule >= :start
|
||||
AND ss.dateschedule < :end
|
||||
ORDER BY ss.dateschedule ASC
|
||||
");
|
||||
$stmt->execute([
|
||||
':uid' => $userId,
|
||||
':start' => $monthStart . ' 00:00:00',
|
||||
':end' => $monthEndPlus1 . ' 00:00:00',
|
||||
]);
|
||||
$rows = $stmt->fetchAll();
|
||||
|
||||
$lessons = [];
|
||||
$nowDt = new DateTime();
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$dateschedule = $r['dateschedule'] ?? null;
|
||||
if ($dateschedule === null) {
|
||||
continue; // riga orfana senza schedule, la saltiamo
|
||||
}
|
||||
|
||||
$classDt = new DateTime($dateschedule);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Regola oraria can_delete (identica a userpanel.php)
|
||||
// ------------------------------------------------------------------
|
||||
$isSameDay = $classDt->format('Y-m-d') === $nowDt->format('Y-m-d');
|
||||
$classHour = (int) $classDt->format('H');
|
||||
$classMinute = (int) $classDt->format('i');
|
||||
// "prima delle 17:00" = ora < 17, oppure esattamente 17:00
|
||||
$isBefore1700 = ($classHour < 17) || ($classHour === 17 && $classMinute === 0);
|
||||
|
||||
if ($isSameDay) {
|
||||
if ($isBefore1700) {
|
||||
// lezioni prima delle 17: valido fino alle 00:01 dello stesso giorno
|
||||
$deadline = new DateTime($classDt->format('Y-m-d 00:01:00'));
|
||||
} else {
|
||||
// lezioni dalle 17 in poi: valido fino alle 12:00 dello stesso giorno
|
||||
$deadline = new DateTime($classDt->format('Y-m-d 12:00:00'));
|
||||
}
|
||||
$canByTime = $nowDt <= $deadline;
|
||||
} else {
|
||||
// giorni futuri: sempre consentito
|
||||
$canByTime = true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Limite riprogrammazioni dell'ordine (identico a userpanel.php)
|
||||
// ------------------------------------------------------------------
|
||||
$maxreschedule = (int) ($r['maxreschedule'] ?? 0);
|
||||
$reprogrammed = (int) ($r['reprogrammed'] ?? 0);
|
||||
$canReprogram = $reprogrammed < $maxreschedule;
|
||||
|
||||
// Nella webapp i bottoni "Riprogramma" e "Cancella" compaiono entrambi
|
||||
// solo se ($canByTime && $canReprogram). Riproduciamo la stessa condizione.
|
||||
$canReschedule = $canByTime && $canReprogram;
|
||||
$canDelete = $canByTime && $canReprogram;
|
||||
|
||||
$lessons[] = [
|
||||
'booking_id' => (int) $r['idbookingclass'],
|
||||
'status' => (string) $r['status'],
|
||||
'datetime' => $classDt->format('Y-m-d H:i:s'),
|
||||
'date' => $classDt->format('Y-m-d'),
|
||||
'time' => $classDt->format('H:i'),
|
||||
'class_name' => (string) ($r['servicename'] ?? ''),
|
||||
'color' => (string) ($r['colorclass'] ?? '#1ebf73'),
|
||||
'location' => LESSON_LOCATION,
|
||||
'expire_on' => $r['expireon'] ?? null,
|
||||
'lost_lesson' => ($r['lostlesson'] ?? 'N') === 'Y',
|
||||
'can_reschedule' => $canReschedule,
|
||||
'can_delete' => $canDelete,
|
||||
];
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// OUTPUT
|
||||
// ==========================================================================
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'month' => $month,
|
||||
'summary' => $summary,
|
||||
'lessons' => $lessons,
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
+10
-3
@@ -29,16 +29,23 @@ if (isset($_POST['idserviceordered'])) {
|
||||
$idserviceordered = $_POST['idserviceordered'];
|
||||
}
|
||||
|
||||
// Recupera la data di scadenza dell'ordine
|
||||
$expiryQuery = "SELECT expireon FROM orderbook WHERE order_id = ?";
|
||||
// Recover the expiry date of the order linked to the booking being rescheduled
|
||||
$expiryQuery = "SELECT ob.expireon
|
||||
FROM bookingclass bc
|
||||
INNER JOIN orderbook ob ON bc.idorder = ob.idorderbook
|
||||
WHERE bc.idbookingclass = ?";
|
||||
|
||||
$stmt = $conn->prepare($expiryQuery);
|
||||
$stmt->bind_param("i", $idpreviousbooking);
|
||||
$stmt->execute();
|
||||
$expiryResult = $stmt->get_result();
|
||||
|
||||
$expiryDate = null;
|
||||
if ($expiryResult->num_rows > 0) {
|
||||
$row = $expiryResult->fetch_assoc();
|
||||
$expiryDate = new DateTime($row['expireon']);
|
||||
if (!empty($row['expireon'])) {
|
||||
$expiryDate = new DateTime($row['expireon']);
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
Reference in New Issue
Block a user