feat(supply): unit-centric fit-out & overview — per-unit fit-out, editable demand budget, multi-unit price/availability
- domain/unit: optional per-unit fitOut override (falls back to property.hardFacts.fitOut) - matchSyncService: pre-market unit scored with its own fitOut; matchCardAdapter prefers unit fitOut - PreMarketUnitGrid/PreMarketPanel: per-unit Ausbaustandard override in the release list (default "Wie Objekt") - PropertyDetailOverview: edit/read "Wer baut aus?" for existing listings (SHELL/BASIC), central FIT_OUT_LABELS - Phase 1 unit-centric overview: header shows area+count, price as range, "Verfügbar ab → pro Einheit"; unit table shows per-unit price + availability; "Objekt & Lage" labels marked as object-defaults for multi-unit - NeedExtendedRequirements: "Eigenes Ausbaubudget" only shown when min fit-out set + clearer helper text - UnitStructurePanel: spin-off prefill carries fitOutByLandlord Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
e169f8e310
commit
5d26dd4a6c
8 files changed
+176
-68
No files matched your search
@@ -152,28 +152,29 @@ export function buildMatchCardViewModel(
|
||||
preMarketUnit: unit,
|
||||
preMarketAllUnits: property?.units,
|
||||
fitOutLabel: (() => {
|
||||
const fitOut = property?.hardFacts?.fitOut
|
||||
// Einheit-Ausbau hat Vorrang vor dem Objekt-Ausbau (Pre-Market)
|
||||
const fitOut = unit?.fitOut ?? property?.hardFacts?.fitOut
|
||||
if (!fitOut) return undefined
|
||||
const LABELS: Record<string, string> = { SHELL: 'Rohbau', BASIC: 'Basisausbau', FULL: 'Vollausbau', PREMIUM: 'Premiumausbau' }
|
||||
const mab = property.hardFacts?.mieterausbaubeitragPerSqm
|
||||
const mab = property?.hardFacts?.mieterausbaubeitragPerSqm
|
||||
if (fitOut === 'FULL' || fitOut === 'PREMIUM') return `${LABELS[fitOut]} — bezugsfertig`
|
||||
if (mab) return `${LABELS[fitOut]} + CHF ${mab} MAB`
|
||||
return LABELS[fitOut] ?? fitOut
|
||||
})(),
|
||||
fitOutViable: (() => {
|
||||
const fitOut = property?.hardFacts?.fitOut
|
||||
const fitOut = unit?.fitOut ?? property?.hardFacts?.fitOut
|
||||
if (!fitOut) return undefined
|
||||
if (fitOut === 'FULL' || fitOut === 'PREMIUM') return true
|
||||
const mab = property.hardFacts?.mieterausbaubeitragPerSqm ?? 0
|
||||
const mab = property?.hardFacts?.mieterausbaubeitragPerSqm ?? 0
|
||||
if (fitOut === 'BASIC' && mab >= 150) return true
|
||||
if (fitOut === 'SHELL' && mab >= 350) return true
|
||||
return undefined
|
||||
})(),
|
||||
fitOutInvestment: (() => {
|
||||
const fitOut = property?.hardFacts?.fitOut
|
||||
const fitOut = unit?.fitOut ?? property?.hardFacts?.fitOut
|
||||
if (!fitOut || fitOut === 'FULL' || fitOut === 'PREMIUM') return undefined
|
||||
const mab = property.hardFacts?.mieterausbaubeitragPerSqm ?? 0
|
||||
const area = property.areaSqm ?? 0
|
||||
const mab = property?.hardFacts?.mieterausbaubeitragPerSqm ?? 0
|
||||
const area = unit?.areaSqm ?? property?.areaSqm ?? 0
|
||||
return calcFitOutInvestment(fitOut, area, mab, 0) ?? undefined
|
||||
})(),
|
||||
isDivisible: property?.units ? property.units.length > 1 : false,
|
||||
|
||||
Reference in new issue
Block a user