some changes about fee and tenancy mapping

This commit is contained in:
Wolfgang Hottgenroth 2021-09-09 11:36:01 +02:00
parent 3dfb7e2bf2
commit b394a16d7e
Signed by: wn
GPG Key ID: 6C1E5E531E0D5D7F
9 changed files with 332 additions and 136 deletions

View File

@ -8,7 +8,7 @@
/v1/overhead_advances/flat/{flatId}:
get:
tags: [ "overhead_advance", "flat" ]
summary: Return overhead_advances by $flat
summary: Return overhead_advances by flat
operationId: additional_methods.get_overhead_advances_by_flat
parameters:
- name: flatId
@ -27,3 +27,25 @@
$ref: '#/components/schemas/overhead_advance'
security:
- jwt: ['secret']
/v1/fees/tenancy/{tenancyId}:
get:
tags: [ "fee", "tenancy" ]
summary: Return fees by tenancy
operationId: additional_methods.get_fees_by_tenancy
parameters:
- name: tenancyId
in: path
required: true
schema:
type: integer
responses:
'200':
description: get_fees_by_tenancy response
content:
'application/json':
schema:
type: array
items:
$ref: '#/components/schemas/fee'
security:
- jwt: ['secret']

View File

@ -15,3 +15,13 @@ SELECT o.id ,o.description ,o.amount ,o.startdate ,o.enddate
"params": (flatId, )
}
)
def get_fees_by_tenancy(user, token_info, tenancyId=None):
return dbGetMany(user, token_info, {
"statement": """
SELECT o.id, o.description, o.amount, o.fee_type, o.startdate, o.enddate
FROM fee_t o, tenancy_fee_mapping_t m
WHERE o.id = m.fee and m.tenancy = %s""",
"params": (tenancyId, )
}
)

View File

@ -1267,7 +1267,7 @@ paths:
/v1/overhead_advances/flat/{flatId}:
get:
tags: [ "overhead_advance", "flat" ]
summary: Return overhead_advances by $flat
summary: Return overhead_advances by flat
operationId: additional_methods.get_overhead_advances_by_flat
parameters:
- name: flatId
@ -1286,6 +1286,28 @@ paths:
$ref: '#/components/schemas/overhead_advance'
security:
- jwt: ['secret']
/v1/fees/tenancy/{tenancyId}:
get:
tags: [ "fee", "tenancy" ]
summary: Return fees by tenancy
operationId: additional_methods.get_fees_by_tenancy
parameters:
- name: tenancyId
in: path
required: true
schema:
type: integer
responses:
'200':
description: get_fees_by_tenancy response
content:
'application/json':
schema:
type: array
items:
$ref: '#/components/schemas/fee'
security:
- jwt: ['secret']
components:
securitySchemes:

View File

@ -6,15 +6,20 @@ import { MessageService } from './message.service';
import { serviceBaseUrl } from './config';
import { OverheadAdvance } from './data-objects';
import { Fee, OverheadAdvance } from './data-objects';
@Injectable({ providedIn: 'root' })
export class ExtOverheadAdvanceService {
export class ExtApiService {
constructor(private messageService: MessageService, private http: HttpClient) { }
async getOverheadAdvancesByFlat(flatId: number): Promise<OverheadAdvance[]> {
this.messageService.add(`OverheadAdvanceService: get data by flat ${flatId}`);
return this.http.get<OverheadAdvance[]>(`${serviceBaseUrl}/v1/overhead_advances/flat/${flatId}`).toPromise()
async getOverheadAdvancesByFlat(id: number): Promise<OverheadAdvance[]> {
this.messageService.add(`ExtApiService: get overheadadvances by flat ${id}`);
return this.http.get<OverheadAdvance[]>(`${serviceBaseUrl}/v1/overhead_advances/flat/${id}`).toPromise()
}
async getFeeByTenancies(id: number): Promise<Fee[]> {
this.messageService.add(`ExtApiService: get fees by flat ${id}`);
return this.http.get<Fee[]>(`${serviceBaseUrl}/v1/fees/tenancy/${id}`).toPromise()
}
}

View File

@ -5,7 +5,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { ActivatedRoute, Router } from '@angular/router';
import { FlatService, OverheadAdvanceFlatMappingService, OverheadAdvanceService, PremiseService } from '../data-object-service';
import { Flat, OverheadAdvance, OverheadAdvanceFlatMapping, Premise } from '../data-objects';
import { ExtOverheadAdvanceService } from '../ext-data-object-service';
import { ExtApiService } from '../ext-data-object-service';
import { MessageService } from '../message.service';
@Component({
@ -45,7 +45,7 @@ export class FlatDetailsComponent implements OnInit {
constructor(
private flatService: FlatService,
private premiseService: PremiseService,
private extOverheadAdvanceService: ExtOverheadAdvanceService,
private extApiService: ExtApiService,
private overheadAdvanceService: OverheadAdvanceService,
private overheadAdvanceFlatMappingService: OverheadAdvanceFlatMappingService,
private messageService: MessageService,
@ -59,7 +59,7 @@ export class FlatDetailsComponent implements OnInit {
if (id != 0) {
this.flat = await this.flatService.getFlat(id)
this.premise = await this.premiseService.getPremise(this.flat.premise)
this.mappedOverheadAdvances = await this.extOverheadAdvanceService.getOverheadAdvancesByFlat(this.flat.id)
this.mappedOverheadAdvances = await this.extApiService.getOverheadAdvancesByFlat(this.flat.id)
this.dataSource = new MatTableDataSource<OverheadAdvance>(this.mappedOverheadAdvances)
}
} catch (err) {

View File

@ -6,14 +6,14 @@
<mat-toolbar>Menu</mat-toolbar>
<mat-nav-list>
<a mat-list-item href="/tenants">Meine Mieter/innen</a>
</mat-nav-list><hr/><mat-nav-list>
</mat-nav-list><mat-divider></mat-divider><mat-nav-list>
<a mat-list-item href="/flats">Meine Wohnungen</a>
<a mat-list-item href="/parkings">Meine Garagen</a>
<a mat-list-item href="/commercialunits">Meine Büros</a>
</mat-nav-list><hr/><mat-nav-list>
</mat-nav-list><mat-divider></mat-divider><mat-nav-list>
<a mat-list-item href="/overheadadvances">Betriebskostensätze</a>
<a mat-list-item href="/fees">Mietsätze</a>
</mat-nav-list><hr/><mat-nav-list>
</mat-nav-list><mat-divider></mat-divider><mat-nav-list>
<a mat-list-item href="/premises">Meine Häuser</a>
</mat-nav-list>
</mat-sidenav>

View File

@ -6,6 +6,10 @@ table {
flex: 1 1 auto;
}
#addoverheadfield {
#setenddatefield {
margin-right: 15px;
}
#addfeefield {
margin-right: 15px;
}

View File

@ -129,7 +129,7 @@
<td mat-cell *matCellDef="let element">{{element.rawTenancy.enddate}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="tenancyDisplayColumns"></tr>
<tr mat-row *matRowDef="let row; columns: tenancyDisplayColumns;"></tr>
<tr mat-row *matRowDef="let row; columns: tenancyDisplayColumns;" (click)="setSelectedTenancy(row.rawTenancy)"></tr>
</table>
</div>
</mat-expansion-panel>
@ -137,4 +137,70 @@
</mat-card-content>
</mat-card>
<mat-card class="defaultCard" *ngIf="selectedTenancy">
<mat-card-header>
<mat-card-title>
<span>{{selectedTenancy.description}}</span>
<button mat-icon-button color="accent" aria-label="Schließen" (click)="clearSelectedTenancy()">
<mat-icon>done</mat-icon>
</button>
</mat-card-title>
</mat-card-header>
<mat-card-content>
Mietdetails: {{selectedTenancy.description}}
<div>
<form (ngSubmit)="setTenancyEndData()">
<mat-form-field appearance="outline" id="setenddatefield">
<mat-label>Ende</mat-label>
<input matInput name="enddate" [(ngModel)]="selectedTenancy.enddate" [matDatepicker]="enddatepicker"/>
<mat-datepicker-toggle matSuffix [for]="enddatepicker"></mat-datepicker-toggle>
<mat-datepicker #enddatepicker></mat-datepicker>
</mat-form-field>
<button #setTenancyEndDataButton type="submit" mat-raised-button color="primary">Enddatum setzen</button>
</form>
</div>
<div>
<table mat-table [dataSource]="mappedFeesDataSource" #zftable>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef>Beschreibung</th>
<td mat-cell *matCellDef="let element">{{element.description}}</td>
</ng-container>
<ng-container matColumnDef="amount">
<th mat-header-cell *matHeaderCellDef>Betrag</th>
<td mat-cell *matCellDef="let element">{{element.amount}} €</td>
</ng-container>
<ng-container matColumnDef="fee_type">
<th mat-header-cell *matHeaderCellDef>Typ</th>
<td mat-cell *matCellDef="let element">{{element.fee_type}} €</td>
</ng-container>
<ng-container matColumnDef="startdate">
<th mat-header-cell *matHeaderCellDef>Beginn</th>
<td mat-cell *matCellDef="let element">{{element.startdate}}</td>
</ng-container>
<ng-container matColumnDef="enddate">
<th mat-header-cell *matHeaderCellDef>Ende</th>
<td mat-cell *matCellDef="let element">{{element.enddate}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="mappedFeesDisplayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: mappedFeesDisplayedColumns;"></tr>
</table>
</div>
<div>
<form (ngSubmit)="addFee()">
<mat-form-field appearance="standard" id="addfeefield">
<mat-label>Mietsatz</mat-label>
<mat-select #mapSelect [(ngModel)]="selectedFee" name="fee">
<mat-option *ngFor="let p of allFees" [value]="p.id">{{p.description}} {{p.amount}} {{p.startdate}}</mat-option>
</mat-select>
</mat-form-field>
<button #mapFeeButton type="submit" mat-raised-button color="primary">Zuordnen</button>
</form>
</div>
</mat-card-content>
</mat-card>
</section>

View File

@ -1,10 +1,11 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AccountService, CommercialPremiseService, FlatService, ParkingService, PremiseService, TenancyService, TenantService } from '../data-object-service';
import { Account, CommercialPremise, Flat, NULL_Account, NULL_CommercialPremise, NULL_Flat, NULL_Parking, NULL_Tenant, Parking, Premise, Tenancy, Tenant } from '../data-objects';
import { AccountService, CommercialPremiseService, FeeService, FlatService, ParkingService, PremiseService, TenancyFeeMappingService, TenancyService, TenantService } from '../data-object-service';
import { Account, CommercialPremise, Fee, Flat, NULL_Account, NULL_CommercialPremise, NULL_Flat, NULL_Parking, NULL_Tenancy, NULL_Tenant, Parking, Premise, Tenancy, TenancyFeeMapping, Tenant } from '../data-objects';
import { MessageService } from '../message.service';
import { MatButton } from '@angular/material/button';
import { MatTableDataSource } from '@angular/material/table';
import { ExtApiService } from '../ext-data-object-service';
interface DN_Tenancy {
@ -25,14 +26,23 @@ export class TenantDetailsComponent implements OnInit {
account: Account = NULL_Account
tenancies: DN_Tenancy[] = []
tenancies: DN_Tenancy[]
tenancyDataSource: MatTableDataSource<DN_Tenancy>
tenancyDisplayColumns: string[] = [ "description", "flat", "parking", "commercial_premise", "startdate", "enddate" ]
collapseTenantDetails: boolean = false
collapseTenancies: boolean = false
selectedTenancy: Tenancy = undefined
mappedFees: Fee[]
mappedFeesDataSource: MatTableDataSource<Fee>
mappedFeesDisplayedColumns: string[] = [ "description", "amount", "fee_type", "startdate", "enddate" ]
allFees: Fee[]
selectedFee: number
@ViewChild('submitButton') submitButton: MatButton
@ViewChild('mapFeeButton') mapFeeButton: MatButton
constructor(
private tenantService: TenantService,
@ -41,6 +51,9 @@ export class TenantDetailsComponent implements OnInit {
private flatService: FlatService,
private parkingService: ParkingService,
private commercialPremiseService: CommercialPremiseService,
private tenancyFeeMappingService: TenancyFeeMappingService,
private feeService: FeeService,
private extApiService: ExtApiService,
private premiseService: PremiseService,
private messageService: MessageService,
private route: ActivatedRoute,
@ -53,7 +66,16 @@ export class TenantDetailsComponent implements OnInit {
if (id != 0) {
this.tenant = await this.tenantService.getTenant(id)
this.account = await this.accountService.getAccount(this.tenant.account)
this.getTenancies()
}
} catch (err) {
this.messageService.add(JSON.stringify(err, undefined, 4))
}
}
async getTenancies(): Promise<void> {
try {
this.tenancies = []
const premises: Premise[] = await this.premiseService.getPremises()
const premisesDict = new Map<number, Premise>()
for (let p of premises) {
@ -71,13 +93,12 @@ export class TenantDetailsComponent implements OnInit {
})
}
this.tenancyDataSource = new MatTableDataSource<DN_Tenancy>(this.tenancies)
}
} catch (err) {
this.messageService.add(JSON.stringify(err, undefined, 4))
}
}
async saveTenant() {
async saveTenant(): Promise<void> {
try {
this.submitButton.disabled = true
this.messageService.add("saveTenant")
@ -103,8 +124,54 @@ export class TenantDetailsComponent implements OnInit {
}
}
async setSelectedTenancy(selectedTenancy: Tenancy): Promise<void> {
this.selectedTenancy = selectedTenancy
this.getMappedFees()
}
async getMappedFees(): Promise<void> {
this.mappedFees = await this.extApiService.getFeeByTenancies(this.selectedTenancy.id)
this.messageService.add(`setSelectedTenancy: mappedFees: ${JSON.stringify(this.mappedFees, undefined, 4)}`)
this.mappedFeesDataSource = new MatTableDataSource<Fee>(this.mappedFees)
this.messageService.add("mappedFeesDataSource set")
}
clearSelectedTenancy(): void {
this.selectedTenancy = undefined
}
async getFees(): Promise<void> {
try {
this.messageService.add("Trying to load fees")
this.allFees = await this.feeService.getFees()
this.messageService.add("fees loaded")
} catch (err) {
this.messageService.add(JSON.stringify(err, undefined, 4))
}
}
async addFee() {
try {
this.mapFeeButton.disabled = true
this.messageService.add(`fee: ${ JSON.stringify(this.selectedFee, undefined, 4) }`)
let newMapping: TenancyFeeMapping = {
'tenancy': this.selectedTenancy.id,
'fee': this.selectedFee,
'id': 0
}
newMapping = await this.tenancyFeeMappingService.postTenancyFeeMapping(newMapping)
this.messageService.add(`New fee tenancy mapping created: ${newMapping.id}`)
this.selectedFee = undefined
this.getMappedFees()
} finally {
this.mapFeeButton.disabled = false
}
}
ngOnInit(): void {
this.getTenant()
this.getFees()
}
}