"use strict"; window.CLIENT = window.CLIENT || null; window.ELWIG_API = window.ELWIG_API || null; function getCredentialsUsername() { return window.localStorage.getItem(`${CLIENT}/username`); } function getCredentialsPassword() { return window.localStorage.getItem(`${CLIENT}/password`); } function getBasicAuth() { return { 'Authorization': 'Basic ' + btoa(getCredentialsUsername() + ':' + getCredentialsPassword()), }; } async function _get(path) { const res = await fetch(`${ELWIG_API}${path}`, { method: 'GET', headers: {...getBasicAuth()}, }); const json = await res.json(); if (!res.ok) throw new ApiError(res.status, json['message']); return json; } async function get(path) { return (await _get(path))['data']; } async function getMember(mgnr) { return await get(`/members/${mgnr}`); } async function getWineVarieties() { return Object.fromEntries((await get('/wine/varieties')).map(item => [item['sortid'], item])); } async function getWineQualityLevels() { return Object.fromEntries((await get('/wine/quality_levels')).map(item => [item['qualid'], item])); } async function getWineAttributes() { return Object.fromEntries((await get('/wine/attributes')).map(item => [item['attrid'], item])); } async function getWineCultivations() { return Object.fromEntries((await get('/wine/cultivations')).map(item => [item['cultid'], item])); } async function getModifiers() { const list = await get('/modifiers'); const dict = {}; for (const item of list) { if (!dict[item['year']]) dict[item['year']] = {}; dict[item['year']][item['modid']] = item; } return dict; } async function getDeliveries(filters, limit, offset) { const query = ['sort=reverse']; if (!!filters) query.push(`filters=${filters.join(',')}`); if (!!limit) query.push(`limit=${limit}`); if (!!offset) query.push(`offset=${offset}`); return await _get(`/deliveries${!!query ? '?' : ''}${query.join('&')}`); } async function getDeliveryStats(filters, detail) { const query = []; if (!!filters) query.push(`filters=${filters.join(',')}`); if (!!detail) query.push(`detail=${detail}`); return await _get(`/deliveries/stat${!!query ? '?' : ''}${query.join('&')}`); } async function getDeliverySchedules(filters, limit, offset) { const query = []; if (!!filters) query.push(`filters=${filters.join(',')}`); if (!!limit) query.push(`limit=${limit}`); if (!!offset) query.push(`offset=${offset}`); return await _get(`/delivery_schedules${!!query ? '?' : ''}${query.join('&')}`); } async function getDeliveryAnnouncements(filters, limit, offset) { const query = []; if (!!filters) query.push(`filters=${filters.join(',')}`); if (!!limit) query.push(`limit=${limit}`); if (!!offset) query.push(`offset=${offset}`); return await _get(`/delivery_announcements${!!query ? '?' : ''}${query.join('&')}`); } async function load() { const main = document.getElementById("access"); const form = main.getElementsByTagName("form")[0]; if (form) { const elements = form.getElementsByClassName('error'); for (const e of elements) form.removeChild(e); } try { window.MEMBER = await getMember(getCredentialsUsername()); const txt = document.getElementById('usertext'); txt.innerHTML = `${MEMBER.prefix ?? ''} ${MEMBER.given_name ?? ''} ${MEMBER.middle_names ?? ''} ${MEMBER.name ?? ''} ${MEMBER.suffix ?? ''}
MgNr. ${MEMBER.mgnr}
`; window.WINE_VARIETIES = await getWineVarieties(); window.WINE_QUALITY_LEVELS = await getWineQualityLevels(); window.WINE_ATTRIBUTES = await getWineAttributes(); window.WINE_CULTIVATIONS = await getWineCultivations(); window.MODIFIERS = await getModifiers(); return true; } catch (e) { if (form) { window.localStorage.removeItem(`${CLIENT}/password`); const error = document.createElement('div'); error.className = 'error'; error.innerText = e.localizedMessage ?? ERROR_MESSAGES[e.message] ?? 'Unbekannter Fehler'; form.insertBefore(error, form.lastChild.previousSibling); } else { window.location.hash = '#/login'; } return false; } } async function init() { if (!getCredentialsUsername() || !getCredentialsPassword()) { window.location.hash = '#/login'; render(); return; } await load(); render(); } async function updateOverview() { const [schedules] = await Promise.all([getDeliverySchedules([`year=${getCurrentLastSeason()}`])]); const main = document.getElementsByTagName('main')[0]; const days = groupBy(schedules.data, 'date'); for (const [dateString, day] of Object.entries(days)) { const row = document.createElement('div'); row.className = 'day'; const date = new Date(dateString); row.innerHTML = `
${fmtDateWeekday(date)}${fmtDate(date)}
`; const container = document.createElement('div'); container.className = 'schedule-container'; for (const schedule of day) { const now = new Date(); const from = schedule.announcement_from !== null ? new Date(schedule.announcement_from) : null; const to = schedule.announcement_to !== null ? new Date(schedule.announcement_to) : null; const status = from === null && to === null ? 'Anmeldung offen' : from > now ? `Anmeldung ab ${fmtDateTime(from)}` : to > now ? `Anmeldung bis ${fmtDateTime(new Date(to - 1))}` : 'Anmeldefrist vorbei'; const link = document.createElement('a'); link.href = `#/anmelden/${schedule.year}/${schedule.dsnr}` link.innerHTML += `
${schedule.description}${status}
`; if (schedule.delivered_weight > 0) { link.innerHTML += ` ${fmtInt(schedule.delivered_weight)} kg / ${fmtInt(schedule.announced_weight)} kg (${fmtInt(Math.round(schedule.delivered_weight / schedule.announced_weight * 100))}%) `; } else { link.innerHTML += ` ${fmtInt(schedule.announced_weight)} kg / ${fmtInt(schedule.max_weight)} kg (${fmtInt(Math.round(schedule.announced_weight / schedule.max_weight * 100))}%) `; } container.append(link); } row.appendChild(container); main.appendChild(row); } } async function updateDeliveries(year) { const filters = [`mgnr=${MEMBER.mgnr}`, `year=${year}`]; const [deliveries, stat] = await Promise.all([getDeliveries(filters), getDeliveryStats(filters)]); const tbody = document.getElementById('delivery-list'); tbody.innerHTML = ''; for (const delivery of deliveries.data) { const tr = document.createElement('tr'); tr.style.background = '#C0C0C0'; tr.innerHTML = ` ${delivery.lsnr} ${fmtDate(new Date(delivery.date))} ${delivery.time.substring(0, 5)} ${delivery.branch.name} ${delivery.comment ?? ''}`; tbody.appendChild(tr); for (const part of delivery.parts) { const tr = document.createElement('tr'); const defaultQualityLevel = getDefaultQualityLevel(part.gradation.kmw); tr.innerHTML = ` ${part.dpnr} ${WINE_VARIETIES[part.variety.sortid]?.name ?? ''} ${WINE_CULTIVATIONS[part.cultivation?.cultid]?.name ?? ''} ${WINE_ATTRIBUTES[part.attribute?.attrid]?.name ?? ''} ${WINE_QUALITY_LEVELS[part.quality_level.qualid]?.name ?? ''} ${fmtOe(part.gradation.oe)} ${fmtKmw(part.gradation.kmw)} ${fmtInt(part.weight)} ${part.modifiers.map(m => MODIFIERS[delivery.year][m.modid]).sort(m => m.ordering).map(m => m.name).join(' / ')} ${part.comment ?? ''}`; tbody.appendChild(tr); } } const element = document.getElementById('delivery-stat'); element.innerText = `(Teil-)Lieferungen: ${fmtInt(stat.data.total.count)} (${fmtInt(stat.data.total.parts)}), Gewicht: ${fmtInt(stat.data.total.weight.sum)} kg`; } function render() { const hash = window.location.hash; const main = document.getElementById("access"); const nav = document.getElementsByTagName("nav")[0].getElementsByTagName("ul")[0]; for (const li of nav.children) li.className = ''; if (hash === '#/login') { main.className = 'login'; main.innerHTML = `

Anmelden

`; } else if (hash === '#/') { nav.children[0].className = 'active'; main.className = 'overview'; main.innerHTML = `

Übersicht

`; updateOverview().then(); } else if (hash === '#/mitglied') { nav.children[1].className = 'active'; main.className = 'member'; main.innerHTML = `

Mitglied

${JSON.stringify(MEMBER, null, 2)}
`; } else if (hash === '#/lieferungen') { nav.children[2].className = 'active'; main.className = 'deliveries'; main.innerHTML = `

Lieferungen

Sorte Bewirt. Attribut Qualitätsstufe Gradation Gewicht Zu-/Abschläge
[°Oe] [°KMW] [kg]
`; updateDeliveries(getCurrentLastSeason()).then(); } else if (hash === '#/anmeldungen') { nav.children[3].className = 'active'; main.className = 'announcements'; main.innerHTML = '

Anmeldungen

'; } else if (hash.startsWith('#/anmelden/')) { nav.children[3].className = 'active'; main.className = 'announce'; main.innerHTML = '

Anmelden

'; } else { window.location.hash = `#/`; } } document.addEventListener('DOMContentLoaded', async () => { await init(); }); window.addEventListener('hashchange', () => { if ((!getCredentialsUsername() || !getCredentialsPassword()) && window.location.hash !== '#/login') { window.location.hash = '#/login'; return; } render(); }); function actionLogin(form) { window.localStorage.setItem(`${CLIENT}/username`, form.username.value); window.localStorage.setItem(`${CLIENT}/password`, form.password.value); load().then(success => { if (success) window.location.hash = '#/'; }); return false; } function actionLogout() { window.localStorage.removeItem(`${CLIENT}/username`); window.localStorage.removeItem(`${CLIENT}/password`); window.location.reload(); }