diff --git a/app/DoctrineMigrations/Version20230928014611.php b/app/DoctrineMigrations/Version20230928014611.php new file mode 100644 index 00000000000..21ee6ffb328 --- /dev/null +++ b/app/DoctrineMigrations/Version20230928014611.php @@ -0,0 +1,50 @@ +connection->fetchAllKeyValue(" +SELECT product_class_id, product_class_id_count +FROM ( + SELECT + product_class_id, + COUNT(product_class_id) AS product_class_id_count + FROM + dtb_product_stock + GROUP BY + product_class_id + ) AS subquery +WHERE product_class_id_count > 1; +"); + + // 重複在庫がある場合、dtb_product_class.stockを正として、それ以外の在庫情報は削除する + if (count($exists) != 0) { + foreach ($exists as $pc_id => $value) { + $stock = $this->connection->fetchOne("SELECT stock FROM dtb_product_class WHERE id = :id", ["id" => $pc_id]); + $this->addSql("DELETE FROM dtb_product_stock WHERE product_class_id = :pc_id", ["pc_id" => $pc_id]); + $this->addSql("INSERT INTO dtb_product_stock (product_class_id, creator_id, stock, create_date, update_date, discriminator_type) VALUES (:pc_id, NULL, :stock, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'productstock')", ["pc_id" => $pc_id, "stock" => $stock]); + } + } + } + + public function down(Schema $schema): void + { + } +} diff --git a/codeception/_support/Page/Admin/ProductClassEditPage.php b/codeception/_support/Page/Admin/ProductClassEditPage.php index e1e588981cd..4f603370243 100644 --- a/codeception/_support/Page/Admin/ProductClassEditPage.php +++ b/codeception/_support/Page/Admin/ProductClassEditPage.php @@ -51,6 +51,22 @@ public function 入力_規格1($value) return $this; } + public function 無効_規格($rowNum) + { + --$rowNum; + $this->tester->uncheckOption(['id' => "product_class_matrix_product_classes_${rowNum}_checked"]); + + return $this; + } + + public function 有効_規格($rowNum) + { + --$rowNum; + $this->tester->checkOption(['id' => "product_class_matrix_product_classes_${rowNum}_checked"]); + + return $this; + } + public function 入力_在庫数無制限($rowNum) { --$rowNum; @@ -59,6 +75,14 @@ public function 入力_在庫数無制限($rowNum) return $this; } + public function 無効_在庫数無制限($rowNum) + { + --$rowNum; + $this->tester->uncheckOption(['id' => "product_class_matrix_product_classes_${rowNum}_stock_unlimited"]); + + return $this; + } + public function 入力_販売価格($rowNum, $value) { --$rowNum; @@ -67,6 +91,14 @@ public function 入力_販売価格($rowNum, $value) return $this; } + public function 入力_個数($rowNum, $value) + { + --$rowNum; + $this->tester->fillField(['id' => "product_class_matrix_product_classes_${rowNum}_stock"], $value); + + return $this; + } + public function 選択($rowNum) { --$rowNum; diff --git a/codeception/acceptance/EA03ProductCest.php b/codeception/acceptance/EA03ProductCest.php index db3e71ddbc2..8d0b846c057 100644 --- a/codeception/acceptance/EA03ProductCest.php +++ b/codeception/acceptance/EA03ProductCest.php @@ -12,6 +12,8 @@ */ use Codeception\Util\Fixtures; +use Doctrine\DBAL\Connection; +use Doctrine\ORM\EntityManager; use Page\Admin\CategoryCsvUploadPage; use Page\Admin\CategoryManagePage; use Page\Admin\ClassCategoryManagePage; @@ -31,6 +33,12 @@ */ class EA03ProductCest { + /** @var EntityManager */ + private EntityManager $em; + + /** @var Connection */ + private Connection $conn; + const ページタイトル = '#main .page-header'; const ページタイトルStyleGuide = '.c-pageTitle'; @@ -39,6 +47,9 @@ public function _before(AcceptanceTester $I) // すべてのテストケース実施前にログインしておく // ログイン後は管理アプリのトップページに遷移している $I->loginAsAdmin(); + + $this->em = Fixtures::get('entityManager'); + $this->conn = $this->em->getConnection(); } public function _after(AcceptanceTester $I) @@ -264,9 +275,9 @@ public function product_一覧からの規格編集規格なし_(AcceptanceTeste $I->seeElement(ProductClassEditPage::$初期化ボタン); } - public function product_一覧からの規格編集規格あり2(AcceptanceTester $I) + public function product_一覧からの規格編集_規格あり_規格登録(AcceptanceTester $I) { - $I->wantTo('EA0310-UC02-T02 一覧からの規格編集 規格あり2'); + $I->wantTo('EA0310-UC02-T02 一覧からの規格編集 規格あり 規格登録'); $findProducts = Fixtures::get('findProducts'); $Products = array_filter($findProducts(), function ($Product) { @@ -357,9 +368,9 @@ public function product_商品の廃止(AcceptanceTester $I) /** * ATTENTION 削除すると後続の規格編集関連のテストが失敗するため、最後に実行する */ - public function product_一覧からの規格編集規格あり1(AcceptanceTester $I) + public function product_一覧からの規格編集規格あり(AcceptanceTester $I) { - $I->wantTo('EA0310-UC02-T01 一覧からの規格編集 規格あり1'); + $I->wantTo('EA0310-UC02-T01 一覧からの規格編集 規格あり'); $findProducts = Fixtures::get('findProducts'); $Products = array_filter($findProducts(), function ($Product) { @@ -1006,4 +1017,66 @@ public function product_詳細検索_タグ(AcceptanceTester $I) $I->see('検索結果:1件が該当しました', ProductManagePage::$検索結果_メッセージ); } + + /** + * @see https://github.com/EC-CUBE/ec-cube/pull/6029 + * + * @throws \Doctrine\ORM\OptimisticLockException + * @throws \Doctrine\ORM\TransactionRequiredException + * @throws \Doctrine\ORM\Exception\ORMException + * @throws \Doctrine\DBAL\Exception + */ + public function product_一覧からの規格編集_規格あり_重複在庫の修正(AcceptanceTester $I) + { + $I->wantTo('EA0310-UC02-T03 一覧からの規格編集 規格あり 重複在庫の修正'); + + $findProducts = Fixtures::get('findProducts'); + $Products = array_filter($findProducts(), function ($Product) { + return $Product->hasProductClass(); + }); + $Product = array_pop($Products); + + // 先頭のproductClass要素に対してStockを登録する + ProductManagePage::go($I) + ->検索($Product->getName()) + ->検索結果_選択(1); + + ProductEditPage::at($I) + ->規格管理(); + + ProductClassEditPage::at($I) + ->入力_在庫数無制限(1) + ->登録(); + + ProductClassEditPage::at($I) + ->無効_在庫数無制限(1) + ->入力_個数(1, 100) + ->登録(); + + ProductClassEditPage::at($I) + ->無効_規格(1) + ->登録(); + + ProductClassEditPage::at($I) + ->有効_規格(1) + ->入力_個数(1, 10) + ->入力_販売価格(1, 5000) + ->登録(); + + $I->see('保存しました', ProductClassEditPage::$登録完了メッセージ); + + /** 重複して在庫が登録されていないのかチェック **/ + // idを取得 + $ProductClasses = $Product->getProductClasses(); + $ProductClass = $ProductClasses[0]; + $id = $ProductClass->getId(); + + // 該当IDの商品が1つか確認 + $count = $this->conn->fetchOne('SELECT COUNT(*) FROM dtb_product_stock WHERE product_class_id = ?', [$id]); + $I->assertEquals('1', $count, '該当データは1件です'); + + // 個数のズレがないか確認 + $stock = $this->conn->fetchOne('SELECT stock FROM dtb_product_stock WHERE product_class_id = ?', [$id]); + $I->assertEquals('10', $stock, 'Stockが一致'); + } } diff --git a/src/Eccube/Controller/Admin/Product/ProductClassController.php b/src/Eccube/Controller/Admin/Product/ProductClassController.php index a6588b73d03..79c6beefd98 100644 --- a/src/Eccube/Controller/Admin/Product/ProductClassController.php +++ b/src/Eccube/Controller/Admin/Product/ProductClassController.php @@ -348,6 +348,7 @@ protected function saveProductClasses(Product $Product, $ProductClasses = []) 'create_date', 'update_date', 'Creator', + 'ProductStock', ]); $pc = $ExistsProductClass; }