v0.0.2: pre-productie (Bootstrap 5.3.3, LightPdf klant-PDF, server-setup en release-script)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bffa053c05
commit
7d302dc405
+54
-31
@@ -2,8 +2,8 @@
|
||||
{% block title %}Offerte {{ qt.number }}{% endblock %}
|
||||
{% macro row(l) %}
|
||||
<tr>
|
||||
<td>
|
||||
<select name="l_product" class="prod" aria-label="Product">
|
||||
<td data-label="Product">
|
||||
<select name="l_product" class="prod form-select form-select-sm" aria-label="Product">
|
||||
<option value="">Vrije regel</option>
|
||||
{% for p in products %}
|
||||
<option value="{{ p.id }}" {{ 'selected' if l.product_id == p.id }}
|
||||
@@ -12,14 +12,14 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
<td><textarea name="l_desc" rows="1" aria-label="Omschrijving">{{ l.description }}</textarea></td>
|
||||
<td><input type="number" step="any" name="l_qty" value="{{ l.qty|default(1) }}" aria-label="Aantal"></td>
|
||||
<td><input name="l_unit" value="{{ l.unit }}" aria-label="Eenheid"></td>
|
||||
<td><input type="number" step="0.01" name="l_price" value="{{ l.price }}" aria-label="Prijs">
|
||||
<td data-label="Omschrijving"><textarea class="form-control form-control-sm" name="l_desc" rows="1" aria-label="Omschrijving">{{ l.description }}</textarea></td>
|
||||
<td data-label="Aantal"><input class="form-control form-control-sm" type="number" step="any" inputmode="decimal" name="l_qty" value="{{ l.qty|default(1) }}" aria-label="Aantal"></td>
|
||||
<td data-label="Eenheid"><input class="form-control form-control-sm" name="l_unit" value="{{ l.unit }}" aria-label="Eenheid"></td>
|
||||
<td data-label="Prijs excl."><input class="form-control form-control-sm" type="number" step="0.01" inputmode="decimal" name="l_price" value="{{ l.price }}" aria-label="Prijs">
|
||||
{% if l.product_id and prices.get(l.product_id) is not none and prices[l.product_id] != l.price %}<p class="hint" style="margin:.2rem 0 0">Actueel: {{ prices[l.product_id]|euro }}</p>{% endif %}</td>
|
||||
<td><select name="l_vat" aria-label="Btw">{% for v in [21, 9, 0] %}<option value="{{ v }}" {{ 'selected' if l.vat|default(21) == v }}>{{ v }}%</option>{% endfor %}</select></td>
|
||||
<td class="num amt"></td>
|
||||
<td><button type="button" class="linkbtn del" aria-label="Regel verwijderen">✕</button></td>
|
||||
<td data-label="Btw"><select class="form-select form-select-sm" name="l_vat" aria-label="Btw">{% for v in [21, 9, 0] %}<option value="{{ v }}" {{ 'selected' if l.vat|default(21) == v }}>{{ v }}%</option>{% endfor %}</select></td>
|
||||
<td class="num amt" data-label="Totaal"></td>
|
||||
<td class="del-cell"><button type="button" class="linkbtn del" aria-label="Regel verwijderen">✕</button></td>
|
||||
</tr>
|
||||
{% endmacro %}
|
||||
{% block content %}
|
||||
@@ -27,52 +27,75 @@
|
||||
<div class="head">
|
||||
<div><a class="label" href="{{ url_for('quotes') }}">← Offertes</a><h1>Offerte {{ qt.number }}</h1></div>
|
||||
<div class="actions">
|
||||
<button class="btn ghost" name="then" value="print">Opslaan en afdrukken</button>
|
||||
<button class="btn">Opslaan</button>
|
||||
<button class="btn btn-outline-primary" name="then" value="print">Opslaan en afdrukken</button>
|
||||
<button class="btn btn-primary">Opslaan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="fields">
|
||||
<div><label for="contact">Klant</label>
|
||||
<select id="contact" name="contact_id">
|
||||
<div class="card"><div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6"><label class="form-label" for="contact">Klant</label>
|
||||
<select class="form-select" id="contact" name="contact_id">
|
||||
<option value="">— Kies een contact —</option>
|
||||
{% for c in contacts %}<option value="{{ c.id }}" {{ 'selected' if c.id == qt.contact_id }}>{{ c.name }}{% if c.company %} ({{ c.company }}){% endif %}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div><label for="status">Status</label>
|
||||
<select id="status" name="status">{% for k, l in QUOTE_STATUSES %}<option value="{{ k }}" {{ 'selected' if qt.status == k }}>{{ l }}</option>{% endfor %}</select>
|
||||
<div class="col-md-6"><label class="form-label" for="status">Status</label>
|
||||
<select class="form-select" id="status" name="status">{% for k, l in QUOTE_STATUSES %}<option value="{{ k }}" {{ 'selected' if qt.status == k }}>{{ l }}</option>{% endfor %}</select>
|
||||
<p class="hint">Op "Verzonden" zetten = zichtbaar in het klantportaal.</p>
|
||||
</div>
|
||||
<div><label for="date">Datum</label><input id="date" type="date" name="date" value="{{ qt.date }}"></div>
|
||||
<div><label for="valid">Geldig tot</label><input id="valid" type="date" name="valid_until" value="{{ qt.valid_until or '' }}"></div>
|
||||
<div class="full"><label for="title">Onderwerp</label><input id="title" name="title" value="{{ qt.title }}" placeholder="Bijv. Mantelzorgwoning model Amstel"></div>
|
||||
<div class="full"><label for="intro">Inleiding</label><textarea id="intro" name="intro">{{ qt.intro }}</textarea></div>
|
||||
<div class="col-6"><label class="form-label" for="date">Datum</label><input class="form-control" id="date" type="date" name="date" value="{{ qt.date }}"></div>
|
||||
<div class="col-6"><label class="form-label" for="valid">Geldig tot</label><input class="form-control" id="valid" type="date" name="valid_until" value="{{ qt.valid_until or '' }}"></div>
|
||||
<div class="col-12"><label class="form-label" for="title">Onderwerp</label><input class="form-control" id="title" name="title" value="{{ qt.title }}" placeholder="Bijv. Mantelzorgwoning model Amstel"></div>
|
||||
<div class="col-12"><label class="form-label" for="intro">Inleiding</label><textarea class="form-control" id="intro" name="intro">{{ qt.intro }}</textarea></div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card"><div class="card-body">
|
||||
<h2>Regels</h2>
|
||||
<div class="table-wrap"><table class="lines">
|
||||
<div class="table-responsive"><table class="table lines">
|
||||
<thead><tr><th style="min-width:170px">Product</th><th style="min-width:240px">Omschrijving</th><th style="width:90px">Aantal</th><th style="width:100px">Eenheid</th><th style="width:130px">Prijs excl.</th><th style="width:90px">Btw</th><th class="num" style="width:120px">Totaal</th><th></th></tr></thead>
|
||||
<tbody id="rows">{% for l in lines %}{{ row(l) }}{% endfor %}</tbody>
|
||||
</table></div>
|
||||
<div class="actions"><button type="button" class="btn ghost small" id="add">Regel toevoegen</button></div>
|
||||
<div class="actions"><button type="button" class="btn btn-outline-primary btn-sm" id="add">Regel toevoegen</button></div>
|
||||
<table class="totals">
|
||||
<tr><td>Subtotaal</td><td class="num" id="t-sub"></td></tr>
|
||||
<tbody id="t-vat"></tbody>
|
||||
<tr class="grand"><td>Totaal</td><td class="num" id="t-total"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<div class="card">
|
||||
<label for="notes">Opmerkingen en voorwaarden</label>
|
||||
<textarea id="notes" name="notes">{{ qt.notes }}</textarea>
|
||||
</div>
|
||||
<div class="card"><div class="card-body">
|
||||
<label class="form-label" for="notes">Opmerkingen en voorwaarden</label>
|
||||
<textarea class="form-control" id="notes" name="notes">{{ qt.notes }}</textarea>
|
||||
</div></div>
|
||||
</form>
|
||||
|
||||
<div class="card"><div class="card-body">
|
||||
<div class="card-top">
|
||||
<h2>Bestek uit ontwerp</h2>
|
||||
<div class="actions">
|
||||
{% if bestek %}
|
||||
<a class="btn btn-outline-primary btn-sm" href="{{ url_for('quote_print', qid=qt.id) }}#bestek">Bekijken</a>
|
||||
{% if designs %}<a class="btn btn-outline-primary btn-sm" href="{{ url_for('quote_bestek', qid=qt.id) }}">Opnieuw berekenen</a>{% endif %}
|
||||
<form method="post" action="{{ url_for('quote_bestek_delete', qid=qt.id) }}" class="inline" onsubmit="return confirm('Bestek loskoppelen? De offerteregels blijven staan.')"><button class="btn btn-outline-secondary btn-sm">Loskoppelen</button></form>
|
||||
{% elif designs %}
|
||||
<a class="btn btn-primary btn-sm" href="{{ url_for('quote_bestek', qid=qt.id) }}">Bestek maken</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% if bestek %}
|
||||
<p class="muted" style="margin:0">{{ bestek.design.title }} · berekend {{ bestek.computedAt[:19]|dt }} · {{ bestek.chapters|length }} hoofdstukken ·
|
||||
{{ bestek.totals.exBtw|euro }} excl. btw ({{ bestek.totals.inclBtw|euro }} incl.). Het bestek staat als bijlage bij de offerte, ook in het klantportaal.</p>
|
||||
{% elif designs %}
|
||||
<p class="muted" style="margin:0">Hoeveelheden en prijzen uit het gekozen model van de klant (gevel, dak, kozijnen, stopcontacten, leidingen, …) als offerteregels en bijlage.</p>
|
||||
{% else %}
|
||||
<p class="empty" style="padding:0">Kies (en sla op) een klant met een gekozen model om een bestek uit het ontwerp te maken.</p>
|
||||
{% endif %}
|
||||
</div></div>
|
||||
|
||||
<form method="post" action="{{ url_for('quote_delete', qid=qt.id) }}" onsubmit="return confirm('Offerte verwijderen?')">
|
||||
<button class="btn quiet small">Offerte verwijderen</button>
|
||||
<button class="btn btn-outline-secondary btn-sm">Offerte verwijderen</button>
|
||||
</form>
|
||||
|
||||
<template id="tpl">{{ row({}) }}</template>
|
||||
|
||||
Reference in New Issue
Block a user