maak nog 1 extra knop om alle 4 spelers aanwezig in 1x te kunnen selecteren en sla de informatie van aanwezigheid per speler of alle 4 de spelers met tijdstempel op, zodat we ook bij grote groepen en clinics de aanwezigheid kunnen registreren en notities kunnen maken als iemand niet aanwezig was of later aanwezig was, dus als iemand op afwezig staat om 12h maar om 12h30 aanwezig is moet die wijziging ook mogelijk zijn en met tijdstempel worden geregistreerd, gebruik altijd Amsterdam NL tijd, en zorg dat dit binnen het scherm van 1 mobiel zichtbaar is voor de trainer van 4 spelers of bij clinics eventueel in meerdere schermen op alfabet van voornaam en / of achternaam instelbaar van de spelers, eventueel rangschikken op leeftijd geboortedatum woonplaats of telefoonnummer volgorde of zelfs email volgorde of volgorde van aanmelding van registratie, dan zou elke speler dus ook een tijdstempel mogen krijgen van het moment van de registratie van hun profiel en de registratie van hun les of lessenreeks, zo houden we inzichtelijk wie waar wat wanneer waarom hoe en waarvoor of waarmee en hoelang of hoevaak en waardoor - reden van wijzigingen of notities omtrent lesdoelen leerplan en lesvoorbereidingen etc mogelijk zijn voor persoon of personen en teams duo's en samenstelling van groepen of groep en trainers die daarbij in contact waren of nog les geven en in de planning staan of al eerder gepland waren en eventuele lessen die gegeven zijn.
voeg een knop “Iedereen aanwezig” toe en bewaar elke aanwezigheidswijziging met tijdstempel en notitie. Zo blijft zichtbaar wanneer iemand eerst afwezig en later aanwezig was. Ik maak de spelerslijst compact voor mobiel, met vier spelers per pagina en instelbare sortering voor clinics. Alle zichtbare tijdstempels worden in Amsterdamse tijd getoond.
Ik voeg een knop “Iedereen aanwezig” toe en bewaar elke aanwezigheidswijziging met tijdstempel en notitie. Zo blijft zichtbaar wanneer iemand eerst afwezig en later aanwezig was. Ik maak de spelerslijst compact voor mobiel, met vier spelers per pagina en instelbare sortering voor clinics. Alle zichtbare tijdstempels worden in Amsterdamse tijd getoond.
Ik breid dit uit met datumselectie, kopiëren van reeksen, spelerprofielen en leshistorie. Ik controleer eerst de huidige code en sheet, zodat bestaande gegevens behouden blijven. Voor de voorbeeldplanning neem ik voorlopig oktober 2026 tot en met september 2027, met de drie genoemde lesdagen en 60 duidelijk herkenbare testspelers.
Ran 1 command, explored files, used Google Drive en searched the web
Je screenshot bevestigt dat je als admin kunt inboeken. De sheet heeft nog geen lessen of spelers, dus ik kan de voorbeelden toevoegen zonder bestaande planning te overschrijven.
Ik voeg spelergegevens toe in aparte tabbladen en koppel die aan boekingen, zodat leshistorie bewaard blijft bij vervangen of archiveren van spelers. Betaallinks en automatisch mailen worden instelbaar. Een betaling via zo’n link telt pas als betaald na registratie door de admin; automatische bankcontrole vraagt een aparte koppeling met een betaalprovider.
In Code.gs zit de verwerking achter de schermen:
Inloggen met e-mailadres en wachtwoord.
Wachtwoord aanmaken of herstellen na controle van een mailcode.
Wachtwoorden opslaan als beveiligde hash in PT_PASSWORDS.
Beperken van foutieve inlogpogingen.
Mailcodes met spaties of een ontbrekende beginnul verwerken. Een werkelijk verkeerde code blijft geweigerd.
Trainers blijven geblokkeerd totdat een admin ze goedkeurt.
In Index.html zit wat je ziet en aanklikt:
De keuze Mailcode / Wachtwoord / Wachtwoord aanmaken of vergeten.
De wachtwoordvelden en het herhaalveld.
De knoppen die deze gegevens naar Code.gs sturen.
Daarom krijg je beide: Index toont de wachtwoordlogin; Code controleert het wachtwoord en geeft toegang. Alleen Index vervangen geeft wel de velden, maar geen werkende verwerking. Alleen Code vervangen laat het oude inlogscherm staan.
Je gekozen adminwachtwoord staat niet leesbaar in deze bestanden.
oke top als padelstijn ben ik ingelogt, nu wil ik meteen 1 reeks erin kunnen zetten, onderin zie ik datums extra toevoegen maar ik mis dan een knop voor de agenda om datums te selecteren en het liefste ook meteen meerdere datums, dus meerder maandagen of dinsdagen of woensdagen of donderdagen of vrijdagen etc, ook om de lessenreeks te kopieren als ik meerdere uren op de zelfde locatie wil boeken, baannummer, binnen of buiten, 1 les uur en 4 namen van 4 speler, de spelers details opslaan, ook met naam, eventueel extra details zoals telefoonnr email adres niet verplicht maar wel makkelijk als die in het systeem worden weergegeven voor de admin en de trainer, ook speelsterkte,
PadelTrainer • PadelOS • cx v1.0.1
FIX: zichtbare setupPadelTrainer zonder afsluitende underscore.
Stijn Gabeler • GABELER Coaching • Stichting GODOGOOD
• 8 oktober 2026
DIT IS EEN NIEUWE MODULE
De aangeleverde Padelplanner v2.5.18 is de functionele en visuele basis.
De nieuwe module gebruikt een aparte gegevensstructuur en servercontrole op rollen.
Deze levering vervangt de oude Padelplanner niet. Installeer haar in een NIEUW project
dat aan de gekozen padeltrainer-sheet is gebonden. Beide oorspronkelijke bestanden
en de aangeleverde Excel-snapshot blijven ongewijzigd.
Geen oude Google Agenda's, lessen, wachtwoorden of testdata worden automatisch geïmporteerd.
1. INSTALLEREN IN DE GEKOZEN SHEET
Open de nieuwe sheet:
padeltrainer module login lessenreeks locaties spelers datums facturen opmaak bijhouden betalingen
Het aangeleverde exacte sheet-ID is al opgenomen in PT.EXPECTED_SHEET_ID:
1FiJ4Q2tQZr8KLTBSnAMmeybm4eoJCdgz_X40hK-gm-4
Ga in die sheet naar Extensies > Apps Script.
Gebruik een nieuw project, met alleen de bestanden uit deze levering.
Plaats de VOLLEDIGE inhoud van het geleverde GS-bestand in Code.gs.
Maak een HTML-bestand met de naam Index (hoofdletter I, zonder .html in het naamveld).
Plaats daarin de VOLLEDIGE inhoud van het HTML-bestand.
Open Projectinstellingen en zet de weergave van het manifest appsscript.json aan.
Vervang dat manifest door de volledige geleverde JSON-inhoud. Bewaar alles.
De lange cx-namen horen bij de downloadbestanden. In Apps Script heten ze exact:
Code.gs, Index.html en appsscript.json.
TXT-kopieën bevatten exact dezelfde code; maak geen extra Apps Script-bestanden daarvan.
2. TABBLADEN EN EERSTE ADMIN
Sla eerst Code.gs op (Ctrl+S) en ververs zo nodig de Apps Script-editor.
Selecteer bovenaan, naast Uitvoeren en Foutopsporing, setupPadelTrainer.
Klik Uitvoeren en accepteer de toestemmingen met het Google-account van dit project.
Het uitvoeringslog toont daarna: Setup voltooid. Admin: jouw Google-e-mailadres.
De functie heet zonder afsluitende underscore en is zichtbaar in de keuzelijst.
Accepteer de Google-toestemmingen voor dit eigen project.
Deze editorfunctie controleert het sheet-ID en maakt alleen ontbrekende PT_-tabbladen.
De bestaande Sheet1 en eventuele andere tabbladen worden niet gewist.
De Google-gebruiker die de setup uitvoert wordt de eerste admin.
Dit is dus NIET automatisch een hardgecodeerd Stijn-account.
Er worden geen namen, spelers, traineruren of fictieve lessen ingevuld.
Herhaald uitvoeren maakt geen dubbele tabbladen of adminaccounts.
Bij afwijkende bestaande PT_-kolommen stopt de setup met een fout.
Gebruik de spreadsheet als database: verplaats of hernoem PT_-kolommen niet.
De juiste administratie voer je in de webapp in.
De oorspronkelijke Google Sheet is door deze levering nog niet gewijzigd:
de tabbladen ontstaan wanneer je setupPadelTrainer zelf uitvoert.
3. PUBLICEREN
Klik Implementeren > Nieuwe implementatie > Web-app.
Uitvoeren als: jezelf (het Google-account dat de sheet mag bewerken).
Toegang: Iedereen, als deze instelling door je Google-account wordt toegestaan.
De webapp heeft daarna haar eigen mailcode-login; de sheet zelf blijft privé.
Geef spelers en trainers geen bewerktoegang tot de database-sheet of scripteditor.
Open de /exec-link in een normale browsertab en log in met het setup-account.
Een /dev-link is alleen bedoeld voor projecteditors.
Voor elke codewijziging: Implementaties beheren > bewerken > Nieuwe versie.
Behoud daarbij dezelfde bestaande webapp-implementatie.
De aflevering hier is code en installatie, geen reeds gepubliceerde webapp.
4. GOOGLE SITES
Gebruik Invoegen > Insluiten > URL en plak de echte /exec-link.
Geef de insluiting voldoende hoogte, bij voorkeur minimaal 850 px.
Voeg ook een knop 'Open PadelTrainer' toe met dezelfde link voor mobiel.
Die losse browsertab helpt als embedded opslag of printen wordt geblokkeerd.
Plak de HTML-code niet rechtstreeks in Google Sites: google.script.run werkt
alleen wanneer Google Apps Script de Index-pagina levert.
5. EERSTE GEBRUIK
Log als admin in met het Google-e-mailadres dat in het setup-log staat.
Vink Nieuw account registreren UIT: setup heeft dit adminaccount al gemaakt.
Vraag een mailcode aan. Controleer ook Spam/Ongewenst.
Vul onder Beheer > School / factuurgegevens de echte naam, adres, contactgegevens,
IBAN, KvK en btw-ID in. Deze feiten zijn niet namens jou ingevuld.
Voeg locaties toe. Een les kan ook een eigen locatie als tekst krijgen.
Laat trainers registreren met de rol Trainer.
De registratie controleert het mailadres, maar de trainer blijft geblokkeerd.
Zet als admin die aanvraag in Beheer op Trainer en Actief, en sla op.
Daarna vraagt de trainer een NIEUWE mailcode aan en kan inloggen.
Spelers registreren als Speler en kunnen na mailcontrole meteen inloggen.
Admins worden uitsluitend door een ingelogde admin toegekend.
Een admin kan ook zichzelf als trainer aan een les toewijzen.
6. LES / REEKS / CLINIC / REIS
Admin of trainer kiest '+ Les / reeks'. Type is vrij invulbaar.
Aantal 1 maakt één les. Aantal 8 met tussenruimte 7 maakt acht wekelijkse datums.
De optie Eigen reeks met expliciete datums vervangt de berekende datums volledig.
Gebruik 'Datums controleren' om alle datums te bekijken vóór opslaan.
Elke datum blijft een zelfstandig agenda-item met een gezamenlijke reeks-ID.
Een padelreis over meer dagen kan met tussenruimte 1 worden geboekt.
Een onderdeel over middernacht moet worden gesplitst in twee dagonderdelen.
Overlap voor dezelfde trainer wordt op de server geblokkeerd, ook bij voorstellen.
Een trainer boekt uitsluitend voor zichzelf. Dat is direct bevestigd.
Een admin boekt een voorstel voor de gekozen trainer.
De toegewezen trainer bevestigt of wijst dat voorstel af.
Pas na bevestiging én publicatie kunnen spelers boeken.
Capaciteit, spelersprijs per les en trainervergoeding per uur zijn aparte velden.
Spelersprijs en trainervergoeding worden in deze versie vastgezet bij het inboeken.
Bestaande boekingen houden hun eigen prijs. Voor andere tarieven boek je een nieuwe les.
Aanvullende prijs-/factuurcorrecties zijn geen verborgen wijziging van de historie.
7. BOEKINGEN, VERZOEKEN EN COMMUNICATIE
Een speler ziet onder Agenda alleen zijn eigen geboekte lessen, inclusief historie.
Onder Boeken staan gepubliceerde, bevestigde lessen van deze padelschool.
Een speler kan één les of de resterende boekbare lessen van een reeks boeken.
Bij een volle les wordt een reeksboeking volledig afgewezen vóór er boekingen ontstaan.
De server controleert capaciteit en dubbele inschrijvingen onder één scriptlock.
De admin kan bij lesdetails een bestaande speler inschrijven.
Een speler kan een lesverzoek met optionele voorkeursdatum indienen.
De admin beantwoordt het verzoek en kan een lesvoorstel koppelen.
Dat antwoord is geen automatische boeking: de speler boekt het bevestigde aanbod zelf.
De trainer ziet de spelers van zijn toegewezen lessen en registreert aanwezigheid.
Een speler schrijft privé aan de toegewezen trainer.
Een trainer/admin kan aan de lesgroep of aan een ingeschreven speler schrijven.
Communicatie en voorstellen zijn zichtbaar IN de webapp na vernieuwen.
Deze versie stuurt daarvoor geen automatische e-mails, SMS of WhatsApp-berichten.
Alleen een door de gebruiker aangevraagde login-/registratiecode wordt gemaild.
8. AGENDA EN UREN
Dag: volledige lijst met tijden, locatie, trainer en status.
Week: op mobiel opeenvolgende dagen; op desktop zeven leesbare kolommen.
Maand: raster met aantal lessen en eerste tijd; tik op een dag voor de daglijst.
Jaar: twaalf maanden met aantallen en bevestigde/gewerkte geplande duur.
Vooruit/terug, Vandaag, datumkeuze, tekstzoeken en statusfilter zijn beschikbaar.
Voorstellen tellen niet mee als bevestigde planning.
Onder Uren / APK kies je een datumbereik en bekijk je gepland versus gewerkt.
Gewerkte minuten kunnen vanaf de lesdatum worden vastgelegd, niet vóór die datum.
De trainer registreert Analyse, Patroon, Koers, SMART, Evaluatie en privénotities.
Deze gegevens zijn alleen zichtbaar voor de betreffende trainer en de admin.
De gedeelde beschrijving en het gedeelde leerdoel staan juist bij de lesdetails.
De registratie zet een bevestigde les op Uitgevoerd.
Gewerkte uren krijgen de trainervergoeding die bij de les is vastgelegd.
Het dashboard gebruikt aanvankelijk het bereik vanaf de eerste dag van deze maand.
Op de urenpagina volgt het dashboard de daar gekozen selectie.
Openstaande facturen zijn de totale zichtbare openstaande bedragen, los van die urenperiode.
9. DATUMBEVEILIGING
Er is geen knop die een lesrij verwijdert en geen slepen dat de datum wijzigt.
Normaal bewerken accepteert geen wijziging van datum, tijd of trainer op de server.
Alleen de admin opent 'Datum / tijd / trainer wijzigen' of 'Les annuleren'.
De admin geeft een reden en ziet popup 1 om de wijziging te controleren.
De server maakt vervolgens een kort geldige, accountgebonden bevestiging.
Popup 2 vraagt letterlijk 'Wilt u dit echt wijzigen?' met oud en nieuw.
Pas daarna voert de server de wijziging uit en bewaart de historie.
Een bevestiging is eenmalig, vijf minuten geldig en gekoppeld aan de recordversie.
Als een ander de les intussen heeft gewijzigd, wordt de oude bevestiging geweigerd.
Bij wijzigen blijft de oorspronkelijke planning behouden en gaan boekingen mee.
De toegewezen trainer moet de gewijzigde les opnieuw bevestigen.
Bij annuleren blijft de les met status Geannuleerd bestaan.
Facturen/boekingen worden niet gewist of automatisch terugbetaald.
Een les met een urenregistratie kan niet meer worden verplaatst of geannuleerd:
de werkelijk uitgevoerde lesdatum blijft behouden; boek een nieuwe vervolgles.
Gebruik voor deze beveiliging de webapp. Een sheet-eigenaar kan via directe
sheetbewerkingen de applicatieregels omzeilen; deel de database daarom niet met deelnemers.
10. FACTUREN EN BETALINGEN
Trainerfactuur: selecteer eigen gewerkte uren die nog niet zijn gefactureerd.
Netto regel = werkelijk gewerkte minuten / 60 × uurvergoeding, afgerond op centen.
Spelerfactuur: alleen de admin factureert geselecteerde actieve boekingen van één speler.
Netto regel = de bij boeking vastgelegde spelersprijs.
Vul en controleer beide factuurpartijen, datum, vervaldatum en btw-percentage.
Het percentage staat aanvankelijk op 0 en moet door de gebruiker juist worden ingevuld.
De code geeft geen advies over het btw-regime; het veld is bewust handmatig.
Controleer alle factuurgegevens vóór vastleggen.
Btw wordt over het netto subtotaal berekend en afgerond op eurocenten.
Factuurnummer is PT-JAAR-volgnummer; facturen worden niet hernummerd of verwijderd.
Geselecteerde bronnen worden vergrendeld tegen dubbele facturering.
Factuurpartijen en regels zijn vaste snapshots, onafhankelijk van latere schoolgegevens.
Admin registreert betalingen met bedrag, werkelijke betaaldatum en kenmerk.
Meerdere deelbetalingen zijn mogelijk; meer dan openstaand wordt geblokkeerd.
Trainernota's betekenen school → trainer; spelersnota's betekenen speler → school.
Trainer en speler zien hun eigen zichtbare facturen; alleen admin registreert betalingen.
PDF wordt gemaakt via PDF / afdrukken > Opslaan als PDF in de browser.
TXT per factuur, CSV facturen, CSV uren, TXT overzicht en JSON-export zijn aanwezig.
JSON is een export van wat het ingelogde account mag zien; het is geen import/restorefunctie.
Deze eerste versie heeft geen creditnota, betalingscorrectie, externe bankkoppeling,
juridische factuurcontrole of automatische terugbetaling. Correcties worden daarom
niet stilzwijgend op bestaande facturen of betalingen toegepast.
11. LOGIN EN BEHEER
Login gebruikt mailcodes en geen wachtwoorden.
Mailcode: 10 minuten, 5 controlepogingen, nieuwe code maakt oudere codes ongeldig.
Maximaal 5 codeaanvragen per mailadres per uur, minstens 60 seconden tussen aanvragen.
Daarnaast maximaal 50 codeaanvragen per uur voor deze gehele implementatie.
Google MailApp-quota gelden daarnaast. Bij mailfouten verschijnt een foutmelding.
Browser bewaart alleen het sessietoken: standaard in sessionStorage,
of in localStorage wanneer 'Ingelogd blijven' is aangevinkt.
Lessen, spelers en facturen worden niet als offline database in browseropslag bewaard.
De server bewaart alleen de tokenhash en een HMAC-hash van de mailcode.
Een sessie eindigt na 12 uur zonder serveractiviteit of uiterlijk na 7 dagen.
Elke nieuwe device/browser moet afzonderlijk een mailcode aanvragen.
Uitloggen trekt de sessie in en wist de zichtbare gegevens en lokale token.
Als de server bij uitloggen onbereikbaar is, wordt het apparaat alsnog lokaal uitgelogd.
Rolwijzigingen beëindigen bestaande sessies van het aangepaste account.
AUTH_SECRET wordt door setup gemaakt en staat uitsluitend in Script Properties.
Interne functies eindigen op _ en zijn niet met google.script.run oproepbaar.
De zichtbare setupPadelTrainer controleert afzonderlijk dat actieve en uitvoerende
Google-identiteit beschikbaar zijn en overeenkomen; andere gebruikers worden geweigerd.
Er is één padelschool per spreadsheet/project. Gebruik een ander project voor een andere school.
12. TABBLADEN
PT_USERS: accounts, rollen en actieve toegang.
PT_AUTH: gehashte sessies, afloop en laatste activiteit.
PT_OTP: gehashte mailcodes, registratiegegevens en pogingenteller.
PT_EVENTS: lessen, expliciete datums, reekskoppeling, planning en oorspronkelijke datum.
PT_BOOKINGS: inschrijvingen, aanwezigheid, prijs en factuurkoppeling.
PT_REQUESTS: spelersverzoeken, reactie en voorstelkoppeling.
PT_MESSAGES: groeps- en privéberichten per les.
PT_WORK: werkelijke minuten, APK SMART, evaluatie en privénotities.
PT_INVOICES: vaste factuurregels, partijen en bedragen.
PT_PAYMENTS: betalingen en kenmerken.
PT_AUDIT: wijzigingen met oud/nieuw en actor-ID.
PT_CHANGES: eenmalige bevestigingen voor admin-planningswijzigingen.
PT_SETTINGS: gegevens van de padelschool.
PT_LOCATIONS: locaties.
13. CONTROLE NA INSTALLATIE
Open de /exec-link als admin, trainer en speler in gescheiden browserprofielen.
Registreer een trainer en controleer dat inloggen pas na admingoedkeuring lukt.
Laat de admin een voorstel maken, de trainer bevestigen en de speler boeken.
Controleer dat een andere trainer die les niet ziet.
Controleer op mobiel dag/week/maand/jaar en het openen van lesdetails.
Test een datumwijziging: beide popups, oorspronkelijke datum, boeking en trainerherbevestiging.
Leg gewerkte minuten vast, maak een factuur en registreer twee deelbetalingen.
Controleer een PDF en de factuurpartijen vóór werkelijke zakelijke verzending.
Deze stappen gebruiken echte Google-toestemmingen, mail en opslag die hier niet live
zijn uitgevoerd. Er zijn lokaal geautomatiseerde server- en schermcontroles gedaan.
De meegeleverde CONTROLE.txt vermeldt de feitelijke testresultaten en beperkingen.
14. TECHNISCHE GRENZEN
Apps Script is geschikt voor een kleine padelschool, maar alle tabellen worden per
actie gelezen; deze versie is geen onbeperkt schaalbare database.
Scriptlocks beschermen tegen gelijktijdige appacties, niet tegen handmatige sheetedits.
Een Sheets/Apps Script-actiereeks is geen database-transactie met automatische rollback.
Bij een Google-storing halverwege een schrijfactie moet admin de betrokken PT_-rijen
en audit controleren vóór opnieuw klikken, vooral bij reeksen of facturen.
Bewaar versies van de sheet. AUTH/OTP/RATE-historie heeft nog geen automatische opschoning.
Pas productie-opschoning gecontroleerd toe; wis geen planning/factuurhistorie.
OFFICIËLE TECHNISCHE REFERENTIES
https://developers.google.com/apps-script/guides/web
https://developers.google.com/apps-script/guides/html/communication
https://developers.google.com/apps-script/reference/utilities/utilities