| @@ -6074,6 +6074,8 @@ components: | |||||
| items: | items: | ||||
| type: string | type: string | ||||
| required: | required: | ||||
| - partner | |||||
| - product | |||||
| - turnover | - turnover | ||||
| - profit | - profit | ||||
| - quantity | - quantity | ||||
| @@ -6161,6 +6163,8 @@ components: | |||||
| items: | items: | ||||
| type: string | type: string | ||||
| required: | required: | ||||
| - partner | |||||
| - product | |||||
| - turnover | - turnover | ||||
| - profit | - profit | ||||
| - quantity | - quantity | ||||
| @@ -6262,6 +6266,8 @@ components: | |||||
| items: | items: | ||||
| type: string | type: string | ||||
| required: | required: | ||||
| - partner | |||||
| - product | |||||
| - turnover | - turnover | ||||
| - profit | - profit | ||||
| - quantity | - quantity | ||||
| @@ -392,10 +392,10 @@ export const productJsonldForm = new FormGroup({ | |||||
| export const saleForm = new FormGroup({ | export const saleForm = new FormGroup({ | ||||
| owner: new FormControl(null, []), | owner: new FormControl(null, []), | ||||
| ownerName: new FormControl(null, []), | ownerName: new FormControl(null, []), | ||||
| partner: new FormControl(null, []), | |||||
| partner: new FormControl(null, [Validators.required]), | |||||
| partnerType: new FormControl(null, []), | partnerType: new FormControl(null, []), | ||||
| partnerName: new FormControl(null, []), | partnerName: new FormControl(null, []), | ||||
| product: new FormControl(null, []), | |||||
| product: new FormControl(null, [Validators.required]), | |||||
| productName: new FormControl(null, []), | productName: new FormControl(null, []), | ||||
| turnover: new FormControl(null, [Validators.required]), | turnover: new FormControl(null, [Validators.required]), | ||||
| profit: new FormControl(null, [Validators.required]), | profit: new FormControl(null, [Validators.required]), | ||||
| @@ -409,10 +409,10 @@ export const saleJsonhalForm = new FormGroup({ | |||||
| _links: new FormControl(null, []), | _links: new FormControl(null, []), | ||||
| owner: new FormControl(null, []), | owner: new FormControl(null, []), | ||||
| ownerName: new FormControl(null, []), | ownerName: new FormControl(null, []), | ||||
| partner: new FormControl(null, []), | |||||
| partner: new FormControl(null, [Validators.required]), | |||||
| partnerType: new FormControl(null, []), | partnerType: new FormControl(null, []), | ||||
| partnerName: new FormControl(null, []), | partnerName: new FormControl(null, []), | ||||
| product: new FormControl(null, []), | |||||
| product: new FormControl(null, [Validators.required]), | |||||
| productName: new FormControl(null, []), | productName: new FormControl(null, []), | ||||
| turnover: new FormControl(null, [Validators.required]), | turnover: new FormControl(null, [Validators.required]), | ||||
| profit: 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({ | export const saleJsonldForm = new FormGroup({ | ||||
| owner: new FormControl(null, []), | owner: new FormControl(null, []), | ||||
| ownerName: new FormControl(null, []), | ownerName: new FormControl(null, []), | ||||
| partner: new FormControl(null, []), | |||||
| partner: new FormControl(null, [Validators.required]), | |||||
| partnerType: new FormControl(null, []), | partnerType: new FormControl(null, []), | ||||
| partnerName: new FormControl(null, []), | partnerName: new FormControl(null, []), | ||||
| product: new FormControl(null, []), | |||||
| product: new FormControl(null, [Validators.required]), | |||||
| productName: new FormControl(null, []), | productName: new FormControl(null, []), | ||||
| turnover: new FormControl(null, [Validators.required]), | turnover: new FormControl(null, [Validators.required]), | ||||
| profit: new FormControl(null, [Validators.required]), | profit: new FormControl(null, [Validators.required]), | ||||
| @@ -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 +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(); | |||||
| }); | |||||
| }); | |||||
| @@ -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); | |||||
| } | |||||
| } | |||||
| @@ -1,97 +1,8 @@ | |||||
| <div class="spt-container"> | <div class="spt-container"> | ||||
| <div class="d-flex justify-content-between align-items-start"> | <div class="d-flex justify-content-between align-items-start"> | ||||
| <h2>{{ 'basic.documents' | translate }}</h2> | <h2>{{ 'basic.documents' | translate }}</h2> | ||||
| <button class="btn btn-primary" (click)="openModalNewDocument()">{{ 'basic.new-document' | translate }}</button> | |||||
| </div> | </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> | |||||
| @@ -12,6 +12,8 @@ import {NewDocumentComponent} from "@app/_views/documents/new-document/new-docum | |||||
| import {TranslateModule} from "@ngx-translate/core"; | import {TranslateModule} from "@ngx-translate/core"; | ||||
| import {ModalStatus} from "@app/_helpers/modal.states"; | import {ModalStatus} from "@app/_helpers/modal.states"; | ||||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | 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({ | @Component({ | ||||
| selector: 'app-documents', | selector: 'app-documents', | ||||
| @@ -19,126 +21,17 @@ import {AppHelperService} from "@app/_helpers/app-helper.service"; | |||||
| styleUrl: './documents.component.scss', | styleUrl: './documents.component.scss', | ||||
| }) | }) | ||||
| export class DocumentsComponent { | 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( | 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() { | ngOnInit() { | ||||
| this.getDocumentsData(); | |||||
| } | } | ||||
| ngAfterViewInit() { | 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(); | |||||
| } | |||||
| }); | |||||
| } | |||||
| } | } | ||||
| @@ -31,53 +31,16 @@ | |||||
| <input type="number" class="form-control" id="profit" formControlName="profit" min="0" step="1" /> | <input type="number" class="form-control" id="profit" formControlName="profit" min="0" step="1" /> | ||||
| </div> | </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"> | <div class="mb-3"> | ||||
| <label for="comment" class="form-label">{{ 'form.comment' | translate }}:</label> | <label for="comment" class="form-label">{{ 'form.comment' | translate }}:</label> | ||||
| <textarea class="form-control" id="comment" formControlName="comment" cols="50" rows="5"></textarea> | <textarea class="form-control" id="comment" formControlName="comment" cols="50" rows="5"></textarea> | ||||
| </div> | </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 type="submit" class="btn btn-primary" [disabled]="saleForm.invalid">{{ 'form.send' | translate }} | ||||
| </button> | </button> | ||||
| </form> | </form> | ||||
| @@ -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 +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(); | |||||
| }); | |||||
| }); | |||||
| @@ -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); | |||||
| } | |||||
| } | |||||
| @@ -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 +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(); | |||||
| }); | |||||
| }); | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -1,121 +1,7 @@ | |||||
| <div class="spt-container"> | <div class="spt-container"> | ||||
| <div class="d-flex justify-content-between align-items-start"> | <div class="d-flex justify-content-between align-items-start"> | ||||
| <h2>{{ 'basic.sales' | translate }}</h2> | <h2>{{ 'basic.sales' | translate }}</h2> | ||||
| <button class="btn btn-primary" (click)="openModalNewSale()">{{ 'basic.new-sale' | translate }}</button> | |||||
| </div> | </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> | |||||
| @@ -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 {registerLocaleData} from "@angular/common"; | ||||
| import localeDe from '@angular/common/locales/de'; | 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); | 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( | 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() { | 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; | |||||
| } | } | ||||
| @@ -56,6 +56,9 @@ import { SearchInputComponent } from './_components/search-input/search-input.co | |||||
| import { PagingComponent } from '@app/_components/paging/paging.component'; | import { PagingComponent } from '@app/_components/paging/paging.component'; | ||||
| import { PartnerListComponent } from './_views/partners/partner-list/partner-list.component'; | import { PartnerListComponent } from './_views/partners/partner-list/partner-list.component'; | ||||
| import { ProductListComponent } from './_views/products/product-list/product-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 { | export function apiConfigFactory(): Configuration { | ||||
| const params: ConfigurationParameters = { | const params: ConfigurationParameters = { | ||||
| @@ -133,6 +136,9 @@ export function HttpLoaderFactory(http: HttpClient) { | |||||
| PagingComponent, | PagingComponent, | ||||
| PartnerListComponent, | PartnerListComponent, | ||||
| ProductListComponent, | ProductListComponent, | ||||
| DocumentListComponent, | |||||
| SaleListComponent, | |||||
| SaleSummaryComponent, | |||||
| ], | ], | ||||
| providers: [ | providers: [ | ||||
| {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | ||||
| @@ -17,10 +17,10 @@ | |||||
| export interface Sale { | export interface Sale { | ||||
| readonly owner?: string | null; | readonly owner?: string | null; | ||||
| readonly ownerName?: string | null; | readonly ownerName?: string | null; | ||||
| partner?: string | null; | |||||
| partner: string | null; | |||||
| readonly partnerType?: Sale.PartnerTypeEnum; | readonly partnerType?: Sale.PartnerTypeEnum; | ||||
| readonly partnerName?: string | null; | readonly partnerName?: string | null; | ||||
| product?: string | null; | |||||
| product: string | null; | |||||
| readonly productName?: string | null; | readonly productName?: string | null; | ||||
| turnover: number | null; | turnover: number | null; | ||||
| profit: number | null; | profit: number | null; | ||||
| @@ -19,10 +19,10 @@ export interface SaleJsonhal { | |||||
| _links?: CommentJsonhalLinks; | _links?: CommentJsonhalLinks; | ||||
| readonly owner?: string | null; | readonly owner?: string | null; | ||||
| readonly ownerName?: string | null; | readonly ownerName?: string | null; | ||||
| partner?: string | null; | |||||
| partner: string | null; | |||||
| readonly partnerType?: SaleJsonhal.PartnerTypeEnum; | readonly partnerType?: SaleJsonhal.PartnerTypeEnum; | ||||
| readonly partnerName?: string | null; | readonly partnerName?: string | null; | ||||
| product?: string | null; | |||||
| product: string | null; | |||||
| readonly productName?: string | null; | readonly productName?: string | null; | ||||
| turnover: number | null; | turnover: number | null; | ||||
| profit: number | null; | profit: number | null; | ||||
| @@ -21,10 +21,10 @@ export interface SaleJsonld { | |||||
| readonly type?: string; | readonly type?: string; | ||||
| readonly owner?: string | null; | readonly owner?: string | null; | ||||
| readonly ownerName?: string | null; | readonly ownerName?: string | null; | ||||
| partner?: string | null; | |||||
| partner: string | null; | |||||
| readonly partnerType?: SaleJsonld.PartnerTypeEnum; | readonly partnerType?: SaleJsonld.PartnerTypeEnum; | ||||
| readonly partnerName?: string | null; | readonly partnerName?: string | null; | ||||
| product?: string | null; | |||||
| product: string | null; | |||||
| readonly productName?: string | null; | readonly productName?: string | null; | ||||
| turnover: number | null; | turnover: number | null; | ||||
| profit: number | null; | profit: number | null; | ||||
| @@ -115,6 +115,7 @@ | |||||
| "product": "Produkt", | "product": "Produkt", | ||||
| "turnover": "Umsatz", | "turnover": "Umsatz", | ||||
| "profit": "Gewinn", | "profit": "Gewinn", | ||||
| "quantity": "Anzahl", | |||||
| "send": "Speichern" | "send": "Speichern" | ||||
| }, | }, | ||||
| "sales": | "sales": | ||||