Kundenansicht P5: Shop-Anfrage im Abo-Modell (Unternehmer aus Kundenart)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b6f2df0d4a
commit
23252df359
3 files changed
+143
-6
No files matched your search
+16
-1
@@ -8,6 +8,8 @@ import { isKundenansicht, logIfKundenansicht } from '../services/kundenansicht.j
|
||||
import { createWriteLimiter } from '../services/writeLimiter.js'
|
||||
import { anfrageAnsicht, ensureShopConfig, leseShopConfig, stelleAnfrage, zieheZurueck } from '../services/shop/anfrage.js'
|
||||
import { shopFuerKunde } from '../services/shop/schalter.js'
|
||||
import { kundenartWirksam } from '../services/kundenart.js'
|
||||
import { neueAnsicht } from '../services/kundenansicht/schalter.js'
|
||||
import { kontoAnlegen, kontoStatus, onboardingLink, statusAusKonto } from '../services/shop/connect.js'
|
||||
import { bestellungKunde, bestellungLesen, csv as bestellungenCsv, erstatte, listeBestellungen, setzeStatus } from '../services/shop/bestellungen.js'
|
||||
import { listeWiderrufe, markiereBearbeitet } from '../services/shop/widerrufe.js'
|
||||
@@ -210,12 +212,25 @@ router.get('/status', requireSession, route(async (req, res) => {
|
||||
res.json(antwort)
|
||||
}))
|
||||
|
||||
/** Kundenart des Kundendokuments (leer oder unbekannt = privat) - nur der Server entscheidet, nie der Client; ein unbekannter Kunde ist privat. */
|
||||
async function kundenartDesKunden(customerId) {
|
||||
try {
|
||||
return kundenartWirksam(await getDocument(config.collections.customers, customerId))
|
||||
} catch (err) {
|
||||
if (err?.status === 404) return 'privat'
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
router.post('/anfrage', requireSession, nurKunde, limitAnfrage, route(async (req, res) => {
|
||||
const customerId = getSessionCustomerId(req)
|
||||
const anfrage = await stelleAnfrage({
|
||||
customerId: getSessionCustomerId(req),
|
||||
customerId,
|
||||
projectId: projectIdOf(req),
|
||||
eingabe: req.body?.anfrage,
|
||||
person: person(req),
|
||||
// Abo-Modell (neue Ansicht): Unternehmer aus der Kundenart, privat nur_betrieb; sonst unveraendert (undefined)
|
||||
kundenart: neueAnsicht(req) ? await kundenartDesKunden(customerId) : undefined,
|
||||
})
|
||||
res.json({ anfrage })
|
||||
}))
|
||||
|
||||
@@ -4,6 +4,7 @@ import { withLocks } from '../keyedLock.js'
|
||||
import { sendAdminNotice, sendCustomerMail } from '../mailer.js'
|
||||
import { assertOwnProject, customerOf, ensureFeatureDoc, getFeatureDoc } from '../siteFeatures.js'
|
||||
import { shopFuerKunde } from './schalter.js'
|
||||
import { NUR_BETRIEB_TEXT } from '../kundenart.js'
|
||||
|
||||
/**
|
||||
* Webshop-Anfrage (Spezifikation 2026-10-05-webshop-design.md, Abschnitt 4 "Auf Anfrage"). Der Kunde stellt eine Anfrage, das Team
|
||||
@@ -163,15 +164,21 @@ async function pruefeZugang({ customerId, projectId, person, neu }) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Anfrage stellen. Reihenfolge: Projekt (403/409 archiviert), Schalter (409), Eingabe (400 mit `fehler`), dann unter Sperre
|
||||
* je Projekt: Funktion muss `off` sein (409), Anfrage-Status '' | abgelehnt | zurueckgezogen (409). Speichert JSON, Status `offen`
|
||||
* und anfrageAt, loescht eine fruehere Entscheidung und schickt T21 ans Team (ein Fehler dabei wird nur geloggt).
|
||||
* Anfrage stellen. Reihenfolge: Projekt (403/409 archiviert), Schalter (409), Kundenart (409 nur_betrieb, nur im Abo-Modell), Eingabe
|
||||
* (400 mit `fehler`), dann unter Sperre je Projekt: Funktion muss `off` sein (409), Anfrage-Status '' | abgelehnt | zurueckgezogen (409).
|
||||
* Speichert JSON, Status `offen` und anfrageAt, loescht eine fruehere Entscheidung und schickt T21 ans Team (ein Fehler dabei wird nur geloggt).
|
||||
* kundenart (nur mit neuer Ansicht, kundenartWirksam des Kundendokuments; ohne Angabe wie bisher): nur Betriebe ('unternehmen') duerfen
|
||||
* anfragen, jeder andere Wert ist 409 nur_betrieb. Fuer Betriebe setzt der Server `unternehmer` auf true (ein Wert des Clients zaehlt
|
||||
* nicht); die gespeicherte Anfrage traegt zusaetzlich kundenart.
|
||||
* @returns {Promise<object>} anfrageAnsicht des neuen Standes
|
||||
*/
|
||||
export async function stelleAnfrage({ customerId, projectId, eingabe, person = {}, now = new Date() }) {
|
||||
export async function stelleAnfrage({ customerId, projectId, eingabe, person = {}, now = new Date(), kundenart }) {
|
||||
const project = await pruefeZugang({ customerId, projectId, person, neu: true })
|
||||
const { anfrage, fehler } = normalisiereAnfrage(eingabe)
|
||||
const abo = kundenart !== undefined
|
||||
if (abo && kundenart !== 'unternehmen') throw stop(409, NUR_BETRIEB_TEXT, 'nur_betrieb')
|
||||
const { anfrage: geprueft, fehler } = normalisiereAnfrage(abo && istObjekt(eingabe) ? { ...eingabe, unternehmer: true } : eingabe)
|
||||
if (fehler) throw Object.assign(stop(400, Object.values(fehler)[0]), { fehler })
|
||||
const anfrage = abo ? { ...geprueft, kundenart } : geprueft
|
||||
|
||||
const gespeichert = await withLocks([`shop-anfrage:${projectId}`], async () => {
|
||||
const feature = await ensureFeatureDoc(customerId, projectId, 'shop')
|
||||
|
||||
Reference in new issue
Block a user