subscribtion category variants / system category variants
CI / testsuite (mysql, 8.2, ) (push) Waiting to run Details
CI / testsuite (mysql, 8.4, ) (push) Waiting to run Details
CI / testsuite (sqlite, 8.2, prefer-lowest) (push) Waiting to run Details
CI / Coding Standard & Static Analysis (push) Waiting to run Details

This commit is contained in:
Brandon Shipley 2025-11-04 01:50:05 -08:00
parent 868f9dbcce
commit a471be8ff9
Signed by: bmfs
GPG Key ID: 14E38571D8BB0DE4
13 changed files with 254 additions and 12 deletions

View File

@ -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();
}
}

View File

@ -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();
}
}
}

View File

@ -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'));
}

View File

@ -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;

View File

@ -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,

View File

@ -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')

View File

@ -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() ?>

View File

@ -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() ?>

View File

@ -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>

View File

@ -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',

View File

@ -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();
}

View File

@ -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();

View File

@ -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);