feat: Implement pagination and filtering for linked offers by integration

- Refactored `listLinkedOffersByIntegration` to `paginateLinkedOffersByIntegration` in `MarketplaceRepository`.
- Added pagination support with `page` and `per_page` filters.
- Introduced sorting options for offers.
- Created `listOfferChannelsByIntegration` method to retrieve distinct sales channels.
- Enhanced SQL queries to support dynamic filtering based on provided parameters.

feat: Add new fields for products and SKU generation

- Introduced new fields: `new_to_date`, `additional_message`, `additional_message_required`, and `additional_message_text` in the `products` table.
- Added `findAllSkus` method in `ProductRepository` to retrieve all SKUs.
- Created `ProductSkuGenerator` class to handle SKU generation based on a configurable format.
- Implemented `nextSku` method to generate the next available SKU.

feat: Enhance product settings management in the UI

- Added new settings page for product SKU format in `SettingsController`.
- Implemented form handling for saving SKU format settings.
- Updated the view to include SKU format configuration options.

feat: Implement cron job for refreshing ShopPro offer titles

- Created `ShopProOfferTitlesRefreshHandler` to handle the cron job for refreshing offer titles.
- Integrated with the `OfferImportService` to import offers from ShopPro.

docs: Update database schema documentation

- Added documentation for new fields in the `products` table and new cron job for offer title refresh.
- Documented the purpose and structure of the `app_settings` table.

migrations: Add necessary migrations for new features

- Created migration to add `products_sku_format` setting in `app_settings`.
- Added migration to introduce new fields in the `products` table.
- Created migration for the new cron job schedule for refreshing ShopPro offer titles.
This commit is contained in:
2026-03-01 22:05:21 +01:00
parent bcf078baac
commit d1576bc4ab
28 changed files with 1503 additions and 104 deletions

View File

@@ -18,6 +18,7 @@ use App\Modules\ProductLinks\ProductLinksController;
use App\Modules\ProductLinks\ProductLinksRepository;
use App\Modules\ProductLinks\ProductLinksService;
use App\Modules\Products\ProductRepository;
use App\Modules\Products\ProductSkuGenerator;
use App\Modules\Products\ProductsController;
use App\Modules\Products\ProductService;
use App\Modules\Products\ProductValidator;
@@ -73,6 +74,7 @@ return static function (Application $app): void {
);
$productValidator = new ProductValidator();
$productService = new ProductService($app->db(), $productRepository, $productValidator);
$productSkuGenerator = new ProductSkuGenerator($appSettingsRepository, $productRepository);
$shopProExportService = new ShopProExportService($app->db(), $productRepository, $integrationRepository, $shopProClient);
$gs1Service = new GS1Service($productRepository, $appSettingsRepository);
$productsController = new ProductsController(
@@ -81,6 +83,7 @@ return static function (Application $app): void {
$auth,
$productRepository,
$productService,
$productSkuGenerator,
$integrationRepository,
$productLinksService,
$shopProExportService,
@@ -93,7 +96,9 @@ return static function (Application $app): void {
$marketplaceRepository,
$integrationRepository,
$shopProClient,
$productRepository
$productRepository,
$productService,
$productValidator
);
$authMiddleware = new AuthMiddleware($auth);
@@ -136,6 +141,8 @@ return static function (Application $app): void {
$router->get('/products/{id}', [$productsController, 'show'], [$authMiddleware]);
$router->get('/marketplace', [$marketplaceController, 'index'], [$authMiddleware]);
$router->get('/marketplace/{integration_id}', [$marketplaceController, 'offers'], [$authMiddleware]);
$router->get('/marketplace/{integration_id}/product/{external_product_id}/edit', [$marketplaceController, 'editProduct'], [$authMiddleware]);
$router->post('/marketplace/{integration_id}/product/{external_product_id}/update', [$marketplaceController, 'updateProduct'], [$authMiddleware]);
$router->get('/marketplace/{integration_id}/categories', [$marketplaceController, 'categoriesJson'], [$authMiddleware]);
$router->get('/marketplace/{integration_id}/product/{external_product_id}/categories', [$marketplaceController, 'productCategoriesJson'], [$authMiddleware]);
$router->post('/marketplace/{integration_id}/product/{external_product_id}/categories', [$marketplaceController, 'saveProductCategoriesJson'], [$authMiddleware]);
@@ -150,6 +157,7 @@ return static function (Application $app): void {
$router->post('/products/images/upload', [$productsController, 'uploadImage'], [$authMiddleware]);
$router->post('/products/images/set-main', [$productsController, 'setMainImage'], [$authMiddleware]);
$router->post('/products/images/delete', [$productsController, 'deleteImage'], [$authMiddleware]);
$router->post('/products/next-sku', [$productsController, 'nextSku'], [$authMiddleware]);
$router->post('/products/links/create', [$productLinksController, 'create'], [$authMiddleware]);
$router->post('/products/links/relink', [$productLinksController, 'relink'], [$authMiddleware]);
$router->post('/products/links/unlink', [$productLinksController, 'unlink'], [$authMiddleware]);
@@ -175,4 +183,6 @@ return static function (Application $app): void {
$router->post('/settings/cron/save', [$settingsController, 'saveCronSettings'], [$authMiddleware]);
$router->get('/settings/gs1', [$settingsController, 'gs1'], [$authMiddleware]);
$router->post('/settings/gs1/save', [$settingsController, 'gs1Save'], [$authMiddleware]);
$router->get('/settings/products', [$settingsController, 'products'], [$authMiddleware]);
$router->post('/settings/products/save', [$settingsController, 'productsSave'], [$authMiddleware]);
};