Merge branch 'master' of https://home.hottis.de/gitlab/hv/hv-ui into master

This commit is contained in:
2021-01-19 10:31:51 +01:00
23 changed files with 397 additions and 6 deletions

View File

@ -2,10 +2,14 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { MietersComponent } from './mieters/mieters.component'; import { MietersComponent } from './mieters/mieters.component';
import { ObjekteComponent } from './objekte/objekte.component'; import { ObjekteComponent } from './objekte/objekte.component';
import { WohnungenComponent } from './wohnungen/wohnungen.component';
import { MieterDetailComponent } from './mieter-detail/mieter-detail.component'
const routes: Routes = [ const routes: Routes = [
{ path: 'objekte', component: ObjekteComponent }, { path: 'objekte', component: ObjekteComponent },
{ path: 'mieters', component: MietersComponent } { path: 'mieters', component: MietersComponent },
{ path: 'mieter/:id', component: MieterDetailComponent },
{ path: 'wohnungen/:objektId', component: WohnungenComponent }
]; ];
@NgModule({ @NgModule({

View File

@ -7,13 +7,17 @@ import { AppComponent } from './app.component';
import { MessagesComponent } from './messages/messages.component'; import { MessagesComponent } from './messages/messages.component';
import { ObjekteComponent } from './objekte/objekte.component'; import { ObjekteComponent } from './objekte/objekte.component';
import { MietersComponent } from './mieters/mieters.component'; import { MietersComponent } from './mieters/mieters.component';
import { WohnungenComponent } from './wohnungen/wohnungen.component';
import { MieterDetailComponent } from './mieter-detail/mieter-detail.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
AppComponent, AppComponent,
MessagesComponent, MessagesComponent,
ObjekteComponent, ObjekteComponent,
MietersComponent MietersComponent,
WohnungenComponent,
MieterDetailComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@ -1 +1 @@
export const serviceBaseUrl = "http://172.16.3.32:5000"; export const serviceBaseUrl = "http://172.16.3.185:5000";

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { ForderungService } from './forderung.service';
describe('ForderungService', () => {
let service: ForderungService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ForderungService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,24 @@
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Forderung } from './forderung';
import { MessageService } from './message.service';
import { serviceBaseUrl } from './config';
@Injectable({
providedIn: 'root'
})
export class ForderungService {
constructor(private messageService: MessageService, private http: HttpClient) { }
getForderungenByMieter(mieterId: number): Promise<Forderung[]> {
this.messageService.add(`ForderungService: fetched forderungen by mieter ${mieterId}`);
return this.http.get<Forderung[]>(`${serviceBaseUrl}/hv/mieter/${mieterId}/forderungen`).toPromise()
}
getForderung(id: number): Promise<Forderung> {
this.messageService.add(`ForderungService: fetch forderung id=${id}`);
return this.http.get<Forderung>(`${serviceBaseUrl}/hv/forderung/${id}`).toPromise()
}
}

View File

@ -0,0 +1,7 @@
export interface Forderung {
id: number;
mieter_id: number;
ref_wohnung: number;
datum: string;
betrag: number;
}

View File

@ -0,0 +1,27 @@
<h1>Mieter: {{mieter.vorname}} {{mieter.nachname}} ({{mieter.id}})</h1>
<table>
<tr><td>Objekt:</td><td>{{mieter.objekt}} ({{mieter.objekt_id}})</td></tr>
<tr><td>Wohnung:</td><td>{{mieter.wohnung}} ({{mieter.wohnung_id}})</td></tr>
<tr><td>Vorname:</td><td>{{mieter.vorname}}</td></tr>
<tr><td>Nachname:</td><td>{{mieter.nachname}}</td></tr>
<tr><td>Anrede:</td><td>{{mieter.anrede}}</td></tr>
<tr><td>Strasse:</td><td>{{mieter.strasse}}</td></tr>
<tr><td>PLZ:</td><td>{{mieter.plz}}</td></tr>
<tr><td>Ort:</td><td>{{mieter.ort}}</td></tr>
<tr><td>Telefon:</td><td>{{mieter.telefon}}</td></tr>
<tr><td>Einzug:</td><td>{{mieter.einzug}}</td></tr>
<tr><td>Auszug:</td><td>{{mieter.auszug}}</td></tr>
</table>
<table>
<tr>
<th>Datum</th>
<th>Forderung</th>
<th>Zahlung</th>
</tr>
<tr *ngFor="let forderung of forderungen">
<td>{{forderung.datum}}</td>
<td>{{forderung.betrag}}<br/><span style="font-size: small;">{{forderung.kommentar}}</span></td>
</tr>
</table>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MieterDetailComponent } from './mieter-detail.component';
describe('MieterDetailComponent', () => {
let component: MieterDetailComponent;
let fixture: ComponentFixture<MieterDetailComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ MieterDetailComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(MieterDetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,43 @@
import { Component, OnInit } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { Location } from '@angular/common'
import { Mieter } from '../mieter'
import { Forderung } from '../forderung'
import { MieterService} from '../mieter.service'
import { ForderungService} from '../forderung.service'
import { MessageService } from '../message.service'
@Component({
selector: 'app-mieter-detail',
templateUrl: './mieter-detail.component.html',
styleUrls: ['./mieter-detail.component.css']
})
export class MieterDetailComponent implements OnInit {
mieter: Mieter
forderungen : Forderung[]
constructor(
private mieterService: MieterService,
private forderungService: ForderungService,
private messageService: MessageService,
private route: ActivatedRoute,
private location: Location ) {
}
async getMieter() {
const id = +this.route.snapshot.paramMap.get('id')
try {
this.mieter = await this.mieterService.getMieter(id)
this.forderungen = await this.forderungService.getForderungenByMieter(id)
} catch (err) {
this.messageService.add(JSON.stringify(err, undefined, 4))
}
}
ngOnInit(): void {
this.getMieter()
}
}

View File

@ -13,5 +13,4 @@ export interface Mieter {
telefon: string; telefon: string;
einzug: string; einzug: string;
auszug: string; auszug: string;
flaeche: number;
} }

View File

@ -1,6 +1,7 @@
<h2>Meine Mieter</h2> <h2>Meine Mieter</h2>
<ul class="mieters"> <ul class="mieters">
<li *ngFor="let mieter of mieters"> <li *ngFor="let mieter of mieters"
routerLink="/mieter/{{mieter.id}}">
<span>{{mieter.vorname}} {{mieter.nachname}}</span> <span>{{mieter.vorname}} {{mieter.nachname}}</span>
</li> </li>
</ul> </ul>

View File

@ -1,6 +1,7 @@
<h2>Meine Objekte</h2> <h2>Meine Objekte</h2>
<ul class="objekte"> <ul class="objekte">
<li *ngFor="let objekt of objekte"> <li *ngFor="let objekt of objekte"
routerLink="/wohnungen/{{objekt.id}}">
<span>{{objekt.shortname}}</span> <span>{{objekt.shortname}}</span>
</li> </li>
</ul> </ul>

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { WohnungService } from './wohnung.service';
describe('WohnungService', () => {
let service: WohnungService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(WohnungService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,29 @@
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Wohnung } from './wohnung';
import { MessageService } from './message.service';
import { serviceBaseUrl } from './config';
@Injectable({
providedIn: 'root'
})
export class WohnungService {
constructor(private messageService: MessageService, private http: HttpClient) { }
getWohnungen(): Promise<Wohnung[]> {
this.messageService.add('WohnungService: fetched wohnungen');
return this.http.get<Wohnung[]>(`${serviceBaseUrl}/hv/wohnungen`).toPromise()
}
getWohnungenByObjekt(objektId: number): Promise<Wohnung[]> {
this.messageService.add(`WohnungService: fetched wohnungen by Objekt ${objektId}`);
return this.http.get<Wohnung[]>(`${serviceBaseUrl}/hv/objekt/${objektId}/wohnungen`).toPromise()
}
getWohnung(id: number): Promise<Wohnung> {
this.messageService.add(`WohnungService: fetch wohnung id=${id}`);
return this.http.get<Wohnung>(`${serviceBaseUrl}/hv/wohnung/${id}`).toPromise()
}
}

8
hv-ui/src/app/wohnung.ts Normal file
View File

@ -0,0 +1,8 @@
export interface Wohnung {
id: number;
objekt_id: number;
wohnung_id: number;
wohnung: string;
objekt: string;
flaeche: number;
}

View File

@ -0,0 +1,57 @@
/* HeroesComponent's private CSS styles */
.wohnungen {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.wohnungen li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.wohnungen li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.wohnungen li.selected {
background-color: #CFD8DC;
color: white;
}
.wohnungen li.selected:hover {
background-color: #BBD8DC;
color: white;
}
.wohnungen .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color:#405061;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
.wohnungen a {
color: #333;
text-decoration: none;
position: relative;
display: block;
width: 250px;
}
.wohnungen a:hover {
color:#607D8B;
}

View File

@ -0,0 +1,10 @@
<h2>Meine Wohnungen</h2>
<h3>Objekt: {{objekt.shortname}}</h3>
<p>
Objektfläche: {{objekt.flaeche}}
</p>
<ul class="wohnungen">
<li *ngFor="let wohnung of wohnungen">
<span>{{wohnung.wohnung}}</span>: <span>{{wohnung.flaeche}}</span>
</li>
</ul>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { WohnungenComponent } from './wohnungen.component';
describe('WohnungenComponent', () => {
let component: WohnungenComponent;
let fixture: ComponentFixture<WohnungenComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ WohnungenComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(WohnungenComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,44 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { Wohnung } from '../wohnung';
import { WohnungService } from '../wohnung.service';
import { ObjektService } from '../objekt.service';
import { MessageService } from '../message.service';
import { Objekt } from '../objekt';
@Component({
selector: 'app-wohnungen',
templateUrl: './wohnungen.component.html',
styleUrls: ['./wohnungen.component.css']
})
export class WohnungenComponent implements OnInit {
wohnungen: Wohnung[];
objekt: Objekt;
constructor(
private wohnungService: WohnungService,
private objektService: ObjektService,
private messageService: MessageService,
private route: ActivatedRoute,
private location: Location ) {
}
async getWohnungen() {
const objektId = +this.route.snapshot.paramMap.get('objektId')
try {
this.objekt = await this.objektService.getObjekt(objektId)
this.wohnungen = await this.wohnungService.getWohnungenByObjekt(objektId);
} catch (err) {
this.messageService.add(JSON.stringify(err, undefined, 4))
}
}
ngOnInit(): void {
this.getWohnungen();
}
}

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { ZahlungForderungService } from './zahlung-forderung.service';
describe('ZahlungForderungService', () => {
let service: ZahlungForderungService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ZahlungForderungService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,25 @@
import { Injectable } from '@angular/core'
import { Observable, of } from 'rxjs'
import { HttpClient, HttpHeaders } from '@angular/common/http'
import { ZahlungForderung } from './zahlung-forderung'
import { Forderung } from './forderung'
import { MessageService } from './message.service'
import { serviceBaseUrl } from './config'
@Injectable({
providedIn: 'root'
})
export class ZahlungForderungService {
constructor(private messageService: MessageService, private http: HttpClient) { }
getZahlungenForderungenByMieterAndYear(mieterId: number, year: number): Promise<ZahlungForderung[]> {
this.messageService.add(`ZahlungForderungService: fetched zahlungen and forderungen by mieter ${mieterId} and year ${year}`)
return this.http.get<ZahlungForderung[]>(`${serviceBaseUrl}/hv/mieter/${mieterId}/zahlungforderung${year}`).toPromise()
}
getForderung(id: number): Promise<Forderung> {
this.messageService.add(`ZahlungForderungService: fetch forderung id=${id}`)
return this.http.get<Forderung>(`${serviceBaseUrl}/hv/forderung/${id}`).toPromise()
}
}

View File

@ -0,0 +1,10 @@
export interface ZahlungForderung {
id: number
zf_type: string
mieter: number
datum_soll: string
datum_ist: string
betrag_zahlung: number
betrag_forderung: number
kommentar: string
}