burningTyger преди 6 години
родител
ревизия
83519f26f1
променени са 10 файла, в които са добавени 165 реда и са изтрити 122 реда
  1. 102 0
      Abgangszeugnis.html
  2. 4 0
      CSV Import.html
  3. 6 13
      Fotoliste.html
  4. 6 1
      Halbjahreszeugnis LF.html
  5. 1 1
      Halbjahreszeugnis.html
  6. 5 1
      Jahreszeugnis.html
  7. 3 3
      css/main.css
  8. 1 7
      css/normalize.css
  9. 37 6
      partials/Noten.html
  10. 0 90
      partials/NotenLF.html

+ 102 - 0
Abgangszeugnis.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/>
+      <Pageheader logo="daten/agz_logo.svg"/>
+      <div class="main">
+        <div style="font-size: 15pt; line-height: 1.5em">
+          {(fkl[s.fachklasse.Kennung] || fkl.default).Schulform}
+        </div>
+        <div style="font-size: 12pt; line-height: 1.2em">
+          {(fkl[s.fachklasse.Kennung] || fkl.default).Bereich}<br />{s.Geschlecht === '3' ? s.fachklasse.Bezeichnung : s.fachklasse.Beschreibung_W}
+          {#if s.ASDSchulform.startsWith('B')}
+            <br />
+            Abschluss {s.Geschlecht === '3' ? fkl[s.fachklasse.Kennung || fkl.default].Berufsbezeichnung_m : fkl[s.fachklasse.Kennung].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 {(fkl[s.fachklasse.Kennung] || fkl.default).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}></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 />{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 schulNr={schule.SchulNr}></Fussnote>
+      </div>
+    </div>
+  {/each}
+{/each}
+
+<script>
+  import { datum, versetzungsvermerk, volljaehrigBei, bemerkungen }  from './helfer'
+  import fkl from './daten/fachklassen.json'
+
+  export default {
+    components: {
+      Seitenlogo: './partials/Seitenlogo.html',
+      Pageheader: './partials/Pageheader.html',
+      Noten: './partials/Noten.html',
+      Fussnote: './partials/Fussnoten.html',
+      Voffset: './partials/Voffset.html'
+    },
+    helpers: { fkl, datum, versetzungsvermerk, volljaehrigBei, bemerkungen, _ },
+    computed: {
+      aktHalbjahr: ({jahr, abschnitt}) => { return a => a.Jahr === jahr && a.Abschnitt === abschnitt }
+    }
+  }
+</script>
+
+<style>
+  @import 'css/main.css';
+</style>

+ 4 - 0
CSV Import.html

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

+ 6 - 13
Fotoliste.html

@@ -29,22 +29,15 @@
 </style>
 
 <script>
+  const SchuelerFoto = R.models.Schuelerfoto
+
   export default {
     computed: {
-      fotos: async ({schueler, knex}) => {
-        R.objection.Model.knex(R.knex({
-          client: 'mysql',
-          useNullAsDefault: true,
-          connection: {
-            host: knex.host,
-            database: knex.name,
-            user: knex.user,
-            password: knex.password,
-            charset: 'utf8'
-          }
-        }))
+      fotos: async ({schueler, knexConfig}) => {
         let f = {}
-        const schuelerfotos = await R.models.Schuelerfoto.query().whereIn('Schueler_ID', schueler.map(s => s.ID))
+        const knex = await R.knex(knexConfig)
+        await SchuelerFoto.knex(knex)
+        const schuelerfotos = await SchuelerFoto.query().whereIn('Schueler_ID', schueler.map(s => s.ID))
         schuelerfotos.forEach(element => {
           f[element.Schueler_ID] = Buffer.from(element.Foto, 'binary').toString('base64')
         })

+ 6 - 1
Halbjahreszeugnis LF.html

@@ -16,7 +16,9 @@
         besuchte im Schuljahr {hj.schuljahr} die Klasse {hj.Klasse}
         <Voffset v="2"/>
         Leistungen laut Konferenzbeschluss vom {datum(hj.Konferenzdatum)}:
-        <Noten noten={hj.noten}></Noten>
+        <div class="lf-noten">
+          <Noten lernfeld noten={hj.noten} fachGliederungen={s.fachklasse.fach_gliederungen}></Noten>
+        </div>
         <hr />
         Fehlstunden: {_.toNumber(hj.SumFehlStd)}
         {#if hj.SumFehlStdU > 0}
@@ -69,4 +71,7 @@
 
 <style>
   @import 'css/main.css';
+  .lf-noten {
+    font-size: 0.9rem;
+  }
 </style>

+ 1 - 1
Halbjahreszeugnis.html

@@ -20,7 +20,7 @@
         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}></Noten>
+        <Noten noten={hj.noten} fachGliederungen={s.fachklasse.fach_gliederungen}></Noten>
         <hr />
         Fehlstunden: {_.toNumber(hj.SumFehlStd)}
         {#if hj.SumFehlStdU > 0}

+ 5 - 1
Jahreszeugnis.html

@@ -9,6 +9,10 @@
         </div>
         <div style="font-size: 12pt; line-height: 1.2em">
           {(fkl[s.fachklasse.Kennung] || fkl.default).Bereich}<br />{s.Geschlecht === '3' ? s.fachklasse.Bezeichnung : s.fachklasse.Beschreibung_W}
+          {#if s.ASDSchulform.startsWith('B')}
+            <br />
+            Abschluss {s.Geschlecht === '3' ? fkl[s.fachklasse.Kennung || fkl.default].Berufsbezeichnung_m : fkl[s.fachklasse.Kennung].Berufsbezeichnung_w}
+          {/if}
         </div>
         <Voffset v="1"/>
         <b>{s.anrede} {s.Vorname} {s.Zusatz || ''} {s.Name},</b>
@@ -20,7 +24,7 @@
         {/if}
         <Voffset v="2"/>
         Leistungen laut Konferenzbeschluss vom {datum(hj.Konferenzdatum)}:
-        <Noten noten={hj.noten}></Noten>
+        <Noten noten={hj.noten} fachGliederungen={s.fachklasse.fach_gliederungen}></Noten>
         <hr />
         {#if !s.ASDSchulform.startsWith('E')}
           Fehlstunden: {Number(hj.SumFehlStd) || 0}

+ 3 - 3
css/main.css

@@ -174,7 +174,7 @@ p {
   display: grid;
   grid-gap: 0;
   gap: 0;
-  align-content: start;
+  /* align-content: start; */
   grid-template-columns: auto;
   grid-template-rows: auto 1fr auto;
   grid-template-areas: "header" "main" "footer";
@@ -182,12 +182,12 @@ p {
 
 .header {
   grid-area: header;
-  align-self: start;
+  /* align-self: start; */
 }
 
 .main {
   grid-area: main;
-  align-self: start;
+  /* align-self: start; */
 }
 
 .footer {

+ 1 - 7
css/normalize.css

@@ -1,8 +1,2 @@
-/**
- * Minified by jsDelivr using clean-css v4.1.11.
- * Original file: /npm/modern-normalize@0.4.0/modern-normalize.css
- * 
- * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
- */
 /*! 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}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'}h1{font-size:2em;margin:.67em 0}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}details{display:block}summary{display:list-item}
+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}

+ 37 - 6
partials/Noten.html

@@ -1,3 +1,19 @@
+<!--
+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
+-->
+
 <table class="table-noten">
   {#each faechergruppen as [gruppen_id, gruppenFaecher]}
     <tr>
@@ -7,18 +23,20 @@
     </tr>
     {#each lernbereicheUndFaecher(gruppenFaecher) as [lernbereich, faecher]}
       {#if lernbereich != faecher[0].fach.Zeugnisbez}
-        <tr><td colspan="2" class="fach-bezeichnung">{lernbereich}</td></tr>
+        <tr><td colspan="2" class="{lernfeld ? '' : 'fach-bezeichnung'}">{lernbereich}</td></tr>
       {/if}
       {#each faecher as f (f.ID)}
         <tr>
-          <td class="fach-bezeichnung {lernbereich != faecher[0].fach.Zeugnisbez ? 'lernfeld-lernbereich' : ''}">
+          <td class="{lernfeld ? '' : 'fach-bezeichnung'} {lernbereich != faecher[0].fach.Zeugnisbez ? 'lernfeld-lernbereich' : ''}">
             {#if f.fach.Zeugnisbez.includes("Projekt")}
               {f.Lernentw}
             {:else}
-              {f.fach.Zeugnisbez}
+              <!-- Die Zeugnisbezeichnung hat bei gesetzten fachGliederungen einen anderen Namen... -->
+              {f.fach.ZeugnisBez || f.fach.Zeugnisbez}
             {/if}
           </td>
-          <td class="td-fach-note"><span>{f.NotenKrz || '–––––'}</span></td>
+          <!-- Entweder Abschlussnote, wenn gesetzt oder Abschnittsnote oder nix -->
+          <td class="td-fach-note"><span>{f.NoteAbschluss || f.NotenKrz || '–––––'}</span></td>
         </tr>
       {/each}
     {/each}
@@ -38,7 +56,20 @@
       lernbereicheUndFaecher: gruppenFaecher => Object.entries(_.groupBy(gruppenFaecher, f => f.fach.Bezeichnung))
     },
     computed: {
-      faechergruppen: ({ noten }) => Object.entries(_.groupBy(_.sortBy(noten, f => f.fach.SortierungS2), f => f.fach.Fachgruppe_ID)),
+      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
@@ -80,7 +111,7 @@
 }
 
 .lernfeld-lernbereich {
-  padding-left: 20mm;
+  padding-left: 2rem;
   padding-bottom: 0;
 }
 

+ 0 - 90
partials/NotenLF.html

@@ -1,90 +0,0 @@
-<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">{lernbereich}</td></tr>
-      {/if}
-      {#each faecher as f (f.ID)}
-        <tr>
-          <td class="{lernbereich != faecher[0].fach.Zeugnisbez ? 'lernfeld-lernbereich' : ''}">
-            {#if f.fach.Zeugnisbez.includes("Projekt")}
-              {f.Lernentw}
-            {:else}
-              {f.fach.Zeugnisbez}
-            {/if}
-          </td>
-          <td class="td-fach-note"><span>{f.NotenKrz || '–––––'}</span></td>
-        </tr>
-      {/each}
-    {/each}
-    <tr>
-    </tr>
-  {/each}
-</table>
-
-<script>
-  import { gruppenIds } from './gruppenIDs'
-  const _ = R.lodash
-
-  export default {
-    helpers: {
-      _,
-      gruppenbezeichnung: gruppe => gruppenIds[gruppe],
-      lernbereicheUndFaecher: gruppenFaecher => Object.entries(_.groupBy(gruppenFaecher, f => f.fach.Bezeichnung))
-    },
-    computed: {
-      faechergruppen: ({ noten }) => Object.entries(_.groupBy(_.sortBy(noten, 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: 9rem;
-}
-.td-fach-note span {
-  background-color: #dcdcdc !important;
-  text-align: center;
-  width: 9rem;
-  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>