diff --git a/apps/backend/src/renovation/furniture.service.ts b/apps/backend/src/renovation/furniture.service.ts
index 69eff1d..f383ac1 100644
--- a/apps/backend/src/renovation/furniture.service.ts
+++ b/apps/backend/src/renovation/furniture.service.ts
@@ -281,27 +281,38 @@ export class FurnitureService {
await this.access.require(projectId, userId, 'edit');
await this.owned(this.furniture.requirements, projectId, requirementId);
await this.validateOptionLinks(projectId, dto.budgetCategoryId);
- const totalPrice = this.total(dto);
- const saved = await this.furniture.options.save(
- this.furniture.options.create({
- ...this.optionValues(dto),
+ return this.dataSource.transaction(async (manager) => {
+ const options = manager.getRepository(FurnitureOptionEntity);
+ const saved = await options.save(
+ options.create({
+ ...this.optionValues(dto),
+ projectId,
+ requirementId,
+ totalPrice: this.total(dto),
+ currentlySelected: false,
+ createdByUserId: userId,
+ }),
+ );
+ await manager
+ .getRepository(FurnitureRequirementEntity)
+ .update(
+ { id: requirementId, projectId },
+ { status: FurnitureRequirementStatus.HasOptions },
+ );
+ await this.refreshAutomaticScenarios(projectId, manager);
+ await this.activity(
projectId,
- requirementId,
- totalPrice,
- currentlySelected: false,
- createdByUserId: userId,
- }),
- );
- await this.furniture.requirements.update(
- { id: requirementId, projectId },
- { status: FurnitureRequirementStatus.HasOptions },
- );
- await this.activity(projectId, userId, 'furniture.option-created', {
- requirementId,
- optionId: saved.id,
- name: saved.name,
+ userId,
+ 'furniture.option-created',
+ {
+ requirementId,
+ optionId: saved.id,
+ name: saved.name,
+ },
+ manager,
+ );
+ return saved;
});
- return saved;
}
async updateOption(
projectId: string,
@@ -725,12 +736,27 @@ export class FurnitureService {
}
async deleteScenario(projectId: string, id: string, userId: string) {
await this.access.require(projectId, userId, 'edit');
- const scenario = await this.owned(this.furniture.scenarios, projectId, id);
- if (scenario.isDefault)
- this.conflict(
- 'Das Standardszenario kann nicht archiviert werden. Legen Sie zuerst ein anderes Standardszenario fest.',
+ await this.owned(this.furniture.scenarios, projectId, id);
+ await this.dataSource.transaction(async (manager) => {
+ const scenarios = manager.getRepository(FurnitureScenarioEntity);
+ const scenario = await scenarios.findOneByOrFail({ id, projectId });
+ await scenarios.softDelete({ id, projectId });
+ if (scenario.isDefault) {
+ const replacement = await scenarios.findOne({
+ where: { projectId, deletedAt: IsNull() },
+ order: { createdAt: 'ASC' },
+ });
+ if (replacement)
+ await scenarios.update({ id: replacement.id }, { isDefault: true });
+ }
+ await this.activity(
+ projectId,
+ userId,
+ 'furniture.scenario-deleted',
+ { scenarioId: id },
+ manager,
);
- await this.furniture.scenarios.softDelete({ id, projectId });
+ });
}
async updateSelections(
projectId: string,
@@ -1134,6 +1160,35 @@ export class FurnitureService {
}
await selectionRepo.save(selections);
}
+
+ private async refreshAutomaticScenarios(
+ projectId: string,
+ manager: EntityManager,
+ ) {
+ const scenarios = await manager
+ .getRepository(FurnitureScenarioEntity)
+ .find({
+ where: { projectId, deletedAt: IsNull() },
+ });
+ const selectionRepo = manager.getRepository(
+ FurnitureScenarioSelectionEntity,
+ );
+ for (const scenario of scenarios) {
+ if (
+ ![
+ FurnitureScenarioType.Budget,
+ FurnitureScenarioType.Preferred,
+ FurnitureScenarioType.Premium,
+ FurnitureScenarioType.Existing,
+ ].includes(scenario.type)
+ )
+ continue;
+ await selectionRepo.delete({ projectId, scenarioId: scenario.id });
+ await this.autoSelections(projectId, scenario.id, scenario.type, manager);
+ scenario.version += 1;
+ await manager.getRepository(FurnitureScenarioEntity).save(scenario);
+ }
+ }
private optionValues(dto: CreateFurnitureOptionDto) {
const text = (value?: string) => value?.trim() || null;
const decimal = (value?: number | null) =>
diff --git a/apps/frontend/src/app/features/projects/furniture-section.component.html b/apps/frontend/src/app/features/projects/furniture-section.component.html
index 0cbb86e..12cd2b4 100644
--- a/apps/frontend/src/app/features/projects/furniture-section.component.html
+++ b/apps/frontend/src/app/features/projects/furniture-section.component.html
@@ -97,13 +97,29 @@
{{ scenario.total | currency: 'EUR' : 'symbol' : '1.2-2' : 'de' }}
{{ scenario.selectedRequirements }} gewählt · {{ scenario.openRequirements }} offen
@if (canEdit) {
-
+
+
+
+
+
}
}
@@ -312,7 +328,7 @@
+
+