diff --git a/config/class.yaml b/config/class.yaml index 1de06806..e818c5e5 100644 --- a/config/class.yaml +++ b/config/class.yaml @@ -17,6 +17,11 @@ services: Pimcore\Bundle\StudioBackendBundle\Class\Service\FieldCollection\LayoutDefinitionServiceInterface: class: Pimcore\Bundle\StudioBackendBundle\Class\Service\FieldCollection\LayoutDefinitionService + Pimcore\Bundle\StudioBackendBundle\Class\Repository\QuantityValueRepositoryInterface: + class: Pimcore\Bundle\StudioBackendBundle\Class\Repository\QuantityValueRepository + + Pimcore\Bundle\StudioBackendBundle\Class\Service\QuantityValueServiceInterface: + class: Pimcore\Bundle\StudioBackendBundle\Class\Service\QuantityValueService # # Hydrators diff --git a/src/Class/Attribute/Request/ConvertRequestBody.php b/src/Class/Attribute/Request/ConvertRequestBody.php new file mode 100644 index 00000000..799e4800 --- /dev/null +++ b/src/Class/Attribute/Request/ConvertRequestBody.php @@ -0,0 +1,34 @@ +value)] + #[Post( + path: self::PREFIX . '/class/quantity-value/convert-all', + operationId: 'class_quantity_value_unit_convert_all', + description: 'class_quantity_value_unit_convert_all_description', + summary: 'class_quantity_value_unit_convert_all_summary', + tags: [Tags::ClassDefinition->value] + )] + #[SuccessResponse( + description: 'class_quantity_value_unit_convert_all_success_response', + content: new JsonContent(ref: ConvertedQuantityValues::class) + )] + #[ConvertRequestBody(ConvertAllParameters::class)] + #[DefaultResponses([ + HttpResponseCodes::UNAUTHORIZED, + HttpResponseCodes::NOT_FOUND, + ])] + public function covertAll(#[MapRequestPayload] ConvertAllParameters $parameters): JsonResponse + { + return $this->jsonResponse($this->quantityValueService->convertAllUnits($parameters)); + } +} diff --git a/src/Class/Controller/QuantityValue/ConvertController.php b/src/Class/Controller/QuantityValue/ConvertController.php new file mode 100644 index 00000000..b68fd81f --- /dev/null +++ b/src/Class/Controller/QuantityValue/ConvertController.php @@ -0,0 +1,83 @@ +value)] + #[Post( + path: self::PREFIX . '/class/quantity-value/convert', + operationId: 'class_quantity_value_unit_convert', + description: 'class_quantity_value_unit_convert_description', + summary: 'class_quantity_value_unit_convert_summary', + tags: [Tags::ClassDefinition->value] + )] + #[SuccessResponse( + description: 'class_quantity_value_unit_convert_success_response', + content: new ConvertedValueJson() + )] + #[ConvertRequestBody] + #[DefaultResponses([ + HttpResponseCodes::UNAUTHORIZED, + HttpResponseCodes::NOT_FOUND, + ])] + public function convert(#[MapRequestPayload] ConvertParameters $parameters): JsonResponse + { + return $this->jsonResponse(['data' => $this->quantityValueService->convertUnit($parameters)]); + } +} diff --git a/src/Class/Controller/QuantityValue/UnitListController.php b/src/Class/Controller/QuantityValue/UnitListController.php new file mode 100644 index 00000000..b6e26905 --- /dev/null +++ b/src/Class/Controller/QuantityValue/UnitListController.php @@ -0,0 +1,73 @@ +value)] + #[Get( + path: self::PREFIX . '/class/quantity-value/unit-list', + operationId: 'class_quantity_value_unit_list', + description: 'class_quantity_value_unit_list_description', + summary: 'class_quantity_value_unit_list_summary', + tags: [Tags::ClassDefinition->value] + )] + #[SuccessResponse( + description: 'class_quantity_value_unit_list_success_response', + content: new QuantityValueUnitsJson() + )] + #[DefaultResponses([ + HttpResponseCodes::UNAUTHORIZED, + ])] + public function listUnits(): JsonResponse + { + return $this->jsonResponse(['items' => $this->quantityValueService->listUnits()]); + } +} diff --git a/src/Class/Event/PreResponse/QuantityValueConversionEvent.php b/src/Class/Event/PreResponse/QuantityValueConversionEvent.php new file mode 100644 index 00000000..c9c0c15c --- /dev/null +++ b/src/Class/Event/PreResponse/QuantityValueConversionEvent.php @@ -0,0 +1,39 @@ +collection); + } + + /** + * Use this to get additional infos out of the response object + */ + public function getCollection(): ConvertedQuantityValues + { + return $this->collection; + } +} diff --git a/src/Class/Event/PreResponse/QuantityValueUnitEvent.php b/src/Class/Event/PreResponse/QuantityValueUnitEvent.php new file mode 100644 index 00000000..40f58c6b --- /dev/null +++ b/src/Class/Event/PreResponse/QuantityValueUnitEvent.php @@ -0,0 +1,39 @@ +unit); + } + + /** + * Use this to get additional infos out of the response object + */ + public function getUnit(): QuantityValueUnit + { + return $this->unit; + } +} diff --git a/src/Class/Repository/QuantityValueRepository.php b/src/Class/Repository/QuantityValueRepository.php new file mode 100644 index 00000000..9d01939d --- /dev/null +++ b/src/Class/Repository/QuantityValueRepository.php @@ -0,0 +1,52 @@ +setOrderKey(['baseunit', 'factor', 'abbreviation']); + $list->setOrder(['ASC', 'ASC', 'ASC']); + + return $list->getUnits(); + } + + /** + * @return Unit[] + */ + public function getUnitListByBaseUnit(string $baseUnitId, string $fromUnitId): array + { + $list = new Listing(); + $list->setCondition( + 'baseunit = ' . $list->quote($baseUnitId) . + ' AND id != ' . $list->quote($fromUnitId) + ); + + return $list->getUnits(); + } +} diff --git a/src/Class/Repository/QuantityValueRepositoryInterface.php b/src/Class/Repository/QuantityValueRepositoryInterface.php new file mode 100644 index 00000000..f68f2651 --- /dev/null +++ b/src/Class/Repository/QuantityValueRepositoryInterface.php @@ -0,0 +1,35 @@ +fromUnitId; + } + + public function getValue(): float|int + { + return $this->value; + } +} diff --git a/src/Class/Schema/ConvertParameters.php b/src/Class/Schema/ConvertParameters.php new file mode 100644 index 00000000..d63d0c04 --- /dev/null +++ b/src/Class/Schema/ConvertParameters.php @@ -0,0 +1,53 @@ +fromUnitId; + } + + public function getToUnitId(): string + { + return $this->toUnitId; + } + + public function getValue(): float|int + { + return $this->value; + } +} diff --git a/src/Class/Schema/ConvertedQuantityValue.php b/src/Class/Schema/ConvertedQuantityValue.php new file mode 100644 index 00000000..900d8fea --- /dev/null +++ b/src/Class/Schema/ConvertedQuantityValue.php @@ -0,0 +1,57 @@ +unitAbbreviation; + } + + public function getUnitLongName(): string + { + return $this->unitLongName; + } + + public function getConvertedValue(): float + { + return $this->convertedValue; + } +} diff --git a/src/Class/Schema/ConvertedQuantityValues.php b/src/Class/Schema/ConvertedQuantityValues.php new file mode 100644 index 00000000..7b70c494 --- /dev/null +++ b/src/Class/Schema/ConvertedQuantityValues.php @@ -0,0 +1,70 @@ +originalValue; + } + + public function getFromUnitId(): string + { + return $this->fromUnitId; + } + + public function getConvertedValues(): array + { + return $this->convertedValues; + } +} diff --git a/src/Class/Schema/QuantityValueUnit.php b/src/Class/Schema/QuantityValueUnit.php new file mode 100644 index 00000000..288ebc13 --- /dev/null +++ b/src/Class/Schema/QuantityValueUnit.php @@ -0,0 +1,109 @@ +id; + } + + public function getAbbreviation(): ?string + { + return $this->abbreviation; + } + + public function getGroup(): ?string + { + return $this->group; + } + + public function getLongName(): ?string + { + return $this->longName; + } + + public function getBaseUnit(): ?string + { + return $this->baseUnit; + } + + public function getReference(): ?string + { + return $this->reference; + } + + public function getFactor(): ?float + { + return $this->factor; + } + + public function getConversionOffset(): ?float + { + return $this->conversionOffset; + } + + public function getConverter(): ?string + { + return $this->converter; + } +} diff --git a/src/Class/Service/QuantityValueService.php b/src/Class/Service/QuantityValueService.php new file mode 100644 index 00000000..3c602838 --- /dev/null +++ b/src/Class/Service/QuantityValueService.php @@ -0,0 +1,159 @@ +quantityValueRepository->getUnitList(); + $units = []; + + foreach ($listing as $unit) { + $quantityValueUnit = new QuantityValueUnit( + $unit->getId(), + $unit->getAbbreviation(), + $unit->getGroup(), + $unit->getLongname(), + $unit->getBaseunit() ? $unit->getBaseunit()->getId() : null, + $unit->getReference(), + $unit->getFactor(), + $unit->getConversionOffset(), + $unit->getConverter() + ); + + $this->eventDispatcher->dispatch( + new QuantityValueUnitEvent($quantityValueUnit), + QuantityValueUnitEvent::EVENT_NAME + ); + + $units[] = $quantityValueUnit; + } + + return $units; + } + + /** + * @throws DatabaseException|NotFoundException + */ + public function convertUnit(ConvertParameters $parameters): float|int + { + return $this->getConvertedValue( + $this->getUnit($parameters->getFromUnitId()), + $this->getUnit($parameters->getToUnitId()), + $parameters->getValue() + ); + } + + /** + * @throws DatabaseException|NotFoundException + */ + public function convertAllUnits(ConvertAllParameters $parameters): ConvertedQuantityValues + { + $fromUnit = $this->getUnit($parameters->getFromUnitId()); + $baseUnit = $fromUnit->getBaseunit() ?? $fromUnit; + $toUnits = $this->quantityValueRepository->getUnitListByBaseUnit($baseUnit->getId(), $fromUnit->getId()); + + $convertedValues = []; + foreach ($toUnits as $toUnit) { + $convertedValue = $this->getConvertedValue($fromUnit, $toUnit, $parameters->getValue()); + $convertedValues[] = new ConvertedQuantityValue( + $toUnit->getAbbreviation(), + $toUnit->getLongname(), + round($convertedValue, 4) + ); + } + + $collection = new ConvertedQuantityValues( + $parameters->getValue(), + $parameters->getFromUnitId(), + $convertedValues + ); + + $this->eventDispatcher->dispatch( + new QuantityValueConversionEvent($collection), + QuantityValueConversionEvent::EVENT_NAME + ); + + return $collection; + } + + /** + * @throws NotFoundException + */ + private function getUnit(string $unitId): Unit + { + $unit = $this->unitResolver->getById($unitId); + + if ($unit === null) { + throw new NotFoundException('Unit', $unitId); + } + + return $unit; + } + + /** + * @throws DatabaseException + */ + private function getConvertedValue(Unit $fromUnit, Unit $toUnit, float|int $value): float|int + { + try { + $convertedValue = $this->unitConversionService->convert( + new QuantityValue($value, $fromUnit), + $toUnit + ); + } catch (Exception $exception) { + throw new DatabaseException( + sprintf('Could not convert unit "%s" to "%s": %s', $fromUnit, $toUnit, $exception->getMessage()) + ); + } + + return $convertedValue->getValue(); + } +} diff --git a/src/Class/Service/QuantityValueServiceInterface.php b/src/Class/Service/QuantityValueServiceInterface.php new file mode 100644 index 00000000..553005f8 --- /dev/null +++ b/src/Class/Service/QuantityValueServiceInterface.php @@ -0,0 +1,45 @@ +{value} from one unit to another based on the given {fromUnitId} and {toUnitId} +class_quantity_value_unit_convert_summary: Convert quantity value from one unit to another +class_quantity_value_unit_convert_success_response: Converted quantity value +class_quantity_value_unit_convert_all_description: | + Convert quantity {value} from one unit to all other available units based on the given {fromUnitId}.
+ Units have to have {fromUnitId} defined as base unit to be considered for conversion. +class_quantity_value_unit_convert_all_summary: Convert quantity value from one unit to all other related units +class_quantity_value_unit_convert_all_success_response: Converted quantity value \ No newline at end of file