aktualizacja modułu
This commit is contained in:
@@ -4,7 +4,10 @@
|
|||||||
"Bash(head:*)",
|
"Bash(head:*)",
|
||||||
"Bash(cp:*)",
|
"Bash(cp:*)",
|
||||||
"Bash(cd:*)",
|
"Bash(cd:*)",
|
||||||
"Bash(curl:*)"
|
"Bash(curl:*)",
|
||||||
|
"mcp__plugin_serena_serena__activate_project",
|
||||||
|
"mcp__plugin_serena_serena__check_onboarding_performed",
|
||||||
|
"mcp__plugin_serena_serena__list_dir"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,3 +124,12 @@ initial_prompt: ""
|
|||||||
# This overrides the corresponding setting in the global configuration; see the documentation there.
|
# This overrides the corresponding setting in the global configuration; see the documentation there.
|
||||||
# If null or missing, use the setting from the global configuration.
|
# If null or missing, use the setting from the global configuration.
|
||||||
symbol_info_budget:
|
symbol_info_budget:
|
||||||
|
|
||||||
|
# line ending convention to use when writing source files.
|
||||||
|
# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default)
|
||||||
|
# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings.
|
||||||
|
line_ending:
|
||||||
|
|
||||||
|
# list of regex patterns which, when matched, mark a memory entry as read‑only.
|
||||||
|
# Extends the list from the global configuration, merging the two lists.
|
||||||
|
read_only_memory_patterns: []
|
||||||
|
|||||||
3
.vscode/ftp-kr.json
vendored
3
.vscode/ftp-kr.json
vendored
@@ -14,6 +14,7 @@
|
|||||||
".git",
|
".git",
|
||||||
"/.vscode",
|
"/.vscode",
|
||||||
"/.serena",
|
"/.serena",
|
||||||
"/.claude"
|
"/.claude",
|
||||||
|
"CLAUDE.md"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
69
CLAUDE.md
Normal file
69
CLAUDE.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is a **PrestaShop 1.7.x e-commerce store** (interblue.pl) with a custom theme and multiple custom/third-party modules. The codebase is a live PrestaShop installation deployed via FTP to the production server.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Directory Structure
|
||||||
|
|
||||||
|
- **`themes/InterBlue/`** — Custom theme based on PrestaShop's classic theme. Templates use Smarty (`.tpl`), CSS is compiled from SCSS via VSCode Live Sass Compiler.
|
||||||
|
- **`modules/`** — 130+ modules. Custom/in-house modules: `customfeaturetab`, `AddOrderExtraFields`. Key third-party: `x13allegro` (Allegro marketplace), `onepagecheckoutps` (one-page checkout), `baselinker`, `empikmarketplace`, `dpdpoland`/`sensbitinpost`/`sensbitpaczkawruchu`/`sensbitpocztapolska` (shipping carriers).
|
||||||
|
- **`override/`** — PrestaShop class/controller overrides. Critical overrides:
|
||||||
|
- `override/classes/order/Order.php` — Modified by `modrefchange` module to fire hooks (`actionBeforeAddOrder`, `actionBeforeAddOrderInvoice`, `actionBeforeAddDeliveryNumber`) before invoice/delivery number assignment.
|
||||||
|
- `override/controllers/front/OrderController.php` — Modified by `onepagecheckoutps` module for one-page checkout flow.
|
||||||
|
- **`src/`** — Extended PrestaShop core: `src/Adapter/Order/QueryHandler/` and `src/Core/Domain/Order/` for order viewing query pattern (CQRS).
|
||||||
|
|
||||||
|
### Theme Architecture
|
||||||
|
|
||||||
|
- **SCSS workflow**: Edit `themes/InterBlue/assets/css/custom.scss` (or `theme.scss`). The VSCode Live Sass Compiler auto-compiles to `custom.css` with autoprefixer on save.
|
||||||
|
- Templates override classic theme templates in `themes/InterBlue/templates/`.
|
||||||
|
- Default layout is full-width; category pages use left column.
|
||||||
|
|
||||||
|
### Module Architecture
|
||||||
|
|
||||||
|
Custom modules follow standard PrestaShop module structure:
|
||||||
|
- Main PHP class extends `Module`
|
||||||
|
- `views/templates/` for Smarty templates
|
||||||
|
- `classes/` for business logic
|
||||||
|
- DB install/uninstall in `install()`/`uninstall()` methods
|
||||||
|
- Hooks registered via `registerHook()` in `install()`
|
||||||
|
|
||||||
|
The `customfeaturetab` module (`modules/customfeaturetab/`) uses a custom DB table `ps_custom_feature_tab` to map product features/values to extra product page tabs, displayed via the `displayProductExtraContent` hook.
|
||||||
|
|
||||||
|
### Override Conflicts
|
||||||
|
|
||||||
|
When adding overrides, check for existing overrides that multiple modules may have contributed to. The `Order.php` override was generated by `AddOrderExtraFields` copying files from `modules/AddOrderExtraFields/_overrides/`. If `modrefchange` module is installed, a different version is used.
|
||||||
|
|
||||||
|
**Known issue**: After updating `empikmarketplace`, the admin product catalog list view is overridden by:
|
||||||
|
- `modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/list.html.twig`
|
||||||
|
- `modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/products_table.html.twig`
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### CSS/SCSS
|
||||||
|
|
||||||
|
Use the VSCode **Live Sass Compiler** extension. It watches on launch (configured in `.vscode/settings.json`) and compiles SCSS to compressed CSS with sourcemaps and autoprefixing automatically on save.
|
||||||
|
|
||||||
|
Main file to edit: [themes/InterBlue/assets/css/custom.scss](themes/InterBlue/assets/css/custom.scss)
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
|
||||||
|
Files are deployed to production via FTP using the **SFTP/FTP Sync** VSCode extension (configured in `.vscode/ftp-kr.json`). Upload is not automatic on save — files must be manually synced.
|
||||||
|
|
||||||
|
### PrestaShop Cache
|
||||||
|
|
||||||
|
After modifying PHP classes, overrides, or templates, PrestaShop's cache must be cleared from the admin panel: **Advanced Parameters → Performance → Clear cache**, or by deleting `var/cache/` on the server.
|
||||||
|
|
||||||
|
When creating or modifying overrides, PrestaShop also needs to rebuild the class index (`var/cache/*/class_index.php`).
|
||||||
|
|
||||||
|
## Key Conventions
|
||||||
|
|
||||||
|
- All custom module display strings use `$this->l('...')` for translation support (Polish locale is primary).
|
||||||
|
- Override classes extend `*Core` (e.g., `class Order extends OrderCore`).
|
||||||
|
- Module DB tables use `_DB_PREFIX_` constant (typically `ps_`).
|
||||||
|
- PrestaShop hooks are the integration point — prefer hooks over direct core edits.
|
||||||
|
- The `admin658c34/` directory is the custom admin panel path (security through obscurity).
|
||||||
134
docs/empik.md
Normal file
134
docs/empik.md
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# Modyfikacje modułu empikmarketplace
|
||||||
|
|
||||||
|
Data modyfikacji: 2026-03-11
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
Moduł empikmarketplace przy nieudanym imporcie zamówienia z EMPIK do PrestaShop powodował:
|
||||||
|
1. Brak powiadomienia o błędzie — nikt nie wiedział, że zamówienie nie przeszło
|
||||||
|
2. Dziury w numeracji zamówień (`id_order`) — MySQL AUTO_INCREMENT nie cofa się po ROLLBACK transakcji
|
||||||
|
|
||||||
|
## Zmodyfikowane pliki
|
||||||
|
|
||||||
|
### `src/Processor/OrderProcessor.php`
|
||||||
|
|
||||||
|
Dodany import `Mail` na górze pliku:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Mail;
|
||||||
|
```
|
||||||
|
|
||||||
|
Dodana stała z adresem email do powiadomień:
|
||||||
|
|
||||||
|
```php
|
||||||
|
class OrderProcessor
|
||||||
|
{
|
||||||
|
const CODE_WAITING_ACCEPTANCE = 'WAITING_ACCEPTANCE';
|
||||||
|
const CODE_SHIPPING = 'SHIPPING';
|
||||||
|
const ERROR_NOTIFICATION_EMAIL = 'jacek.pyziak@project-pro.pl';
|
||||||
|
```
|
||||||
|
|
||||||
|
Zmodyfikowana metoda `import()` — dodano wywołanie resetu AUTO_INCREMENT i wysyłki emaila w bloku catch:
|
||||||
|
|
||||||
|
```php
|
||||||
|
protected function import(EmpikOrderWrapper $empikOrder)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Db::getInstance()->execute('START TRANSACTION');
|
||||||
|
$this->orderFulfiller->fulfill($empikOrder);
|
||||||
|
Db::getInstance()->execute('COMMIT');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Db::getInstance()->execute('ROLLBACK');
|
||||||
|
$this->resetOrderAutoIncrement();
|
||||||
|
|
||||||
|
$data = $empikOrder->getData();
|
||||||
|
$empikOrderId = isset($data['order_id']) ? $data['order_id'] : 'unknown';
|
||||||
|
$errorMsg = sprintf('Error importing EMPIK order [%s]: %s', $empikOrderId, $e->getMessage());
|
||||||
|
$this->logger->logError($errorMsg);
|
||||||
|
$this->sendFailureNotification($empikOrderId, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Dodana metoda `resetOrderAutoIncrement()` — zapobiega dziurom w numeracji zamówień:
|
||||||
|
|
||||||
|
```php
|
||||||
|
protected function resetOrderAutoIncrement()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$lastId = (int) Db::getInstance()->getValue(
|
||||||
|
'SELECT MAX(id_order) FROM ' . _DB_PREFIX_ . 'orders'
|
||||||
|
);
|
||||||
|
Db::getInstance()->execute(
|
||||||
|
'ALTER TABLE ' . _DB_PREFIX_ . 'orders AUTO_INCREMENT = ' . ($lastId + 1)
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->logger->logError(sprintf('Error resetting AUTO_INCREMENT: %s', $e->getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Dodana metoda `sendFailureNotification()` — wysyła email z informacją o błędzie:
|
||||||
|
|
||||||
|
```php
|
||||||
|
protected function sendFailureNotification($empikOrderId, Exception $exception)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$shopName = Configuration::get('PS_SHOP_NAME');
|
||||||
|
$subject = sprintf('[%s] Błąd importu zamówienia EMPIK: %s', $shopName, $empikOrderId);
|
||||||
|
|
||||||
|
$body = sprintf(
|
||||||
|
"Zamówienie EMPIK: %s\nData: %s\nBłąd: %s\n\nStack trace:\n%s",
|
||||||
|
$empikOrderId,
|
||||||
|
date('Y-m-d H:i:s'),
|
||||||
|
$exception->getMessage(),
|
||||||
|
$exception->getTraceAsString()
|
||||||
|
);
|
||||||
|
|
||||||
|
Mail::send(
|
||||||
|
(int) Configuration::get('PS_LANG_DEFAULT'),
|
||||||
|
'empik_import_error',
|
||||||
|
$subject,
|
||||||
|
[
|
||||||
|
'{empik_order_id}' => $empikOrderId,
|
||||||
|
'{error_message}' => $exception->getMessage(),
|
||||||
|
'{error_date}' => date('Y-m-d H:i:s'),
|
||||||
|
'{stack_trace}' => nl2br($exception->getTraceAsString()),
|
||||||
|
],
|
||||||
|
self::ERROR_NOTIFICATION_EMAIL,
|
||||||
|
null,
|
||||||
|
Configuration::get('PS_SHOP_EMAIL'),
|
||||||
|
$shopName,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
_PS_MODULE_DIR_ . 'empikmarketplace/mails/'
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->logger->logError(sprintf('Error sending failure notification email: %s', $e->getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dodane pliki
|
||||||
|
|
||||||
|
### `mails/pl/empik_import_error.html`
|
||||||
|
|
||||||
|
Szablon HTML emaila z powiadomieniem o błędzie. Zawiera placeholdery:
|
||||||
|
- `{empik_order_id}` — ID zamówienia EMPIK
|
||||||
|
- `{error_date}` — data błędu
|
||||||
|
- `{error_message}` — komunikat błędu
|
||||||
|
- `{stack_trace}` — stack trace wyjątku
|
||||||
|
|
||||||
|
### `mails/pl/empik_import_error.txt`
|
||||||
|
|
||||||
|
Wersja tekstowa tego samego szablonu (wymagana przez PrestaShop `Mail::send()`).
|
||||||
|
|
||||||
|
## Po aktualizacji modułu
|
||||||
|
|
||||||
|
Jeśli moduł empikmarketplace zostanie zaktualizowany, powyższe zmiany zostaną nadpisane. Należy ponownie:
|
||||||
|
|
||||||
|
1. Dodać `use Mail;` do importów w `OrderProcessor.php`
|
||||||
|
2. Dodać stałą `ERROR_NOTIFICATION_EMAIL`
|
||||||
|
3. Zmodyfikować metodę `import()` zgodnie z powyższym kodem
|
||||||
|
4. Dodać metody `resetOrderAutoIncrement()` i `sendFailureNotification()`
|
||||||
|
5. Skopiować szablony emaili do `mails/pl/`
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Notatka: override tabeli produktow BO
|
||||||
|
|
||||||
|
Data: 2026-02-09
|
||||||
|
|
||||||
|
Po aktualizacji modulu `empikmarketplace` wyglad tabeli produktow w panelu administratora PrestaShop zostal nadpisany przez:
|
||||||
|
|
||||||
|
- `modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/list.html.twig`
|
||||||
|
|
||||||
|
To ten plik odpowiada za modyfikacje widoku listy produktow (katalog, BO).
|
||||||
26
modules/empikmarketplace/mails/pl/empik_import_error.html
Normal file
26
modules/empikmarketplace/mails/pl/empik_import_error.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Błąd importu zamówienia EMPIK</title>
|
||||||
|
</head>
|
||||||
|
<body style="font-family: Arial, sans-serif; font-size: 14px; color: #333;">
|
||||||
|
<h2 style="color: #c0392b;">Błąd importu zamówienia EMPIK</h2>
|
||||||
|
<table style="border-collapse: collapse; width: 100%; max-width: 600px;">
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Zamówienie EMPIK:</td>
|
||||||
|
<td style="padding: 8px; border: 1px solid #ddd;">{empik_order_id}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Data:</td>
|
||||||
|
<td style="padding: 8px; border: 1px solid #ddd;">{error_date}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Komunikat błędu:</td>
|
||||||
|
<td style="padding: 8px; border: 1px solid #ddd;">{error_message}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Stack trace:</h3>
|
||||||
|
<pre style="background: #f5f5f5; padding: 10px; font-size: 12px; overflow-x: auto;">{stack_trace}</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
8
modules/empikmarketplace/mails/pl/empik_import_error.txt
Normal file
8
modules/empikmarketplace/mails/pl/empik_import_error.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Błąd importu zamówienia EMPIK
|
||||||
|
|
||||||
|
Zamówienie EMPIK: {empik_order_id}
|
||||||
|
Data: {error_date}
|
||||||
|
Komunikat błędu: {error_message}
|
||||||
|
|
||||||
|
Stack trace:
|
||||||
|
{stack_trace}
|
||||||
@@ -13,12 +13,14 @@ use Empik\Marketplace\OrderFulfiller\OrderFulfiller;
|
|||||||
use Exception;
|
use Exception;
|
||||||
use Configuration;
|
use Configuration;
|
||||||
use Db;
|
use Db;
|
||||||
|
use Mail;
|
||||||
use Empik\Marketplace\Provider\Order\ProductRefResolver;
|
use Empik\Marketplace\Provider\Order\ProductRefResolver;
|
||||||
|
|
||||||
class OrderProcessor
|
class OrderProcessor
|
||||||
{
|
{
|
||||||
const CODE_WAITING_ACCEPTANCE = 'WAITING_ACCEPTANCE';
|
const CODE_WAITING_ACCEPTANCE = 'WAITING_ACCEPTANCE';
|
||||||
const CODE_SHIPPING = 'SHIPPING';
|
const CODE_SHIPPING = 'SHIPPING';
|
||||||
|
const ERROR_NOTIFICATION_EMAIL = 'jacek.pyziak@project-pro.pl';
|
||||||
|
|
||||||
/** @var EmpikClientFactory */
|
/** @var EmpikClientFactory */
|
||||||
protected $empikClientFactory;
|
protected $empikClientFactory;
|
||||||
@@ -98,7 +100,74 @@ class OrderProcessor
|
|||||||
Db::getInstance()->execute('COMMIT');
|
Db::getInstance()->execute('COMMIT');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
Db::getInstance()->execute('ROLLBACK');
|
Db::getInstance()->execute('ROLLBACK');
|
||||||
$this->logger->logError(sprintf('Error importing order [%s]', $e->getMessage()));
|
$this->resetOrderAutoIncrement();
|
||||||
|
|
||||||
|
$data = $empikOrder->getData();
|
||||||
|
$empikOrderId = isset($data['order_id']) ? $data['order_id'] : 'unknown';
|
||||||
|
$errorMsg = sprintf('Error importing EMPIK order [%s]: %s', $empikOrderId, $e->getMessage());
|
||||||
|
$this->logger->logError($errorMsg);
|
||||||
|
$this->sendFailureNotification($empikOrderId, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resetuje AUTO_INCREMENT tabeli ps_orders do MAX(id_order) + 1
|
||||||
|
* aby uniknąć dziur w numeracji zamówień po ROLLBACK.
|
||||||
|
*/
|
||||||
|
protected function resetOrderAutoIncrement()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$lastId = (int) Db::getInstance()->getValue(
|
||||||
|
'SELECT MAX(id_order) FROM ' . _DB_PREFIX_ . 'orders'
|
||||||
|
);
|
||||||
|
Db::getInstance()->execute(
|
||||||
|
'ALTER TABLE ' . _DB_PREFIX_ . 'orders AUTO_INCREMENT = ' . ($lastId + 1)
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->logger->logError(sprintf('Error resetting AUTO_INCREMENT: %s', $e->getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wysyła email z powiadomieniem o nieudanym imporcie zamówienia EMPIK.
|
||||||
|
*
|
||||||
|
* @param string $empikOrderId
|
||||||
|
* @param Exception $exception
|
||||||
|
*/
|
||||||
|
protected function sendFailureNotification($empikOrderId, Exception $exception)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$shopName = Configuration::get('PS_SHOP_NAME');
|
||||||
|
$subject = sprintf('[%s] Błąd importu zamówienia EMPIK: %s', $shopName, $empikOrderId);
|
||||||
|
|
||||||
|
$body = sprintf(
|
||||||
|
"Zamówienie EMPIK: %s\nData: %s\nBłąd: %s\n\nStack trace:\n%s",
|
||||||
|
$empikOrderId,
|
||||||
|
date('Y-m-d H:i:s'),
|
||||||
|
$exception->getMessage(),
|
||||||
|
$exception->getTraceAsString()
|
||||||
|
);
|
||||||
|
|
||||||
|
Mail::send(
|
||||||
|
(int) Configuration::get('PS_LANG_DEFAULT'),
|
||||||
|
'empik_import_error',
|
||||||
|
$subject,
|
||||||
|
[
|
||||||
|
'{empik_order_id}' => $empikOrderId,
|
||||||
|
'{error_message}' => $exception->getMessage(),
|
||||||
|
'{error_date}' => date('Y-m-d H:i:s'),
|
||||||
|
'{stack_trace}' => nl2br($exception->getTraceAsString()),
|
||||||
|
],
|
||||||
|
self::ERROR_NOTIFICATION_EMAIL,
|
||||||
|
null,
|
||||||
|
Configuration::get('PS_SHOP_EMAIL'),
|
||||||
|
$shopName,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
_PS_MODULE_DIR_ . 'empikmarketplace/mails/'
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->logger->logError(sprintf('Error sending failure notification email: %s', $e->getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
$issues = array();
|
$issues = array();
|
||||||
|
|
||||||
if (!(PHP_VERSION_ID >= 50600)) {
|
if (!(PHP_VERSION_ID >= 70200)) {
|
||||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.';
|
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($issues) {
|
if ($issues) {
|
||||||
|
|||||||
Reference in New Issue
Block a user