Commit 31fd12a0 authored by Michail Tzanatos's avatar Michail Tzanatos
Browse files

added mapping of service spec characteristics to product spec characteristics logic

parent 58e2114c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import { EditProductOfferingsComponent } from './p_product/admin/productCatalogM
import { PreviewMarketPlaceItemComponent } from './p_product/marketplace/preview-market-place-item/preview-market-place-item.component';
import { AssignProductOfferingsComponent } from './p_product/admin/productCatalogManagement/edit-product-categories/assign-product-offerings/assign-product-offerings.component';
import { AssignSubcategoriesComponent } from './p_product/admin/productCatalogManagement/edit-product-categories/assign-subcategories/assign-subcategories.component';

import { ConfirmCharacteristicAssignmentComponent } from './p_product/admin/productCatalogManagement/edit-product-specs/assign-service-specification/confirm-characteristic-assignment/confirm-characteristic-assignment.component';


@NgModule({
@@ -42,6 +42,7 @@ import { AssignSubcategoriesComponent } from './p_product/admin/productCatalogMa
        DeleteProductCategoriesComponent,
        DeleteProductSpecsComponent,
        AssignServiceSpecificationComponent,
        ConfirmCharacteristicAssignmentComponent,
        ListProductOfferingsComponent,
        DeleteProductOfferingComponent,
        EditProductOfferingsComponent,
+104 −12
Original line number Diff line number Diff line
import { Component, OnInit, Inject, ViewChild, ElementRef } from '@angular/core';
import { UntypedFormControl } from '@angular/forms';
import { MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { ToastrService } from 'ngx-toastr';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators'
import { ProductSpecification, ProductSpecificationUpdate } from 'src/app/openApis/productCatalogManagement/models';
import { ProductSpecificationService } from 'src/app/openApis/productCatalogManagement/services';
import { ServiceSpecification } from 'src/app/openApis/serviceCatalogManagement/models';
import { ServiceSpecificationService } from 'src/app/openApis/serviceCatalogManagement/services';
import { ConfirmCharacteristicAssignmentComponent } from './confirm-characteristic-assignment/confirm-characteristic-assignment.component';


@Component({
  selector: 'app-assign-service-specification',
@@ -24,7 +27,10 @@ export class AssignServiceSpecificationComponent implements OnInit {
    },
    private dialogRef: MatDialogRef<AssignServiceSpecificationComponent>,
    private productSpecService: ProductSpecificationService,
    private serviceSpecService: ServiceSpecificationService
    private serviceSpecService: ServiceSpecificationService,
    private toast: ToastrService,
    private dialog: MatDialog
    
  ) { }

  @ViewChild('specInput') specInput: ElementRef<HTMLInputElement>;  
@@ -51,6 +57,8 @@ export class AssignServiceSpecificationComponent implements OnInit {
      data => this.nonSelectedSpecs = data,
      error => console.error(error),
      () => {


        //remove self from available spec list as well as the allready assigned specs
        const initiallyAssignedSpecIDs: string[] = this.data.productSpec.serviceSpecification.map(el => el.id)
        this.nonSelectedSpecs = this.nonSelectedSpecs.filter(spec => !initiallyAssignedSpecIDs.includes(spec.id))
@@ -68,13 +76,26 @@ export class AssignServiceSpecificationComponent implements OnInit {
  }

  selected(event: MatAutocompleteSelectedEvent): void {
    this.selectedSpecs.push(event.option.value);
    this.dataSource.data = this.selectedSpecs

    this.nonSelectedSpecs = this.nonSelectedSpecs.filter(el => el.name != event.option.value.name)

    const selectedLiteSpec = event.option.value;
    //retrieve full service specs details, @type and spec characteristics once a service spec is selected
    this.specInput.nativeElement.value = '';
    this.specInputCtrl.setValue(null);

    this.serviceSpecService.retrieveServiceSpecification({ 
      id: selectedLiteSpec.id 
    }).subscribe(
      (fullSpec: ServiceSpecification) => {

        this.selectedSpecs.push(fullSpec);
        this.dataSource.data = this.selectedSpecs;
        this.nonSelectedSpecs = this.nonSelectedSpecs.filter(
          el => el.name != selectedLiteSpec.name
        );
      },
      (error) => {
        this.toast.error('Failed to fetch full service specification details', error);
      }
    );
  }

  private _filter(value: string): ProductSpecification[] {
@@ -103,16 +124,87 @@ export class AssignServiceSpecificationComponent implements OnInit {

  confirmAssignment() {
    
    const updateRelationshipsObj: ProductSpecificationUpdate = {
      serviceSpecification: this.selectedSpecs.map(spec =>{ return {id: spec.id, name: spec.name}})
    const hasConfigurableCFSS = this.selectedSpecs.some(spec => {
      const s = spec as any;
      const type = s['@type'] || 'ServiceSpecification';
      const chars = s.serviceSpecCharacteristic || [];
      const hasConfigurable = chars.some(c => c.configurable === true);
      
      return type === 'CustomerFacingServiceSpecification' && hasConfigurable;
    });

    if (hasConfigurableCFSS) {
      // Open the dialog to ask the user
      const dialogRef = this.dialog.open(ConfirmCharacteristicAssignmentComponent, {
        width: '600px',
        disableClose: true
      });

      dialogRef.afterClosed().subscribe(result => {
        // result === true (Yes), result === false (No), result === undefined (Cancel)
        if (result === true) {
          this.executeAssignment(true);
        } else if (result === false) {
          this.executeAssignment(false);
        }
      });
    } else {
      this.executeAssignment(false);
    }
  }

  executeAssignment(importCharacteristics: boolean) {
    const serviceRefs: any[] = [];
    const newProductCharacteristics: any[] = [];

    this.selectedSpecs.forEach(spec => {
      const sourceSpec = spec as any;
      const type = sourceSpec['@type'] || 'ServiceSpecification';

      serviceRefs.push({
        id: sourceSpec.id,
        name: sourceSpec.name,
        '@type': type
      });

      if (importCharacteristics && type === 'CustomerFacingServiceSpecification') {
        const serviceChars = sourceSpec.serviceSpecCharacteristic || [];
        const configurableChars = serviceChars.filter(char => char.configurable === true);

        const mappedChars = configurableChars.map(char => ({
          name: char.name,
          description: char.description,
          valueType: char.valueType,
          configurable: char.configurable,
          minCardinality: char.minCardinality,
          maxCardinality: char.maxCardinality,
          productSpecCharacteristicValue: char.serviceSpecCharacteristicValue,
          '@type': 'ProductSpecCharacteristic'
        }));

        newProductCharacteristics.push(...mappedChars);
      }
    });

    const existingChars = this.data.productSpec.productSpecCharacteristic || [];
    
    const finalCharacteristics = [...existingChars, ...newProductCharacteristics];

    this.productSpecService.patchProductSpecification({id: this.data.productSpec.id, productSpecification: updateRelationshipsObj}).subscribe(
    const updateRelationshipsObj: ProductSpecificationUpdate = {
      serviceSpecification: serviceRefs,
      productSpecCharacteristic: finalCharacteristics
    };

    // console.log(updateRelationshipsObj);

    this.productSpecService.patchProductSpecification({
      id: this.data.productSpec.id, 
      productSpecification: updateRelationshipsObj
    }).subscribe(
      data => {},
      error => console.error(error),
      error => this.toast.error('Failed to update Product Specification', error),
      () => {this.dialogRef.close('updated')}
    )
  }


}
+14 −0
Original line number Diff line number Diff line
<h2 mat-dialog-title>Import Characteristics?</h2>
<mat-dialog-content class="mat-typography">
    <p>
    The selected <b>CustomerFacingServiceSpecification</b>(s) contain configurable characteristics.
    </p>
    <p>
    Do you want to automatically add these as <b>Product Characteristics</b> to the Product Specification?
    </p>
</mat-dialog-content>
<mat-dialog-actions align="end">
    <button (click)="onCancel()" class="btn btn-danger">Cancel</button>
    <button (click)="onNo()" class="btn btn-primary ml-2">No, just link Service Specification</button>
    <button (click)="onYes()" class="btn btn-success mt-2">Yes, Import Characteristics</button>
</mat-dialog-actions>
 No newline at end of file
+26 −0
Original line number Diff line number Diff line
import { Component } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';

@Component({
  selector: 'app-confirm-characteristic-assignment',
  templateUrl: './confirm-characteristic-assignment.component.html',
  styles: []
})
export class ConfirmCharacteristicAssignmentComponent {

  constructor(
    public dialogRef: MatDialogRef<ConfirmCharacteristicAssignmentComponent>
  ) {}

  onCancel(): void {
    this.dialogRef.close(); // Returns undefined
  }

  onNo(): void {
    this.dialogRef.close(false); // Returns false
  }

  onYes(): void {
    this.dialogRef.close(true); // Returns true
  }
}
 No newline at end of file
+11 −5
Original line number Diff line number Diff line
@@ -184,22 +184,28 @@ export class EditProductSpecCharacteristicsComponent implements OnInit {

    submitDialog() {



        if (this.newSpec) {
            this.data.productSpec.productSpecCharacteristic.push(this.editFormCharacteristic.getRawValue())
        } else {
            const updateCharacteristIndex = this.data.productSpec.productSpecCharacteristic.findIndex(char => char.uuid === this.data.specToBeUpdated.uuid)
            this.data.productSpec.productSpecCharacteristic[updateCharacteristIndex] = this.editFormCharacteristic.getRawValue()
        }
        console.log(this.newSpec);
        console.log(this.data.productSpec);

        const updateCharacteristicObj: ProductSpecificationUpdate = {
            productSpecCharacteristic: this.data.productSpec.productSpecCharacteristic
        }

        this.specService.patchProductSpecification({ id: this.data.productSpec.id, productSpecification: updateCharacteristicObj }).subscribe(
            data => { },
            error => { console.error(error); this.toast.error("An error occurred upon updating Spec Characteristics") },
            () => { this.dialogRef.close('updated') }
        )
        console.log(updateCharacteristicObj);

        // this.specService.patchProductSpecification({ id: this.data.productSpec.id, productSpecification: updateCharacteristicObj }).subscribe(
        //     data => { },
        //     error => { console.error(error); this.toast.error("An error occurred upon updating Spec Characteristics") },
        //     () => { this.dialogRef.close('updated') }
        // )
    }

    ngOnDestroy(): void {