Add giftcard fields, improve errors
This commit is contained in:
+2
-2
@@ -14,13 +14,13 @@
|
|||||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
<querydsl.version>5.1.0</querydsl.version>
|
<querydsl.version>5.1.0</querydsl.version>
|
||||||
<revision>0.4.3</revision>
|
<revision>0.5.0</revision>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.3.4</version>
|
<version>3.3.5</version>
|
||||||
<relativePath />
|
<relativePath />
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ public class TurnoverManager {
|
|||||||
|
|
||||||
JPAQuery<Tuple> query = jpaQueryFactory.from(qTurnover).where(builder.getValue()).groupBy(qTurnover.username)
|
JPAQuery<Tuple> query = jpaQueryFactory.from(qTurnover).where(builder.getValue()).groupBy(qTurnover.username)
|
||||||
.select(qTurnover.username.as("username"), qTurnover.price.sum().as("price"),
|
.select(qTurnover.username.as("username"), qTurnover.price.sum().as("price"),
|
||||||
qTurnover.timeInvestment.sum().as("timeInvestment"));
|
qTurnover.timeInvestment.sum().as("timeInvestment"),
|
||||||
|
qTurnover.giftcardPrice.sum().as("giftcardPrice"));
|
||||||
Long total = query.clone().select(qTurnover.username.countDistinct()).fetchOne();
|
Long total = query.clone().select(qTurnover.username.countDistinct()).fetchOne();
|
||||||
|
|
||||||
if (StringUtils.hasText(sortBy)) {
|
if (StringUtils.hasText(sortBy)) {
|
||||||
|
|||||||
+6
@@ -34,5 +34,11 @@ public class TurnoverValidator implements Validator {
|
|||||||
if (turnover.getPrice() < 0) {
|
if (turnover.getPrice() < 0) {
|
||||||
errors.rejectValue("price", "POSITIVE_VALUE");
|
errors.rejectValue("price", "POSITIVE_VALUE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (turnover.getGiftcardPrice() != null && turnover.getGiftcardPrice() < 0) {
|
||||||
|
errors.rejectValue("giftcardPrice", "POSITIVE_VALUE");
|
||||||
|
} else if (turnover.getGiftcardPrice() != null && turnover.getGiftcardPrice() > turnover.getPrice()) {
|
||||||
|
errors.rejectValue("giftcardPrice", "GREATER_THAN_PRICE");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ public class Turnover {
|
|||||||
@Column(name = "material_consumption", nullable = true, length = 5000)
|
@Column(name = "material_consumption", nullable = true, length = 5000)
|
||||||
private String materialConsumption;
|
private String materialConsumption;
|
||||||
|
|
||||||
|
@Column(name = "giftcard_number", nullable = true)
|
||||||
|
private String giftcardNumber;
|
||||||
|
|
||||||
|
@Column(name = "giftcard_price", nullable = true)
|
||||||
|
private Float giftcardPrice;
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -139,6 +145,22 @@ public class Turnover {
|
|||||||
this.materialConsumption = materialConsumption;
|
this.materialConsumption = materialConsumption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getGiftcardNumber() {
|
||||||
|
return giftcardNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGiftcardNumber(String giftcardNumber) {
|
||||||
|
this.giftcardNumber = giftcardNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float getGiftcardPrice() {
|
||||||
|
return giftcardPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGiftcardPrice(Float giftcardPrice) {
|
||||||
|
this.giftcardPrice = giftcardPrice;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (!(obj instanceof Turnover)) {
|
if (!(obj instanceof Turnover)) {
|
||||||
@@ -170,6 +192,12 @@ public class Turnover {
|
|||||||
equals &= materialConsumption == null && turnover.getMaterialConsumption() == null
|
equals &= materialConsumption == null && turnover.getMaterialConsumption() == null
|
||||||
|| materialConsumption != null && materialConsumption.equals(turnover.getMaterialConsumption());
|
|| materialConsumption != null && materialConsumption.equals(turnover.getMaterialConsumption());
|
||||||
|
|
||||||
|
equals &= giftcardNumber == null && turnover.getGiftcardNumber() == null
|
||||||
|
|| giftcardNumber != null && giftcardNumber.equals(turnover.getGiftcardNumber());
|
||||||
|
|
||||||
|
equals &= giftcardPrice == null && turnover.getGiftcardPrice() == null
|
||||||
|
|| giftcardPrice != null && giftcardPrice.equals(turnover.getGiftcardPrice());
|
||||||
|
|
||||||
return equals;
|
return equals;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+875
-1128
File diff suppressed because it is too large
Load Diff
+19
-19
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "buntspecht-web",
|
"name": "buntspecht-web",
|
||||||
"version": "0.4.3",
|
"version": "0.5.0",
|
||||||
"license": "AGPL3",
|
"license": "AGPL3",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
@@ -12,30 +12,30 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^18.2.7",
|
"@angular/animations": "^18.2.9",
|
||||||
"@angular/cdk": "^18.2.7",
|
"@angular/cdk": "^18.2.10",
|
||||||
"@angular/common": "^18.2.7",
|
"@angular/common": "^18.2.9",
|
||||||
"@angular/compiler": "^18.2.7",
|
"@angular/compiler": "^18.2.9",
|
||||||
"@angular/core": "^18.2.7",
|
"@angular/core": "^18.2.9",
|
||||||
"@angular/forms": "^18.2.7",
|
"@angular/forms": "^18.2.9",
|
||||||
"@angular/material": "^18.2.7",
|
"@angular/material": "^18.2.10",
|
||||||
"@angular/material-moment-adapter": "^18.2.7",
|
"@angular/material-moment-adapter": "^18.2.10",
|
||||||
"@angular/platform-browser": "^18.2.7",
|
"@angular/platform-browser": "^18.2.9",
|
||||||
"@angular/platform-browser-dynamic": "^18.2.7",
|
"@angular/platform-browser-dynamic": "^18.2.9",
|
||||||
"@angular/router": "^18.2.7",
|
"@angular/router": "^18.2.9",
|
||||||
"@angular/service-worker": "^18.2.7",
|
"@angular/service-worker": "^18.2.9",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"rxjs": "~7.8.1",
|
"rxjs": "~7.8.1",
|
||||||
"tslib": "^2.7.0",
|
"tslib": "^2.8.0",
|
||||||
"zone.js": "~0.14.10"
|
"zone.js": "~0.14.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^18.2.7",
|
"@angular-devkit/build-angular": "^18.2.10",
|
||||||
"@angular/cli": "^18.2.7",
|
"@angular/cli": "^18.2.10",
|
||||||
"@angular/compiler-cli": "^18.2.7",
|
"@angular/compiler-cli": "^18.2.9",
|
||||||
"@angular/localize": "^18.2.7",
|
"@angular/localize": "^18.2.9",
|
||||||
"@types/jasmine": "^5.1.4",
|
"@types/jasmine": "^5.1.4",
|
||||||
"jasmine-core": "~5.3.0",
|
"jasmine-core": "~5.4.0",
|
||||||
"karma": "^6.4.4",
|
"karma": "^6.4.4",
|
||||||
"karma-chrome-launcher": "~3.2.0",
|
"karma-chrome-launcher": "~3.2.0",
|
||||||
"karma-coverage": "~2.2.1",
|
"karma-coverage": "~2.2.1",
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
<div class="flex column fill">
|
<div class="flex column fill">
|
||||||
@if (entries && entries.error) {
|
@if (entries && entries.error) {<div class="container">
|
||||||
<div class="flex column fill">
|
<div class="flex column fill center middle">
|
||||||
<mat-card class="accent box">
|
<mat-card class="accent error box">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title>{{ 'management.error.' + entries.error.status | i18n}}</mat-card-title>
|
<mat-card-title>{{ 'management.error.' + entries.error.status | i18n}}</mat-card-title>
|
||||||
<mat-card-subtitle>{{'management.error' | i18n}}</mat-card-subtitle>
|
<mat-card-subtitle>{{'management.error' | i18n}}</mat-card-subtitle>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<p>
|
<p>
|
||||||
{{ 'management.error.' + entries.error.status + '.text' | i18n}}
|
{{ 'management.error.' + entries.error.status + '.text' | i18n}}
|
||||||
</p>
|
</p>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@if (entries && !entries.error) {
|
||||||
<div class="flex wrap filter-container">
|
<div class="flex wrap filter-container">
|
||||||
<a mat-icon-button (click)="filterOpen=!filterOpen" title="{{'turnovers.filter' | i18n}}"
|
<a mat-icon-button (click)="filterOpen=!filterOpen" title="{{'turnovers.filter' | i18n}}"
|
||||||
[color]="filterOpen ? 'primary': 'accent'">
|
[color]="filterOpen ? 'primary': 'accent'">
|
||||||
@@ -51,10 +54,12 @@
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
<span class="spacer"></span>
|
<span class="spacer"></span>
|
||||||
<a class="margin" mat-icon-button (click)="export()" title="{{'turnovers.export' | i18n}}" color="primary" [disabled]="!entries.total">
|
<a class="margin" mat-icon-button (click)="export()" title="{{'turnovers.export' | i18n}}" color="primary"
|
||||||
|
[disabled]="!entries.total">
|
||||||
<mat-icon>file_download</mat-icon>
|
<mat-icon>file_download</mat-icon>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
@if (entries && entries.total == 0) {
|
@if (entries && entries.total == 0) {
|
||||||
<mat-list>
|
<mat-list>
|
||||||
@@ -109,6 +114,22 @@
|
|||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="giftcardPrice">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||||
|
<span class="spacer"></span>
|
||||||
|
<span>{{'turnover.giftcard.priceUsage' | i18n}}</span>
|
||||||
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let entry">
|
||||||
|
<div class="flex">
|
||||||
|
<span class="spacer"></span>
|
||||||
|
<span>{{entry[3] | number: '1.2-2'}}</span>
|
||||||
|
@if (entry[3]) {
|
||||||
|
<span> {{'turnover.price.suffix' | i18n}}</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="menu">
|
<ng-container matColumnDef="menu">
|
||||||
<th mat-header-cell *matHeaderCellDef></th>
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
<td mat-cell *matCellDef="let entry">
|
<td mat-cell *matCellDef="let entry">
|
||||||
@@ -127,8 +148,8 @@
|
|||||||
<ng-container matColumnDef="expanded">
|
<ng-container matColumnDef="expanded">
|
||||||
<td mat-cell *matCellDef="let entry" [attr.colspan]="columns.length">
|
<td mat-cell *matCellDef="let entry" [attr.colspan]="columns.length">
|
||||||
@if (expanded && entries.total && entries.filter && entries.filter.username == entry[0]) {
|
@if (expanded && entries.total && entries.filter && entries.filter.username == entry[0]) {
|
||||||
<ui-turnovers #uiTurnovers class="flex column fill" [turnovers]="turnovers" (page)="applyTurnoverPage($event)"
|
<ui-turnovers #uiTurnovers class="flex column fill" [turnovers]="turnovers"
|
||||||
[enableSort]="false"></ui-turnovers>
|
(page)="applyTurnoverPage($event)" [enableSort]="false"></ui-turnovers>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class PageManagement implements OnInit {
|
|||||||
descending: boolean = false;
|
descending: boolean = false;
|
||||||
filterOpen: boolean = true;
|
filterOpen: boolean = true;
|
||||||
|
|
||||||
columns: string[] = ['username', 'price', 'timeInvestment', 'menu'];
|
columns: string[] = ['username', 'price', 'timeInvestment', 'giftcardPrice', 'menu'];
|
||||||
expanded: boolean = false;
|
expanded: boolean = false;
|
||||||
|
|
||||||
users: Observable<any>;
|
users: Observable<any>;
|
||||||
@@ -198,10 +198,10 @@ export class PageManagement implements OnInit {
|
|||||||
|
|
||||||
export() {
|
export() {
|
||||||
if (this.entries.total) {
|
if (this.entries.total) {
|
||||||
let rows = [[this.i18n.get('user.username'), this.i18n.get('turnover.price'), this.i18n.get('turnover.timeInvestment')]];
|
let rows = [[this.i18n.get('user.username'), this.i18n.get('turnover.price'), this.i18n.get('turnover.timeInvestment'), this.i18n.get('turnover.giftcard.priceUsage')]];
|
||||||
|
|
||||||
this.entries.results.forEach(result => {
|
this.entries.results.forEach(result => {
|
||||||
rows[rows.length] = [result[0], result[1], [result[2]]]
|
rows[rows.length] = [result[0], result[1], result[2], result[3]]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.uiTurnovers) {
|
if (this.uiTurnovers) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="flex column fill center middle">
|
<div class="flex column fill center middle">
|
||||||
<mat-card class="accent box">
|
<mat-card class="accent error box">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title>404</mat-card-title>
|
<mat-card-title>404</mat-card-title>
|
||||||
<mat-card-subtitle>{{'not-found' | i18n}}</mat-card-subtitle>
|
<mat-card-subtitle>{{'not-found' | i18n}}</mat-card-subtitle>
|
||||||
|
|||||||
@@ -8,21 +8,21 @@
|
|||||||
<input matInput formControlName="old" type="password">
|
<input matInput formControlName="old" type="password">
|
||||||
<mat-error *ngFor="let error of passwordForm.get('old').errors | keyvalue">
|
<mat-error *ngFor="let error of passwordForm.get('old').errors | keyvalue">
|
||||||
{{'password.error.' + error.key | i18n}}
|
{{'password.error.' + error.key | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{'password.new' | i18n}}</mat-label>
|
<mat-label>{{'password.new' | i18n}}</mat-label>
|
||||||
<input matInput formControlName="password" type="password">
|
<input matInput formControlName="password" type="password">
|
||||||
<mat-error *ngFor="let error of passwordForm.get('password').errors | keyvalue">
|
<mat-error *ngFor="let error of passwordForm.get('password').errors | keyvalue">
|
||||||
{{'password.error.' + error.key | i18n}}
|
{{'password.error.' + error.key | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{'password.repeat' | i18n}}</mat-label>
|
<mat-label>{{'password.repeat' | i18n}}</mat-label>
|
||||||
<input matInput formControlName="password2" type="password">
|
<input matInput formControlName="password2" type="password">
|
||||||
<mat-error *ngFor="let error of passwordForm.get('password2').errors | keyvalue">
|
<mat-error *ngFor="let error of passwordForm.get('password2').errors | keyvalue">
|
||||||
{{'password.error.' + error.key | i18n}}
|
{{'password.error.' + error.key | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
<mat-card-actions>
|
<mat-card-actions>
|
||||||
|
|||||||
@@ -24,16 +24,16 @@
|
|||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{'turnover.customer' | i18n}}</mat-label>
|
<mat-label>{{'turnover.customer' | i18n}}</mat-label>
|
||||||
<input matInput formControlName="customer" type="text" [required]="true">
|
<input matInput formControlName="customer" type="text" [required]="true">
|
||||||
<mat-error *ngIf="hasError('customer')">
|
<mat-error *ngFor="let error of form.get('customer').errors | keyvalue">
|
||||||
{{'turnover.customer.error' | i18n}}
|
{{'turnover.customer.error.' + error.key | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{'turnover.motif' | i18n}}</mat-label>
|
<mat-label>{{'turnover.motif' | i18n}}</mat-label>
|
||||||
<input matInput formControlName="motif" type="text" [required]="true">
|
<input matInput formControlName="motif" type="text" [required]="true">
|
||||||
<mat-error *ngIf="hasError('motif')">
|
<mat-error *ngFor="let error of form.get('motif').errors | keyvalue">
|
||||||
{{'turnover.motif.error' | i18n}}
|
{{'turnover.motif.error.' + error.key | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
@@ -41,8 +41,29 @@
|
|||||||
<mat-label>{{'turnover.price' | i18n}}</mat-label>
|
<mat-label>{{'turnover.price' | i18n}}</mat-label>
|
||||||
<input matInput formControlName="price" type="number" min="0" step="0.01" [required]="true">
|
<input matInput formControlName="price" type="number" min="0" step="0.01" [required]="true">
|
||||||
<span matTextSuffix>{{'turnover.price.suffix' | i18n}}</span>
|
<span matTextSuffix>{{'turnover.price.suffix' | i18n}}</span>
|
||||||
<mat-error *ngIf="hasError('price')">
|
<mat-error *ngFor="let error of form.get('price').errors | keyvalue">
|
||||||
{{'turnover.price.error' | i18n}}
|
{{'turnover.price.error.' + error.key | i18n}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-slide-toggle class="margin" [checked]="hasGiftcard" (change)="hasGiftcard=$event.checked">
|
||||||
|
{{'turnover.giftcard' | i18n}}
|
||||||
|
</mat-slide-toggle>
|
||||||
|
|
||||||
|
<mat-form-field [ngClass]="{'hidden' : !hasGiftcard}">
|
||||||
|
<mat-label>{{'turnover.giftcard.number' | i18n}}</mat-label>
|
||||||
|
<input matInput formControlName="giftcardNumber" type="text">
|
||||||
|
<mat-error *ngFor="let error of form.get('giftcardNumber').errors | keyvalue">
|
||||||
|
{{'turnover.giftcard.number.error.' + error.key | i18n}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field [ngClass]="{'hidden' : !hasGiftcard}">
|
||||||
|
<mat-label>{{'turnover.giftcard.price' | i18n}}</mat-label>
|
||||||
|
<input matInput formControlName="giftcardPrice" type="number" min="0" step="0.01">
|
||||||
|
<span matTextSuffix>{{'turnover.price.suffix' | i18n}}</span>
|
||||||
|
<mat-error *ngFor="let error of form.get('giftcardPrice').errors | keyvalue">
|
||||||
|
{{'turnover.giftcard.price.error.' + error.key | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
@@ -50,24 +71,24 @@
|
|||||||
<mat-label>{{'turnover.timeInvestment' | i18n}}</mat-label>
|
<mat-label>{{'turnover.timeInvestment' | i18n}}</mat-label>
|
||||||
<input matInput formControlName="timeInvestment" type="number" min="0" step="0.1">
|
<input matInput formControlName="timeInvestment" type="number" min="0" step="0.1">
|
||||||
<span matTextSuffix>{{'turnover.timeInvestment.suffix' | i18n}}</span>
|
<span matTextSuffix>{{'turnover.timeInvestment.suffix' | i18n}}</span>
|
||||||
<mat-error *ngIf="hasError('timeInvestment')">
|
<mat-error *ngFor="let error of form.get('timeInvestment').errors | keyvalue">
|
||||||
{{'turnover.timeInvestment.error' | i18n}}
|
{{'turnover.timeInvestment.error.' + error.key | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{'turnover.remark' | i18n}}</mat-label>
|
<mat-label>{{'turnover.remark' | i18n}}</mat-label>
|
||||||
<textarea matAutosize matAutosizeMinRows="3" matInput formControlName="remark"></textarea>
|
<textarea matAutosize matAutosizeMinRows="3" matInput formControlName="remark"></textarea>
|
||||||
<mat-error *ngIf="hasError('remark')">
|
<mat-error *ngFor="let error of form.get('remark').errors | keyvalue">
|
||||||
{{'turnover.remark.error' | i18n}}
|
{{'turnover.remark.error.' + error.key | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{'turnover.materialConsumption' | i18n}}</mat-label>
|
<mat-label>{{'turnover.materialConsumption' | i18n}}</mat-label>
|
||||||
<textarea matAutosize matAutosizeMinRows="3" matInput formControlName="materialConsumption"></textarea>
|
<textarea matAutosize matAutosizeMinRows="3" matInput formControlName="materialConsumption"></textarea>
|
||||||
<mat-error *ngIf="hasError('materialConsumption')">
|
<mat-error *ngFor="let error of form.get('materialConsumption').errors | keyvalue">
|
||||||
{{'turnover.materialConsumption.error' | i18n}}
|
{{'turnover.materialConsumption.error.' + error.key | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,11 @@ mat-form-field {
|
|||||||
display: block;
|
display: block;
|
||||||
margin: 20px 0 !important;
|
margin: 20px 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
min-width: 390px;
|
min-width: 390px;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export class PageTurnover implements OnInit {
|
|||||||
username: string = "";
|
username: string = "";
|
||||||
admin: boolean = false;
|
admin: boolean = false;
|
||||||
today: Moment = moment();
|
today: Moment = moment();
|
||||||
|
hasGiftcard: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private turnoverService: TurnoverService,
|
private turnoverService: TurnoverService,
|
||||||
@@ -43,6 +44,8 @@ export class PageTurnover implements OnInit {
|
|||||||
customer: ['', Validators.required],
|
customer: ['', Validators.required],
|
||||||
motif: ['', Validators.required],
|
motif: ['', Validators.required],
|
||||||
price: ['', Validators.required],
|
price: ['', Validators.required],
|
||||||
|
giftcardNumber: ['', Validators.nullValidator],
|
||||||
|
giftcardPrice: ['', Validators.nullValidator],
|
||||||
timeInvestment: ['', Validators.nullValidator],
|
timeInvestment: ['', Validators.nullValidator],
|
||||||
remark: ['', Validators.nullValidator],
|
remark: ['', Validators.nullValidator],
|
||||||
materialConsumption: ['', Validators.nullValidator],
|
materialConsumption: ['', Validators.nullValidator],
|
||||||
@@ -74,10 +77,12 @@ export class PageTurnover implements OnInit {
|
|||||||
this.form.get("customer").setValue(this.turnover.customer);
|
this.form.get("customer").setValue(this.turnover.customer);
|
||||||
this.form.get("motif").setValue(this.turnover.motif);
|
this.form.get("motif").setValue(this.turnover.motif);
|
||||||
this.form.get("price").setValue(this.turnover.price);
|
this.form.get("price").setValue(this.turnover.price);
|
||||||
|
this.form.get("giftcardNumber").setValue(this.turnover.giftcardNumber);
|
||||||
|
this.form.get("giftcardPrice").setValue(this.turnover.giftcardPrice);
|
||||||
this.form.get("timeInvestment").setValue(this.turnover.timeInvestment);
|
this.form.get("timeInvestment").setValue(this.turnover.timeInvestment);
|
||||||
this.form.get("remark").setValue(this.turnover.remark);
|
this.form.get("remark").setValue(this.turnover.remark);
|
||||||
this.form.get("materialConsumption").setValue(this.turnover.materialConsumption);
|
this.form.get("materialConsumption").setValue(this.turnover.materialConsumption);
|
||||||
|
this.hasGiftcard = this.turnover.giftcardNumber || this.turnover.giftcardPrice || false;
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
if (error.status == 404) {
|
if (error.status == 404) {
|
||||||
@@ -116,6 +121,13 @@ export class PageTurnover implements OnInit {
|
|||||||
this.turnover.timeInvestment = this.form.get("timeInvestment").value;
|
this.turnover.timeInvestment = this.form.get("timeInvestment").value;
|
||||||
this.turnover.remark = this.form.get("remark").value;
|
this.turnover.remark = this.form.get("remark").value;
|
||||||
this.turnover.materialConsumption = this.form.get("materialConsumption").value;
|
this.turnover.materialConsumption = this.form.get("materialConsumption").value;
|
||||||
|
if (this.hasGiftcard) {
|
||||||
|
this.turnover.giftcardNumber = this.form.get("giftcardNumber").value;
|
||||||
|
this.turnover.giftcardPrice = this.form.get("giftcardPrice").value;
|
||||||
|
} else {
|
||||||
|
this.turnover.giftcardNumber = undefined;
|
||||||
|
this.turnover.giftcardPrice = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
this.turnoverService.create(this.turnover).subscribe({
|
this.turnoverService.create(this.turnover).subscribe({
|
||||||
next: (data) => {
|
next: (data) => {
|
||||||
@@ -152,6 +164,13 @@ export class PageTurnover implements OnInit {
|
|||||||
this.turnover.timeInvestment = this.form.get("timeInvestment").value;
|
this.turnover.timeInvestment = this.form.get("timeInvestment").value;
|
||||||
this.turnover.remark = this.form.get("remark").value;
|
this.turnover.remark = this.form.get("remark").value;
|
||||||
this.turnover.materialConsumption = this.form.get("materialConsumption").value;
|
this.turnover.materialConsumption = this.form.get("materialConsumption").value;
|
||||||
|
if (this.hasGiftcard) {
|
||||||
|
this.turnover.giftcardNumber = this.form.get("giftcardNumber").value;
|
||||||
|
this.turnover.giftcardPrice = this.form.get("giftcardPrice").value;
|
||||||
|
} else {
|
||||||
|
this.turnover.giftcardNumber = undefined;
|
||||||
|
this.turnover.giftcardPrice = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const request = this.admin ? this.turnoverManagementService.update(this.turnover) : this.turnoverService.update(this.turnover);
|
const request = this.admin ? this.turnoverManagementService.update(this.turnover) : this.turnoverService.update(this.turnover);
|
||||||
|
|
||||||
@@ -163,10 +182,11 @@ export class PageTurnover implements OnInit {
|
|||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
this.working = false;
|
this.working = false;
|
||||||
|
this.success = false;
|
||||||
if (error.status == 403) {
|
if (error.status == 403) {
|
||||||
this.snackBar.open("Error");
|
this.snackBar.open("Error");
|
||||||
}
|
}
|
||||||
if (error.status == 422) {
|
if (error.status == 409) {
|
||||||
let errors = {};
|
let errors = {};
|
||||||
for (let code of error.error) {
|
for (let code of error.error) {
|
||||||
errors[code.field] = errors[code.field] || {};
|
errors[code.field] = errors[code.field] || {};
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<div class="flex column fill">
|
<div class="flex column fill">
|
||||||
|
@if (turnovers && !turnovers.error) {
|
||||||
<div class="flex wrap filter-container">
|
<div class="flex wrap filter-container">
|
||||||
<a mat-icon-button (click)="filterOpen=!filterOpen" title="{{'turnovers.filter' | i18n}}"
|
<a mat-icon-button (click)="filterOpen=!filterOpen" title="{{'turnovers.filter' | i18n}}"
|
||||||
[color]="filterOpen ? 'primary': 'accent'">
|
[color]="filterOpen ? 'primary': 'accent'">
|
||||||
@@ -35,11 +36,13 @@
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
<span class="spacer"></span>
|
<span class="spacer"></span>
|
||||||
<a class="margin" mat-icon-button (click)="export()" title="{{'turnovers.export' | i18n}}" color="primary" [disabled]="!turnovers.total">
|
<a class="margin" mat-icon-button (click)="export()" title="{{'turnovers.export' | i18n}}" color="primary"
|
||||||
|
[disabled]="!turnovers.total">
|
||||||
<mat-icon>file_download</mat-icon>
|
<mat-icon>file_download</mat-icon>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<ui-turnovers #uiTurnovers class="flex column grow" [turnovers]="turnovers" [overview]="overview" (page)="applyPage($event)"
|
<ui-turnovers #uiTurnovers class="flex column grow" [turnovers]="turnovers" [overview]="overview"
|
||||||
(sort)="applySort($event)"></ui-turnovers>
|
(page)="applyPage($event)" (sort)="applySort($event)"></ui-turnovers>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="flex column fill center middle">
|
<div class="flex column fill center middle">
|
||||||
<mat-card class="warn box">
|
<mat-card class="warn error box">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title>503</mat-card-title>
|
<mat-card-title>503</mat-card-title>
|
||||||
<mat-card-subtitle>{{'service-unavailable' | i18n}}</mat-card-subtitle>
|
<mat-card-subtitle>{{'service-unavailable' | i18n}}</mat-card-subtitle>
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
mat-form-field {
|
mat-form-field {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 20px 0 !important;
|
margin: 20px 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin: 5px;
|
||||||
|
min-width: 390px;
|
||||||
|
|
||||||
|
@media screen and (min-width: 576px) {
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
form {
|
|
||||||
margin: 5px;
|
@media screen and (min-width: 768px) {
|
||||||
min-width: 390px;
|
max-width: 80%;
|
||||||
|
margin: 15px;
|
||||||
@media screen and (min-width: 576px) {
|
}
|
||||||
max-width: 100%;
|
|
||||||
}
|
@media screen and (min-width: 992px) {
|
||||||
|
max-width: 50%;
|
||||||
@media screen and (min-width: 768px) {
|
}
|
||||||
max-width: 80%;
|
}
|
||||||
margin: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 992px) {
|
|
||||||
max-width: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
<div class="flex column fill">
|
<div class="flex column fill">
|
||||||
@if (users && users.error) {
|
@if (users && users.error) {
|
||||||
<div class="flex column fill">
|
<div class="container">
|
||||||
<mat-card class="accent box">
|
<div class="flex column fill center middle">
|
||||||
<mat-card-header>
|
<mat-card class="accent error box">
|
||||||
<mat-card-title>{{ 'users.error.' + users.error.status | i18n}}</mat-card-title>
|
<mat-card-header>
|
||||||
<mat-card-subtitle>{{'users.error' | i18n}}</mat-card-subtitle>
|
<mat-card-title>{{ 'users.error.' + users.error.status | i18n}}</mat-card-title>
|
||||||
</mat-card-header>
|
<mat-card-subtitle>{{'users.error' | i18n}}</mat-card-subtitle>
|
||||||
<mat-card-content>
|
</mat-card-header>
|
||||||
<p>
|
<mat-card-content>
|
||||||
{{ 'users.error.' + users.error.status + '.text' | i18n}}
|
<p>
|
||||||
</p>
|
{{ 'users.error.' + users.error.status + '.text' | i18n}}
|
||||||
</mat-card-content>
|
</p>
|
||||||
</mat-card>
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
@if (turnovers && turnovers.error) {
|
@if (turnovers && turnovers.error) {
|
||||||
<div class="flex column fill">
|
<div class="container">
|
||||||
<mat-card class="accent box">
|
<div class="flex column fill center middle">
|
||||||
<mat-card-header>
|
<mat-card class="accent error box">
|
||||||
<mat-card-title>{{ 'turnovers.error.' + turnovers.error.status | i18n}}</mat-card-title>
|
<mat-card-header>
|
||||||
<mat-card-subtitle>{{'turnovers.error' | i18n}}</mat-card-subtitle>
|
<mat-card-title>{{ 'turnovers.error.' + turnovers.error.status | i18n}}</mat-card-title>
|
||||||
</mat-card-header>
|
<mat-card-subtitle>{{'turnovers.error' | i18n}}</mat-card-subtitle>
|
||||||
<mat-card-content>
|
</mat-card-header>
|
||||||
<p>
|
<mat-card-content>
|
||||||
{{ 'turnovers.error.' + turnovers.error.status + '.text' | i18n}}
|
<p>
|
||||||
</p>
|
{{ 'turnovers.error.' + turnovers.error.status + '.text' | i18n}}
|
||||||
</mat-card-content>
|
</p>
|
||||||
</mat-card>
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (turnovers) {
|
@if (turnovers && !turnovers.error) {
|
||||||
|
|
||||||
@if (turnovers.total == 0) {
|
@if (turnovers.total == 0) {
|
||||||
<mat-list>
|
<mat-list>
|
||||||
@@ -69,6 +71,22 @@
|
|||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="giftcardPrice">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||||
|
<span class="spacer"></span>
|
||||||
|
<span>{{'turnover.giftcard.price' | i18n}}</span>
|
||||||
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let turnover">
|
||||||
|
<div class="flex">
|
||||||
|
<span class="spacer"></span>
|
||||||
|
<span>{{turnover.giftcardPrice | number: '1.2-2'}}</span>
|
||||||
|
@if (turnover.giftcardPrice) {
|
||||||
|
<span> {{'turnover.price.suffix' | i18n}}</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="timeInvestment">
|
<ng-container matColumnDef="timeInvestment">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
||||||
<span class="spacer"></span>
|
<span class="spacer"></span>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export class UiTurnovers implements OnInit {
|
|||||||
if (width < 992) {
|
if (width < 992) {
|
||||||
this.columns = ['customer', 'price', 'motif'];
|
this.columns = ['customer', 'price', 'motif'];
|
||||||
} else {
|
} else {
|
||||||
this.columns = ['customer', 'motif', 'price', 'timeInvestment', 'remark', 'materialConsumption', 'created', 'updated'];
|
this.columns = ['customer', 'motif', 'price', 'giftcardPrice', 'timeInvestment', 'remark', 'materialConsumption', 'created', 'updated'];
|
||||||
}
|
}
|
||||||
if (this.username) {
|
if (this.username) {
|
||||||
this.columns.unshift('username');
|
this.columns.unshift('username');
|
||||||
@@ -62,6 +62,8 @@ export class UiTurnovers implements OnInit {
|
|||||||
this.i18n.get('turnover.customer'),
|
this.i18n.get('turnover.customer'),
|
||||||
this.i18n.get('turnover.motif'),
|
this.i18n.get('turnover.motif'),
|
||||||
this.i18n.get('turnover.price'),
|
this.i18n.get('turnover.price'),
|
||||||
|
this.i18n.get('turnover.giftcard.number'),
|
||||||
|
this.i18n.get('turnover.giftcard.price'),
|
||||||
this.i18n.get('turnover.timeInvestment'),
|
this.i18n.get('turnover.timeInvestment'),
|
||||||
this.i18n.get('turnover.remark'),
|
this.i18n.get('turnover.remark'),
|
||||||
this.i18n.get('turnover.materialConsumption'),
|
this.i18n.get('turnover.materialConsumption'),
|
||||||
@@ -79,6 +81,8 @@ export class UiTurnovers implements OnInit {
|
|||||||
turnover.customer,
|
turnover.customer,
|
||||||
turnover.motif,
|
turnover.motif,
|
||||||
turnover.price.toFixed(2),
|
turnover.price.toFixed(2),
|
||||||
|
turnover.giftcardNumber,
|
||||||
|
turnover.giftcardPrice && turnover.giftcardPrice.toFixed(2) || '',
|
||||||
turnover.timeInvestment.toFixed(1),
|
turnover.timeInvestment.toFixed(1),
|
||||||
turnover.remark,
|
turnover.remark,
|
||||||
turnover.materialConsumption,
|
turnover.materialConsumption,
|
||||||
|
|||||||
@@ -107,7 +107,9 @@
|
|||||||
},
|
},
|
||||||
"customer": {
|
"customer": {
|
||||||
".": "Kunde",
|
".": "Kunde",
|
||||||
"error": "Angabe von Kunde erforderlich"
|
"error": {
|
||||||
|
"required": "Angabe von Kunde erforderlich"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"dueDate": {
|
"dueDate": {
|
||||||
".": "Fälligkeitsdatum",
|
".": "Fälligkeitsdatum",
|
||||||
@@ -117,15 +119,35 @@
|
|||||||
},
|
},
|
||||||
"delete": "Löschen",
|
"delete": "Löschen",
|
||||||
"edit": "Buchung bearbeiten",
|
"edit": "Buchung bearbeiten",
|
||||||
|
"giftcard": {
|
||||||
|
".": "Gutschein",
|
||||||
|
"number": {
|
||||||
|
".": "Gutscheinnummer",
|
||||||
|
"error": ""
|
||||||
|
},
|
||||||
|
"price": {
|
||||||
|
".": "Gutscheinwert",
|
||||||
|
"error": {
|
||||||
|
"GREATER_THAN_PRICE": "Gutscheinwert übersteigt Preis",
|
||||||
|
"min": "Üngültiger Wert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"priceUsage": "Gutscheinanteil"
|
||||||
|
},
|
||||||
"info": "Neue Buchung erstellen",
|
"info": "Neue Buchung erstellen",
|
||||||
"materialConsumption": "Materialverbrauch",
|
"materialConsumption": "Materialverbrauch",
|
||||||
"motif": {
|
"motif": {
|
||||||
".": "Motiv",
|
".": "Motiv",
|
||||||
"error": "Angabe von Motiv erforderlich"
|
"error": {
|
||||||
|
"required": "Angabe von Motiv erforderlich"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"price": {
|
"price": {
|
||||||
".": "Preis",
|
".": "Preis",
|
||||||
"error": "Angabe des Preises erforderlich",
|
"error": {
|
||||||
|
"min": "Üngültiger Wert",
|
||||||
|
"required": "Angabe des Preises erforderlich"
|
||||||
|
},
|
||||||
"suffix": "€",
|
"suffix": "€",
|
||||||
"total": "Umsatz: {0} €"
|
"total": "Umsatz: {0} €"
|
||||||
},
|
},
|
||||||
@@ -133,6 +155,9 @@
|
|||||||
"success": "Erfolgreich gespeichert",
|
"success": "Erfolgreich gespeichert",
|
||||||
"timeInvestment": {
|
"timeInvestment": {
|
||||||
".": "Zeiteinsatz",
|
".": "Zeiteinsatz",
|
||||||
|
"error": {
|
||||||
|
"min": "Üngültiger Wert"
|
||||||
|
},
|
||||||
"suffix": "Std.",
|
"suffix": "Std.",
|
||||||
"total": "Zeiteinsatz: {0} Std."
|
"total": "Zeiteinsatz: {0} Std."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ app-root {
|
|||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat-card.error {
|
||||||
|
width: 400px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
ui-main {
|
ui-main {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user