From 09825de7b903003ced9186302c0a363d9c8bcd83 Mon Sep 17 00:00:00 2001 From: Krzysiej Date: Wed, 25 Feb 2026 09:10:14 +0100 Subject: [PATCH 1/3] Add a source of currency exchange rates to scrape command. --- src/Command/ScrapeWebsite.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Command/ScrapeWebsite.php b/src/Command/ScrapeWebsite.php index 8178b64..fa7b719 100644 --- a/src/Command/ScrapeWebsite.php +++ b/src/Command/ScrapeWebsite.php @@ -27,11 +27,13 @@ class ScrapeWebsite extends Command public function __construct(protected Capsule $database) { parent::__construct(); + $this->client = new Client(); + $this->getCurrencyExchange(); + die(); } protected function configure(): void { - $this->client = new Client(); $this->addOption(self::COUNTRY_ID, 'c', InputOption::VALUE_OPTIONAL, 'Country id'); } @@ -147,4 +149,12 @@ class ScrapeWebsite extends Command $productModel->stock()->save($stock); } } + + public function getCurrencyExchange(): void { + + $result = $this->client->request('GET', 'https://api.nbp.pl/api/exchangerates/tables/A/?format=json'); + dd(json_decode($result->getBody()->getContents())); + + + } } -- 2.52.0 From 5088f6173fae400463b258881182300521b54076 Mon Sep 17 00:00:00 2001 From: Krzysiej Date: Thu, 26 Feb 2026 09:15:02 +0100 Subject: [PATCH 2/3] Add conversion rate to products, prices, and save them while scraping. --- src/Command/Migrate.php | 10 ++++++++++ src/Command/ScrapeWebsite.php | 24 ++++++++++++++++++------ src/Models/Price.php | 1 + src/Models/Product.php | 1 + 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/Command/Migrate.php b/src/Command/Migrate.php index 434e768..468aad7 100644 --- a/src/Command/Migrate.php +++ b/src/Command/Migrate.php @@ -246,6 +246,16 @@ class Migrate extends Command $table->json('promotions')->nullable(); }); } + if (!Capsule::schema()->hasColumn('prices', 'conversionRate')) { + Capsule::schema()->table('prices', function (Blueprint $table) { + $table->float('conversionRate')->nullable(); + }); + } + if (!Capsule::schema()->hasColumn('products', 'conversionRate')) { + Capsule::schema()->table('products', function (Blueprint $table) { + $table->float('conversionRate')->nullable(); + }); + } } public function index(): void diff --git a/src/Command/ScrapeWebsite.php b/src/Command/ScrapeWebsite.php index fa7b719..dffd416 100644 --- a/src/Command/ScrapeWebsite.php +++ b/src/Command/ScrapeWebsite.php @@ -23,13 +23,13 @@ class ScrapeWebsite extends Command { const COUNTRY_ID = 'country'; private Client $client; + private array $rates; public function __construct(protected Capsule $database) { parent::__construct(); $this->client = new Client(); - $this->getCurrencyExchange(); - die(); + $this->rates = $this->getCurrencyExchange(); } protected function configure(): void @@ -70,6 +70,7 @@ class ScrapeWebsite extends Command $product->priceLowest = $product->lowestPrice->price; $product->lastSeen = $newestPrice->created_at->format('Y-m-d'); $product->stock = $currentStock->stock; + $product->conversionRate = $newestPrice->conversionRate; $product->save(['timestamps' => false]); $progress->advance(); } @@ -100,7 +101,7 @@ class ScrapeWebsite extends Command $products = array_merge($products, $responseObject->products); $page++; $canLoadMore = $responseObject->canLoadMore; - } catch (GuzzleException $e) { + } catch (GuzzleException) { return $products; } } while ($canLoadMore); @@ -134,6 +135,7 @@ class ScrapeWebsite extends Command $price->price = $product->productPrice; $price->productStandardPrice = $product->productStandardPrice; $price->lowestProductPrice30Days = $product->lowestProductPrice30Days; + $price->conversionRate = $this->getConversionRate($country->currency); $productModel->price()->save($price); } $stockExist = $productModel->stock()->whereRaw("strftime('%Y-%m-%d', created_at) = ?", [date('Y-m-d')])->exists(); @@ -150,11 +152,21 @@ class ScrapeWebsite extends Command } } - public function getCurrencyExchange(): void { - + public function getCurrencyExchange(): array + { $result = $this->client->request('GET', 'https://api.nbp.pl/api/exchangerates/tables/A/?format=json'); - dd(json_decode($result->getBody()->getContents())); + $rates = ['PLN' => 1.0]; + foreach(json_decode($result->getBody()->getContents(),true)[0]['rates'] as $rate){ + $rates[$rate['code']] = $rate['mid']; + } + return $rates; + } + private function getConversionRate(string $currency): float + { + $currency = strtoupper($currency); + + return $this->rates[$currency]; } } diff --git a/src/Models/Price.php b/src/Models/Price.php index a80c94a..9c4d75c 100644 --- a/src/Models/Price.php +++ b/src/Models/Price.php @@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property float $price * @property float $productStandardPrice * @property float $lowestProductPrice30Days + * @property float $conversionRate */ class Price extends Model { diff --git a/src/Models/Product.php b/src/Models/Product.php index 3f5d456..64b03a9 100644 --- a/src/Models/Product.php +++ b/src/Models/Product.php @@ -27,6 +27,7 @@ use function Symfony\Component\Clock\now; * @property float $priceLowest * @property float $productStandardPrice * @property float $lowestProductPrice30Days + * @property float $conversionRate * @property Date $lastSeen * @property integer $stock * @property Object $promotions -- 2.52.0 From e02fa4fc67162131b6c6593cae115f896346dc1f Mon Sep 17 00:00:00 2001 From: Krzysiej Date: Fri, 27 Feb 2026 11:37:23 +0100 Subject: [PATCH 3/3] Display prices in PLN --- src/Models/Product.php | 5 +++++ templates/productList.html.twig | 25 ++++++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/Models/Product.php b/src/Models/Product.php index 64b03a9..21f2e38 100644 --- a/src/Models/Product.php +++ b/src/Models/Product.php @@ -104,6 +104,11 @@ class Product extends Model ); } + public function conversionRate(): ?float + { + return $this->conversionRate; + } + public function isDiscontinued(): bool { return $this->lastSeen < now()->format('Y-m-d'); diff --git a/templates/productList.html.twig b/templates/productList.html.twig index 0f5f595..23b6226 100644 --- a/templates/productList.html.twig +++ b/templates/productList.html.twig @@ -80,19 +80,30 @@ link {% if product.isDiscontinued() or product.priceCurrent == product.productStandardPrice %} - {{ product.priceLowest | format_currency(product.country.currency, {}, product.country.locale) }} + {{ product.priceLowest | format_currency(product.country.currency, {}, product.country.locale) }}
+ {% if product.conversionRate is not empty and product.conversionRate != 1 %} + {{ (product.priceLowest * product.conversionRate) | format_currency('PLN', {}, 'pl') }} + {% endif %} {% else %} {% if product.priceLowest != product.priceCurrent %}{{ product.priceLowest | format_currency(product.country.currency, {}, product.country.locale) }}{% else %} - now lowest{% endif %} + now lowest + {% endif %} {% endif %} - {{ product.priceCurrent | format_currency(product.country.currency, {}, product.country.locale) }} + + {{ product.priceCurrent | format_currency(product.country.currency, {}, product.country.locale) }}
+ {% if product.conversionRate is not empty and product.conversionRate != 1 %} + {{ (product.priceCurrent * product.conversionRate) | format_currency('PLN', {}, 'pl') }} + {% endif %} +
- {% if product.priceCurrent != product.productStandardPrice %}{{ product.productStandardPrice | format_currency(product.country.currency, {}, product.country.locale) }} - {{ ((1 - product.priceCurrent / product.productStandardPrice)*100)|number_format(0) }}% + {% if product.priceCurrent != product.productStandardPrice %} + {{ product.productStandardPrice | format_currency(product.country.currency, {}, product.country.locale) }} + {% if product.conversionRate is not empty and product.conversionRate != 1 %} + {{ (product.productStandardPrice * product.conversionRate) | format_currency('PLN', {}, 'pl') }} + {% endif %} + {{ ((1 - product.priceCurrent / product.productStandardPrice)*100)|number_format(0) }}% {% endif %}
-- 2.52.0