5 Commits

Author SHA1 Message Date
0042fda5cc Fix product page not loading 2026-01-21 08:32:24 +01:00
646383fb6a Improved countries migration 2026-01-20 11:00:39 +01:00
f9c58edccd Improvements to handling countries. 2026-01-20 10:44:33 +01:00
9ec3291a6a Add stock to product. 2026-01-20 10:09:35 +01:00
373fd1641b Start working on handling multiple countries at once 2026-01-20 08:40:34 +01:00
6 changed files with 36 additions and 30 deletions

View File

@@ -6,6 +6,7 @@ namespace Krzysiej\RyobiCrawler\Command;
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Database\Schema\Blueprint;
use Krzysiej\RyobiCrawler\Models\Country;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
@@ -93,26 +94,30 @@ class Migrate extends Command
$table->timestamps();
});
}
$id = Capsule::table('countries')->insertGetId(
[
'countryName' => 'Poland',
'productsUrl' => 'https://pl.ryobitools.eu/api/product-listing/get-products',
'cultureCode' => 'pl-PL',
'currency' => 'PLN',
'locale' => 'pl',
'created_at' => now(),
'updated_at' => now(),
]);
Capsule::table('countries')->insert([
'countryName' => 'UK',
'productsUrl' => 'https://uk.ryobitools.eu/api/product-listing/get-products',
'cultureCode' => 'en-GB',
'currency' => 'GBP',
'locale' => 'en',
'created_at' => now(),
'updated_at' => now(),
]
);
if (Capsule::schema()->hasTable('countries') && !Country::where('countryName', 'Poland')->exists()) {
$id = Capsule::table('countries')->insertGetId(
[
'countryName' => 'Poland',
'productsUrl' => 'https://pl.ryobitools.eu/api/product-listing/get-products',
'cultureCode' => 'pl-PL',
'currency' => 'PLN',
'locale' => 'pl',
'created_at' => now(),
'updated_at' => now(),
]);
}
if (Capsule::schema()->hasTable('countries') && !Country::where('countryName', 'UK')->exists()) {
Capsule::table('countries')->insert([
'countryName' => 'UK',
'productsUrl' => 'https://uk.ryobitools.eu/api/product-listing/get-products',
'cultureCode' => 'en-GB',
'currency' => 'GBP',
'locale' => 'en',
'created_at' => now(),
'updated_at' => now(),
]
);
}
if (!Capsule::schema()->hasColumn('products', 'country_id')) {
Capsule::schema()->table('products', function (Blueprint $table) use ($id) {

View File

@@ -111,7 +111,7 @@ class ScrapeWebsite extends Command
$productModel->skuID = $product->skuID;
$productModel->name = $product->name;
$productModel->availableQuantity = $product->availableQuantity;
$productModel->categories = $product->categories;
$productModel->categories = str_replace(['/', ' '], '', $product->categories);
$productModel->image = $product->image;
$productModel->subTitle = $product->subTitle;
$productModel->variantCode = $product->variantCode;

View File

@@ -16,11 +16,11 @@ final class NewController extends BaseController
if($this->cache->getItem('list_new')->isHit()) {
return $this->render('productList.html.twig', ['listType' => 'new']);
}
$products = Product::where('created_at', '>', now()->modify('-30 days')->format('Y-m-d'))
$date = now()->modify('-30 days')->format('Y-m-d');
$products = Product::where('created_at', '>', $date)
->with(['country', 'stock'])
->orderByDesc('starred')
->orderByDesc('created_by')
->with(['currentPrice', 'lowestPrice'])
->get();
return $this->render('productList.html.twig', ['products' => $products, 'listType' => 'new']);
}

View File

@@ -32,7 +32,7 @@ use function Symfony\Component\Clock\now;
class Product extends Model
{
public $timestamps = true;
public $fillable = ['skuID'];
public $fillable = ['skuID', 'country_id'];
public function country(): BelongsTo
{

View File

@@ -10,7 +10,7 @@
<td><img src='{{ product.image }}&width=150' class='border rounded p-1' alt='{{ product.name }}'/></td>
<td>
<a href='{{ path('app_product', {'productId': product.id}) }}' class="text-decoration-none">{{ product.name }}</a>
<span class="badge text-bg-light">{{ product.subTitle }}</span>
<span class="badge text-bg-light"><a href="{{ path('app_search', {'search': product.subTitle}) }}" class="link-underline link-underline-opacity-0 link-dark">{{ product.subTitle }}</a></span>
</td>
<td>
<nav aria-label="breadcrumb" style="--bs-breadcrumb-divider: '>';">
@@ -42,13 +42,14 @@
<th>Stock</th>
</tr>
</thead>
{% set stock = product.stock().get() %}
{% for price in product.price %}
<tr>
<td>{{ price.price | format_currency(product.country.currency, {}, product.country.locale) }}</td>
<td>{{ price.lowestProductPrice30Days | format_currency(product.country.currency, {}, product.country.locale) }}</td>
<td>{{ price.productStandardPrice | format_currency(product.country.currency, {}, product.country.locale) }}</td>
<td>{{ price.created_at }}</td>
<td>{{ (product.stock | findByCreatedAtDate(price.created_at | slice(0,10))).stock ?? '' }}</td>
<td>{{ (stock | findByCreatedAtDate(price.created_at | slice(0,10))).stock ?? '' }}</td>
</tr>
{% endfor %}
</table>

View File

@@ -23,8 +23,8 @@
<td class="align-middle" style="width: 120px;"><img src='{{ product.image }}&width=70' class='img-thumbnail' alt='{{ product.name }}'/></td>
<td class="align-middle">
<a href='{{ path('app_product', {'productId': product.id}) }}' class="text-decoration-none">{{ product.name }}</a>
{% if product.currentStock.stock > 0 %}
<span class="badge text-bg-light">stock: {{ product.currentStock.stock }}</span>
{% if product.stock > 0 %}
<span class="badge text-bg-light">stock: {{ product.stock }}</span>
{% else %}
<span class="badge text-bg-warning">out of stock</span>
{% endif %}
@@ -34,7 +34,7 @@
{% if product.isNew() %}
<span class="badge text-bg-success">is new</span>
{% endif %}
<span class="badge text-bg-light">{{ product.subTitle }}</span>
<span class="badge text-bg-light"><a href="{{ path('app_search', {'search': product.subTitle}) }}" class="link-underline link-underline-opacity-0 link-dark">{{ product.subTitle }}</a></span>
</td>
<td class="align-middle">
<nav aria-label="breadcrumb" style="--bs-breadcrumb-divider: '>';" >