mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 01:25:55 +02:00
Added a button to update exchange rates via web gui.
This commit is contained in:
parent
ff7c1cddc7
commit
af42c3cca0
11 changed files with 1137 additions and 909 deletions
|
@ -16,6 +16,7 @@
|
||||||
"dompdf/dompdf": "^0.8.5",
|
"dompdf/dompdf": "^0.8.5",
|
||||||
"erusev/parsedown": "^1.7",
|
"erusev/parsedown": "^1.7",
|
||||||
"florianv/swap": "^4.0",
|
"florianv/swap": "^4.0",
|
||||||
|
"florianv/swap-bundle": "dev-master",
|
||||||
"friendsofsymfony/ckeditor-bundle": "^2.0",
|
"friendsofsymfony/ckeditor-bundle": "^2.0",
|
||||||
"gregwar/captcha-bundle": "^2.1.0",
|
"gregwar/captcha-bundle": "^2.1.0",
|
||||||
"league/html-to-markdown": "^4.8",
|
"league/html-to-markdown": "^4.8",
|
||||||
|
|
67
composer.lock
generated
67
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "07efae478ec4174b9406bb3b35c8aa82",
|
"content-hash": "4c03a0cabed4fc08ab4f6e0fe85dd2bf",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "beberlei/assert",
|
"name": "beberlei/assert",
|
||||||
|
@ -1668,6 +1668,70 @@
|
||||||
],
|
],
|
||||||
"time": "2020-06-05T12:28:59+00:00"
|
"time": "2020-06-05T12:28:59+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "florianv/swap-bundle",
|
||||||
|
"version": "dev-master",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/florianv/symfony-swap.git",
|
||||||
|
"reference": "3d31a6cc5c37ab36e4af2a47664b47260a628b69"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/florianv/symfony-swap/zipball/3d31a6cc5c37ab36e4af2a47664b47260a628b69",
|
||||||
|
"reference": "3d31a6cc5c37ab36e4af2a47664b47260a628b69",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"florianv/swap": "^4.0",
|
||||||
|
"php": "^5.6|^7.0",
|
||||||
|
"symfony/framework-bundle": "~3.0|~4.0|~5.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"nyholm/psr7": "^1.1",
|
||||||
|
"php-http/guzzle6-adapter": "^1.0",
|
||||||
|
"php-http/message": "^1.7",
|
||||||
|
"phpunit/phpunit": "~5.0",
|
||||||
|
"symfony/cache": "~3.0|~4.0|~5.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"symfony/cache": "For caching"
|
||||||
|
},
|
||||||
|
"type": "symfony-bundle",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "5.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Florianv\\SwapBundle\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Florian Voutzinos",
|
||||||
|
"email": "florian@voutzinos.com",
|
||||||
|
"homepage": "http://florian.voutzinos.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Integrates the Swap library with Symfony",
|
||||||
|
"homepage": "https://github.com/florianv/FlorianvSwapBundle",
|
||||||
|
"keywords": [
|
||||||
|
"Rate",
|
||||||
|
"bundle",
|
||||||
|
"conversion",
|
||||||
|
"currency",
|
||||||
|
"exchange",
|
||||||
|
"money",
|
||||||
|
"symfony"
|
||||||
|
],
|
||||||
|
"time": "2020-05-12T11:25:49+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "friendsofsymfony/ckeditor-bundle",
|
"name": "friendsofsymfony/ckeditor-bundle",
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
|
@ -12795,6 +12859,7 @@
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": {
|
"stability-flags": {
|
||||||
|
"florianv/swap-bundle": 20,
|
||||||
"roave/security-advisories": 20
|
"roave/security-advisories": 20
|
||||||
},
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
|
|
|
@ -24,4 +24,5 @@ return [
|
||||||
R\U2FTwoFactorBundle\RU2FTwoFactorBundle::class => ['all' => true],
|
R\U2FTwoFactorBundle\RU2FTwoFactorBundle::class => ['all' => true],
|
||||||
Translation\Bundle\TranslationBundle::class => ['all' => true],
|
Translation\Bundle\TranslationBundle::class => ['all' => true],
|
||||||
Symplify\ParameterNameGuard\ParameterNameGuardBundle::class => ['dev' => true, 'test' => true],
|
Symplify\ParameterNameGuard\ParameterNameGuardBundle::class => ['dev' => true, 'test' => true],
|
||||||
|
Florianv\SwapBundle\FlorianvSwapBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
|
6
config/packages/swap.yaml
Normal file
6
config/packages/swap.yaml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
florianv_swap:
|
||||||
|
providers:
|
||||||
|
exchange_rates_api: ~
|
||||||
|
fixer:
|
||||||
|
access_key: "%env(FIXER_API_KEY)%"
|
||||||
|
european_central_bank: ~ # European Central Bank
|
|
@ -142,6 +142,11 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
$base_currency: '%partdb.default_currency%'
|
$base_currency: '%partdb.default_currency%'
|
||||||
|
|
||||||
|
App\Services\ExchangeRateUpdater:
|
||||||
|
arguments:
|
||||||
|
$base_currency: '%partdb.default_currency%'
|
||||||
|
$swap: '@florianv_swap.swap'
|
||||||
|
|
||||||
###################################################################################################################
|
###################################################################################################################
|
||||||
# User system
|
# User system
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
|
|
|
@ -47,14 +47,29 @@ use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Parameters\CurrencyParameter;
|
use App\Entity\Parameters\CurrencyParameter;
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
use App\Form\AdminPages\CurrencyAdminForm;
|
use App\Form\AdminPages\CurrencyAdminForm;
|
||||||
|
use App\Services\Attachments\AttachmentSubmitHandler;
|
||||||
use App\Services\EntityExporter;
|
use App\Services\EntityExporter;
|
||||||
use App\Services\EntityImporter;
|
use App\Services\EntityImporter;
|
||||||
|
use App\Services\ExchangeRateUpdater;
|
||||||
|
use App\Services\LabelSystem\Barcodes\BarcodeExampleElementsGenerator;
|
||||||
|
use App\Services\LabelSystem\LabelGenerator;
|
||||||
|
use App\Services\LogSystem\EventCommentHelper;
|
||||||
|
use App\Services\LogSystem\HistoryHelper;
|
||||||
|
use App\Services\LogSystem\TimeTravel;
|
||||||
use App\Services\StructuralElementRecursionHelper;
|
use App\Services\StructuralElementRecursionHelper;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Exchanger\Exception\ChainException;
|
||||||
|
use Exchanger\Exception\Exception;
|
||||||
|
use Exchanger\Exception\UnsupportedCurrencyPairException;
|
||||||
|
use Omines\DataTablesBundle\DataTableFactory;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/currency")
|
* @Route("/currency")
|
||||||
|
@ -70,6 +85,40 @@ class CurrencyController extends BaseAdminController
|
||||||
protected $attachment_class = CurrencyAttachment::class;
|
protected $attachment_class = CurrencyAttachment::class;
|
||||||
protected $parameter_class = CurrencyParameter::class;
|
protected $parameter_class = CurrencyParameter::class;
|
||||||
|
|
||||||
|
protected $exchangeRateUpdater;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
TranslatorInterface $translator,
|
||||||
|
UserPasswordEncoderInterface $passwordEncoder,
|
||||||
|
AttachmentSubmitHandler $attachmentSubmitHandler,
|
||||||
|
EventCommentHelper $commentHelper,
|
||||||
|
HistoryHelper $historyHelper,
|
||||||
|
TimeTravel $timeTravel,
|
||||||
|
DataTableFactory $dataTableFactory,
|
||||||
|
EventDispatcherInterface $eventDispatcher,
|
||||||
|
BarcodeExampleElementsGenerator $barcodeExampleGenerator,
|
||||||
|
LabelGenerator $labelGenerator,
|
||||||
|
EntityManagerInterface $entityManager,
|
||||||
|
ExchangeRateUpdater $exchangeRateUpdater
|
||||||
|
|
||||||
|
) {
|
||||||
|
$this->exchangeRateUpdater = $exchangeRateUpdater;
|
||||||
|
|
||||||
|
parent::__construct(
|
||||||
|
$translator,
|
||||||
|
$passwordEncoder,
|
||||||
|
$attachmentSubmitHandler,
|
||||||
|
$commentHelper,
|
||||||
|
$historyHelper,
|
||||||
|
$timeTravel,
|
||||||
|
$dataTableFactory,
|
||||||
|
$eventDispatcher,
|
||||||
|
$barcodeExampleGenerator,
|
||||||
|
$labelGenerator,
|
||||||
|
$entityManager
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{id}", name="currency_delete", methods={"DELETE"})
|
* @Route("/{id}", name="currency_delete", methods={"DELETE"})
|
||||||
*
|
*
|
||||||
|
@ -80,6 +129,30 @@ class CurrencyController extends BaseAdminController
|
||||||
return $this->_delete($request, $entity, $recursionHelper);
|
return $this->_delete($request, $entity, $recursionHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function additionalActionEdit(FormInterface $form, AbstractNamedDBElement $entity): bool
|
||||||
|
{
|
||||||
|
if (!$entity instanceof Currency) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($form->get('update_exchange_rate')->isClicked()) {
|
||||||
|
$this->denyAccessUnlessGranted('edit', $entity);
|
||||||
|
try {
|
||||||
|
$this->exchangeRateUpdater->update($entity);
|
||||||
|
$this->addFlash('info', 'currency.edit.exchange_rate_updated.success');
|
||||||
|
} catch (ChainException $exception) {
|
||||||
|
$exception = $exception->getExceptions()[0];
|
||||||
|
if ($exception instanceof UnsupportedCurrencyPairException || stripos($exception->getMessage(), "supported") !== false) {
|
||||||
|
$this->addFlash('error', 'currency.edit.exchange_rate_update.unsupported_currency');
|
||||||
|
} else {
|
||||||
|
$this->addFlash('error', 'currency.edit.exchange_rate_update.generic_error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="currency_edit")
|
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="currency_edit")
|
||||||
* @Route("/{id}", requirements={"id"="\d+"})
|
* @Route("/{id}", requirements={"id"="\d+"})
|
||||||
|
|
|
@ -46,6 +46,7 @@ use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Form\Type\BigDecimalMoneyType;
|
use App\Form\Type\BigDecimalMoneyType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
|
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
@ -82,5 +83,16 @@ class CurrencyAdminForm extends BaseEntityAdminForm
|
||||||
'scale' => 6,
|
'scale' => 6,
|
||||||
'disabled' => ! $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
'disabled' => ! $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if(!$is_new) {
|
||||||
|
$builder->add(
|
||||||
|
'update_exchange_rate',
|
||||||
|
SubmitType::class,
|
||||||
|
[
|
||||||
|
'label' => 'currency.edit.update_rate',
|
||||||
|
'disabled' => ! $this->security->isGranted('edit', $entity)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
34
src/Services/ExchangeRateUpdater.php
Normal file
34
src/Services/ExchangeRateUpdater.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Entity\PriceInformations\Currency;
|
||||||
|
use Brick\Math\BigDecimal;
|
||||||
|
use Swap\Swap;
|
||||||
|
|
||||||
|
class ExchangeRateUpdater
|
||||||
|
{
|
||||||
|
private $base_currency;
|
||||||
|
private $swap;
|
||||||
|
|
||||||
|
public function __construct(string $base_currency, Swap $swap)
|
||||||
|
{
|
||||||
|
$this->base_currency = $base_currency;
|
||||||
|
$this->swap = $swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the exchange rate of the given currency using the globally configured providers.
|
||||||
|
* @param Currency $currency
|
||||||
|
* @return Currency
|
||||||
|
*/
|
||||||
|
public function update(Currency $currency): Currency
|
||||||
|
{
|
||||||
|
$rate = $this->swap->latest($currency->getIsoCode().'/'.$this->base_currency);
|
||||||
|
$currency->setExchangeRate(BigDecimal::of($rate->getValue()));
|
||||||
|
return $currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -150,6 +150,9 @@
|
||||||
"florianv/swap": {
|
"florianv/swap": {
|
||||||
"version": "3.5.0"
|
"version": "3.5.0"
|
||||||
},
|
},
|
||||||
|
"florianv/swap-bundle": {
|
||||||
|
"version": "5.0.0"
|
||||||
|
},
|
||||||
"friendsofphp/php-cs-fixer": {
|
"friendsofphp/php-cs-fixer": {
|
||||||
"version": "2.2",
|
"version": "2.2",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ form_row(form.exchange_rate) }}
|
{{ form_row(form.exchange_rate) }}
|
||||||
|
|
||||||
|
{% if form.update_exchange_rate is defined %}
|
||||||
|
{{ form_row(form.update_exchange_rate, {attr: {class: 'btn-link'}}) }}
|
||||||
|
{% endif %}
|
||||||
{% if entity.inverseExchangeRate %}
|
{% if entity.inverseExchangeRate %}
|
||||||
<span class="form-text text-muted offset-3 col-9">
|
<span class="form-text text-muted offset-3 col-9">
|
||||||
{{ '1'|format_currency(default_currency) }} = {{ entity.inverseExchangeRate.tofloat | format_currency(entity.isoCode, {fraction_digit: 5}) }}
|
{{ '1'|format_currency(default_currency) }} = {{ entity.inverseExchangeRate.tofloat | format_currency(entity.isoCode, {fraction_digit: 5}) }}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue