Claude-Session: https://claude.ai/code/session_01GGe7kUhooMFuzY6GaDb2w9
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
---
|
||||
title: "NemHandel-opslag"
|
||||
description: "Slå et CVR-nummer op og se om virksomheden er registreret i NemHandelsregisteret, og hvilke profilpakker den understøtter."
|
||||
template: sider/nemhandel.html
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: "NemHandel-opslag"
|
||||
template: sider/peppol.html
|
||||
---
|
||||
@@ -36,11 +36,6 @@
|
||||
}
|
||||
],
|
||||
"kort": [
|
||||
{
|
||||
"href": "/nemhandel",
|
||||
"title": "NemHandel-opslag",
|
||||
"desc": "Slå et CVR-nummer op og se om virksomheden er registreret i NemHandelsregisteret, og hvilke profilpakker den understøtter."
|
||||
},
|
||||
{
|
||||
"href": "/chat",
|
||||
"title": "Spørg mit CV",
|
||||
|
||||
@@ -93,7 +93,7 @@ def lastmods():
|
||||
|
||||
|
||||
def sitemap():
|
||||
skip = ("/tags", "/peppol")
|
||||
skip = ("/tags",)
|
||||
skip_exact = ("/cookies", "/status", "/chat")
|
||||
routes = []
|
||||
for f in pages():
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[{"type":"page","title":"Forside","url":"/"},{"type":"page","title":"CV","url":"/cv"},{"type":"page","title":"CV (English)","url":"/en/cv"},{"type":"page","title":"Home (English)","url":"/en"},{"type":"page","title":"Ask my CV (English)","url":"/en/chat"},{"type":"page","title":"Projekter","url":"/projekter"},
|
||||
{%- for p in pages %}{% if p.components[0] == "projekter" %}{"type":"page","title":{{ ("Projekt: " ~ p.title) | json_encode | safe }},"url":"{{ p.path | trim_end(pat="/") }}","extra":{{ [p.extra.sprog, ...p.extra.aur, ...p.extra.tags] | join(sep=" ") | json_encode | safe }}},{% elif p.components[0] == "en" %}{"type":"page","title":{{ ("Project: " ~ p.title ~ " (English)") | json_encode | safe }},"url":"{{ p.path | trim_end(pat="/") }}","extra":{{ [p.extra.sprog, ...p.extra.aur, ...p.extra.tags] | join(sep=" ") | json_encode | safe }}},{% endif %}{% endfor -%}
|
||||
{"type":"page","title":"Færdigbyggede pakker (tarballz)","url":"/tarballz/"},{"type":"page","title":"Blog","url":"/blog"},{"type":"page","title":"Tags","url":"/tags"},{"type":"page","title":"NemHandel-opslag","url":"/nemhandel"},{"type":"page","title":"Profil-opslag (Nemhandel & Peppol)","url":"/profiler"},{"type":"page","title":"UBL-tjek & identifikator-afkoder","url":"/ubl"},{"type":"page","title":"Spørg mit CV (AI-chat)","url":"/chat"},{"type":"page","title":"Status (homelab)","url":"/status"},{"type":"page","title":"Now","url":"/now"},{"type":"page","title":"Uses","url":"/uses"},{"type":"page","title":"Kolofon","url":"/colophon"},{"type":"page","title":"Cookies","url":"/cookies"}
|
||||
{"type":"page","title":"Færdigbyggede pakker (tarballz)","url":"/tarballz/"},{"type":"page","title":"Blog","url":"/blog"},{"type":"page","title":"Tags","url":"/tags"},{"type":"page","title":"Profil-opslag (Nemhandel & Peppol)","url":"/profiler"},{"type":"page","title":"UBL-tjek & identifikator-afkoder","url":"/ubl"},{"type":"page","title":"Spørg mit CV (AI-chat)","url":"/chat"},{"type":"page","title":"Status (homelab)","url":"/status"},{"type":"page","title":"Now","url":"/now"},{"type":"page","title":"Uses","url":"/uses"},{"type":"page","title":"Kolofon","url":"/colophon"},{"type":"page","title":"Cookies","url":"/cookies"}
|
||||
{%- for p in pages %}{% if p.components[0] == "blog" %},{"type":"post","title":{{ p.title | json_encode | safe }},"url":"{{ p.path | trim_end(pat="/") }}","extra":{{ p.taxonomies.tags | default(value=[]) | join(sep=" ") | json_encode | safe }}}{% endif %}{% endfor %}]
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
{% block main %}
|
||||
<h1 class="text-4xl font-bold tracking-tight">NemHandel-opslag</h1>
|
||||
<p class="mt-4 max-w-2xl text-muted">
|
||||
Tast et CVR-nummer og se om virksomheden er registreret i NemHandelsregisteret, og hvilke
|
||||
<strong class="text-text">profilpakker</strong> den understøtter. Det er et øjebliksbillede,
|
||||
ikke en autoritativ kilde.
|
||||
</p>
|
||||
|
||||
<form id="pep-form" class="mt-8 flex gap-3">
|
||||
<input id="pep-cvr" type="text" inputmode="numeric" pattern="[0-9]{{ 8 }}" maxlength="8" required
|
||||
placeholder="CVR (8 cifre)" autocomplete="off"
|
||||
class="w-44 wt-input wt-input--lg" />
|
||||
<button type="submit" class="wt-btn wt-btn--primary wt-btn--lg">Slå op</button>
|
||||
</form>
|
||||
|
||||
<div id="pep-result" class="mt-8" hidden>
|
||||
<div class="wt-card">
|
||||
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
||||
<h2 id="pep-name" class="text-xl font-semibold tracking-tight"></h2>
|
||||
<span id="pep-badge" class="wt-tag"></span>
|
||||
</div>
|
||||
<p id="pep-cvr-line" class="mt-1 text-sm text-muted"></p>
|
||||
<div id="pep-caps" class="mt-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p id="pep-error" class="mt-8 text-sm text-muted" hidden></p>
|
||||
<div id="peppol-net" class="mt-4" hidden></div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var form = document.getElementById('pep-form');
|
||||
if (!form || form.__wired) return; form.__wired = true;
|
||||
var esc = function (s) { return String(s).replace(/[&<>"]/g, function (c) {
|
||||
return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); };
|
||||
var PROF = {
|
||||
'urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0': 'Peppol BIS Billing 3.0',
|
||||
'urn:fdc:peppol.eu:poacc:trns:order:3': 'Ordering (Order)',
|
||||
'urn:fdc:peppol.eu:poacc:trns:order_response:3': 'Order Response',
|
||||
'urn:fdc:peppol.eu:poacc:trns:despatch_advice:3': 'Despatch Advice',
|
||||
'urn:fdc:peppol.eu:poacc:trns:catalogue:3': 'Catalogue',
|
||||
'urn:fdc:peppol.eu:poacc:trns:invoice_response:3': 'Invoice Response',
|
||||
'urn:fdc:peppol.eu:poacc:trns:mlr:3': 'Message Level Response',
|
||||
};
|
||||
async function loadPeppol(cvr) {
|
||||
var box = document.getElementById('peppol-net'); box.hidden = false;
|
||||
box.innerHTML = '<div class="wt-card"><p class="text-sm text-muted">Slår op i Peppol-netværket…</p></div>';
|
||||
try {
|
||||
var r = await fetch('/api/peppol/smp/' + encodeURIComponent(cvr));
|
||||
var d = await r.json();
|
||||
if (!r.ok) { box.innerHTML = '<div class="wt-card"><p class="text-sm text-muted">Peppol-opslag ikke tilgængeligt lige nu.</p></div>'; return; }
|
||||
if (!d.on_peppol) {
|
||||
box.innerHTML = '<div class="wt-card"><div class="flex items-baseline justify-between gap-2"><h2 class="text-xl font-semibold tracking-tight">Peppol-netværk</h2><span class="wt-tag wt-muted">Ikke fundet</span></div><p class="mt-2 text-sm text-muted">Virksomheden blev ikke fundet i Peppol Directory via CVR-opslag (kan stadig være på Peppol under et andet identifikator-scheme).</p></div>';
|
||||
return;
|
||||
}
|
||||
var docs = (d.doctypes || []).map(function (dt) {
|
||||
var label = PROF[dt.customization] || dt.customization;
|
||||
return '<span class="wt-tag">' + esc(dt.document) + ' · ' + esc(label) + '</span>';
|
||||
}).join('');
|
||||
box.innerHTML = '<div class="wt-card">' +
|
||||
'<div class="flex flex-wrap items-baseline justify-between gap-2"><h2 class="text-xl font-semibold tracking-tight">Peppol-netværk</h2>' +
|
||||
'<span class="wt-tag wt-tag--accent">På Peppol</span></div>' +
|
||||
'<p class="mt-1 text-sm text-muted">' + esc(d.name || '') + (d.country ? ' · ' + esc(d.country) : '') +
|
||||
' · <span class="font-mono text-xs">' + esc(d.participant_id || '') + '</span>' + (d.reg_date ? ' · reg. ' + esc(d.reg_date) : '') + '</p>' +
|
||||
'<p class="mt-4 text-xs font-semibold uppercase tracking-widest text-accent">Kan modtage</p>' +
|
||||
'<div class="mt-2 flex flex-wrap gap-2">' + (docs || '<span class="text-sm text-muted">ingen dokumenttyper</span>') + '</div>' +
|
||||
'<p class="mt-3 text-xs text-muted/80">Live fra Peppol Directory via egen proxy, intet gemt.</p></div>';
|
||||
} catch (_) {
|
||||
box.innerHTML = '<div class="wt-card"><p class="text-sm text-muted">Kunne ikke nå Peppol-opslaget.</p></div>';
|
||||
}
|
||||
}
|
||||
form.addEventListener('submit', async function (e) {
|
||||
e.preventDefault();
|
||||
var res = document.getElementById('pep-result'), err = document.getElementById('pep-error');
|
||||
res.hidden = true; err.hidden = true;
|
||||
var cvr = document.getElementById('pep-cvr').value.trim();
|
||||
var btn = form.querySelector('button'); btn.disabled = true; btn.textContent = 'Slår op…';
|
||||
loadPeppol(cvr);
|
||||
try {
|
||||
var r = await fetch('/api/nemhandel/' + encodeURIComponent(cvr));
|
||||
var data = await r.json();
|
||||
if (!r.ok) { err.textContent = data.error || 'Noget gik galt.. prøv igen.'; err.hidden = false; return; }
|
||||
document.getElementById('pep-name').textContent = data.name || 'Ukendt navn';
|
||||
document.getElementById('pep-cvr-line').textContent = 'CVR ' + data.cvr;
|
||||
var badge = document.getElementById('pep-badge');
|
||||
badge.textContent = data.registered ? 'Registreret i NemHandel' : 'Ikke registreret';
|
||||
badge.className = 'wt-tag ' + (data.registered ? 'wt-tag--accent' : 'wt-muted');
|
||||
var caps = document.getElementById('pep-caps');
|
||||
if (data.registered && (data.profiles.length || data.networks.length)) {
|
||||
caps.innerHTML =
|
||||
(data.networks.length ? '<p class="text-xs font-semibold uppercase tracking-widest text-accent">Netværk</p>' +
|
||||
'<div class="mt-2 flex flex-wrap gap-2">' + data.networks.map(function (n) {
|
||||
return '<span class="wt-tag">' + esc(n) + '</span>'; }).join('') + '</div>' : '') +
|
||||
(data.profiles.length ? '<p class="mt-4 text-xs font-semibold uppercase tracking-widest text-accent">Profilpakker</p>' +
|
||||
'<div class="mt-2 flex flex-wrap gap-2">' + data.profiles.map(function (p) {
|
||||
return '<span class="wt-tag">' + esc(p) + '</span>'; }).join('') + '</div>' : '');
|
||||
} else {
|
||||
caps.innerHTML = '<p class="text-sm text-muted">' + (data.registered
|
||||
? 'Registreret, men ingen profildata i seneste opdatering.'
|
||||
: 'Virksomheden findes i CVR, men er ikke registreret som e-faktura-modtager.') + '</p>';
|
||||
}
|
||||
res.hidden = false;
|
||||
} catch (_) {
|
||||
err.textContent = 'Kunne ikke nå opslagstjenesten.. prøv igen om lidt.'; err.hidden = false;
|
||||
} finally { btn.disabled = false; btn.textContent = 'Slå op'; }
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<p class="mt-10 text-xs text-muted/80">
|
||||
API: <code class="rounded bg-surface-2 px-1.5 py-0.5">curl https://asger.weirsoe.dk/api/nemhandel/<cvr></code> (rate-limited).
|
||||
</p>
|
||||
{% endblock %}
|
||||
@@ -1,14 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="da">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="robots" content="noindex, follow" />
|
||||
<meta http-equiv="refresh" content="0; url=/nemhandel" />
|
||||
<link rel="canonical" href="https://asger.weirsoe.dk/nemhandel" />
|
||||
<title>NemHandel-opslag</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Siden er flyttet til <a href="/nemhandel">/nemhandel</a>…</p>
|
||||
<script>location.replace('/nemhandel');</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user