acl = $acl; $this->entityManager = $entityManager; $this->fieldUtil = $fieldUtil; $this->metadata = $metadata; $this->configDataProvider = $configDataProvider; $this->currencyConverter = $currencyConverter; } public function process(Params $params, Data $data): void { $entityType = $params->getEntityType(); $id = $params->getId(); if (!$this->acl->checkScope($entityType, 'edit')) { throw new Forbidden(); } $fieldList = $this->getFieldList($entityType, $data); if (empty($fieldList)) { throw new Forbidden("No fields to convert."); } $baseCurrency = $this->configDataProvider->getBaseCurrency(); $targetCurrency = $data->get('targetCurrency'); if (!$targetCurrency) { throw new BadRequest("No target currency."); } $rates = $this->getRatesFromData($data) ?? $this->configDataProvider->getCurrencyRates(); if ($targetCurrency !== $baseCurrency && !$rates->hasRate($targetCurrency)) { throw new BadRequest("Target currency rate is not specified."); } $entity = $this->entityManager->getEntity($entityType, $id); if (!$entity) { throw new NotFound(); } if (!$this->acl->checkEntity($entity, 'edit')) { throw new Forbidden(); } $this->convertEntity($entity, $fieldList, $targetCurrency, $rates); } /** * @param string[] $fieldList */ protected function convertEntity( Entity $entity, array $fieldList, string $targetCurrency, CurrencyRates $rates ): void { $entityDefs = $this->entityManager ->getDefs() ->getEntity($entity->getEntityType()); foreach ($fieldList as $field) { $disabled = $entityDefs->getField($field)->getParam('conversionDisabled'); if ($disabled) { continue; } $amount = $entity->get($field); $code = $entity->get($field . 'Currency'); if ($amount === null) { continue; } if ($targetCurrency === $code) { continue; } $value = new Currency($amount, $code); $convertedValue = $this->currencyConverter->convertWithRates($value, $targetCurrency, $rates); $entity->set($field, $convertedValue->getAmount()); $entity->set($field . 'Currency', $convertedValue->getCode()); } $this->entityManager->saveEntity($entity); } protected function getRatesFromData(Data $data): ?CurrencyRates { if ($data->get('rates') === null) { return null; } $baseCurrency = $this->configDataProvider->getBaseCurrency(); $ratesArray = get_object_vars($data->get('rates')); $ratesArray[$baseCurrency] = 1.0; return CurrencyRates::fromArray($ratesArray, $baseCurrency); } /** * @return string[] */ protected function getFieldList(string $entityType, Data $data): array { $forbiddenFieldList = $this->acl->getScopeForbiddenFieldList($entityType, 'edit'); $resultList = []; $fieldList = $data->get('fieldList') ?? $this->fieldUtil->getEntityTypeFieldList($entityType); foreach ($fieldList as $field) { $type = $this->metadata->get(['entityDefs', $entityType, 'fields', $field, 'type']); if ($type !== 'currency') { continue; } if (in_array($field, $forbiddenFieldList)) { continue; } $resultList[] = $field; } return $resultList; } }