Przeglądaj źródła

sales refactored

master
Daniel 1 rok temu
rodzic
commit
decf693623
25 zmienionych plików z 553 dodań i 529 usunięć
  1. +1
    -1
      matsen-tool/openapi.json
  2. +6
    -0
      matsen-tool/openapi.yaml
  3. +6
    -6
      matsen-tool/src/app/_forms/apiForms.ts
  4. +92
    -0
      matsen-tool/src/app/_views/documents/document-list/document-list.component.html
  5. +0
    -0
      matsen-tool/src/app/_views/documents/document-list/document-list.component.scss
  6. +23
    -0
      matsen-tool/src/app/_views/documents/document-list/document-list.component.spec.ts
  7. +88
    -0
      matsen-tool/src/app/_views/documents/document-list/document-list.component.ts
  8. +3
    -92
      matsen-tool/src/app/_views/documents/documents.component.html
  9. +3
    -110
      matsen-tool/src/app/_views/documents/documents.component.ts
  10. +5
    -42
      matsen-tool/src/app/_views/sales/new-sale/new-sale.component.html
  11. +91
    -0
      matsen-tool/src/app/_views/sales/sale-list/sale-list.component.html
  12. +0
    -0
      matsen-tool/src/app/_views/sales/sale-list/sale-list.component.scss
  13. +23
    -0
      matsen-tool/src/app/_views/sales/sale-list/sale-list.component.spec.ts
  14. +92
    -0
      matsen-tool/src/app/_views/sales/sale-list/sale-list.component.ts
  15. +19
    -0
      matsen-tool/src/app/_views/sales/sale-summary/sale-summary.component.html
  16. +0
    -0
      matsen-tool/src/app/_views/sales/sale-summary/sale-summary.component.scss
  17. +23
    -0
      matsen-tool/src/app/_views/sales/sale-summary/sale-summary.component.spec.ts
  18. +55
    -0
      matsen-tool/src/app/_views/sales/sale-summary/sale-summary.component.ts
  19. +3
    -117
      matsen-tool/src/app/_views/sales/sales.component.html
  20. +7
    -155
      matsen-tool/src/app/_views/sales/sales.component.ts
  21. +6
    -0
      matsen-tool/src/app/app.module.ts
  22. +2
    -2
      matsen-tool/src/app/core/api/v1/model/sale.ts
  23. +2
    -2
      matsen-tool/src/app/core/api/v1/model/saleJsonhal.ts
  24. +2
    -2
      matsen-tool/src/app/core/api/v1/model/saleJsonld.ts
  25. +1
    -0
      matsen-tool/src/assets/i18n/de.json

+ 1
- 1
matsen-tool/openapi.json
Plik diff jest za duży
Wyświetl plik


+ 6
- 0
matsen-tool/openapi.yaml Wyświetl plik

@@ -6074,6 +6074,8 @@ components:
items:
type: string
required:
- partner
- product
- turnover
- profit
- quantity
@@ -6161,6 +6163,8 @@ components:
items:
type: string
required:
- partner
- product
- turnover
- profit
- quantity
@@ -6262,6 +6266,8 @@ components:
items:
type: string
required:
- partner
- product
- turnover
- profit
- quantity


+ 6
- 6
matsen-tool/src/app/_forms/apiForms.ts Wyświetl plik

@@ -392,10 +392,10 @@ export const productJsonldForm = new FormGroup({
export const saleForm = new FormGroup({
owner: new FormControl(null, []),
ownerName: new FormControl(null, []),
partner: new FormControl(null, []),
partner: new FormControl(null, [Validators.required]),
partnerType: new FormControl(null, []),
partnerName: new FormControl(null, []),
product: new FormControl(null, []),
product: new FormControl(null, [Validators.required]),
productName: new FormControl(null, []),
turnover: new FormControl(null, [Validators.required]),
profit: new FormControl(null, [Validators.required]),
@@ -409,10 +409,10 @@ export const saleJsonhalForm = new FormGroup({
_links: new FormControl(null, []),
owner: new FormControl(null, []),
ownerName: new FormControl(null, []),
partner: new FormControl(null, []),
partner: new FormControl(null, [Validators.required]),
partnerType: new FormControl(null, []),
partnerName: new FormControl(null, []),
product: new FormControl(null, []),
product: new FormControl(null, [Validators.required]),
productName: new FormControl(null, []),
turnover: new FormControl(null, [Validators.required]),
profit: new FormControl(null, [Validators.required]),
@@ -425,10 +425,10 @@ export const saleJsonhalForm = new FormGroup({
export const saleJsonldForm = new FormGroup({
owner: new FormControl(null, []),
ownerName: new FormControl(null, []),
partner: new FormControl(null, []),
partner: new FormControl(null, [Validators.required]),
partnerType: new FormControl(null, []),
partnerName: new FormControl(null, []),
product: new FormControl(null, []),
product: new FormControl(null, [Validators.required]),
productName: new FormControl(null, []),
turnover: new FormControl(null, [Validators.required]),
profit: new FormControl(null, [Validators.required]),


+ 92
- 0
matsen-tool/src/app/_views/documents/document-list/document-list.component.html Wyświetl plik

@@ -0,0 +1,92 @@
<div class="spt-container">
<button class="btn btn-primary" (click)="openModalNewDocument()">{{ 'basic.new-document' | translate }}</button>
<app-paging #pagingComponent
[getDataFunction]="getData"
[dataSource]="dataSource"
>
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="onSortChange($event)"
class="mat-elevation-z8 mb-3">

<ng-container matColumnDef="pos">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.number' | translate }}
</th>
<td mat-cell
*matCellDef="let element">{{ pagingComponent.getPageSize() * (pagingComponent.getPageIndex()-1) + dataSource.filteredData.indexOf(element) + 1 }}
</td>
</ng-container>

<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.document' | translate }}">
{{ 'overview.document' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.name }}
</td>
</ng-container>

<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.description' | translate }}
</th>
<td mat-cell *matCellDef="let element"
title="{{element.description}}">{{ element.description?.length > 70 ? element.description?.slice(0, 70) + '...' : element.description }}
</td>
</ng-container>

<ng-container matColumnDef="partnerName">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.partner' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.partnerName }}
</td>
</ng-container>

<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.product' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.productName }}
</td>
</ng-container>

<ng-container matColumnDef="createdAt">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.uploaded' | translate }}">
{{ 'overview.uploaded' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.createdAt | date:'dd.MM.YYYY HH:mm' }}
</td>
</ng-container>

<ng-container matColumnDef="createdByName">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.createdBy' | translate }}">
{{ 'overview.createdBy' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.createdByName }}
</td>
</ng-container>

<ng-container matColumnDef="download">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<span class="btn btn-primary bi bi-download p-2-4"
data-type="user-tool" data-action="edit" (click)="navigateToDocumentFile(element)"></span>
</td>
</ng-container>

<ng-container matColumnDef="edit">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<span class="btn btn-primary bi bi-pencil p-2-4"
data-type="user-tool" data-action="edit" (click)="openModalEditDocument(element)"></span>
</td>
</ng-container>

<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</app-paging>
</div>


+ 0
- 0
matsen-tool/src/app/_views/documents/document-list/document-list.component.scss Wyświetl plik


+ 23
- 0
matsen-tool/src/app/_views/documents/document-list/document-list.component.spec.ts Wyświetl plik

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { DocumentListComponent } from './document-list.component';

describe('DocumentListComponent', () => {
let component: DocumentListComponent;
let fixture: ComponentFixture<DocumentListComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [DocumentListComponent]
})
.compileComponents();
fixture = TestBed.createComponent(DocumentListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 88
- 0
matsen-tool/src/app/_views/documents/document-list/document-list.component.ts Wyświetl plik

@@ -0,0 +1,88 @@
import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
import {DocumentJsonld, DocumentService} from "@app/core/api/v1";
import {AppHelperService} from "@app/_helpers/app-helper.service";
import {MatSort, Sort} from "@angular/material/sort";
import {Subscription} from "rxjs";
import {MatTableDataSource} from "@angular/material/table";
import {PagingComponent} from "@app/_components/paging/paging.component";
import {OrderFilter} from "@app/_models/orderFilter";
import {NewDocumentComponent} from "@app/_views/documents/new-document/new-document.component";

@Component({
selector: 'app-document-list',
templateUrl: './document-list.component.html',
styleUrl: './document-list.component.scss'
})
export class DocumentListComponent implements OnInit, AfterViewInit {

@ViewChild(MatSort) sort;
@ViewChild("pagingComponent", { static: false }) pagingComponent!: PagingComponent;

protected displayedColumns: string[];

protected documentsSub: Subscription;
protected documents: Array<DocumentJsonld>;
protected dataSource;

constructor(
private documentService: DocumentService,
protected appHelperService: AppHelperService
) {
this.sort = new MatSort();
this.displayedColumns = ['pos', 'name', 'description', 'partnerName', 'productName', 'createdAt', 'createdByName', 'download', 'edit'];

this.documentsSub = new Subscription();
this.documents = [];
this.dataSource = new MatTableDataSource<DocumentJsonld>(this.documents);

}

ngOnInit(){
}

ngAfterViewInit() {
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.pagingComponent.paginator;
this.pagingComponent.getData();
}

getData = () => {
this.documentsSub = this.documentService.documentsGetCollection(
this.pagingComponent.getPageIndex(),
this.pagingComponent.getPageSize()
).subscribe(
data => {
this.documents = data["hydra:member"];
this.dataSource = new MatTableDataSource<DocumentJsonld>(this.documents);
this.pagingComponent.dataLength = Number(data["hydra:totalItems"]);
}
);
}

onSortChange(sortState: Sort) {
// Reset page index to first page
this.pagingComponent.resetPageIndex();

let order: OrderFilter;
if (sortState.direction === "") {
order = OrderFilter.Undefined;
} else {
order = sortState.direction;
}
this.getData();
}

navigateToDocumentFile(element: DocumentJsonld) {
window.open(element.documentUrl?.toString(), '_blank');
}

openModalNewDocument() {
let document: DocumentJsonld = {} as DocumentJsonld;
this.appHelperService.openModal(NewDocumentComponent, { 'document': document }, this.getData);
}

openModalEditDocument(document: DocumentJsonld) {
this.appHelperService.openModal(NewDocumentComponent, { 'document': document }, this.getData);
}

}

+ 3
- 92
matsen-tool/src/app/_views/documents/documents.component.html Wyświetl plik

@@ -1,97 +1,8 @@
<div class="spt-container">
<div class="d-flex justify-content-between align-items-start">
<h2>{{ 'basic.documents' | translate }}</h2>
<button class="btn btn-primary" (click)="openModalNewDocument()">{{ 'basic.new-document' | translate }}</button>
</div>
<table mat-table [dataSource]="documentsDataSource" matSort (matSortChange)="onSortChange($event)"
class="mat-elevation-z8 mb-3">
<app-document-list #documentList

<ng-container matColumnDef="pos">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.number' | translate }}
</th>
<td mat-cell
*matCellDef="let element">{{ (documentsPageSize * documentsPageIndex) + documentsDataSource.filteredData.indexOf(element) + 1 }}
</td>
</ng-container>

<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.document' | translate }}">
{{ 'overview.document' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.name }}
</td>
</ng-container>

<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.description' | translate }}
</th>
<td mat-cell *matCellDef="let element"
title="{{element.description}}">{{ element.description?.length > 70 ? element.description?.slice(0, 70) + '...' : element.description }}
</td>
</ng-container>

<ng-container matColumnDef="partnerName">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.partner' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.partnerName }}
</td>
</ng-container>

<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.product' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.productName }}
</td>
</ng-container>

<ng-container matColumnDef="createdAt">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.uploaded' | translate }}">
{{ 'overview.uploaded' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.createdAt | date:'dd.MM.YYYY HH:mm' }}
</td>
</ng-container>

<ng-container matColumnDef="createdByName">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.createdBy' | translate }}">
{{ 'overview.createdBy' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{ element.createdByName }}
</td>
</ng-container>

<ng-container matColumnDef="download">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<span class="btn btn-primary bi bi-download p-2-4"
data-type="user-tool" data-action="edit" (click)="navigateToDocumentFile(element)"></span>
</td>
</ng-container>

<ng-container matColumnDef="edit">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<span class="btn btn-primary bi bi-pencil p-2-4"
data-type="user-tool" data-action="edit" (click)="openModalEditDocument(element)"></span>
</td>
</ng-container>

<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator class="rounded-1"
[pageSizeOptions]="[10,25,50]"
[length]="documentsLength"
(page)="handlePageEvent($event)"
[pageSize]="documentsPageSize"
[pageIndex]="documentsPageIndex"
showFirstLastButtons>
</mat-paginator>
</div>
></app-document-list>
</div>

+ 3
- 110
matsen-tool/src/app/_views/documents/documents.component.ts Wyświetl plik

@@ -12,6 +12,8 @@ import {NewDocumentComponent} from "@app/_views/documents/new-document/new-docum
import {TranslateModule} from "@ngx-translate/core";
import {ModalStatus} from "@app/_helpers/modal.states";
import {AppHelperService} from "@app/_helpers/app-helper.service";
import {ProductListComponent} from "@app/_views/products/product-list/product-list.component";
import {DocumentListComponent} from "@app/_views/documents/document-list/document-list.component";

@Component({
selector: 'app-documents',
@@ -19,126 +21,17 @@ import {AppHelperService} from "@app/_helpers/app-helper.service";
styleUrl: './documents.component.scss',
})
export class DocumentsComponent {
@ViewChild(MatSort) sort;
@ViewChild(MatPaginator) documentsPaginator: MatPaginator;

protected displayedColumns: string[];

protected documentsSub: Subscription;
protected documents: Array<DocumentJsonld>;
protected documentsDataSource;
protected documentsLength: number;
protected documentsPageEvent: PageEvent;
protected documentsPageSize: number;
protected documentsPageIndex: number;

protected modalOptions: NgbModalOptions = {
centered: true
};
@ViewChild("documentList", { static: false }) documentList!: DocumentListComponent;

constructor(
private router: Router,
private modalService: NgbModal,
private documentService: DocumentService,
protected appHelperService: AppHelperService
) {
this.sort = new MatSort();
this.displayedColumns = ['pos', 'name', 'description', 'partnerName', 'productName', 'createdAt', 'createdByName', 'download', 'edit'];

this.documentsSub = new Subscription();
this.documents = [];
this.documentsPaginator = new MatPaginator(new MatPaginatorIntl(), ChangeDetectorRef.prototype);
this.documentsDataSource = new MatTableDataSource<DocumentJsonld>(this.documents);
this.documentsLength = 0;
this.documentsPageEvent = new PageEvent();
this.documentsPageSize = 10;
this.documentsPageIndex = 0;
}

ngOnInit() {
this.getDocumentsData();
}

ngAfterViewInit() {
this.documentsDataSource.sort = this.sort;
this.documentsDataSource.paginator = this.documentsPaginator;
}

getDocumentsData() {
this.documentsSub = this.documentService.documentsGetCollection(
this.documentsPageIndex + 1,
this.documentsPageSize
).subscribe(
data => {
this.documents = data["hydra:member"];
this.documentsDataSource = new MatTableDataSource<DocumentJsonld>(this.documents);
this.documentsLength = Number(data["hydra:totalItems"]);
this.documentsPaginator.length = this.documentsLength;
}
);
}

/** Announce the change in sort state for assistive technology. */
onSortChange(sortState: Sort) {
// Reset page index to first page
this.documentsPageIndex = 0;

let order: OrderFilter;
if (sortState.direction === "") {
order = OrderFilter.Undefined;
} else {
order = sortState.direction;
}

// this.nameOrderAsc = OrderFilter.Undefined;
// this.cityOrderAsc = OrderFilter.Undefined;
// this.websiteOrderAsc = OrderFilter.Undefined;
// switch (sortState.active) {
// case "name":
// this.nameOrderAsc = order;
// break;
// case "address":
// this.cityOrderAsc = order;
// break;
// case "website":
// this.websiteOrderAsc = order;
// break;
// }
this.getDocumentsData();
}

handlePageEvent(e: PageEvent) {
this.documentsPageEvent = e;
this.documentsLength = e.length;
this.documentsPageIndex = e.pageIndex.valueOf();
this.documentsPageSize = e.pageSize.valueOf();
this.getDocumentsData();
}

navigateToDocumentFile(element: DocumentJsonld) {
window.open(element.documentUrl?.toString(), '_blank');
}

openModalNewDocument() {
const modalRefDocument = this.modalService.open(NewDocumentComponent, this.appHelperService.getModalOptions());
let document: DocumentJsonld = {} as DocumentJsonld;
modalRefDocument.componentInstance.document = document;
modalRefDocument.componentInstance.submit.subscribe((modalStatus: ModalStatus) => {
if (modalStatus === ModalStatus.Submitted) {
modalRefDocument.dismiss();
this.getDocumentsData();
}
});
}

openModalEditDocument(document: DocumentJsonld) {
const modalRefDocument = this.modalService.open(NewDocumentComponent, this.appHelperService.getModalOptions());
modalRefDocument.componentInstance.document = document;
modalRefDocument.componentInstance.submit.subscribe((modalStatus: ModalStatus) => {
if (modalStatus === ModalStatus.Submitted) {
modalRefDocument.dismiss();
this.getDocumentsData();
}
});
}
}

+ 5
- 42
matsen-tool/src/app/_views/sales/new-sale/new-sale.component.html Wyświetl plik

@@ -31,53 +31,16 @@
<input type="number" class="form-control" id="profit" formControlName="profit" min="0" step="1" />
</div>

<div class="mb-3">
<label for="quantity" class="form-label">{{ 'form.quantity' | translate }}:</label>
<input type="number" class="form-control" id="quantity" formControlName="quantity" min="0" step="1" />
</div>

<div class="mb-3">
<label for="comment" class="form-label">{{ 'form.comment' | translate }}:</label>
<textarea class="form-control" id="comment" formControlName="comment" cols="50" rows="5"></textarea>
</div>

<!-- <div class="mb-3">-->
<!-- <label for="street" class="form-label">{{ 'form.street' | translate }}:</label>-->
<!-- <input type="text" class="form-control" id="street" formControlName="street"/>-->
<!-- </div>-->

<!-- <div class="mb-3">-->
<!-- <label for="streetNo" class="form-label">{{ 'form.street-no' | translate }}:</label>-->
<!-- <input type="text" class="form-control" id="streetNo" formControlName="streetNo"/>-->
<!-- </div>-->

<!-- <div class="mb-3">-->
<!-- <label for="zip" class="form-label">{{ 'form.zip' | translate }}:</label>-->
<!-- <input type="text" class="form-control" id="zip" formControlName="zip"/>-->
<!-- </div>-->

<!-- <div class="mb-3">-->
<!-- <label for="city" class="form-label">{{ 'form.city' | translate }}:</label>-->
<!-- <input type="text" class="form-control" id="city" formControlName="city"/>-->
<!-- </div>-->

<!-- <div class="mb-3">-->
<!-- <label for="country" class="form-label">{{ 'form.country' | translate }}:</label>-->
<!-- <input type="text" class="form-control" id="country" formControlName="country"/>-->
<!-- </div>-->

<!-- <div class="mb-3">-->
<!-- <label for="website" class="form-label">{{ 'form.website' | translate }}:</label>-->
<!-- <input type="text" class="form-control" id="website" formControlName="website"/>-->
<!-- </div>-->

<!-- <div class="mb-3" *ngIf="partnerForm.get('logoUrl')?.value === null">-->
<!-- <label for="logo" class="form-label">{{ 'form.upload-image' | translate }}:</label>-->
<!-- <input type="file" class="form-control" id="logo" (change)="onFileSelected($event)" accept="image/*"/>-->
<!-- </div>-->

<!-- <div class="mb-3" *ngIf="partnerForm.get('logoUrl')?.value !== null">-->
<!-- <div class="delete-image" (click)="onDeleteImage()">-->
<!-- <img src="{{partner.logoUrl}}" width="40" height="40" />-->
<!-- <p class="mb-0 ms-3">{{ 'system.delete-image' | translate }}</p>-->
<!-- </div>-->
<!-- </div>-->

<button type="submit" class="btn btn-primary" [disabled]="saleForm.invalid">{{ 'form.send' | translate }}
</button>
</form>


+ 91
- 0
matsen-tool/src/app/_views/sales/sale-list/sale-list.component.html Wyświetl plik

@@ -0,0 +1,91 @@
<button class="btn btn-primary" (click)="openModalNewSale()">{{ 'basic.new-sale' | translate }}</button>
<app-paging #pagingComponent
[getDataFunction]="getData"
[dataSource]="dataSource"
>
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="onSortChange($event)"
class="mat-elevation-z8 mb-3">

<ng-container matColumnDef="pos">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.number' | translate }}
</th>
<td mat-cell
*matCellDef="let element">{{ pagingComponent.getPageSize() * (pagingComponent.getPageIndex()-1) + dataSource.filteredData.indexOf(element) + 1 }}
</td>
</ng-container>

<ng-container matColumnDef="user">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.sale-user' | translate }}">
{{ 'overview.sale-user' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.ownerName }}
</td>
</ng-container>

<ng-container matColumnDef="partner">
<th mat-header-cell *matHeaderCellDef mat-sort-header="address"
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.sale-partner' | translate }}">
{{ 'overview.sale-partner' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<a [routerLink]="['/customer', appHelperService.extractId(element.partner)]">{{ element.partnerName }}</a>
</td>
</ng-container>

<ng-container matColumnDef="product">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.productname' | translate }}">
{{ 'overview.productname' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<a [routerLink]="['/products', appHelperService.extractId(element.product)]">{{ element.productName }}</a>
</td>
</ng-container>

<ng-container matColumnDef="turnover">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.turnover' | translate }}">
{{ 'overview.turnover' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.turnover | currency: 'EUR' }}
</td>
</ng-container>

<ng-container matColumnDef="profit">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.profit' | translate }}">
{{ 'overview.profit' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.profit | currency: 'EUR' }}
</td>
</ng-container>

<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.createdAt' | translate }}">
{{ 'overview.createdAt' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.createdAt | date:'dd.MM.YYYY HH:mm' }}
</td>
</ng-container>

<ng-container matColumnDef="details">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.details' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<span class="btn btn-primary bi bi-zoom-in p-2-4"
data-type="user-tool" data-action="edit" (click)="navigateToSaleDetails(element)"></span>
</td>
</ng-container>

<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</app-paging>

+ 0
- 0
matsen-tool/src/app/_views/sales/sale-list/sale-list.component.scss Wyświetl plik


+ 23
- 0
matsen-tool/src/app/_views/sales/sale-list/sale-list.component.spec.ts Wyświetl plik

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { SaleListComponent } from './sale-list.component';

describe('SaleListComponent', () => {
let component: SaleListComponent;
let fixture: ComponentFixture<SaleListComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [SaleListComponent]
})
.compileComponents();
fixture = TestBed.createComponent(SaleListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 92
- 0
matsen-tool/src/app/_views/sales/sale-list/sale-list.component.ts Wyświetl plik

@@ -0,0 +1,92 @@
import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
import {Subscription} from "rxjs";
import {SaleJsonld, SaleService, SaleSummaryJsonld} from "@app/core/api/v1";
import {TranslateService} from "@ngx-translate/core";
import {Router} from "@angular/router";
import {AppHelperService} from "@app/_helpers/app-helper.service";
import {MatSort, Sort} from "@angular/material/sort";
import {MatTableDataSource} from "@angular/material/table";
import {PagingComponent} from "@app/_components/paging/paging.component";
import {NewSaleComponent} from "@app/_views/sales/new-sale/new-sale.component";
import {OrderFilter} from "@app/_models/orderFilter";
import {AccountService} from "@app/_services";

@Component({
selector: 'app-sale-list',
templateUrl: './sale-list.component.html',
styleUrl: './sale-list.component.scss'
})
export class SaleListComponent implements OnInit, AfterViewInit {

@ViewChild(MatSort) sort;
@ViewChild("pagingComponent", { static: false }) pagingComponent!: PagingComponent;

protected displayedColumns: string[];
protected salesSub: Subscription;
protected sales: Array<SaleJsonld>;
protected salesSummarySub: Subscription;
protected saleSummaries: Array<SaleSummaryJsonld>;

protected dataSource;

constructor(
private saleService: SaleService,
private router: Router,
protected appHelperService: AppHelperService,
protected accountService: AccountService,
) {
this.sort = new MatSort();
this.displayedColumns = ['pos', 'user', 'partner', 'product', 'turnover', 'profit', 'date', 'details'];
this.salesSub = new Subscription();
this.sales = [];
this.salesSummarySub = new Subscription();
this.saleSummaries = [];

this.dataSource = new MatTableDataSource<SaleJsonld>(this.sales);
}

ngOnInit() {
}

ngAfterViewInit(): void {
this.pagingComponent.getData();
}

getData = () => {
this.salesSub = this.saleService.salesGetCollection(
this.pagingComponent.getPageIndex(),
this.pagingComponent.getPageSize(),
).subscribe(
data => {
this.sales = data["hydra:member"];
this.dataSource = new MatTableDataSource<SaleJsonld>(this.sales);
this.pagingComponent.dataLength = Number(data["hydra:totalItems"]);
}
)
}

onSortChange(sortState: Sort) {
// Reset page index to first page
this.pagingComponent.resetPageIndex();

let order: OrderFilter;
if (sortState.direction === "") {
order = OrderFilter.Undefined;
} else {
order = sortState.direction;
}

this.pagingComponent.getData();
}

navigateToSaleDetails(element: any) {
const sale: SaleJsonld = element as SaleJsonld;
this.router.navigate(['/sales', this.appHelperService.extractId(sale.id)]);
}

openModalNewSale() {
let sale: SaleJsonld = {} as SaleJsonld;
this.appHelperService.openModal(NewSaleComponent, { 'sale': sale }, this.getData);
}

}

+ 19
- 0
matsen-tool/src/app/_views/sales/sale-summary/sale-summary.component.html Wyświetl plik

@@ -0,0 +1,19 @@
<div class="sales-summary-container mb-4" *ngFor="let saleSummary of saleSummaries">
<p><strong>{{ saleSummary.ownerName }}</strong></p>
<div class="sales-summary-bar">
<div>
<span class="sales-summary-turnover"
[ngStyle]="{ 'width.%': calculateWidthPercentage(Number(saleSummary.turnover), saleSummaryMaxTurnover)}">
{{ 'sales.turnover' | translate }}: <strong>{{ saleSummary.turnover | currency: 'EUR' }}</strong>
</span>
</div>
</div>
<div class="sales-summary-bar">
<div>
<span class="sales-summary-profit"
[ngStyle]="{ 'width.%': calculateWidthPercentage(Number(saleSummary.profit), saleSummaryMaxTurnover)}">
{{ 'sales.profit' | translate }}: <strong>{{ saleSummary.profit | currency: 'EUR' }}</strong>
</span>
</div>
</div>
</div>

+ 0
- 0
matsen-tool/src/app/_views/sales/sale-summary/sale-summary.component.scss Wyświetl plik


+ 23
- 0
matsen-tool/src/app/_views/sales/sale-summary/sale-summary.component.spec.ts Wyświetl plik

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { SaleSummaryComponent } from './sale-summary.component';

describe('SaleSummaryComponent', () => {
let component: SaleSummaryComponent;
let fixture: ComponentFixture<SaleSummaryComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [SaleSummaryComponent]
})
.compileComponents();
fixture = TestBed.createComponent(SaleSummaryComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 55
- 0
matsen-tool/src/app/_views/sales/sale-summary/sale-summary.component.ts Wyświetl plik

@@ -0,0 +1,55 @@
import {AfterViewInit, Component, OnInit} from '@angular/core';
import {Subscription} from "rxjs";
import {SaleSummaryJsonld, SaleSummaryService} from "@app/core/api/v1";

@Component({
selector: 'app-sale-summary',
templateUrl: './sale-summary.component.html',
styleUrl: './sale-summary.component.scss'
})
export class SaleSummaryComponent implements OnInit, AfterViewInit {

protected readonly Number = Number;
protected salesSummarySub: Subscription;
protected saleSummaries: Array<SaleSummaryJsonld>;
protected saleSummaryMaxTurnover: number;


constructor(
private saleSummaryService: SaleSummaryService,
) {
this.salesSummarySub = new Subscription();
this.saleSummaries = [];
this.saleSummaryMaxTurnover = 0;
}

ngOnInit(): void {
this.getData();
}

ngAfterViewInit(): void {
}



getData() {
this.salesSummarySub = this.saleSummaryService.saleSummariesGetCollection(
1,
50
).subscribe(
data => {
this.saleSummaries = data["hydra:member"];
if (this.saleSummaries.length > 0) {
this.saleSummaryMaxTurnover = Number(this.saleSummaries[0].turnover);
}
}
)
}

calculateWidthPercentage(turnover: number, maxTurnOver: number): number {
if (turnover && maxTurnOver && maxTurnOver !== 0) {
return (turnover / maxTurnOver) * 100;
}
return 0;
}
}

+ 3
- 117
matsen-tool/src/app/_views/sales/sales.component.html Wyświetl plik

@@ -1,121 +1,7 @@
<div class="spt-container">
<div class="d-flex justify-content-between align-items-start">
<h2>{{ 'basic.sales' | translate }}</h2>
<button class="btn btn-primary" (click)="openModalNewSale()">{{ 'basic.new-sale' | translate }}</button>
</div>

<div class="sales-summary-container mb-4" *ngFor="let saleSummary of saleSummaries">
<p><strong>{{ saleSummary.ownerName }}</strong></p>
<div class="sales-summary-bar">
<div>
<span class="sales-summary-turnover"
[ngStyle]="{ 'width.%': calculateWidthPercentage(Number(saleSummary.turnover), saleSummaryMaxTurnover)}">
{{ 'sales.turnover' | translate }}: <strong>{{ saleSummary.turnover | currency: 'EUR' }}</strong>
</span>
</div>
</div>
<div class="sales-summary-bar">
<div>
<span class="sales-summary-profit"
[ngStyle]="{ 'width.%': calculateWidthPercentage(Number(saleSummary.profit), saleSummaryMaxTurnover)}">
{{ 'sales.profit' | translate }}: <strong>{{ saleSummary.profit | currency: 'EUR' }}</strong>
</span>
</div>
</div>
</div>


<table mat-table [dataSource]="dataSource" matSort (matSortChange)="onSortChange($event)"
class="mat-elevation-z8 mb-3">

<ng-container matColumnDef="pos">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.number' | translate }}
</th>
<td mat-cell
*matCellDef="let element">{{ (pageSize * pageIndex) + dataSource.filteredData.indexOf(element) + 1 }}
</td>
</ng-container>

<ng-container matColumnDef="user">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.sale-user' | translate }}">
{{ 'overview.sale-user' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.ownerName }}
</td>
</ng-container>

<ng-container matColumnDef="partner">
<th mat-header-cell *matHeaderCellDef mat-sort-header="address"
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.sale-partner' | translate }}">
{{ 'overview.sale-partner' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<a [routerLink]="['/customer', appHelperService.extractId(element.partner)]">{{ element.partnerName }}</a>
</td>
</ng-container>

<ng-container matColumnDef="product">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.productname' | translate }}">
{{ 'overview.productname' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<a [routerLink]="['/products', appHelperService.extractId(element.product)]">{{ element.productName }}</a>
</td>
</ng-container>

<ng-container matColumnDef="turnover">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.turnover' | translate }}">
{{ 'overview.turnover' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.turnover | currency: 'EUR' }}
</td>
</ng-container>

<ng-container matColumnDef="profit">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.profit' | translate }}">
{{ 'overview.profit' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.profit | currency: 'EUR' }}
</td>
</ng-container>

<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef mat-sort-header
sortActionDescription="{{ 'overview.sort' | translate }}: {{ 'overview.createdAt' | translate }}">
{{ 'overview.createdAt' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.createdAt | date:'dd.MM.YYYY HH:mm' }}
</td>
</ng-container>

<ng-container matColumnDef="details">
<th mat-header-cell *matHeaderCellDef>
{{ 'overview.details' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<span class="btn btn-primary bi bi-zoom-in p-2-4"
data-type="user-tool" data-action="edit" (click)="navigateToSaleDetails(element)"></span>
</td>
</ng-container>

<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator class="rounded-1"
[pageSizeOptions]="[10,25,50]"
[length]="length"
(page)="handlePageEvent($event)"
[pageSize]="pageSize"
[pageIndex]="pageIndex"
showFirstLastButtons>
</mat-paginator>
</div>
<app-sale-summary></app-sale-summary>
<app-sale-list></app-sale-list>
</div>

+ 7
- 155
matsen-tool/src/app/_views/sales/sales.component.ts Wyświetl plik

@@ -1,26 +1,8 @@
import {ChangeDetectorRef, Component, LOCALE_ID, OnInit, ViewChild} from '@angular/core';
import {
ContactJsonld,
ProductJsonld,
SaleJsonld,
SaleService,
SaleSummaryJsonld,
SaleSummaryService
} from "@app/core/api/v1";
import {Subscription} from "rxjs";
import {MatPaginator, MatPaginatorIntl, PageEvent} from "@angular/material/paginator";
import {MatSort, Sort} from "@angular/material/sort";
import {TranslateService} from "@ngx-translate/core";
import {NewPartnerComponent} from "@app/_views/partners/new-partner/new-partner.component";
import {ModalStatus} from "@app/_helpers/modal.states";
import {NgbModal, NgbModalOptions} from "@ng-bootstrap/ng-bootstrap";
import {MatTableDataSource} from "@angular/material/table";
import {OrderFilter} from "@app/_models/orderFilter";
import {AppHelperService} from "@app/_helpers/app-helper.service";
import {Router} from "@angular/router";
import {AfterViewInit, Component, LOCALE_ID, OnInit, ViewChild} from '@angular/core';
import {registerLocaleData} from "@angular/common";
import localeDe from '@angular/common/locales/de';
import {NewSaleComponent} from "@app/_views/sales/new-sale/new-sale.component";
import {SaleListComponent} from "@app/_views/sales/sale-list/sale-list.component";
import {SaleSummaryComponent} from "@app/_views/sales/sale-summary/sale-summary.component";

registerLocaleData(localeDe);

@@ -35,148 +17,18 @@ registerLocaleData(localeDe);
},
],
})
export class SalesComponent implements OnInit {
@ViewChild(MatSort) sort;
@ViewChild(MatPaginator) paginator: MatPaginator;

protected displayedColumns: string[];
protected salesSub: Subscription;
protected sales: Array<SaleJsonld>;
protected salesSummarySub: Subscription;
protected saleSummaries: Array<SaleSummaryJsonld>;

protected dataSource;
protected length: number;
protected pageEvent: PageEvent;
protected pageSize: number;
protected pageIndex: number;

protected saleSummaryMaxTurnover: number;

protected modalOptions: NgbModalOptions = {
centered: true
};
export class SalesComponent implements OnInit, AfterViewInit {
@ViewChild("saleSummary", { static: false }) saleSummary!: SaleSummaryComponent;
@ViewChild("saleList", { static: false }) saleList!: SaleListComponent;

constructor(
private saleService: SaleService,
private saleSummaryService: SaleSummaryService,
private translateService: TranslateService,
private modalService: NgbModal,
private router: Router,
protected appHelperService: AppHelperService,
) {
this.sort = new MatSort();
this.displayedColumns = ['pos', 'user', 'partner', 'product', 'turnover', 'profit', 'date', 'details'];
this.salesSub = new Subscription();
this.sales = [];
this.salesSummarySub = new Subscription();
this.saleSummaries = [];

this.dataSource = new MatTableDataSource<SaleJsonld>(this.sales);
this.paginator = new MatPaginator(new MatPaginatorIntl(), ChangeDetectorRef.prototype);
this.length = 0;
this.pageEvent = new PageEvent();
this.pageSize = 10;
this.pageIndex = 0;

this.saleSummaryMaxTurnover = 0;
}

ngOnInit() {
this.getSalesData();
this.getSalesSummaryData();
}

getSalesData() {
this.salesSub = this.saleService.salesGetCollection(
this.pageIndex + 1,
this.pageSize,
).subscribe(
data => {
this.sales = data["hydra:member"];
this.dataSource = new MatTableDataSource<SaleJsonld>(this.sales);
this.length = Number(data["hydra:totalItems"]);
this.paginator.length = this.length;
console.log(this.sales);
}
)
}

getSalesSummaryData() {
this.salesSummarySub = this.saleSummaryService.saleSummariesGetCollection(
1,
50
).subscribe(
data => {
this.saleSummaries = data["hydra:member"];
console.log(this.saleSummaries);
if (this.saleSummaries.length > 0) {
this.saleSummaryMaxTurnover = Number(this.saleSummaries[0].turnover);
}
}
)
}

calculateWidthPercentage(turnover: number, maxTurnOver: number): number {
if (turnover && maxTurnOver && maxTurnOver !== 0) {
return (turnover / maxTurnOver) * 100;
}
return 0;
}

onSortChange(sortState: Sort) {
// Reset page index to first page
this.pageIndex = 0;

let order: OrderFilter;
if (sortState.direction === "") {
order = OrderFilter.Undefined;
} else {
order = sortState.direction;
}

// this.nameOrderAsc = OrderFilter.Undefined;
// this.cityOrderAsc = OrderFilter.Undefined;
// this.websiteOrderAsc = OrderFilter.Undefined;
// switch (sortState.active) {
// case "name":
// this.nameOrderAsc = order;
// break;
// case "address":
// this.cityOrderAsc = order;
// break;
// case "website":
// this.websiteOrderAsc = order;
// break;
// }
this.getSalesData();
}

handlePageEvent(e: PageEvent) {
this.pageEvent = e;
this.length = e.length;
this.pageIndex = e.pageIndex.valueOf();
this.pageSize = e.pageSize.valueOf();
this.getSalesData();
}

navigateToSaleDetails(element: any) {
const sale: SaleJsonld = element as SaleJsonld;
this.router.navigate(['/sales', this.appHelperService.extractId(sale.id)]);
}

openModalNewSale() {
const modalRefSale = this.modalService.open(NewSaleComponent, this.appHelperService.getModalOptions());
let sale: SaleJsonld = {} as SaleJsonld;
modalRefSale.componentInstance.sale = sale;
modalRefSale.componentInstance.submit.subscribe((modalStatus: ModalStatus) => {
if (modalStatus === ModalStatus.Submitted) {
modalRefSale.dismiss();
this.getSalesData();
this.getSalesSummaryData();
}
});
ngAfterViewInit(): void {
}

protected readonly Number = Number;
}

+ 6
- 0
matsen-tool/src/app/app.module.ts Wyświetl plik

@@ -56,6 +56,9 @@ import { SearchInputComponent } from './_components/search-input/search-input.co
import { PagingComponent } from '@app/_components/paging/paging.component';
import { PartnerListComponent } from './_views/partners/partner-list/partner-list.component';
import { ProductListComponent } from './_views/products/product-list/product-list.component';
import { DocumentListComponent } from './_views/documents/document-list/document-list.component';
import { SaleListComponent } from './_views/sales/sale-list/sale-list.component';
import { SaleSummaryComponent } from './_views/sales/sale-summary/sale-summary.component';

export function apiConfigFactory(): Configuration {
const params: ConfigurationParameters = {
@@ -133,6 +136,9 @@ export function HttpLoaderFactory(http: HttpClient) {
PagingComponent,
PartnerListComponent,
ProductListComponent,
DocumentListComponent,
SaleListComponent,
SaleSummaryComponent,
],
providers: [
{provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true},


+ 2
- 2
matsen-tool/src/app/core/api/v1/model/sale.ts Wyświetl plik

@@ -17,10 +17,10 @@
export interface Sale {
readonly owner?: string | null;
readonly ownerName?: string | null;
partner?: string | null;
partner: string | null;
readonly partnerType?: Sale.PartnerTypeEnum;
readonly partnerName?: string | null;
product?: string | null;
product: string | null;
readonly productName?: string | null;
turnover: number | null;
profit: number | null;


+ 2
- 2
matsen-tool/src/app/core/api/v1/model/saleJsonhal.ts Wyświetl plik

@@ -19,10 +19,10 @@ export interface SaleJsonhal {
_links?: CommentJsonhalLinks;
readonly owner?: string | null;
readonly ownerName?: string | null;
partner?: string | null;
partner: string | null;
readonly partnerType?: SaleJsonhal.PartnerTypeEnum;
readonly partnerName?: string | null;
product?: string | null;
product: string | null;
readonly productName?: string | null;
turnover: number | null;
profit: number | null;


+ 2
- 2
matsen-tool/src/app/core/api/v1/model/saleJsonld.ts Wyświetl plik

@@ -21,10 +21,10 @@ export interface SaleJsonld {
readonly type?: string;
readonly owner?: string | null;
readonly ownerName?: string | null;
partner?: string | null;
partner: string | null;
readonly partnerType?: SaleJsonld.PartnerTypeEnum;
readonly partnerName?: string | null;
product?: string | null;
product: string | null;
readonly productName?: string | null;
turnover: number | null;
profit: number | null;


+ 1
- 0
matsen-tool/src/assets/i18n/de.json Wyświetl plik

@@ -115,6 +115,7 @@
"product": "Produkt",
"turnover": "Umsatz",
"profit": "Gewinn",
"quantity": "Anzahl",
"send": "Speichern"
},
"sales":


Ładowanie…
Anuluj
Zapisz