Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 562495f120 | |||
| 9de4afec9a | |||
| 3a3c2adb47 | |||
| db7c881d36 |
@@ -11,7 +11,10 @@ Gdy użytkownik napisze `KONIEC PRACY`, wykonaj kolejno:
|
||||
- `docs/FORM_EDIT_SYSTEM.md`
|
||||
- `docs/CHANGELOG.md`
|
||||
- `docs/TESTING.md`
|
||||
3. Przygotowanie aktualizacji zgodnie z plikiem docs/UPDATE_INSTRUCTIONS.md (ZIP, plik z usuwanymi plikami, plik SQL jeśli wymagany).
|
||||
3. Migracje SQL (jeśli były zmiany w bazie danych):
|
||||
- Plik: `migrations/{version}.sql` (np. `migrations/0.304.sql`)
|
||||
- **NIE** w `updates/` — build script sam wczyta z `migrations/`
|
||||
- Sprawdź czy plik istnieje i jest poprawnie nazwany przed commitem
|
||||
4. Commit.
|
||||
5. Push.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ composer test
|
||||
|
||||
PHPUnit 9.6 via `phpunit.phar`. Bootstrap: `tests/bootstrap.php`. Config: `phpunit.xml`.
|
||||
|
||||
Current suite: **730 tests, 2066 assertions**.
|
||||
Current suite: **734 tests, 2080 assertions**.
|
||||
|
||||
### Creating Updates
|
||||
See `docs/UPDATE_INSTRUCTIONS.md` for the full procedure. Updates are ZIP packages in `updates/0.XX/`. Never include `*.md` files, `updates/changelog.php`, or root `.htaccess` in update ZIPs.
|
||||
@@ -208,7 +208,7 @@ $controller = new \admin\Controllers\ExampleController($repo);
|
||||
When user says **"KONIEC PRACY"**, execute in order:
|
||||
1. Run tests
|
||||
2. Update documentation if needed: `docs/DATABASE_STRUCTURE.md`, `docs/PROJECT_STRUCTURE.md`, `docs/FORM_EDIT_SYSTEM.md`, `docs/CHANGELOG.md`, `docs/TESTING.md`
|
||||
3. Prepare update package per `docs/UPDATE_INSTRUCTIONS.md`
|
||||
3. SQL migrations (if DB changes): place in `migrations/{version}.sql` (e.g. `migrations/0.304.sql`). **NOT** in `updates/` — build script reads from `migrations/` automatically
|
||||
4. Commit
|
||||
5. Push
|
||||
|
||||
|
||||
@@ -61,6 +61,10 @@ $_SESSION['can_use_rfm'] = true;
|
||||
<a href="<?= htmlspecialchars($action->url) ?>" class="btn btn-dark btn-sm" id="g-edit-cancel">
|
||||
<i class="fa fa-reply mr5"></i>Wstecz
|
||||
</a>
|
||||
<?php elseif ($action->name === 'preview'): ?>
|
||||
<a href="<?= htmlspecialchars($action->url) ?>" class="btn btn-info btn-sm" target="_blank">
|
||||
<i class="fa fa-eye mr5"></i><?= htmlspecialchars($action->label) ?>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<a href="<?= htmlspecialchars($action->url) ?>" class="btn <?= htmlspecialchars($action->cssClass) ?> btn-sm">
|
||||
<?= htmlspecialchars($action->label) ?>
|
||||
|
||||
@@ -120,10 +120,16 @@ class PaymentMethodRepository
|
||||
'description' => trim((string)($data['description'] ?? '')),
|
||||
'status' => $this->toSwitchValue($data['status'] ?? 0),
|
||||
'apilo_payment_type_id' => $this->normalizeApiloPaymentTypeId($data['apilo_payment_type_id'] ?? null),
|
||||
'min_order_amount' => $this->normalizeDecimalOrNull($data['min_order_amount'] ?? null),
|
||||
'max_order_amount' => $this->normalizeDecimalOrNull($data['max_order_amount'] ?? null),
|
||||
];
|
||||
|
||||
$this->db->update('pp_shop_payment_methods', $row, ['id' => $paymentMethodId]);
|
||||
|
||||
$cacheHandler = new \Shared\Cache\CacheHandler();
|
||||
$cacheHandler->deletePattern('payment_method*');
|
||||
$cacheHandler->deletePattern('payment_methods*');
|
||||
|
||||
return $paymentMethodId;
|
||||
}
|
||||
|
||||
@@ -232,7 +238,9 @@ class PaymentMethodRepository
|
||||
spm.name,
|
||||
spm.description,
|
||||
spm.status,
|
||||
spm.apilo_payment_type_id
|
||||
spm.apilo_payment_type_id,
|
||||
spm.min_order_amount,
|
||||
spm.max_order_amount
|
||||
FROM pp_shop_payment_methods AS spm
|
||||
INNER JOIN pp_shop_transport_payment_methods AS stpm
|
||||
ON stpm.id_payment_method = spm.id
|
||||
@@ -325,6 +333,8 @@ class PaymentMethodRepository
|
||||
$row['description'] = (string)($row['description'] ?? '');
|
||||
$row['status'] = $this->toSwitchValue($row['status'] ?? 0);
|
||||
$row['apilo_payment_type_id'] = $this->normalizeApiloPaymentTypeId($row['apilo_payment_type_id'] ?? null);
|
||||
$row['min_order_amount'] = $this->normalizeDecimalOrNull($row['min_order_amount'] ?? null);
|
||||
$row['max_order_amount'] = $this->normalizeDecimalOrNull($row['max_order_amount'] ?? null);
|
||||
|
||||
return $row;
|
||||
}
|
||||
@@ -350,6 +360,23 @@ class PaymentMethodRepository
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float|null
|
||||
*/
|
||||
private function normalizeDecimalOrNull($value)
|
||||
{
|
||||
if ($value === null || $value === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$text = trim((string)$value);
|
||||
if ($text === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (float)$text;
|
||||
}
|
||||
|
||||
private function toSwitchValue($value): int
|
||||
{
|
||||
if (is_bool($value)) {
|
||||
|
||||
@@ -3359,12 +3359,18 @@ class ProductRepository
|
||||
|
||||
$attributes = \Shared\Helpers\Helpers::removeDuplicates($attributes, 'id');
|
||||
|
||||
$sorted = [];
|
||||
$toSort = [];
|
||||
foreach ($attributes as $key => $val) {
|
||||
$row = [];
|
||||
$row['id'] = $key;
|
||||
$row['values'] = $val;
|
||||
$sorted[$attrRepo->getAttributeOrder((int) $key)] = $row;
|
||||
$toSort[] = ['order' => (int) $attrRepo->getAttributeOrder((int) $key), 'data' => $row];
|
||||
}
|
||||
usort($toSort, function ($a, $b) { return $a['order'] - $b['order']; });
|
||||
|
||||
$sorted = [];
|
||||
foreach ($toSort as $i => $item) {
|
||||
$sorted[$i + 1] = $item['data'];
|
||||
}
|
||||
|
||||
return $sorted;
|
||||
|
||||
@@ -182,6 +182,8 @@ class ShopPaymentMethodController
|
||||
'description' => (string)($paymentMethod['description'] ?? ''),
|
||||
'status' => (int)($paymentMethod['status'] ?? 0),
|
||||
'apilo_payment_type_id' => $paymentMethod['apilo_payment_type_id'] ?? '',
|
||||
'min_order_amount' => $paymentMethod['min_order_amount'] ?? '',
|
||||
'max_order_amount' => $paymentMethod['max_order_amount'] ?? '',
|
||||
];
|
||||
|
||||
$fields = [
|
||||
@@ -203,6 +205,16 @@ class ShopPaymentMethodController
|
||||
'tab' => 'settings',
|
||||
'rows' => 5,
|
||||
]),
|
||||
FormField::number('min_order_amount', [
|
||||
'label' => 'Min. kwota zamowienia (PLN)',
|
||||
'tab' => 'settings',
|
||||
'step' => 0.01,
|
||||
]),
|
||||
FormField::number('max_order_amount', [
|
||||
'label' => 'Maks. kwota zamowienia (PLN)',
|
||||
'tab' => 'settings',
|
||||
'step' => 0.01,
|
||||
]),
|
||||
FormField::select('apilo_payment_type_id', [
|
||||
'label' => 'Typ platnosci Apilo',
|
||||
'tab' => 'settings',
|
||||
|
||||
@@ -547,6 +547,11 @@ class ShopProductController
|
||||
FormAction::cancel( $backUrl ),
|
||||
];
|
||||
|
||||
if ( $productId > 0 ) {
|
||||
$previewUrl = $this->repository->getProductUrl( $productId );
|
||||
$actions[] = FormAction::preview( $previewUrl );
|
||||
}
|
||||
|
||||
return new FormEditViewModel(
|
||||
'product-edit',
|
||||
$title,
|
||||
|
||||
@@ -56,6 +56,22 @@ class FormAction
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Predefiniowana akcja Podgląd (otwiera w nowej karcie)
|
||||
*/
|
||||
public static function preview(string $url, string $label = 'Podgląd'): self
|
||||
{
|
||||
return new self(
|
||||
'preview',
|
||||
$label,
|
||||
$url,
|
||||
null,
|
||||
'btn btn-info',
|
||||
'link',
|
||||
['target' => '_blank']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Predefiniowana akcja Anuluj
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,25 @@ Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze.
|
||||
|
||||
---
|
||||
|
||||
## ver. 0.304 (2026-02-22) - Konfigurowalne limity kwotowe metod platnosci
|
||||
|
||||
- **NEW**: Kolumny `min_order_amount` i `max_order_amount` w `pp_shop_payment_methods` — konfigurowalne limity kwotowe per metoda platnosci
|
||||
- **NEW**: Pola min/max kwoty zamowienia w formularzu edycji metody platnosci (admin)
|
||||
- **FIX**: Zastapiono hardcoded warunek PayPo (id=6, 40-1000 PLN) generycznym filtrowaniem na froncie (basket checkout)
|
||||
- **NEW**: Cache invalidation po zapisie metody platnosci
|
||||
- **NEW**: 4 nowe testy jednostkowe (734 total, 2080 assertions)
|
||||
- **MIGRATION**: `migrations/0.304.sql` — ALTER TABLE pp_shop_payment_methods ADD min/max_order_amount
|
||||
|
||||
---
|
||||
|
||||
## ver. 0.303 (2026-02-22) - Fix: wyswietlanie atrybutow produktu na froncie + podglad produktu w adminie
|
||||
|
||||
- **FIX**: Naprawiono wyswietlanie atrybutow produktu na froncie — gdy dwa atrybuty mialy te sama wartosc kolejnosci (`o`), jeden nadpisywal drugi (kolizja kluczy tablicy). Teraz atrybuty sortowane przez `usort()` z unikalnymi kluczami sekwencyjnymi.
|
||||
- **NEW**: Przycisk "Podglad" w formularzu edycji produktu — otwiera strone produktu w nowej karcie
|
||||
- **NEW**: `FormAction::preview()` — nowy typ akcji formularza z `target="_blank"`
|
||||
|
||||
---
|
||||
|
||||
## ver. 0.302 (2026-02-22) - REST API: warianty produktow, atrybuty, filtrowanie
|
||||
|
||||
- **NEW**: API wariantow produktow — CRUD: `variants`, `create_variant`, `update_variant`, `delete_variant`
|
||||
|
||||
@@ -508,12 +508,16 @@ Metody platnosci sklepu (modul `/admin/shop_payment_method`).
|
||||
| description | Opis metody platnosci (wyswietlany m.in. w checkout) |
|
||||
| status | Status: 1 = aktywna, 0 = nieaktywna |
|
||||
| apilo_payment_type_id | ID typu platnosci Apilo (NULL gdy brak mapowania) |
|
||||
| min_order_amount | Minimalna kwota zamowienia (DECIMAL(10,2), NULL = brak limitu) |
|
||||
| max_order_amount | Maksymalna kwota zamowienia (DECIMAL(10,2), NULL = brak limitu) |
|
||||
| sellasist_payment_type_id | DEPRECATED (integracja Sellasist usunieta w ver. 0.263) |
|
||||
|
||||
**Uzywane w:** `Domain\PaymentMethod\PaymentMethodRepository`, `admin\Controllers\ShopPaymentMethodController`, `front\factory\ShopPaymentMethod`, `shop\PaymentMethod`, `admin\controls\ShopTransport`, `cron.php`
|
||||
|
||||
**Aktualizacja 2026-02-14 (ver. 0.268):** modul `/admin/shop_payment_method` korzysta z `Domain\PaymentMethod\PaymentMethodRepository` przez `admin\Controllers\ShopPaymentMethodController`. Usunieto legacy klasy `admin\controls\ShopPaymentMethod`, `admin\factory\ShopPaymentMethod`, `admin\view\ShopPaymentMethod` oraz widok `admin/templates/shop-payment-method/view-list.php`.
|
||||
|
||||
**Aktualizacja 2026-02-22 (ver. 0.304):** dodano kolumny `min_order_amount` i `max_order_amount` — konfigurowalne limity kwotowe metod platnosci. Zastapiono hardcoded warunek PayPo (id=6, 40-1000 PLN) generycznym filtrowaniem na froncie.
|
||||
|
||||
## pp_shop_transports
|
||||
Rodzaje transportu sklepu (modul `/admin/shop_transport`).
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@ composer test # standard
|
||||
## Aktualny stan
|
||||
|
||||
```text
|
||||
OK (730 tests, 2066 assertions)
|
||||
OK (734 tests, 2080 assertions)
|
||||
```
|
||||
|
||||
Zweryfikowano: 2026-02-21 (ver. 0.300)
|
||||
Zweryfikowano: 2026-02-22 (ver. 0.304)
|
||||
|
||||
## Konfiguracja
|
||||
|
||||
|
||||
@@ -69,45 +69,5 @@ Build script automatycznie je wczyta i umieści w manifeście + legacy `_sql.txt
|
||||
### .updateignore
|
||||
Plik w katalogu głównym projektu, wzorce plików wykluczonych z paczek (jak `.gitignore`).
|
||||
|
||||
---
|
||||
|
||||
## Stary sposób (do v0.300) — ręczne pakowanie
|
||||
|
||||
### Struktura aktualizacji
|
||||
|
||||
Aktualizacje znajdują się w folderze `updates/0.XX/` gdzie XX oznacza dziesiątki wersji.
|
||||
|
||||
#### Pliki aktualizacji:
|
||||
- `ver_X.XXX.zip` - paczka ZIP ze zmienionymi plikami (BEZ folderu wersji, bezpośrednio struktura katalogów)
|
||||
- `ver_X.XXX_sql.txt` - opcjonalny plik z zapytaniami SQL (jeśli wymagane zmiany w bazie)
|
||||
- `ver_X.XXX_files.txt` - opcjonalny plik z listą plików do **USUNIĘCIA** przy aktualizacji (format: `F: ../sciezka/do/pliku.php`)
|
||||
- `changelog.php` - historia zmian
|
||||
- `versions.php` - konfiguracja wersji (zmienna `$current_ver`)
|
||||
|
||||
#### Zasada pakowania plików
|
||||
- Do paczek aktualizacji **nie dodajemy plików `*.md`** (dokumentacja jest tylko wewnętrzna/deweloperska).
|
||||
- Do paczek aktualizacji **nie dodajemy `updates/changelog.php`** (to plik serwisowy po stronie repozytorium aktualizacji, nie runtime klienta).
|
||||
- Do paczek aktualizacji **nie dodajemy głównego `.htaccess` z katalogu projektu** (ten plik wdrażamy osobno, poza ZIP aktualizacji).
|
||||
|
||||
### Procedura ręczna
|
||||
|
||||
1. Określ numer wersji
|
||||
2. Utwórz folder tymczasowy: `mkdir -p temp/temp_XXX/sciezka/do/pliku`
|
||||
3. Skopiuj zmienione pliki do folderu tymczasowego
|
||||
4. Utwórz ZIP z zawartości folderu (nie z samego folderu!)
|
||||
5. Usuń folder tymczasowy
|
||||
6. Zaktualizuj `changelog.php` i `versions.php`
|
||||
7. (Opcjonalnie) Utwórz `_sql.txt` i `_files.txt`
|
||||
|
||||
**WAŻNE:** W archiwum ZIP NIE powinno być folderu z nazwą wersji. Struktura ZIP zaczyna się bezpośrednio od katalogów projektu (admin/, autoload/, itp.).
|
||||
|
||||
## Status bieżącej aktualizacji (ver. 0.302)
|
||||
|
||||
- Wersja udostępniona: `0.302` (data: 2026-02-22).
|
||||
- Pliki publikacyjne:
|
||||
- `updates/0.30/ver_0.302.zip`
|
||||
- Pliki metadanych aktualizacji:
|
||||
- `updates/changelog.php`
|
||||
- `updates/versions.php` (`$current_ver = 302`)
|
||||
- Weryfikacja testów przed publikacją:
|
||||
- `OK (730 tests, 2066 assertions)`
|
||||
### INFO
|
||||
pamiętaj że push czasem zwraca błąd autoryzacji, wtedy spróbuj ponownie
|
||||
2
migrations/0.304.sql
Normal file
2
migrations/0.304.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE pp_shop_payment_methods ADD COLUMN min_order_amount DECIMAL(10,2) DEFAULT NULL;
|
||||
ALTER TABLE pp_shop_payment_methods ADD COLUMN max_order_amount DECIMAL(10,2) DEFAULT NULL;
|
||||
@@ -13,7 +13,14 @@
|
||||
$basket_summary = \Domain\Basket\BasketCalculator::summaryPrice( $basket, $coupon ) + $transport_cost;
|
||||
?>
|
||||
<? if ( is_array( $this -> payment_methods ) ): foreach ( $this -> payment_methods as $payment_method ):?>
|
||||
<? if ( $payment_method['id'] != 6 or $payment_method['id'] == 6 and $basket_summary >= 40 and $basket_summary <= 1000 ):?>
|
||||
<?
|
||||
$min = isset($payment_method['min_order_amount']) ? (float)$payment_method['min_order_amount'] : null;
|
||||
$max = isset($payment_method['max_order_amount']) ? (float)$payment_method['max_order_amount'] : null;
|
||||
$show = true;
|
||||
if ($min !== null && $min > 0 && $basket_summary < $min) $show = false;
|
||||
if ($max !== null && $max > 0 && $basket_summary > $max) $show = false;
|
||||
?>
|
||||
<? if ( $show ):?>
|
||||
<div class="options">
|
||||
<div class="check">
|
||||
<input type="radio" class="icheck" name="payment_method" value="<?= $payment_method['id'];?>"
|
||||
|
||||
@@ -78,6 +78,8 @@ class PaymentMethodRepositoryTest extends TestCase
|
||||
$this->assertSame('test', $updateRow['description']);
|
||||
$this->assertSame(1, $updateRow['status']);
|
||||
$this->assertSame(22, $updateRow['apilo_payment_type_id']);
|
||||
$this->assertNull($updateRow['min_order_amount']);
|
||||
$this->assertNull($updateRow['max_order_amount']);
|
||||
$this->assertSame(['id' => 3], $updateWhere);
|
||||
}
|
||||
|
||||
@@ -113,6 +115,102 @@ class PaymentMethodRepositoryTest extends TestCase
|
||||
$this->assertNull($repository->save(0, ['status' => 1]));
|
||||
}
|
||||
|
||||
public function testSavePersistsMinMaxOrderAmount(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$updateRow = null;
|
||||
|
||||
$mockDb->expects($this->once())
|
||||
->method('update')
|
||||
->willReturnCallback(function ($table, $row) use (&$updateRow) {
|
||||
$updateRow = $row;
|
||||
return true;
|
||||
});
|
||||
|
||||
$repository = new PaymentMethodRepository($mockDb);
|
||||
$repository->save(5, [
|
||||
'description' => 'test',
|
||||
'status' => 1,
|
||||
'apilo_payment_type_id' => '',
|
||||
'min_order_amount' => '40.00',
|
||||
'max_order_amount' => '1000.00',
|
||||
]);
|
||||
|
||||
$this->assertSame(40.0, $updateRow['min_order_amount']);
|
||||
$this->assertSame(1000.0, $updateRow['max_order_amount']);
|
||||
}
|
||||
|
||||
public function testSaveConvertsEmptyMinMaxToNull(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$updateRow = null;
|
||||
|
||||
$mockDb->expects($this->once())
|
||||
->method('update')
|
||||
->willReturnCallback(function ($table, $row) use (&$updateRow) {
|
||||
$updateRow = $row;
|
||||
return true;
|
||||
});
|
||||
|
||||
$repository = new PaymentMethodRepository($mockDb);
|
||||
$repository->save(6, [
|
||||
'description' => 'test',
|
||||
'status' => 1,
|
||||
'apilo_payment_type_id' => '',
|
||||
'min_order_amount' => '',
|
||||
'max_order_amount' => '',
|
||||
]);
|
||||
|
||||
$this->assertNull($updateRow['min_order_amount']);
|
||||
$this->assertNull($updateRow['max_order_amount']);
|
||||
}
|
||||
|
||||
public function testFindNormalizesMinMaxOrderAmount(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->with('pp_shop_payment_methods', '*', ['id' => 6])
|
||||
->willReturn([
|
||||
'id' => '6',
|
||||
'name' => 'PayPo',
|
||||
'description' => '',
|
||||
'status' => '1',
|
||||
'apilo_payment_type_id' => null,
|
||||
'min_order_amount' => '40.00',
|
||||
'max_order_amount' => '1000.00',
|
||||
]);
|
||||
|
||||
$repository = new PaymentMethodRepository($mockDb);
|
||||
$result = $repository->find(6);
|
||||
|
||||
$this->assertSame(40.0, $result['min_order_amount']);
|
||||
$this->assertSame(1000.0, $result['max_order_amount']);
|
||||
}
|
||||
|
||||
public function testFindNormalizesNullMinMaxOrderAmount(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->with('pp_shop_payment_methods', '*', ['id' => 7])
|
||||
->willReturn([
|
||||
'id' => '7',
|
||||
'name' => 'Przelew',
|
||||
'description' => '',
|
||||
'status' => '1',
|
||||
'apilo_payment_type_id' => null,
|
||||
'min_order_amount' => null,
|
||||
'max_order_amount' => null,
|
||||
]);
|
||||
|
||||
$repository = new PaymentMethodRepository($mockDb);
|
||||
$result = $repository->find(7);
|
||||
|
||||
$this->assertNull($result['min_order_amount']);
|
||||
$this->assertNull($result['max_order_amount']);
|
||||
}
|
||||
|
||||
public function testListForAdminWhitelistsSortAndDirection(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
|
||||
BIN
updates/0.30/ver_0.303.zip
Normal file
BIN
updates/0.30/ver_0.303.zip
Normal file
Binary file not shown.
26
updates/0.30/ver_0.303_manifest.json
Normal file
26
updates/0.30/ver_0.303_manifest.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"changelog": "FIX - naprawiono wyswietlanie atrybutow produktu na froncie (kolizja kolejnosci), NEW - przycisk Podglad w edycji produktu",
|
||||
"version": "0.303",
|
||||
"files": {
|
||||
"added": [
|
||||
|
||||
],
|
||||
"deleted": [
|
||||
|
||||
],
|
||||
"modified": [
|
||||
"admin/templates/components/form-edit.php",
|
||||
"autoload/Domain/Product/ProductRepository.php",
|
||||
"autoload/admin/Controllers/ShopProductController.php",
|
||||
"autoload/admin/ViewModels/Forms/FormAction.php"
|
||||
]
|
||||
},
|
||||
"checksum_zip": "sha256:6d8cc0c3419c50345d9c4fa1f526a09004194cbf7f76302f3cfe7afe64b00545",
|
||||
"sql": [
|
||||
|
||||
],
|
||||
"date": "2026-02-22",
|
||||
"directories_deleted": [
|
||||
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,10 @@
|
||||
<b>ver. 0.302 - 22.02.2026</b><br />
|
||||
<b>ver. 0.304 - 22.02.2026</b><br />
|
||||
NEW - konfigurowalne limity kwotowe metod platnosci (min/max kwota zamowienia), zastapienie hardcoded warunku PayPo
|
||||
<hr>
|
||||
<b>ver. 0.303 - 22.02.2026</b><br />
|
||||
FIX - naprawiono wyswietlanie atrybutow produktu na froncie (kolizja kolejnosci), NEW - przycisk Podglad w edycji produktu
|
||||
<hr>
|
||||
<b>ver. 0.302 - 22.02.2026</b><br />
|
||||
NEW - REST API wariantów produktów (CRUD), słownik atrybutów, filtrowanie po atrybutach, wzbogacone atrybuty z tłumaczeniami
|
||||
<hr>
|
||||
<b>ver. 0.301 - 22.02.2026</b><br />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?
|
||||
$current_ver = 302;
|
||||
$current_ver = 304;
|
||||
|
||||
for ($i = 1; $i <= $current_ver; $i++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user