diff --git a/api/openapi.yaml b/api/openapi.yaml index 9781178..107850e 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -1519,26 +1519,37 @@ components: type: integer salutation: type: string + nullable: true firstname: type: string + nullable: true lastname: type: string + nullable: true address1: type: string + nullable: true address2: type: string + nullable: true address3: type: string + nullable: true zip: type: string + nullable: true city: type: string + nullable: true phone1: type: string + nullable: true phone2: type: string + nullable: true iban: type: string + nullable: true account: type: integer premise: @@ -1549,6 +1560,7 @@ components: type: integer description: type: string + nullable: true street: type: string zip: @@ -1563,12 +1575,15 @@ components: type: integer description: type: string + nullable: true premise: type: integer + nullable: true area: type: number flat_no: type: integer + nullable: true overhead_advance: description: overhead_advance type: object @@ -1577,12 +1592,15 @@ components: type: integer description: type: string + nullable: true amount: type: number startdate: type: string + nullable: true enddate: type: string + nullable: true overhead_advance_flat_mapping: description: overhead_advance_flat_mapping type: object @@ -1601,8 +1619,10 @@ components: type: integer description: type: string + nullable: true premise: type: integer + nullable: true commercial_premise: description: commercial_premise type: object @@ -1611,8 +1631,10 @@ components: type: integer description: type: string + nullable: true premise: type: integer + nullable: true tenancy: description: tenancy type: object @@ -1621,18 +1643,23 @@ components: type: integer description: type: string + nullable: true tenant: type: integer flat: type: integer + nullable: true parking: type: integer + nullable: true commercial_premise: type: integer + nullable: true startdate: type: string enddate: type: string + nullable: true fee: description: fee type: object @@ -1641,14 +1668,17 @@ components: type: integer description: type: string + nullable: true amount: type: number fee_type: type: string startdate: type: string + nullable: true enddate: type: string + nullable: true tenancy_fee_mapping: description: tenancy_fee_mapping type: object diff --git a/api/openapi.yaml.tmpl b/api/openapi.yaml.tmpl index de768eb..5cd1cc0 100644 --- a/api/openapi.yaml.tmpl +++ b/api/openapi.yaml.tmpl @@ -151,5 +151,8 @@ components: #for $column in $table.columns $column.name: type: $column.apitype +#if (('notnull' not in $column) or (not $column.notnull)) + nullable: true +#end if #end for #end for diff --git a/ui/hv2-ui/src/app/tenant-details/tenant-details.component.html b/ui/hv2-ui/src/app/tenant-details/tenant-details.component.html index c0550f0..b176e9d 100644 --- a/ui/hv2-ui/src/app/tenant-details/tenant-details.component.html +++ b/ui/hv2-ui/src/app/tenant-details/tenant-details.component.html @@ -98,7 +98,8 @@ - @@ -138,6 +139,54 @@ + + + + Mietverhältnis hinzufügen + + + + + + + + + Beginn + + + + + + Beschreibung + + + + + + Wohnung + {{p.rawFlat.description}} {{p.premise}} + + + + Garage + + {{p.rawParking.description}} {{p.premise}} + + + + Büro + + {{p.rawCommercialPremise.description}} {{p.premise}} + + + + + Anlegen + + + diff --git a/ui/hv2-ui/src/app/tenant-details/tenant-details.component.ts b/ui/hv2-ui/src/app/tenant-details/tenant-details.component.ts index a9b18b9..caf0fe3 100644 --- a/ui/hv2-ui/src/app/tenant-details/tenant-details.component.ts +++ b/ui/hv2-ui/src/app/tenant-details/tenant-details.component.ts @@ -6,6 +6,7 @@ import { MessageService } from '../message.service'; import { MatButton } from '@angular/material/button'; import { MatTableDataSource } from '@angular/material/table'; import { ExtApiService } from '../ext-data-object-service'; +import { MatExpansionPanel } from '@angular/material/expansion'; interface DN_Tenancy { @@ -15,6 +16,21 @@ interface DN_Tenancy { commercialPremise: string } +interface DN_Flat { + rawFlat: Flat + premise: string +} + +interface DN_Parking { + rawParking: Parking + premise: string +} + +interface DN_CommercialPremise { + rawCommercialPremise: CommercialPremise + premise: string +} + @Component({ selector: 'app-tenant-details', templateUrl: './tenant-details.component.html', @@ -27,12 +43,15 @@ export class TenantDetailsComponent implements OnInit { account: Account = NULL_Account + premisesMap: Map + tenancies: DN_Tenancy[] tenancyDataSource: MatTableDataSource tenancyDisplayColumns: string[] = [ "description", "flat", "parking", "commercial_premise", "startdate", "enddate" ] collapseTenantDetails: boolean = false collapseTenancies: boolean = false + collapseTenancyMapping: boolean = false selectedTenancy: Tenancy = undefined mappedFees: Fee[] @@ -41,9 +60,15 @@ export class TenantDetailsComponent implements OnInit { allFees: Fee[] selectedFee: number + newTenancy: Tenancy = NULL_Tenancy + allFlats: DN_Flat[] + allParkings: DN_Parking[] + allCommercialPremises: DN_CommercialPremise[] @ViewChild('submitButton') submitButton: MatButton @ViewChild('mapFeeButton') mapFeeButton: MatButton + @ViewChild('panelTenancies') panelTenancies: MatExpansionPanel + @ViewChild('panelAddMapping') panelAddMapping: MatExpansionPanel constructor( private tenantService: TenantService, @@ -78,20 +103,16 @@ export class TenantDetailsComponent implements OnInit { async getTenancies(): Promise { try { this.tenancies = [] - const premises: Premise[] = await this.premiseService.getPremises() - const premisesDict = new Map() - for (let p of premises) { - premisesDict.set(p.id, p) - } + await this.getPremises() for (let t of await this.tenancyService.getTenancysByTenant(this.tenant.id)) { const flat: Flat = (t.flat) ? await this.flatService.getFlat(t.flat) : NULL_Flat const parking: Parking = (t.parking) ? await this.parkingService.getParking(t.parking) : NULL_Parking const commercialPremise: CommercialPremise = (t.commercial_premise) ? await this.commercialPremiseService.getCommercialPremise(t.commercial_premise) : NULL_CommercialPremise this.tenancies.push({ rawTenancy: t, - flat: (flat != NULL_Flat) ? `${flat.description} (${premisesDict.get(flat.premise).description})` : '', - parking: (parking != NULL_Parking) ? `${parking.description} (${premisesDict.get(parking.premise).description})` : '', - commercialPremise: (commercialPremise != NULL_CommercialPremise) ? `${commercialPremise.description} (${premisesDict.get(commercialPremise.premise).description})` : '' + flat: (flat != NULL_Flat) ? `${flat.description} (${this.premisesMap.get(flat.premise).description})` : '', + parking: (parking != NULL_Parking) ? `${parking.description} (${this.premisesMap.get(parking.premise).description})` : '', + commercialPremise: (commercialPremise != NULL_CommercialPremise) ? `${commercialPremise.description} (${this.premisesMap.get(commercialPremise.premise).description})` : '' }) } this.tenancyDataSource = new MatTableDataSource(this.tenancies) @@ -156,7 +177,25 @@ export class TenantDetailsComponent implements OnInit { } } - async addFee() { + async getPremises(): Promise { + if ((! this.premisesMap) || (this.premisesMap.size == 0)) { + try { + this.messageService.add("Trying to load premises") + const premises = await this.premiseService.getPremises() + this.premisesMap = new Map() + for (let p of premises) { + this.premisesMap.set(p.id, p) + } + this.messageService.add("Premises loaded") + } catch (err) { + this.messageService.add(`Error in getPremises: ${ JSON.stringify(err, undefined, 4) }`) + } + } else { + this.messageService.add("Premises already loaded") + } + } + + async addFee(): Promise { try { this.mapFeeButton.disabled = true this.messageService.add(`fee: ${ JSON.stringify(this.selectedFee, undefined, 4) }`) @@ -174,6 +213,79 @@ export class TenantDetailsComponent implements OnInit { } } + async openTenancyMapping(): Promise { + this.messageService.add("TenancyMapping opened") + this.collapseTenancyMapping = true + await this.getPremises() + if (! this.allFlats) { + let flats = await this.flatService.getFlats() + this.allFlats = [] + for (let p of flats) { + this.allFlats.push({ + rawFlat: p, + premise: this.premisesMap.get(p.premise).description + }) + } + } + if (! this.allParkings) { + let parkings = await this.parkingService.getParkings() + this.allParkings = [] + for (let p of parkings) { + this.allParkings.push({ + rawParking: p, + premise: this.premisesMap.get(p.premise).description + }) + } + } + if (! this.allCommercialPremises) { + let commercialPremises = await this.commercialPremiseService.getCommercialPremises() + this.allCommercialPremises = [] + for (let p of commercialPremises) { + this.allCommercialPremises.push({ + rawCommercialPremise: p, + premise: this.premisesMap.get(p.premise).description + }) + } + } + } + + async closeTenancyMapping(): Promise { + this.messageService.add("TenancyMapping closed") + this.collapseTenancyMapping = false + + } + + flatSelected(): void { + this.newTenancy.parking = null + this.newTenancy.commercial_premise = null + } + + parkingSelected(): void { + this.newTenancy.flat = null + this.newTenancy.commercial_premise = null + } + + commercialPremiseSelected(): void { + this.newTenancy.parking = null + this.newTenancy.flat = null + } + + async addTenancyToTenant(): Promise { + try { + this.messageService.add(`Going to mapping ${JSON.stringify(this.newTenancy, undefined, 4)}`) + this.newTenancy.tenant = this.tenant.id + this.messageService.add(`new tenancy is ${JSON.stringify(this.newTenancy, undefined, 4)}`) + this.newTenancy = await this.tenancyService.postTenancy(this.newTenancy) + this.messageService.add(`New tenancy added with id ${this.newTenancy.id}`) + this.panelAddMapping.close() + this.panelTenancies.open() + this.getTenancies() + } catch (err) { + this.messageService.add(`Error in addTenancyToTenant: ${ JSON.stringify(err, undefined, 4)}`) + } + } + + ngOnInit(): void { this.getTenant() this.getFees()