diff --git a/.gitignore b/.gitignore index 87dd65f8..78416f23 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,8 @@ target/ .idea/* -demand-capacity-mgmt-backend/.mvn/wrapper/maven-wrapper.jar \ No newline at end of file +demand-capacity-mgmt-backend/.mvn/wrapper/maven-wrapper.jar +.env +keycloak/generate-secret.sh +keycloak/init-db.sql +keycloak/realm-export.json diff --git a/DEPENDENCIES_FRONTEND b/DEPENDENCIES_FRONTEND index 0e5e8ea9..e9aaff39 100644 --- a/DEPENDENCIES_FRONTEND +++ b/DEPENDENCIES_FRONTEND @@ -367,7 +367,7 @@ npm/npmjs/-/flatted/3.2.7, ISC AND (ISC AND MIT), approved, #2430 npm/npmjs/-/flow-enums-runtime/0.0.5, MIT, approved, clearlydefined npm/npmjs/-/flow-parser/0.206.0, MIT, approved, clearlydefined npm/npmjs/-/flow-parser/0.209.0, MIT, approved, clearlydefined -npm/npmjs/-/follow-redirects/1.15.2, MIT, approved, clearlydefined +npm/npmjs/-/follow-redirects/1.15.2, MIT, approved, #10782 npm/npmjs/-/for-each/0.3.3, MIT, approved, clearlydefined npm/npmjs/-/for-in/1.0.2, MIT, approved, clearlydefined npm/npmjs/-/fork-ts-checker-webpack-plugin/6.5.3, MIT, approved, #7487 diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/CapacityGroupsController.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/CapacityGroupsController.java new file mode 100644 index 00000000..3b4b367c --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/CapacityGroupsController.java @@ -0,0 +1,63 @@ +/* + * ****************************************************************************** + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************* + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.controllers; + +import eclipse.tractusx.demand_capacity_mgmt_specification.api.CapacityGroupApi; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; +import java.util.List; +import lombok.AllArgsConstructor; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.CapacityGroupService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@AllArgsConstructor +public class CapacityGroupsController implements CapacityGroupApi { + + private CapacityGroupService service; + + @Override + public ResponseEntity> getCapacityGroups() { + List capacityGroupDefaultViewResponses = service.getAll(); + return ResponseEntity.status(HttpStatus.OK).body(capacityGroupDefaultViewResponses); + } + + @Override + public ResponseEntity getCapacityGroupById(String capacityGroupId) { + CapacityGroupResponse capacityGroupResponse = service.getCapacityGroupById(capacityGroupId); + return ResponseEntity.status(HttpStatus.OK).body(capacityGroupResponse); + } + + @Override + public ResponseEntity postCapacityGroup(CapacityGroupRequest capacityGroupRequest) { + CapacityGroupResponse capacityGroupResponse = service.createCapacityGroup(capacityGroupRequest); + return ResponseEntity.status(HttpStatus.OK).body(capacityGroupResponse); + } + + @Override + public ResponseEntity postLinkedCapacityGroupDemand(LinkCGDSRequest linkCGDSRequest) throws Exception { + service.linkCapacityGroupToMaterialDemand(linkCGDSRequest); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/DemandController.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/DemandController.java index b8b1c3b7..0c8e227c 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/DemandController.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/DemandController.java @@ -23,8 +23,7 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.controllers; import eclipse.tractusx.demand_capacity_mgmt_specification.api.DemandApi; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.MaterialDemandRequest; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.MaterialDemandResponse; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import java.util.List; import lombok.AllArgsConstructor; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.DemandService; @@ -56,6 +55,23 @@ public ResponseEntity> getDemandsByProjectID() { return ResponseEntity.status(HttpStatus.OK).body(demandResponseDtos); } + @Override + public ResponseEntity getLinkedDemandSeriesByCompositeKeyID( + DemandSeriesCompositeRequest demandSeriesCompositeRequest + ) throws Exception { + DemandSeriesCompositeResponse response = demandService.getAllDemandsByCompositeKey( + demandSeriesCompositeRequest + ); + return ResponseEntity.status(HttpStatus.OK).body(response); + } + + @Override + public ResponseEntity unlinkedDemandSeriesComposites(DemandSeriesUnlinkRequest demandSeriesUnlinkRequest) + throws Exception { + demandService.unlinkComposites(demandSeriesUnlinkRequest); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } + @Override public ResponseEntity postDemand(MaterialDemandRequest materialDemandRequest) { MaterialDemandResponse responseDto = demandService.createDemand(materialDemandRequest); diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/CapacityGroupController.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/StatusesController.java similarity index 55% rename from demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/CapacityGroupController.java rename to demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/StatusesController.java index 975cf19a..11196459 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/CapacityGroupController.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/StatusesController.java @@ -22,38 +22,36 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.controllers; -import eclipse.tractusx.demand_capacity_mgmt_specification.api.CapacityGroupApi; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityGroupDefaultViewResponse; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityGroupRequest; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityGroupResponse; +import eclipse.tractusx.demand_capacity_mgmt_specification.api.StatusesApi; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.StatusRequest; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.StatusesResponse; import java.util.List; import lombok.AllArgsConstructor; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.CapacityGroupService; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.DemandService; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.StatusesService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RestController; @RestController @AllArgsConstructor -public class CapacityGroupController implements CapacityGroupApi { +public class StatusesController implements StatusesApi { - private final CapacityGroupService capacityGroupService; + private final StatusesService statusesService; @Override - public ResponseEntity> getCapacityGroup() { - List capacityGroupDefaultViewResponseList = capacityGroupService.getAll(); - return ResponseEntity.status(HttpStatus.OK).body(capacityGroupDefaultViewResponseList); + public ResponseEntity getStatuses() { + return ResponseEntity.status(HttpStatus.OK).body(statusesService.getAllStatuses()); } @Override - public ResponseEntity getCapacityGroupById(String capacityGroupId) { - CapacityGroupResponse responseDto = capacityGroupService.getCapacityGroupById(capacityGroupId); - return ResponseEntity.status(HttpStatus.OK).body(responseDto); + public ResponseEntity postStatus(StatusRequest statusRequest) { + StatusesResponse responseDto = statusesService.postStatuses(statusRequest); + return ResponseEntity.status(HttpStatus.CREATED).body(responseDto); } @Override - public ResponseEntity postCapacityGroup(CapacityGroupRequest capacityGroupRequest) { - CapacityGroupResponse capacityGroupResponse = capacityGroupService.createCapacityGroup(capacityGroupRequest); - return ResponseEntity.status(HttpStatus.OK).body(capacityGroupResponse); + public ResponseEntity updateStatusesById(String statusId, StatusRequest statusRequest) { + return null; } } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/WeekBasedCapacityGroupController.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/WeekBasedCapacityGroupController.java index 221fef90..26f448ea 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/WeekBasedCapacityGroupController.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/WeekBasedCapacityGroupController.java @@ -23,7 +23,7 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.controllers; import eclipse.tractusx.demand_capacity_mgmt_specification.api.WeekBasedCapacityGroupApi; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedCapacityGroupRequest; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import java.util.List; import lombok.AllArgsConstructor; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.WeekBasedCapacityGroupService; @@ -37,11 +37,29 @@ public class WeekBasedCapacityGroupController implements WeekBasedCapacityGroupA private final WeekBasedCapacityGroupService weekBasedCapacityGroupService; + @Override + public ResponseEntity> getWeekBasedCapacityGroup() { + List capacityGroupDefaultViewResponseList = weekBasedCapacityGroupService.getWeekBasedCapacityGroups(); + return ResponseEntity.status(HttpStatus.OK).body(capacityGroupDefaultViewResponseList); + } + @Override public ResponseEntity postWeekBasedCapacityGroup( - List weekBasedCapacityGroupRequest + List weekBasedCapacityGroupRequest ) { weekBasedCapacityGroupService.createWeekBasedCapacityGroup(weekBasedCapacityGroupRequest); return ResponseEntity.status(HttpStatus.OK).build(); } + + @Override + public ResponseEntity updateWeekBasedCapacityGroupById( + String weekBasedCapacityId, + WeekBasedCapacityGroupDtoRequest weekBasedCapacityGroupRequest + ) { + WeekBasedCapacityGroupDtoResponse responseDto = weekBasedCapacityGroupService.updateWeekBasedCapacityGroup( + weekBasedCapacityId, + weekBasedCapacityGroupRequest + ); + return ResponseEntity.status(HttpStatus.OK).body(responseDto); + } } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/WeekBasedMaterialController.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/WeekBasedMaterialController.java index 2a385d74..8b3e1e08 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/WeekBasedMaterialController.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/controllers/WeekBasedMaterialController.java @@ -24,6 +24,7 @@ import eclipse.tractusx.demand_capacity_mgmt_specification.api.WeekBasedMaterialDemandApi; import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequestDto; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandResponseDto; import java.util.List; import lombok.AllArgsConstructor; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.WeekBasedMaterialService; @@ -37,6 +38,12 @@ public class WeekBasedMaterialController implements WeekBasedMaterialDemandApi { private final WeekBasedMaterialService weekBasedMaterialService; + @Override + public ResponseEntity> getWeekBasedMaterialDemand() { + List capacityGroupDefaultViewResponseList = weekBasedMaterialService.getWeekBasedMaterialDemands(); + return ResponseEntity.status(HttpStatus.OK).body(capacityGroupDefaultViewResponseList); + } + @Override public ResponseEntity postWeekBasedMaterialDemand( List weekBasedMaterialDemandRequestDto @@ -44,4 +51,16 @@ public ResponseEntity postWeekBasedMaterialDemand( weekBasedMaterialService.createWeekBasedMaterial(weekBasedMaterialDemandRequestDto); return ResponseEntity.status(HttpStatus.OK).build(); } + + @Override + public ResponseEntity updateWeekBasedMaterialDemandById( + String demandId, + WeekBasedMaterialDemandRequestDto weekBasedMaterialDemandRequestDto + ) { + WeekBasedMaterialDemandResponseDto responseDto = weekBasedMaterialService.updateWeekBasedMaterial( + demandId, + weekBasedMaterialDemandRequestDto + ); + return ResponseEntity.status(HttpStatus.OK).body(responseDto); + } } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/CapacityGroupEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/CapacityGroupEntity.java index cc12da30..0ac7a170 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/CapacityGroupEntity.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/CapacityGroupEntity.java @@ -22,24 +22,16 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.UUID; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Convert; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import lombok.*; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.converters.ListToStringConverter; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.CapacityGroupStatus; +import javax.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; @Entity @Table(name = "capacity_group") @@ -54,49 +46,26 @@ public class CapacityGroupEntity { @Column(columnDefinition = "uuid", updatable = false, name = "id") private UUID id; - @Column(columnDefinition = "uuid", updatable = false, name = "capacity_group_id") - private UUID capacityGroupId; + @Column(name = "capacity_group_name") + private String capacityGroupName; - @Column(name = "material_description_customer") - private String materialDescriptionCustomer; + @Column(name = "defaultactualcapacity") + private float defaultActualCapacity; - @Column(name = "material_number_customer") - private String materialNumberCustomer; + @Column(name = "defaultmaximumcapacity") + private float defaultMaximumCapacity; - @Column(name = "material_number_supplier") - private String materialNumberSupplier; + @Column(name = "start_date", nullable = false) + private LocalDate startDate; - @Column(name = "changed_at", nullable = false) - private LocalDateTime changedAt; + @Column(name = "end_date", nullable = false) + private LocalDate endDate; @OneToOne - @JoinColumn(name = "customer_id", referencedColumnName = "ID") - private CompanyEntity customerId; + @JoinColumn(name = "customer", referencedColumnName = "ID") + private CompanyEntity customer; @OneToOne - @JoinColumn(name = "supplier_id", referencedColumnName = "ID") - private CompanyEntity supplierId; - - @OneToOne - @JoinColumn(name = "unity_of_measure_id", referencedColumnName = "ID") - private UnitMeasureEntity unitMeasure; - - @OneToMany(mappedBy = "capacityGroupEntity", cascade = CascadeType.ALL) - @ToString.Exclude - private List capacityTimeSeries; - - @OneToMany(mappedBy = "capacityGroupEntity", cascade = CascadeType.ALL) - @ToString.Exclude - private List linkedDemandSeries; - - @Column(name = "supplier_locations") - @Convert(converter = ListToStringConverter.class) - private List supplierLocation; - - @Column(name = "name") - private String name; - - @Column(name = "status") - @Enumerated(EnumType.STRING) - private CapacityGroupStatus status; + @JoinColumn(name = "supplier", referencedColumnName = "ID") + private CompanyEntity supplier; } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/DemandSeries.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/DemandSeries.java index 2f7de53b..d1549730 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/DemandSeries.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/DemandSeries.java @@ -22,24 +22,12 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import java.util.List; import java.util.UUID; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Convert; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import javax.persistence.*; +import lombok.*; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.converters.ListToStringConverter; @Entity @@ -48,6 +36,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class DemandSeries { @Id @@ -74,6 +63,8 @@ public class DemandSeries { @JoinColumn(name = "demand_series_id") private List demandSeriesValues; + @ToString.Exclude + @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) private MaterialDemandEntity materialDemand; } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/FavoriteEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/FavoriteEntity.java index 0dbe5787..52184c38 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/FavoriteEntity.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/FavoriteEntity.java @@ -39,7 +39,6 @@ public class FavoriteEntity { @Id - @GeneratedValue @Column(columnDefinition = "uuid", updatable = false, name = "user_id") private UUID id; diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/LinkDemandEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/LinkDemandEntity.java index d3a0b695..8da3178b 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/LinkDemandEntity.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/LinkDemandEntity.java @@ -23,13 +23,7 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities; import java.util.UUID; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; +import javax.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -41,6 +35,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor +@Deprecated public class LinkDemandEntity { @Id diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/LinkedCapacityGroupMaterialDemandEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/LinkedCapacityGroupMaterialDemandEntity.java new file mode 100644 index 00000000..f2a8c663 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/LinkedCapacityGroupMaterialDemandEntity.java @@ -0,0 +1,62 @@ +/* + * ****************************************************************************** + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************* + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities; + +import java.util.UUID; +import javax.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "link_capacitygroup_demandseries") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class LinkedCapacityGroupMaterialDemandEntity { + + @Id + @GeneratedValue + @Column(columnDefinition = "uuid", updatable = false, name = "id") + private UUID id; + + @Column(columnDefinition = "uuid", updatable = false, name = "demand_category_code_id") + private UUID demandCategoryCodeID; + + @Column(columnDefinition = "uuid", updatable = false, name = "customer_id") + private UUID customerID; + + @Column(name = "material_number_customer") + private String materialNumberCustomer; + + @Column(name = "material_number_supplier") + private String materialNumberSupplier; + + @Column(columnDefinition = "uuid", updatable = false, name = "capacity_group_id", nullable = false) + private UUID capacityGroupID; + + @Column(columnDefinition = "uuid", updatable = false, name = "material_demand_id", nullable = false) + private UUID materialDemandID; +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/MaterialDemandEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/MaterialDemandEntity.java index 51ff1a18..a651bdf1 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/MaterialDemandEntity.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/MaterialDemandEntity.java @@ -22,25 +22,13 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import java.time.LocalDateTime; import java.util.List; import java.util.UUID; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import javax.persistence.*; +import lombok.*; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.MaterialDemandStatus; @Entity @@ -49,6 +37,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class MaterialDemandEntity { @Id @@ -77,9 +66,11 @@ public class MaterialDemandEntity { private CompanyEntity supplierId; @OneToOne - @JoinColumn(name = "unity_of_measure_id", referencedColumnName = "ID") + @JoinColumn(name = "unit_of_measure_id", referencedColumnName = "ID") private UnitMeasureEntity unitMeasure; + @ToString.Exclude + @EqualsAndHashCode.Exclude @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) @JoinColumn(name = "material_demand_id") private List demandSeries; diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/StatusObjectEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/StatusObjectEntity.java new file mode 100644 index 00000000..6a487b3c --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/StatusObjectEntity.java @@ -0,0 +1,46 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities; + +import java.util.UUID; +import javax.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "status_object") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class StatusObjectEntity { + + @Id + @Column(columnDefinition = "uuid") + private UUID id; + + @Column(name = "count") + private int count; +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/StatusesEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/StatusesEntity.java new file mode 100644 index 00000000..b3bb6fa6 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/StatusesEntity.java @@ -0,0 +1,86 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities; + +import java.util.UUID; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.GenericGenerator; + +@Entity +@Table(name = "statuses") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class StatusesEntity { + + @Id + // @SequenceGenerator(name = "status_id_sequence", sequenceName = "status_id_sequence") + // @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "status_id_sequence") + @GenericGenerator(name = "uuid2", strategy = "uuid2") + // @Type(type = "uuid-char") // This is important for PostgreSQL + @Column(columnDefinition = "uuid") + private UUID id; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "todos", referencedColumnName = "id") + private StatusObjectEntity todos; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "status_improvment", referencedColumnName = "id") + private StatusObjectEntity statusImprovment; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "status_degredation", referencedColumnName = "id") + private StatusObjectEntity statusDegredation; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "general", referencedColumnName = "id") + private StatusObjectEntity general; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "overall_todos", referencedColumnName = "id") + private StatusObjectEntity overAllTodos; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "overall_status_improvment", referencedColumnName = "id") + private StatusObjectEntity overAllStatusImprovment; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "overall_status_degredation", referencedColumnName = "id") + private StatusObjectEntity overAllStatusDegredation; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "overall_general", referencedColumnName = "id") + private StatusObjectEntity overAllGeneral; +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/UnitMeasureEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/UnitMeasureEntity.java index b8d496ce..1a264a22 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/UnitMeasureEntity.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/UnitMeasureEntity.java @@ -30,7 +30,7 @@ import lombok.NoArgsConstructor; @Entity -@Table(name = "unity_of_measure") +@Table(name = "unit_of_measure") @Data @Builder @NoArgsConstructor @@ -42,9 +42,21 @@ public class UnitMeasureEntity { @Column(columnDefinition = "uuid", updatable = false, name = "id") private UUID id; - @Column(name = "code_value") - private String codeValue; + @Column(name = "dimension") + private String dimension; - @Column(name = "display_value") - private String displayValue; + @Column(name = "un_code") + private String unCode; + + @Column(name = "description") + private String description; + + @Column(name = "description_german") + private String descriptionGerman; + + @Column(name = "un_symbol") + private String unSymbol; + + @Column(name = "c_x_symbol") + private String cxSymbol; } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/WeekBasedCapacityGroupEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/WeekBasedCapacityGroupEntity.java index 06cb0da7..0834670a 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/WeekBasedCapacityGroupEntity.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/WeekBasedCapacityGroupEntity.java @@ -23,11 +23,10 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities; import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedCapacityGroupRequest; +import java.util.UUID; import javax.persistence.Column; import javax.persistence.Convert; import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import lombok.AllArgsConstructor; @@ -35,9 +34,6 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.converters.WeekBasedCapacityGroupConverter; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.converters.WeekBasedMaterialConverter; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.jsonEntities.WeekBasedCapacityGroup; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.jsonEntities.WeekBasedMaterialDemand; import org.hibernate.annotations.ColumnTransformer; @Entity @@ -49,9 +45,8 @@ public class WeekBasedCapacityGroupEntity { @Id - @Column(name = "ID") - @GeneratedValue(strategy = GenerationType.SEQUENCE) - private Long id; + @Column(columnDefinition = "uuid", updatable = false, name = "id") + private UUID id; @Convert(converter = WeekBasedCapacityGroupConverter.class) @Column(name = "data", columnDefinition = "jsonb") diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/WeekBasedMaterialDemandEntity.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/WeekBasedMaterialDemandEntity.java index d16a7b9f..c97c07cc 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/WeekBasedMaterialDemandEntity.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/WeekBasedMaterialDemandEntity.java @@ -22,12 +22,11 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequestDto; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequest; +import java.util.UUID; import javax.persistence.Column; import javax.persistence.Convert; import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import lombok.AllArgsConstructor; @@ -35,7 +34,6 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.converters.WeekBasedMaterialConverter; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.jsonEntities.WeekBasedMaterialDemand; import org.hibernate.annotations.ColumnTransformer; @Entity @@ -47,14 +45,13 @@ public class WeekBasedMaterialDemandEntity { @Id - @Column(name = "ID") - @GeneratedValue(strategy = GenerationType.SEQUENCE) - private Long id; + @Column(columnDefinition = "uuid", updatable = false, name = "id") + private UUID id; @Convert(converter = WeekBasedMaterialConverter.class) @Column(name = "data", columnDefinition = "jsonb") @ColumnTransformer(write = "?::jsonb") - private WeekBasedMaterialDemandRequestDto weekBasedMaterialDemand; + private WeekBasedMaterialDemandRequest weekBasedMaterialDemand; @Column(name = "viewed") private Boolean viewed; diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/converters/WeekBasedMaterialConverter.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/converters/WeekBasedMaterialConverter.java index 3b391ad1..606762fe 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/converters/WeekBasedMaterialConverter.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/converters/WeekBasedMaterialConverter.java @@ -23,23 +23,22 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.converters; import com.google.gson.Gson; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequestDto; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequest; import javax.persistence.AttributeConverter; import javax.persistence.Converter; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.jsonEntities.WeekBasedMaterialDemand; @Converter(autoApply = true) -public class WeekBasedMaterialConverter implements AttributeConverter { +public class WeekBasedMaterialConverter implements AttributeConverter { private static final Gson GSON = new Gson(); @Override - public String convertToDatabaseColumn(WeekBasedMaterialDemandRequestDto mjo) { + public String convertToDatabaseColumn(WeekBasedMaterialDemandRequest mjo) { return GSON.toJson(mjo); } @Override - public WeekBasedMaterialDemandRequestDto convertToEntityAttribute(String dbData) { - return GSON.fromJson(dbData, WeekBasedMaterialDemandRequestDto.class); + public WeekBasedMaterialDemandRequest convertToEntityAttribute(String dbData) { + return GSON.fromJson(dbData, WeekBasedMaterialDemandRequest.class); } } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/enums/CapacityDeviation.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/enums/CapacityDeviation.java new file mode 100644 index 00000000..ed9af709 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/enums/CapacityDeviation.java @@ -0,0 +1,39 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums; + +public enum CapacityDeviation { + BOTTLENECK(StatusColor.RED), + SURPLUS(StatusColor.GREEN), + ZERO(StatusColor.GREEN); + + private final StatusColor statusColor; + + CapacityDeviation(StatusColor statusColor) { + this.statusColor = statusColor; + } + + public StatusColor getStatusColor() { + return statusColor; + } +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/enums/EventType.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/enums/EventType.java new file mode 100644 index 00000000..9c1fc3f8 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/enums/EventType.java @@ -0,0 +1,32 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums; + +public enum EventType { + GENERAL_EVENT, + TODO, + STATUS_IMPROVEMENT, + STATUS_REDUCTION, + LINKED, + NOT_LINKED, +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/enums/StatusColor.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/enums/StatusColor.java new file mode 100644 index 00000000..7f91333a --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/entities/enums/StatusColor.java @@ -0,0 +1,29 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums; + +public enum StatusColor { + RED, + GREEN, + YELLOW, +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/CapacityGroupRepository.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/CapacityGroupRepository.java index 5dac0a1b..161e4d9c 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/CapacityGroupRepository.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/CapacityGroupRepository.java @@ -25,13 +25,10 @@ import java.util.List; import java.util.UUID; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.CapacityGroupEntity; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.CapacityGroupStatus; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface CapacityGroupRepository extends JpaRepository { - List findAllByStatus(CapacityGroupStatus status); - List findAll(); } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/DemandSeriesRepository.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/DemandSeriesRepository.java new file mode 100644 index 00000000..71b9808b --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/DemandSeriesRepository.java @@ -0,0 +1,51 @@ +/* + * ****************************************************************************** + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************* + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories; + +import java.util.List; +import java.util.UUID; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.DemandSeries; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.lang.NonNull; + +public interface DemandSeriesRepository extends JpaRepository { + @Query( + """ + select d from DemandSeries d + where d.customerLocation.id = ?1 and d.demandCategory.id = ?2 and d.materialDemand.materialNumberCustomer = ?3""" + ) + List ByCategoryIDCustomerIDMaterialNrCustomer( + @NonNull UUID id, + @NonNull UUID id1, + @NonNull String materialNumberCustomer + ); + + @Query( + """ + select d from DemandSeries d + where d.capacityGroupId = ?1 and d.materialDemand.id = ?2 + """ + ) + DemandSeries fetchByCGIDandMatID(@NonNull UUID id, @NonNull UUID id2); +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/LinkedCapacityGroupMaterialDemandRepository.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/LinkedCapacityGroupMaterialDemandRepository.java new file mode 100644 index 00000000..686fc521 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/LinkedCapacityGroupMaterialDemandRepository.java @@ -0,0 +1,44 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories; + +import java.math.BigDecimal; +import java.util.List; +import java.util.UUID; +import javax.transaction.Transactional; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.LinkedCapacityGroupMaterialDemandEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface LinkedCapacityGroupMaterialDemandRepository + extends JpaRepository { + @Transactional + void deleteByCapacityGroupIDAndMaterialDemandID(UUID capacityGroup, UUID materialDemandID); + + List findLinkedCapacityGroupMaterialDemandEntitiesByCapacityGroupID( + UUID capacityGroup + ); + + BigDecimal countByCapacityGroupID(UUID id); +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/StatusesRepository.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/StatusesRepository.java new file mode 100644 index 00000000..9464db35 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/repositories/StatusesRepository.java @@ -0,0 +1,29 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories; + +import java.util.UUID; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.StatusesEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface StatusesRepository extends JpaRepository {} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/CapacityGroupService.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/CapacityGroupService.java index 87e87ab4..7ae53ca3 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/CapacityGroupService.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/CapacityGroupService.java @@ -22,19 +22,15 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityGroupDefaultViewResponse; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityGroupRequest; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityGroupResponse; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import java.util.List; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.CapacityGroupEntity; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.CapacityGroupStatus; public interface CapacityGroupService { CapacityGroupResponse createCapacityGroup(CapacityGroupRequest capacityGroupRequest); - CapacityGroupResponse getCapacityGroupById(String CapacityGroupId); + void linkCapacityGroupToMaterialDemand(LinkCGDSRequest linkCGDSRequest); - List getAllByStatus(CapacityGroupStatus status); + CapacityGroupResponse getCapacityGroupById(String CapacityGroupId); List getAll(); } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/DemandService.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/DemandService.java index dc6096aa..bedc9d96 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/DemandService.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/DemandService.java @@ -22,8 +22,7 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.MaterialDemandRequest; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.MaterialDemandResponse; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import java.util.List; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.MaterialDemandEntity; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.MaterialDemandStatus; @@ -40,4 +39,10 @@ public interface DemandService { void deleteDemandById(String demandId); List getAllByStatus(MaterialDemandStatus status); + + DemandSeriesCompositeResponse getAllDemandsByCompositeKey( + DemandSeriesCompositeRequest demandSeriesCompositeRequest + ); + + void unlinkComposites(DemandSeriesUnlinkRequest demandSeriesUnlinkRequest); } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/StatusesService.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/StatusesService.java new file mode 100644 index 00000000..2c2963f4 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/StatusesService.java @@ -0,0 +1,37 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services; + +import eclipse.tractusx.demand_capacity_mgmt_specification.model.MaterialDemandRequest; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.MaterialDemandResponse; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.StatusRequest; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.StatusesResponse; +import java.util.List; +import java.util.UUID; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.WeekBasedMaterialDemandEntity; + +public interface StatusesService { + StatusesResponse postStatuses(StatusRequest statusRequest); + StatusesResponse getAllStatuses(); + void updateStatus(); +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedCapacityGroupService.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedCapacityGroupService.java index 2a98fc1f..7e67c30f 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedCapacityGroupService.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedCapacityGroupService.java @@ -22,19 +22,29 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedCapacityGroupRequest; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import java.util.List; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.CapacityGroupEntity; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.WeekBasedCapacityGroupEntity; public interface WeekBasedCapacityGroupService { - void createWeekBasedCapacityGroup(List weekBasedCapacityGroupRequest); + void createWeekBasedCapacityGroup(List weekBasedCapacityGroupRequest); void receiveWeekBasedCapacityGroup(); void sendWeekBasedCapacityGroup(); + List getOldWeekBasedCapacityGroups(); + + List getUpdatedWeekBasedCapacityGroups(); + + List getWeekBasedCapacityGroups(); + void createWeekBasedCapacityGroupRequestFromEntity(CapacityGroupEntity capacityGroupEntity); + WeekBasedCapacityGroupDtoResponse updateWeekBasedCapacityGroup( + String id, + WeekBasedCapacityGroupDtoRequest weekBasedCapacityGroupRequest + ); WeekBasedCapacityGroupEntity findById(String capacityGroupId); } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedMaterialService.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedMaterialService.java index c0b63e1f..cfdd6956 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedMaterialService.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedMaterialService.java @@ -23,15 +23,22 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services; import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequestDto; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandResponseDto; import java.util.List; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.MaterialDemandEntity; public interface WeekBasedMaterialService { void createWeekBasedMaterial(List weekBasedMaterialDemandRequestDto); - void sendWeekBasedMaterial(); - void receiveWeekBasedMaterial(); + List getWeekBasedMaterialDemands(); + List getOldWeekBasedMaterialDemands(); + List getUpdatedWeekBasedMaterialDemands(); + WeekBasedMaterialDemandResponseDto updateWeekBasedMaterial( + String id, + WeekBasedMaterialDemandRequestDto weekBasedMaterialDemandRequestDto + ); + void createWeekBasedMaterialRequestFromEntity(MaterialDemandEntity materialDemandEntity); } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/CapacityGroupServiceImpl.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/CapacityGroupServiceImpl.java index b26ee594..3732b7a9 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/CapacityGroupServiceImpl.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/CapacityGroupServiceImpl.java @@ -1,4 +1,4 @@ - /* +/* * ******************************************************************************* * Copyright (c) 2023 BMW AG * Copyright (c) 2023 Contributors to the Eclipse Foundation @@ -25,26 +25,17 @@ import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import java.math.BigDecimal; import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.*; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.CapacityGroupStatus; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.exceptions.type.BadRequestException; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.exceptions.type.NotFoundException; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.CapacityGroupRepository; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.LinkDemandRepository; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.*; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.CapacityGroupService; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.CompanyService; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.DemandCategoryService; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.UnityOfMeasureService; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.DataConverterUtil; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.UUIDUtil; import org.springframework.stereotype.Service; @@ -53,37 +44,93 @@ @Slf4j public class CapacityGroupServiceImpl implements CapacityGroupService { - private final CompanyService companyService; - - private final UnityOfMeasureService unityOfMeasureService; + private final MaterialDemandRepository materialDemandRepository; + private final CompanyRepository companyRepository; + private final CompanyService companyService; + private final LinkedCapacityGroupMaterialDemandRepository linkedCapacityGroupMaterialDemandRepository; private final CapacityGroupRepository capacityGroupRepository; - private final LinkDemandRepository linkDemandRepository; - - private final DemandCategoryService demandCategoryService; + private final DemandSeriesRepository demandSeriesRepository; + private UnitMeasure unitMeasure; @Override public CapacityGroupResponse createCapacityGroup(CapacityGroupRequest capacityGroupRequest) { - validateRequestFields(capacityGroupRequest); - CapacityGroupEntity capacityGroupEntity = enrichCapacityGroup(capacityGroupRequest); - capacityGroupEntity = capacityGroupRepository.save(capacityGroupEntity); - + for (UUID uuid : capacityGroupRequest.getLinkDemandSeriesID()) { + LinkedCapacityGroupMaterialDemandEntity entity = new LinkedCapacityGroupMaterialDemandEntity(); + entity.setCapacityGroupID(capacityGroupEntity.getId()); + entity.setMaterialDemandID(uuid); + linkedCapacityGroupMaterialDemandRepository.save(entity); + } return convertCapacityGroupDto(capacityGroupEntity); } @Override - public CapacityGroupResponse getCapacityGroupById(String capacityGroupId) { - CapacityGroupEntity capacityGroupEntity = getCapacityGroupEntity(capacityGroupId); + public void linkCapacityGroupToMaterialDemand(LinkCGDSRequest linkCGDSRequest) { + Optional optionalCapacityGroupEntity = capacityGroupRepository.findById( + UUID.fromString(linkCGDSRequest.getCapacityGroupID()) + ); - return convertCapacityGroupDto(capacityGroupEntity); + List materialDemandEntities = new ArrayList<>(); + + for (UUID uuid : linkCGDSRequest.getLinkedMaterialDemandID()) { + Optional materialDemandEntity = materialDemandRepository.findById(uuid); + if (materialDemandEntity.isPresent()) { + MaterialDemandEntity materialDemand = materialDemandEntity.get(); + materialDemandEntities.add(materialDemand); + } + } + + for (MaterialDemandEntity matEntity : materialDemandEntities) { + LinkedCapacityGroupMaterialDemandEntity entity = new LinkedCapacityGroupMaterialDemandEntity(); + if (optionalCapacityGroupEntity.isPresent()) { + CapacityGroupEntity capacityGroupEntity = optionalCapacityGroupEntity.get(); + entity.setCapacityGroupID(capacityGroupEntity.getId()); + entity.setMaterialDemandID(matEntity.getId()); + entity.setCustomerID(matEntity.getCustomerId().getId()); + entity.setMaterialNumberCustomer(matEntity.getMaterialNumberCustomer()); + entity.setMaterialNumberSupplier(matEntity.getMaterialNumberSupplier()); + + List demandSeriesList = matEntity.getDemandSeries(); + + List matchedDemandSeriesList = demandSeriesList + .stream() + .filter(d -> matEntity.getId().equals(d.getMaterialDemand().getId())) + .toList(); + + for (DemandSeries matchedDemandSeries : matchedDemandSeriesList) { + UUID demandCategoryId = matchedDemandSeries.getDemandCategory().getId(); + entity.setDemandCategoryCodeID(demandCategoryId); + matchedDemandSeries.setCapacityGroupId(capacityGroupEntity.getId().toString()); + demandSeriesRepository.save(matchedDemandSeries); + } + + linkedCapacityGroupMaterialDemandRepository.save(entity); + } + } + } + + private CapacityGroupEntity enrichCapacityGroup(CapacityGroupRequest request) { + CompanyEntity customer = companyService.getCompanyById(UUID.fromString(request.getCustomer())); + CompanyEntity supplier = companyService.getCompanyById(UUID.fromString(request.getSupplier())); + + CapacityGroupEntity capacityGroupEntity = new CapacityGroupEntity(); + capacityGroupEntity.setCapacityGroupName(request.getCapacitygroupname()); + capacityGroupEntity.setDefaultActualCapacity(request.getDefaultActualCapacity()); + capacityGroupEntity.setDefaultMaximumCapacity(request.getDefaultMaximumCapacity()); + capacityGroupEntity.setStartDate(LocalDate.parse(request.getStartDate())); + capacityGroupEntity.setEndDate(LocalDate.parse(request.getEndDate())); + capacityGroupEntity.setCustomer(customer); + capacityGroupEntity.setSupplier(supplier); + return capacityGroupEntity; } @Override - public List getAllByStatus(CapacityGroupStatus status) { - return capacityGroupRepository.findAllByStatus(status); + public CapacityGroupResponse getCapacityGroupById(String capacityGroupId) { + CapacityGroupEntity capacityGroupEntity = getCapacityGroupEntity(capacityGroupId); + return convertCapacityGroupDto(capacityGroupEntity); } @Override @@ -108,206 +155,41 @@ private CapacityGroupEntity getCapacityGroupEntity(String capacityGroupId) { return capacityGroup.get(); } - private void validateRequestFields(CapacityGroupRequest capacityGroupRequest) { - if (!UUIDUtil.checkValidUUID(capacityGroupRequest.getCustomer())) { - throw new BadRequestException( - 400, - "Not a valid customer ID", - new ArrayList<>(List.of(capacityGroupRequest.getCustomer())) - ); - } - - if (!UUIDUtil.checkValidUUID(capacityGroupRequest.getSupplier())) { - throw new BadRequestException( - 400, - "Not a valid supplier ID", - new ArrayList<>(List.of(capacityGroupRequest.getSupplier())) - ); - } - - capacityGroupRequest.getSupplierLocations().forEach(UUIDUtil::checkValidUUID); - - List expectedSuppliersLocation = capacityGroupRequest - .getSupplierLocations() - .stream() - .map(UUIDUtil::generateUUIDFromString) - .toList(); - - List companyEntities = companyService.getCompanyIn(expectedSuppliersLocation); - - boolean hasAllCompanies = companyEntities - .stream() - .map(CompanyEntity::getId) - .allMatch(expectedSuppliersLocation::contains); + private CapacityGroupResponse convertCapacityGroupDto(CapacityGroupEntity capacityGroupEntity) { + final CapacityGroupResponse responseDto = new CapacityGroupResponse(); - if (!hasAllCompanies) { - throw new BadRequestException( - 400, - "Not a valid company", - new ArrayList<>(List.of("hasCompanies returned false.")) - ); - } + final CompanyDto customer = Optional + .ofNullable(capacityGroupEntity.getCustomer()) + .map(companyService::convertEntityToDto) + .orElse(null); - List dates = capacityGroupRequest - .getCapacities() - .stream() - .map(capacityResponse -> DataConverterUtil.convertFromString(capacityResponse.getCalendarWeek())) - .toList(); - - if ( - Boolean.TRUE.equals(!DataConverterUtil.checkListAllMonday(dates)) || - Boolean.TRUE.equals(!DataConverterUtil.checkDatesSequence(dates)) - ) { - throw new BadRequestException( - 400, - "Dates provided failed to verify", - new ArrayList<>( - List.of( - "Dates need to be all Monday", - "Dates need to be aligned one week apart (Ex: monday to monday)" - ) - ) - ); - } - } + final CompanyDto supplier = Optional + .ofNullable(capacityGroupEntity.getSupplier()) + .map(companyService::convertEntityToDto) + .orElse(null); - private CapacityGroupEntity enrichCapacityGroup(CapacityGroupRequest capacityGroupRequest) { - UUID capacityGroupId = UUID.randomUUID(); - AtomicReference materialNumberCustomer = new AtomicReference<>(""); - AtomicReference materialDescriptionCustomer = new AtomicReference<>(""); - UnitMeasureEntity unitMeasure = unityOfMeasureService.findById( - UUIDUtil.generateUUIDFromString(capacityGroupRequest.getUnitOfMeasure()) + responseDto.setCapacityGroupId( + Optional.ofNullable(capacityGroupEntity.getId()).map(UUID::toString).orElse(null) ); - - CompanyEntity supplier = companyService.getCompanyById( - UUIDUtil.generateUUIDFromString(capacityGroupRequest.getSupplier()) + responseDto.setCapacitygroupname(capacityGroupEntity.getCapacityGroupName()); + responseDto.setDefaultActualCapacity(capacityGroupEntity.getDefaultActualCapacity()); + responseDto.setDefaultMaximumCapacity(capacityGroupEntity.getDefaultMaximumCapacity()); + responseDto.setStartDate( + Optional.ofNullable(capacityGroupEntity.getStartDate()).map(Object::toString).orElse(null) ); - - CompanyEntity customer = companyService.getCompanyById( - UUIDUtil.generateUUIDFromString(capacityGroupRequest.getSupplier()) + responseDto.setEndDate( + Optional.ofNullable(capacityGroupEntity.getEndDate()).map(Object::toString).orElse(null) ); - - List capacityTimeSeries = capacityGroupRequest - .getCapacities() - .stream() - .map( - capacityRequest -> - enrichCapacityTimeSeries( - LocalDate.parse(capacityRequest.getCalendarWeek()).atStartOfDay(), - capacityRequest.getActualCapacity().doubleValue(), - capacityRequest.getMaximumCapacity().doubleValue() - ) - ) - .toList(); - - List linkDemandEntityList = capacityGroupRequest - .getLinkedDemandSeries() - .stream() - .map( - s -> { - LinkDemandEntity linkDemandEntity = linkDemandRepository - .findById(UUIDUtil.generateUUIDFromString(s)) - .orElseThrow(); - - WeekBasedMaterialDemandEntity weekBasedMaterialDemandEntity = linkDemandEntity.getWeekBasedMaterialDemand(); - WeekBasedMaterialDemandRequestDto weekBasedMaterialDemandRequestDto = weekBasedMaterialDemandEntity.getWeekBasedMaterialDemand(); - CompanyEntity customerId = companyService.getCompanyById( - UUID.fromString(weekBasedMaterialDemandRequestDto.getCustomer()) - ); - - materialNumberCustomer.set(linkDemandEntity.getMaterialNumberCustomer()); - - materialDescriptionCustomer.set(linkDemandEntity.getMaterialNumberCustomer()); - - String demandCategoryId = linkDemandEntity.getDemandCategoryId(); - DemandCategoryEntity demandCategoryEntity = demandCategoryService.findById( - UUID.fromString(demandCategoryId) - ); - - linkDemandEntity.setLinked(true); - linkDemandRepository.save(linkDemandEntity); - - return LinkedDemandSeries - .builder() - .materialNumberSupplier(linkDemandEntity.getMaterialNumberSupplier()) - .materialNumberCustomer(linkDemandEntity.getMaterialNumberCustomer()) - .customerId(customerId) - .demandCategory(demandCategoryEntity) - .build(); - } - ) - .toList(); - - return CapacityGroupEntity - .builder() - .id(UUID.randomUUID()) - .capacityGroupId(capacityGroupId) - .supplierId(supplier) - .supplierLocation(capacityGroupRequest.getSupplierLocations()) - .customerId(customer) - .unitMeasure(unitMeasure) - .changedAt(LocalDateTime.now()) - .capacityTimeSeries(capacityTimeSeries) - .linkedDemandSeries(linkDemandEntityList) - .name(capacityGroupRequest.getName()) - .materialNumberCustomer(materialNumberCustomer.get()) - .materialDescriptionCustomer(materialDescriptionCustomer.get()) - .status(CapacityGroupStatus.DRAFT) - .build(); - } - - private CapacityTimeSeries enrichCapacityTimeSeries( - LocalDateTime calendarWeek, - Double actualCapacity, - Double maximumCapacity - ) { - return CapacityTimeSeries - .builder() - .id(UUID.randomUUID()) - .calendarWeek(calendarWeek) - .actualCapacity(actualCapacity) - .maximumCapacity(maximumCapacity) - .build(); - } - - private CapacityGroupResponse convertCapacityGroupDto(CapacityGroupEntity capacityGroupEntity) { - CapacityGroupResponse responseDto = new CapacityGroupResponse(); - - CompanyDto customer = companyService.convertEntityToDto(capacityGroupEntity.getCustomerId()); - CompanyDto supplier = companyService.convertEntityToDto(capacityGroupEntity.getSupplierId()); - UnitMeasure unitMeasure = enrichUnitMeasure(capacityGroupEntity.getUnitMeasure()); - responseDto.setCustomer(customer); responseDto.setSupplier(supplier); - responseDto.setUnitOfMeasure(unitMeasure); - responseDto.setChangeAt(capacityGroupEntity.getChangedAt().toString()); - responseDto.setName(capacityGroupEntity.getName()); - responseDto.setWeekBasedCapacityGroupId(capacityGroupEntity.getCapacityGroupId().toString()); - responseDto.setCapacityGroupId(capacityGroupEntity.getId().toString()); - - List capacityRequests = capacityGroupEntity - .getCapacityTimeSeries() - .stream() - .map(this::convertCapacityTimeSeries) - .toList(); - - responseDto.setCapacities(capacityRequests); - - List linkedDemandSeriesResponses = capacityGroupEntity - .getLinkedDemandSeries() - .stream() - .map(this::convertLinkedDemandSeries) - .toList(); - responseDto.setLinkedDemandSeries(linkedDemandSeriesResponses); - - List companyDtoList = capacityGroupEntity - .getSupplierLocation() - .stream() - .map(this::convertString) - .toList(); - - responseDto.setSupplierLocations(companyDtoList); - + List linkedCGMD = linkedCapacityGroupMaterialDemandRepository.findLinkedCapacityGroupMaterialDemandEntitiesByCapacityGroupID( + capacityGroupEntity.getId() + ); + List linkedDemands = new ArrayList<>(); + for (LinkedCapacityGroupMaterialDemandEntity ent : linkedCGMD) { + linkedDemands.add(ent.getMaterialDemandID()); + } + responseDto.setLinkMaterialDemandIds(linkedDemands); return responseDto; } @@ -315,8 +197,8 @@ private UnitMeasure enrichUnitMeasure(UnitMeasureEntity unitMeasureEntity) { UnitMeasure unitMeasure = new UnitMeasure(); unitMeasure.setId(unitMeasureEntity.getId().toString()); - unitMeasure.setCodeValue(unitMeasureEntity.getCodeValue()); - unitMeasure.setDisplayValue(unitMeasureEntity.getDisplayValue()); + unitMeasure.setUnCode(unitMeasureEntity.getUnCode()); + unitMeasure.setCxSymbol(unitMeasureEntity.getCxSymbol()); return unitMeasure; } @@ -370,19 +252,16 @@ private List convertCapacityGroupEntity( for (CapacityGroupEntity entity : capacityGroupEntityList) { CapacityGroupDefaultViewResponse response = new CapacityGroupDefaultViewResponse(); - response.setName(entity.getName()); - response.setStatus(entity.getStatus().toString()); - response.setSupplierBNPL(entity.getSupplierId().getBpn()); - response.setCustomerName(entity.getCustomerId().getCompanyName()); - response.setCustomerBPNL(entity.getCustomerId().getBpn()); + response.setName(entity.getCapacityGroupName()); + response.setSupplierBNPL(entity.getSupplier().getBpn()); + response.setCustomerName(entity.getCustomer().getCompanyName()); + response.setCustomerBPNL(entity.getCustomer().getBpn()); response.setInternalId(entity.getId().toString()); - response.setNumberOfMaterials(new BigDecimal(entity.getCapacityTimeSeries().size())); - //response.setFavoritedBy(); - //response.setCatXUuid(); - + response.setNumberOfMaterials( + linkedCapacityGroupMaterialDemandRepository.countByCapacityGroupID(entity.getId()) + ); capacityGroupList.add(response); } - return capacityGroupList; } } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/DemandServiceImpl.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/DemandServiceImpl.java index a00067e9..84ac205f 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/DemandServiceImpl.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/DemandServiceImpl.java @@ -36,11 +36,10 @@ import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.MaterialDemandStatus; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.exceptions.type.BadRequestException; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.exceptions.type.NotFoundException; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.DemandSeriesRepository; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.LinkedCapacityGroupMaterialDemandRepository; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.MaterialDemandRepository; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.CompanyService; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.DemandCategoryService; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.DemandService; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.UnityOfMeasureService; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.*; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.DataConverterUtil; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.UUIDUtil; import org.springframework.stereotype.Service; @@ -58,6 +57,10 @@ public class DemandServiceImpl implements DemandService { private final DemandCategoryService demandCategoryService; + private final DemandSeriesRepository demandSeriesRepository; + + private final LinkedCapacityGroupMaterialDemandRepository linkedCapacityGroupMaterialDemandRepository; + @Override public MaterialDemandResponse createDemand(MaterialDemandRequest materialDemandRequest) { validateMaterialDemandRequestFields(materialDemandRequest); @@ -103,6 +106,74 @@ public List getAllByStatus(MaterialDemandStatus status) { return materialDemandRepository.findAllByStatus(status); } + @Override + public DemandSeriesCompositeResponse getAllDemandsByCompositeKey( + DemandSeriesCompositeRequest demandSeriesCompositeRequest + ) { + List demandSeriesEntities = demandSeriesRepository.ByCategoryIDCustomerIDMaterialNrCustomer( + UUID.fromString(demandSeriesCompositeRequest.getCustomerID()), + UUID.fromString(demandSeriesCompositeRequest.getDemandCategoryCodeID()), + demandSeriesCompositeRequest.getMaterialNumberCustomer() + ); + + DemandSeriesCompositeResponse demandSeriesCompositeResponse = new DemandSeriesCompositeResponse(); + List linkedDemandMaterialCompositeResponses = new ArrayList<>(); + + for (DemandSeries demandSeries : demandSeriesEntities) { + LinkedDemandMaterialCompositeResponse compositeResponse = new LinkedDemandMaterialCompositeResponse(); + + DemandCategoryResponse demandCategory = demandCategoryService.convertEntityToDto( + demandCategoryService.findById(demandSeries.getDemandCategory().getId()) + ); + compositeResponse.setDemandCategory(demandCategory); + + Optional materialDemand = materialDemandRepository.findById( + demandSeries.getMaterialDemand().getId() + ); + if (materialDemand.isPresent()) { + MaterialDemandResponse materialDemandResponse = convertDemandResponseDto(materialDemand.get()); + compositeResponse.setMaterialDemandID(materialDemandResponse.getId()); + compositeResponse.setCustomerLocation(materialDemandResponse.getCustomer()); + List supplierLocations = new ArrayList<>(); + for (String locations : demandSeries.getExpectedSupplierLocation()) { + CompanyEntity entity = companyService.getCompanyById(UUID.fromString(locations)); + CompanyDto companyDto = new CompanyDto(); + companyDto.setBpn(entity.getBpn()); + companyDto.setCompanyName(entity.getCompanyName()); + companyDto.setId(entity.getId().toString()); + companyDto.setMyCompany(entity.getMyCompany()); + companyDto.setCountry(entity.getCountry()); + companyDto.setNumber(entity.getNumber()); + companyDto.setStreet(entity.getStreet()); + companyDto.setZipCode(entity.getZipCode()); + supplierLocations.add(companyDto); + } + compositeResponse.setExpectedSupplierLocation(supplierLocations); + } + + List materialDemandSeriesValues = new ArrayList<>(); + + for (DemandSeriesValues values : demandSeries.getDemandSeriesValues()) { + MaterialDemandSeriesValue demandSeriesValue = new MaterialDemandSeriesValue(); + demandSeriesValue.setDemand(BigDecimal.valueOf(values.getDemand())); + demandSeriesValue.setCalendarWeek(values.getCalendarWeek().toString()); + materialDemandSeriesValues.add(demandSeriesValue); + } + compositeResponse.setDemandSeriesValues(materialDemandSeriesValues); + compositeResponse.setDemandSeriesID(demandSeries.getId().toString()); + linkedDemandMaterialCompositeResponses.add(compositeResponse); + } + demandSeriesCompositeResponse.setDemandSeries(linkedDemandMaterialCompositeResponses); + return demandSeriesCompositeResponse; + } + + @Override + public void unlinkComposites(DemandSeriesUnlinkRequest demandSeriesUnlinkRequest) { + UUID cgID = UUID.fromString(demandSeriesUnlinkRequest.getCapacityGroupID()); + UUID mdID = UUID.fromString(demandSeriesUnlinkRequest.getMaterialDemandID()); + linkedCapacityGroupMaterialDemandRepository.deleteByCapacityGroupIDAndMaterialDemandID(cgID, mdID); + } + private MaterialDemandEntity getDemandEntity(String demandId) { UUIDUtil.checkValidUUID(demandId); UUID uuid = UUIDUtil.generateUUIDFromString(demandId); @@ -122,8 +193,15 @@ private MaterialDemandEntity getDemandEntity(String demandId) { private MaterialDemandResponse convertDemandResponseDto(MaterialDemandEntity materialDemandEntity) { MaterialDemandResponse responseDto = new MaterialDemandResponse(); - CompanyDto customer = companyService.convertEntityToDto(materialDemandEntity.getCustomerId()); - CompanyDto supplier = companyService.convertEntityToDto(materialDemandEntity.getSupplierId()); + CompanyDto customer = null; + if (materialDemandEntity.getCustomerId() != null) { + customer = companyService.convertEntityToDto(materialDemandEntity.getCustomerId()); + } + + CompanyDto supplier = null; + if (materialDemandEntity.getSupplierId() != null) { + supplier = companyService.convertEntityToDto(materialDemandEntity.getSupplierId()); + } responseDto.setMaterialDescriptionCustomer(materialDemandEntity.getMaterialDescriptionCustomer()); responseDto.setMaterialNumberCustomer(materialDemandEntity.getMaterialNumberCustomer()); @@ -356,8 +434,12 @@ private UnitMeasure enrichUnitMeasure(UnitMeasureEntity unitMeasureEntity) { UnitMeasure unitMeasure = new UnitMeasure(); unitMeasure.setId(unitMeasureEntity.getId().toString()); - unitMeasure.setCodeValue(unitMeasureEntity.getCodeValue()); - unitMeasure.setDisplayValue(unitMeasureEntity.getDisplayValue()); + unitMeasure.setDimension(unitMeasureEntity.getDimension()); + unitMeasure.setUnCode(unitMeasureEntity.getUnCode()); + unitMeasure.setDescription(unitMeasureEntity.getDescription()); + unitMeasure.setDescriptionGerman(unitMeasureEntity.getDescriptionGerman()); + unitMeasure.setUnSymbol(unitMeasureEntity.getUnSymbol()); + unitMeasure.setCxSymbol(unitMeasureEntity.getCxSymbol()); return unitMeasure; } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/FavoriteServiceImpl.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/FavoriteServiceImpl.java index b4e84c59..4b92f1d8 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/FavoriteServiceImpl.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/FavoriteServiceImpl.java @@ -66,9 +66,9 @@ public FavoriteResponse createFavorite(FavoriteRequest favoriteRequest) { @Override public FavoriteResponse updateFavorite(UUID id, FavoriteType type, FavoriteRequest favoriteRequest) { FavoriteEntity entity = favoriteRepository.findByFavoriteIdAndTypeAndId( - id, - type, - UUID.fromString("8842f835-38e9-42b1-8c07-fb310b90ef3a") + id, + type, + UUID.fromString("8842f835-38e9-42b1-8c07-fb310b90ef3a") ); //TODO FETCH USER ID TO UPDATE OPERATION if (entity != null) { @@ -76,13 +76,11 @@ public FavoriteResponse updateFavorite(UUID id, FavoriteType type, FavoriteReque entity.setType(FavoriteType.valueOf(favoriteRequest.getfType())); favoriteRepository.saveAndFlush(entity); return convertFavoriteResponse(entity); - } else throw new NotFoundException( 404, "Demand category not found", new ArrayList<>(List.of("provided UUID did not match any records. - " + id)) ); - } @Override @@ -100,10 +98,10 @@ private FavoriteResponse convertFavoriteResponse(FavoriteEntity request) { private FavoriteEntity generateFavoriteEntity(FavoriteRequest request) { return FavoriteEntity - .builder() - .id(UUID.randomUUID()) //TODO USER ID HERE - .favoriteId(UUID.fromString(request.getFavoriteId())) - .type(FavoriteType.valueOf(request.getfType())) - .build(); + .builder() + .id(UUID.randomUUID()) //TODO USER ID HERE + .favoriteId(UUID.fromString(request.getFavoriteId())) + .type(FavoriteType.valueOf(request.getfType())) + .build(); } -} \ No newline at end of file +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/StatusesServiceImpl.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/StatusesServiceImpl.java new file mode 100644 index 00000000..7e4c8965 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/StatusesServiceImpl.java @@ -0,0 +1,578 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.impl; + +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; +import java.time.LocalDateTime; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.StatusObjectEntity; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.StatusesEntity; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.EventType; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.StatusColor; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.StatusesRepository; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.StatusesService; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.DataConverterUtil; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.StatusManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +@Lazy +public class StatusesServiceImpl implements StatusesService { + + @Autowired + private final StatusesRepository statusesRepository; + + List oldWeekBasedCapacityGroupResponse; + List newWeekBasedCapacityGroupResponse; + List newWeekBasedMaterialDemandResponse; + List oldWeekBasedMaterialDemandResponse; + + int materialDemandOrder = 0; + + public StatusesServiceImpl( + StatusesRepository statusesRepository, + List oldWeekBasedMaterialDemandResponse, + List newWeekBasedMaterialDemandResponse, + List oldWeekBasedCapacityGroupResponse, + List newWeekBasedCapacityGroupResponse + ) { + this.statusesRepository = statusesRepository; + this.oldWeekBasedMaterialDemandResponse = oldWeekBasedMaterialDemandResponse; + this.newWeekBasedMaterialDemandResponse = newWeekBasedMaterialDemandResponse; + this.oldWeekBasedCapacityGroupResponse = oldWeekBasedCapacityGroupResponse; + this.newWeekBasedCapacityGroupResponse = newWeekBasedCapacityGroupResponse; + } + + @Override + public StatusesResponse postStatuses(StatusRequest statusRequest) { + StatusesEntity statusesEntity = convertDtoToEntity(statusRequest); + statusesRepository.save(statusesEntity); + return convertStatusesResponseDto(statusesEntity); + } + + // TODO: remove the hardcoded id + private StatusesEntity convertDtoToEntity(StatusRequest statusRequest) { + StatusObjectEntity todos = StatusObjectEntity + .builder() + .id(UUID.fromString("21c10efa-9a75-4da9-9ef9-589d3a54b2ab")) + .count(statusRequest.getTodos().getCount()) + .build(); + + StatusObjectEntity general = StatusObjectEntity + .builder() + .id(UUID.fromString("526cf84f-6be3-4b06-9fd5-9da276ab6f32")) + .count(statusRequest.getGeneral().getCount()) + .build(); + + StatusObjectEntity statusImprovement = StatusObjectEntity + .builder() + .id(UUID.fromString("a10f808a-52e0-4375-ac1b-19eba4523c72")) + .count(statusRequest.getStatusImprovement().getCount()) + .build(); + + StatusObjectEntity statusDegredation = StatusObjectEntity + .builder() + .id(UUID.fromString("aeeab6ed-cdb1-434f-8886-f065ac5dafc0")) + .count(statusRequest.getStatusDegredation().getCount()) + .build(); + + StatusObjectEntity overAllTodos = StatusObjectEntity + .builder() + .id(UUID.fromString("9e2e6aaf-5a39-4162-b101-e18813616b74")) + .count(statusRequest.getOverallTodos().getCount()) + .build(); + + StatusObjectEntity overAllStatusDegredation = StatusObjectEntity + .builder() + .id(UUID.fromString("9e2e6aaf-5a39-4162-b101-e18813616b73")) + .count(statusRequest.getOverallStatusDegredation().getCount()) + .build(); + + StatusObjectEntity overAllStatusImprovment = StatusObjectEntity + .builder() + .id(UUID.fromString("9e2e6aaf-5a39-4162-b101-e18813616b72")) + .count(statusRequest.getOverallStatusImprovement().getCount()) + .build(); + + StatusObjectEntity overAllGeneral = StatusObjectEntity + .builder() + .id(UUID.fromString("9e2e6aaf-5a39-4162-b101-e18813616b71")) + .count(statusRequest.getOverallGeneral().getCount()) + .build(); + + return StatusesEntity + .builder() + .id(UUID.fromString("9e2e6aaf-5a39-4162-b101-e18813616b70")) + .todos(todos) + .general(general) + .statusImprovment(statusImprovement) + .statusDegredation(statusDegredation) + .overAllStatusDegredation(overAllStatusDegredation) + .overAllGeneral(overAllGeneral) + .overAllStatusImprovment(overAllStatusImprovment) + .overAllTodos(overAllTodos) + .build(); + } + + @Override + public StatusesResponse getAllStatuses() { + List statusesEntities = statusesRepository.findAll(); + if (statusesEntities.isEmpty()) { + StatusDto zeroCountStatus = new StatusDto(); + zeroCountStatus.setCount(0); + return new StatusesResponse(); + } + return statusesEntities.stream().map(this::convertStatusesResponseDto).toList().get(0); + } + + private StatusesResponse convertStatusesResponseDto(StatusesEntity statusesEntity) { + StatusesResponse responseDto = new StatusesResponse(); + StatusDto todos = new StatusDto(); + StatusDto general = new StatusDto(); + StatusDto statusImprovement = new StatusDto(); + StatusDto statusDegredation = new StatusDto(); + + StatusDto overallGeneral = new StatusDto(); + StatusDto overallTodos = new StatusDto(); + StatusDto overallStatusImprovement = new StatusDto(); + StatusDto overallStatusDegredation = new StatusDto(); + + todos.setCount(statusesEntity.getTodos().getCount()); + + general.setCount(statusesEntity.getGeneral().getCount()); + + statusImprovement.setCount(statusesEntity.getStatusImprovment().getCount()); + + statusDegredation.setCount(statusesEntity.getStatusDegredation().getCount()); + overallGeneral.setCount(statusesEntity.getOverAllGeneral().getCount()); + overallTodos.setCount(statusesEntity.getOverAllTodos().getCount()); + overallStatusImprovement.setCount(statusesEntity.getOverAllStatusImprovment().getCount()); + overallStatusDegredation.setCount(statusesEntity.getOverAllStatusDegredation().getCount()); + + responseDto.setTodos(todos); + responseDto.setGeneral(general); + responseDto.setStatusImprovement(statusImprovement); + responseDto.setStatusDegredation(statusDegredation); + responseDto.setOverallGeneral(overallGeneral); + responseDto.setOverallTodos(overallTodos); + responseDto.setOverallStatusImprovement(overallStatusImprovement); + responseDto.setOverallStatusDegredation(overallStatusDegredation); + + return responseDto; + } + + // TODO : Saja Add these methods + // private EventType getStatusForMaterialDemand(){ + // EventType eventType; + // if(eventType == EventType.TODO){ + // return EventType.TODO; + // } + // return EventType.LINKED; + // } + // + // private EventType getStatusForCapacityGroup(){ + // EventType eventType; + // if(eventType == EventType.STATUS_IMPROVEMENT){ + // return EventType.TODO; + // } + // return EventType.STATUS_REDUCTION; + // } + + @Override + public void updateStatus() { + saveStatusesData(); + } + + public void saveStatusesData() { + StatusRequest statusRequest = new StatusRequest(); + + List oldCapacityQuantities = new ArrayList<>(); + List newCapacityQuantities = new ArrayList<>(); + + AtomicInteger todoCount = new AtomicInteger(); + AtomicInteger generalCount = new AtomicInteger(); + AtomicInteger statusImprovementCount = new AtomicInteger(); + AtomicInteger statusReductionCount = new AtomicInteger(); + AtomicInteger allDemandsCount = new AtomicInteger(); + AtomicInteger overAllGeneralCount = new AtomicInteger(); + AtomicInteger overAllStatusImprovementCount = new AtomicInteger(); + AtomicInteger overAllStatusReductionCount = new AtomicInteger(); + AtomicInteger overAllTodoCount = new AtomicInteger(); + + Map> oldMaterialNumberCapacitiesMapList = createMaterialNumberCapacitiesMapList( + oldWeekBasedCapacityGroupResponse + ); + Map> newMaterialNumberCapacitiesMapList = createMaterialNumberCapacitiesMapList( + newWeekBasedCapacityGroupResponse + ); + + Map> oldMaterialNumberDemandsMapList = createMaterialNumberDemandsMapList( + oldWeekBasedMaterialDemandResponse + ); + Map> newMaterialNumberDemandsMapList = createMaterialNumberDemandsMapList( + newWeekBasedMaterialDemandResponse + ); + + processMaterialDemands( + todoCount, + overAllTodoCount, + true, + newCapacityQuantities, + newMaterialNumberDemandsMapList, + newMaterialNumberCapacitiesMapList + ); + + processMaterialDemands( + todoCount, + overAllTodoCount, + false, + oldCapacityQuantities, + oldMaterialNumberDemandsMapList, + oldMaterialNumberCapacitiesMapList + ); + + processCapacityQuantities( + oldCapacityQuantities, + newCapacityQuantities, + statusReductionCount, + statusImprovementCount, + overAllStatusReductionCount, + overAllStatusImprovementCount + ); + + setAllDemandsCountCount(allDemandsCount, newMaterialNumberDemandsMapList); + + // set the general count + generalCount.set( + allDemandsCount.get() - (todoCount.get() + statusImprovementCount.get() + statusReductionCount.get()) + ); + + overAllGeneralCount.set( + newMaterialNumberDemandsMapList.size() - + (overAllTodoCount.get() + overAllStatusImprovementCount.get() + overAllStatusReductionCount.get()) + ); + + StatusDto todos = new StatusDto(); + todos.setCount(todoCount.get()); + + StatusDto generalStatusDto = new StatusDto(); + generalStatusDto.setCount(generalCount.get()); + + StatusDto improvementStatusDto = new StatusDto(); + improvementStatusDto.setCount(statusImprovementCount.get()); + + StatusDto degradationStatusDto = new StatusDto(); + degradationStatusDto.setCount(statusReductionCount.get()); + + StatusDto overAllTodos = new StatusDto(); + overAllTodos.setCount(overAllTodoCount.get()); + + StatusDto overAllGeneralStatusDto = new StatusDto(); + overAllGeneralStatusDto.setCount(overAllGeneralCount.get()); + + StatusDto overAllImprovementStatusDto = new StatusDto(); + overAllImprovementStatusDto.setCount(overAllStatusImprovementCount.get()); + + StatusDto overAllDegradationStatusDto = new StatusDto(); + overAllDegradationStatusDto.setCount(overAllStatusReductionCount.get()); + + // Set DTOs in StatusRequest + statusRequest.setTodos(todos); + statusRequest.setGeneral(generalStatusDto); + statusRequest.setStatusImprovement(improvementStatusDto); + statusRequest.setStatusDegredation(degradationStatusDto); + statusRequest.setOverallTodos(overAllTodos); + statusRequest.setOverallGeneral(overAllGeneralStatusDto); + statusRequest.setOverallStatusImprovement(overAllImprovementStatusDto); + statusRequest.setOverallStatusDegredation(overAllDegradationStatusDto); + + // Post the StatusRequest + postStatuses(statusRequest); + } + + private Map> createMaterialNumberDemandsMapList( + List weekBasedMaterialDemandEntities + ) { + Map> materialNumberDemandsMapList = new HashMap<>(); + + weekBasedMaterialDemandEntities.forEach( + weekBasedMaterialDemand -> { + // weekBasedMaterialDemand.getId() + String materialNumberCustomer = weekBasedMaterialDemand + .getWeekBasedMaterialDemandRequest() + .getMaterialNumberCustomer(); + + weekBasedMaterialDemand + .getWeekBasedMaterialDemandRequest() + .getDemandSeries() + .forEach( + demandWeekSeriesDto -> + materialNumberDemandsMapList.put(materialNumberCustomer, demandWeekSeriesDto.getDemands()) + ); + } + ); + return materialNumberDemandsMapList; + } + + private Map> createMaterialNumberCapacitiesMapList( + List weekBasedCapacityGroupEntities + ) { + Map> materialNumberCapacitiesMap = new HashMap<>(); + + weekBasedCapacityGroupEntities.forEach( + weekBasedCapacityGroup -> { + // weekBasedCapacityGroup.getId(); + + List capacitiesDtos = weekBasedCapacityGroup + .getWeekBasedCapacityGroupRequest() + .getCapacities(); + weekBasedCapacityGroup + .getWeekBasedCapacityGroupRequest() + .getLinkedDemandSeries() + .forEach( + linkedDemandSeriesRequest -> + materialNumberCapacitiesMap.put( + linkedDemandSeriesRequest.getMaterialNumberCustomer(), + capacitiesDtos + ) + ); + } + ); + return materialNumberCapacitiesMap; + } + + private void setAllDemandsCountCount( + AtomicInteger allDemandsCount, + Map> materialNumberDemandsMap + ) { + for (Map.Entry> materialNumberDemandsMapEntry : materialNumberDemandsMap.entrySet()) { + allDemandsCount.set(allDemandsCount.get() + materialNumberDemandsMapEntry.getValue().size()); + } + } + + private void processMaterialDemands( + AtomicInteger todoCount, + AtomicInteger overAllTodoCount, + boolean isNewMaterialDemands, + List capacityQuantities, + Map> materialNumberDemandsMap, + Map> materialNumberCapacitiesMap + ) { + for (Map.Entry> materialNumberDemandsMapEntry : materialNumberDemandsMap.entrySet()) { + if ( + !materialNumberCapacitiesMap.containsKey(materialNumberDemandsMapEntry.getKey()) && isNewMaterialDemands + ) { + overAllTodoCount.incrementAndGet(); + } + materialDemandOrder++; + materialNumberDemandsMapEntry + .getValue() + .forEach( + demandSeriesDto -> { + if ( + !materialNumberCapacitiesMap.containsKey(materialNumberDemandsMapEntry.getKey()) && + isNewMaterialDemands + ) { + todoCount.incrementAndGet(); + } + for (Map.Entry> materialNumberCapacitiesMapEntry : materialNumberCapacitiesMap.entrySet()) { + if ( + materialNumberDemandsMapEntry.getKey().equals(materialNumberCapacitiesMapEntry.getKey()) + ) { + materialNumberCapacitiesMapEntry + .getValue() + .forEach( + capacitiesDto -> { + if ( + capacitiesDto + .getCalendarWeek() + .equals(demandSeriesDto.getCalendarWeek()) + ) { + capacityQuantities.add( + new MaterialCapacityQuantity( + Double.parseDouble(capacitiesDto.getMaximumCapacity()), + Double.parseDouble(capacitiesDto.getActualCapacity()), + DataConverterUtil.convertFromString( + capacitiesDto.getCalendarWeek() + ), + Double.parseDouble(demandSeriesDto.getDemand()), + materialDemandOrder + ) + ); + } + } + ); + } + } + } + ); + } + } + + // Helper method to process old and new capacity quantities and update status lists + private void processCapacityQuantities( + List oldMaterialCapacityQuantities, + List newMaterialCapacityQuantities, + AtomicInteger statusReductionCount, + AtomicInteger statusImprovementCount, + AtomicInteger overAllStatusReductionCount, + AtomicInteger overAllStatusImprovementCount + ) { + AtomicInteger previousDemand = new AtomicInteger(-1); + oldMaterialCapacityQuantities.forEach( + oldCapacityQuantity -> + newMaterialCapacityQuantities.forEach( + newCapacityQuantity -> { + if ( + oldCapacityQuantity.getCalendarWeek().getDayOfYear() == + newCapacityQuantity.calendarWeek.getDayOfYear() + ) { + EventType eventType = getEventType(oldCapacityQuantity, newCapacityQuantity); + + if (eventType == EventType.STATUS_REDUCTION) { + if ( + previousDemand.get() == -1 || + previousDemand.get() != newCapacityQuantity.getMaterialDemandOrder() + ) { + overAllStatusReductionCount.set(overAllStatusReductionCount.get() + 1); + } + statusReductionCount.set(statusReductionCount.get() + 1); + } else if (eventType == EventType.STATUS_IMPROVEMENT) { + if ( + previousDemand.get() != -1 || + previousDemand.get() != newCapacityQuantity.getMaterialDemandOrder() + ) { + overAllStatusImprovementCount.set(overAllStatusImprovementCount.get() + 1); + } + statusImprovementCount.set(statusImprovementCount.get() + 1); + } + previousDemand.set(newCapacityQuantity.getMaterialDemandOrder()); + } + } + ) + ); + } + + private static EventType getEventType( + MaterialCapacityQuantity oldCapacityQuantity, + MaterialCapacityQuantity newCapacityQuantity + ) { + StatusColor oldStatusColor = StatusManager.getStatusColor( + oldCapacityQuantity.getDemand(), + oldCapacityQuantity.getMaximumCapacity(), + oldCapacityQuantity.getActualCapacity() + ); + StatusColor newStatusColor = StatusManager.getStatusColor( + newCapacityQuantity.getDemand(), + newCapacityQuantity.getMaximumCapacity(), + newCapacityQuantity.getActualCapacity() + ); + + return StatusManager.getEventType(true, oldStatusColor, newStatusColor); + } + + public static class MaterialCapacityQuantity { + + private double maximumCapacity; + private double actualCapacity; + private LocalDateTime calendarWeek; + private double demand; + + private int materialDemandOrder; + + public MaterialCapacityQuantity( + double maximumCapacity, + double actualCapacity, + LocalDateTime calendarWeek, + double demand, + int materialDemandOrder + ) { + this.maximumCapacity = maximumCapacity; + this.actualCapacity = actualCapacity; + this.calendarWeek = calendarWeek; + this.demand = demand; + this.materialDemandOrder = materialDemandOrder; + } + + public double getMaximumCapacity() { + return maximumCapacity; + } + + public void setMaximumCapacity(double maximumCapacity) { + this.maximumCapacity = maximumCapacity; + } + + public double getActualCapacity() { + return actualCapacity; + } + + public int getMaterialDemandOrder() { + return materialDemandOrder; + } + + public void setActualCapacity(double actualCapacity) { + this.actualCapacity = actualCapacity; + } + + public LocalDateTime getCalendarWeek() { + return calendarWeek; + } + + public void setCalendarWeek(LocalDateTime calendarWeek) { + this.calendarWeek = calendarWeek; + } + + public double getDemand() { + return demand; + } + + public void setDemand(double demand) { + this.demand = demand; + } + + public void setMaterialDemandOrder(int materialDemandOrder) { + this.materialDemandOrder = materialDemandOrder; + } + + @Override + public String toString() { + return ( + "MaterialCapacityQuantity{" + + "maximumCapacity=" + + maximumCapacity + + ", actualCapacity=" + + actualCapacity + + ", calendarWeek=" + + calendarWeek + + ", demand=" + + demand + + '}' + ); + } + } +} diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/UnityOfMeasureServiceImpl.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/UnityOfMeasureServiceImpl.java index 5d46c847..d04bed40 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/UnityOfMeasureServiceImpl.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/UnityOfMeasureServiceImpl.java @@ -31,7 +31,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.UnitMeasureEntity; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.exceptions.type.NotFoundException; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.exceptions.type.BadRequestException; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.UnitMeasureRepository; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.UnityOfMeasureService; import org.springframework.stereotype.Service; @@ -48,10 +48,10 @@ public UnitMeasureEntity findById(UUID id) { Optional unitMeasure = unitMeasureRepository.findById(id); if (unitMeasure.isEmpty()) { - throw new NotFoundException( + throw new BadRequestException( 404, - "The unit of measure was not found in DB.", - new ArrayList<>(List.of("Provided ID : " + id)) + "Unit of measure not found", + new ArrayList<>(List.of("unit of measure could not be retrieved by DB")) ); } return unitMeasure.get(); @@ -69,8 +69,12 @@ public UnitMeasure convertEntityToDto(UnitMeasureEntity unitMeasureEntity) { UnitMeasure unitMeasure = new UnitMeasure(); unitMeasure.setId(String.valueOf(unitMeasureEntity.getId())); - unitMeasure.setDisplayValue(unitMeasureEntity.getDisplayValue()); - unitMeasure.setCodeValue(unitMeasureEntity.getCodeValue()); + unitMeasure.setDimension(unitMeasureEntity.getDimension()); + unitMeasure.setUnCode(unitMeasureEntity.getUnCode()); + unitMeasure.setDescription(unitMeasureEntity.getDescription()); + unitMeasure.setDescriptionGerman(unitMeasureEntity.getDescriptionGerman()); + unitMeasure.setUnSymbol(unitMeasureEntity.getUnSymbol()); + unitMeasure.setCxSymbol(unitMeasureEntity.getCxSymbol()); return unitMeasure; } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/WeekBasedCapacityGroupServiceImpl.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/WeekBasedCapacityGroupServiceImpl.java index 2da42195..ab060400 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/WeekBasedCapacityGroupServiceImpl.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/WeekBasedCapacityGroupServiceImpl.java @@ -22,49 +22,78 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.impl; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacitiesDto; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.DemandCategoryDto; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.LinkedDemandSeriesRequest; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedCapacityGroupRequest; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.*; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.CapacityGroupStatus; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.exceptions.type.BadRequestException; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.exceptions.type.NotFoundException; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.MaterialDemandRepository; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.StatusesRepository; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.WeekBasedCapacityGroupRepository; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.WeekBasedMaterialDemandRepository; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.CapacityGroupService; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.StatusesService; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.WeekBasedCapacityGroupService; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.DataConverterUtil; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.UUIDUtil; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.springframework.web.client.RestTemplate; @RequiredArgsConstructor @Service @Slf4j public class WeekBasedCapacityGroupServiceImpl implements WeekBasedCapacityGroupService { + private final StatusesRepository statusesRepository; + private final WeekBasedCapacityGroupRepository weekBasedCapacityGroupRepository; private final CapacityGroupService capacityGroupService; private final MaterialDemandRepository materialDemandRepository; + private static List oldWeekBasedCapacityGroups; + private static List newWeekBasedCapacityGroups; + + private final WeekBasedMaterialDemandRepository weekBasedMaterialDemandRepository; + @Override - public void createWeekBasedCapacityGroup(List weekBasedCapacityGroupRequestList) { + public void createWeekBasedCapacityGroup(List weekBasedCapacityGroupRequestList) { weekBasedCapacityGroupRequestList.forEach( weekBasedCapacityGroupRequest -> { - validateFields(weekBasedCapacityGroupRequest); - - WeekBasedCapacityGroupEntity weekBasedCapacityGroup = convertEntity(weekBasedCapacityGroupRequest); + validateFields(weekBasedCapacityGroupRequest.getWeekBasedCapacityGroupRequest()); + WeekBasedCapacityGroupEntity weekBasedCapacityGroup = convertEntity( + weekBasedCapacityGroupRequest.getWeekBasedCapacityGroupRequest() + ); weekBasedCapacityGroupRepository.save(weekBasedCapacityGroup); } ); + oldWeekBasedCapacityGroups = + DataConverterUtil.convertToWeekBasedCapacityGroupDtoList(weekBasedCapacityGroupRepository.findAll()); + updateStatus(); + } + + public void updateStatus() { + if (statusesRepository != null) { + List oldWeekBasedMaterialDemands = DataConverterUtil.convertToWeekBasedMaterialDemandDtoList( + weekBasedMaterialDemandRepository.findAll() + ); + if (newWeekBasedCapacityGroups == null) { + newWeekBasedCapacityGroups = List.of(); + } + final StatusesService statusesService = new StatusesServiceImpl( + statusesRepository, + oldWeekBasedMaterialDemands, + oldWeekBasedMaterialDemands, + oldWeekBasedCapacityGroups, + newWeekBasedCapacityGroups + ); + statusesService.updateStatus(); + } } @Override @@ -111,6 +140,12 @@ public void receiveWeekBasedCapacityGroup() { } } ); + // updateStatus(); TODO: remove the comment when the EDC is ready + } + + @Override + public List getWeekBasedCapacityGroups() { + return DataConverterUtil.convertToWeekBasedCapacityGroupDtoList(weekBasedCapacityGroupRepository.findAll()); } @Override @@ -120,28 +155,81 @@ public void sendWeekBasedCapacityGroup() {} public void createWeekBasedCapacityGroupRequestFromEntity(CapacityGroupEntity capacityGroupEntity) { WeekBasedCapacityGroupRequest basedCapacityGroupRequest = new WeekBasedCapacityGroupRequest(); - basedCapacityGroupRequest.setCapacityGroupId(capacityGroupEntity.getCapacityGroupId().toString()); - basedCapacityGroupRequest.setUnityOfMeasure(capacityGroupEntity.getUnitMeasure().getCodeValue()); - basedCapacityGroupRequest.setCustomer(capacityGroupEntity.getCustomerId().getBpn()); - basedCapacityGroupRequest.setSupplier(capacityGroupEntity.getSupplierId().getBpn()); - basedCapacityGroupRequest.setName(capacityGroupEntity.getName()); - basedCapacityGroupRequest.setChangedAt(capacityGroupEntity.getChangedAt().toString()); - basedCapacityGroupRequest.setSupplierLocations(capacityGroupEntity.getSupplierLocation()); - - List linkedDemandSeries = capacityGroupEntity - .getLinkedDemandSeries() - .stream() - .map(WeekBasedCapacityGroupServiceImpl::getLinkedDemandSeries) - .toList(); - basedCapacityGroupRequest.setLinkedDemandSeries(linkedDemandSeries); - - List capacitiesDtos = capacityGroupEntity - .getCapacityTimeSeries() - .stream() - .map(WeekBasedCapacityGroupServiceImpl::getCapacitiesDto) - .toList(); - - basedCapacityGroupRequest.setCapacities(capacitiesDtos); + basedCapacityGroupRequest.setCapacityGroupId(capacityGroupEntity.getId().toString()); + // basedCapacityGroupRequest.setUnityOfMeasure(capacityGroupEntity.getUnitMeasure().getCodeValue()); + basedCapacityGroupRequest.setCustomer(capacityGroupEntity.getCustomer().getBpn()); + // basedCapacityGroupRequest.setCustomer(capacityGroupEntity.getCustomerId().getBpn()); + basedCapacityGroupRequest.setSupplier(capacityGroupEntity.getSupplier().getBpn()); + basedCapacityGroupRequest.setName(capacityGroupEntity.getCapacityGroupName()); + // basedCapacityGroupRequest.setChangedAt(capacityGroupEntity.getChangedAt().toString()); + // basedCapacityGroupRequest.setSupplierLocations(capacityGroupEntity.getSupplierLocation()); + + // List linkedDemandSeries = capacityGroupEntity + // .getLinkedDemandSeries() + // .stream() + // .map(WeekBasedCapacityGroupServiceImpl::getLinkedDemandSeries) + // .toList(); + // basedCapacityGroupRequest.setLinkedDemandSeries(linkedDemandSeries); + // + // List capacitiesDtos = capacityGroupEntity + // .getCapacityTimeSeries() + // .stream() + // .map(WeekBasedCapacityGroupServiceImpl::getCapacitiesDto) + // .toList(); + // + // basedCapacityGroupRequest.setCapacities(capacitiesDtos); + updateStatus(); + } + + @Override + public WeekBasedCapacityGroupDtoResponse updateWeekBasedCapacityGroup( + String id, + WeekBasedCapacityGroupDtoRequest weekBasedCapacityGroupRequest + ) { + oldWeekBasedCapacityGroups = + DataConverterUtil.convertToWeekBasedCapacityGroupDtoList(weekBasedCapacityGroupRepository.findAll()); + WeekBasedCapacityGroupEntity weekBasedCapacityGroupEntity = convertWeekMaterialDemandToEntity( + weekBasedCapacityGroupRequest + ); + weekBasedCapacityGroupEntity.setId(UUID.fromString(id)); + weekBasedCapacityGroupEntity = weekBasedCapacityGroupRepository.save(weekBasedCapacityGroupEntity); + newWeekBasedCapacityGroups = + DataConverterUtil.convertToWeekBasedCapacityGroupDtoList(weekBasedCapacityGroupRepository.findAll()); + updateStatus(); + return convertToWeekBasedCapacityGroupDto(weekBasedCapacityGroupEntity); + } + + private WeekBasedCapacityGroupEntity convertWeekMaterialDemandToEntity( + WeekBasedCapacityGroupDtoRequest weekBasedCapacityGroupResponses + ) { + WeekBasedCapacityGroupEntity weekBasedCapacityGroupEntity = new WeekBasedCapacityGroupEntity(); + weekBasedCapacityGroupEntity.setWeekBasedCapacityGroup( + weekBasedCapacityGroupResponses.getWeekBasedCapacityGroupRequest() + ); + weekBasedCapacityGroupEntity.setViewed(weekBasedCapacityGroupResponses.getViewed()); + + return weekBasedCapacityGroupEntity; + } + + @Override + public List getOldWeekBasedCapacityGroups() { + return oldWeekBasedCapacityGroups; + } + + @Override + public List getUpdatedWeekBasedCapacityGroups() { + return newWeekBasedCapacityGroups; + } + + private WeekBasedCapacityGroupDtoResponse convertToWeekBasedCapacityGroupDto( + WeekBasedCapacityGroupEntity weekBasedMaterialDemandEntity + ) { + WeekBasedCapacityGroupDtoResponse responseDto = new WeekBasedCapacityGroupDtoResponse(); + responseDto.setId(weekBasedMaterialDemandEntity.getId().toString()); + responseDto.setViewed(weekBasedMaterialDemandEntity.getViewed()); + responseDto.setWeekBasedCapacityGroupRequest(weekBasedMaterialDemandEntity.getWeekBasedCapacityGroup()); + + return responseDto; } @Override @@ -197,6 +285,7 @@ private void validateFields(WeekBasedCapacityGroupRequest weekBasedCapacityGroup private WeekBasedCapacityGroupEntity convertEntity(WeekBasedCapacityGroupRequest weekBasedCapacityGroupRequest) { return WeekBasedCapacityGroupEntity .builder() + .id(UUID.randomUUID()) .weekBasedCapacityGroup(weekBasedCapacityGroupRequest) .viewed(false) .build(); diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/WeekBasedMaterialServiceImpl.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/WeekBasedMaterialServiceImpl.java index 7f7f7ad6..4d714161 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/WeekBasedMaterialServiceImpl.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/impl/WeekBasedMaterialServiceImpl.java @@ -22,22 +22,22 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.impl; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.DemandSeriesCategoryDto; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.DemandSeriesDto; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.DemandWeekSeriesDto; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequestDto; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.MaterialDemandEntity; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.WeekBasedMaterialDemandEntity; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.MaterialDemandStatus; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.exceptions.type.BadRequestException; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.StatusesRepository; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.WeekBasedCapacityGroupRepository; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.WeekBasedMaterialDemandRepository; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.DemandService; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.LinkDemandService; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.StatusesService; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.WeekBasedMaterialService; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.DataConverterUtil; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils.UUIDUtil; @@ -52,20 +52,30 @@ public class WeekBasedMaterialServiceImpl implements WeekBasedMaterialService { private final LinkDemandService linkDemandService; + private final StatusesRepository statusesRepository; + private List oldWeekBasedMaterialDemands; + private List newWeekBasedMaterialDemands; + private final WeekBasedCapacityGroupRepository weekBasedCapacityGroupRepository; + private final DemandService demandService; @Override public void createWeekBasedMaterial(List weekBasedMaterialDemandRequestDtoList) { + oldWeekBasedMaterialDemands = + DataConverterUtil.convertToWeekBasedMaterialDemandDtoList(weekBasedMaterialDemandRepository.findAll()); weekBasedMaterialDemandRequestDtoList.forEach( weekBasedMaterialDemandRequestDto -> { validateFields(weekBasedMaterialDemandRequestDto); WeekBasedMaterialDemandEntity weekBasedMaterialDemand = convertEntity( - weekBasedMaterialDemandRequestDto + weekBasedMaterialDemandRequestDto.getWeekBasedMaterialDemandRequest() ); weekBasedMaterialDemandRepository.save(weekBasedMaterialDemand); } ); + newWeekBasedMaterialDemands = + DataConverterUtil.convertToWeekBasedMaterialDemandDtoList(weekBasedMaterialDemandRepository.findAll()); + updateStatus(); } @Override @@ -76,23 +86,88 @@ public void receiveWeekBasedMaterial() { List weekBasedMaterialDemandEntities = weekBasedMaterialDemandRepository.getAllByViewed( false ); + // updateStatus(); TODO: remove the comment when the EDC is ready linkDemandService.createLinkDemands(weekBasedMaterialDemandEntities); } @Override - public void createWeekBasedMaterialRequestFromEntity(MaterialDemandEntity materialDemandEntity) { - WeekBasedMaterialDemandRequestDto basedMaterialDemandRequestDto = new WeekBasedMaterialDemandRequestDto(); + public List getOldWeekBasedMaterialDemands() { + return oldWeekBasedMaterialDemands; + } + + @Override + public List getUpdatedWeekBasedMaterialDemands() { + return newWeekBasedMaterialDemands; + } + + private WeekBasedMaterialDemandResponseDto convertToWeekBasedCapacityGroupDto( + WeekBasedMaterialDemandEntity weekBasedMaterialDemandEntity + ) { + WeekBasedMaterialDemandResponseDto responseDto = new WeekBasedMaterialDemandResponseDto(); + responseDto.setId(weekBasedMaterialDemandEntity.getId().toString()); + responseDto.setViewed(weekBasedMaterialDemandEntity.getViewed()); + responseDto.setWeekBasedMaterialDemandRequest(weekBasedMaterialDemandEntity.getWeekBasedMaterialDemand()); + + return responseDto; + } + + public void updateStatus() { + if (statusesRepository != null) { + List oldWeekBasedCapacityGroups = DataConverterUtil.convertToWeekBasedCapacityGroupDtoList( + weekBasedCapacityGroupRepository.findAll() + ); + + if (newWeekBasedMaterialDemands == null) { + newWeekBasedMaterialDemands = List.of(); + } + final StatusesService statusesService = new StatusesServiceImpl( + statusesRepository, + oldWeekBasedMaterialDemands, + newWeekBasedMaterialDemands, + oldWeekBasedCapacityGroups, + oldWeekBasedCapacityGroups + ); + statusesService.updateStatus(); + } + } + + @Override + public WeekBasedMaterialDemandResponseDto updateWeekBasedMaterial( + String id, + WeekBasedMaterialDemandRequestDto weekBasedCapacityGroupRequest + ) { + oldWeekBasedMaterialDemands = + DataConverterUtil.convertToWeekBasedMaterialDemandDtoList(weekBasedMaterialDemandRepository.findAll()); + WeekBasedMaterialDemandEntity weekBasedCapacityGroupEntity = convertWeekMaterialDemandToEntity( + weekBasedCapacityGroupRequest + ); + weekBasedCapacityGroupEntity.setId(UUID.fromString(id)); + weekBasedCapacityGroupEntity = weekBasedMaterialDemandRepository.save(weekBasedCapacityGroupEntity); + newWeekBasedMaterialDemands = + DataConverterUtil.convertToWeekBasedMaterialDemandDtoList(weekBasedMaterialDemandRepository.findAll()); + updateStatus(); + return convertToWeekBasedCapacityGroupDto(weekBasedCapacityGroupEntity); + } - basedMaterialDemandRequestDto.setMaterialDemandId(materialDemandEntity.getId().toString()); - basedMaterialDemandRequestDto.setMaterialNumberCustomer(materialDemandEntity.getMaterialNumberCustomer()); - basedMaterialDemandRequestDto.setMaterialDescriptionCustomer( - materialDemandEntity.getMaterialDescriptionCustomer() + private WeekBasedMaterialDemandEntity convertWeekMaterialDemandToEntity( + WeekBasedMaterialDemandRequestDto weekBasedMaterialDemandRequestDto + ) { + WeekBasedMaterialDemandEntity weekBasedMaterialDemand = new WeekBasedMaterialDemandEntity(); + weekBasedMaterialDemand.setWeekBasedMaterialDemand( + weekBasedMaterialDemandRequestDto.getWeekBasedMaterialDemandRequest() ); - basedMaterialDemandRequestDto.setCustomer(materialDemandEntity.getCustomerId().getBpn()); - basedMaterialDemandRequestDto.setSupplier(materialDemandEntity.getSupplierId().getBpn()); - basedMaterialDemandRequestDto.setUnityOfMeasure(materialDemandEntity.getUnitMeasure().getCodeValue()); + weekBasedMaterialDemand.setViewed(weekBasedMaterialDemandRequestDto.getViewed()); + return weekBasedMaterialDemand; + } + + public List getWeekBasedMaterialDemands() { + return DataConverterUtil.convertToWeekBasedMaterialDemandDtoList(weekBasedMaterialDemandRepository.findAll()); + } + + @Override + public void createWeekBasedMaterialRequestFromEntity(MaterialDemandEntity materialDemandEntity) { List demandWeekSeriesDtoList = new LinkedList<>(); materialDemandEntity @@ -131,18 +206,26 @@ public void createWeekBasedMaterialRequestFromEntity(MaterialDemandEntity materi demandWeekSeriesDtoList.add(demandWeekSeriesDto); } ); + updateStatus(); } private void validateFields(WeekBasedMaterialDemandRequestDto weekBasedMaterialDemandRequestDto) { - if (!UUIDUtil.checkValidUUID(weekBasedMaterialDemandRequestDto.getMaterialDemandId())) { + if ( + !UUIDUtil.checkValidUUID( + weekBasedMaterialDemandRequestDto.getWeekBasedMaterialDemandRequest().getMaterialDemandId() + ) + ) { throw new BadRequestException( 400, "Not a valid materialDemand ID", - new ArrayList<>(List.of(weekBasedMaterialDemandRequestDto.getMaterialDemandId())) + new ArrayList<>( + List.of(weekBasedMaterialDemandRequestDto.getWeekBasedMaterialDemandRequest().getMaterialDemandId()) + ) ); } weekBasedMaterialDemandRequestDto + .getWeekBasedMaterialDemandRequest() .getDemandSeries() .forEach( demandWeekSeriesDto -> @@ -164,12 +247,11 @@ private void validateFields(WeekBasedMaterialDemandRequestDto weekBasedMaterialD ); } - private WeekBasedMaterialDemandEntity convertEntity( - WeekBasedMaterialDemandRequestDto weekBasedMaterialDemandRequestDto - ) { + private WeekBasedMaterialDemandEntity convertEntity(WeekBasedMaterialDemandRequest weekBasedMaterialDemandRequest) { return WeekBasedMaterialDemandEntity .builder() - .weekBasedMaterialDemand(weekBasedMaterialDemandRequestDto) + .id(UUID.randomUUID()) + .weekBasedMaterialDemand(weekBasedMaterialDemandRequest) .viewed(false) .build(); } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/utils/DataConverterUtil.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/utils/DataConverterUtil.java index 94a14ed9..626514c9 100644 --- a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/utils/DataConverterUtil.java +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/utils/DataConverterUtil.java @@ -22,13 +22,17 @@ package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedCapacityGroupDtoResponse; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandResponseDto; import java.time.DayOfWeek; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoField; +import java.util.ArrayList; import java.util.List; -import lombok.experimental.UtilityClass; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.WeekBasedCapacityGroupEntity; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.WeekBasedMaterialDemandEntity; public class DataConverterUtil { @@ -65,4 +69,52 @@ public static Boolean checkDatesSequence(List dates) { } return isSequentialWeeks; } + + public static List convertToWeekBasedMaterialDemandDtoList( + List weekBasedMaterialDemandEntities + ) { + List weekBasedMaterialDemandResponseList = new ArrayList<>(); + + for (WeekBasedMaterialDemandEntity entity : weekBasedMaterialDemandEntities) { + WeekBasedMaterialDemandResponseDto responseDto = new WeekBasedMaterialDemandResponseDto(); + responseDto = convertToWeekBasedCapacityGroupDto(entity); + weekBasedMaterialDemandResponseList.add(responseDto); + } + return weekBasedMaterialDemandResponseList; + } + + private static WeekBasedMaterialDemandResponseDto convertToWeekBasedCapacityGroupDto( + WeekBasedMaterialDemandEntity weekBasedMaterialDemandEntity + ) { + WeekBasedMaterialDemandResponseDto responseDto = new WeekBasedMaterialDemandResponseDto(); + responseDto.setId(weekBasedMaterialDemandEntity.getId().toString()); + responseDto.setViewed(weekBasedMaterialDemandEntity.getViewed()); + responseDto.setWeekBasedMaterialDemandRequest(weekBasedMaterialDemandEntity.getWeekBasedMaterialDemand()); + + return responseDto; + } + + public static List convertToWeekBasedCapacityGroupDtoList( + List weekBasedMaterialDemandEntities + ) { + List weekBasedCapacityGroupList = new ArrayList<>(); + + for (WeekBasedCapacityGroupEntity entity : weekBasedMaterialDemandEntities) { + WeekBasedCapacityGroupDtoResponse responseDto = new WeekBasedCapacityGroupDtoResponse(); + responseDto = convertToWeekBasedCapacityGroupDto(entity); + weekBasedCapacityGroupList.add(responseDto); + } + return weekBasedCapacityGroupList; + } + + private static WeekBasedCapacityGroupDtoResponse convertToWeekBasedCapacityGroupDto( + WeekBasedCapacityGroupEntity weekBasedMaterialDemandEntity + ) { + WeekBasedCapacityGroupDtoResponse responseDto = new WeekBasedCapacityGroupDtoResponse(); + responseDto.setId(weekBasedMaterialDemandEntity.getId().toString()); + responseDto.setViewed(weekBasedMaterialDemandEntity.getViewed()); + responseDto.setWeekBasedCapacityGroupRequest(weekBasedMaterialDemandEntity.getWeekBasedCapacityGroup()); + + return responseDto; + } } diff --git a/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/utils/StatusManager.java b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/utils/StatusManager.java new file mode 100644 index 00000000..8729e510 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/main/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/utils/StatusManager.java @@ -0,0 +1,67 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.utils; + +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.CapacityDeviation; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.EventType; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.StatusColor; + +public class StatusManager { + + public static StatusColor getStatusColor(double demand, double maxCapacity, double actualCapacity) { + CapacityDeviation capacityDeviation = CapacityDeviation.ZERO; + if (demand > maxCapacity) { + capacityDeviation = CapacityDeviation.BOTTLENECK; + } else if (demand > actualCapacity && demand < maxCapacity) { + capacityDeviation = CapacityDeviation.BOTTLENECK; + } else if (demand < actualCapacity) { + capacityDeviation = CapacityDeviation.SURPLUS; + } + return capacityDeviation.getStatusColor(); + } + + public static EventType getEventType( + boolean isMaterialDemandLinkedToCG, + StatusColor oldStatusColor, + StatusColor newStatusColor + ) { + if (!isMaterialDemandLinkedToCG) return EventType.TODO; + if (newStatusColor == oldStatusColor) { + return EventType.GENERAL_EVENT; + } + if ( + newStatusColor == StatusColor.GREEN || + (oldStatusColor == StatusColor.RED && newStatusColor == StatusColor.YELLOW) + ) { + return EventType.STATUS_IMPROVEMENT; + } + if ( + newStatusColor == StatusColor.RED || + (oldStatusColor == StatusColor.GREEN && newStatusColor == StatusColor.YELLOW) + ) { + return EventType.STATUS_REDUCTION; + } + + return EventType.GENERAL_EVENT; + } +} diff --git a/demand-capacity-mgmt-backend/src/main/resources/application.yml b/demand-capacity-mgmt-backend/src/main/resources/application.yml index 972a399a..6a0006e6 100644 --- a/demand-capacity-mgmt-backend/src/main/resources/application.yml +++ b/demand-capacity-mgmt-backend/src/main/resources/application.yml @@ -21,6 +21,8 @@ spring: jpa: + hibernate: + ddl-auto: update database: POSTGRESQL show-sql: true datasource: @@ -32,13 +34,13 @@ spring: init: platform: postgres -flyway: - enabled: true - url: jdbc:postgresql://${DCM_DATASOURCE_HOST:localhost:5432}/${DCM_DATASOURCE_NAME:dcm} - user: ${DCM_DATASOURCE_USER:dcm} - password: ${DCM_DATASOURCE_PASS:dcm} - schemas: migrations - locations: classpath:db/migration/postgresql + flyway: + enabled: true + url: jdbc:postgresql://${DCM_DATASOURCE_HOST:localhost:5432}/${DCM_DATASOURCE_NAME:dcm} + user: ${DCM_DATASOURCE_USER:dcm} + password: ${DCM_DATASOURCE_PASS:dcm} + schemas: migrations + locations: classpath:db/migration/postgresql management: security: diff --git a/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202305161804__1_add_main_tables.sql b/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202305161804__1_add_main_tables.sql index 959286a9..2cf5d2b0 100644 --- a/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202305161804__1_add_main_tables.sql +++ b/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202305161804__1_add_main_tables.sql @@ -29,13 +29,18 @@ create table demand_category demand_category_name varchar(400) ); -create table unity_of_measure +CREATE TABLE IF NOT EXISTS unit_of_measure ( - id uuid constraint unity_of_measure_pk primary key, - code_value varchar(400) , - display_value varchar(400) + id uuid DEFAULT uuid_generate_v4() primary key , + dimension varchar(15), + un_code varchar(15), + description varchar(50), + description_german varchar(50), + un_symbol varchar(15), + c_x_symbol varchar(15) ); + create table company_base_data ( id uuid constraint company_base_data_pk primary key, @@ -58,7 +63,7 @@ create table material_demand changed_at timestamp, customer_id uuid constraint customer_id references company_base_data(id), supplier_id uuid constraint supplier_id references company_base_data(id), - unity_of_measure_id uuid constraint unity_of_measure_id references unity_of_measure(id) + unit_of_measure_id uuid constraint unit_of_measure_id references unit_of_measure(id) ); create table demand_series @@ -77,4 +82,54 @@ create table demand_series_values calendar_week timestamp not null, demand numeric -) \ No newline at end of file +); + +INSERT INTO unit_of_measure +(dimension,un_code, description, description_german, un_symbol, c_x_symbol) +VALUES + ('Mass','GRM','Gram','Gramm','g','g'), + ('Mass','KGM','Kilogram','Kilogramm','kg','kg'), + ('Mass','TNE','Metric ton','Metrische Tonne','t','t'), + ('Mass','STN','ton (US) - short ton (UK/US)','US Tonne','ton (US)','ton'), + ('Mass','ONZ','Ounce','Unze','oz','oz'), + ('Mass','LBR','Pound','Pfund','lb','lb'), + ('Length','CMT','Centimetre','Zentimeter','cm','cm'), + ('Length','MTR','Metre','Meter','m','m'), + ('Length','KTM','Kilometre','Kiometer','km','km'), + ('Length','INH','Inch','Zoll','in','in'), + ('Length','FOT','Foot','Fuß','ft','ft'), + ('Length','YRD','Yard','yard','yd','yd'), + ('Area','CMK','Square centimetre','Quadrat-zentimeter','cm2','cm2'), + ('Area','MTK','Square metre','Quadratmeter','m2','m2'), + ('Area','INK','Square inch','Quadratzoll','in2','in2'), + ('Area','FTK','Square foot','Quadratfuß','ft2','ft2'), + ('Area','YDK','Square yard','Quadratyard','yd2','yd2'), + ('Volume','CMQ','Cubic centimetre','Kubikzentimeter','cm3','cm3'), + ('Volume','MTQ','Cubic metre','Kubikmeter','m3','m3'), + ('Volume','INQ','Cubic inch','Kubikzoll','in3','in3'), + ('Volume','FTQ','Cubic foot','Kubikfuß','ft3','ft3'), + ('Volume','YDQ','Cubic yard','Kubikyard','yd3','yd3'), + ('Volume','MLT','Millilitre','Milliliter','ml','ml'), + ('Volume','LTR','Litre','Liter','l','l'), + ('Volume','HLT','Hectolitre','Hektoliter','hl','hl'), + ('Quantity','H87','Piece','Stück','','pc'), + ('Quantity','SET','Set','Satz','','set'), + ('Quantity','PR','Pair','Paar','','pr'), + ('Quantity','ZP','Page','Blatt','','pg'), + ('Mechanic','KWH','Kilowatt hour','Kilowattstunde','kW-h','kwh'), + ('(blank)','','','','','xxx'); + + +ALTER TABLE IF EXISTS demand_category ADD COLUMN description varchar(200); + +INSERT INTO demand_category +(demand_category_code, demand_category_name, description) +VALUES + ('0001','Default','No Assignement'), + ('A1S1','After-Sales','After sales demand of spare parts'), + ('SR99','Series','Dependent demand, production, assembly, raw material'), + ('PI01','Phase-In-period','Ramp up of a new product or new material introduction'), + ('OS01','Single-Order','Demand outside the normal spectrum of supply'), + ('OI01','Small series','Short time frame for demand and pose to higher volatility'), + ('ED01','Extraordinary demand','Temporary demand on top of standard demand'), + ('PO01','Phase-Out-period','Ramp down. Product or material retires from the market') \ No newline at end of file diff --git a/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202307071630__3_create_capacity_group_tables.sql b/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202307071630__3_create_capacity_group_tables.sql index 623429e4..3b4be79c 100644 --- a/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202307071630__3_create_capacity_group_tables.sql +++ b/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202307071630__3_create_capacity_group_tables.sql @@ -25,16 +25,13 @@ CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; create table capacity_group ( id uuid DEFAULT uuid_generate_v4() primary key, - material_description_customer varchar(400), - material_number_customer varchar(400), - material_number_supplier varchar(400), - changed_at timestamp, - customer_id uuid constraint capacity_group_customer_id references company_base_data(id), - supplier_id uuid constraint capacity_group_supplier_id references company_base_data(id), - capacity_group_id uuid, - unity_of_measure_id uuid constraint unity_of_measure_id references unity_of_measure(id), - supplier_locations varchar(720), - name varchar(400) + capacity_group_name varchar(400), + defaultActualCapacity float, + defaultMaximumCapacity float, + start_date varchar(50), + end_date varchar(50), + customer uuid constraint capacity_group_customer_id references company_base_data(id), + supplier uuid constraint capacity_group_supplier_id references company_base_data(id) ); create table capacity_time_series @@ -57,6 +54,18 @@ create table linked_demand_series capacity_group_id uuid constraint capacity_group_id references capacity_group(id) ); +create table link_capacitygroup_demandseries +( + id uuid primary key, + demand_category_code_id uuid, + customer_id uuid, + material_number_customer varchar(400), + material_number_supplier varchar(400), + capacity_group_id uuid, + material_demand_id uuid +); + +/*DEPRECATED TABLE TODO REMOVE*/ create table link_demand ( id uuid DEFAULT uuid_generate_v4() primary key, @@ -65,4 +74,4 @@ create table link_demand demand_category_id varchar(400), linked boolean, week_based_material_demand_id integer constraint week_based_material_demand_id references week_based_material_demand(id) -); +); \ No newline at end of file diff --git a/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202307221430__4_create_demand_status_and_capacity_status.sql b/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202307221430__4_create_demand_status_and_capacity_status.sql index 359654d0..0a1eeb52 100644 --- a/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202307221430__4_create_demand_status_and_capacity_status.sql +++ b/demand-capacity-mgmt-backend/src/main/resources/db/migration/V202307221430__4_create_demand_status_and_capacity_status.sql @@ -23,6 +23,3 @@ ALTER TABLE material_demand ADD COLUMN status varchar(40); - -ALTER TABLE capacity_group -ADD COLUMN status varchar(40); diff --git a/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/CapacityGroupServiceTest.java b/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/CapacityGroupServiceTest.java index 9ee053fa..1101f555 100644 --- a/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/CapacityGroupServiceTest.java +++ b/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/CapacityGroupServiceTest.java @@ -1,222 +1,226 @@ -/* - * ******************************************************************************* - * Copyright (c) 2023 BMW AG - * Copyright (c) 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ******************************************************************************** - */ - -package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityGroupRequest; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityRequest; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequestDto; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.*; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.CapacityGroupStatus; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.CapacityGroupRepository; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.DemandCategoryRepository; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.LinkDemandRepository; -import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.impl.CapacityGroupServiceImpl; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -public class CapacityGroupServiceTest { - - @InjectMocks - private CapacityGroupServiceImpl capacityGroupService; - - @Mock - private CompanyService companyService; - - @Mock - private UnityOfMeasureService unityOfMeasureService; - - @Mock - private CapacityGroupRepository capacityGroupRepository; - - @Mock - private LinkDemandRepository linkDemandRepository; - - @Mock - private DemandCategoryService demandCategoryService; - - private static CapacityGroupRequest capacityGroupRequest = createCapacityGroupRequest(); - - private static CompanyEntity company = createCompanyEntity(); - - private LinkDemandEntity linkDemandEntity = createLinkDemandEntity(); - - private static UnitMeasureEntity unitMeasure = createUnitMeasureEntity(); - - private static WeekBasedMaterialDemandEntity weekBasedMaterialDemandEntity = createWeekBasedMaterialDemandEntity(); - - private static DemandCategoryEntity demandCategoryEntity = createDemandCategoryEntity(); - private CapacityGroupEntity capacityGroupEntity = createCapacityGroupEntity(); - - @Test - void shouldCreateCapacityGroup() { - when(companyService.getCompanyIn(any())).thenReturn(List.of(company)); - when(unityOfMeasureService.findById(any())).thenReturn(null); - when(companyService.getCompanyById(any())).thenReturn(company); - when(demandCategoryService.findById(any())).thenReturn(demandCategoryEntity); - when(linkDemandRepository.findById(any())).thenReturn(Optional.of(linkDemandEntity)); - // when(demandCategoryService.save(any())).thenReturn(demandCategoryEntity); - when(capacityGroupRepository.save(any())).thenReturn(capacityGroupEntity); - - capacityGroupService.createCapacityGroup(capacityGroupRequest); - - verify(capacityGroupRepository, times(1)).save(any()); - } - - private static CapacityGroupRequest createCapacityGroupRequest() { - CapacityGroupRequest capacityGroupRequest = new CapacityGroupRequest(); - - CapacityRequest capacityRequest = new CapacityRequest(); - capacityRequest.setActualCapacity(BigDecimal.valueOf(20)); - capacityRequest.setMaximumCapacity(BigDecimal.valueOf(20)); - capacityRequest.setCalendarWeek("2023-06-19"); - - //08b95a75-11a7-4bea-a958-821b9cb01641 - capacityGroupRequest.setCustomer("08b95a75-11a7-4bea-a958-821b9cb01641"); - capacityGroupRequest.setSupplier("08b95a75-11a7-4bea-a958-821b9cb01641"); - capacityGroupRequest.setName("Test"); - capacityGroupRequest.setUnitOfMeasure("529f760c-71f4-4d0d-a924-7e4a5b645c5e"); - capacityGroupRequest.setLinkedDemandSeries(List.of("e6ee8fc4-60e5-4af8-b878-e87105d834f2")); - capacityGroupRequest.setSupplierLocations(List.of("08b95a75-11a7-4bea-a958-821b9cb01641")); - capacityGroupRequest.setCapacities(List.of(capacityRequest)); - - return capacityGroupRequest; - } - - private static CompanyEntity createCompanyEntity() { - return CompanyEntity - .builder() - .id(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01641")) - .myCompany("Test") - .companyName("Test") - .build(); - } - - private static LinkDemandEntity createLinkDemandEntity() { - return LinkDemandEntity - .builder() - .linked(false) - .demandCategoryId("08b95a75-11a7-4bea-a958-821b9cb01642") - .materialNumberSupplier("08b95a75-11a7-4bea-a958-821b9cb01642") - .materialNumberCustomer("08b95a75-11a7-4bea-a958-821b9cb01642") - .weekBasedMaterialDemand(weekBasedMaterialDemandEntity) - .build(); - } - - private static UnitMeasureEntity createUnitMeasureEntity() { - return UnitMeasureEntity - .builder() - .id(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01643")) - .codeValue("Kilogram") - .displayValue("Kg") - .build(); - } - - private static CapacityGroupEntity createCapacityGroupEntity() { - CapacityGroupEntity capacityGroup = CapacityGroupEntity - .builder() - .id(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01642")) - .capacityGroupId(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01642")) - .materialDescriptionCustomer("08b95a75-11a7-4bea-a958-821b9cb01641") - .materialNumberCustomer("08b95a75-11a7-4bea-a958-821b9cb01641") - .changedAt(LocalDateTime.now()) - .customerId(company) - .supplierId(company) - .unitMeasure(unitMeasure) - .linkedDemandSeries(new ArrayList<>()) - .supplierLocation(new ArrayList<>()) - .name("08b95a75-11a7-4bea-a958-821b9cb01642") - .status(CapacityGroupStatus.READY_SYNCHRONIZE) - .build(); - - List timeSeriesList = createCapacityTimeSeries(capacityGroup); - - capacityGroup.setCapacityTimeSeries(timeSeriesList); - - return capacityGroup; - } - - private static List createCapacityTimeSeries(CapacityGroupEntity capacityGroup) { - CapacityTimeSeries capacityTimeSeries1 = new CapacityTimeSeries(); - capacityTimeSeries1.setId(UUID.randomUUID()); - capacityTimeSeries1.setCalendarWeek(LocalDateTime.now()); - capacityTimeSeries1.setActualCapacity(100.0); - capacityTimeSeries1.setMaximumCapacity(150.0); - capacityTimeSeries1.setCapacityGroupEntity(capacityGroup); - - CapacityTimeSeries capacityTimeSeries2 = new CapacityTimeSeries(); - capacityTimeSeries2.setId(UUID.randomUUID()); - capacityTimeSeries2.setCalendarWeek(LocalDateTime.now()); - capacityTimeSeries2.setActualCapacity(120.0); - capacityTimeSeries2.setMaximumCapacity(160.0); - capacityTimeSeries2.setCapacityGroupEntity(capacityGroup); - - List timeSeriesList = new ArrayList<>(); - timeSeriesList.add(capacityTimeSeries1); - timeSeriesList.add(capacityTimeSeries2); - - return timeSeriesList; - } - - private static WeekBasedMaterialDemandEntity createWeekBasedMaterialDemandEntity() { - WeekBasedMaterialDemandRequestDto dto = new WeekBasedMaterialDemandRequestDto(); - dto.setUnityOfMeasure("kg"); - dto.setCustomer("08b95a75-11a7-4bea-a958-821b9cb01643"); - dto.setMaterialDemandId("ID"); - dto.setMaterialNumberCustomer("IDD"); - dto.setMaterialDescriptionCustomer("08b95a75-11a7-4bea-a958-821b9cb01643"); - dto.setChangedAt("now"); - - WeekBasedMaterialDemandEntity entity = WeekBasedMaterialDemandEntity - .builder() - .id(Long.valueOf("4")) - .viewed(false) - .weekBasedMaterialDemand(dto) - .build(); - return entity; - } - - private static DemandCategoryEntity createDemandCategoryEntity() { - DemandCategoryEntity demandCategoryEntity = DemandCategoryEntity - .builder() - .id(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01642")) - .demandCategoryCode("Test") - .demandCategoryName("test2") - .build(); - return demandCategoryEntity; - } -} +///* +// * ******************************************************************************* +// * Copyright (c) 2023 BMW AG +// * Copyright (c) 2023 Contributors to the Eclipse Foundation +// * +// * See the NOTICE file(s) distributed with this work for additional +// * information regarding copyright ownership. +// * +// * This program and the accompanying materials are made available under the +// * terms of the Apache License, Version 2.0 which is available at +// * https://www.apache.org/licenses/LICENSE-2.0. +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// * License for the specific language governing permissions and limitations +// * under the License. +// * +// * SPDX-License-Identifier: Apache-2.0 +// * ******************************************************************************** +// */ +// +//package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services; +// +//import static org.mockito.ArgumentMatchers.any; +//import static org.mockito.Mockito.times; +//import static org.mockito.Mockito.verify; +//import static org.mockito.Mockito.when; +// +//import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityGroupRequest; +//import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacityRequest; +//import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequest; +//import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedMaterialDemandRequestDto; +//import java.math.BigDecimal; +//import java.time.LocalDateTime; +//import java.util.ArrayList; +//import java.util.List; +//import java.util.Optional; +//import java.util.UUID; +//import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.*; +//import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.enums.CapacityGroupStatus; +//import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.CapacityGroupRepository; +//import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.LinkDemandRepository; +//import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.impl.CapacityGroupServiceImpl; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.api.extension.ExtendWith; +//import org.mockito.InjectMocks; +//import org.mockito.Mock; +//import org.springframework.test.context.junit.jupiter.SpringExtension; +// +//@ExtendWith(SpringExtension.class) +//public class CapacityGroupServiceTest { +// +// @InjectMocks +// private CapacityGroupServiceImpl capacityGroupService; +// +// @Mock +// private CompanyService companyService; +// +// @Mock +// private UnityOfMeasureService unityOfMeasureService; +// +// @Mock +// private CapacityGroupRepository capacityGroupRepository; +// +// @Mock +// private LinkDemandRepository linkDemandRepository; +// +// @Mock +// private DemandCategoryService demandCategoryService; +// +// private static CapacityGroupRequest capacityGroupRequest = createCapacityGroupRequest(); +// +// private static CompanyEntity company = createCompanyEntity(); +// +// private LinkDemandEntity linkDemandEntity = createLinkDemandEntity(); +// +// private static UnitMeasureEntity unitMeasure = createUnitMeasureEntity(); +// +// private static WeekBasedMaterialDemandEntity weekBasedMaterialDemandEntity = createWeekBasedMaterialDemandEntity(); +// +// private static DemandCategoryEntity demandCategoryEntity = createDemandCategoryEntity(); +// private CapacityGroupEntity capacityGroupEntity = createCapacityGroupEntity(); +// +// @Test +// void shouldCreateCapacityGroup() { +// when(companyService.getCompanyIn(any())).thenReturn(List.of(company)); +// when(unityOfMeasureService.findById(any())).thenReturn(null); +// when(companyService.getCompanyById(any())).thenReturn(company); +// when(demandCategoryService.findById(any())).thenReturn(demandCategoryEntity); +// when(linkDemandRepository.findById(any())).thenReturn(Optional.of(linkDemandEntity)); +// // when(demandCategoryService.save(any())).thenReturn(demandCategoryEntity); +// when(capacityGroupRepository.save(any())).thenReturn(capacityGroupEntity); +// +// capacityGroupService.createCapacityGroup(capacityGroupRequest); +// +// verify(capacityGroupRepository, times(1)).save(any()); +// } +// +// private static CapacityGroupRequest createCapacityGroupRequest() { +// CapacityGroupRequest capacityGroupRequest = new CapacityGroupRequest(); +// +// CapacityRequest capacityRequest = new CapacityRequest(); +// capacityRequest.setActualCapacity(BigDecimal.valueOf(20)); +// capacityRequest.setMaximumCapacity(BigDecimal.valueOf(20)); +// capacityRequest.setCalendarWeek("2023-06-19"); +// +// //08b95a75-11a7-4bea-a958-821b9cb01641 +// capacityGroupRequest.setCustomer("08b95a75-11a7-4bea-a958-821b9cb01641"); +// capacityGroupRequest.setSupplier("08b95a75-11a7-4bea-a958-821b9cb01641"); +//// capacityGroupRequest.setName("Test"); +//// capacityGroupRequest.setUnitOfMeasure("529f760c-71f4-4d0d-a924-7e4a5b645c5e"); +//// capacityGroupRequest.setLinkedDemandSeries(List.of("e6ee8fc4-60e5-4af8-b878-e87105d834f2")); +//// capacityGroupRequest.setSupplierLocations(List.of("08b95a75-11a7-4bea-a958-821b9cb01641")); +//// capacityGroupRequest.setCapacities(List.of(capacityRequest)); +// +// return capacityGroupRequest; +// } +// +// private static CompanyEntity createCompanyEntity() { +// return CompanyEntity +// .builder() +// .id(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01641")) +// .myCompany("Test") +// .companyName("Test") +// .build(); +// } +// +// private static LinkDemandEntity createLinkDemandEntity() { +// return LinkDemandEntity +// .builder() +// .linked(false) +// .demandCategoryId("08b95a75-11a7-4bea-a958-821b9cb01642") +// .materialNumberSupplier("08b95a75-11a7-4bea-a958-821b9cb01642") +// .materialNumberCustomer("08b95a75-11a7-4bea-a958-821b9cb01642") +// .weekBasedMaterialDemand(weekBasedMaterialDemandEntity) +// .build(); +// } +// +// private static UnitMeasureEntity createUnitMeasureEntity() { +// return UnitMeasureEntity +// .builder() +// .id(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01643")) +// .codeValue("Kilogram") +// .displayValue("Kg") +// .build(); +// } +// +// private static CapacityGroupEntity createCapacityGroupEntity() { +// CapacityGroupEntity capacityGroup = CapacityGroupEntity +// .builder() +// .id(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01642")) +// .capacityGroupId(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01642")) +// .materialDescriptionCustomer("08b95a75-11a7-4bea-a958-821b9cb01641") +// .materialNumberCustomer("08b95a75-11a7-4bea-a958-821b9cb01641") +// .changedAt(LocalDateTime.now()) +// .customerId(company) +// .supplierId(company) +// .unitMeasure(unitMeasure) +// .linkedDemandSeries(new ArrayList<>()) +// .supplierLocation(new ArrayList<>()) +// .name("08b95a75-11a7-4bea-a958-821b9cb01642") +// .status(CapacityGroupStatus.READY_SYNCHRONIZE) +// .build(); +// +// List timeSeriesList = createCapacityTimeSeries(capacityGroup); +// +// capacityGroup.setCapacityTimeSeries(timeSeriesList); +// +// return capacityGroup; +// } +// +// private static List createCapacityTimeSeries(CapacityGroupEntity capacityGroup) { +// CapacityTimeSeries capacityTimeSeries1 = new CapacityTimeSeries(); +// capacityTimeSeries1.setId(UUID.randomUUID()); +// capacityTimeSeries1.setCalendarWeek(LocalDateTime.now()); +// capacityTimeSeries1.setActualCapacity(100.0); +// capacityTimeSeries1.setMaximumCapacity(150.0); +// capacityTimeSeries1.setCapacityGroupEntity(capacityGroup); +// +// CapacityTimeSeries capacityTimeSeries2 = new CapacityTimeSeries(); +// capacityTimeSeries2.setId(UUID.randomUUID()); +// capacityTimeSeries2.setCalendarWeek(LocalDateTime.now()); +// capacityTimeSeries2.setActualCapacity(120.0); +// capacityTimeSeries2.setMaximumCapacity(160.0); +// capacityTimeSeries2.setCapacityGroupEntity(capacityGroup); +// +// List timeSeriesList = new ArrayList<>(); +// timeSeriesList.add(capacityTimeSeries1); +// timeSeriesList.add(capacityTimeSeries2); +// +// return timeSeriesList; +// } +// +// private static WeekBasedMaterialDemandEntity createWeekBasedMaterialDemandEntity() { +// WeekBasedMaterialDemandRequestDto dto = new WeekBasedMaterialDemandRequestDto(); +// WeekBasedMaterialDemandRequest weekBasedMaterialDemandRequest = new WeekBasedMaterialDemandRequest(); +// +// weekBasedMaterialDemandRequest.setUnityOfMeasure("kg"); +// weekBasedMaterialDemandRequest.setCustomer("08b95a75-11a7-4bea-a958-821b9cb01643"); +// weekBasedMaterialDemandRequest.setMaterialDemandId("ID"); +// weekBasedMaterialDemandRequest.setMaterialNumberCustomer("IDD"); +// weekBasedMaterialDemandRequest.setMaterialDescriptionCustomer("08b95a75-11a7-4bea-a958-821b9cb01643"); +// weekBasedMaterialDemandRequest.setChangedAt("now"); +// +// dto.setWeekBasedMaterialDemandRequest(weekBasedMaterialDemandRequest); +// +// WeekBasedMaterialDemandEntity entity = WeekBasedMaterialDemandEntity +// .builder() +// .id(UUID.randomUUID()) +// .viewed(false) +// .weekBasedMaterialDemand(weekBasedMaterialDemandRequest) +// .build(); +// return entity; +// } +// +// private static DemandCategoryEntity createDemandCategoryEntity() { +// DemandCategoryEntity demandCategoryEntity = DemandCategoryEntity +// .builder() +// .id(UUID.fromString("08b95a75-11a7-4bea-a958-821b9cb01642")) +// .demandCategoryCode("Test") +// .demandCategoryName("test2") +// .build(); +// return demandCategoryEntity; +// } +//} diff --git a/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/StatusesServiceTest.java b/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/StatusesServiceTest.java new file mode 100644 index 00000000..60f14216 --- /dev/null +++ b/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/StatusesServiceTest.java @@ -0,0 +1,75 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import eclipse.tractusx.demand_capacity_mgmt_specification.model.StatusDto; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.StatusRequest; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.repositories.StatusesRepository; +import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services.impl.StatusesServiceImpl; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +public class StatusesServiceTest { + + @InjectMocks + private StatusesServiceImpl statusesService; + + @Mock + private StatusesRepository statusesRepository; + + private final StatusRequest statusRequest = createStatusRequest(); + + @Test + void shouldCreateStatusesObject() { + statusesService.postStatuses(statusRequest); + + verify(statusesRepository, times(1)).save(any()); + } + + StatusRequest createStatusRequest() { + StatusRequest statusRequest = new StatusRequest(); + statusRequest.setStatusDegredation(createStatusDto()); + statusRequest.setStatusImprovement(createStatusDto()); + statusRequest.setTodos(createStatusDto()); + statusRequest.setGeneral(createStatusDto()); + statusRequest.setOverallTodos(createStatusDto()); + statusRequest.setOverallStatusDegredation(createStatusDto()); + statusRequest.setOverallStatusImprovement(createStatusDto()); + statusRequest.setOverallGeneral(createStatusDto()); + return statusRequest; + } + + StatusDto createStatusDto() { + StatusDto statusDto = new StatusDto(); + statusDto.setCount(2); + return statusDto; + } +} diff --git a/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedCapacityGroupServiceTest.java b/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedCapacityGroupServiceTest.java index 32dca36f..8410ed48 100644 --- a/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedCapacityGroupServiceTest.java +++ b/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedCapacityGroupServiceTest.java @@ -28,11 +28,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.CapacitiesDto; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.DemandCategoryDto; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.LinkedDemandSeriesRequest; -import eclipse.tractusx.demand_capacity_mgmt_specification.model.WeekBasedCapacityGroupRequest; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import java.util.List; +import java.util.UUID; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.DemandSeries; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.MaterialDemandEntity; import org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.entities.WeekBasedCapacityGroupEntity; @@ -63,7 +61,7 @@ public class WeekBasedCapacityGroupServiceTest { private static DemandCategoryDto demandCategoryDto = createDemandCategoryDto(); private static CapacitiesDto capacitiesDto = createCapacitiesDto(); private static LinkedDemandSeriesRequest linkedDemandSeriesRequest = createLinkedDemandSeriesRequest(); - private static WeekBasedCapacityGroupRequest weekBasedCapacityGroupRequest = createWeekBasedCapacityGroupRequest(); + private static WeekBasedCapacityGroupDtoRequest weekBasedCapacityGroupRequest = createWeekBasedCapacityGroupRequest(); private static WeekBasedCapacityGroupEntity weekBasedCapacityGroup = createWeekBasedCapacityGroupEntity(); private static MaterialDemandEntity materialDemandEntity = createMaterialDemandEntity(); @@ -91,18 +89,21 @@ void shouldReceiveWeekBasedCapacityGroup() { verify(materialDemandRepository, times(1)).saveAll(any()); } - private static WeekBasedCapacityGroupRequest createWeekBasedCapacityGroupRequest() { - WeekBasedCapacityGroupRequest weekBasedCapacityGroupRequest = new WeekBasedCapacityGroupRequest(); + private static WeekBasedCapacityGroupDtoRequest createWeekBasedCapacityGroupRequest() { + WeekBasedCapacityGroupDtoRequest weekBasedCapacityGroupRequest = new WeekBasedCapacityGroupDtoRequest(); + WeekBasedCapacityGroupRequest weekBasedCapacityGroupRequest1 = new WeekBasedCapacityGroupRequest(); - weekBasedCapacityGroupRequest.setName("test"); - weekBasedCapacityGroupRequest.setCustomer("test"); - weekBasedCapacityGroupRequest.setCapacityGroupId("2c478e29-3909-481a-99b9-df3d0db97a4c"); - weekBasedCapacityGroupRequest.setUnityOfMeasure("un"); + weekBasedCapacityGroupRequest.setId(UUID.randomUUID().toString()); - weekBasedCapacityGroupRequest.setCapacities(List.of(capacitiesDto)); - weekBasedCapacityGroupRequest.setLinkedDemandSeries(List.of(linkedDemandSeriesRequest)); - weekBasedCapacityGroupRequest.setSupplierLocations(List.of("")); + weekBasedCapacityGroupRequest1.setName("test"); + weekBasedCapacityGroupRequest1.setCustomer("test"); + weekBasedCapacityGroupRequest1.setCapacityGroupId("2c478e29-3909-481a-99b9-df3d0db97a4c"); + weekBasedCapacityGroupRequest1.setUnityOfMeasure("un"); + weekBasedCapacityGroupRequest1.setCapacities(List.of(capacitiesDto)); + weekBasedCapacityGroupRequest1.setLinkedDemandSeries(List.of(linkedDemandSeriesRequest)); + weekBasedCapacityGroupRequest1.setSupplierLocations(List.of("")); + weekBasedCapacityGroupRequest.setWeekBasedCapacityGroupRequest(weekBasedCapacityGroupRequest1); return weekBasedCapacityGroupRequest; } @@ -137,8 +138,8 @@ private static WeekBasedCapacityGroupEntity createWeekBasedCapacityGroupEntity() return WeekBasedCapacityGroupEntity .builder() .viewed(false) - .id(1l) - .weekBasedCapacityGroup(weekBasedCapacityGroupRequest) + .id(UUID.randomUUID()) + .weekBasedCapacityGroup(weekBasedCapacityGroupRequest.getWeekBasedCapacityGroupRequest()) .build(); } diff --git a/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedMaterialServiceTest.java b/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedMaterialServiceTest.java index e583963d..367aa00a 100644 --- a/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedMaterialServiceTest.java +++ b/demand-capacity-mgmt-backend/src/test/java/org/eclipse/tractusx/demandcapacitymgmt/demandcapacitymgmtbackend/services/WeekBasedMaterialServiceTest.java @@ -1,9 +1,32 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + package org.eclipse.tractusx.demandcapacitymgmt.demandcapacitymgmtbackend.services; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import eclipse.tractusx.demand_capacity_mgmt_specification.model.*; import eclipse.tractusx.demand_capacity_mgmt_specification.model.DemandSeriesCategoryDto; import eclipse.tractusx.demand_capacity_mgmt_specification.model.DemandSeriesDto; import eclipse.tractusx.demand_capacity_mgmt_specification.model.DemandWeekSeriesDto; @@ -68,14 +91,15 @@ private static DemandWeekSeriesDto createDemandWeekSeriesDto() { private static WeekBasedMaterialDemandRequestDto createWeekBasedMaterialDemandRequestDto() { WeekBasedMaterialDemandRequestDto basedMaterialDemandRequestDto = new WeekBasedMaterialDemandRequestDto(); - basedMaterialDemandRequestDto.setMaterialNumberCustomer("test"); - basedMaterialDemandRequestDto.setMaterialDemandId("f50c3e71-a1a7-44c9-9de6-2e7aaaf65ac4"); - basedMaterialDemandRequestDto.setSupplier("f50c3e71-a1a7-44c9-9de6-2e7aaaf65ac4"); - basedMaterialDemandRequestDto.setCustomer("f50c3e71-a1a7-44c9-9de6-2e7aaaf65ac4"); - basedMaterialDemandRequestDto.setMaterialDescriptionCustomer(""); - basedMaterialDemandRequestDto.setUnityOfMeasure("un"); - - basedMaterialDemandRequestDto.setDemandSeries(List.of(demandWeekSeriesDto)); + WeekBasedMaterialDemandRequest weekBasedMaterialDemandRequest = new WeekBasedMaterialDemandRequest(); + weekBasedMaterialDemandRequest.setMaterialNumberCustomer("test"); + weekBasedMaterialDemandRequest.setMaterialDemandId("f50c3e71-a1a7-44c9-9de6-2e7aaaf65ac4"); + weekBasedMaterialDemandRequest.setSupplier("f50c3e71-a1a7-44c9-9de6-2e7aaaf65ac4"); + weekBasedMaterialDemandRequest.setCustomer("f50c3e71-a1a7-44c9-9de6-2e7aaaf65ac4"); + weekBasedMaterialDemandRequest.setMaterialDescriptionCustomer(""); + weekBasedMaterialDemandRequest.setUnityOfMeasure("un"); + weekBasedMaterialDemandRequest.setDemandSeries(List.of(demandWeekSeriesDto)); + basedMaterialDemandRequestDto.setWeekBasedMaterialDemandRequest(weekBasedMaterialDemandRequest); return basedMaterialDemandRequestDto; } diff --git a/demand-capacity-mgmt-frontend/package.json b/demand-capacity-mgmt-frontend/package.json index 9cfe7671..518dbf81 100644 --- a/demand-capacity-mgmt-frontend/package.json +++ b/demand-capacity-mgmt-frontend/package.json @@ -7,6 +7,8 @@ "@babel/plugin-syntax-flow": "^7.14.5", "@babel/plugin-transform-react-jsx": "^7.14.9", "@babel/preset-env": "^7.1.6", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", "@popperjs/core": "^2.11.8", "@react-icons/all-files": "^4.1.0", "@testing-library/dom": ">=7.21.4", @@ -18,7 +20,7 @@ "@types/react": "^18.2.13", "@types/react-dom": "^18.2.6", "axios": "^1.4.0", - "bootstrap": "^5.3.0", + "bootstrap": "^5.3.2", "date-fns": "^2.30.0", "http-proxy-middleware": "^2.0.6", "moment": "^2.29.4", @@ -30,6 +32,8 @@ "react-native": "^0.72.4", "react-router-dom": "^6.14.2", "react-scripts": "^5.0.1", + "react-select": "4.3.1", + "react-spinners": "^0.13.8", "recharts": "^2.8.0", "typescript": "^5.1.3", "web-vitals": "^2.1.4" @@ -62,8 +66,10 @@ "@babel/template": "^7.22.5", "@types/react-datepicker": "^4.11.2", "@types/react-native": "^0.72.2", + "@types/react-select": "^4.0.18", "@types/react-test-renderer": "^18.0.0", "react-bootstrap": "^2.8.0", + "sass": "^1.67.0", "ts-migrate": "^0.1.35" } } diff --git a/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupAddToExisting.tsx b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupAddToExisting.tsx new file mode 100644 index 00000000..8ba18b3e --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupAddToExisting.tsx @@ -0,0 +1,202 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ +import React, { useState, useEffect, useContext } from 'react'; +import Modal from 'react-bootstrap/Modal'; +import Button from 'react-bootstrap/Button'; +import Alert from 'react-bootstrap/Alert'; +import Form from 'react-bootstrap/Form'; +import ListGroup from 'react-bootstrap/ListGroup'; +import { DemandProp } from '../../interfaces/demand_interfaces'; +import { CapacityGroupProp } from '../../interfaces/capacitygroup_interfaces'; +import { CapacityGroupContext } from '../../contexts/CapacityGroupsContextProvider'; +import {LoadingMessage} from './../common/LoadingMessages'; +import { InputGroup } from 'react-bootstrap'; +import { FaSearch } from 'react-icons/fa'; + +interface CapacityGroupAddToExistingProps { + show: boolean; + onHide: () => void; + checkedDemands: DemandProp[] | null; +} + +const CapacityGroupAddToExisting: React.FC = ({ + show, + onHide, + checkedDemands +}) => { + const [selectedCapacityGroupId, setSelectedCapacityGroupId] = useState(null); + const [customerFilter, setCustomerFilter] = useState(null); + const [filteredCapacityGroups, setFilteredCapacityGroups] = useState(null); + const [searchQuery, setSearchQuery] = useState(''); + const [isLoading, setIsLoading] = useState(false); + + const capacityGroupContext = useContext(CapacityGroupContext); + const { capacitygroups } = capacityGroupContext || {}; + + const toggleDemandSelection = (demandId: string) => { + if (selectedCapacityGroupId === demandId) { + setSelectedCapacityGroupId(null); + } else { + setSelectedCapacityGroupId(demandId); + } + }; + + const resetModalValues = () => { + setSelectedCapacityGroupId(null); + setSearchQuery(''); + }; + + useEffect(() => { + if (checkedDemands) { + const customer = checkedDemands[0]?.customer.companyName || null; + setCustomerFilter(customer); + + if (customer) { + setIsLoading(true); + + if (capacitygroups) { + const filteredGroups = capacitygroups.filter((group) => group.customerName === customer); + setFilteredCapacityGroups(filteredGroups); + setIsLoading(false); + } + } + } + }, [checkedDemands, capacityGroupContext, capacitygroups]); + + useEffect(() => { + if (customerFilter && capacitygroups) { + const filteredGroups = capacitygroups.filter((group) => + (group.name && group.name.toLowerCase().includes(searchQuery.toLowerCase())) || + (group.customerName && group.customerName.toLowerCase().includes(searchQuery.toLowerCase())) || + (group.customerBPNL && group.customerBPNL.toLowerCase().includes(searchQuery.toLowerCase())) || + (group.capacityGroupId && group.capacityGroupId.toString().toLowerCase().includes(searchQuery.toLowerCase())) + ); + setFilteredCapacityGroups(filteredGroups); + } + }, [searchQuery, customerFilter, capacitygroups]); + + const handleLinkToCapacityGroup = () => { + if (selectedCapacityGroupId && checkedDemands && checkedDemands.length > 0) { + const demandIds = checkedDemands.map((demand) => demand.id); + + const capacityGroupLink = { + capacityGroupID: selectedCapacityGroupId, + linkedMaterialDemandID: demandIds, + }; + + capacityGroupContext?.linkToCapacityGroup(capacityGroupLink); + + onHide(); + resetModalValues(); + } + }; + + const renderDemands = () => { + if (!checkedDemands || checkedDemands.length === 0) { + return ( + +

No Demands selected.

+
+ ); + } + + return ( + <> +
+ + + setSearchQuery(e.target.value)} + aria-describedby="basic-addon1" + /> + +
+ Customer - Capacity Group Name + {isLoading ? ( + + ) : ( + + {filteredCapacityGroups && + filteredCapacityGroups.map((group) => ( + + {group.customerName} - {group.name} + + + ))} + + )} +
+
+
+

Selected Capacity Group :

+ + {selectedCapacityGroupId && ( + + {selectedCapacityGroupId} + + + )} + +
+ + ); + }; + + return ( + + + Link to Existing Capacity Group + + + {renderDemands()} + + + + {checkedDemands !== null && checkedDemands.length > 0 && ( + + )} + + + ); +}; + +export default CapacityGroupAddToExisting; diff --git a/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupChronogram.tsx b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupChronogram.tsx index 6923cdaa..f95d1024 100644 --- a/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupChronogram.tsx +++ b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupChronogram.tsx @@ -38,10 +38,10 @@ type CapacityGroupChronogramProps = { }; const computeLinkedDemandSum = (capacityGroup: SingleCapacityGroup | null | undefined) => { - if (!capacityGroup || !capacityGroup.linkedDemandSeries) return 0; + if (!capacityGroup || !capacityGroup.linkMaterialDemandIds) return 0; - return capacityGroup.linkedDemandSeries.length; + return capacityGroup.linkMaterialDemandIds.length; }; function CapacityGroupChronogram(props: CapacityGroupChronogramProps) { diff --git a/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupDemandsList.tsx b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupDemandsList.tsx new file mode 100644 index 00000000..17fdd0c2 --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupDemandsList.tsx @@ -0,0 +1,330 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +import React, { useContext, useState, useMemo, useCallback } from 'react'; +import { Button, Form, Col, Row, Dropdown } from 'react-bootstrap'; +import { DemandProp, DemandSeries, DemandSeriesValue } from '../../interfaces/demand_interfaces'; +import Pagination from './../common/Pagination'; +import { FaCopy, FaEllipsisV, FaInfoCircle, FaSearch, FaTrashAlt, FaUnlink } from 'react-icons/fa'; +import { DemandContext } from '../../contexts/DemandContextProvider'; +import DemandDetailsModal from './../common/DemandDetailsModal'; +import DemandListTable from '../demands/DemandListTable'; +import { LoadingMessage } from './../common/LoadingMessages'; +import DangerConfirmationModal, { ConfirmationAction } from '../common/DangerConfirmationModal'; + + +const CapacityGroupDemandsList: React.FC<{ + searchQuery?: string; + capacityGroupDemands?: string[]; + capacityGroupId?: string; +}> = ({ + searchQuery = '', + capacityGroupDemands = [], + capacityGroupId='', +}) => { + + const [showDetailsModal, setShowDetailsModal] = useState(false); + const [showConfirmationModal, setShowConfirmationModal] = useState(false); + const [confirmationAction, setConfirmationAction] = useState(ConfirmationAction.Delete); + const [selectedItemId, setSelectedItemId] = useState(null); + + const [selectedDemand, setSelectedDemand] = useState(null); + const { deleteDemand, unlinkDemand} = useContext(DemandContext)!; + const { demandprops, fetchDemandProps, isLoading } = useContext(DemandContext)!; // Make sure to get the fetchDemands function from the context. + + const [currentPage, setCurrentPage] = useState(1);//Its updated from showWizard + const [sortColumn, setSortColumn] = useState(null); + const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc'); + + const [demandsPerPage, setDemandsPerPage] = useState(6); //Only show 5 items by default + const [filteredDemands, setFilteredDemands] = useState([]); + + const handleSort = (column: string | null) => { + if (sortColumn === column) { + // If the same column is clicked again, toggle the sort order + setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc'); + } else { + // If a different column is clicked, set it as the new sort column and default to ascending order + setSortColumn(column as keyof DemandProp | null); + setSortOrder('asc'); + } + }; + + const handleDetails = (demand: DemandProp) => { + setSelectedDemand(demand); + setShowDetailsModal(true); + }; + + const handleConfirmationButtonClick = (id: string, action: ConfirmationAction) => { + setSelectedItemId(id); + setConfirmationAction(action); + setShowConfirmationModal(true); + }; + + const handleDeleteDemand = useCallback( + async (id: string) => { + try { + await deleteDemand(id); + } catch (error) { + console.error('Error deleting demand:', error); + } + }, + [deleteDemand] + ); + + const handleUnlinkDemand = useCallback( + async (id: string, capacityGroupID:string) => { + try { + await unlinkDemand(id,capacityGroupID); + } catch (error) { + console.error('Error deleting demand:', error); + } + }, + [unlinkDemand] + ); + + const handleConfirmationWrapper = () => { + if (selectedItemId && capacityGroupId) { + if (confirmationAction === ConfirmationAction.Delete) { + console.log('NOO') + handleDeleteDemand(selectedItemId) + } else if (confirmationAction === ConfirmationAction.Unlink) { + console.log('YES') + handleUnlinkDemand(selectedItemId, capacityGroupId) // Call unlinkDemand function with materialDemandID and capacityGroupID + .then(() => { + fetchDemandProps(); + }) + .catch((error) => { + console.error('Error unlinking demand:', error); + }) + .finally(() => { + // Close the delete confirmation modal + setShowConfirmationModal(false); + setSelectedItemId(null); + }); + } + console.log('WTH') + } + console.log('WTF') + }; + + const handleCloseDetails = () => setShowDetailsModal(false); + + useMemo(() => { + let sortedDemands = [...demandprops]; + + if (searchQuery !== '') { + sortedDemands = sortedDemands.filter((demand) => + demand.materialDescriptionCustomer.toLowerCase().includes(searchQuery.toLowerCase()) || + demand.id.toString().includes(searchQuery.toLowerCase()) || + demand.customer.bpn.toString().toLowerCase().includes(searchQuery.toLowerCase()) || + demand.materialNumberCustomer.toString().toLowerCase().includes(searchQuery.toLowerCase()) || + demand.materialNumberSupplier.toString().toLowerCase().includes(searchQuery.toLowerCase()) + ); + } + + sortedDemands = sortedDemands.filter((demand) => capacityGroupDemands.includes(demand.id)); + + if (sortColumn) { + sortedDemands.sort((a, b) => { + const aValue = a[sortColumn]; + const bValue = b[sortColumn]; + + if (typeof aValue === 'string' && typeof bValue === 'string') { + // Sort strings alphabetically + return aValue.localeCompare(bValue, undefined, { sensitivity: 'base' }); + } else if (typeof aValue === 'number' && typeof bValue === 'number') { + // Sort numbers numerically + return aValue - bValue; + } + + // If the types are not string or number, return 0 (no sorting) + return 0; + }); + + + if (sortOrder === 'desc') { + // Reverse the array if the sort order is descending + sortedDemands.reverse(); + } + } + + + setFilteredDemands(sortedDemands); + }, [demandprops, searchQuery, sortColumn, sortOrder, capacityGroupDemands]) + + const slicedDemands = useMemo(() => { + const indexOfLastDemand = currentPage * demandsPerPage; + const indexOfFirstDemand = indexOfLastDemand - demandsPerPage; + return filteredDemands.slice(indexOfFirstDemand, indexOfLastDemand); + }, [filteredDemands, currentPage, demandsPerPage]); + + const totalPagesNum = useMemo(() => Math.ceil(filteredDemands.length / demandsPerPage), [ + filteredDemands, + demandsPerPage, + ]); + + const demandItems = useMemo( + () => + slicedDemands.map((demand) => ( + + + + + {demand.customer.bpn} + {demand.materialNumberCustomer} + {demand.materialNumberSupplier} + + {demand.demandSeries && demand.demandSeries.length > 0 + ? demand.demandSeries[0].demandCategory?.demandCategoryName || 'N/A' + : 'N/A'} + + {demand.materialDescriptionCustomer} + + {demand?.demandSeries?.length ? ( + demand.demandSeries.reduce((earliest: string | null, series: DemandSeries) => { + const values = series.demandSeriesValues || []; + const earliestValue = values.reduce((earliestVal: string | null, value: DemandSeriesValue) => { + if (!earliestVal || value.calendarWeek < earliestVal) { + return value.calendarWeek; + } + return earliestVal; + }, null); + if (!earliest || (earliestValue && earliestValue < earliest)) { + return earliestValue; + } + return earliest; + }, null)?.split('T')[0] ?? 'N/A' + ) : 'N/A'} + + + {demand?.demandSeries?.length ? ( + demand.demandSeries.reduce((latest: string | null, series: DemandSeries) => { + const values = series.demandSeriesValues || []; + const latestValue = values.reduce((latestVal: string | null, value: DemandSeriesValue) => { + if (!latestVal || value.calendarWeek > latestVal) { + return value.calendarWeek; + } + return latestVal; + }, null); + if (!latest || (latestValue && latestValue > latest)) { + return latestValue; + } + return latest; + }, null)?.split('T')[0] ?? 'N/A' + ) : 'N/A'} + + + Up + TODO + Down + + + + + + + + handleDetails(demand)}> Details + { navigator.clipboard.writeText(demand.id) }}> Copy ID + handleConfirmationButtonClick(demand.id, ConfirmationAction.Delete)}> Delete Demand + handleConfirmationButtonClick(demand.id, ConfirmationAction.Unlink)}> Unlink + + + + + )), + [slicedDemands] + ); + + + return ( + <> + {isLoading ? ( // Conditional rendering based on loading state + + ) : ( + <> + handleSort(column)} // Pass the correct parameter type + demandItems={demandItems} + /> + +
+
+ +
+
+
+ + + Per Page: + + + setDemandsPerPage(Number(e.target.value))} + /> + + +
+
+
+
+
+ + setShowConfirmationModal(false)} + onConfirm={handleConfirmationWrapper} + action={confirmationAction} + /> + + + + + )} + + ); + }; + +export default CapacityGroupDemandsList; diff --git a/demand-capacity-mgmt-frontend/src/components/common/CapacityGroupDetails.tsx b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupDetails.tsx similarity index 95% rename from demand-capacity-mgmt-frontend/src/components/common/CapacityGroupDetails.tsx rename to demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupDetails.tsx index ff8c90e5..b746e7a2 100644 --- a/demand-capacity-mgmt-frontend/src/components/common/CapacityGroupDetails.tsx +++ b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupDetails.tsx @@ -20,7 +20,7 @@ * ******************************************************************************** */ -import CapacityGroupsList from "../capacitygroup/CapacityGroupsView"; +import CapacityGroupsList from "./CapacityGroupsList"; import CapacityGroupContext from "../../contexts/CapacityGroupsContextProvider"; function CapacityGroupDetails() { diff --git a/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupWizardModal.tsx b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupWizardModal.tsx new file mode 100644 index 00000000..9a83da0e --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/components/capacitygroup/CapacityGroupWizardModal.tsx @@ -0,0 +1,389 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ +import { useContext, useEffect, useState } from 'react'; +import Modal from 'react-bootstrap/Modal'; +import Form from 'react-bootstrap/Form'; +import { DemandProp } from '../../interfaces/demand_interfaces'; +import { Button, Container, Row, Col, Alert } from 'react-bootstrap'; +import StepBreadcrumbs from './../common/StepsBreadCrumbs'; +import { CapacityGroupContext } from '../../contexts/CapacityGroupsContextProvider'; +import { FaSearch } from 'react-icons/fa'; +import Select from 'react-select'; + +interface CapacityGroupWizardModalProps { + show: boolean; + onHide: () => void; + checkedDemands: DemandProp[] | null; + demands: DemandProp[] | null; +} + +function CapacityGroupWizardModal({ show, onHide, checkedDemands, demands }: CapacityGroupWizardModalProps) { + const [step, setStep] = useState(0); + const [groupName, setGroupName] = useState(''); + const [defaultActualCapacity, setDefaultActualCapacity] = useState(''); + const [defaultMaximumCapacity, setDefaultMaximumCapacity] = useState(''); + const [isNameInputShaking, setIsNameInputShaking] = useState(false); + const [isActualCapacityInputShaking, setIsActualCapacityInputShaking] = useState(false); + const [isMaximumCapacityShaking, setIsMaximumCapacityShaking] = useState(false); + const context = useContext(CapacityGroupContext); + + const [selectedDemands, setSelectedDemands] = useState([]); + + + useEffect(() => { + if (checkedDemands) { + setSelectedDemands([...checkedDemands]); + } + }, [checkedDemands]); + + const nextStep = () => { + + //Validate if required fields are filled + if (step === 1 && (!groupName || !defaultActualCapacity || !defaultMaximumCapacity)) { + if (!groupName) { + setIsNameInputShaking(true); + setTimeout(() => setIsNameInputShaking(false), 500); // Reset after animation duration + } + if (!defaultActualCapacity) { + setIsActualCapacityInputShaking(true); + setTimeout(() => setIsActualCapacityInputShaking(false), 500); + } + if (!defaultMaximumCapacity) { + setIsMaximumCapacityShaking(true); + setTimeout(() => setIsMaximumCapacityShaking(false), 500); + } + return; + } + if (step < 3) { + setStep(step + 1); + } + }; + + const prevStep = () => { + if (step > 0) { + setStep(step - 1); + } + }; + + // Function to handle removing a selected demand + const handleRemoveDemand = (index: number) => { + const updatedDemands = [...selectedDemands]; + updatedDemands.splice(index, 1); + setSelectedDemands(updatedDemands); + }; + + const calculateEarliestAndLatestDates = (selectedDemands: DemandProp[]) => { + let earliestDate = new Date(); + let latestDate = new Date(); + + selectedDemands.forEach((demand) => { + demand.demandSeries?.forEach((series) => { + series.demandSeriesValues?.forEach((value) => { + const date = new Date(value?.calendarWeek || ''); + if (date < earliestDate) { + earliestDate = date; + } + if (date > latestDate) { + latestDate = date; + } + }); + }); + }); + + return { earliestDate, latestDate }; + }; + + function areUnitMeasureIdsEqual(demands: DemandProp[]): boolean { + if (demands.length <= 1) { + return true; // If there's only one or zero demands, they are equal. + } + + const firstUnitMeasureId = demands[0].unitMeasureId; + return demands.every((demand) => demand.unitMeasureId.id === firstUnitMeasureId.id); + } + + + const handleSubmit = async () => { + + if (!context) { + return; + } + // Calculate earliest and latest dates + const { earliestDate, latestDate } = calculateEarliestAndLatestDates(selectedDemands); + + // Create a new capacity group + const newCapacityGroup = { + capacitygroupname: groupName, + defaultActualCapacity: parseInt(defaultActualCapacity), + defaultMaximumCapacity: parseInt(defaultMaximumCapacity), + startDate: earliestDate.toISOString().split('T')[0], + endDate: latestDate.toISOString().split('T')[0], + customer: selectedDemands.length > 0 ? selectedDemands[0].customer.id : '', // Prefill with the customer ID of the first demand + supplier: selectedDemands.length > 0 ? selectedDemands[0].supplier.id : '', // Prefill with the supplier ID of the first demand + linkMaterialDemandIds: selectedDemands.map((demand) => demand.id), // IDs of linked demands + }; + + // Call the createCapacityGroup function + try { + await context.createCapacityGroup(newCapacityGroup); + + } catch (error) { + console.error('Error creating capacity group:', error); + } + + // Reset form and close modal + setGroupName(''); + setDefaultActualCapacity(''); + setDefaultMaximumCapacity(''); + setStep(0); // Reset to Step 0 after submission + onHide(); // Call the onHide function to close the modal + }; + + + const handleDefaultMaximumCapacityChange = (newValue: string) => { + // Use a regular expression to allow only numbers + const numericValue = newValue.replace(/[^0-9]/g, ''); + // Update the state with the numeric value + setDefaultActualCapacity(numericValue); + setDefaultMaximumCapacity(numericValue); + }; + + const handleDefaultActualCapacityChange = (newValue: string) => { + // Use a regular expression to allow only numbers + const numericValue = newValue.replace(/[^0-9]/g, ''); + // Update the state with the numeric value + setDefaultActualCapacity(numericValue); + }; + + return ( + <> + + + Capacity Group Wizard + + + {step === 0 && ( +
+ +
+

Welcome to the Capacity Group Wizard, this intuitive interface will simplify this task.
+ Here, you'll effortlessly create capacity groups and seamlessly link them with demands step-by-step.

+
+ )} + {step === 1 && ( +
+ + +
Group Details
+ + Capacity Group Name + setGroupName(e.target.value)} + required + className={isNameInputShaking ? 'shake-input' : ''} + /> +
+
+ + + + + Default Maximum Capacity + handleDefaultMaximumCapacityChange(e.target.value)} + required + className={isMaximumCapacityShaking ? 'shake-input' : ''} + /> + + + + + Default Actual Capacity + handleDefaultActualCapacityChange(e.target.value)} + required + className={isActualCapacityInputShaking ? 'shake-input' : ''} + /> + + + + + +
+ )} + {step === 2 && ( +
+ +
Demand Linkage
+ {areUnitMeasureIdsEqual(selectedDemands) ? ( + // No warning if unit measure IDs are equal + null + ) : ( + // Display a warning alert if unit measure IDs are not equal + + Units of measure of selected demands are not equal. + + )} + + handleCheckboxChange(e, demand.id)} + checked={selectedDemands.includes(demand)} // Check if the demand is in the selectedDemands array + /> + + + + + {demand.customer.bpn} + {demand.materialNumberCustomer} + {demand.materialNumberSupplier} + + {demand.demandSeries && demand.demandSeries.length > 0 + ? demand.demandSeries[0].demandCategory?.demandCategoryName || 'N/A' + : 'N/A'} + + {demand.materialDescriptionCustomer} + + {demand?.demandSeries?.length ? ( + demand.demandSeries.reduce((earliest: string | null, series: DemandSeries) => { + const values = series.demandSeriesValues || []; + const earliestValue = values.reduce((earliestVal: string | null, value: DemandSeriesValue) => { + if (!earliestVal || value.calendarWeek < earliestVal) { + return value.calendarWeek; + } + return earliestVal; + }, null); + if (!earliest || (earliestValue && earliestValue < earliest)) { + return earliestValue; + } + return earliest; + }, null)?.split('T')[0] ?? 'N/A' + ) : 'N/A'} + + + {demand?.demandSeries?.length ? ( + demand.demandSeries.reduce((latest: string | null, series: DemandSeries) => { + const values = series.demandSeriesValues || []; + const latestValue = values.reduce((latestVal: string | null, value: DemandSeriesValue) => { + if (!latestVal || value.calendarWeek > latestVal) { + return value.calendarWeek; + } + return latestVal; + }, null); + if (!latest || (latestValue && latestValue > latest)) { + return latestValue; + } + return latest; + }, null)?.split('T')[0] ?? 'N/A' + ) : 'N/A'} + + + Up + TODO + Down + + + + + + + + handleDetails(demand)}> Details + { navigator.clipboard.writeText(demand.id) }}> Copy ID + handleDeleteButtonClick(demand.id)}> Delete + + + + + )), + [slicedDemands, selectedDemands, handleCheckboxChange] + ); + + + return ( + <> + {isLoading ? ( // Conditional rendering based on loading state + + ) : ( + <> + handleSort(column)} // Pass the correct parameter type + demandItems={demandItems} + /> + +
+
+ +
+
+
+ + + Per Page: + + + setDemandsPerPage(Number(e.target.value))} + /> + + +
+
+
+
+
+ + { + setShowDeleteConfirmation(false); + setDeleteItemId(null); + }} + onConfirm={handleDeleteDemandWrapper} + action={confirmationAction} + /> + + + + + + + + + )} + + ); + }; + +export default DemandList; diff --git a/demand-capacity-mgmt-frontend/src/components/common/LoadingMessages.tsx b/demand-capacity-mgmt-frontend/src/components/common/LoadingMessages.tsx new file mode 100644 index 00000000..f189209e --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/components/common/LoadingMessages.tsx @@ -0,0 +1,144 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ +import React, { useState, useEffect } from 'react'; +import { BounceLoader, GridLoader } from 'react-spinners'; + +const useLoader = (initialColor: string) => { + const [color, setColor] = useState(initialColor); + const [loadingDots, setLoadingDots] = useState(''); + + const color1 = '#ffa600'; // First color + const color2 = '#b3cb2d'; // Second color + + useEffect(() => { + let startTime: number; + let animationFrameId: number; + + const animateColorChange = (timestamp: number) => { + if (!startTime) startTime = timestamp; + const elapsed = timestamp - startTime; + const progress = (elapsed % 2250) / 2250; // Animation duration is 2250ms (half of the bounce period) + const bouncingProgress = Math.sin(progress * Math.PI); // Apply a sine function for bounce effect + const interpolatedColor = interpolateColor(color1, color2, bouncingProgress); + setColor(interpolatedColor); + animationFrameId = requestAnimationFrame(animateColorChange); + }; + + animationFrameId = requestAnimationFrame(animateColorChange); + + const loadingDotsInterval = setInterval(() => { + setLoadingDots((prevDots) => (prevDots.length === 3 ? '.' : prevDots + '.')); + }, 500); + + return () => { + cancelAnimationFrame(animationFrameId); + clearInterval(loadingDotsInterval); + }; + }, [color]); + + return { color, loadingDots }; +}; + +// Function to interpolate between two colors based on progress +const interpolateColor = (colorStart: string, colorEnd: string, progress: number): string => { + const r = Math.floor(parseInt(colorStart.slice(1, 3), 16) * (1 - progress) + parseInt(colorEnd.slice(1, 3), 16) * progress); + const g = Math.floor(parseInt(colorStart.slice(3, 5), 16) * (1 - progress) + parseInt(colorEnd.slice(3, 5), 16) * progress); + const b = Math.floor(parseInt(colorStart.slice(5, 7), 16) * (1 - progress) + parseInt(colorEnd.slice(5, 7), 16) * progress); + return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`; +}; + +export { useLoader }; + +interface CustomLoaderProps { + message: string; +} + +const LoadingCustomMessage: React.FC = ({ message }) => { + const { color, loadingDots } = useLoader('#ffa600'); + + return ( +
+
+ +
+

{message}{loadingDots}

+
+ ); +}; + +const LoadingGatheringDataMessage = () => { + const { color, loadingDots } = useLoader('#ffa600'); + + return ( +
+
+ +
+

Gathering data{loadingDots}

+
+ ); +}; + +const LoadingMessage = () => { + const { color, loadingDots } = useLoader('#ffa600'); + + const loadingPhrases = [ + 'Loading', + 'Please wait', + 'Fetching items', + 'Syncing objects', + 'Almost there', + 'Hold on a moment', + 'Preparing data', + 'Calculating results', + 'Validating outputs', + 'Loading assets', + 'Optimizing performance', + ]; + + + const [currentPhraseIndex, setCurrentPhraseIndex] = useState(0); + + useEffect(() => { + const phraseInterval = setInterval(() => { + setCurrentPhraseIndex((prevIndex) => (prevIndex + 1) % loadingPhrases.length); + }, 4000); // Change the phrase every 3 seconds + + return () => { + clearInterval(phraseInterval); + }; + }, [loadingPhrases.length]); + + return ( + <> +
+
+
+ +
+

{loadingPhrases[currentPhraseIndex]}{loadingDots}

+
+ + ); +}; + +export { LoadingGatheringDataMessage, LoadingMessage, LoadingCustomMessage }; diff --git a/demand-capacity-mgmt-frontend/src/components/common/QuickAcessItems.tsx b/demand-capacity-mgmt-frontend/src/components/common/QuickAcessItems.tsx index 2b210f84..b07a0b42 100644 --- a/demand-capacity-mgmt-frontend/src/components/common/QuickAcessItems.tsx +++ b/demand-capacity-mgmt-frontend/src/components/common/QuickAcessItems.tsx @@ -23,7 +23,7 @@ import { FaChartLine, FaLink } from 'react-icons/fa'; import { FcComboChart } from 'react-icons/fc'; import { Modal, Button } from 'react-bootstrap'; import { useState } from 'react'; -import DemandsPage from '../demands/DemandPage'; +import DemandManagement from '../demands/DemandManagement'; import DemandContextProvider from '../../contexts/DemandContextProvider'; import '../../index.css'; @@ -53,13 +53,13 @@ function QuickAcessItems() {
- Demand Management View +

Demand Management View

- + diff --git a/demand-capacity-mgmt-frontend/src/components/common/Search.tsx b/demand-capacity-mgmt-frontend/src/components/common/Search.tsx index a6bba38a..e1d69193 100644 --- a/demand-capacity-mgmt-frontend/src/components/common/Search.tsx +++ b/demand-capacity-mgmt-frontend/src/components/common/Search.tsx @@ -31,17 +31,17 @@ type DemandsSearchProps = { const DemandsSearch: React.FC = ({ searchQuery, setSearchQuery }) => { return ( -
- setSearchQuery(e.target.value)} - /> - - +
+ setSearchQuery(e.target.value)} + /> + + ); }; diff --git a/demand-capacity-mgmt-frontend/src/components/common/StepsBreadCrumbs.tsx b/demand-capacity-mgmt-frontend/src/components/common/StepsBreadCrumbs.tsx new file mode 100644 index 00000000..6e9f6291 --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/components/common/StepsBreadCrumbs.tsx @@ -0,0 +1,47 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ +import React from 'react'; + +interface StepBreadcrumbsProps { + currentStep: number; +} + +const StepBreadcrumbs: React.FC = ({ currentStep }) => { + const steps = ['Welcome', 'Step 1', 'Step 2', 'Step 3']; + + return ( +
+

+ {steps.map((stepLabel, index) => ( + + {index > 0 && {' > '}} + + {stepLabel} + + + ))} +

+
+ ); +}; + +export default StepBreadcrumbs; diff --git a/demand-capacity-mgmt-frontend/src/components/common/TopMenu.tsx b/demand-capacity-mgmt-frontend/src/components/common/TopMenu.tsx index 04b025e2..f86685fb 100644 --- a/demand-capacity-mgmt-frontend/src/components/common/TopMenu.tsx +++ b/demand-capacity-mgmt-frontend/src/components/common/TopMenu.tsx @@ -28,10 +28,11 @@ import InfoMenu from "../menu/InfoMenu"; function TopMenuLinks() { + return ( - Logo - CompanyName + Logo - CompanyName diff --git a/demand-capacity-mgmt-frontend/src/components/common/UnitsofMeasureOptions.tsx b/demand-capacity-mgmt-frontend/src/components/common/UnitsofMeasureOptions.tsx index c4336a71..cceaae39 100644 --- a/demand-capacity-mgmt-frontend/src/components/common/UnitsofMeasureOptions.tsx +++ b/demand-capacity-mgmt-frontend/src/components/common/UnitsofMeasureOptions.tsx @@ -21,30 +21,33 @@ */ import React, { useContext } from 'react'; -import { UnitsofMeasureContext } from '../../contexts/UnitsOfMeasureContextProvider'; +import { UnitsofMeasureContext } from '../../contexts/UnitsOfMeasureContextProvider' interface UnitsOfMeasureOptionsProps { - selectedUnitMeasureId: string; + selectedUnitMeasureId: string; } const UnitsOfMeasureOptions: React.FC = ({ selectedUnitMeasureId }) => { - const UnitsOfMeasureContextData = useContext(UnitsofMeasureContext); - const { unitsofmeasure } = UnitsOfMeasureContextData || {}; + const UnitsOfMeasureContextData = useContext(UnitsofMeasureContext); + const { unitsofmeasure } = UnitsOfMeasureContextData || {}; + + // Use the demandcategories array to fill the options - return ( - <> - - {unitsofmeasure && - unitsofmeasure.map((unit) => ( - - ))} - - ); }; export default UnitsOfMeasureOptions; diff --git a/demand-capacity-mgmt-frontend/src/components/demands/DemandAddForm.tsx b/demand-capacity-mgmt-frontend/src/components/demands/DemandAddForm.tsx index 552c52cd..b86f6db0 100644 --- a/demand-capacity-mgmt-frontend/src/components/demands/DemandAddForm.tsx +++ b/demand-capacity-mgmt-frontend/src/components/demands/DemandAddForm.tsx @@ -344,7 +344,7 @@ const AddForm: React.FC = ({ fetchDemandProps }) => { /> - diff --git a/demand-capacity-mgmt-frontend/src/components/demands/DemandListTable.tsx b/demand-capacity-mgmt-frontend/src/components/demands/DemandListTable.tsx new file mode 100644 index 00000000..c5a86530 --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/components/demands/DemandListTable.tsx @@ -0,0 +1,85 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +import { BiCaretDown, BiCaretUp } from 'react-icons/bi'; + +type DemandsTableProps = { + sortColumn: string | null; + sortOrder: string; + handleSort: (column: string | null) => void; + demandItems: React.ReactNode; +}; + +const DemandListTable: React.FC = ({ sortColumn, sortOrder, handleSort, demandItems }) => { + + return ( + + + + + + + + + + + + + + + + {demandItems} +
handleSort('customer.bpn')}> + Company Id{' '} + {sortColumn === 'customer.bpn' && sortOrder === 'asc' && } + {sortColumn === 'customer.bpn' && sortOrder === 'desc' && } + {!sortColumn && ...} + handleSort('materialNumberCustomer')}> + Material No. Customer{' '} + {sortColumn === 'materialNumberCustomer' && sortOrder === 'asc' && } + {sortColumn === 'materialNumberCustomer' && sortOrder === 'desc' && } + handleSort('materialNumberSupplier')}> + Material No. Supplier{' '} + {sortColumn === 'materialNumberSupplier' && sortOrder === 'asc' && } + {sortColumn === 'materialNumberSupplier' && sortOrder === 'desc' && } + handleSort('demandSeries.demandCategory')}> + Demand cat. + {sortColumn === 'demandSeries.demandCategory' && sortOrder === 'asc' && } + {sortColumn === 'demandSeries.demandCategory' && sortOrder === 'desc' && } + handleSort('materialDescriptionCustomer')}> + Description{' '} + {sortColumn === 'materialDescriptionCustomer' && sortOrder === 'asc' && } + {sortColumn === 'materialDescriptionCustomer' && sortOrder === 'desc' && } + handleSort('startDate')}> + Start Date {sortColumn === 'startDate' && sortOrder === 'asc' && } + {sortColumn === 'startDate' && sortOrder === 'desc' && } + handleSort('endDate')}> + End Date {sortColumn === 'endDate' && sortOrder === 'asc' && } + {sortColumn === 'endDate' && sortOrder === 'desc' && } + handleSort('status')}> + Status {sortColumn === 'status' && sortOrder === 'asc' && } + {sortColumn === 'status' && sortOrder === 'desc' && } +
+ ); +}; + +export default DemandListTable; diff --git a/demand-capacity-mgmt-frontend/src/components/demands/DemandPage.tsx b/demand-capacity-mgmt-frontend/src/components/demands/DemandManagement.tsx similarity index 62% rename from demand-capacity-mgmt-frontend/src/components/demands/DemandPage.tsx rename to demand-capacity-mgmt-frontend/src/components/demands/DemandManagement.tsx index ade0eba9..c434d8c9 100644 --- a/demand-capacity-mgmt-frontend/src/components/demands/DemandPage.tsx +++ b/demand-capacity-mgmt-frontend/src/components/demands/DemandManagement.tsx @@ -20,29 +20,35 @@ * ******************************************************************************** */ -import React, { useContext, useState, useMemo, useCallback } from 'react'; -import { Modal, Button, Form, Col, Row, Breadcrumb, Dropdown } from 'react-bootstrap'; +import React, { useContext, useState, useMemo, useCallback, useEffect } from 'react'; +import { Modal, Button, Form, Col, Row, Dropdown } from 'react-bootstrap'; import { DemandProp, DemandSeries, DemandSeriesValue } from '../../interfaces/demand_interfaces'; import Pagination from '../common/Pagination'; -import DemandsTable from './DemandsTable'; import DemandsSearch from '../common/Search'; import EditForm from './DemandEditForm'; -import { FaEllipsisV, FaSearch} from 'react-icons/fa'; +import { FaCopy, FaEllipsisV, FaInfoCircle, FaSearch, FaTrashAlt } from 'react-icons/fa'; import AddForm from './DemandAddForm'; import { DemandContext } from '../../contexts/DemandContextProvider'; import UnitsofMeasureContextContextProvider from '../../contexts/UnitsOfMeasureContextProvider'; import DemandCategoryContextProvider from '../../contexts/DemandCategoryProvider'; import CompanyContextProvider from '../../contexts/CompanyContextProvider'; -import WeeklyView from './DemandsOverview'; +import DemandDetailsModal from '../common/DemandDetailsModal'; -const DemandsPage: React.FC = () => { +import DemandManagementTable from './DemandManagementTable'; +import { LoadingMessage } from '../common/LoadingMessages'; +import DangerConfirmationModal, { ConfirmationAction } from '../common/DangerConfirmationModal'; + +const DemandManagement: React.FC = () => { const [showEditModal, setIsEditModalOpen] = useState(false); const [showAddModal, setShowAddModal] = useState(false); const [showDetailsModal, setShowDetailsModal] = useState(false); + const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false); + const [deleteItemId, setDeleteItemId] = useState(null); + const [confirmationAction, setConfirmationAction] = useState(ConfirmationAction.Delete); const [selectedDemand, setSelectedDemand] = useState(null); const { deleteDemand } = useContext(DemandContext)!; - const { demandprops, fetchDemandProps } = useContext(DemandContext)!; // Make sure to get the fetchDemands function from the context. + const { demandprops, fetchDemandProps, isLoading } = useContext(DemandContext)!; // Make sure to get the fetchDemands function from the context. const [searchQuery, setSearchQuery] = useState(''); const [currentPage, setCurrentPage] = useState(1); @@ -53,6 +59,10 @@ const DemandsPage: React.FC = () => { const [demandsPerPage, setDemandsPerPage] = useState(6); //Only show 5 items by default const [filteredDemands, setFilteredDemands] = useState([]); + useEffect(() => { + fetchDemandProps(); + }, [fetchDemandProps]); + const handleSort = (column: string | null) => { if (sortColumn === column) { // If the same column is clicked again, toggle the sort order @@ -63,7 +73,6 @@ const DemandsPage: React.FC = () => { setSortOrder('asc'); } }; - console.log(demandprops); const handleDeleteDemand = useCallback( async (id: string) => { @@ -90,6 +99,28 @@ const DemandsPage: React.FC = () => { const handleCloseAdd = () => setShowAddModal(false); const handleCloseDetails = () => setShowDetailsModal(false); + const handleDeleteButtonClick = (id: string) => { + setDeleteItemId(id); + setConfirmationAction(ConfirmationAction.Delete); // Set the confirmation action type + setShowDeleteConfirmation(true); + }; + + + const handleDeleteDemandWrapper = () => { + if (deleteItemId) { + handleDeleteDemand(deleteItemId) + .catch((error) => { + console.error('Error deleting demand:', error); + }) + .finally(() => { + // Close the delete confirmation modal + setShowDeleteConfirmation(false); + setDeleteItemId(null); + }); + } + }; + + useMemo(() => { let sortedDemands = [...demandprops]; @@ -199,9 +230,9 @@ const DemandsPage: React.FC = () => { - OK - Warning - Danger + Up + TODO + Down @@ -209,18 +240,18 @@ const DemandsPage: React.FC = () => { - + - handleDetails(demand)}>Details - {navigator.clipboard.writeText(demand.id)}}>Copy ID - handleDeleteDemand(demand.id)}>Delete + handleDetails(demand)}> Details + { navigator.clipboard.writeText(demand.id) }}> Copy ID + handleDeleteButtonClick(demand.id)}> Delete )), - [slicedDemands, handleDeleteDemand] + [slicedDemands] ); return ( @@ -240,109 +271,109 @@ const DemandsPage: React.FC = () => {
- - handleSort(column)} // Pass the correct parameter type - demandItems={demandItems} - /> - -
-
- + ) : ( + <> + handleSort(column)} // Pass the correct parameter type + demandItems={demandItems} /> -
-
-
- - - Per Page: - - - setDemandsPerPage(Number(e.target.value))} - /> - - -
+ +
+
+ +
+
+
+ + + Per Page: + + + setDemandsPerPage(Number(e.target.value))} + /> + + +
+
+
-
-
- setIsEditModalOpen(false)} - backdrop="static" - keyboard={false} - size="lg" - > - - Edit - - - - - - {selectedDemand && setIsEditModalOpen(false)} />} - - - - - - - - - New Material Demand - - - - - - - - - - - Demand Management - {selectedDemand?.id} - Overview - - - - - - - - + setIsEditModalOpen(false)} + backdrop="static" + keyboard={false} + size="lg" + > + + Edit + + + + + + {selectedDemand && setIsEditModalOpen(false)} />} + + + + + + + + + New Material Demand + + + + + + + + { + setShowDeleteConfirmation(false); + setDeleteItemId(null); + }} + onConfirm={handleDeleteDemandWrapper} + action={confirmationAction} + /> + + + + + )} ); }; -export default DemandsPage; +export default DemandManagement; diff --git a/demand-capacity-mgmt-frontend/src/components/demands/DemandsTable.tsx b/demand-capacity-mgmt-frontend/src/components/demands/DemandManagementTable.tsx similarity index 95% rename from demand-capacity-mgmt-frontend/src/components/demands/DemandsTable.tsx rename to demand-capacity-mgmt-frontend/src/components/demands/DemandManagementTable.tsx index 3c075d36..760eff8c 100644 --- a/demand-capacity-mgmt-frontend/src/components/demands/DemandsTable.tsx +++ b/demand-capacity-mgmt-frontend/src/components/demands/DemandManagementTable.tsx @@ -29,7 +29,7 @@ type DemandsTableProps = { demandItems: React.ReactNode; }; -const DemandsTable: React.FC = ({ sortColumn, sortOrder, handleSort, demandItems }) => { +const DemandManagementTable: React.FC = ({ sortColumn, sortOrder, handleSort, demandItems }) => { return ( @@ -81,4 +81,4 @@ const DemandsTable: React.FC = ({ sortColumn, sortOrder, hand ); }; -export default DemandsTable; +export default DemandManagementTable; diff --git a/demand-capacity-mgmt-frontend/src/components/demands/DemandsOverview.tsx b/demand-capacity-mgmt-frontend/src/components/demands/DemandsOverview.tsx index b1f59f73..cbbc9ff9 100644 --- a/demand-capacity-mgmt-frontend/src/components/demands/DemandsOverview.tsx +++ b/demand-capacity-mgmt-frontend/src/components/demands/DemandsOverview.tsx @@ -156,7 +156,6 @@ const WeeklyView: React.FC = ({ demandData }) => { useEffect(() => { - console.log("aqui") const newDemandValuesMap: DemandValuesMap = {}; demandData.demandSeries?.forEach((series) => { @@ -295,17 +294,17 @@ const WeeklyView: React.FC = ({ demandData }) => { setEditMode(!editMode)} >Edit - - diff --git a/demand-capacity-mgmt-frontend/src/components/menu/InfoMenu.tsx b/demand-capacity-mgmt-frontend/src/components/menu/InfoMenu.tsx index 72ff6108..72f11d67 100644 --- a/demand-capacity-mgmt-frontend/src/components/menu/InfoMenu.tsx +++ b/demand-capacity-mgmt-frontend/src/components/menu/InfoMenu.tsx @@ -21,43 +21,43 @@ */ import Nav from "react-bootstrap/Nav"; -import { FaArrowDown, FaArrowUp, FaStar } from "react-icons/fa"; +import { FaArrowDown, FaArrowUp, FaHome, FaStar } from "react-icons/fa"; import { useInfoMenu } from "../../contexts/InfoMenuContextProvider"; function InfoMenu() { const { data } = useInfoMenu(); - console.log(data); return ( <> diff --git a/demand-capacity-mgmt-frontend/src/components/pages/CapacityGroupDetailsPage.tsx b/demand-capacity-mgmt-frontend/src/components/pages/CapacityGroupDetailsPage.tsx index 1c691a5a..d8088887 100644 --- a/demand-capacity-mgmt-frontend/src/components/pages/CapacityGroupDetailsPage.tsx +++ b/demand-capacity-mgmt-frontend/src/components/pages/CapacityGroupDetailsPage.tsx @@ -19,14 +19,16 @@ * SPDX-License-Identifier: Apache-2.0 * ******************************************************************************** */ - -import React, {useState, useContext, useEffect} from 'react'; -import { Tab, Tabs} from 'react-bootstrap'; -import CapacityGroupChronogram from "../../components/capacitygroup/CapacityGroupChronogram"; -import CapacityGroupSumView from "../capacitygroup/CapacityGroupSumView"; -import {useParams} from "react-router-dom"; -import {CapacityGroupContext} from "../../contexts/CapacityGroupsContextProvider"; -import {SingleCapacityGroup} from "../../interfaces/capacitygroup_interfaces"; +import React, { useState, useContext, useEffect, useMemo } from 'react'; +import { Tab, Tabs } from 'react-bootstrap'; +import CapacityGroupChronogram from '../../components/capacitygroup/CapacityGroupChronogram'; +import CapacityGroupSumView from '../capacitygroup/CapacityGroupSumView'; +import { useParams } from 'react-router-dom'; +import { CapacityGroupContext } from '../../contexts/CapacityGroupsContextProvider'; +import { SingleCapacityGroup } from '../../interfaces/capacitygroup_interfaces'; +import DemandContextProvider from '../../contexts/DemandContextProvider'; +import CapacityGroupDemandsList from '../capacitygroup/CapacityGroupDemandsList'; +import { LoadingMessage } from '../common/LoadingMessages'; function CapacityGroupDetailsPage() { const { id } = useParams(); @@ -37,60 +39,70 @@ function CapacityGroupDetailsPage() { } const { getCapacityGroupById } = context; - const [activeTab, setActiveTab] = useState('overview'); const [capacityGroup, setCapacityGroup] = useState(null); useEffect(() => { - (async () => { - try { - const fetchedCapacityGroup = await getCapacityGroupById(id!); - setCapacityGroup(fetchedCapacityGroup || null); - } catch (error) { - console.error('Failed to fetch capacity group:', error); - } - })(); + if (id) { + (async () => { + try { + const fetchedCapacityGroup = await getCapacityGroupById(id); + setCapacityGroup(fetchedCapacityGroup || null); + } catch (error) { + console.error('Failed to fetch capacity group:', error); + } + })(); + } }, [id, getCapacityGroupById]); + const memoizedComponent = useMemo(() => { + if (!capacityGroup) { + return ; + } - return ( - <> -
-
-
-
-
- {capacityGroup?.capacityGroupId} - {capacityGroup?.name} -
+ return ( + <> +
+
+
+
+
+ {capacityGroup?.capacityGroupId} - {capacityGroup?.capacitygroupname} +

+
+ { + if (typeof tabKey === 'string') { + setActiveTab(tabKey); + } + }} + > + + + + + + + + + + + Pre filtered event list here + +
- { - if (typeof tabKey === 'string') { - setActiveTab(tabKey); - } - }} - > - - - - - - Materials Table here - - - Pre filtered event list here - - -
- - ); + + ); + }, [capacityGroup, activeTab]); // Add any other dependencies if necessary + + return memoizedComponent; } export default CapacityGroupDetailsPage; diff --git a/demand-capacity-mgmt-frontend/src/components/pages/CapacityGroupPage.tsx b/demand-capacity-mgmt-frontend/src/components/pages/CapacityGroupPage.tsx index 6a1e1f9a..b0e19b2e 100644 --- a/demand-capacity-mgmt-frontend/src/components/pages/CapacityGroupPage.tsx +++ b/demand-capacity-mgmt-frontend/src/components/pages/CapacityGroupPage.tsx @@ -21,7 +21,7 @@ */ import CapacityGroupsProvider from "../../contexts/CapacityGroupsContextProvider"; -import CapacityGroupsList from "../../components/capacitygroup/CapacityGroupsView"; +import CapacityGroupsList from "../capacitygroup/CapacityGroupsList"; function CapacityGroupPage() { diff --git a/demand-capacity-mgmt-frontend/src/components/pages/DownStatusPage.tsx b/demand-capacity-mgmt-frontend/src/components/pages/DownStatusPage.tsx new file mode 100644 index 00000000..ba66d8a0 --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/components/pages/DownStatusPage.tsx @@ -0,0 +1,48 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +import { FcBearish} from "react-icons/fc"; +import DemandList from "../common/DemandList"; + + + +function DownStatusPage() { + + return ( + <> +
+
+
+

Negative

+
+
+
+ +
+
+
+ + + ); +} + +export default DownStatusPage; \ No newline at end of file diff --git a/demand-capacity-mgmt-frontend/src/components/pages/TodoListPage.tsx b/demand-capacity-mgmt-frontend/src/components/pages/TodoListPage.tsx new file mode 100644 index 00000000..8b066103 --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/components/pages/TodoListPage.tsx @@ -0,0 +1,91 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +import { FcTodoList } from "react-icons/fc"; +import DemandList from "../common/DemandList"; +import DemandsSearch from "../common/Search"; +import { Button } from "react-bootstrap"; +import { useState } from "react"; +import { FaMagic } from "react-icons/fa"; + +function TodoListPage() { + const [searchQuery, setSearchQuery] = useState(''); + const [showWizard, setShowWizard] = useState(false); + const [showAddToExisting, setShowAddToExisting] = useState(false); + const toggleWizardModal = () => { + setShowWizard(!showWizard); // Toggle the state (true to false or false to true) + }; + const toggleAddToExisting = () => { + setShowAddToExisting(!showAddToExisting); // Toggle the state (true to false or false to true) + }; + + return ( + <> +
+
+
+ +

Todo Items

+
+
+
+
+
+
+ +
+
+ + +
+
+
+ +
+
+
+ + + + ); +} + +export default TodoListPage; \ No newline at end of file diff --git a/demand-capacity-mgmt-frontend/src/components/pages/UpStatusPage.tsx b/demand-capacity-mgmt-frontend/src/components/pages/UpStatusPage.tsx new file mode 100644 index 00000000..7d973f40 --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/components/pages/UpStatusPage.tsx @@ -0,0 +1,48 @@ +/* + * ******************************************************************************* + * Copyright (c) 2023 BMW AG + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +import { FcBullish} from "react-icons/fc"; +import DemandList from "../common/DemandList"; + + + +function UpStatusPage() { + + return ( + <> +
+
+
+

Positive

+
+
+
+ +
+
+
+ + + ); +} + +export default UpStatusPage; \ No newline at end of file diff --git a/demand-capacity-mgmt-frontend/src/contexts/CapacityGroupsContextProvider.tsx b/demand-capacity-mgmt-frontend/src/contexts/CapacityGroupsContextProvider.tsx index 9d025312..a31d2897 100644 --- a/demand-capacity-mgmt-frontend/src/contexts/CapacityGroupsContextProvider.tsx +++ b/demand-capacity-mgmt-frontend/src/contexts/CapacityGroupsContextProvider.tsx @@ -22,33 +22,60 @@ import React, { createContext, useState, useEffect } from 'react'; import axios from 'axios'; -import {CapacityGroup, SingleCapacityGroup} from '../interfaces/capacitygroup_interfaces'; +import {CapacityGroupProp, CapacityGroupCreate, CapacityGroupLink, SingleCapacityGroup} from '../interfaces/capacitygroup_interfaces'; + interface CapacityGroupContextData { - capacitygroups: CapacityGroup[]; + capacitygroups: CapacityGroupProp[]; getCapacityGroupById: (id: string) =>Promise; + isLoading: boolean; + createCapacityGroup: (newCapacityGroup: CapacityGroupCreate) => Promise; + linkToCapacityGroup: (linkToCapacityGroup: CapacityGroupLink)=> Promise; } export const CapacityGroupContext = createContext(undefined); + const CapacityGroupsProvider: React.FC> = (props) => { + + + const [capacitygroups, setCapacityGroups] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [retryCount, setRetryCount] = useState(0); - const [capacitygroups, setCapacityGroups] = useState([]); +useEffect(() => { + const maxRetries = 3; + + const fetchCapacityGroupsWithRetry = async () => { + setIsLoading(true); - useEffect(() => { - const fetchCapacityGroups = async () => { try { const response = await axios.get('/capacityGroup', {}); - const result: CapacityGroup[] = response.data; + const result: CapacityGroupProp[] = response.data; setCapacityGroups(result); + setIsLoading(false); // Set isLoading to false on success + setRetryCount(0); // Reset the retry count on success + return; // Exit the loop on success } catch (error) { - console.error('Error fetching capacitygroups:', error); + console.error(`Error fetching capacitygroups (Retry ${retryCount + 1}):`, error); + + if (retryCount < maxRetries - 1) { + // If not the last retry, delay for 30 seconds before the next retry + await new Promise((resolve) => setTimeout(resolve, 30000)); + setRetryCount(retryCount + 1); // Increment the retry count + } else { + // If the last retry failed, set isLoading to false and do not retry further + setIsLoading(false); + setRetryCount(0); // Reset the retry count + } } - }; + + }; + + fetchCapacityGroupsWithRetry(); +}, [retryCount]); - fetchCapacityGroups(); - }, []); const getCapacityGroupById = async (id: string): Promise => { try { @@ -61,18 +88,29 @@ const CapacityGroupsProvider: React.FC> = (props) => } }; + const createCapacityGroup = async (newCapacityGroup: CapacityGroupCreate) => { + try { + console.log(newCapacityGroup); + const response = await axios.post('/capacityGroup', newCapacityGroup); + console.log(response) + } catch (error) { + console.error('Error creating capacityGroup:', error); + } + }; + + const linkToCapacityGroup = async (linkToCapacityGroup: CapacityGroupLink) => { + try { + await axios.post('/capacityGroup/link', linkToCapacityGroup); + } catch (error) { + console.error('Error creating capacityGroup:', error); + } + }; + return ( - + {props.children} ); }; - - - - - - - export default CapacityGroupsProvider; diff --git a/demand-capacity-mgmt-frontend/src/contexts/DemandContextProvider.tsx b/demand-capacity-mgmt-frontend/src/contexts/DemandContextProvider.tsx index 25ee192c..aa1283ce 100644 --- a/demand-capacity-mgmt-frontend/src/contexts/DemandContextProvider.tsx +++ b/demand-capacity-mgmt-frontend/src/contexts/DemandContextProvider.tsx @@ -29,38 +29,58 @@ interface DemandContextData { createDemand: (newDemand: Demand) => Promise; getDemandbyId: (id: string) =>Promise; deleteDemand: (id: string) => Promise; + unlinkDemand: (id: string,capacitygroupId: string) => Promise; updateDemand: (updatedDemand: Demand) => Promise; fetchDemandProps: () => void; - + isLoading: boolean; } export const DemandContext = createContext(undefined); const DemandContextProvider: React.FC> = (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const [demands, setDemands] = useState([]); const [demandprops, setDemandProps] = useState([]); + const [isLoading, setIsLoading] = useState(false); // eslint-disable-next-line react-hooks/exhaustive-deps - const fetchDemandProps = useCallback(async () => { - try { - const response = await axios.get('/demand', { - params: { - project_id: 1, // Adjust the project ID parameter as needed - }, - }); - const result: DemandProp[] = response.data; - setDemandProps(result); - console.log(demands); - } catch (error) { - console.error('Error fetching demands:', error); + const fetchDemandPropsWithRetry = async (maxRetries = 3) => { + let retries = 0; + + while (retries < maxRetries) { + try { + setIsLoading(true); + const response = await axios.get('/demand', { + params: { + project_id: 1, // Adjust the project ID parameter as needed + }, + }); + const result: DemandProp[] = response.data; + setDemandProps(result); + setIsLoading(false); // Set isLoading to false on success + return; // Exit the loop on success + } catch (error) { + console.error(`Error fetching demands (Retry ${retries + 1}):`, error); + retries++; + if (retries < maxRetries) { + // Delay for 30 seconds before the next retry + await new Promise((resolve) => setTimeout(resolve, 30000)); + } else { + setIsLoading(false); // Set isLoading to false on max retries + } + } } - }, [demands]); + }; + + const fetchDemandProps = useCallback(() => { + fetchDemandPropsWithRetry(); + }, []); useEffect(() => { fetchDemandProps(); }, [fetchDemandProps]); - + const getDemandbyId = async (id: string): Promise => { try { @@ -69,14 +89,13 @@ const DemandContextProvider: React.FC> = (props) => return fetchedDemand; } catch (error) { console.error('Error fetching demand by id:', error); - return undefined; } }; const deleteDemand = async (id: string) => { try { await axios.delete(`/demand/${id}`); - setDemandProps((prevDemands) => prevDemands.filter((demand) => demand.id !== id)); + fetchDemandProps(); } catch (error) { console.error('Error deleting demand:', error); } @@ -85,8 +104,7 @@ const DemandContextProvider: React.FC> = (props) => const createDemand = async (newDemand: Demand) => { try { console.log(newDemand); - const response = await axios.post('/demand', newDemand); - console.log(response) //TODO clean + await axios.post('/demand', newDemand); fetchDemandProps(); } catch (error) { console.error('Error creating demand:', error); @@ -95,11 +113,10 @@ const DemandContextProvider: React.FC> = (props) => const updateDemand = async (updatedDemand: Demand) => { try { - console.log(updatedDemand); const response = await axios.put(`/demand/${updatedDemand.id}`, updatedDemand); const modifiedDemand: Demand = response.data; setDemands((prevDemands) => - prevDemands.map((demand) => (demand.id === modifiedDemand.id ? modifiedDemand : demand)) + prevDemands.map((demand) => (demand.id === modifiedDemand.id ? modifiedDemand : demand)) ); fetchDemandProps(); } catch (error) { @@ -107,10 +124,26 @@ const DemandContextProvider: React.FC> = (props) => } }; + const unlinkDemand = async (materialDemandID: string, capacityGroupID: string) => { + + console.log('CALLED IT') + try { + const unlinkreq = { + materialDemandID: materialDemandID, + capacityGroupID: capacityGroupID, + }; + + await axios.post('/demand/series/unlink', unlinkreq); + } catch (error) { + console.error('Error unlinking demand:', error); + throw error; + } + }; + return ( - - {props.children} - + + {props.children} + ); }; diff --git a/demand-capacity-mgmt-frontend/src/contexts/InfoMenuContextProvider.tsx b/demand-capacity-mgmt-frontend/src/contexts/InfoMenuContextProvider.tsx index 369a01a8..f0b4bc13 100644 --- a/demand-capacity-mgmt-frontend/src/contexts/InfoMenuContextProvider.tsx +++ b/demand-capacity-mgmt-frontend/src/contexts/InfoMenuContextProvider.tsx @@ -44,7 +44,6 @@ export const InfoMenuProvider: FunctionComponent = ({ chi const response = await axios.get('/statuses'); const result: InfoMenuData = response.data; setData(result); - console.log(result) } catch (error) { console.error('Error fetching data:', error); } diff --git a/demand-capacity-mgmt-frontend/src/contexts/UnitsOfMeasureContextProvider.tsx b/demand-capacity-mgmt-frontend/src/contexts/UnitsOfMeasureContextProvider.tsx index 8698632c..399a285c 100644 --- a/demand-capacity-mgmt-frontend/src/contexts/UnitsOfMeasureContextProvider.tsx +++ b/demand-capacity-mgmt-frontend/src/contexts/UnitsOfMeasureContextProvider.tsx @@ -25,8 +25,12 @@ import axios from 'axios'; export interface UnitMeasure { id: string - codeValue: string - displayValue: string + dimension: string + unCode: string + description: string + descriptionGerman: string + unSymbol: string + cxSymbol: string } interface UnitsOfMeasureContextData { diff --git a/demand-capacity-mgmt-frontend/src/custom-bootstrap.scss b/demand-capacity-mgmt-frontend/src/custom-bootstrap.scss new file mode 100644 index 00000000..b6241110 --- /dev/null +++ b/demand-capacity-mgmt-frontend/src/custom-bootstrap.scss @@ -0,0 +1,92 @@ +// Import Bootstrap's functions file +@import '~bootstrap/scss/bootstrap'; + +// Theme 1 variables +$theme1-primary: #94cb2d; +$theme1-secondary: #ffa600; +$theme1-info: #6c757d; + +// Theme 2 variables +$theme2-primary: #ffa600; +$theme2-secondary: #94cb2d; +$theme2-info: #6c757d; + +// Define classes for Theme 1 +.theme1 { + --bs-primary: $theme1-primary; /* Override Bootstrap primary color */ + --bs-secondary: $theme1-secondary; /* Override Bootstrap secondary color */ + --bs-info: $theme1-info; /* Override Bootstrap info color */ +} + +// Define classes for Theme 2 +.theme2 { + --bs-primary: $theme2-primary; /* Override Bootstrap primary color */ + --bs-secondary: $theme2-secondary; /* Override Bootstrap secondary color */ + --bs-info: $theme2-info; /* Override Bootstrap info color */ +} + +// Override Bootstrap variables with custom colors +$theme-colors: ( + primary: $theme1-primary, + secondary: $theme1-secondary, + info: $theme1-info +); + +@import '~bootstrap/scss/mixins'; +@import '~bootstrap/scss/root'; +@import '~bootstrap/scss/reboot'; +@import '~bootstrap/scss/forms'; +@import '~bootstrap/scss/buttons'; +@import '~bootstrap/scss/dropdown'; + +// Override button text color +.btn { + color: #ffffff; // White text color +} +.btn-light { + color: black; +} + +// Override outline button text color +.btn-outline-primary { + color: var(--bs-primary); // Custom primary color +} + +.btn-outline-secondary { + color: var(--bs-secondary); // Custom secondary color +} + +.btn-outline-info { + color: var(--bs-info); // Custom info color +} + +.btn-danger { + --bs-btn-color: #fff; + --bs-btn-bg: #dc3545 !important; +} + +// Override Bootstrap pagination button text color +.pagination .page-link { + color: #ffffff; // White text color +} + +// Override Bootstrap pagination active button background color +.pagination .page-item.active .page-link { + background-color: var(--bs-primary); // Custom primary color + border-color: var(--bs-primary); // Custom primary color +} +.pagination .page-link { + color: #303030; +} + +.dropdown-menu { + --bs-dropdown-link-active-bg: var(--bs-primary); +} + +.dropdown-item:hover, +.dropdown-item:focus { + background-color: var(--bs-primary); +} + +@import '~bootstrap/scss/pagination'; +@import 'index.css'; diff --git a/demand-capacity-mgmt-frontend/src/index.css b/demand-capacity-mgmt-frontend/src/index.css index 2765582e..0dd449a8 100644 --- a/demand-capacity-mgmt-frontend/src/index.css +++ b/demand-capacity-mgmt-frontend/src/index.css @@ -34,9 +34,8 @@ code { monospace; } - .custom-modal { - max-width: 1500px; /* Adjust the width as needed */ + max-width: 1500px !important; /* Adjust the width as needed */ } .required-field-label::after { @@ -126,12 +125,62 @@ code { border: 1px solid var(--border-color); } +.table-checkbox{ + -ms-transform: scale(1.5); /* IE */ + -moz-transform: scale(1.5); /* FF */ + -webkit-transform: scale(1.5); /* Safari and Chrome */ + -o-transform: scale(1.5); /* Opera */ +} .red-delete-item { - color: var(--danger-red); + color: var(--danger-red) !important; } .red-delete-item:hover { - background-color: var(--danger-red); - color: white; + background-color: var(--danger-red)!important; + color: white !important; +} + +.icon-text-padding{ + padding-left: 0.5rem; +} + +.active-step { + text-decoration: underline; + text-decoration-color: #94cb2d; + text-decoration-thickness: 4px; +} + +/*Shake Animation*/ +.shake-input { + animation: shake 0.5s; +} + +@keyframes shake { + 0% { transform: translateX(0); } + 10%, 20% { transform: translateX(-5px); } + 30%, 40% { transform: translateX(5px); } + 50%, 60%, 70%, 80% { transform: translateX(-5px); } + 90%, 100% { transform: translateX(0); } +} + +/*Breadcrumbs animation*/ +.active-step { + position: relative; +} + +.active-step:after { + content: ''; + position: absolute; + bottom: -5px; /* Adjust the position based on your design */ + left: 50%; + transform: translateX(-50%); + width: 0; + height: 2px; /* The height of the indicator line */ + background-color: #007bff; /* Color of the indicator line */ + transition: width 0.3s ease; +} + +.active-step.active:after { + width: 100%; /* Width of the indicator line when the step is active */ } \ No newline at end of file diff --git a/demand-capacity-mgmt-frontend/src/index.js b/demand-capacity-mgmt-frontend/src/index.js index 79047260..4255513c 100644 --- a/demand-capacity-mgmt-frontend/src/index.js +++ b/demand-capacity-mgmt-frontend/src/index.js @@ -33,10 +33,16 @@ import { InfoMenuProvider } from './contexts/InfoMenuContextProvider'; import QuickAcessItems from "./components/common/QuickAcessItems"; //Import Context Providers import DemandContextProvider from "../src/contexts/DemandContextProvider"; -// Import your components for different routes +import CapacityGroupsProvider from './contexts/CapacityGroupsContextProvider'; +//Pages import Home from "./components/pages/CapacityGroupPage"; import CapacityGroupDetailsPage from "./components/pages/CapacityGroupDetailsPage"; -import CapacityGroupsProvider from './contexts/CapacityGroupsContextProvider'; +import TodoListPage from "./components/pages/TodoListPage"; +import DownStatusPage from "./components/pages/DownStatusPage"; +import UpStatusPage from "./components/pages/UpStatusPage"; + +import './custom-bootstrap.scss'; +import'./index.css'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( @@ -44,12 +50,13 @@ root.render( - } /> } /> - + } /> + } /> + } /> diff --git a/demand-capacity-mgmt-frontend/src/interfaces/capacitygroup_interfaces.tsx b/demand-capacity-mgmt-frontend/src/interfaces/capacitygroup_interfaces.tsx index 064d1bc8..11e88619 100644 --- a/demand-capacity-mgmt-frontend/src/interfaces/capacitygroup_interfaces.tsx +++ b/demand-capacity-mgmt-frontend/src/interfaces/capacitygroup_interfaces.tsx @@ -22,7 +22,7 @@ import { DemandProp } from "./demand_interfaces" -export interface CapacityGroup { +export interface CapacityGroupProp { internalId: string catXUuid: string name: string @@ -58,27 +58,30 @@ interface Capacities{ calendarWeek: string } -interface DemandCategory { - id: string; - demandCategoryCode: string; - demandCategoryName: string; -} - -interface LinkedDemand { - demandCategory: DemandCategory; - customerLocation: Address; - materialNumberSupplier: string; - materialNumberCustomer: string; -} - export interface SingleCapacityGroup { capacities: Capacities[]; supplierLocations: Address[]; customer: Address; supplier: Address; capacityGroupId: string; - linkedDemandSeries: DemandProp[]; + linkMaterialDemandIds: string[]; unitOfMeasure: UnitOfMeasure; changeAt: string; - name: string; + capacitygroupname: string; +} + +export interface CapacityGroupCreate { + capacitygroupname: string + defaultActualCapacity: number + defaultMaximumCapacity: number + startDate: string + endDate: string + customer: string + supplier: string + linkMaterialDemandIds: string[] +} + +export interface CapacityGroupLink { + capacityGroupID: string + linkedMaterialDemandID: string[] } diff --git a/demand-capacity-mgmt-frontend/src/interfaces/demand_interfaces.tsx b/demand-capacity-mgmt-frontend/src/interfaces/demand_interfaces.tsx index 467b628b..5d2215de 100644 --- a/demand-capacity-mgmt-frontend/src/interfaces/demand_interfaces.tsx +++ b/demand-capacity-mgmt-frontend/src/interfaces/demand_interfaces.tsx @@ -82,4 +82,10 @@ export interface Demand { id: string codeValue: string displayValue: string + } + + //Demand Unlink + export interface DemandUnlink { + materialDemandID: string + capacityGroupID: string } \ No newline at end of file diff --git a/demand-capacity-mgmt-frontend/tsconfig.json b/demand-capacity-mgmt-frontend/tsconfig.json index 9dc81b05..12e67b7d 100644 --- a/demand-capacity-mgmt-frontend/tsconfig.json +++ b/demand-capacity-mgmt-frontend/tsconfig.json @@ -14,7 +14,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ "jsx": "react-jsx", /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "es2018", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ diff --git a/demand-capacity-mgmt-frontend/yarn.lock b/demand-capacity-mgmt-frontend/yarn.lock index 6b170b2f..46b70621 100644 --- a/demand-capacity-mgmt-frontend/yarn.lock +++ b/demand-capacity-mgmt-frontend/yarn.lock @@ -287,7 +287,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-module-imports@^7.22.15": +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== @@ -1512,6 +1512,12 @@ dependencies: regenerator-runtime "^0.13.11" +"@babel/runtime@^7.12.0": + version "7.23.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.1.tgz#72741dc4d413338a91dcb044a86f3c0bc402646d" + integrity sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g== + dependencies: + regenerator-runtime "^0.14.0" "@babel/template@^7.0.0", "@babel/template@^7.22.15": version "7.22.15" @@ -1700,6 +1706,113 @@ resolved "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz" integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.2.0" + +"@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" + +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== + +"@emotion/is-prop-valid@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== + dependencies: + "@emotion/memoize" "^0.8.1" + +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/react@^11.1.1", "@emotion/react@^11.11.1": + version "11.11.1" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.1.tgz#b2c36afac95b184f73b08da8c214fdf861fa4157" + integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + hoist-non-react-statics "^3.3.1" + +"@emotion/serialize@^1.0.0", "@emotion/serialize@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51" + integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA== + dependencies: + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" + csstype "^3.0.2" + +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== + +"@emotion/styled@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" + integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/is-prop-valid" "^1.2.1" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== + +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== + +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -2207,7 +2320,7 @@ "@popperjs/core@^2.11.6", "@popperjs/core@^2.11.8", "@popperjs/core@^2.9.2": version "2.11.8" - resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== "@react-aria/ssr@^3.5.0": @@ -3049,6 +3162,13 @@ date-fns "^2.0.1" react-popper "^2.2.5" +"@types/react-dom@*": + version "18.2.8" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.8.tgz#338f1b0a646c9f10e0a97208c1d26b9f473dffd6" + integrity sha512-bAIvO5lN/U8sPGvs1Xm61rlRHHaq5rp5N3kp9C+NJ/Q41P8iqjkXSu0+/qu8POsjH9pNWb0OYabFez7taP7omw== + dependencies: + "@types/react" "*" + "@types/react-dom@^18.0.0", "@types/react-dom@^18.2.6": version "18.2.6" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.6.tgz" @@ -3064,6 +3184,16 @@ "@react-native/virtualized-lists" "^0.72.4" "@types/react" "*" +"@types/react-select@^4.0.18": + version "4.0.18" + resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-4.0.18.tgz#f907f406411afa862217a9d86c54a301367a35c1" + integrity sha512-uCPRMPshd96BwHuT7oCrFduiv5d6km3VwmtW7rVl9g4XetS3VoJ9nZo540LiwtQgaFcW96POwaxQDZDAyYaepg== + dependencies: + "@emotion/serialize" "^1.0.0" + "@types/react" "*" + "@types/react-dom" "*" + "@types/react-transition-group" "*" + "@types/react-test-renderer@^18.0.0": version "18.0.0" resolved "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz" @@ -3071,6 +3201,13 @@ dependencies: "@types/react" "*" +"@types/react-transition-group@*": + version "4.4.7" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.7.tgz#bf69f269d74aa78b99097673ca6dd6824a68ef1c" + integrity sha512-ICCyBl5mvyqYp8Qeq9B5G/fyBSRC0zx3XM3sCC6KkcMsNeAHqXBKkmat4GqdJET5jtYUpZXrxI5flve5qhi2Eg== + dependencies: + "@types/react" "*" + "@types/react-transition-group@^4.4.5": version "4.4.6" resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz" @@ -4187,10 +4324,10 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== -bootstrap@^5.3.0: - version "5.3.0" - resolved "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.0.tgz" - integrity sha512-UnBV3E3v4STVNQdms6jSGO2CvOkjUMdDAVR2V5N4uCMdaIkaQjbcEAMqRimDHIs4uqBYzDAKCQwCB+97tJgHQw== +bootstrap@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.2.tgz#97226583f27aae93b2b28ab23f4c114757ff16ae" + integrity sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g== brace-expansion@^1.1.7: version "1.1.11" @@ -4413,7 +4550,7 @@ check-types@^11.1.1: resolved "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz" integrity sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA== -chokidar@^3.4.2, chokidar@^3.5.3: +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.2, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -4736,7 +4873,7 @@ content-type@~1.0.4: resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.9.0" resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== @@ -6339,6 +6476,11 @@ find-cache-dir@^3.3.1: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + find-up@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" @@ -6812,6 +6954,12 @@ hermes-profile-transformer@^0.0.6: dependencies: source-map "^0.7.3" +hoist-non-react-statics@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" hoopy@^0.1.4: version "0.1.4" @@ -7014,6 +7162,10 @@ immer@^9.0.7: resolved "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz" integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== +immutable@^4.0.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== import-fresh@^2.0.0: version "2.0.0" @@ -10530,7 +10682,7 @@ react-app-polyfill@^3.0.0: react-bootstrap@^2.8.0: version "2.8.0" - resolved "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz" + resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-2.8.0.tgz#781f254b33090c1d50ed521b40697727267c6add" integrity sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww== dependencies: "@babel/runtime" "^7.21.0" @@ -10609,9 +10761,14 @@ react-icons@^4.10.1: resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.10.1.tgz#3f3b5eec1f63c1796f6a26174a1091ca6437a500" integrity sha512-/ngzDP/77tlCfqthiiGNZeYFACw85fUjZtLbedmJ5DTlNDIwETxhwBzdOJ21zj4iJdvc0J3y7yOsX3PpxAJzrw== +react-input-autosize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-3.0.0.tgz#6b5898c790d4478d69420b55441fcc31d5c50a85" + integrity sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg== + dependencies: + prop-types "^15.5.8" -react-is@^16.10.2, react-is@^16.13.1, react-is@^16.3.2: - +react-is@^16.10.2, react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -10772,6 +10929,18 @@ react-scripts@^5.0.1: optionalDependencies: fsevents "^2.3.2" +react-select@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-4.3.1.tgz#389fc07c9bc7cf7d3c377b7a05ea18cd7399cb81" + integrity sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q== + dependencies: + "@babel/runtime" "^7.12.0" + "@emotion/cache" "^11.4.0" + "@emotion/react" "^11.1.1" + memoize-one "^5.0.0" + prop-types "^15.6.0" + react-input-autosize "^3.0.0" + react-transition-group "^4.3.0" react-shallow-renderer@^16.15.0: version "16.15.0" @@ -10789,6 +10958,11 @@ react-smooth@^2.0.2: fast-equals "^5.0.0" react-transition-group "2.9.0" +react-spinners@^0.13.8: + version "0.13.8" + resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.13.8.tgz#5262571be0f745d86bbd49a1e6b49f9f9cb19acc" + integrity sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA== + react-transition-group@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" @@ -10799,8 +10973,7 @@ react-transition-group@2.9.0: prop-types "^15.6.2" react-lifecycles-compat "^3.0.4" - -react-transition-group@^4.4.5: +react-transition-group@^4.3.0, react-transition-group@^4.4.5: version "4.4.5" resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz" integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== @@ -11243,6 +11416,15 @@ sass-loader@^12.3.0: klona "^2.0.4" neo-async "^2.6.2" +sass@^1.67.0: + version "1.67.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.67.0.tgz#fed84d74b9cd708db603b1380d6dc1f71bb24f6f" + integrity sha512-SVrO9ZeX/QQyEGtuZYCVxoeAL5vGlYjJ9p4i4HFuekWl8y/LtJ7tJc10Z+ck1c8xOuoBm2MYzcLfTAffD0pl/A== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + sax@~1.2.4: version "1.2.4" resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" @@ -11550,7 +11732,7 @@ source-list-map@^2.0.0, source-list-map@^2.0.1: resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -source-map-js@^1.0.1, source-map-js@^1.0.2: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -11593,7 +11775,7 @@ source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, sourc resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.5.6: +source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== @@ -11880,6 +12062,11 @@ stylehacks@^5.1.1: browserslist "^4.21.4" postcss-selector-parser "^6.0.4" +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + sucrase@^3.32.0: version "3.33.0" resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.33.0.tgz" diff --git a/demand-capacity-mgmt-specification/src/main/resources/openapi.yml b/demand-capacity-mgmt-specification/src/main/resources/openapi.yml index 0916e61c..0fe693db 100644 --- a/demand-capacity-mgmt-specification/src/main/resources/openapi.yml +++ b/demand-capacity-mgmt-specification/src/main/resources/openapi.yml @@ -28,6 +28,67 @@ servers: paths: + /statuses: + post: + tags: + - statuses + summary: create a status + operationId: postStatus + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/StatusRequest' + responses: + 200: + description: General greeting + content: + application/json: + schema: + $ref: '#/components/schemas/StatusesResponse' + + get: + tags: + - statuses + summary: get statuses object + operationId: getStatuses + responses: + 200: + description: General greeting + content: + application/json: + schema: + # type: object + # items: + $ref: '#/components/schemas/StatusesResponse' + + put: + tags: + - statuses + summary: update statuses by Id + operationId: updateStatusesById + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/StatusRequest' + parameters: + - in: 'path' + name: 'status_id' + schema: + type: string + required: true + responses: + 200: + description: Update of statuses + content: + application/json: + schema: + $ref: '#/components/schemas/StatusesResponse' + + /demand: post: tags: @@ -62,6 +123,43 @@ paths: items: $ref: '#/components/schemas/MaterialDemandResponse' + /demand/series: + post: + tags: + - Demand + summary: get the list of demand series by composite key + operationId: getLinkedDemandSeriesByCompositeKeyID + requestBody: + description: Demand series composite request object + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DemandSeriesCompositeRequest' + responses: + 200: + description: General greeting + content: + application/json: + schema: + $ref: '#/components/schemas/DemandSeriesCompositeResponse' + /demand/series/unlink: + post: + tags: + - Demand + summary: unlink material demands and demand series + operationId: unlinkedDemandSeriesComposites + requestBody: + description: Demand series composite request object + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DemandSeriesUnlinkRequest' + responses: + 204: + description: no content + /demand/{demand_id}: get: tags: @@ -121,12 +219,27 @@ paths: 200: description: Delete demand with id + /capacityGroup/link: + post: + tags: + - capacityGroup + summary: create a link to capacityGroup and linkedDemand + operationId: postLinkedCapacityGroupDemand + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LinkCGDSRequest' + responses: + 204: + description: no content /capacityGroup: get: tags: - capacityGroup summary: capacityGroup - operationId: getCapacityGroup + operationId: getCapacityGroups responses: 200: description: CapacityGroupResponse @@ -136,7 +249,6 @@ paths: type: array items: $ref: '#/components/schemas/CapacityGroupDefaultViewResponse' - post: tags: - capacityGroup @@ -170,19 +282,34 @@ paths: required: true responses: 200: - description: General greeting + description: Get capacity group representation content: application/json: schema: $ref: '#/components/schemas/CapacityGroupResponse' - /weekbasedcapacitygroup: + get: + tags: + - weekBasedCapacityGroup + summary: get weekBasedCapacityGroup + operationId: getWeekBasedCapacityGroup + responses: + 200: + description: WeekBasedCapacityGroupResponse + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/WeekBasedCapacityGroupDtoResponse' + + post: tags: - weekBasedCapacityGroup - summary: weekBasedCapacityGroup + summary: post weekBasedCapacityGroup operationId: postWeekBasedCapacityGroup requestBody: required: true @@ -191,16 +318,90 @@ paths: schema: type: array items: - $ref: '#/components/schemas/WeekBasedCapacityGroupRequest' + $ref: '#/components/schemas/WeekBasedCapacityGroupDtoRequest' responses: 200: description: weekBasedCapacityGroup endpoint + + /weekbasedcapacitygroup/{weekBasedCapacity_id}: + + put: + tags: + - weekBasedCapacityGroup + summary: update weekBasedCapacityGroup by id + operationId: updateWeekBasedCapacityGroupById + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WeekBasedCapacityGroupDtoRequest' + parameters: + - in: 'path' + name: 'weekBasedCapacity_id' + schema: + type: string + required: true + responses: + 200: + description: Update of weekBasedCapacityGroup + content: + application/json: + schema: + $ref: '#/components/schemas/WeekBasedCapacityGroupDtoResponse' + + + + /weekbasedmaterialdemand/{weekBasedMaterialDemand_id}: + + put: + tags: + - weekBasedMaterialDemand + summary: update weekBasedMaterialDemand + operationId: updateWeekBasedMaterialDemandById + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WeekBasedMaterialDemandRequestDto' + parameters: + - in: 'path' + name: 'weekBasedMaterialDemand_id' + schema: + type: string + required: true + responses: + 200: + description: Update of weekBasedMaterialDemand + content: + application/json: + schema: + $ref: '#/components/schemas/WeekBasedMaterialDemandResponseDto' + + /weekbasedmaterialdemand: + get: + tags: + - weekBasedMaterialDemand + summary: get weekBasedMaterialDemand + operationId: getWeekBasedMaterialDemand + responses: + 200: + description: WeekBasedMaterialDemandResponse + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/WeekBasedMaterialDemandResponseDto' + + post: tags: - weekBasedMaterialDemand - summary: weekBasedCapacityGroup + summary: post weekBasedMaterialDemand operationId: postWeekBasedMaterialDemand requestBody: required: true @@ -371,6 +572,54 @@ paths: components: schemas: + + StatusesResponse: + type: object + properties: + general: + $ref: '#/components/schemas/StatusDto' + todos: + $ref: '#/components/schemas/StatusDto' + statusImprovement: + $ref: '#/components/schemas/StatusDto' + statusDegredation: + $ref: '#/components/schemas/StatusDto' + overall_general: + $ref: '#/components/schemas/StatusDto' + overall_todos: + $ref: '#/components/schemas/StatusDto' + overall_statusImprovement: + $ref: '#/components/schemas/StatusDto' + overall_statusDegredation: + $ref: '#/components/schemas/StatusDto' + + + StatusRequest: + type: object + properties: + general: + $ref: '#/components/schemas/StatusDto' + todos: + $ref: '#/components/schemas/StatusDto' + statusImprovement: + $ref: '#/components/schemas/StatusDto' + statusDegredation: + $ref: '#/components/schemas/StatusDto' + overall_general: + $ref: '#/components/schemas/StatusDto' + overall_todos: + $ref: '#/components/schemas/StatusDto' + overall_statusImprovement: + $ref: '#/components/schemas/StatusDto' + overall_statusDegredation: + $ref: '#/components/schemas/StatusDto' + + StatusDto: + type: object + properties: + count: + type: integer + DemandRequestDto: type: object properties: @@ -395,6 +644,35 @@ components: description: type: string + CapacityGroupResponse: + type: object + properties: + capacityGroupId: + type: string + capacitygroupname: + type: string + defaultActualCapacity: + type: number + format: float + defaultMaximumCapacity: + type: number + format: float + startDate: + type: string + endDate: + type: string + customer: + $ref: '#/components/schemas/CompanyDto' + supplier: + $ref: '#/components/schemas/CompanyDto' + linkMaterialDemandIds: + type: array + items: + type: string + format: uuid + description: 'Array of UUIDs representing linked material demand IDs.' + + DemandResponseDto: type: object properties: @@ -461,6 +739,42 @@ components: maximumCapacity: type: string + + + WeekBasedCapacityGroupDtoRequest: + type: object + properties: + id: + type: string + viewed: + type: boolean + WeekBasedCapacityGroupRequest: + $ref: '#/components/schemas/WeekBasedCapacityGroupRequest' + + + WeekBasedMaterialDemandResponseDto: + type: object + properties: + id: + type: string + viewed: + type: boolean + WeekBasedMaterialDemandRequest: + $ref: '#/components/schemas/WeekBasedMaterialDemandRequest' + + + WeekBasedCapacityGroupDtoResponse: + type: object + properties: + id: + type: string + viewed: + type: boolean + WeekBasedCapacityGroupRequest: + $ref: '#/components/schemas/WeekBasedCapacityGroupRequest' + + + WeekBasedCapacityGroupRequest: type: object properties: @@ -489,35 +803,31 @@ components: customer: type: string - DemandSeriesDto: + WeekBasedMaterialDemandRequest: type: object properties: - demand: + unityOfMeasure: type: string - calendarWeek: + materialDescriptionCustomer: type: string - - DemandSeriesCategoryDto: - type: object - properties: - id: + materialDemandId: type: string - - DemandWeekSeriesDto: - type: object - properties: - expectedSupplierLocation: + materialNumberSupplier: type: string - demands: + supplier: + type: string + changedAt: + type: string + demandSeries: type: array items: - $ref: '#/components/schemas/DemandSeriesDto' - customerLocation: + $ref: '#/components/schemas/DemandWeekSeriesDto' + materialNumberCustomer: + type: string + customer: type: string - demandCategory: - $ref: '#/components/schemas/DemandSeriesCategoryDto' - WeekBasedMaterialDemandRequestDto: + WeekBasedMaterialDemandResponse: type: object properties: unityOfMeasure: @@ -541,6 +851,45 @@ components: customer: type: string + DemandSeriesDto: + type: object + properties: + demand: + type: string + calendarWeek: + type: string + + DemandSeriesCategoryDto: + type: object + properties: + id: + type: string + + DemandWeekSeriesDto: + type: object + properties: + expectedSupplierLocation: + type: string + demands: + type: array + items: + $ref: '#/components/schemas/DemandSeriesDto' + customerLocation: + type: string + demandCategory: + $ref: '#/components/schemas/DemandSeriesCategoryDto' + + WeekBasedMaterialDemandRequestDto: + type: object + properties: + id: + type: string + viewed: + type: boolean + WeekBasedMaterialDemandRequest: + $ref: '#/components/schemas/WeekBasedMaterialDemandRequest' + + MaterialDemandRequest: type: object properties: @@ -634,9 +983,17 @@ components: properties: id: type: string - codeValue: + dimension: + type: string + unCode: + type: string + description: + type: string + descriptionGerman: + type: string + unSymbol: type: string - displayValue: + cxSymbol: type: string MaterialDemandSeriesResponse: @@ -650,12 +1007,57 @@ components: $ref: '#/components/schemas/CompanyDto' demandCategory: $ref: '#/components/schemas/DemandCategoryResponse' + demandSeriesValues: + type: array + items: + $ref: '#/components/schemas/MaterialDemandSeriesValue' + DemandSeriesCompositeResponse: + type: object + properties: + demandSeries: + type: array + items: + $ref: '#/components/schemas/LinkedDemandMaterialCompositeResponse' + + LinkedDemandMaterialCompositeResponse: + type: object + properties: + demandSeriesID: + type: string + materialDemandID: + type: string + customerLocation: + $ref: '#/components/schemas/CompanyDto' + expectedSupplierLocation: + type: array + items: + $ref: '#/components/schemas/CompanyDto' + demandCategory: + $ref: '#/components/schemas/DemandCategoryResponse' demandSeriesValues: type: array items: $ref: '#/components/schemas/MaterialDemandSeriesValue' + DemandSeriesCompositeRequest: + type: object + properties: + demandCategoryCodeID: + type: string + customerID: + type: string + materialNumberCustomer: + type: string + DemandSeriesUnlinkRequest: + type: object + properties: + materialDemandID: + type: string + capacityGroupID: + type: string + + DemandCategoryResponse: type: object properties: @@ -698,7 +1100,7 @@ components: materialNumberCustomer: type: string - CapacityGroupResponse: + DeprecatedCapacityGroupResponse: type: object properties: capacityGroupId: @@ -750,31 +1152,41 @@ components: status: type: string - CapacityGroupRequest: + LinkCGDSRequest: type: object properties: - capacities: - type: array - items: - $ref: '#/components/schemas/CapacityRequest' - linkedDemandSeries: - type: array - items: - type: string - supplierLocations: + capacityGroupID: + type: string + linkedMaterialDemandID: type: array items: type: string - customer: + format: uuid + + CapacityGroupRequest: + type: object + properties: + capacitygroupname: type: string - supplier: + defaultActualCapacity: + type: number + format: float + defaultMaximumCapacity: + type: number + format: float + startDate: type: string - unitOfMeasure: + endDate: type: string - changeAt: + customer: type: string - name: + supplier: type: string + linkDemandSeriesID: + type: array + items: + type: string + format: uuid FavoriteRequest: type: object