Ver Fonte

initial commit

hmt há 6 anos atrás
commit
9435bbc3bf

+ 94 - 0
Abgangszeugnis BFS 2seitig.html

@@ -0,0 +1,94 @@
+{#each schueler as s (s.ID)}
+  {#each s.abschnitte.filter(aktHalbjahr) as hj (hj.ID)}
+    <div class="page grid" orientation="portrait" size="A4">
+      <Seitenlogo logo="{privat.traegerLogo}"/>
+      <Pageheader art="daten/agz.svg" logo="{privat.logo}" untertitel="{privat.untertitel}"/>
+      <div class="main">
+        <div style="font-size: 15pt; line-height: 1.5em">
+          {bg(s, 'Schulform')}
+        </div>
+        <div style="font-size: 12pt; line-height: 1.2em">
+          {bg(s, 'Bereich')}
+          {#if s.ASDSchulform.startsWith('B')}
+            <br />
+            Abschluss {s.Geschlecht === '3' ? bg(s, 'Berufsbezeichnung_m') : bg(s, 'Berufsbezeichnung_w')}
+          {/if}
+        </div>
+        <Voffset v="1"/>
+        <b>{s.anrede} {s.Vorname} {s.Zusatz || ''} {s.Name},</b>
+        <br />geboren am {datum(s.Geburtsdatum)} in {s.Geburtsort},<br />
+        war vom {datum(s.BeginnBildungsgang)} bis {datum(s.Entlassdatum)} {s.schueler_in}
+        des Bildungsgangs {bg(s, 'Zeugniskopf')}.
+        {s.Geschlecht === 3 ? 'Er':'Sie'} war zuletzt {s.schueler_in} in der Klasse {s.Klasse}.
+        <Voffset v="2"/>
+        Leistungen laut Konferenzbeschluss vom {datum(hj.Konferenzdatum)}:
+        <Noten
+          noten={hj.noten}
+          fachGliederungen={s.fachklasse.fach_gliederungen}
+          ger
+          fachklasse={s.fachklasse.Kennung}
+        ></Noten>
+        <hr />
+        <Voffset v="1"/>
+        <b>{versetzungsvermerk(s,hj, true)}</b>
+        <Voffset v="1"/>
+        <b>Bemerkungen</b><br />{@html bemerkungen(hj)}
+      </div>
+      <div class="footer">
+        <div class="flex-grid">
+          <div class="col-2">
+            {schule.Ort}, den {datum(hj.ZeugnisDatum)}
+          </div>
+          <div class="col text-center klein">
+          <Voffset v="3"/>
+            <hr />
+            {schule.SchulleiterVorname} {schule.SchulleiterName} <br />{schule.schulleiter_in}
+          </div>
+          <div class="col text-center klein">
+          <Voffset v="3"/>
+            Siegel
+          </div>
+          <div class="col text-center klein">
+          <Voffset v="3"/>
+            <hr />
+            {hj.v_name_klassenlehrer}<br />{hj.klassenlehrer_in}
+          </div>
+        </div>
+        <Fussnote {schule} ger rechtsbehelfsbelehrung={false} verordnung={false}></Fussnote>
+      </div>
+    </div>
+    <div class="page grid" orientation="portrait" size="A4">
+      <div class="main">
+        Seite 2/2 des Abgangsszeugnisses für {s.anrede} {s.Vorname} {s.Zusatz || ''} {s.Name}
+        <Voffset v="2"/>
+        <SoaTabelle></SoaTabelle>
+      </div>
+      <div class="footer">
+        <Fussnote {schule} bfs notenstufen={false}></Fussnote>
+      </div>
+    </div>
+  {/each}
+{/each}
+
+<script>
+  import { datum, versetzungsvermerk, volljaehrigBei, bemerkungen, bg }  from './helfer'
+
+  export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Noten: './partials/Noten.html',
+      Fussnote: './partials/Fussnoten.html',
+      Voffset: './partials/Voffset.html',
+      SoaTabelle: './partials/SOA-Tabelle.html'
+    },
+    helpers: { bg, datum, versetzungsvermerk, volljaehrigBei, bemerkungen, _ },
+    computed: {
+      aktHalbjahr: ({jahr, abschnitt}) => { return a => a.Jahr === jahr && a.Abschnitt === abschnitt }
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+</style>

+ 264 - 0
Abgangszeugnis BG.html

@@ -0,0 +1,264 @@
+{#each schueler as s (s.ID)}
+  {#each s.abschnitte.filter(aktHalbjahr) as hj (hj.ID)}
+    <div class="page grid" orientation="landscape" size="A3">
+      <div class="header">
+        <Seitenlogo logo="{privat.traegerLogo}"/>
+        <Pageheader art="daten/agz.svg" logo="{privat.logo}" untertitel="{privat.untertitel}"/>
+      </div>
+      <div class="main-grid">
+        <div class="main-left">
+          <div style="font-size: 12pt; line-height: 1.5em">Abgangszeugnis gemäß §13 APO-BK, Anlage D</div>
+          <div style="font-size: 11pt; line-height: 1.2em">Berufliches Gymnasium, {bg(s, 'Bereich')}</div>
+          <Voffset v="0.5"/>
+          {s.anrede} <b>{s.Vorname} {s.Zusatz || ''} {s.Name}</b>, geboren am {datum(s.Geburtsdatum)} in {s.Geburtsort},
+          <br />hat vom {datum(s.Aufnahmedatum)} bis zum {datum(s.Entlassdatum)} den <b>Bildungsgang {bg(s, 'Zeugniskopf')}</b> besucht.
+          <br>{s.Geschlecht === 3 ? 'Er':'Sie'} war zuletzt {s.schueler_in} im {hj.Abschnitt}. Halbjahr der Jahrgangstufe {hj.Jahrgang+10}.
+          <Voffset v="0.5"/>
+          In der Konferenz am {datum(hj.Konferenzdatum)} sind folgende Leistungen festgestellt worden:
+          <table class="table table-bordered table-eng">
+            <tr>
+              <td>Fach</td>
+              <td>Aufg.-<br>feld<sup>2</sup></td>
+              <td>Kurs-<br>Art<sup>3</sup></td>
+              <td colspan="2" class="text-center">12.1<sup>4</sup></td>
+              <td colspan="2" class="text-center">12.2<sup>4</sup></td>
+              <td colspan="2" class="text-center">13.1<sup>4</sup></td>
+              <td colspan="2" class="text-center">13.2<sup>4</sup></td>
+            </tr>
+            <tr>
+              <td colspan="3"></td>
+              <td class="text-center">Note</td>
+              <td class="text-center">Punkte</td>
+              <td class="text-center">Note</td>
+              <td class="text-center">Punkte</td>
+              <td class="text-center">Note</td>
+              <td class="text-center">Punkte</td>
+              <td class="text-center">Note</td>
+              <td class="text-center">Punkte</td>
+            </tr>
+            {#each _.sortBy(s.abi_abschluss_faecher, f => f.FSortierung) as f}
+              <tr>
+                <td>{f.fach.Bezeichnung}
+                  {#if f.fach.IstSprache === '+'}{fremdsprache(f, s.fachklasse.Kennung)}<sup>1</sup>{/if}
+                </td>
+                <td class="text-center">{'I'.repeat(f.fach.Aufgabenfeld)}</td>
+                <td class="text-center">{f.KursartAllg || 'GK'}</td>
+                <td class="text-center">{punkte2note(f.P12_1) || '–'}</td>
+                <td class="text-center">{fhrFach(s, f, '2_1') || '–'}</td>
+                <td class="text-center">{punkte2note(f.P12_2) || '–'}</td>
+                <td class="text-center">{fhrFach(s, f, '2_2') || '–'}</td>
+                <td class="text-center">{punkte2note(f.P13_1) || '–'}</td>
+                <td class="text-center">{fhrFach(s, f, '3_1') || '–'}</td>
+                <td class="text-center">{punkte2note(f.P13_2) || '–'}</td>
+                <td class="text-center">{fhrFach(s, f, '3_2') || '–'}</td>
+              </tr>
+            {/each}
+          </table>
+          <Voffset v="0.5"/>
+          <b>Bemerkungen:
+          <br></b> {@html bemerkungen(hj)}
+        </div>
+        <div class="main-right">
+          <Voffset v="4"/>
+          Die Kurse des letzten Halbjahres gelten als abgeschlossen.
+          <Voffset v="2"/>
+          Dieses Zeugnis gilt in Verbindung mit dem Nachweis über eine
+          abgeschlossene Berufsausbildung oder ein einjähriges gelenktes
+          Praktikum gemäß der Praktikum - Ausbildungsordnung vom 11.12.2006
+          (BASS 13 -31 Nr.1) als Nachweis der Fachhochschulreife. Es
+          berechtigt zum Studium an einer Fachhochschule des Landes
+          Nordrhein-Westfalen. Dieses Zeugnis gilt auch als Nachweis des
+          schulischen Teils der Fachhochschulreife in den Ländern
+          Baden-Württemberg, Berlin, Brandenburg, Bremen, Hamburg, Hessen,
+          Mecklenburg-Vorpommern, Niedersachsen, Rheinland-Pfalz, Saarland,
+          Sachsen-Anhalt, Schleswig-Holstein und Thüringen.
+          <Voffset v="2"/>
+          <table class="table-noten">
+            <tr>
+              <td>Durchschnittsnote:</td>
+              <td class="td-fach-note"><span>{s.fhr_abschluss && s.fhr_abschluss.Note}</span></td>
+              <td>in&nbsp;Worten:</td>
+              <td class="td-fach-note"><span>{s.fhr_abschluss && noteInWorten(s.fhr_abschluss.Note)}</span></td>
+            </tr>
+          </table>
+        </div>
+        <div class="footer-right">
+          <div class="flex-grid">
+            <div class="col-2">
+              {schule.Ort}, den {datum(hj.ZeugnisDatum)}
+            </div>
+            <div class="col text-center klein">
+              <Voffset v="3"/>
+              <hr />
+              {schule.SchulleiterVorname} {schule.SchulleiterName}
+              <br />{schule.schulleiter_in}
+            </div>
+            <div class="col text-center klein">
+              <Voffset v="3"/>
+              Siegel
+            </div>
+            <div class="col text-center klein">
+              <Voffset v="3"/>
+              <hr />
+              {hj.v_name_klassenlehrer}
+              <br />{hj.klassenlehrer_in}
+            </div>
+          </div>
+          <Voffset v="6"/>
+        </div>
+      </div>
+      <div class="footer-grid klein eng">
+        <div class="header">
+          Schulnummer: {schule.SchulNr}
+          <hr />
+        </div>
+        <div class="footer-left">
+          <sup>1</sup>Der Unterricht in den modernen Fremdsprachen hat auf der nach dem Fach in
+          Klammern angegebenen Niveaustufe des „Europäischen Referenzrahmens für
+          Sprachen: Lernen, Lehren, Beurteilen“ stattgefunden. Sind zwei
+          Referenzniveaus ausgewiesen, ist das niedrigere in vollem Umfang, das höhere
+          in Anteilen erreicht. Bei mindestens ausreichenden Leistungen (5 Punkte)
+          wird der sprachliche Kompetenzerwerb auf diesem Niveau bescheinigt.
+          <Voffset v=".5"/>
+          <table>
+            <tr>
+              <td rowspan="4" valign="top" width="5px" ><sup>2</sup> </td>
+              <td width="10px">I</td>
+              <td>= sprachlich literarisches Aufgabenfeld</td>
+              <td rowspan="4" valign="top" width="5px" ><sup>3</sup> </td>
+              <td width="10px">LK</td>
+              <td>= Leistungskurs</td>
+            </tr>
+            <tr>
+              <td>II</td>
+              <td>= gesellschaftswissenschaftliches Aufgabenfeld</td>
+              <td width="10px">GK</td>
+              <td>= Grundkurs</td>
+            </tr>
+            <tr>
+              <td>III</td>
+              <td>= mathematisch-naturwissenschaftlich-technisches Aufgabenfeld</td>
+            </tr>
+          </table>
+          <sup>4</sup> Für die Umsetzung von Noten in Punkte gilt:
+          <table class="table table-bordered table-eng" width="80%">
+            <tr>
+              <td width="5%"></td>
+              {#each ['sehr gut', 'gut', 'befriedigend', 'ausreichend', 'mangelhaft', 'ungenügend'] as n}
+                <td class="text-center" width="10%">{n}</td>
+              {/each}
+            </tr>
+            <tr>
+              <td>Noten</td>
+              {#each [1,2,3,4,5] as i}
+                <td class="text-center">
+                  <div class="flex-grid">
+                    <div class="col">+</div>
+                    <div class="col">{i}</div>
+                    <div class="col">-</div>
+                  </div>
+                </td>
+              {/each}
+              <td class="text-center">6</td>
+            </tr>
+            <tr>
+              <td>Punkte</td>
+              {#each [[15,14,13],[12,11,10],['09','08','07'],['06','05','04'],['03','02','01']] as ii}
+                <td class="text-center">
+                  <div class="flex-grid">
+                    {#each ii as i}
+                      <div class="col">{i}</div>
+                    {/each}
+                  </div>
+                </td>
+              {/each}
+              <td class="text-center">00</td>
+            </tr>
+          </table>
+          <Voffset v=".5"/>
+          <table>
+            <tr>
+              <td width="3%">E1</td>
+              <td width="40%">= Mit besonderem Erfolg teilgenommen</td>
+              <td width="3%">E2</td>
+              <td width="30%">= Mit Erfolg teilgenommen</td>
+              <td width="3%">E3</td>
+              <td width="15%">= Teilgenommen</td>
+            </tr>
+          </table>
+          Die Punkte in Klammern sind nicht in die Durchschnittsnote eingerechnet worden.
+        </div>
+        <div class="footer-right">
+          Dem Zeugnis liegen zugrunde:<br>
+          Die Verordnung über die Ausbildung und Prüfung
+          in den Bildungsgängen des Berufskollegs (Ausbildungs- und Prüfungsordnung
+          Berufskolleg, APO-BK) vom 26. Mai 1999 (SGV. NRW. 223/BASS 13 – 33 Nr. 1.1).
+          <Voffset v=".5"/>
+          Rechtsbehelfsbelehrung:<br>
+          Gegen dieses Zeugnis kann innerhalb eines Monats
+          nach Bekanntgabe des Zeugnisses Widerspruch eingelegt werden. Der Widerspruch
+          ist beim {schule.Bezeichnung2}, {schule.Strasse}, {schule.PLZ} {schule.Ort},
+          schriftlich oder zur Niederschrift zu erheben. <br />Falls die Frist durch
+          das Verschulden einer/eines Bevollmächtigten versäumt wird, wird dies
+          Verschulden der Widerspruchsführerin/dem Widerspruchsführer zugerechnet.
+        </div>
+      </div>
+    </div>
+  {/each}
+{/each}
+
+<script>
+  import { datum, versetzungsvermerk, volljaehrigBei, bemerkungen, bg, punkte2note, noteInWorten, fremdsprache }  from './helfer'
+  const _ = R.lodash
+
+	export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Voffset: './partials/Voffset.html',
+    },
+    helpers: { bg, datum, versetzungsvermerk, volljaehrigBei, bemerkungen, _, punkte2note, noteInWorten, fremdsprache,
+      fhrFach (s, fach, id) {
+        const pid = 'P1' + id
+        if (!fach[pid]) return
+        const fach2 = s.fhr_abschluss_faecher.find(f => f.Fach_ID === fach.Fach_ID)
+        const rsid = 'RSII_' + id
+        return fach2[rsid] === '+' ? fach[pid] : `(${fach[pid]})`
+      }
+    },
+    computed: {
+      aktHalbjahr: ({jahr, abschnitt}) => { return a => a.Jahr === jahr && a.Abschnitt === abschnitt }
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+  @import 'css/a3-landscape.css';
+  .table-bordered {
+    border-collapse: collapse; }
+  .table-bordered tr td {
+    border: thin solid #ddd;
+    line-height: 1.3rem }
+  .table-eng {
+    margin-bottom: 0;
+  }
+  .table-noten {
+    width: 70%;
+    border: none;
+    border-collapse: collapse;
+    margin-bottom: 1rem;
+  }
+  .td-fach-note {
+    padding-bottom: .2rem;
+    padding-top: .2rem;
+    width: 12rem;
+  }
+  .td-fach-note span {
+    background-color: #dcdcdc !important;
+    text-align: center;
+    width: 10rem;
+    display: block;
+    margin: 0 auto;
+  }
+</style>

+ 112 - 0
Abgangszeugnis LF 2seitig.html

@@ -0,0 +1,112 @@
+{#each schueler as s (s.ID)}
+  {#each s.abschnitte.filter(aktHalbjahr) as hj (hj.ID)}
+    <div class="page grid" orientation="portrait" size="A4">
+      <Seitenlogo logo="{privat.traegerLogo}"/>
+      <Pageheader art="daten/agz.svg" logo="{privat.logo}" untertitel="{privat.untertitel}"/>
+      <div class="main">
+        <span style="font-size: 15pt; line-height: 1.5em">
+          {bg(s, 'Schulform')} |
+        </span>
+        <span style="font-size: 12pt; line-height: 1.2em">
+          {bg(s, 'Bereich')}
+        </span>
+        <Voffset v="1"/>
+        <b>{s.anrede} {s.Vorname} {s.Zusatz || ''} {s.Name},</b>
+        <br />geboren am {datum(s.Geburtsdatum)} in {s.Geburtsort},<br />
+        war vom {datum(s.BeginnBildungsgang)} bis {datum(s.Entlassdatum)} {s.studierende_r}
+        des Bildungsgangs {bg(s, 'Zeugniskopf')}.
+        {s.Geschlecht === 3 ? 'Er':'Sie'} war zuletzt {s.studierende_r} in der Klasse {s.Klasse}.
+        <Voffset v="2"/>
+        Leistungen laut Konferenzbeschluss vom {datum(hj.Konferenzdatum)}:
+        <div class="lf-noten">
+          <Noten
+            noten={hj.noten}
+            fachGliederungen={s.fachklasse.fach_gliederungen}
+            ger
+            lernfeld
+            fachklasse={s.fachklasse.Kennung}
+          ></Noten>
+        </div>
+        <hr />
+        <Voffset v="1"/>
+        <b>{versetzungsvermerk(s,hj, true)}</b>
+        <Voffset v="1"/>
+        <b>Bemerkungen</b><br />{@html bemerkungen(hj)}
+      </div>
+      <div class="footer">
+        <div class="flex-grid">
+          <div class="col-2">
+            {schule.Ort}, den {datum(hj.ZeugnisDatum)}
+          </div>
+          <div class="col text-center klein">
+          <Voffset v="3"/>
+            <hr />
+            {schule.SchulleiterVorname} {schule.SchulleiterName} <br />{schule.schulleiter_in}
+          </div>
+          <div class="col text-center klein">
+          <Voffset v="3"/>
+            Siegel
+          </div>
+          <div class="col text-center klein">
+          <Voffset v="3"/>
+            <hr />
+            {hj.v_name_klassenlehrer}<br />{hj.klassenlehrer_in}
+          </div>
+        </div>
+        <div class="flex-grid">
+          {#if !s.ASDSchulform.startsWith('E')}
+            <div class="col-2"></div>
+            <div class="col-2">
+              <Voffset v="1"/>
+              Die Kenntnisnahme wird bestätigt:
+            </div>
+            <div class="col">
+              <Voffset v="3"/>
+              <hr />
+              <div class="klein text-center">
+                {volljaehrigBei(s, hj.ZeugnisDatum) ? s.schueler_in : 'Erziehungsberechtigte'}
+              </div>
+            </div>
+          {/if}
+        </div>
+        <div class="klein eng">
+          <Voffset v="2"/>
+          <div class="schulnummer text-center">
+            Schulnummer: {schule.SchulNr}
+          </div>
+          <hr class="hr-grau" />
+          <div class="grau text-center">
+              Notenstufen gemäß § 48 SchulG: 1 = sehr gut, 2 = gut, 3 = befriedigend,
+              4 = ausreichend, 5 = mangelhaft, 6 = ungenügend
+          </div>
+        </div>
+      </div>
+    </div>
+    <Seite2Fussnote {schule} ger></Seite2Fussnote>
+  {/each}
+{/each}
+
+<script>
+  import { datum, versetzungsvermerk, volljaehrigBei, bemerkungen, bg }  from './helfer'
+
+  export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Noten: './partials/Noten.html',
+      Seite2Fussnote: './partials/Seite2Fussnoten.html',
+      Voffset: './partials/Voffset.html'
+    },
+    helpers: { bg, datum, versetzungsvermerk, volljaehrigBei, bemerkungen, _ },
+    computed: {
+      aktHalbjahr: ({jahr, abschnitt}) => { return a => a.Jahr === jahr && a.Abschnitt === abschnitt }
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+  .lf-noten {
+    font-size: 0.9rem;
+  }
+</style>

+ 79 - 0
Abgangszeugnis.html

@@ -0,0 +1,79 @@
+{#each schueler as s (s.ID)}
+  {#each s.abschnitte.filter(aktHalbjahr) as hj (hj.ID)}
+    <div class="page grid" orientation="portrait" size="A4">
+      <Seitenlogo logo="{privat.traegerLogo}"/>
+      <Pageheader art="daten/agz.svg" logo="{privat.logo}" untertitel="{privat.untertitel}"/>
+      <div class="main">
+        <div style="font-size: 15pt; line-height: 1.5em">
+          {bg(s, 'Schulform')}
+        </div>
+        <div style="font-size: 12pt; line-height: 1.2em">
+          {bg(s, 'Bereich')}
+          <!-- <br />{s.Geschlecht === '3' ? s.fachklasse.Bezeichnung : s.fachklasse.Beschreibung_W} -->
+        </div>
+        <Voffset v="1"/>
+        <b>{s.anrede} {s.Vorname} {s.Zusatz || ''} {s.Name},</b>
+        <br />geboren am {datum(s.Geburtsdatum)} in {s.Geburtsort},<br />
+        war vom {datum(s.BeginnBildungsgang)} bis {datum(s.Entlassdatum)} {s.schueler_in}
+        des Bildungsgangs {bg(s, 'Zeugniskopf')}.
+        {s.Geschlecht === 3 ? 'Er':'Sie'} war zuletzt {s.schueler_in} in der Klasse {s.Klasse}.
+        <Voffset v="2"/>
+        Leistungen laut Konferenzbeschluss vom {datum(hj.Konferenzdatum)}:
+        <Noten
+          noten={hj.noten}
+          fachGliederungen={s.fachklasse.fach_gliederungen}
+          ger
+          fachklasse={s.fachklasse.Kennung}
+        ></Noten>
+        <hr />
+        <b>{versetzungsvermerk(s,hj, true)}</b>
+        <Voffset v="1"/>
+        <b>Bemerkungen</b><br />{@html bemerkungen(hj)}
+      </div>
+      <div class="footer">
+        <div class="flex-grid">
+          <div class="col-2">
+            {schule.Ort}, den {datum(hj.ZeugnisDatum)}
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            <hr />
+            {schule.SchulleiterVorname} {schule.SchulleiterName}<br />{schule.schulleiter_in}
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            Siegel
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            <hr />
+            {hj.v_name_klassenlehrer}<br />{hj.klassenlehrer_in}
+          </div>
+        </div>
+        <Fussnote {schule} ger></Fussnote>
+      </div>
+    </div>
+  {/each}
+{/each}
+
+<script>
+  import { datum, versetzungsvermerk, volljaehrigBei, bemerkungen, bg }  from './helfer'
+
+  export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Noten: './partials/Noten.html',
+      Fussnote: './partials/Fussnoten.html',
+      Voffset: './partials/Voffset.html'
+    },
+    helpers: { bg, datum, versetzungsvermerk, volljaehrigBei, bemerkungen },
+    computed: {
+      aktHalbjahr: ({jahr, abschnitt}) => { return a => a.Jahr === jahr && a.Abschnitt === abschnitt }
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+</style>

+ 29 - 0
Beilage SOA.html

@@ -0,0 +1,29 @@
+{#each schueler as s}
+  <div class="page grid" orientation="portrait" size="A4">
+    <Seitenlogo logo="{privat.traegerLogo}"/>
+    <Pageheader art="daten/zeugnis.svg" logo="{privat.logo}" untertitel="{privat.untertitel}"/>
+    <div class="main">
+      Seite 2/2 des Abschlusszeugnisses für {s.anrede} {s.Vorname} {s.Zusatz || ''} {s.Name}
+      <Voffset v="2"/>
+      <SoaTabelle></SoaTabelle>
+    </div>
+    <div class="footer klein schulnummer">
+      Schulnummer: {schule.SchulNr}
+    </div>
+  </div>
+{/each}
+
+<script>
+  export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Voffset: './partials/Voffset.html',
+      SoaTabelle: './partials/SOA-Tabelle.html'
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+</style>

+ 4 - 0
CSV Import.html

@@ -0,0 +1,4 @@
+{#each schueler as s}
+  <pre>{s.Vorname}
+  </pre>
+{/each}

+ 47 - 0
Fotoliste.html

@@ -0,0 +1,47 @@
+{#await fotos}
+{:then fotosFertig}
+  {#each R.lodash.chunk(schueler, 25) as slice}
+    <div class="page grid" orientation="portrait" size="A4">
+      <div class="main">
+        <h5>{slice[0].Klasse}</h5>
+        Stand: {datum}
+        <div class="grid">
+          {#each slice as s}
+            <div>
+              <img src="data:image/jpg;base64,{fotosFertig[s.ID]}" alt="Foto" style="width: 120px">
+              <br>
+              {s.Name}, {s.Vorname}
+            </div>
+          {/each}
+        </div>
+      </div>
+    </div>
+  {/each}
+{/await}
+
+<style>
+  @import 'css/main.css';
+  .grid {
+    display: grid;
+    grid-template-columns: repeat(5, 1fr);
+    grid-gap: 10px;
+  }
+</style>
+
+<script>
+  const SchuelerFoto = R.models.Schuelerfoto
+
+  export default {
+    computed: {
+      fotos: async ({schueler, knexConfig}) => {
+        SchuelerFoto.knex(R.knex(knexConfig))
+        const schuelerfotos = await SchuelerFoto.query().whereIn('Schueler_ID', schueler.map(s => s.ID))
+        return schuelerfotos.reduce(
+          (f, element) => ({...f, [element.Schueler_ID]: Buffer.from(element.Foto, 'binary').toString('base64')}),
+          {})
+      }
+    },
+    data () { return { datum: new Date().toLocaleDateString('de', {day: '2-digit', month: '2-digit', year: 'numeric'}) } },
+    helpers: { R },
+  }
+</script>

+ 72 - 0
Halbjahreszeugnis LF.html

@@ -0,0 +1,72 @@
+{#each schueler as s (s.ID)}
+  {#each s.abschnitte.filter(aktHalbjahr) as hj (hj.ID)}
+    <div class="page grid" orientation="portrait" size="A4">
+      <Seitenlogo logo="{privat.traegerLogo}"/>
+      <Pageheader art="daten/zeugnis.svg" logo="{privat.logo}" untertitel="{privat.untertitel}"/>
+      <div class="main">
+        <div style="font-size: 15pt; line-height: 1.5em">
+          {bg(s, 'Schulform')}
+        </div>
+        <div style="font-size: 12pt; line-height: 1.2em">
+          {bg(s, 'Bereich')}
+        </div>
+        <Voffset v="1"/>
+        <b>{s.anrede} {s.Vorname} {_.toString(s.Zusatz)} {s.Name},</b>
+        <br />geboren am {datum(s.Geburtsdatum)} in {s.Geburtsort},<br />
+        besuchte im Schuljahr {hj.schuljahr} die Klasse {hj.Klasse}
+        <Voffset v="2"/>
+        Leistungen laut Konferenzbeschluss vom {datum(hj.Konferenzdatum)}:
+        <div class="lf-noten">
+          <Noten lernfeld noten={hj.noten} fachGliederungen={s.fachklasse.fach_gliederungen}></Noten>
+        </div>
+        <hr />
+        Fehlstunden: {Number(hj.SumFehlStd) || 0}{#if Number(hj.SumFehlStdU) > 0}, davon unentschuldigt: {hj.SumFehlStdU}<Voffset v="1"/>{/if}
+        <Voffset v="1"/>
+        <b>Bemerkungen</b><br />{@html bemerkungen(hj)}
+      </div>
+      <div class="footer">
+        <div class="flex-grid">
+          <div class="col-2">
+            {schule.Ort}, den {datum(hj.ZeugnisDatum)}
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            <hr />
+            {hj.v_name_klassenlehrer}<br />{hj.klassenlehrer_in}
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            Siegel
+          </div>
+        </div>
+        <Fussnote schule={schule}></Fussnote>
+      </div>
+    </div>
+  {/each}
+{/each}
+
+<script>
+  import { datum, versetzungsvermerk, volljaehrigBei, bemerkungen, bg }  from './helfer'
+  const _ = R.lodash
+
+	export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Noten: './partials/Noten.html',
+      Fussnote: './partials/Fussnoten.html',
+      Voffset: './partials/Voffset.html'
+    },
+    helpers: { bg, datum, versetzungsvermerk, volljaehrigBei, bemerkungen, _ },
+    computed: {
+      aktHalbjahr: ({jahr, abschnitt}) => { return a => a.Jahr === jahr && a.Abschnitt === abschnitt }
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+  .lf-noten {
+    font-size: 0.9rem;
+  }
+</style>

+ 85 - 0
Halbjahreszeugnis.html

@@ -0,0 +1,85 @@
+{#each schueler as s (s.ID)}
+  {#each s.abschnitte.filter(aktHalbjahr) as hj (hj.ID)}
+    <div class="page grid" orientation="portrait" size="A4">
+      <Seitenlogo logo="{privat.traegerLogo}"/>
+      <Pageheader art="daten/zeugnis.svg" logo="{privat.logo}" untertitel="{privat.untertitel}"/>
+      <div class="main">
+        <div style="font-size: 15pt; line-height: 1.5em">
+          {bg(s, 'Schulform')}
+        </div>
+        <div style="font-size: 12pt; line-height: 1.2em">
+          {bg(s, 'Bereich')}
+          {#if s.ASDSchulform.startsWith('B')}
+            <br />
+            Abschluss {s.Geschlecht === '3' ? bg(s, 'Berufsbezeichnung_m') : bg(s, 'Berufsbezeichnung_w')}
+          {/if}
+        </div>
+        <Voffset v="1"/>
+        <b>{s.anrede} {s.Vorname} {_.toString(s.Zusatz)} {s.Name},</b>
+        <br />geboren am {datum(s.Geburtsdatum)} in {s.Geburtsort},<br />
+        besuchte im {hj.Abschnitt}. Halbjahr des Schuljahres {hj.schuljahr} die Klasse {hj.Klasse}
+        <Voffset v="2"/>
+        Leistungen laut Konferenzbeschluss vom {datum(hj.Konferenzdatum)}:
+        <Noten noten={hj.noten} fachGliederungen={s.fachklasse.fach_gliederungen}></Noten>
+        <hr />
+        Fehlstunden: {Number(hj.SumFehlStd) || 0}{#if Number(hj.SumFehlStdU) > 0}, davon unentschuldigt: {hj.SumFehlStdU}<Voffset v="1"/>{/if}
+        <Voffset v="1"/>
+        <b>Bemerkungen</b><br />{@html bemerkungen(hj)}
+      </div>
+      <div class="footer">
+        <div class="flex-grid">
+          <div class="col-2">
+            {schule.Ort}, den {datum(hj.ZeugnisDatum)}
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            <hr />
+            {hj.v_name_klassenlehrer}<br />{hj.klassenlehrer_in}
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            Siegel
+          </div>
+        </div>
+        <div class="flex-grid">
+          <div class="col-2"></div>
+          <div class="col-2">
+            <Voffset v="1"/>
+            Die Kenntnisnahme wird bestätigt:
+          </div>
+          <div class="col">
+            <Voffset v="3"/>
+            <hr />
+            <div class="klein text-center">
+              {volljaehrigBei(s, hj.ZeugnisDatum) ? s.schueler_in : 'Erziehungsberechtigte'}
+            </div>
+          </div>
+        </div>
+        <Fussnote schule={schule}></Fussnote>
+      </div>
+    </div>
+  {/each}
+{/each}
+
+<script>
+  import { datum, versetzungsvermerk, volljaehrigBei, bemerkungen, bg }  from './helfer'
+  const _ = R.lodash
+
+	export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Noten: './partials/Noten.html',
+      Fussnote: './partials/Fussnoten.html',
+      Voffset: './partials/Voffset.html'
+    },
+    helpers: { datum, versetzungsvermerk, volljaehrigBei, bemerkungen, _ , bg },
+    computed: {
+      aktHalbjahr: ({jahr, abschnitt}) => { return a => a.Jahr === jahr && a.Abschnitt === abschnitt },
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+</style>

+ 102 - 0
Jahreszeugnis.html

@@ -0,0 +1,102 @@
+{#each schueler as s (s.ID)}
+  {#each s.abschnitte.filter(aktHalbjahr) as hj (hj.ID)}
+    <div class="page grid" orientation="portrait" size="A4">
+      <Seitenlogo logo="{privat.traegerLogo}"/>
+      <Pageheader art="daten/zeugnis.svg" logo="{privat.logo}" untertitel="{privat.untertitel}"/>
+      <div class="main">
+        <div style="font-size: 15pt; line-height: 1.5em">
+          {bg(s, 'Schulform')}
+        </div>
+        <div style="font-size: 12pt; line-height: 1.2em">
+          {bg(s, 'Bereich')}
+          <br />{s.Geschlecht === '3' ? s.fachklasse.Bezeichnung : s.fachklasse.Beschreibung_W}
+          {#if s.ASDSchulform.startsWith('B')}
+            <br />
+            Abschluss {s.Geschlecht === '3' ? bg(s, 'Berufsbezeichnung_m') : bg(s, 'Berufsbezeichnung_w')}
+          {/if}
+        </div>
+        <Voffset v="1"/>
+        <b>{s.anrede} {s.Vorname} {s.Zusatz || ''} {s.Name},</b>
+        <br />geboren am {datum(s.Geburtsdatum)} in {s.Geburtsort},<br />
+        {#if s.ASDSchulform.startsWith('E')}
+          besuchte das Schuljahr {hj.schuljahr} in der Klasse {hj.Klasse}
+        {:else}
+          besuchte im {hj.Abschnitt}. Halbjahr des Schuljahres {hj.schuljahr} die Klasse {hj.Klasse}
+        {/if}
+        <Voffset v="2"/>
+        Leistungen laut Konferenzbeschluss vom {datum(hj.Konferenzdatum)}:
+        <Noten noten={hj.noten} fachGliederungen={s.fachklasse.fach_gliederungen}></Noten>
+        <hr />
+        {#if !s.ASDSchulform.startsWith('E')}
+          Fehlstunden: {Number(hj.SumFehlStd) || 0}{#if Number(hj.SumFehlStdU) > 0}, davon unentschuldigt: {hj.SumFehlStdU}
+            <Voffset v="1"/>
+          {/if}
+        {/if}
+        <Voffset v="1"/>
+        <b>{versetzungsvermerk(s,hj)}</b>
+        <Voffset v="1"/>
+        <b>Bemerkungen</b><br />{@html bemerkungen(hj)}
+      </div>
+      <div class="footer">
+        <div class="flex-grid">
+          <div class="col-2">
+            {schule.Ort}, den {datum(hj.ZeugnisDatum)}
+          </div>
+          <div class="col text-center klein">
+          <Voffset v="3"/>
+            <hr />
+            {schule.SchulleiterVorname} {schule.SchulleiterName} <br />{schule.schulleiter_in}
+          </div>
+          <div class="col text-center klein">
+          <Voffset v="3"/>
+            Siegel
+          </div>
+          <div class="col text-center klein">
+          <Voffset v="3"/>
+            <hr />
+            {hj.v_name_klassenlehrer}<br />{hj.klassenlehrer_in}
+          </div>
+        </div>
+        <div class="flex-grid">
+          {#if !s.ASDSchulform.startsWith('E')}
+            <div class="col-2"></div>
+            <div class="col-2">
+              <Voffset v="1"/>
+              Die Kenntnisnahme wird bestätigt:
+            </div>
+            <div class="col">
+              <Voffset v="3"/>
+              <hr />
+              <div class="klein text-center">
+                {volljaehrigBei(s, hj.ZeugnisDatum) ? s.schueler_in : 'Erziehungsberechtigte'}
+              </div>
+            </div>
+          {/if}
+        </div>
+        <Fussnote schule={schule}></Fussnote>
+      </div>
+    </div>
+  {/each}
+{/each}
+
+<script>
+  import { datum, versetzungsvermerk, volljaehrigBei, bemerkungen, bg }  from './helfer'
+
+  export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Noten: './partials/Noten.html',
+      Fussnote: './partials/Fussnoten.html',
+      Voffset: './partials/Voffset.html'
+    },
+    helpers: { bg, datum, versetzungsvermerk, volljaehrigBei, bemerkungen, _ },
+    computed: {
+      aktHalbjahr: ({jahr, abschnitt}) => { return a => a.Jahr === jahr && a.Abschnitt === abschnitt }
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+</style>

+ 231 - 0
Schullaufbahnbescheinigung AHR.html

@@ -0,0 +1,231 @@
+{#each schueler as s (s.ID)}
+  {#each s.abschnitte.filter(aktHalbjahr) as hj (hj.ID)}
+    <div class="page grid" orientation="portrait" size="A4">
+      <div class="header">
+        <Seitenlogo logo="{privat.traegerLogo}"/>
+        <Pageheader logo="{privat.logo}" untertitel="{privat.untertitel}"/>
+      </div>
+      <div class="main">
+        <div style="font-size: 12pt; line-height: 1.5em">Bescheinigung über die Schullaufbahn gemäß §13 APO-BK, Anlage D</div>
+        <div style="font-size: 11pt; line-height: 1.2em">Berufliches Gymnasium, Bereich Gesundheit und Soziales</div>
+        <Voffset v="0.5"/>
+        {s.anrede} <b>{s.Vorname} {s.Zusatz || ''} {s.Name}</b>, geboren am {datum(s.Geburtsdatum)} in {s.Geburtsort},
+        <br />besuchte im Schuljahr {hj.schuljahr} die Jahrgangsstufe {parseInt(hj.ASDJahrgang)+10}.{hj.Abschnitt} im Bildungsgang
+        <br /><b>{bg(s, 'Bereich')}</b>.
+        <Voffset v="0.5"/>
+        In der Konferenz am {datum(hj.Konferenzdatum)} sind folgende Leistungen festgestellt worden:
+        <table class="table table-bordered table-eng">
+          <tr>
+            <td rowspan="2">Fach<sup>1</sup></td>
+            <td rowspan="2" width="20px">Aufg.- feld<sup>2</sup></td>
+            <td rowspan="2" width="20px">Abitur- fach<sup>3</sup></td>
+            <td rowspan="2" width="20px">Fach der Berufs- abschlussprüfung</td>
+            <td colspan="4">Leistungen im Halbjahr<sup>4, 5</sup></td>
+          </tr>
+          <tr>
+            <td class="text-center">12.1</td>
+            <td class="text-center">12.2</td>
+            <td class="text-center">13.1</td>
+            <td class="text-center">13.2</td>
+          </tr>
+          {#each _.sortBy(s.abi_abschluss_faecher, f => f.fach.Sortierung) as f}
+            <tr>
+              <td>{f.fach.Bezeichnung}</td>
+              <td class="text-center">{'I'.repeat(f.fach.Aufgabenfeld)}</td>
+              <td class="text-center">{f.AbiFach || ''}</td>
+              <td class="text-center">{_.inRange(parseInt(f.AbiFach), 1, 3) || f.FachKrz === 'DM' ? '+' : ''}
+              <td class="text-center">{f.P12_1 || '–'}</td>
+              <td class="text-center">{f.P12_2 || '–'}</td>
+              <td class="text-center">{f.P13_1 || '–'}</td>
+              <td class="text-center">{f.P13_2 || '–'}</td>
+            </tr>
+          {/each}
+        </table>
+        Versäumte Stunden: {parseInt(hj.SumFehlStd) || 0}, davon unentschuldigt: {parseInt(hj.SumFehlStdU) || 0}
+        <Voffset v="0.5"/>
+        Kurse unter 5 Punkten in den Fächern und Jahrgangsstufen:
+        <table>
+          <tr>
+            <td width="7%"><b>12.1:</b></td>
+            <td width="40%">{s.abi_abschluss_faecher.filter(f => parseInt(f.P12_1) < 5 && parseInt(f.P12_1) > 0).map(f => f.fach.Bezeichnung).join(', ') || '- keine -'}</td>
+            {#if hj.Jahrgang === 3 || hj.Jahrgang === 2 && hj.Abschnitt === 2}
+              <td width="7%"><b>12.2:</b></td>
+              <td width="40%">{s.abi_abschluss_faecher.filter(f => parseInt(f.P12_2) < 5 && parseInt(f.P12_2) > 0).map(f => f.fach.Bezeichnung).join(', ') || '- keine -'}</td>
+            {/if}
+          </tr>
+          {#if hj.Jahrgang === 3}
+            <tr>
+              <td><b>13.1:</b></td>
+              <td width="40%">{s.abi_abschluss_faecher.filter(f => parseInt(f.P13_1) < 5 && parseInt(f.P13_1) > 0).map(f => f.fach.Bezeichnung).join(', ') || '- keine -'}</td>
+              {#if hj.Jahrgang === 3 && hj.Abschnitt === 2}
+                <td width="7%"><b>13.2:</b></td>
+                <td width="40%">{s.abi_abschluss_faecher.filter(f => parseInt(f.P13_2) < 5 && parseInt(f.P13_2) > 0).map(f => f.fach.Bezeichnung).join(', ') || '- keine -'}</td>
+              {/if}
+            </tr>
+          {/if}
+        </table>
+        <Voffset v="0.5"/>
+        {#if s.abi_abschluss_faecher.some(f => [f.P12_1, f.P12_2, f.P13_1, f.P13_2].some(ff => parseInt(ff) < 5 && parseInt(ff) > 0))}
+          Ihre Schullaufbahn weist Defizite auf, durch die die Zulassung zur
+          Abiturprüfung und zur Berufsabschlussprüfung gefährdet wird.
+        {/if}
+        <Voffset v="0.5"/>
+        <b>Bemerkungen:</b> {@html bemerkungen(hj)}
+      </div>
+      <div class="footer">
+        <div class="flex-grid">
+          <div class="col-2">
+            {schule.Ort}, den {datum(hj.ZeugnisDatum)}
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            <hr />
+            {schule.SchulleiterVorname} {schule.SchulleiterName}
+            <br />{schule.schulleiter_in}
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            Siegel
+          </div>
+          <div class="col text-center klein">
+            <Voffset v="3"/>
+            <hr />
+            {hj.v_name_klassenlehrer}
+            <br />{hj.klassenlehrer_in}
+          </div>
+        </div>
+        <div class="flex-grid">
+          <div class="col-2"></div>
+          <div class="col-2">
+            <Voffset v="1"/>
+            Die Kenntnisnahme wird bestätigt:
+          </div>
+          <div class="col">
+            <Voffset v="3"/>
+            <hr />
+            <div class="klein text-center">
+              {volljaehrigBei(s, hj.ZeugnisDatum) ? s.schueler_in : 'Erziehungsberechtigte'}
+            </div>
+          </div>
+        </div>
+        <div class="klein eng">
+          Schulnummer: {schule.SchulNr}
+          <hr />
+          <table>
+            <tr>
+              <td><sup>1</sup> </td>
+              <td colspan="5">In der Reihenfolge der erlassenen Stundentafel</td>
+            </tr>
+            <tr>
+              <td rowspan="4" valign="top"><sup>2</sup> </td>
+              <td>I</td>
+              <td width="70%">= sprachlich literarisches Aufgabenfeld</td>
+              <td align="right" rowspan="4" valign="top"><sup>3</sup> </td>
+              <td>1</td>
+              <td>= erstes Leistungsfach</td>
+            </tr>
+            <tr>
+              <td>II</td>
+              <td>= gesellschaftswissenschaftliches Aufgabenfeld</td>
+              <td>2</td>
+              <td>= zweites Leistungsfach</td>
+            </tr>
+            <tr>
+              <td>III</td>
+              <td>= mathematisch-naturwissenschaftlich-technisches Aufgabenfeld</td>
+              <td>3</td>
+              <td>= drittes Abiturfach</td>
+            </tr>
+            <tr>
+              <td colspan="2"></td>
+              <td>4</td>
+              <td>= viertes Abiturfach</td>
+            </tr>
+          </table>
+          <sup>4</sup> Für die Umsetzung von Noten in Punkte gilt:
+          <table class="table table-bordered table-eng" width="80%">
+            <tr>
+              <td width="5%"></td>
+              {#each ['sehr gut', 'gut', 'befriedigend', 'ausreichend', 'mangelhaft', 'ungenügend'] as n}
+                <td class="text-center" width="10%">{n}</td>
+              {/each}
+            </tr>
+            <tr>
+              <td>Noten</td>
+              {#each [1,2,3,4,5] as i}
+                <td class="text-center">
+                  <div class="flex-grid">
+                    <div class="col">+</div>
+                    <div class="col">{i}</div>
+                    <div class="col">-</div>
+                  </div>
+                </td>
+              {/each}
+              <td class="text-center">6</td>
+            </tr>
+            <tr>
+              <td>Punkte</td>
+              {#each [[15,14,13],[12,11,10],['09','08','07'],['06','05','04'],['03','02','01']] as ii}
+                <td class="text-center">
+                  <div class="flex-grid">
+                    {#each ii as i}
+                      <div class="col">{i}</div>
+                    {/each}
+                  </div>
+                </td>
+              {/each}
+              <td class="text-center">00</td>
+            </tr>
+          </table>
+          <Voffset v=".5"/>
+          <table>
+            <tr>
+              <td width="1%"><sup>5</sup> </td>
+              <td width="3%">E1</td>
+              <td width="40%">= Mit besonderem Erfolg teilgenommen</td>
+              <td width="3%">E2</td>
+              <td width="30%">= Mit Erfolg teilgenommen</td>
+              <td width="3%">E3</td>
+              <td width="15%">= Teilgenommen</td>
+            </tr>
+          </table>
+        </div>
+      </div>
+    </div>
+    <div class="page grid" orientation="portrait" size="A4">
+      <div class="footer grau">
+        <Fussnote {schule}></Fussnote>
+      </div>
+    </div>
+  {/each}
+{/each}
+
+<script>
+  import { datum, versetzungsvermerk, volljaehrigBei, bemerkungen, bg }  from './helfer'
+  const _ = R.lodash
+
+	export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Voffset: './partials/Voffset.html',
+      Fussnote: './partials/Fussnoten.html'
+    },
+    helpers: { bg, datum, versetzungsvermerk, volljaehrigBei, bemerkungen, _ },
+    computed: {
+      aktHalbjahr: ({jahr, abschnitt}) => { return a => a.Jahr === jahr && a.Abschnitt === abschnitt }
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+  .table-bordered {
+    border-collapse: collapse; }
+  .table-bordered tr td {
+    border: thin solid #ddd;
+    line-height: 1.3rem }
+  .table-eng {
+    margin-bottom: 0;
+  }
+</style>

+ 3 - 0
css/a3-landscape.css

@@ -0,0 +1,3 @@
+@page {
+  size: A3 landscape;
+}

+ 3 - 0
css/a3-portrait.css

@@ -0,0 +1,3 @@
+@page {
+  size: A3 portrait;
+}

+ 3 - 0
css/a4-landscape.css

@@ -0,0 +1,3 @@
+@page {
+  size: A4 landscape;
+}

+ 3 - 0
css/a4-portrait.css

@@ -0,0 +1,3 @@
+@page {
+  size: A4 portrait;
+}

+ 300 - 0
css/main.css

@@ -0,0 +1,300 @@
+@charset "UTF-8";
+@import url(normalize.css);
+@font-face {
+  font-family: 'TeX Gyre Heros';
+  src: url("../daten/texgyreheros-regular-webfont.woff") format("woff");
+  font-style: normal;
+}
+@font-face {
+  font-family: 'TeX Gyre Heros';
+  src: url("../daten/texgyreheros-bold-webfont.woff") format("woff");
+  font-style: normal;
+  font-weight: bold;
+}
+@font-face {
+  font-family: 'TeX Gyre Heros';
+  src: url("../daten/texgyreheros-italic-webfont.woff") format("woff");
+  font-style: italic;
+}
+@font-face {
+  font-family: 'TeX Gyre Heros';
+  src: url("../daten/texgyreheros-bolditalic-webfont.woff") format("woff");
+  font-style: italic;
+  font-weight: bold;
+}
+
+@media screen {
+  .page {
+    border: 1px solid black;
+    box-shadow: 5px 5px 4px 0 silver;
+  }
+}
+
+@media print {
+  * {
+    -webkit-print-color-adjust: exact;
+  }
+
+  .page {
+    page-break-after: always;
+    page-break-inside: avoid;
+    margin: 0;
+  }
+}
+
+@page {
+  margin: 0;
+  size: auto;
+}
+
+html {
+  font-size: 10pt;
+}
+
+.page {
+  line-height: 1.5;
+  font-weight: normal;
+  font-family: "Tex Gyre Heros";
+  color: #333;
+  position: relative;
+  padding: 10mm 25mm 10mm 25mm;
+  display: block;
+}
+
+/*
+Da *named pages*, also z.B. @page a3landscape noch nicht von Chrome
+unterstützt werden, gilt vorerst die Standard-Einstellung von A4 Portrait.
+Um andere Formate zu erzeugen, muss die Größe in den svelte-Koponenten
+als setup-Einstellung hinterlegt werden. Oder man verwendet ein besonderes CSS
+mit der anderen Einstellung.
+Dazu bitte ein @import 'nicht_a4_portrait.css' verwenden. Svelte ignoriert sonst
+die in den <style> tags hinterlegten @... Anweisungen.
+Link: https://www.w3.org/TR/css3-page/#using-named-pages
+*/
+
+.page[size="A4"][orientation="portrait"] {
+  /* page: a4portrait; */
+  width: 210mm;
+  height: 296.8mm;
+}
+/* @page a4portrait {
+  margin: 0;
+  size: A4 portrait;
+} */
+
+.page[size="A4"][orientation="landscape"] {
+  /* page: a4landscape; */
+  width: 296.8mm;
+  height: 209mm;
+}
+/* @page a4landscape {
+  margin: 0;
+  size: A4 landscape;
+} */
+
+.page[size="A3"][orientation="portrait"] {
+  /* page: a3portrait; */
+  width: 296.8mm;
+  height: 420mm;
+}
+/* @page a3portrait {
+  margin: 0;
+  size: A3 portrait;
+} */
+
+.page[size="A3"][orientation="landscape"] {
+  /* page: a3landscape; */
+  width: 420mm;
+  height: 296.8mm;
+}
+/* @page a3landscape {
+  margin: 0;
+  size: A3 landscape;
+} */
+
+.page[size="A5"][orientation="portrait"] {
+  /* page: a5portrait; */
+  width: 148mm;
+  height: 210mm;
+}
+/* @page a5portrait {
+  margin: 0;
+  size: A5 portrait;
+} */
+
+.page[size="A5"][orientation="landscape"] {
+  /* page: a5landscape; */
+  width: 210mm;
+  height: 148mm;
+}
+/* @page a5landscape {
+  margin: 0;
+  size: A5 landscape;
+} */
+
+/* Typography */
+h1, h2, h3, h4, h5, h6 {
+  font-weight: 300;
+  letter-spacing: -.1rem;
+  margin-bottom: 2.0rem;
+  margin-top: 0;
+}
+h1 {
+  font-size: 4.6rem;
+  line-height: 1.2;
+}
+h2 {
+  font-size: 3.6rem;
+  line-height: 1.25;
+}
+h3 {
+  font-size: 2.8rem;
+  line-height: 1.3;
+}
+h4 {
+  font-size: 2.2rem;
+  letter-spacing: -.08rem;
+  line-height: 1.35;
+}
+h5 {
+  font-size: 1.8rem;
+  letter-spacing: -.05rem;
+  line-height: 1.5;
+}
+h6 {
+  font-size: 1.6rem;
+  letter-spacing: 0;
+  line-height: 1.4;
+}
+p {
+  margin-top: 0;
+}
+
+.grid {
+  display: grid;
+  grid-gap: 0;
+  gap: 0;
+  /* align-content: start; */
+  grid-template-columns: auto;
+  grid-template-rows: auto 1fr auto;
+  grid-template-areas: "header" "main" "footer";
+}
+
+.header {
+  grid-area: header;
+  /* align-self: start; */
+}
+
+.main {
+  grid-area: main;
+  /* align-self: start; */
+}
+
+.footer {
+  grid-area: footer;
+  align-self: end;
+}
+
+.main-grid {
+  grid-area: main;
+  display: grid;
+  grid-column-gap: 25mm;
+  grid-template-columns: 1fr 1fr;
+  grid-template-rows: 1fr auto;
+  grid-template-areas: "main-left main-right" "footer-left footer-right";
+}
+
+.main-left {
+  grid-area: main-left;
+}
+
+.main-right {
+  grid-area: main-right;
+}
+
+.footer-grid {
+  grid-area: footer;
+  display: grid;
+  grid-column-gap: 25mm;
+  grid-template-columns: 1fr 1fr;
+  grid-template-rows: 1fr auto;
+  grid-template-areas: "header header" "footer-left footer-right";
+}
+
+.footer-header {
+  grid-area: footer-header;
+}
+
+.footer-left {
+  grid-area: footer-left;
+}
+
+.footer-right {
+  grid-area: footer-right;
+}
+
+.flex-grid {
+  display: flex;
+}
+
+.col {
+  flex: 1;
+}
+
+.col-2 {
+  flex: 2;
+}
+
+.text-center {
+  text-align: center !important;
+}
+
+hr {
+  border: 0;
+  border-top: 1px solid #eee;
+  border-color: #000;
+  height: 1px;
+  margin: 3px 0;
+}
+.hr-grau {
+  border-color: #646464 !important;
+}
+
+.fett {
+  font-weight: bolder;
+}
+
+.klein {
+  font-size: 0.7rem;
+}
+
+.eng {
+ line-height: 0.9rem;
+}
+
+.grau * {
+  color: #646464 !important;
+}
+
+ul.dashes {
+  margin: 0;
+  list-style-type: none;
+  padding-left: 1rem;
+}
+ul.dashes li:before {
+  content: "–";
+  position: absolute;
+  margin-left: -1rem;
+}
+
+.schulnummer {
+  text-align: left;
+}
+
+.wasserzeichen {
+  position: absolute;
+  opacity: 0.5;
+  z-index: 99;
+  color: red;
+  font-size: 96pt;
+}

+ 2 - 0
css/normalize.css

@@ -0,0 +1,2 @@
+/*! modern-normalize | MIT License | https://github.com/sindresorhus/modern-normalize */
+html{box-sizing:border-box}*,::after,::before{box-sizing:inherit}:root{-moz-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'}hr{height:0}abbr[title]{text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:SFMono-Regular,Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{padding:0}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}

BIN
daten/abiturformel.png


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
daten/agz.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 74 - 0
daten/asz.svg


+ 170 - 0
daten/fachklassen.json

@@ -0,0 +1,170 @@
+{
+	"default": {
+		"Schulform": "Schulform fehlt",
+		"Bereich": "Bereich fehlt",
+		"Zeugniskopf": "ohne Angabe",
+		"Berufsbezeichnung_m": "männliche Berufsbezeichnung",
+		"Berufsbezeichnung_w": "weibliche Berufsbezeichnung"
+	},
+	"10-106-00": {
+		"Schulform": "Berufliches Gymnasium, Bereich Gesundheit und Soziales",
+		"Bereich": "Erzieherin/AHR, Erzieher/AHR",
+		"Zeugniskopf": "Erzieherin/AHR, Erzieher/AHR",
+		"Examen": "Berufsabschlussprüfung",
+		"Berufsbezeichnung_m": "Staatlich anerkannter Erzieher",
+		"Berufsbezeichnung_w": "Staatlich anerkannte Erzieherin",
+		"Fremdsprache": {
+			"114": "(B2/C1)"
+		}
+	},
+	"170-120-00": {
+		"Schulform": "Berufliches Gymnasium, Bereich Gesundheit und Soziales",
+		"Bereich": "Allgemeine Hochschulreife (Gesundheit)",
+		"Zeugniskopf": "Allgemeine Hochschulreife (Gesundheit)",
+		"Fremdsprache": {
+			"114": "(B2/C1)"
+		}
+	},
+	"93-103-01": {
+		"Schulform": "Berufsfachschule",
+		"Bereich": "Fachbereich Gesundheit/Erziehung und Soziales",
+		"Abschluss": true,
+		"Examen": "Berufsabschlussprüfung",
+		"Zeugniskopf": "Berufsfachschule für Gesundheit/Erziehung und Soziales",
+		"Berufsbezeichnung_m": "Staatlich geprüfter Sozialassistent, Schwerpunkt Heilerziehung",
+		"Berufsbezeichnung_w": "Staatlich geprüfte Sozialassistentin, Schwerpunkt Heilerziehung",
+		"Fremdsprache": {
+			"114": "(B1)"
+		}
+	},
+	"93-103-00": {
+		"Schulform": "Berufsfachschule",
+		"Bereich": "Fachbereich Gesundheit/Erziehung und Soziales",
+		"Berufsbezeichnung_m": "Staatlich geprüfter Sozialassistent",
+		"Berufsbezeichnung_w": "Staatlich geprüfte Sozialassistentin",
+		"Abschluss": true,
+		"Examen": "Berufsabschlussprüfung",
+		"Zeugniskopf": "Berufsfachschule für Sozial- und Gesundheitswesen",
+		"Fremdsprache": {
+			"114": "(B1)"
+		}
+	},
+	"10-109-00": {
+		"Schulform": "Fachoberschule",
+		"Bereich": "Fachrichtung Gesundheit und Soziales",
+		"Zeugniskopf": "Fachoberschule mit dem fachlichen Schwerpunkt Gesundheit und Soziales",
+		"Fremdsprache": {
+			"114": "(B2)"
+		}
+	},
+	"100-102-01": {
+		"Schulform": "Fachschule des Sozialwesens",
+		"Bereich": "Fachrichtung Sozialpädagogik",
+		"Lernbereich": "Bildungsbereiche in der Kinder- und Jugendarbeit",
+		"Lernfeld_Lernbereich": "Vertiefung in den Bildungsbereichen",
+		"Lernfeld_Lernbereich_LF": "Lernfelder",
+		"Zeugniskopf": "Fachschule des Sozialwesens in der Fachrichtung Sozialpädagogik",
+		"Fehlstunden": false,
+		"Examen": "Fachschulexamen",
+		"Berufsbezeichnung_m": "Staatlich anerkannter Erzieher",
+		"Berufsbezeichnung_w": "Staatlich anerkannte Erzieherin",
+		"Fremdsprache": {
+			"19": "(B2)"
+		}
+	},
+	"100-102-02": {
+		"Schulform": "Fachschule des Sozialwesens",
+		"Bereich": "Fachrichtung Sozialpädagogik",
+		"Lernbereich": "Bildungsbereiche in der Kinder- und Jugendarbeit",
+		"Lernfeld_Lernbereich": "Vertiefung in den Bildungsbereichen",
+		"Lernfeld_Lernbereich_LF": "Lernfelder",
+		"Zeugniskopf": "Fachschule des Sozialwesens in der Fachrichtung Sozialpädagogik",
+		"Fehlstunden": false,
+		"Examen": "Fachschulexamen",
+		"Berufsbezeichnung_m": "Staatlich anerkannter Erzieher",
+		"Berufsbezeichnung_w": "Staatlich anerkannte Erzieherin",
+		"Fremdsprache": {
+			"19": "(B2)"
+		}
+	},
+	"40-102-05": {
+		"Schulform": "Fachschule des Sozialwesens",
+		"Bereich": "Fachrichtung Sozialpädagogik – praxisintegrierte Form",
+		"Zeugniskopf": "der Fachschule für Sozialwesen in der Fachrichtung Sozialpädagogik – praxisintegrierte Form",
+		"Lernbereich": "Bildungsbereiche in der Kinder- und Jugendarbeit",
+		"Lernfeld_Lernbereich": "Vertiefung in den Bildungsbereichen",
+		"Lernfeld_Lernbereich_LF": "Lernfelder",
+		"Fehlstunden": false,
+		"Examen": "Fachschulexamen",
+		"Berufsbezeichnung_m": "Staatlich anerkannter Erzieher",
+		"Berufsbezeichnung_w": "Staatlich anerkannte Erzieherin",
+		"Fremdsprache": {
+			"19": "(B2)"
+		}
+	},
+	"10-101-01": {
+		"Schulform": "Fachschule des Sozialwesens",
+		"Bereich": "Fachrichtung Heilerziehungspflege",
+		"Lernbereich": "Heilerziehungspflegerische Schwerpunkte",
+		"Zeugniskopf": "Fachschule des Sozialwesens in der Fachrichtung Heilerziehungspflege",
+		"Berufsbezeichnung_m": "Staatlich anerkannter Heilerziehungspfleger",
+		"Berufsbezeichnung_w": "Staatlich anerkannte Heilerziehungspflegerin",
+		"Fehlstunden": false,
+		"Examen": "Fachschulexamen",
+		"Fremdsprache": {
+			"19": "(B2)"
+		}
+	},
+	"10-101-02": {
+		"Schulform": "Fachschule des Sozialwesens",
+		"Bereich": "Fachrichtung Heilerziehungspflege",
+		"Lernbereich": "Heilerziehungspflegerische Schwerpunkte",
+		"Zeugniskopf": "Fachschule des Sozialwesens in der Fachrichtung Heilerziehungspflege",
+		"Fehlstunden": false,
+		"Examen": "Fachschulexamen",
+		"Berufsbezeichnung_m": "Staatlich anerkannter Heilerziehungspfleger",
+		"Berufsbezeichnung_w": "Staatlich anerkannte Heilerziehungspflegerin",
+		"Fremdsprache": {
+			"19": "(B2)"
+		}
+	},
+	"40-101-05": {
+		"Schulform": "Fachschule des Sozialwesens",
+		"Bereich": "Fachrichtung Heilerziehungspflege – praxisintegrierte Form",
+		"Lernbereich": "Heilerziehungspflegerische Schwerpunkte",
+		"Zeugniskopf": "Fachschule des Sozialwesens in der Fachrichtung Heilerziehungspflege",
+		"Fehlstunden": false,
+		"Examen": "Fachschulexamen",
+		"Berufsbezeichnung_m": "Staatlich anerkannter Heilerziehungspfleger",
+		"Berufsbezeichnung_w": "Staatlich anerkannte Heilerziehungspflegerin",
+		"Fremdsprache": {
+			"19": "(B2)"
+		}
+	},
+	"210-111-02": {
+		"Schulform": "Fachschule des Sozialwesens",
+		"Bereich": "Fachrichtung Heilpädagogik",
+		"Lernbereich": "Methoden in der Heilpädagogik und den Bereichen",
+		"Lernfeld_Lernbereich": "Vertiefung in den Bildungsbereichen",
+		"Lernfeld_Lernbereich_LF": "Lernfelder",
+		"Zeugniskopf": "Fachschule des Sozialwesens in der Fachrichtung Heilpädagogik",
+		"Fehlstunden": false,
+		"Examen": "Fachschulexamen",
+		"Fremdsprache": {
+			"252": "(B2)"
+		}
+	},
+	"10-140-00": {
+		"Schulform": "Fachschule des Sozialwesens",
+		"Bereich": "Fachrichtung Heilpädagogik",
+		"Lernbereich": "Methoden in der Heilpädagogik und den Bereichen",
+		"Lernfeld_Lernbereich": "Vertiefung in den Bildungsbereichen",
+		"Lernfeld_Lernbereich_LF": "Lernfelder",
+		"Zeugniskopf": "Fachschule des Sozialwesens, Aufbaubildungsgang<br />heilpädagogische Förderung mit dem Pferd",
+		"Fehlstunden": false,
+		"Examen": "Fachschulexamen",
+		"Fremdsprache": {
+			"252": "(B2)"
+		}
+	}
+}

BIN
daten/texgyreheros-bold-webfont.woff


BIN
daten/texgyreheros-bolditalic-webfont.woff


BIN
daten/texgyreheros-italic-webfont.woff


BIN
daten/texgyreheros-regular-webfont.woff


+ 1 - 0
daten/zeugnis.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" clip-path="url(#a)" height="19.43" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 2835.68 548.34" width="100.48" fill-rule="evenodd" stroke-width="28.22" stroke-linejoin="round"><defs class="ClipPathGroup"><clipPath id="a"><path d="M0 0h21000v29700H0z"/></clipPath></defs><g class="SlideGroup"><g class="Slide" clip-path="url(#a)" transform="translate(-2182.7 -14344.06) scale(.9688)"><g class="Page"><g class="Graphic"><path d="M2253 15362h354v-47h-295l286-453v-46h-338v46h280l-287 453zm446 0h279v-47h-224v-211h204v-46h-204v-196h214v-46h-269zm790-546h-54v355c0 45-12 82-36 110-25 29-61 43-110 43-47 0-83-14-108-43-25-28-37-65-37-110v-355h-54v355c0 39 6 72 20 99 13 27 30 47 50 61 20 15 42 25 65 31s44 10 64 10c21 0 44-4 67-10 22-6 44-16 65-31 20-14 36-34 49-61 12-27 19-60 19-99zm510 490c-14 7-32 11-54 13-24 4-44 5-63 5-73 0-128-22-166-66-38-43-58-99-58-170 0-69 20-125 59-168 38-44 93-65 165-67 25 0 49 2 73 5 24 4 47 12 67 24l7-50c-19-9-42-16-70-21-29-3-54-5-77-5-86 1-154 27-203 78-50 52-75 120-75 204 0 87 25 154 74 206 49 50 117 76 204 78 59 0 117-11 170-34v-272h-181v47h128zm185 56h55v-472h1l276 472h73v-546h-54v481h-1l-281-481h-69zm528 0h55v-546h-55zm168-69l-5 55c29 14 71 22 124 24 46 0 87-13 124-37s56-63 57-118c0-20-3-38-10-54s-17-29-29-41c-25-24-54-43-87-59-16-9-31-17-46-26-15-8-29-16-41-25s-21-18-28-29c-8-10-12-22-12-36 0-18 4-33 12-46 7-12 16-21 27-28 12-8 25-13 39-16 14-2 28-4 42-4 40 0 73 7 100 20l9-49c-19-7-38-12-58-15-19-2-36-3-51-3-49 1-90 13-123 38s-50 60-51 105c1 34 14 62 39 85 13 12 26 22 42 32 14 10 30 19 45 27 16 8 32 17 47 25 15 9 29 18 40 27 26 19 39 41 40 67-1 38-13 67-36 85s-53 27-88 27c-50 0-91-11-122-31z" fill="#003258"/><path d="M2233 15372h654z" fill="#0ff"/></g></g></g></g></svg>

+ 63 - 0
helfer.js

@@ -0,0 +1,63 @@
+import fkl from './daten/fachklassen.json'
+const noten = [null, 'sehr gut', 'gut', 'befriedigend', 'ausreichend', 'mangelhaft', 'ungenügend']
+const enoten = {'E1': 'mit besonderem Erfolg teilgenommen', 'E2': 'mit Erfolg teilgenommen', 'E3': 'teilgenommen'}
+const punkte = {
+  15: '1+', 14: '1', 13: '1-',
+  12: '2+', 11: '2', 10: '2-',
+   9: '3+',  8: '3',  7: '3-',
+   6: '4+',  5: '4',  4: '4-',
+   3: '5+',  2: '5',  1: '5-',
+             0: '6'}
+  const zahlwort = {1: "eins",2: "zwei",3: "drei",4: "vier",5: "fünf",6: "sechs",7: "sieben",8: "acht",9: "neun",0: "null"}
+
+export const datum = (t) => {
+  // gibt ein Datum im deutschen Format zurück
+  try {
+    return new Date(t).toLocaleDateString('de', {day: '2-digit', month: '2-digit', year: 'numeric'})
+  } catch (e) {console.log(e); return}
+}
+export const versetzungsvermerk = (s, hj, agz=null) => {
+  // gibt, wenn vorhanden den passenden Vermerk zurück
+  // wenn es ein agz ist und kein Konferenzdatum feststeht
+  if (agz && !hj.Konferenzdatum) return
+  let vermerk = ''
+  if (hj.Abschnitt === 2 || s.Klasse.startsWith('H')) {
+    switch (hj.VersetzungKrz) {
+      case 'N': vermerk = `Nicht versetzt laut Konferenzbeschluss vom ${datum(hj.Konferenzdatum)}`
+      case 'V': vermerk = `Versetzt laut Konferenzbeschluss vom ${datum(hj.Konferenzdatum)}`
+      default:  vermerk = 'Kein Versetzungsvermerk hinterlegt'
+    }
+  }
+  return vermerk
+}
+export const bemerkungen = (hj) => {
+  return hj.ZeugnisBem ? hj.ZeugnisBem.replace('\r\n', '<br/>') : 'keine'
+}
+export const volljaehrigBei = (s, datum) => {
+  // gibt an, ob der Schüler *s* zu einem Zeitpunkt *datum* volljährig war
+  try {
+  const g = new Date(s.Geburtsdatum)
+  const d = new Date(datum)
+  const volljaehrig = d.getFullYear() - g.getFullYear() - ((d.getMonth() > g.getMonth() || (d.getMonth() == g.getMonth() && d.getDay() >= g.getDay()) ? 0 : 1)) >= 18
+  return volljaehrig
+  } catch (e) {console.log(e); return}
+}
+export const schulform = (s) => {
+  switch (s.ASDSchulform[0]) {
+    case 'B': return 'Berufsfachschule'
+  }
+}
+export const bg = (s,k) => {
+  if (s.fachklasse && s.fachklasse.Kennung && fkl[s.fachklasse.Kennung]) {
+    return fkl[s.fachklasse.Kennung][k]
+  } else
+  return ''
+}
+export const note = (note) => noten[parseInt(note)] || enoten[note]
+export const punkte2note = (p) => punkte[parseInt(p)]
+export const noteInWorten = (n) => n.split('').map(n => n === ',' ? '/' : zahlwort[parseInt(n)]).join(' ')
+export const fremdsprache = (fach, fachklasse) => {
+  try {
+    return fach.Lernentw || fkl[fachklasse]['Fremdsprache'][fach.Fach_ID]
+  } catch (e) { return 'undefined - Sprachniveau fehlt'}
+}

+ 69 - 0
partials/Fussnoten.html

@@ -0,0 +1,69 @@
+<!-- Allgemeine Fussnoten
+
+Folgende Attribute werden unterstützt:
+schule:     Hier stehen die SchulNr etc drin. Muss mitgegeben werden
+ger:        Wenn der GER für AGZ oder ASZ verwendet werden soll, mitangeben.
+            true|false Standardwert ist false
+notenstufen:Wenn die Notenstufen mit angegeben werden sollen.
+            true|false Standardwert ist true
+verordnung :true|false Standartwert true
+bfs:        true|false Standardwert false
+rechtsbehlfsbelehrung :true|false Standartwert true
+
+Beachte, true|false nicht als String setzen, sondern als statement:
+notenstufen={false} -->
+
+<div class="klein eng">
+  <Voffset v="2"/>
+  <div class="schulnummer">
+    Schulnummer: {schule.SchulNr}
+  </div>
+  <hr class="hr-grau" />
+  <div class="grau">
+    {#if notenstufen}
+      Notenstufen gemäß § 48 SchulG: 1 = sehr gut, 2 = gut, 3 = befriedigend,
+      4 = ausreichend, 5 = mangelhaft, 6 = ungenügend
+      <Voffset v=".5"/>
+    {/if}
+    {#if ger}
+      <sup>1</sup>Der Unterricht in den modernen Fremdsprachen hat auf der nach dem Fach in
+      Klammern angegebenen Niveaustufe des „Europäischen Referenzrahmens für
+      Sprachen: Lernen, Lehren, Beurteilen“ stattgefunden. Sind zwei
+      Referenzniveaus ausgewiesen, ist das niedrigere in vollem Umfang, das höhere
+      in Anteilen erreicht. Bei mindestens ausreichenden Leistungen wird der
+      sprachliche Kompetenzerwerb auf diesem Niveau bescheinigt.
+      <Voffset v=".5"/>
+    {/if}
+    {#if verordnung}
+      Dem Zeugnis liegen zugrunde: Die Verordnung über die Ausbildung und Prüfung
+      in den Bildungsgängen des Berufskollegs (Ausbildungs- und Prüfungsordnung
+      Berufskolleg, APO-BK) vom 26. Mai 1999 (SGV. NRW. 223/BASS 13 – 33 Nr. 1.1).
+    {#if bfs}
+      <br>Die Rahmenvereinbarung über die Berufsfachschulen (Beschluss der
+      Kultusministerkonferenz vom 17.10.2013) in der jeweils geltenden Fassung.
+    {/if}
+      <Voffset v=".5"/>
+    {/if}
+    {#if rechtsbehelfsbelehrung}
+      Rechtsbehelfsbelehrung: Gegen dieses Zeugnis kann innerhalb eines Monats
+      nach Bekanntgabe des Zeugnisses Widerspruch eingelegt werden. Der Widerspruch
+      ist beim {schule.Bezeichnung2}, {schule.Strasse}, {schule.PLZ} {schule.Ort},
+      schriftlich oder zur Niederschrift zu erheben. <br />Falls die Frist durch
+      das Verschulden einer/eines Bevollmächtigten versäumt wird, wird dies
+      Verschulden der Widerspruchsführerin/dem Widerspruchsführer zugerechnet.
+    {/if}
+  </div>
+</div>
+
+<script>
+  export default {
+    components: { Voffset: './Voffset.html' },
+    data () {
+      return {
+        notenstufen: true,
+        verordnung: true,
+        rechtsbehelfsbelehrung: true
+      }
+    }
+  }
+</script>

+ 134 - 0
partials/Noten.html

@@ -0,0 +1,134 @@
+<!--
+Allgemeine Notentabelle für Berufskollegs, die z.B. die etwas langtextigen
+Lernfeldfächer unterstützt oder verschiedene Abschlussnoten.
+
+Folgende Attribute werden unterstützt:
+lernfeld: Sorgt dafür, dass die Klasse `fach-bezeichnung` nicht gesetzt wird und
+          Fächer dementsprechend nicht eingerückt werden (nur Lernfeldfächer)
+          true|false Standardwert false
+noten:    Hier können Abschnittsnoten oder Abschlussnoten gesetzt werden, z.B.
+          hj.noten oder s.bk_abschluss_faecher oder s.fhr_abschluss_faecher
+          Muss gesetzt werden
+fachGliederungen: sollten mitgegeben werden, wenn die für verschiedene Bildungsgänge
+          geänderten Werte berücksichtigt werden sollen, z.B. andere Bezeichnungen
+          in den verschiedenen Bildungsgängen
+ger:      Wenn ein Referenzniveau für die Fremdsprachen angegeben werden soll
+          true|false, Standardwert false,
+fachklasse: muss mitgegeben werden, wenn aus der Fachklassen.json Datei der Standard-
+          Wert gelesen werden soll. Ansonsten über Lernentw festlegen, was eigetragen wird
+-->
+
+<table class="table-noten">
+  {#each faechergruppen as [gruppen_id, gruppenFaecher]}
+    <tr>
+      <td class="fachgruppe-margin">
+        <b>{gruppenbezeichnung(gruppen_id)}</b>
+      </td>
+    </tr>
+    {#each lernbereicheUndFaecher(gruppenFaecher) as [lernbereich, faecher]}
+      {#if lernbereich != faecher[0].fach.Zeugnisbez}
+        <tr><td colspan="2" class="{lernfeld ? '' : 'fach-bezeichnung'}">{lernbereich}</td></tr>
+      {/if}
+      {#each faecher as f (f.ID)}
+        {#if f.AufZeugnis === '+'}
+          <tr>
+            <td class="{lernfeld ? '' : 'fach-bezeichnung'} {lernbereich != faecher[0].fach.Zeugnisbez ? 'lernfeld-lernbereich' : ''}">
+              {#if f.fach.Zeugnisbez.includes("Projekt")}
+                {f.Lernentw}
+              {:else}
+                <!-- Die Zeugnisbezeichnung hat bei gesetzten fachGliederungen einen anderen Namen... -->
+                {f.fach.ZeugnisBez || f.fach.Zeugnisbez}
+                <!-- Ist ger gesetzt, unter Lernentw nach Eintrag schauen. Wenn dort nichts steht,
+                in der Fachklassen.json nach Einträgen für Fremdsprache und Fach_ID suchen
+                Mit der Fussnote 1 muss natürlich auch tatsächlich eine Fussnote zum GER existieren … -->
+                {#if ger && f.fach.IstSprache === '+'}
+                  {fremdsprache(f, fachklasse)}<sup>1</sup>
+                {/if}
+              {/if}
+            </td>
+            <!-- Entweder Abschlussnote, wenn gesetzt oder Abschnittsnote oder nix -->
+            <td class="td-fach-note"><span>{note(f.NoteAbschluss) || note(f.NotenKrz) || '–––––'}</span></td>
+          </tr>
+        {/if}
+      {/each}
+    {/each}
+    <tr>
+    </tr>
+  {/each}
+</table>
+
+<script>
+  import { gruppenIds } from './gruppenIDs'
+  import { note, fremdsprache } from '../helfer'
+  const _ = R.lodash
+
+  export default {
+    helpers: {
+      _, note, fremdsprache,
+      gruppenbezeichnung: gruppe => gruppenIds[gruppe],
+      lernbereicheUndFaecher: gruppenFaecher => Object.entries(_.groupBy(gruppenFaecher, f => f.fach.Bezeichnung)),
+    },
+    computed: {
+      faechergruppen: ({ noten, fachGliederungen }) => {
+        // noten werden im jeweiligen Dokument über das *noten*-Attribut mitgegeben.
+        // z.B. die Abschnittsnote oder die Noten aus *s.bk_abschluss_faecher* und co.
+        // Nutzer über Konsole auf Änderungen in den Fächern hinweisen
+        if (fachGliederungen && fachGliederungen.length > 0) console.log('Es wurden Fachgliederungswerte gesetzt: ', fachGliederungen)
+        // suche in den fachGliederungen, ob für die jeweilige Fachklasse was besonderes festgelegt wurde
+        // vorausgesetzt, fachGliederungen wurde mitgegeben
+        const faecher = fachGliederungen
+          ? noten.map(f => {return {...f, fach: Object.assign(f.fach, fachGliederungen.find(fg => fg.Fach_ID === f.Fach_ID))}})
+          : noten
+        // erstmal alle Fächer sortieren in der passenden Reihenfolge,
+        // dann nach Fachgruppe gruppieren
+        return Object.entries(_.groupBy(_.sortBy(faecher, f => f.fach.SortierungS2), f => f.fach.Fachgruppe_ID))
+      },
+      // Berufsbezogen kommt neuerdings zuerst, dann berufsübergreifend
+      // wenn aber nur eine Note vermerkt ist, dann normal zurück
+      faechergruppenUmsortiert: ({ faechergruppen }) => faechergruppen.length > 1
+        ? [faechergruppen[0], faechergruppen[1]] = [faechergruppen[1], faechergruppen[0]]
+        : faechergruppen
+    }
+  }
+</script>
+<style>
+.table-noten {
+  width: 100%;
+  border: none;
+  border-collapse: collapse;
+  margin-bottom: 1rem;
+}
+.fach-bezeichnung {
+  padding-left: 10mm;
+}
+.td-fach-note {
+  padding-bottom: .2rem;
+  padding-top: .2rem;
+  width: 12rem;
+}
+.td-fach-note span {
+  background-color: #dcdcdc !important;
+  text-align: center;
+  width: 10rem;
+  display: block;
+  margin: 0 auto;
+}
+/*.td-fach-note span.e-note {
+  background-color: white !important;
+  width: 17rem;
+  margin: 0;
+}*/
+
+.fachgruppe-margin {
+  padding-top: 0.3rem;
+}
+
+.lernfeld-lernbereich {
+  padding-left: 2rem;
+  padding-bottom: 0;
+}
+
+.lernbereich {
+  padding-left: 20mm;
+}
+</style>

+ 44 - 0
partials/Pageheader.html

@@ -0,0 +1,44 @@
+<!-- Folgende Attribute werden unterstützt:
+art:  z.B. Zeugnis, Abgangszeugnis etc. Sollte auf eine vorhandene Datei zeigen
+      wird unten links platziert im Header
+logo: z.B Schullogo. Wird oben recht splatziert
+untertitel: Wird unterhalb des Logos platziert. -->
+<div class="header">
+    {#if art}
+      <img class="art" src="{art}" alt="logo_art"/>
+    {/if}
+    {#if logo}
+      <img class="logo" src="{logo}" alt="logo"/>
+    {/if}
+    {#if untertitel}
+      <img class="untertitel" src="{untertitel}" alt="logo_untertitel"/>
+    {/if}
+  <hr class="hr-rot"/>
+</div>
+
+<style>
+  .header {
+    position: relative;
+    height: 115px;
+  }
+  .art {
+    position: absolute;
+    bottom: 12px;
+  }
+  .logo {
+    position: absolute;
+    right: 0px;
+  }
+  .untertitel {
+    position: absolute;
+    right: 0px;
+    bottom: 12px;
+  }
+  .hr-rot {
+    border-color: #ff2700;
+    margin: 8px 0;
+    position: absolute;
+    bottom: 0px;
+    width: -webkit-fill-available;
+  }
+</style>

+ 51 - 0
partials/SOA-Tabelle.html

@@ -0,0 +1,51 @@
+<table class="table table-bordered" style="width: 100%">
+  <tr>
+    <th width="35%">Bereichsspezifische Fächer</th>
+    <th>Zugeordnete Lernfelder</th>
+  </tr>
+  <tr>
+    <td>Erziehung und Soziales</td>
+    <td>
+      <ul class="dashes">
+        <li>Bedürfnisse und Potentiale wahrnehmen, beobachten und analysieren</li>
+        <li>Mit Konzepten in sozialpädagogischen Einrichtungen arbeiten</li>
+        <li>Beziehungen in der sozialpädagogischen und pflegerischen Arbeit gestalten</li>
+        <li>Gestaltungsprinzipien und Gestaltungsmittel in Räumen sozialpflegerischer Einrichtungen</li>
+      </ul>
+    </td>
+  </tr>
+  <tr>
+    <td>Gesundheitsförderung und Pflege</td>
+    <td>
+      <ul class="dashes">
+        <li>Sozialpflegerische Handlungsprozesse systematisch planen, umsetzen, dokumentieren und evaluieren</li>
+        <li>Pflegekonzepte als Grundlage der pflegerischen Tätigkeiten anwenden</li>
+        <li>Kompetenzen, Ressourcen und Potentiale erkennen und fördern</li>
+        <li>Gesunde Lebensführung fördern</li>
+      </ul>
+    </td>
+  </tr>
+  <tr>
+    <td>Arbeitsorganisation und Recht</td>
+    <td>
+      <ul class="dashes">
+        <li>Sich im Berufsfeld orientieren, auf Anforderungen einlassen und die eigene Person darstellen</li>
+        <li>Rechte und Pflichten des Sozialassistenten kennen und wahrnehmen</li>
+        <li>Außendarstellung der sozialpädagogischen bzw. -pflegerischen Einrichtungen unterstützen</li>
+        <li>Wirtschaftlich mit Materialien umgehen</li>
+      </ul>
+    </td>
+  </tr>
+</table>
+
+<style>
+  .table-bordered {
+    border-collapse: collapse;
+  }
+  .table-bordered tr {
+    border-bottom: thin solid #333;
+  }
+  .schulnummer {
+    text-align: right;
+  }
+</style>

+ 12 - 0
partials/Seite2Fussnoten.html

@@ -0,0 +1,12 @@
+<div class="page grid" orientation="portrait" size="A4">
+  <div class="footer grau">
+    <Fussnote notenstufen={false} {schule} {ger}></Fussnote>
+  </div>
+</div>
+
+<script>
+	export default { components: {
+      Fussnote: './Fussnoten.html'
+    }
+  }
+</script>

+ 13 - 0
partials/Seitenlogo.html

@@ -0,0 +1,13 @@
+<div class="seitenlogo">
+  {#if logo}
+    <img src="{logo}" height="160" alt="traeger_logo"/>
+  {/if}
+</div>
+
+<style>
+  .seitenlogo {
+    position: absolute;
+    bottom: 10mm;
+    left: 10mm;
+  }
+</style>

+ 1 - 0
partials/Voffset.html

@@ -0,0 +1 @@
+<div style="margin-top: {v}em"></div>

+ 32 - 0
partials/gruppenIDs.js

@@ -0,0 +1,32 @@
+export const gruppenIds = {
+    10:'Berufsübergreifender Lernbereich',
+    11:'Aufgabenbereich I',
+    20:'Berufsbezogener Lernbereich',
+    21:'Aufgabenbereich II',
+    25:'Berufsbezogener Bereich (Schwerpunkt)',
+    30:'Differenzierungsbereich',
+    31:'Aufgabenbereich III.1',
+    32:'Aufgabenbereich III.2',
+    33:'Aufgabenbereich III.3',
+    40:'Berufspraktikum',
+    60:'besondere Lernleistung',
+    100:'Fremdsprachen',
+    110:'Deutsch',
+    200:'Naturwissenschaften',
+    300:'Gesellschaftslehre',
+    400:'Arbeitslehre',
+    500:'Kunst und Musik',
+    600:'Sport',
+    700:'Mathematik',
+    800:'Wahlpflichtbereich',
+    900:'Religion',
+    1000:'Zusätzliche Unterrichtsveranstaltungen',
+    1100:'Angleichungskurse',
+    1200:'Sprache',
+    1300:'Sachunterricht',
+    1400:'Förderunterricht',
+    1500:'Vertiefungskurs',
+    1600:'Projektkurs',
+    1700:'Abschlussarbeit',
+    1800:'Projektarbeit'
+}

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff