Bulk add, delete + BulkEntry add, delete
This commit is contained in:
parent
8e5d639bbe
commit
162e1fd2f3
@ -3,6 +3,7 @@ import {validateNumberNotNull, validateStringNotEmptyNotNull} from "./validators
|
|||||||
export class SearchResult {
|
export class SearchResult {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
readonly type: string,
|
||||||
readonly id: number,
|
readonly id: number,
|
||||||
readonly title: string,
|
readonly title: string,
|
||||||
) {
|
) {
|
||||||
@ -10,6 +11,7 @@ export class SearchResult {
|
|||||||
|
|
||||||
static fromJson(json: any): SearchResult {
|
static fromJson(json: any): SearchResult {
|
||||||
return new SearchResult(
|
return new SearchResult(
|
||||||
|
validateStringNotEmptyNotNull(json['type']),
|
||||||
validateNumberNotNull(json['id']),
|
validateNumberNotNull(json['id']),
|
||||||
validateStringNotEmptyNotNull(json['title']),
|
validateStringNotEmptyNotNull(json['title']),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import {CompatClient, Stomp} from "@stomp/stompjs";
|
|||||||
import {Update} from "./Update";
|
import {Update} from "./Update";
|
||||||
import {LocationStrategy} from "@angular/common";
|
import {LocationStrategy} from "@angular/common";
|
||||||
import {Page} from "./Page";
|
import {Page} from "./Page";
|
||||||
|
import {Next} from "./types";
|
||||||
|
|
||||||
export function NO_OP() {
|
export function NO_OP() {
|
||||||
}
|
}
|
||||||
@ -81,6 +82,10 @@ export class ApiService {
|
|||||||
this.http.post<any>(this.restUrl(path), data).pipe(map(list => list.map(fromJson))).subscribe(next, errorInterceptor(error));
|
this.http.post<any>(this.restUrl(path), data).pipe(map(list => list.map(fromJson))).subscribe(next, errorInterceptor(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete(path: string, next: Next<void>): void {
|
||||||
|
this.http.delete<void>(this.restUrl(path)).subscribe(next);
|
||||||
|
}
|
||||||
|
|
||||||
private restUrl(path: string): string {
|
private restUrl(path: string): string {
|
||||||
return environment.restBase + this.locationStrategy.getBaseHref() + path;
|
return environment.restBase + this.locationStrategy.getBaseHref() + path;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export class BulkEntry {
|
|||||||
readonly version: number,
|
readonly version: number,
|
||||||
readonly position: number,
|
readonly position: number,
|
||||||
readonly enabled: boolean,
|
readonly enabled: boolean,
|
||||||
readonly property: Property,
|
readonly property: Property | null,
|
||||||
readonly value: number,
|
readonly value: number,
|
||||||
) {
|
) {
|
||||||
// nothing
|
// nothing
|
||||||
@ -20,7 +20,7 @@ export class BulkEntry {
|
|||||||
validateNumberNotNull(json['version']),
|
validateNumberNotNull(json['version']),
|
||||||
validateNumberNotNull(json['position']),
|
validateNumberNotNull(json['position']),
|
||||||
validateBooleanNotNull(json['enabled']),
|
validateBooleanNotNull(json['enabled']),
|
||||||
Property.fromJson(json['property']),
|
Property.fromJsonOrNull(json['property']),
|
||||||
validateNumberNotNull(json['value']),
|
validateNumberNotNull(json['value']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/main/angular/src/app/api/bulk/BulkEntryCreate.ts
Normal file
19
src/main/angular/src/app/api/bulk/BulkEntryCreate.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import {Property} from "../property/Property";
|
||||||
|
import {Bulk} from "./Bulk";
|
||||||
|
|
||||||
|
export class BulkEntryCreate {
|
||||||
|
readonly bulkId: number;
|
||||||
|
|
||||||
|
readonly position: number;
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
bulk: Bulk,
|
||||||
|
readonly enabled: boolean,
|
||||||
|
readonly property: Property | null,
|
||||||
|
readonly value: number,
|
||||||
|
) {
|
||||||
|
this.bulkId = bulk.id;
|
||||||
|
this.position = bulk.entries.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,6 +5,19 @@ import {SearchResult} from "../SearchResult";
|
|||||||
import {Update} from "../Update";
|
import {Update} from "../Update";
|
||||||
import {Bulk} from "./Bulk";
|
import {Bulk} from "./Bulk";
|
||||||
import {BulkEntry} from "./BulkEntry";
|
import {BulkEntry} from "./BulkEntry";
|
||||||
|
import {Next} from "../types";
|
||||||
|
import {BulkEntryCreate} from "./BulkEntryCreate";
|
||||||
|
|
||||||
|
class BulkCreate {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
readonly name: string,
|
||||||
|
readonly enabled: boolean,
|
||||||
|
) {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -42,7 +55,7 @@ export class BulkService implements ISearchService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
create(next: (item: Bulk) => void, error: (error: any) => void = NO_OP): void {
|
create(next: (item: Bulk) => void, error: (error: any) => void = NO_OP): void {
|
||||||
this.api.getReturnItem("bulk/create/", Bulk.fromJson, next, error);
|
this.api.postReturnItem("bulk/create/", new BulkCreate("Neu", true), Bulk.fromJson, next, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(bulk: Bulk, next: () => void, error: (error: any) => void = NO_OP): void {
|
delete(bulk: Bulk, next: () => void, error: (error: any) => void = NO_OP): void {
|
||||||
@ -53,4 +66,13 @@ export class BulkService implements ISearchService {
|
|||||||
this.api.putReturnItem("BulkEntry/" + entry.id + "/set/" + key, value, next, error);
|
this.api.putReturnItem("BulkEntry/" + entry.id + "/set/" + key, value, next, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteEntry(entry: BulkEntry, next: Next<void>): void {
|
||||||
|
this.api.delete("BulkEntry/" + entry.id, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
createEntry(bulk: Bulk, next: Next<BulkEntry>): void {
|
||||||
|
const dto: BulkEntryCreate = new BulkEntryCreate(bulk, false, null, 0);
|
||||||
|
this.api.postReturnItem("BulkEntry/create", dto, BulkEntry.fromJson, next);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import {validateDateAllowNull, validateNumberAllowNull, validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators";
|
import {validateDateAllowNull, validateListOrEmpty, validateNumberAllowNull, validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators";
|
||||||
import {Channel} from "../channel/Channel";
|
import {Channel} from "../channel/Channel";
|
||||||
|
import {SearchResult} from "../SearchResult";
|
||||||
|
|
||||||
export class Property {
|
export class Property {
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ export class Property {
|
|||||||
public timestamp: Date | null,
|
public timestamp: Date | null,
|
||||||
public readChannel: Channel | null,
|
public readChannel: Channel | null,
|
||||||
public writeChannel: Channel | null,
|
public writeChannel: Channel | null,
|
||||||
|
public usages: SearchResult[],
|
||||||
) {
|
) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
@ -31,9 +33,17 @@ export class Property {
|
|||||||
validateDateAllowNull(json['timestamp']),
|
validateDateAllowNull(json['timestamp']),
|
||||||
Channel.fromJsonAllowNull(json['readChannel']),
|
Channel.fromJsonAllowNull(json['readChannel']),
|
||||||
Channel.fromJsonAllowNull(json['writeChannel']),
|
Channel.fromJsonAllowNull(json['writeChannel']),
|
||||||
|
validateListOrEmpty(json['usages'], SearchResult.fromJson),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJsonOrNull(json: any): Property | null {
|
||||||
|
if (json === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
public static trackBy(index: number, item: Property): number {
|
public static trackBy(index: number, item: Property): number {
|
||||||
return item.id;
|
return item.id;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {ISearchService} from "../ISearchService";
|
|||||||
import {SearchResult} from "../SearchResult";
|
import {SearchResult} from "../SearchResult";
|
||||||
import {Update} from "../Update";
|
import {Update} from "../Update";
|
||||||
import {Property} from "./Property";
|
import {Property} from "./Property";
|
||||||
|
import {Next} from "../types";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -40,4 +41,8 @@ export class PropertyService implements ISearchService {
|
|||||||
this.api.getReturnItem("property/create/", Property.fromJson, next, error);
|
this.api.getReturnItem("property/create/", Property.fromJson, next, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete(property: Property, next: Next<void>): void {
|
||||||
|
this.api.delete("property/" + property.id, next);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
<table>
|
<ng-container *ngIf="bulk">
|
||||||
|
<h1>{{bulk.name}}</h1>
|
||||||
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Eigenschaft</th>
|
<th>Eigenschaft</th>
|
||||||
<th>Wert</th>
|
<th>Wert</th>
|
||||||
|
<th> </th>
|
||||||
</tr>
|
</tr>
|
||||||
<ng-container *ngIf="bulk">
|
<ng-container *ngIf="bulk">
|
||||||
<tr *ngFor="let entry of bulk.entries">
|
<tr *ngFor="let entry of bulk.entries">
|
||||||
@ -9,6 +12,7 @@
|
|||||||
<app-search [searchService]="propertyService" [allowEmpty]="false" [initial]="entry.property?.id" (valueChange)="setEntry(entry, 'property', $event)"></app-search>
|
<app-search [searchService]="propertyService" [allowEmpty]="false" [initial]="entry.property?.id" (valueChange)="setEntry(entry, 'property', $event)"></app-search>
|
||||||
</td>
|
</td>
|
||||||
<ng-container [ngSwitch]="entry.property?.type">
|
<ng-container [ngSwitch]="entry.property?.type">
|
||||||
|
|
||||||
<td *ngSwitchCase="'BOOLEAN'" [class.true]="entry.value" [class.false]="!entry.value" (click)="setEntry(entry, 'value', entry.value > 0 ? 0 : 1)">
|
<td *ngSwitchCase="'BOOLEAN'" [class.true]="entry.value" [class.false]="!entry.value" (click)="setEntry(entry, 'value', entry.value > 0 ? 0 : 1)">
|
||||||
{{entry.value ? "An" : "Aus"}}
|
{{entry.value ? "An" : "Aus"}}
|
||||||
</td>
|
</td>
|
||||||
@ -40,7 +44,17 @@
|
|||||||
<td *ngSwitchDefault class="empty">
|
<td *ngSwitchDefault class="empty">
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
<td class="delete">
|
||||||
|
<fa-icon title="Löschen" [icon]="faTimes" (click)="delete(entry)"></fa-icon>
|
||||||
|
</td>
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<button (click)="create()">+ Hinzufügen</button>
|
||||||
|
</p>
|
||||||
|
</ng-container>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {Bulk} from "../../../api/bulk/Bulk";
|
|||||||
import {ActivatedRoute} from "@angular/router";
|
import {ActivatedRoute} from "@angular/router";
|
||||||
import {PropertyService} from "../../../api/property/property.service";
|
import {PropertyService} from "../../../api/property/property.service";
|
||||||
import {BulkEntry} from "../../../api/bulk/BulkEntry";
|
import {BulkEntry} from "../../../api/bulk/BulkEntry";
|
||||||
|
import {faTimesCircle} from "@fortawesome/free-regular-svg-icons";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-bulk',
|
selector: 'app-bulk',
|
||||||
@ -12,6 +13,8 @@ import {BulkEntry} from "../../../api/bulk/BulkEntry";
|
|||||||
})
|
})
|
||||||
export class BulkComponent implements OnInit {
|
export class BulkComponent implements OnInit {
|
||||||
|
|
||||||
|
readonly faTimes = faTimesCircle;
|
||||||
|
|
||||||
bulk!: Bulk;
|
bulk!: Bulk;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -44,4 +47,14 @@ export class BulkComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete(entry: BulkEntry): void {
|
||||||
|
if (confirm(`Eintrag #"${entry.position}" wirklich löschen?`)) {
|
||||||
|
this.bulkService.deleteEntry(entry, () => this.bulk.entries.splice(this.bulk.entries.findIndex(e => e.id === entry.id), 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
create(): void {
|
||||||
|
this.bulkService.createEntry(this.bulk, entry => this.update(entry));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,12 +14,17 @@
|
|||||||
<th>Zeitstempel</th>
|
<th>Zeitstempel</th>
|
||||||
<th>Lesekanal</th>
|
<th>Lesekanal</th>
|
||||||
<th>Schreibkanal</th>
|
<th>Schreibkanal</th>
|
||||||
|
<th>
|
||||||
|
<fa-icon title="Löschen" [icon]="faTimes"></fa-icon>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<ng-container *ngFor="let property of properties.sort(Property.compareTypeThenTitle)">
|
<ng-container *ngFor="let property of properties.sort(Property.compareTypeThenTitle)">
|
||||||
<tr>
|
<tr>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<app-edit-field [initial]="property.title" (valueChange)="edit(property, 'title', $event)"></app-edit-field>
|
<app-edit-field [initial]="property.title" (valueChange)="edit(property, 'title', $event)"></app-edit-field>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<select [(ngModel)]="property.type" (ngModelChange)="edit(property, 'type', property.type)">
|
<select [(ngModel)]="property.type" (ngModelChange)="edit(property, 'type', property.type)">
|
||||||
<option value="BOOLEAN">Schalter</option>
|
<option value="BOOLEAN">Schalter</option>
|
||||||
@ -30,6 +35,7 @@
|
|||||||
<option value="SCENE">Szene</option>
|
<option value="SCENE">Szene</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<ng-container *ngIf="property.value !== null else empty">
|
<ng-container *ngIf="property.value !== null else empty">
|
||||||
<td *ngIf="property.type === 'BOOLEAN'" class="boolean" [class.true]="property.value" [class.false]="!property.value" (click)="edit(property, 'value', property.value > 0 ? 0 : 1)">
|
<td *ngIf="property.type === 'BOOLEAN'" class="boolean" [class.true]="property.value" [class.false]="!property.value" (click)="edit(property, 'value', property.value > 0 ? 0 : 1)">
|
||||||
{{property.value ? "An" : "Aus"}}
|
{{property.value ? "An" : "Aus"}}
|
||||||
@ -50,15 +56,22 @@
|
|||||||
{{findScene(property)?.title || "Unbekannt: " + property.value}}
|
{{findScene(property)?.title || "Unbekannt: " + property.value}}
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<td *ngIf="property.timestamp !== null else empty">
|
<td *ngIf="property.timestamp !== null else empty">
|
||||||
{{property.timestamp | date:'yyyy-MM-dd HH:mm:ss'}}
|
{{property.timestamp | date:'yyyy-MM-dd HH:mm:ss'}}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="full">
|
<td class="full">
|
||||||
<app-search [searchService]="channelService" [initial]="property.readChannel?.id" (valueChange)="set(property, 'readChannel', $event)"></app-search>
|
<app-search [searchService]="channelService" [initial]="property.readChannel?.id" (valueChange)="set(property, 'readChannel', $event)"></app-search>
|
||||||
</td>
|
</td>
|
||||||
<td class="full">
|
<td class="full">
|
||||||
<app-search [searchService]="channelService" [initial]="property.writeChannel?.id" (valueChange)="set(property, 'writeChannel', $event)"></app-search>
|
<app-search [searchService]="channelService" [initial]="property.writeChannel?.id" (valueChange)="set(property, 'writeChannel', $event)"></app-search>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
<td class="delete">
|
||||||
|
<fa-icon title="Löschen" *ngIf="property.usages.length === 0" [icon]="faTimes" (click)="delete(property)"></fa-icon>
|
||||||
|
</td>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {PropertyService} from "../../api/property/property.service";
|
|||||||
import {Scene} from "../../api/scene/Scene";
|
import {Scene} from "../../api/scene/Scene";
|
||||||
import {SceneService} from "../../api/scene/scene.service";
|
import {SceneService} from "../../api/scene/scene.service";
|
||||||
import {ChannelService} from "../../api/channel/channel.service";
|
import {ChannelService} from "../../api/channel/channel.service";
|
||||||
|
import {faTimesCircle} from "@fortawesome/free-regular-svg-icons";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-property-list',
|
selector: 'app-property-list',
|
||||||
@ -12,6 +13,8 @@ import {ChannelService} from "../../api/channel/channel.service";
|
|||||||
})
|
})
|
||||||
export class PropertyListComponent implements OnInit {
|
export class PropertyListComponent implements OnInit {
|
||||||
|
|
||||||
|
readonly faTimes = faTimesCircle;
|
||||||
|
|
||||||
Property = Property;
|
Property = Property;
|
||||||
|
|
||||||
properties: Property[] = [];
|
properties: Property[] = [];
|
||||||
@ -80,4 +83,10 @@ export class PropertyListComponent implements OnInit {
|
|||||||
this.propertyService.create(property => this.updateProperty(property, true));
|
this.propertyService.create(property => this.updateProperty(property, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete(property: Property): void {
|
||||||
|
if (confirm(`Eigenschaft "${property.title}" wirklich löschen?`)) {
|
||||||
|
this.propertyService.delete(property, () => this.properties.splice(this.properties.findIndex(p => p.id === property.id), 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,6 +98,7 @@ table.vertical {
|
|||||||
|
|
||||||
.delete {
|
.delete {
|
||||||
color: darkred;
|
color: darkred;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.disabled {
|
.disabled {
|
||||||
|
|||||||
@ -18,6 +18,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "UnusedReturnValue", "SameParameterValue", "UnusedAssignment", "RedundantSuppression"})
|
@SuppressWarnings({"unchecked", "UnusedReturnValue", "SameParameterValue", "UnusedAssignment", "RedundantSuppression"})
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -52,7 +54,8 @@ public class DemoDataService {
|
|||||||
bulkEntryController.create(new BulkEntryCreateDto(bulk.getId(), propertyBulkBrightness.getId(), 40, 0));
|
bulkEntryController.create(new BulkEntryCreateDto(bulk.getId(), propertyBulkBrightness.getId(), 40, 0));
|
||||||
bulkEntryController.create(new BulkEntryCreateDto(bulk.getId(), propertyBulkColorTemperature.getId(), 55, 0));
|
bulkEntryController.create(new BulkEntryCreateDto(bulk.getId(), propertyBulkColorTemperature.getId(), 55, 0));
|
||||||
final long scheduleId = createSchedule(true, "schedule");
|
final long scheduleId = createSchedule(true, "schedule");
|
||||||
createTime(scheduleId, true, 12, 0, 0, 0, propertyDirect, 1, bulk);
|
final ZonedDateTime now = ZonedDateTime.now().plusSeconds(3);
|
||||||
|
createTime(scheduleId, true, now.getHour(), now.getMinute(), now.getSecond(), 0, propertyDirect, 1, bulk);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Property createProperty(final String title, final PropertyType type, final Channel readChannel, final Channel writeChannel) {
|
private Property createProperty(final String title, final PropertyType type, final Channel readChannel, final Channel writeChannel) {
|
||||||
|
|||||||
@ -72,7 +72,7 @@ public class BulkController implements ISearchController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SearchResult toSearchResult(final BulkDto bulkDto) {
|
private SearchResult toSearchResult(final BulkDto bulkDto) {
|
||||||
return new SearchResult(bulkDto.getId(), bulkDto.getName());
|
return new SearchResult(Bulk.class, bulkDto.getId(), bulkDto.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ public class BulkExecutor {
|
|||||||
private final PropertyWriteService propertyWriteService;
|
private final PropertyWriteService propertyWriteService;
|
||||||
|
|
||||||
public void execute(final Bulk bulk) {
|
public void execute(final Bulk bulk) {
|
||||||
log.debug("Executing Bulk: {}", bulk);
|
log.info("Executing Bulk: {}", bulk);
|
||||||
bulk.getEntries().forEach(entry -> propertyWriteService.writeToChannel(entry.getProperty(), entry.getValue()));
|
bulk.getEntries().forEach(entry -> propertyWriteService.writeToChannel(entry.getProperty(), entry.getValue()));
|
||||||
log.debug("Finished executing Bulk: {}", bulk);
|
log.debug("Finished executing Bulk: {}", bulk);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ public class BulkMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BulkEntryDto toDto(final BulkEntry entry) {
|
public BulkEntryDto toDto(final BulkEntry entry) {
|
||||||
final PropertyDto property = propertyMapper.toDto(entry.getProperty());
|
final PropertyDto property = propertyMapper.toDtoOrNull(entry.getProperty());
|
||||||
return new BulkEntryDto(entry, property);
|
return new BulkEntryDto(entry, property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.homeautomation.bulk;
|
package de.ph87.homeautomation.bulk;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.property.Property;
|
||||||
import de.ph87.homeautomation.web.NotFoundException;
|
import de.ph87.homeautomation.web.NotFoundException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -46,4 +47,8 @@ public class BulkReader {
|
|||||||
return bulkRepository.findByEntries_Id(id).orElseThrow(NotFoundException.supply(Bulk.class, "entries_id", id));
|
return bulkRepository.findByEntries_Id(id).orElseThrow(NotFoundException.supply(Bulk.class, "entries_id", id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Bulk> findAllByProperty(final Property property) {
|
||||||
|
return bulkRepository.findDistinctByEntries_Property(property);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.homeautomation.bulk;
|
package de.ph87.homeautomation.bulk;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.property.Property;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
@ -13,4 +14,6 @@ public interface BulkRepository extends JpaRepository<Bulk, Long>, JpaSpecificat
|
|||||||
|
|
||||||
Optional<Bulk> findByEntries_Id(long id);
|
Optional<Bulk> findByEntries_Id(long id);
|
||||||
|
|
||||||
|
List<Bulk> findDistinctByEntries_Property(Property property);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,7 @@ public class BulkEntry {
|
|||||||
private int position;
|
private int position;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
@ManyToOne(optional = false)
|
@ManyToOne
|
||||||
private Property property;
|
private Property property;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
|
|||||||
@ -22,8 +22,8 @@ public class BulkEntryController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("{id}/set/property")
|
@PutMapping("{id}/set/property")
|
||||||
public BulkEntryDto setValue(@PathVariable final long id, @RequestBody final long propertyId) {
|
public BulkEntryDto setValue(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) {
|
||||||
return bulkMapper.toDto(bulkEntryWriter.set(id, entry -> entry.setProperty(propertyReader.getById(propertyId))));
|
return bulkMapper.toDto(bulkEntryWriter.set(id, entry -> entry.setProperty(propertyId == null ? null : propertyReader.getById(propertyId))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("{id}/set/value")
|
@PutMapping("{id}/set/value")
|
||||||
|
|||||||
@ -56,7 +56,9 @@ public class BulkEntryWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void remove(final long id) {
|
public void remove(final long id) {
|
||||||
getEntryById(id);
|
final Bulk bulk = bulkReader.getBulkByEntryId(id);
|
||||||
|
final BulkEntry entry = getEntryById(bulk, id);
|
||||||
|
bulk.getEntries().remove(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BulkEntry getEntryById(final long id) {
|
private BulkEntry getEntryById(final long id) {
|
||||||
|
|||||||
@ -34,7 +34,7 @@ public class ChannelController implements ISearchController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SearchResult toSearchResult(final ChannelDto dto) {
|
private SearchResult toSearchResult(final ChannelDto dto) {
|
||||||
return new SearchResult(dto.getId(), dto.getTitle());
|
return new SearchResult(Channel.class, dto.getId(), dto.getTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,7 +87,7 @@ public class PropertyController implements ISearchController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SearchResult toSearchResult(final PropertyDto propertyDto) {
|
private SearchResult toSearchResult(final PropertyDto propertyDto) {
|
||||||
return new SearchResult(propertyDto.getId(), propertyDto.getTitle());
|
return new SearchResult(Property.class, propertyDto.getId(), propertyDto.getTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
package de.ph87.homeautomation.property;
|
package de.ph87.homeautomation.property;
|
||||||
|
|
||||||
import de.ph87.homeautomation.channel.ChannelDto;
|
import de.ph87.homeautomation.channel.ChannelDto;
|
||||||
|
import de.ph87.homeautomation.shared.SearchResult;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public final class PropertyDto implements Serializable {
|
public final class PropertyDto implements Serializable {
|
||||||
@ -23,7 +25,9 @@ public final class PropertyDto implements Serializable {
|
|||||||
|
|
||||||
private final ChannelDto writeChannel;
|
private final ChannelDto writeChannel;
|
||||||
|
|
||||||
public PropertyDto(final Property property, final ChannelDto readChannel, final ChannelDto writeChannel) {
|
private final List<SearchResult> usages;
|
||||||
|
|
||||||
|
public PropertyDto(final Property property, final ChannelDto readChannel, final ChannelDto writeChannel, final List<SearchResult> usages) {
|
||||||
this.id = property.getId();
|
this.id = property.getId();
|
||||||
this.type = property.getType();
|
this.type = property.getType();
|
||||||
this.title = property.getTitle();
|
this.title = property.getTitle();
|
||||||
@ -31,6 +35,7 @@ public final class PropertyDto implements Serializable {
|
|||||||
this.timestamp = property.getTimestamp();
|
this.timestamp = property.getTimestamp();
|
||||||
this.readChannel = readChannel;
|
this.readChannel = readChannel;
|
||||||
this.writeChannel = writeChannel;
|
this.writeChannel = writeChannel;
|
||||||
|
this.usages = usages;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,20 @@
|
|||||||
package de.ph87.homeautomation.property;
|
package de.ph87.homeautomation.property;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.bulk.Bulk;
|
||||||
|
import de.ph87.homeautomation.bulk.BulkRepository;
|
||||||
import de.ph87.homeautomation.channel.ChannelService;
|
import de.ph87.homeautomation.channel.ChannelService;
|
||||||
|
import de.ph87.homeautomation.schedule.Schedule;
|
||||||
|
import de.ph87.homeautomation.schedule.ScheduleRepository;
|
||||||
|
import de.ph87.homeautomation.shared.SearchResult;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@Transactional
|
@Transactional
|
||||||
@ -14,14 +23,27 @@ public class PropertyMapper {
|
|||||||
|
|
||||||
private final ChannelService channelService;
|
private final ChannelService channelService;
|
||||||
|
|
||||||
|
private final ScheduleRepository scheduleRepository;
|
||||||
|
|
||||||
|
private final BulkRepository bulkRepository;
|
||||||
|
|
||||||
public PropertyDto toDto(final Property property) {
|
public PropertyDto toDto(final Property property) {
|
||||||
|
final List<SearchResult> usages = findUsages(property);
|
||||||
return new PropertyDto(
|
return new PropertyDto(
|
||||||
property,
|
property,
|
||||||
channelService.toDtoAllowNull(property.getReadChannel()),
|
channelService.toDtoAllowNull(property.getReadChannel()),
|
||||||
channelService.toDtoAllowNull(property.getWriteChannel())
|
channelService.toDtoAllowNull(property.getWriteChannel()),
|
||||||
|
usages
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<SearchResult> findUsages(final Property property) {
|
||||||
|
final List<SearchResult> searchResults = new ArrayList<>();
|
||||||
|
searchResults.addAll(scheduleRepository.findDistinctByEntries_Property(property).stream().map(this::toSearchResult).collect(Collectors.toList()));
|
||||||
|
searchResults.addAll(bulkRepository.findDistinctByEntries_Property(property).stream().map(this::toSearchResult).collect(Collectors.toList()));
|
||||||
|
return searchResults;
|
||||||
|
}
|
||||||
|
|
||||||
public PropertyDto toDtoOrNull(final Property property) {
|
public PropertyDto toDtoOrNull(final Property property) {
|
||||||
if (property == null) {
|
if (property == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -29,4 +51,12 @@ public class PropertyMapper {
|
|||||||
return toDto(property);
|
return toDto(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SearchResult toSearchResult(final Schedule schedule) {
|
||||||
|
return new SearchResult(Schedule.class, schedule.getId(), schedule.getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchResult toSearchResult(final Bulk bulk) {
|
||||||
|
return new SearchResult(Bulk.class, bulk.getId(), bulk.getName());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ public class Schedule {
|
|||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@ToString.Exclude
|
@ToString.Exclude
|
||||||
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
|
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "schedule")
|
||||||
private Set<ScheduleEntry> entries = new HashSet<>();
|
private Set<ScheduleEntry> entries = new HashSet<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,14 +29,14 @@ public class ScheduleCalculationService {
|
|||||||
|
|
||||||
private final Config config;
|
private final Config config;
|
||||||
|
|
||||||
private final ScheduleReadService scheduleReadService;
|
private final ScheduleReader scheduleReader;
|
||||||
|
|
||||||
private final ApplicationEventPublisher applicationEventPublisher;
|
private final ApplicationEventPublisher applicationEventPublisher;
|
||||||
|
|
||||||
@EventListener(ApplicationStartedEvent.class)
|
@EventListener(ApplicationStartedEvent.class)
|
||||||
public void calculateAllNext() {
|
public void calculateAllNext() {
|
||||||
final ZonedDateTime now = ZonedDateTime.now();
|
final ZonedDateTime now = ZonedDateTime.now();
|
||||||
scheduleReadService.findAll().forEach(schedule -> calculateSchedule(schedule, now));
|
scheduleReader.findAll().forEach(schedule -> calculateSchedule(schedule, now));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void calculateSchedule(final Schedule schedule, final ZonedDateTime now) {
|
public void calculateSchedule(final Schedule schedule, final ZonedDateTime now) {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ScheduleController {
|
public class ScheduleController {
|
||||||
|
|
||||||
private final ScheduleReadService scheduleReadService;
|
private final ScheduleReader scheduleReader;
|
||||||
|
|
||||||
private final ScheduleWriteService scheduleWriteService;
|
private final ScheduleWriteService scheduleWriteService;
|
||||||
|
|
||||||
@ -19,12 +19,12 @@ public class ScheduleController {
|
|||||||
|
|
||||||
@GetMapping("findAll")
|
@GetMapping("findAll")
|
||||||
public List<ScheduleDto> findAll() {
|
public List<ScheduleDto> findAll() {
|
||||||
return scheduleReadService.findAllDtos();
|
return scheduleReader.findAllDtos();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("searchById/{id}")
|
@GetMapping("searchById/{id}")
|
||||||
public ScheduleDto getById(@PathVariable final long id) {
|
public ScheduleDto getById(@PathVariable final long id) {
|
||||||
return scheduleReadService.getDtoById(id);
|
return scheduleReader.getDtoById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("create")
|
@GetMapping("create")
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import java.util.Comparator;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ScheduleExecutionService {
|
public class ScheduleExecutionService {
|
||||||
|
|
||||||
private final ScheduleReadService scheduleReadService;
|
private final ScheduleReader scheduleReader;
|
||||||
|
|
||||||
private final ScheduleCalculationService scheduleCalculationService;
|
private final ScheduleCalculationService scheduleCalculationService;
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ public class ScheduleExecutionService {
|
|||||||
|
|
||||||
public void executeAllLastDue() {
|
public void executeAllLastDue() {
|
||||||
final ZonedDateTime now = ZonedDateTime.now();
|
final ZonedDateTime now = ZonedDateTime.now();
|
||||||
scheduleReadService.findAll().forEach(schedule -> executeLastDue(schedule, now));
|
scheduleReader.findAll().forEach(schedule -> executeLastDue(schedule, now));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeLastDue(final Schedule schedule, final ZonedDateTime now) {
|
private void executeLastDue(final Schedule schedule, final ZonedDateTime now) {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.homeautomation.schedule;
|
package de.ph87.homeautomation.schedule;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.property.Property;
|
||||||
import de.ph87.homeautomation.schedule.entry.ScheduleEntry;
|
import de.ph87.homeautomation.schedule.entry.ScheduleEntry;
|
||||||
import de.ph87.homeautomation.web.NotFoundException;
|
import de.ph87.homeautomation.web.NotFoundException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -14,7 +15,7 @@ import java.util.stream.Collectors;
|
|||||||
@Service
|
@Service
|
||||||
@Transactional
|
@Transactional
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ScheduleReadService {
|
public class ScheduleReader {
|
||||||
|
|
||||||
private final ScheduleRepository scheduleRepository;
|
private final ScheduleRepository scheduleRepository;
|
||||||
|
|
||||||
@ -40,4 +41,8 @@ public class ScheduleReadService {
|
|||||||
return scheduleMapper.toDto(getById(id));
|
return scheduleMapper.toDto(getById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Schedule> findAllByProperty(final Property property) {
|
||||||
|
return scheduleRepository.findDistinctByEntries_Property(property);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.homeautomation.schedule;
|
package de.ph87.homeautomation.schedule;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.property.Property;
|
||||||
import de.ph87.homeautomation.schedule.entry.ScheduleEntry;
|
import de.ph87.homeautomation.schedule.entry.ScheduleEntry;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
@ -13,4 +14,6 @@ public interface ScheduleRepository extends CrudRepository<Schedule, Long> {
|
|||||||
|
|
||||||
boolean existsByTitle(String title);
|
boolean existsByTitle(String title);
|
||||||
|
|
||||||
|
List<Schedule> findDistinctByEntries_Property(Property property);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package de.ph87.homeautomation.schedule;
|
package de.ph87.homeautomation.schedule;
|
||||||
|
|
||||||
import de.ph87.homeautomation.schedule.entry.ScheduleEntryReadService;
|
import de.ph87.homeautomation.schedule.entry.ScheduleEntryReader;
|
||||||
import de.ph87.homeautomation.shared.AbstractThreadService;
|
import de.ph87.homeautomation.shared.AbstractThreadService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -17,7 +17,7 @@ public class ScheduleThreadService extends AbstractThreadService {
|
|||||||
|
|
||||||
private final ScheduleExecutionService scheduleExecutionService;
|
private final ScheduleExecutionService scheduleExecutionService;
|
||||||
|
|
||||||
private final ScheduleEntryReadService scheduleEntryReadService;
|
private final ScheduleEntryReader scheduleEntryReader;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getThreadName() {
|
protected String getThreadName() {
|
||||||
@ -32,7 +32,7 @@ public class ScheduleThreadService extends AbstractThreadService {
|
|||||||
@Override
|
@Override
|
||||||
protected long doStep() throws InterruptedException {
|
protected long doStep() throws InterruptedException {
|
||||||
scheduleExecutionService.executeAllLastDue();
|
scheduleExecutionService.executeAllLastDue();
|
||||||
return scheduleEntryReadService.getNextTimestamp().map(nextTimestamp -> Duration.between(ZonedDateTime.now(), nextTimestamp).toMillis()).orElse(0L);
|
return scheduleEntryReader.getNextTimestamp().map(nextTimestamp -> Duration.between(ZonedDateTime.now(), nextTimestamp).toMillis()).orElse(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -17,7 +17,7 @@ public class ScheduleWriteService {
|
|||||||
|
|
||||||
public static final String NAME_PREFIX = "Neu ";
|
public static final String NAME_PREFIX = "Neu ";
|
||||||
|
|
||||||
private final ScheduleReadService scheduleReadService;
|
private final ScheduleReader scheduleReader;
|
||||||
|
|
||||||
private final ScheduleCalculationService scheduleCalculationService;
|
private final ScheduleCalculationService scheduleCalculationService;
|
||||||
|
|
||||||
@ -43,14 +43,14 @@ public class ScheduleWriteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T> ScheduleDto set(final long id, final BiConsumer<Schedule, T> setter, final T value) {
|
public <T> ScheduleDto set(final long id, final BiConsumer<Schedule, T> setter, final T value) {
|
||||||
final Schedule schedule = scheduleReadService.getById(id);
|
final Schedule schedule = scheduleReader.getById(id);
|
||||||
setter.accept(schedule, value);
|
setter.accept(schedule, value);
|
||||||
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
||||||
return publish(schedule, true);
|
return publish(schedule, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(final long id) {
|
public void delete(final long id) {
|
||||||
final Schedule schedule = scheduleReadService.getById(id);
|
final Schedule schedule = scheduleReader.getById(id);
|
||||||
scheduleRepository.delete(schedule);
|
scheduleRepository.delete(schedule);
|
||||||
publish(schedule, false);
|
publish(schedule, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,10 @@ package de.ph87.homeautomation.schedule.entry;
|
|||||||
import com.luckycatlabs.sunrisesunset.Zenith;
|
import com.luckycatlabs.sunrisesunset.Zenith;
|
||||||
import de.ph87.homeautomation.bulk.Bulk;
|
import de.ph87.homeautomation.bulk.Bulk;
|
||||||
import de.ph87.homeautomation.property.Property;
|
import de.ph87.homeautomation.property.Property;
|
||||||
|
import de.ph87.homeautomation.schedule.Schedule;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
@ -14,6 +16,7 @@ import java.util.Random;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Entity
|
@Entity
|
||||||
|
@NoArgsConstructor
|
||||||
public class ScheduleEntry {
|
public class ScheduleEntry {
|
||||||
|
|
||||||
private static final Random RANDOM = new Random(System.currentTimeMillis());
|
private static final Random RANDOM = new Random(System.currentTimeMillis());
|
||||||
@ -23,6 +26,9 @@ public class ScheduleEntry {
|
|||||||
@Setter(AccessLevel.NONE)
|
@Setter(AccessLevel.NONE)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Schedule schedule;
|
||||||
|
|
||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
|
|
||||||
private boolean monday = true;
|
private boolean monday = true;
|
||||||
@ -71,6 +77,10 @@ public class ScheduleEntry {
|
|||||||
@Setter(AccessLevel.NONE)
|
@Setter(AccessLevel.NONE)
|
||||||
private ZonedDateTime nextFuzzyTimestamp;
|
private ZonedDateTime nextFuzzyTimestamp;
|
||||||
|
|
||||||
|
public ScheduleEntry(final Schedule schedule) {
|
||||||
|
this.schedule = schedule;
|
||||||
|
}
|
||||||
|
|
||||||
public void setNextClearTimestamp(final ZonedDateTime next) {
|
public void setNextClearTimestamp(final ZonedDateTime next) {
|
||||||
nextClearTimestamp = next;
|
nextClearTimestamp = next;
|
||||||
if (nextClearTimestamp == null) {
|
if (nextClearTimestamp == null) {
|
||||||
@ -82,24 +92,6 @@ public class ScheduleEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWorkday(final boolean enabled) {
|
|
||||||
monday = enabled;
|
|
||||||
tuesday = enabled;
|
|
||||||
wednesday = enabled;
|
|
||||||
thursday = enabled;
|
|
||||||
friday = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWeekend(final boolean enabled) {
|
|
||||||
saturday = enabled;
|
|
||||||
sunday = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEveryday(final boolean enabled) {
|
|
||||||
setWorkday(enabled);
|
|
||||||
setWeekend(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
@ -111,13 +103,13 @@ public class ScheduleEntry {
|
|||||||
builder.append(", type=");
|
builder.append(", type=");
|
||||||
builder.append(type);
|
builder.append(type);
|
||||||
builder.append(", weekdays=");
|
builder.append(", weekdays=");
|
||||||
builder.append(monday ? 1 : 0);
|
builder.append(monday ? "Mon" : "___");
|
||||||
builder.append(tuesday ? 1 : 0);
|
builder.append(tuesday ? "Tue" : "___");
|
||||||
builder.append(wednesday ? 1 : 0);
|
builder.append(wednesday ? "Wed" : "___");
|
||||||
builder.append(thursday ? 1 : 0);
|
builder.append(thursday ? "Thu" : "___");
|
||||||
builder.append(friday ? 1 : 0);
|
builder.append(friday ? "Fri" : "___");
|
||||||
builder.append(saturday ? 1 : 0);
|
builder.append(saturday ? "Sat" : "___");
|
||||||
builder.append(sunday ? 1 : 0);
|
builder.append(sunday ? "Sun" : "___");
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TIME:
|
case TIME:
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import java.util.Optional;
|
|||||||
@Service
|
@Service
|
||||||
@Transactional
|
@Transactional
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ScheduleEntryReadService {
|
public class ScheduleEntryReader {
|
||||||
|
|
||||||
private final ScheduleEntryRepository scheduleEntryRepository;
|
private final ScheduleEntryRepository scheduleEntryRepository;
|
||||||
|
|
||||||
@ -2,7 +2,7 @@ package de.ph87.homeautomation.schedule.entry;
|
|||||||
|
|
||||||
import de.ph87.homeautomation.schedule.Schedule;
|
import de.ph87.homeautomation.schedule.Schedule;
|
||||||
import de.ph87.homeautomation.schedule.ScheduleCalculationService;
|
import de.ph87.homeautomation.schedule.ScheduleCalculationService;
|
||||||
import de.ph87.homeautomation.schedule.ScheduleReadService;
|
import de.ph87.homeautomation.schedule.ScheduleReader;
|
||||||
import de.ph87.homeautomation.web.WebSocketService;
|
import de.ph87.homeautomation.web.WebSocketService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -19,9 +19,9 @@ import java.util.function.Consumer;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ScheduleEntryWriteService {
|
public class ScheduleEntryWriteService {
|
||||||
|
|
||||||
private final ScheduleEntryReadService scheduleEntryReadService;
|
private final ScheduleEntryReader scheduleEntryReader;
|
||||||
|
|
||||||
private final ScheduleReadService scheduleReadService;
|
private final ScheduleReader scheduleReader;
|
||||||
|
|
||||||
private final ScheduleCalculationService scheduleCalculationService;
|
private final ScheduleCalculationService scheduleCalculationService;
|
||||||
|
|
||||||
@ -33,31 +33,31 @@ public class ScheduleEntryWriteService {
|
|||||||
|
|
||||||
@Deprecated(since = "Use alternative 'set' instead.", forRemoval = true)
|
@Deprecated(since = "Use alternative 'set' instead.", forRemoval = true)
|
||||||
public <T> ScheduleEntryDto set(final long id, final BiConsumer<ScheduleEntry, T> setter, final T value) {
|
public <T> ScheduleEntryDto set(final long id, final BiConsumer<ScheduleEntry, T> setter, final T value) {
|
||||||
final ScheduleEntry entry = scheduleEntryReadService.getById(id);
|
final ScheduleEntry entry = scheduleEntryReader.getById(id);
|
||||||
setter.accept(entry, value);
|
setter.accept(entry, value);
|
||||||
final Schedule schedule = scheduleReadService.getByEntry(entry);
|
final Schedule schedule = scheduleReader.getByEntry(entry);
|
||||||
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
||||||
return publish(entry, true);
|
return publish(entry, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduleEntryDto set(final long id, final Consumer<ScheduleEntry> setter) {
|
public ScheduleEntryDto set(final long id, final Consumer<ScheduleEntry> setter) {
|
||||||
final ScheduleEntry entry = scheduleEntryReadService.getById(id);
|
final ScheduleEntry entry = scheduleEntryReader.getById(id);
|
||||||
setter.accept(entry);
|
setter.accept(entry);
|
||||||
final Schedule schedule = scheduleReadService.getByEntry(entry);
|
final Schedule schedule = scheduleReader.getByEntry(entry);
|
||||||
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
||||||
return publish(entry, true);
|
return publish(entry, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduleEntryDto create(final long scheduleId) {
|
public ScheduleEntryDto create(final long scheduleId) {
|
||||||
final Schedule schedule = scheduleReadService.getById(scheduleId);
|
final Schedule schedule = scheduleReader.getById(scheduleId);
|
||||||
final ScheduleEntry entry = new ScheduleEntry();
|
final ScheduleEntry entry = scheduleEntryRepository.save(new ScheduleEntry(schedule));
|
||||||
schedule.getEntries().add(scheduleEntryRepository.save(entry));
|
schedule.getEntries().add(entry);
|
||||||
return publish(entry, true);
|
return publish(entry, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(final long id) {
|
public void delete(final long id) {
|
||||||
final ScheduleEntry entry = scheduleEntryReadService.getById(id);
|
final ScheduleEntry entry = scheduleEntryReader.getById(id);
|
||||||
scheduleReadService.getByEntry(entry).getEntries().remove(entry);
|
scheduleReader.getByEntry(entry).getEntries().remove(entry);
|
||||||
scheduleEntryRepository.delete(entry);
|
scheduleEntryRepository.delete(entry);
|
||||||
publish(entry, false);
|
publish(entry, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,11 +5,14 @@ import lombok.Getter;
|
|||||||
@Getter
|
@Getter
|
||||||
public class SearchResult {
|
public class SearchResult {
|
||||||
|
|
||||||
public final long id;
|
private final String type;
|
||||||
|
|
||||||
public final String title;
|
private final long id;
|
||||||
|
|
||||||
public SearchResult(final long id, final String title) {
|
private final String title;
|
||||||
|
|
||||||
|
public SearchResult(final Class<?> clazz, final long id, final String title) {
|
||||||
|
this.type = clazz.getSimpleName();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user