subscribtion category variants / system category variants
This commit is contained in:
parent
868f9dbcce
commit
a471be8ff9
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Migrations\BaseMigration;
|
||||
|
||||
class AddIsSystemToProductCategoryVariants extends BaseMigration
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* More information on this method is available here:
|
||||
* https://book.cakephp.org/migrations/4/en/migrations.html#the-change-method
|
||||
* @return void
|
||||
*/
|
||||
public function change(): void
|
||||
{
|
||||
$table = $this->table('product_category_variants');
|
||||
$table->addColumn('is_system_variant', 'boolean', [
|
||||
'default' => false,
|
||||
'limit' => 11,
|
||||
'null' => false,
|
||||
]);
|
||||
$table->update();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Seeds;
|
||||
|
||||
use Migrations\BaseSeed;
|
||||
|
||||
/**
|
||||
* CreateSystemCategoryVariants seed.
|
||||
*/
|
||||
class CreateSystemCategoryVariantsSeed extends BaseSeed
|
||||
{
|
||||
/**
|
||||
* Run Method.
|
||||
*
|
||||
* Write your database seeder using this method.
|
||||
*
|
||||
* More information on writing seeds is available here:
|
||||
* https://book.cakephp.org/migrations/4/en/seeding.html
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$data = [
|
||||
[
|
||||
'id' => \Cake\Utility\Text::uuid(),
|
||||
'name' => 'Subscription Length',
|
||||
'product_category_id' => null,
|
||||
'enabled' => true,
|
||||
'is_system_variant' => true,
|
||||
],
|
||||
[
|
||||
'id' => \Cake\Utility\Text::uuid(),
|
||||
'name' => 'Subscription Length Units',
|
||||
'product_category_id' => null,
|
||||
'enabled' => true,
|
||||
'is_system_variant' => true,
|
||||
],
|
||||
];
|
||||
$table = $this->table('product_category_variants');
|
||||
$toInsert = [];
|
||||
foreach ($data as $singleRecordToInsert) {
|
||||
$stmt = $this->query('SELECT * FROM product_category_variants WHERE name="' . $singleRecordToInsert['name'] . '" AND product_category_id IS NULL;'); // returns PDOStatement
|
||||
$rows = $stmt->fetchAll(); // returns the result as an array
|
||||
if ($rows) {
|
||||
continue;
|
||||
}
|
||||
$toInsert[] = $singleRecordToInsert;
|
||||
}
|
||||
if ($toInsert) {
|
||||
$table->insert($data)->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -111,21 +111,32 @@ class ProductCategoryVariantsController extends AppController
|
|||
// if ($this->request->getSession()->read('Auth.User.id')) {
|
||||
// $postData['created_by'] = $this->request->getSession()->read('Auth.User.id');
|
||||
// }
|
||||
$postData = $productCategoryVariant->is_system_variant ? ['product_category_variant_options' => $this->request->getData('product_category_variant_options')] : $postData;
|
||||
$saveOptions = [
|
||||
'fields' => $productCategoryVariant->is_system_variant ? [
|
||||
'product_category_variant_options',
|
||||
] : [
|
||||
'name',
|
||||
'product_category_id',
|
||||
'enabled',
|
||||
'product_category_variant_options',
|
||||
],
|
||||
'associated' => [
|
||||
'ProductCategoryVariantOptions'
|
||||
],
|
||||
];
|
||||
$productCategoryVariant = $productCategoryVariantsTable->patchEntity($productCategoryVariant, $postData, $saveOptions);
|
||||
// dd($postData);
|
||||
if ($productCategoryVariantsTable->save($productCategoryVariant, $saveOptions)) {
|
||||
$this->Flash->success(__('The product category variant has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
// dd($productCategoryVariant->getErrors());
|
||||
$this->Flash->error(__('The product category variant could not be saved. Please, try again.'));
|
||||
}
|
||||
$productCategories = $productCategoryVariantsTable->ProductCategories->find('list', keyField: 'internal_id', valueField: 'name')->all();
|
||||
$products = $productCategoryVariantsTable->Products->find('list', limit: 200)->where(['product_category_id' => $productCategoryVariant->product_category_id])->all();
|
||||
$products = isset($productCategoryVariant->product_category_id) ? $productCategoryVariantsTable->Products->find('list', limit: 200)->where(['product_category_id' => $productCategoryVariant->product_category_id])->all() : [];
|
||||
$this->set(compact('productCategoryVariant', 'productCategories', 'products'));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ class ProductPhotosController extends AppController
|
|||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
dd($productPhoto->getErrors());
|
||||
// dd($productPhoto->getErrors());
|
||||
$this->Flash->error(__('The product photo could not be saved. Please, try again.'));
|
||||
}
|
||||
$productCategory = $productPhoto->product_category_id ? $productPhotosTable->ProductCategories->find()->where(['internal_id' => $productPhoto->product_category_id ?? '-1'])->first() : null;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use Cake\ORM\Entity;
|
|||
* @property string|null $product_category_id
|
||||
* @property string|null $product_id
|
||||
* @property bool $enabled
|
||||
* @property bool $is_system_variant
|
||||
*
|
||||
* @property ProductCategory|EntityInterface $product_category
|
||||
* @property ProductCategoryVariantOption[]|EntityInterface[] $product_category_variant_options
|
||||
|
|
@ -34,6 +35,7 @@ class ProductCategoryVariant extends Entity
|
|||
'product_category_id' => true,
|
||||
'product_id' => true,
|
||||
'enabled' => true,
|
||||
'is_system_variant' => true,
|
||||
|
||||
// entities
|
||||
'product_category' => false,
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class ProductCategoryVariantsTable extends Table
|
|||
'className' => 'CakeProducts.ProductCategoryVariantOptions',
|
||||
'dependent' => true,
|
||||
'cascadeCallbacks' => true,
|
||||
'saveStrategy' => 'replace',
|
||||
]);
|
||||
|
||||
$this->hasMany('ProductVariants', [
|
||||
|
|
@ -102,6 +103,10 @@ class ProductCategoryVariantsTable extends Table
|
|||
->uuid('product_id')
|
||||
->allowEmptyString('product_id');
|
||||
|
||||
$validator
|
||||
->boolean('is_system_variant')
|
||||
->allowEmptyString('is_system_variant');
|
||||
|
||||
$validator
|
||||
->boolean('enabled')
|
||||
->requirePresence('enabled', 'create')
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<?= $this->Form->create($productCategoryVariant) ?>
|
||||
<fieldset>
|
||||
<legend><?= __('Add Product Category Variant') ?></legend>
|
||||
<?= $this->element('ProductCategoryVariants/form'); ?>
|
||||
<?= $this->element('ProductCategoryVariants/form', ['productCategoryVariant' => $productCategoryVariant]); ?>
|
||||
</fieldset>
|
||||
<?= $this->Form->button(__('Submit')) ?>
|
||||
<?= $this->Form->end() ?>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
<?= $this->Form->create($productCategoryVariant) ?>
|
||||
<fieldset>
|
||||
<legend><?= __('Edit Product Category Variant') ?></legend>
|
||||
<?= $this->element('ProductCategoryVariants/form'); ?>
|
||||
<?= $this->element('ProductCategoryVariants/form', ['productCategoryVariant' => $productCategoryVariant]); ?>
|
||||
</fieldset>
|
||||
<?= $this->Form->button(__('Submit')) ?>
|
||||
<?= $this->Form->end() ?>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
<th><?= __('Id') ?></th>
|
||||
<td><?= h($productPhoto->id) ?></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?= __('Product Category') ?></th>
|
||||
<td><?= $productPhoto->hasValue('product_category') ? $this->Html->link($productPhoto->product_category->name, ['controller' => 'ProductCategories', 'action' => 'view', $productPhoto->product_category->internal_id]) : '' ?></td>
|
||||
|
|
|
|||
|
|
@ -2,11 +2,30 @@
|
|||
/**
|
||||
* @var array $productCategories
|
||||
* @var array $products
|
||||
* @var \CakeProducts\Model\Entity\ProductCategoryVariant|\Cake\Datasource\EntityInterface $productCategoryVariant
|
||||
*/
|
||||
echo $this->Form->control('name');
|
||||
echo $this->Form->control('product_category_id', ['options' => $productCategories, 'empty' => true]);
|
||||
echo $this->Form->control('product_id', ['options' => $products, 'empty' => true]);
|
||||
echo $this->Form->control('enabled');
|
||||
|
||||
$nameOptions = [];
|
||||
$categoryOptions = ['options' => $productCategories, 'empty' => true];
|
||||
$enabledOptions = [];
|
||||
if ($productCategoryVariant->is_system_variant) {
|
||||
$nameOptions = [
|
||||
'disabled' => true,
|
||||
'readonly' => true,
|
||||
];
|
||||
$categoryOptions = $categoryOptions + [
|
||||
'disabled' => true,
|
||||
'readonly' => true,
|
||||
];
|
||||
$enabledOptions = [
|
||||
'disabled' => true,
|
||||
'readonly' => true,
|
||||
];
|
||||
|
||||
}
|
||||
echo $this->Form->control('name', $nameOptions);
|
||||
echo $this->Form->control('product_category_id', $categoryOptions);
|
||||
echo $this->Form->control('enabled', $enabledOptions);
|
||||
?>
|
||||
<legend><?= __('Variant Options') . '<small class="ms-2">' . $this->Html->link('Add Option', '#', [
|
||||
'id' => 'add-option-button',
|
||||
|
|
|
|||
|
|
@ -56,6 +56,43 @@ class ProductCategoryVariantOptionsFixture extends TestFixture
|
|||
'modified' => '2025-07-04 12:00:00',
|
||||
'enabled' => 1,
|
||||
],
|
||||
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78111',
|
||||
'variant_value' => 'Months',
|
||||
'variant_label' => 'Months',
|
||||
'product_category_variant_id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78111',
|
||||
'created' => '2025-07-04 12:00:00',
|
||||
'modified' => '2025-07-04 12:00:00',
|
||||
'enabled' => 1,
|
||||
],
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78112',
|
||||
'variant_value' => 'Years',
|
||||
'variant_label' => 'Years',
|
||||
'product_category_variant_id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78111',
|
||||
'created' => '2025-07-04 12:00:00',
|
||||
'modified' => '2025-07-04 12:00:00',
|
||||
'enabled' => 1,
|
||||
],
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f22221',
|
||||
'variant_value' => '6',
|
||||
'variant_label' => '6',
|
||||
'product_category_variant_id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78222',
|
||||
'created' => '2025-07-04 12:00:00',
|
||||
'modified' => '2025-07-04 12:00:00',
|
||||
'enabled' => 1,
|
||||
],
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f22222',
|
||||
'variant_value' => 12,
|
||||
'variant_label' => 12,
|
||||
'product_category_variant_id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78222',
|
||||
'created' => '2025-07-04 12:00:00',
|
||||
'modified' => '2025-07-04 12:00:00',
|
||||
'enabled' => 1,
|
||||
],
|
||||
];
|
||||
parent::init();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,17 +18,34 @@ class ProductCategoryVariantsFixture extends TestFixture
|
|||
public function init(): void
|
||||
{
|
||||
$this->records = [
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78111',
|
||||
'name' => 'Subscription Length Units',
|
||||
'product_category_id' => null,
|
||||
'enabled' => true,
|
||||
'is_system_variant' => true,
|
||||
],
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78222',
|
||||
'name' => 'Subscription Length',
|
||||
'product_category_id' => null,
|
||||
'enabled' => true,
|
||||
'is_system_variant' => true,
|
||||
],
|
||||
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78d93',
|
||||
'name' => 'Color',
|
||||
'product_category_id' => 'db4b4273-eddc-46d4-93c8-45cf7c6e058e',
|
||||
'enabled' => 1,
|
||||
'enabled' => true,
|
||||
'is_system_variant' => false,
|
||||
],
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f78d94',
|
||||
'name' => 'AWG',
|
||||
'product_category_id' => 'db4b4273-eddc-46d4-93c8-45cf7c6e058e',
|
||||
'enabled' => 1,
|
||||
'enabled' => true,
|
||||
'is_system_variant' => false,
|
||||
],
|
||||
];
|
||||
parent::init();
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class ProductCategoryVariantsControllerTest extends BaseControllerTest
|
|||
*/
|
||||
protected array $fixtures = [
|
||||
'plugin.CakeProducts.ProductCategoryVariants',
|
||||
'plugin.CakeProducts.ProductCategoryVariantOptions',
|
||||
'plugin.CakeProducts.ProductVariants',
|
||||
'plugin.CakeProducts.ProductCategories',
|
||||
'plugin.CakeProducts.Products',
|
||||
|
|
@ -289,6 +290,77 @@ class ProductCategoryVariantsControllerTest extends BaseControllerTest
|
|||
// assert saved properly below
|
||||
}
|
||||
|
||||
/**
|
||||
* Test edit method
|
||||
*
|
||||
* Tests a PUT request to the edit action with a logged in user
|
||||
*
|
||||
* @uses \CakeProducts\Controller\ProductCategoryVariantsController::edit()
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testEditPutLoggedInSuccessSystemVariant(): void
|
||||
{
|
||||
//$this->loginUserByRole('admin');
|
||||
$id = '5a386e9f-6e7a-4ae7-9360-c8e529f78222'; // subscription length
|
||||
$before = $this->ProductCategoryVariants->get($id);
|
||||
$cntBeforeOptions = $this->ProductCategoryVariantOptions
|
||||
->find()
|
||||
->where(['product_category_variant_id' => $id])
|
||||
->toArray();
|
||||
|
||||
// $this->assertEquals(2, count($cntBeforeOptions));
|
||||
$url = [
|
||||
'plugin' => 'CakeProducts',
|
||||
'controller' => 'ProductCategoryVariants',
|
||||
'action' => 'edit',
|
||||
$id,
|
||||
];
|
||||
$data = [
|
||||
// test new data here
|
||||
'name' => 'updated name',
|
||||
'product_category_id' => 'db4b4273-eddc-46d4-93c8-45cf7c6e058e',
|
||||
'enabled' => false,
|
||||
'product_category_variant_options' => [
|
||||
[
|
||||
'variant_value' => '14',
|
||||
'variant_label' => '14',
|
||||
'enabled' => true,
|
||||
],
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f22221',
|
||||
'variant_value' => '6',
|
||||
'variant_label' => '6',
|
||||
'enabled' => true,
|
||||
],
|
||||
[
|
||||
'id' => '5a386e9f-6e7a-4ae7-9360-c8e529f22222',
|
||||
'variant_value' => 12,
|
||||
'variant_label' => 12,
|
||||
'enabled' => true,
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->put($url, $data);
|
||||
|
||||
$this->assertResponseCode(302);
|
||||
$this->assertRedirectContains('product-category-variants');
|
||||
|
||||
$after = $this->ProductCategoryVariants->get($id);
|
||||
$cntAfterOptions = $this->ProductCategoryVariantOptions
|
||||
->find()
|
||||
->where(['product_category_variant_id' => $id])
|
||||
->toArray();
|
||||
|
||||
$this->assertEquals(count($cntBeforeOptions) + 1, count($cntAfterOptions));
|
||||
|
||||
$this->assertEquals($before->name, $after->name);
|
||||
$this->assertNull($after->product_category_id);
|
||||
$this->assertTrue($after->enabled);
|
||||
// assert saved properly below
|
||||
}
|
||||
|
||||
/**
|
||||
* Test edit method
|
||||
*
|
||||
|
|
@ -312,7 +384,7 @@ class ProductCategoryVariantsControllerTest extends BaseControllerTest
|
|||
];
|
||||
$data = [
|
||||
'name' => '',
|
||||
'product_category_id' => 'db4b4273-eddc-46d4-93c8-45cf7c6e058e',
|
||||
'product_category_id' => 'NOT A VALID ID',
|
||||
'enabled' => true,
|
||||
];
|
||||
$this->put($url, $data);
|
||||
|
|
|
|||
Loading…
Reference in New Issue