diff --git a/app/DoctrineMigrations/Version20220603074035.php b/app/DoctrineMigrations/Version20220603074035.php new file mode 100644 index 00000000000..60c3159c821 --- /dev/null +++ b/app/DoctrineMigrations/Version20220603074035.php @@ -0,0 +1,78 @@ +connection->fetchColumn( + 'SELECT COUNT(*) FROM mtb_csv_type WHERE id = 6' + ); + if ($statusExists == 0) { + $this->addSql("INSERT INTO mtb_csv_type ('id', 'name', 'sort_no', 'discriminator_type') VALUES (6, 'Class NameCSV', 6, 'csvtype');"); + } + $statusExists = $this->connection->fetchColumn( + 'SELECT COUNT(*) FROM mtb_csv_type WHERE id = 7' + ); + if ($statusExists == 0) { + $this->addSql("INSERT INTO mtb_csv_type ('id', 'name', 'sort_no', 'discriminator_type') VALUES (7, 'Class Category CSV', 7, 'csvtype');"); + } + $statusExists = $this->connection->fetchColumn( + 'SELECT COUNT(*) FROM dtb_csv WHERE id = 206' + ); + if ($statusExists == 0) { + $this->addSql("INSERT INTO dtb_csv ('id','csv_type_id','creator_id','entity_name','field_name','reference_field_name','disp_name','sort_no','enabled','create_date','update_date','discriminator_type') VALUES ('206','6',,'Eccube\\Entity\\ClassName','id',,'規格ID','1','1','2021-05-18 01:26:41','2021-05-18 01:26:41','csv');"); + } + $statusExists = $this->connection->fetchColumn( + 'SELECT COUNT(*) FROM dtb_csv WHERE id = 207' + ); + if ($statusExists == 0) { + $this->addSql("INSERT INTO dtb_csv ('id','csv_type_id','creator_id','entity_name','field_name','reference_field_name','disp_name','sort_no','enabled','create_date','update_date','discriminator_type') VALUES ('207','6',,'Eccube\\Entity\\ClassName','name',,'規格名','2','1','2021-05-18 01:26:41','2021-05-18 01:26:41','csv');"); + } + $statusExists = $this->connection->fetchColumn( + 'SELECT COUNT(*) FROM dtb_csv WHERE id = 208' + ); + if ($statusExists == 0) { + $this->addSql("INSERT INTO dtb_csv ('id','csv_type_id','creator_id','entity_name','field_name','reference_field_name','disp_name','sort_no','enabled','create_date','update_date','discriminator_type') VALUES ('208','6',,'Eccube\\Entity\\ClassName','backend_name',,'管理名','3','1','2021-05-18 01:26:41','2021-05-18 01:26:41','csv');"); + } + $statusExists = $this->connection->fetchColumn( + 'SELECT COUNT(*) FROM dtb_csv WHERE id = 209' + ); + if ($statusExists == 0) { + $this->addSql("INSERT INTO dtb_csv ('id','csv_type_id','creator_id','entity_name','field_name','reference_field_name','disp_name','sort_no','enabled','create_date','update_date','discriminator_type') VALUES ('209','7',,'Eccube\\Entity\\ClassCategory','id',,'規格分類ID','1','1','2021-05-18 01:26:41','2021-05-18 01:26:41','csv');"); + } + $statusExists = $this->connection->fetchColumn( + 'SELECT COUNT(*) FROM dtb_csv WHERE id = 210' + ); + if ($statusExists == 0) { + $this->addSql("INSERT INTO dtb_csv ('id','csv_type_id','creator_id','entity_name','field_name','reference_field_name','disp_name','sort_no','enabled','create_date','update_date','discriminator_type') VALUES ('210','7',,'Eccube\\Entity\\ClassCategory','ClassName','id','規格ID','2','1','2021-05-18 01:26:41','2021-05-18 01:26:41','csv');"); + } + $statusExists = $this->connection->fetchColumn( + 'SELECT COUNT(*) FROM dtb_csv WHERE id = 211' + ); + if ($statusExists == 0) { + $this->addSql("INSERT INTO dtb_csv ('id','csv_type_id','creator_id','entity_name','field_name','reference_field_name','disp_name','sort_no','enabled','create_date','update_date','discriminator_type') VALUES ('211','7',,'Eccube\\Entity\\ClassCategory','name',,'規格分類名','3','1','2021-05-18 01:26:41','2021-05-18 01:26:41','csv');"); + } + $statusExists = $this->connection->fetchColumn( + 'SELECT COUNT(*) FROM dtb_csv WHERE id = 212' + ); + if ($statusExists == 0) { + $this->addSql("INSERT INTO dtb_csv ('id','csv_type_id','creator_id','entity_name','field_name','reference_field_name','disp_name','sort_no','enabled','create_date','update_date','discriminator_type') VALUES ('212','7',,'Eccube\\Entity\\ClassCategory','backend_name',,'分類管理名','4','1','2021-05-18 01:26:41','2021-05-18 01:26:41','csv');"); + } + } + + public function down(Schema $schema) : void + { + // this down() migration is auto-generated, please modify it to your needs + + } +} diff --git a/app/config/eccube/packages/eccube_nav.yaml b/app/config/eccube/packages/eccube_nav.yaml index c99677e05d3..e83df1b6ee3 100644 --- a/app/config/eccube/packages/eccube_nav.yaml +++ b/app/config/eccube/packages/eccube_nav.yaml @@ -22,6 +22,12 @@ parameters: product_csv_import: name: admin.product.product_csv_upload url: admin_product_csv_import + class_name_csv_import: + name: admin.product.class_name_csv_upload + url: admin_product_class_name_csv_import + class_category_csv_import: + name: admin.product.class_category_csv_upload + url: admin_product_class_category_csv_import category_csv_import: name: admin.product.category_csv_upload url: admin_product_category_csv_import diff --git a/codeception/_data/class_category.csv b/codeception/_data/class_category.csv new file mode 100644 index 00000000000..5d0c79d99b0 --- /dev/null +++ b/codeception/_data/class_category.csv @@ -0,0 +1,4 @@ +規格ID,規格分類ID,規格分類名,規格分類管理名,規格分類削除フラグ +1,,アップロード規格分類1,, +1,,アップロード規格分類2,, +1,,アップロード規格分類3,, \ No newline at end of file diff --git a/codeception/_data/class_name.csv b/codeception/_data/class_name.csv new file mode 100644 index 00000000000..e8c57218c34 --- /dev/null +++ b/codeception/_data/class_name.csv @@ -0,0 +1,4 @@ +規格ID,規格名,管理名,規格削除フラグ +,アップロード規格1,, +,アップロード規格2,, +,アップロード規格3,, diff --git a/codeception/_support/Page/Admin/ClassCategoryCsvUploadPage.php b/codeception/_support/Page/Admin/ClassCategoryCsvUploadPage.php new file mode 100644 index 00000000000..f56a4f31d35 --- /dev/null +++ b/codeception/_support/Page/Admin/ClassCategoryCsvUploadPage.php @@ -0,0 +1,55 @@ + div.alert-success'; + + /** + * ClassCategoryCsvUploadPage constructor. + */ + public function __construct(\AcceptanceTester $I) + { + parent::__construct($I); + } + + public static function go($I) + { + $page = new self($I); + + return $page->goPage('/product/class_category_csv_upload', '規格分類CSV登録商品管理'); + } + + public function 入力_CSVファイル($fileName) + { + $this->tester->attachFile(['id' => 'admin_csv_import_import_file'], $fileName); + + return $this; + } + + public function CSVアップロード() + { + $this->tester->click(['id' => 'upload-button']); + + return $this; + } + + public function 雛形ダウンロード() + { + $this->tester->click('#download-button'); + + return $this; + } +} diff --git a/codeception/_support/Page/Admin/ClassCategoryManagePage.php b/codeception/_support/Page/Admin/ClassCategoryManagePage.php index 2505ce1e395..bf80f1c63a3 100644 --- a/codeception/_support/Page/Admin/ClassCategoryManagePage.php +++ b/codeception/_support/Page/Admin/ClassCategoryManagePage.php @@ -85,6 +85,18 @@ public function acceptModal() return $this; } + public function CSVダウンロード実行() + { + $this->tester->click('body > div > div.c-contentsArea > div.c-outsideBlock > div > div > div.col-6.text-end > div > a:nth-child(1)'); + + return $this; + } + + public function CSV出力項目設定() + { + $this->tester->click('body > div > div.c-contentsArea > div.c-outsideBlock > div > div > div.col-6.text-end > div > a:nth-child(2)'); + } + public function 一覧_上に($rowNum) { $this->tester->dragAndDropBy("ul.list-group > li:nth-child(${rowNum})", 0, -60); @@ -103,4 +115,9 @@ public function 一覧_名称($rowNum) { return "ul.list-group > li:nth-child(${rowNum}) > div > div.col.d-flex.align-items-center"; } + + public static function XPathでタグを取得する($textEl) + { + return '//*[@id="page_admin_product_class_category"]/div[1]/div[3]/div[2]/div[1]/div/div[3]/div[2]/div/ul/li/div/div[3][contains(text(), "'.$textEl.'")]'; + } } diff --git a/codeception/_support/Page/Admin/ClassNameCsvUploadPage.php b/codeception/_support/Page/Admin/ClassNameCsvUploadPage.php new file mode 100644 index 00000000000..266325c46fc --- /dev/null +++ b/codeception/_support/Page/Admin/ClassNameCsvUploadPage.php @@ -0,0 +1,55 @@ + div.alert-success'; + + /** + * ClassNameCsvUploadPage constructor. + */ + public function __construct(\AcceptanceTester $I) + { + parent::__construct($I); + } + + public static function go($I) + { + $page = new self($I); + + return $page->goPage('/product/class_name_csv_upload', '規格CSV登録商品管理'); + } + + public function 入力_CSVファイル($fileName) + { + $this->tester->attachFile(['id' => 'admin_csv_import_import_file'], $fileName); + + return $this; + } + + public function CSVアップロード() + { + $this->tester->click(['id' => 'upload-button']); + + return $this; + } + + public function 雛形ダウンロード() + { + $this->tester->click('#download-button'); + + return $this; + } +} diff --git a/codeception/_support/Page/Admin/ClassNameManagePage.php b/codeception/_support/Page/Admin/ClassNameManagePage.php index 1edf45ada66..29660603cc3 100644 --- a/codeception/_support/Page/Admin/ClassNameManagePage.php +++ b/codeception/_support/Page/Admin/ClassNameManagePage.php @@ -79,6 +79,13 @@ public function 一覧_分類登録($rowNum) return $this; } + public function 一覧_分類登録2() + { + $this->tester->click("ul.list-group > li:last-child > div > div.col.d-flex.align-items-center > a"); + + return $this; + } + public function 一覧_編集($rowNum) { $this->tester->click("ul.list-group > li:nth-child(${rowNum}) > div > div.col-auto.text-end > a.action-edit"); @@ -103,6 +110,18 @@ public function acceptModal() return $this; } + public function CSVダウンロード実行() + { + $this->tester->click('body > div > div.c-contentsArea > div.c-outsideBlock > div > div > div.col-6.text-end > div > a:nth-child(1)'); + + return $this; + } + + public function CSV出力項目設定() + { + $this->tester->click('body > div > div.c-contentsArea > div.c-outsideBlock > div > div > div.col-6.text-end > div > a:nth-child(2)'); + } + public function 一覧_上に($rowNum) { $this->tester->dragAndDropBy("ul.list-group > li:nth-child(${rowNum})", 0, -60); @@ -116,4 +135,9 @@ public function 一覧_下に($rowNum) return $this; } + + public static function XPathでタグを取得する($textEl) + { + return '//*[@id="page_admin_product_class_name"]/div[1]/div[3]/div[3]/div[1]/div/div/div/div/ul/li/div/div[3]/a[contains(text(), "'.$textEl.'")]'; + } } diff --git a/codeception/acceptance/EA03ProductCest.php b/codeception/acceptance/EA03ProductCest.php index 8d0b846c057..5db3e4562a9 100644 --- a/codeception/acceptance/EA03ProductCest.php +++ b/codeception/acceptance/EA03ProductCest.php @@ -15,6 +15,8 @@ use Doctrine\DBAL\Connection; use Doctrine\ORM\EntityManager; use Page\Admin\CategoryCsvUploadPage; +use Page\Admin\ClassNameCsvUploadPage; +use Page\Admin\ClassCategoryCsvUploadPage; use Page\Admin\CategoryManagePage; use Page\Admin\ClassCategoryManagePage; use Page\Admin\ClassNameManagePage; @@ -872,6 +874,92 @@ public function product_カテゴリCSV登録雛形ファイルダウンロー $I->assertEquals(1, count(file($CategoryTemplateCSV)), 'ヘッダ行だけのファイル'); } + public function product_規格CSV登録(AcceptanceTester $I) + { + $I->wantTo('EA0307-UC02-T01 規格CSV登録'); + + ClassNameManagePage::go($I); + $I->dontSeeElement(['xpath' => '//div[@id="sortable_list_box"]//a[contains(text(), "アップロード規格")]']); + + ClassNameCsvUploadPage::go($I) + ->入力_CSVファイル('class_name.csv') + ->CSVアップロード(); + + $I->see('CSVファイルをアップロードしました', ClassNameCsvUploadPage::$完了メッセージ); + + ClassNameManagePage::go($I); + + $I->seeElement(['xpath' => ClassNameManagePage::XPathでタグを取得する('アップロード規格1')]); + $I->seeElement(['xpath' => ClassNameManagePage::XPathでタグを取得する('アップロード規格2')]); + $I->seeElement(['xpath' => ClassNameManagePage::XPathでタグを取得する('アップロード規格3')]); + + // アップロード失敗 (フォーマットの異なるcsvをアップロードする) + ClassNameCsvUploadPage::go($I) + ->入力_CSVファイル('product.csv') + ->CSVアップロード(); + $I->see('CSVのフォーマットが一致しません', '#upload-form'); + } + + /** + * @env firefox + * @env chrome + */ + public function product_規格CSV登録雛形ファイルダウンロード(AcceptanceTester $I) + { + $I->wantTo('EA0307-UC02-T02 規格CSV登録雛形ファイルダウンロード'); + + // 雛形のダウンロード + ClassNameCsvUploadPage::go($I)->雛形ダウンロード(); + $ClassNameTemplateCSV = $I->getLastDownloadFile('/^class_name\.csv$/'); + $I->assertEquals(1, count(file($ClassNameTemplateCSV)), 'ヘッダ行だけのファイル'); + } + + public function product_規格分類CSV登録(AcceptanceTester $I) + { + $I->wantTo('EA0307-UC03-T01 規格分類CSV登録'); + + ClassNameManagePage::go($I) + ->一覧_分類登録(3); + + ClassCategoryManagePage::at($I); + $I->dontSeeElement(['xpath' => '//div[@id="sortable_list_box"]//a[contains(text(), "アップロード規格分類")]']); + + ClassCategoryCsvUploadPage::go($I) + ->入力_CSVファイル('class_category.csv') + ->CSVアップロード(); + + $I->see('CSVファイルをアップロードしました', ClassCategoryCsvUploadPage::$完了メッセージ); + + ClassNameManagePage::go($I) + ->一覧_分類登録2(); + + ClassCategoryManagePage::at($I); + + $I->seeElement(['xpath' => ClassCategoryManagePage::XPathでタグを取得する('アップロード規格分類1')]); + $I->seeElement(['xpath' => ClassCategoryManagePage::XPathでタグを取得する('アップロード規格分類2')]); + $I->seeElement(['xpath' => ClassCategoryManagePage::XPathでタグを取得する('アップロード規格分類3')]); + + // アップロード失敗 (フォーマットの異なるcsvをアップロードする) + ClassCategoryCsvUploadPage::go($I) + ->入力_CSVファイル('product.csv') + ->CSVアップロード(); + $I->see('CSVのフォーマットが一致しません', '#upload-form'); + } + + /** + * @env firefox + * @env chrome + */ + public function product_規格分類CSV登録雛形ファイルダウンロード(AcceptanceTester $I) + { + $I->wantTo('EA0307-UC03-T02 規格分類CSV登録雛形ファイルダウンロード'); + + // 雛形のダウンロード + ClassCategoryCsvUploadPage::go($I)->雛形ダウンロード(); + $ClassCategoryTemplateCSV = $I->getLastDownloadFile('/^class_category\.csv$/'); + $I->assertEquals(1, count(file($ClassCategoryTemplateCSV)), 'ヘッダ行だけのファイル'); + } + public function product_タグ登録(AcceptanceTester $I) { $I->wantTo('EA0308-UC01-T01 / UC01-T02 タグ登録'); diff --git a/src/Eccube/Controller/Admin/Product/ClassCategoryController.php b/src/Eccube/Controller/Admin/Product/ClassCategoryController.php index 9f6e189d423..a25ac281566 100644 --- a/src/Eccube/Controller/Admin/Product/ClassCategoryController.php +++ b/src/Eccube/Controller/Admin/Product/ClassCategoryController.php @@ -14,15 +14,18 @@ namespace Eccube\Controller\Admin\Product; use Eccube\Controller\AbstractController; +use Eccube\Entity\Master\CsvType; use Eccube\Event\EccubeEvents; use Eccube\Event\EventArgs; use Eccube\Form\Type\Admin\ClassCategoryType; use Eccube\Repository\ClassCategoryRepository; use Eccube\Repository\ClassNameRepository; use Eccube\Repository\ProductClassRepository; +use Eccube\Service\CsvExportService; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; @@ -44,21 +47,29 @@ class ClassCategoryController extends AbstractController */ protected $classNameRepository; + /** + * @var CsvExportService + */ + protected $csvExportService; + /** * ClassCategoryController constructor. * * @param ProductClassRepository $productClassRepository * @param ClassCategoryRepository $classCategoryRepository * @param ClassNameRepository $classNameRepository + * @param CsvExportService $csvExportService */ public function __construct( ProductClassRepository $productClassRepository, ClassCategoryRepository $classCategoryRepository, - ClassNameRepository $classNameRepository + ClassNameRepository $classNameRepository, + CsvExportService $csvExportService ) { $this->productClassRepository = $productClassRepository; $this->classCategoryRepository = $classCategoryRepository; $this->classNameRepository = $classNameRepository; + $this->csvExportService = $csvExportService; } /** @@ -265,4 +276,77 @@ public function moveSortNo(Request $request) return new Response('Successful'); } } + + /** + * 規格分類CSVの出力. + * + * @Route("/%eccube_admin_route%/product/class_category/export/{class_name_id}", name="admin_product_class_category_export") + * + * @param Request $request + * + * @return StreamedResponse + */ + public function export(Request $request, $class_name_id) + { + // タイムアウトを無効にする. + set_time_limit(0); + + // sql loggerを無効にする. + $em = $this->entityManager; + $em->getConfiguration()->setSQLLogger(null); + + $response = new StreamedResponse(); + $response->setCallback(function () use ($request, $class_name_id) { + // CSV種別を元に初期化. + $this->csvExportService->initCsvType(CsvType::CSV_TYPE_CLASS_CATEGORY); + // ヘッダ行の出力. + $this->csvExportService->exportHeader(); + + $qb = $this->classCategoryRepository + ->createQueryBuilder('cc') + ->where('cc.ClassName = :ClassName') + ->setParameter('ClassName', $class_name_id) + ->orderBy('cc.sort_no', 'DESC'); + + // データ行の出力. + $this->csvExportService->setExportQueryBuilder($qb); + $this->csvExportService->exportData(function ($entity, $csvService) use ($request) { + $Csvs = $csvService->getCsvs(); + + /** @var $ClassCategory \Eccube\Entity\ClassCategory */ + $ClassCategory = $entity; + + // CSV出力項目と合致するデータを取得. + $ExportCsvRow = new \Eccube\Entity\ExportCsvRow(); + foreach ($Csvs as $Csv) { + $ExportCsvRow->setData($csvService->getData($Csv, $ClassCategory)); + + $event = new EventArgs( + [ + 'csvService' => $csvService, + 'Csv' => $Csv, + 'ClassCategory' => $ClassCategory, + 'ExportCsvRow' => $ExportCsvRow, + ], + $request + ); + $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_CLASS_CATEGORY_CSV_EXPORT, $event); + + $ExportCsvRow->pushData(); + } + //$row[] = number_format(memory_get_usage(true)); + // 出力. + $csvService->fputcsv($ExportCsvRow->getRow()); + }); + }); + $now = new \DateTime(); + $filename = 'class_category_'.$now->format('YmdHis').'.csv'; + $response->headers->set('Content-Type', 'application/octet-stream'); + $response->headers->set('Content-Disposition', 'attachment; filename='.$filename); + $response->send(); + + log_info('規格分類CSV出力ファイル名', [$filename]); + + return $response; + } } diff --git a/src/Eccube/Controller/Admin/Product/ClassNameController.php b/src/Eccube/Controller/Admin/Product/ClassNameController.php index be9f39b3cfd..bf6fc2aeddd 100644 --- a/src/Eccube/Controller/Admin/Product/ClassNameController.php +++ b/src/Eccube/Controller/Admin/Product/ClassNameController.php @@ -15,13 +15,16 @@ use Eccube\Controller\AbstractController; use Eccube\Entity\ClassName; +use Eccube\Entity\Master\CsvType; use Eccube\Event\EccubeEvents; use Eccube\Event\EventArgs; use Eccube\Form\Type\Admin\ClassNameType; use Eccube\Repository\ClassNameRepository; +use Eccube\Service\CsvExportService; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; @@ -33,14 +36,23 @@ class ClassNameController extends AbstractController */ protected $classNameRepository; + /** + * @var CsvExportService + */ + protected $csvExportService; + /** * ClassNameController constructor. * * @param ClassNameRepository $classNameRepository + * @param CsvExportService $csvExportService */ - public function __construct(ClassNameRepository $classNameRepository) - { + public function __construct( + ClassNameRepository $classNameRepository, + CsvExportService $csvExportService + ) { $this->classNameRepository = $classNameRepository; + $this->csvExportService = $csvExportService; } /** @@ -184,4 +196,77 @@ public function moveSortNo(Request $request) return new Response(); } } + + /** + * 規格CSVの出力. + * + * @Route("/%eccube_admin_route%/product/class_name/export", name="admin_product_class_name_export") + * + * @param Request $request + * + * @return StreamedResponse + */ + public function export(Request $request) + { + // タイムアウトを無効にする. + set_time_limit(0); + + // sql loggerを無効にする. + $em = $this->entityManager; + $em->getConfiguration()->setSQLLogger(null); + + $response = new StreamedResponse(); + $response->setCallback(function () use ($request) { + // CSV種別を元に初期化. + $this->csvExportService->initCsvType(CsvType::CSV_TYPE_CLASS_NAME); + + // ヘッダ行の出力. + $this->csvExportService->exportHeader(); + + $qb = $this->classNameRepository + ->createQueryBuilder('cn') + ->orderBy('cn.sort_no', 'DESC'); + + // データ行の出力. + $this->csvExportService->setExportQueryBuilder($qb); + $this->csvExportService->exportData(function ($entity, $csvService) use ($request) { + $Csvs = $csvService->getCsvs(); + + /** @var $ClassName \Eccube\Entity\ClassName */ + $ClassName = $entity; + + // CSV出力項目と合致するデータを取得. + $ExportCsvRow = new \Eccube\Entity\ExportCsvRow(); + foreach ($Csvs as $Csv) { + $ExportCsvRow->setData($csvService->getData($Csv, $ClassName)); + + $event = new EventArgs( + [ + 'csvService' => $csvService, + 'Csv' => $Csv, + 'ClassName' => $ClassName, + 'ExportCsvRow' => $ExportCsvRow, + ], + $request + ); + $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_CLASS_NAME_CSV_EXPORT, $event); + + $ExportCsvRow->pushData(); + } + //$row[] = number_format(memory_get_usage(true)); + // 出力. + $csvService->fputcsv($ExportCsvRow->getRow()); + }); + }); + + $now = new \DateTime(); + $filename = 'class_name_'.$now->format('YmdHis').'.csv'; + $response->headers->set('Content-Type', 'application/octet-stream'); + $response->headers->set('Content-Disposition', 'attachment; filename='.$filename); + $response->send(); + + log_info('規格CSV出力ファイル名', [$filename]); + + return $response; + } } diff --git a/src/Eccube/Controller/Admin/Product/CsvImportController.php b/src/Eccube/Controller/Admin/Product/CsvImportController.php index 31e9c282444..c5bbd06caf6 100644 --- a/src/Eccube/Controller/Admin/Product/CsvImportController.php +++ b/src/Eccube/Controller/Admin/Product/CsvImportController.php @@ -18,6 +18,8 @@ use Eccube\Controller\Admin\AbstractCsvImportController; use Eccube\Entity\BaseInfo; use Eccube\Entity\Category; +use Eccube\Entity\ClassName; +use Eccube\Entity\ClassCategory; use Eccube\Entity\Product; use Eccube\Entity\ProductCategory; use Eccube\Entity\ProductClass; @@ -27,6 +29,7 @@ use Eccube\Form\Type\Admin\CsvImportType; use Eccube\Repository\BaseInfoRepository; use Eccube\Repository\CategoryRepository; +use Eccube\Repository\ClassNameRepository; use Eccube\Repository\ClassCategoryRepository; use Eccube\Repository\DeliveryDurationRepository; use Eccube\Repository\Master\ProductStatusRepository; @@ -81,6 +84,11 @@ class CsvImportController extends AbstractCsvImportController */ protected $classCategoryRepository; + /** + * @var ClassNameRepository + */ + protected $classNameRepository; + /** * @var ProductImageRepository */ @@ -126,6 +134,7 @@ class CsvImportController extends AbstractCsvImportController * @param SaleTypeRepository $saleTypeRepository * @param TagRepository $tagRepository * @param CategoryRepository $categoryRepository + * @param ClassNameRepository $classNameRepository * @param ClassCategoryRepository $classCategoryRepository * @param ProductImageRepository $productImageRepository * @param ProductStatusRepository $productStatusRepository @@ -141,6 +150,7 @@ public function __construct( SaleTypeRepository $saleTypeRepository, TagRepository $tagRepository, CategoryRepository $categoryRepository, + ClassNameRepository $classNameRepository, ClassCategoryRepository $classCategoryRepository, ProductImageRepository $productImageRepository, ProductStatusRepository $productStatusRepository, @@ -153,6 +163,7 @@ public function __construct( $this->saleTypeRepository = $saleTypeRepository; $this->tagRepository = $tagRepository; $this->categoryRepository = $categoryRepository; + $this->classNameRepository = $classNameRepository; $this->classCategoryRepository = $classCategoryRepository; $this->productImageRepository = $productImageRepository; $this->productStatusRepository = $productStatusRepository; @@ -843,6 +854,262 @@ public function csvCategory(Request $request, CacheUtil $cacheUtil) return $this->renderWithError($form, $headers); } + /** + * 規格登録CSVアップロード + * + * @Route("/%eccube_admin_route%/product/class_name_csv_upload", name="admin_product_class_name_csv_import") + * @Template("@admin/Product/csv_class_name.twig") + */ + public function csvClassName(Request $request, CacheUtil $cacheUtil) + { + $form = $this->formFactory->createBuilder(CsvImportType::class)->getForm(); + + $headers = $this->getClassNameCsvHeader(); + if ('POST' === $request->getMethod()) { + $form->handleRequest($request); + if ($form->isValid()) { + $formFile = $form['import_file']->getData(); + if (!empty($formFile)) { + log_info('規格CSV登録開始'); + $data = $this->getImportData($formFile); + if ($data === false) { + $this->addErrors(trans('admin.common.csv_invalid_format')); + + return $this->renderWithError($form, $headers, false); + } + + $getId = function ($item) { + return $item['id']; + }; + $requireHeader = array_keys(array_map($getId, array_filter($headers, function ($value) { + return $value['required']; + }))); + + $headerByKey = array_flip(array_map($getId, $headers)); + + $columnHeaders = $data->getColumnHeaders(); + if (count(array_diff($requireHeader, $columnHeaders)) > 0) { + $this->addErrors(trans('admin.common.csv_invalid_format')); + + return $this->renderWithError($form, $headers, false); + } + + $size = count($data); + if ($size < 1) { + $this->addErrors(trans('admin.common.csv_invalid_no_data')); + + return $this->renderWithError($form, $headers, false); + } + $this->entityManager->getConfiguration()->setSQLLogger(null); + $this->entityManager->getConnection()->beginTransaction(); + // CSVファイルの登録処理 + foreach ($data as $row) { + // dump($row,$headerByKey);exit; + /** @var $ClassName ClassName */ + $ClassName = new ClassName(); + if (isset($row[$headerByKey['id']]) && strlen($row[$headerByKey['id']]) > 0) { + if (!preg_match('/^\d+$/', $row[$headerByKey['id']])) { + $this->addErrors(($data->key() + 1).'行目の規格IDが存在しません。'); + + return $this->renderWithError($form, $headers); + } + $ClassName = $this->classNameRepository->find($row[$headerByKey['id']]); + if (!$ClassName) { + $this->addErrors(($data->key() + 1).'行目の更新対象の規格IDが存在しません。新規登録の場合は、規格IDの値を空で登録してください。'); + + return $this->renderWithError($form, $headers); + } + } + + if (isset($row[$headerByKey['class_name_del_flg']]) && StringUtil::isNotBlank($row[$headerByKey['class_name_del_flg']])) { + if (StringUtil::trimAll($row[$headerByKey['class_name_del_flg']]) == 1) { + if ($ClassName->getId()) { + log_info('規格削除開始', [$ClassName->getId()]); + try { + $this->classNameRepository->delete($ClassName); + log_info('規格削除完了', [$ClassName->getId()]); + } catch (ForeignKeyConstraintViolationException $e) { + log_info('規格削除エラー', [$ClassName->getId(), $e]); + $message = trans('admin.common.delete_error_foreign_key', ['%name%' => $ClassName->getName()]); + $this->addError($message, 'admin'); + + return $this->renderWithError($form, $headers); + } + } + + continue; + } + } + + if (!isset($row[$headerByKey['name']]) || StringUtil::isBlank($row[$headerByKey['name']])) { + $this->addErrors(($data->key() + 1).'行目規格名が設定されていません。'); + + return $this->renderWithError($form, $headers); + } else { + $ClassName->setName(StringUtil::trimAll($row[$headerByKey['name']])); + } + + if (isset($row[$headerByKey['backend_name']]) && StringUtil::isNotBlank($row[$headerByKey['backend_name']])) { + $ClassName->setBackendName(StringUtil::trimAll($row[$headerByKey['backend_name']])); + } + + if ($this->hasErrors()) { + return $this->renderWithError($form, $headers); + } + $this->entityManager->persist($ClassName); + $this->classNameRepository->save($ClassName); + } + + $this->entityManager->getConnection()->commit(); + log_info('規格CSV登録完了'); + $message = 'admin.common.csv_upload_complete'; + $this->session->getFlashBag()->add('eccube.admin.success', $message); + + $cacheUtil->clearDoctrineCache(); + } + } + } + + return $this->renderWithError($form, $headers); + } + + + /** + * 規格分類CSV登録CSVアップロード + * + * @Route("/%eccube_admin_route%/product/class_category_csv_upload", name="admin_product_class_category_csv_import") + * @Template("@admin/Product/csv_class_category.twig") + */ + public function csvClassCategory(Request $request, CacheUtil $cacheUtil) + { + $form = $this->formFactory->createBuilder(CsvImportType::class)->getForm(); + + $headers = $this->getClassCategoryCsvHeader(); + if ('POST' === $request->getMethod()) { + $form->handleRequest($request); + if ($form->isValid()) { + $formFile = $form['import_file']->getData(); + if (!empty($formFile)) { + log_info('規格分類CSV登録開始'); + $data = $this->getImportData($formFile); + if ($data === false) { + $this->addErrors(trans('admin.common.csv_invalid_format')); + + return $this->renderWithError($form, $headers, false); + } + + $getId = function ($item) { + return $item['id']; + }; + $requireHeader = array_keys(array_map($getId, array_filter($headers, function ($value) { + return $value['required']; + }))); + + $headerByKey = array_flip(array_map($getId, $headers)); + + $columnHeaders = $data->getColumnHeaders(); + if (count(array_diff($requireHeader, $columnHeaders)) > 0) { + $this->addErrors(trans('admin.common.csv_invalid_format')); + + return $this->renderWithError($form, $headers, false); + } + + $size = count($data); + if ($size < 1) { + $this->addErrors(trans('admin.common.csv_invalid_no_data')); + + return $this->renderWithError($form, $headers, false); + } + $this->entityManager->getConfiguration()->setSQLLogger(null); + $this->entityManager->getConnection()->beginTransaction(); + // CSVファイルの登録処理 + foreach ($data as $row) { + // dump($row,$headerByKey);exit; + /** @var $ClassCategory ClassCategory */ + $ClassCategory = new ClassCategory(); + + if (isset($row[$headerByKey['id']]) && strlen($row[$headerByKey['id']]) > 0) { + if (!preg_match('/^\d+$/', $row[$headerByKey['id']])) { + $this->addErrors(($data->key() + 1).'行目の規格分類IDが存在しません。'); + + return $this->renderWithError($form, $headers); + } + $ClassCategory = $this->classCategoryRepository->find($row[$headerByKey['id']]); + if (!$ClassCategory) { + $this->addErrors(($data->key() + 1).'行目の更新対象の規格分類IDが存在しません。新規登録の場合は、規格分類IDの値を空で登録してください。'); + + return $this->renderWithError($form, $headers); + } + } + + if (isset($row[$headerByKey['class_name_id']]) && strlen($row[$headerByKey['class_name_id']]) > 0) { + if (!preg_match('/^\d+$/', $row[$headerByKey['class_name_id']])) { + $this->addErrors(($data->key() + 1).'行目の規格IDが存在しません。'); + + return $this->renderWithError($form, $headers); + } + $ClassName = $this->classNameRepository->find($row[$headerByKey['class_name_id']]); + if (!$ClassName) { + $this->addErrors(($data->key() + 1).'行目の更新対象の規格IDが存在しません。'); + + return $this->renderWithError($form, $headers); + } + $ClassCategory->setClassName($ClassName); + } + + if (isset($row[$headerByKey['class_category_del_flg']]) && StringUtil::isNotBlank($row[$headerByKey['class_category_del_flg']])) { + if (StringUtil::trimAll($row[$headerByKey['class_category_del_flg']]) == 1) { + if ($ClassCategory->getId()) { + log_info('規格分類削除開始', [$ClassCategory->getId()]); + try { + $this->classCategoryRepository->delete($ClassCategory); + log_info('規格分類削除完了', [$ClassCategory->getId()]); + } catch (ForeignKeyConstraintViolationException $e) { + log_info('規格分類削除エラー', [$ClassCategory->getId(), $e]); + $message = trans('admin.common.delete_error_foreign_key', ['%name%' => $ClassCategory->getName()]); + $this->addError($message, 'admin'); + + return $this->renderWithError($form, $headers); + } + } + + continue; + } + } + + if (!isset($row[$headerByKey['name']]) || StringUtil::isBlank($row[$headerByKey['name']])) { + $this->addErrors(($data->key() + 1).'行目規格分類名が設定されていません。'); + + return $this->renderWithError($form, $headers); + } else { + $ClassCategory->setName(StringUtil::trimAll($row[$headerByKey['name']])); + } + + if (isset($row[$headerByKey['backend_name']]) && StringUtil::isNotBlank($row[$headerByKey['backend_name']])) { + $ClassCategory->setBackendName(StringUtil::trimAll($row[$headerByKey['backend_name']])); + } + + if ($this->hasErrors()) { + return $this->renderWithError($form, $headers); + } + $this->entityManager->persist($ClassCategory); + $this->classCategoryRepository->save($ClassCategory); + } + + $this->entityManager->getConnection()->commit(); + log_info('規格分類CSV登録完了'); + $message = 'admin.common.csv_upload_complete'; + $this->session->getFlashBag()->add('eccube.admin.success', $message); + + $cacheUtil->clearDoctrineCache(); + } + } + } + + return $this->renderWithError($form, $headers); + } + + /** * アップロード用CSV雛形ファイルダウンロード * @@ -860,6 +1127,12 @@ public function csvTemplate(Request $request, $type) } elseif ($type == 'category') { $headers = $this->getCategoryCsvHeader(); $filename = 'category.csv'; + } elseif ($type == 'class_name') { + $headers = $this->getClassNameCsvHeader(); + $filename = 'class_name.csv'; + } elseif ($type == 'class_category') { + $headers = $this->getClassCategoryCsvHeader(); + $filename = 'class_category.csv'; } else { throw new NotFoundHttpException(); } @@ -1602,6 +1875,69 @@ protected function getCategoryCsvHeader() ]; } + /** + * 規格CSVヘッダー定義 + */ + protected function getClassNameCsvHeader() + { + return [ + trans('admin.product.class_name_csv.class_name_id_col') => [ + 'id' => 'id', + 'description' => 'admin.product.class_name_csv.class_name_id_description', + 'required' => false, + ], + trans('admin.product.class_name_csv.class_name_col') => [ + 'id' => 'name', + 'description' => 'admin.product.class_name_csv.class_name_description', + 'required' => true, + ], + trans('admin.product.class_name_csv.class_backend_name_col') => [ + 'id' => 'backend_name', + 'description' => 'admin.product.class_name_csv.class_backend_name_description', + 'required' => false, + ], + trans('admin.product.class_name_csv.delete_flag_col') => [ + 'id' => 'class_name_del_flg', + 'description' => 'admin.product.class_name_csv.delete_flag_description', + 'required' => false, + ], + ]; + } + + /** + * 規格分類CSVヘッダー定義 + */ + protected function getClassCategoryCsvHeader() + { + return [ + trans('admin.product.class_category_csv.class_name_id_col') => [ + 'id' => 'class_name_id', + 'description' => 'admin.product.class_category_csv.class_name_id_description', + 'required' => true, + ], + trans('admin.product.class_category_csv.class_category_id_col') => [ + 'id' => 'id', + 'description' => 'admin.product.class_category_csv.class_category_id_description', + 'required' => false, + ], + trans('admin.product.class_category_csv.class_category_name_col') => [ + 'id' => 'name', + 'description' => 'admin.product.class_category_csv.class_category_name_description', + 'required' => true, + ], + trans('admin.product.class_category_csv.class_category_backend_name_col') => [ + 'id' => 'backend_name', + 'description' => 'admin.product.class_category_csv.class_category_backend_name_description', + 'required' => false, + ], + trans('admin.product.class_category_csv.delete_flag_col') => [ + 'id' => 'class_category_del_flg', + 'description' => 'admin.product.class_category_csv.delete_flag_description', + 'required' => false, + ], + ]; + } + /** * ProductCategory作成 * diff --git a/src/Eccube/Entity/Master/CsvType.php b/src/Eccube/Entity/Master/CsvType.php index 908c7f471c1..829470f6e25 100644 --- a/src/Eccube/Entity/Master/CsvType.php +++ b/src/Eccube/Entity/Master/CsvType.php @@ -52,5 +52,15 @@ class CsvType extends \Eccube\Entity\Master\AbstractMasterEntity * @var integer */ public const CSV_TYPE_CATEGORY = 5; + + /** + * @var integer + */ + public const CSV_TYPE_CLASS_NAME = 6; + + /** + * @var integer + */ + public const CSV_TYPE_CLASS_CATEGORY = 7; } } diff --git a/src/Eccube/Event/EccubeEvents.php b/src/Eccube/Event/EccubeEvents.php index 1cff1fab64e..3d02d9a86b6 100644 --- a/src/Eccube/Event/EccubeEvents.php +++ b/src/Eccube/Event/EccubeEvents.php @@ -214,6 +214,9 @@ final class EccubeEvents // delete public const ADMIN_PRODUCT_CLASS_CATEGORY_DELETE_COMPLETE = 'admin.product.class.category.delete.complete'; + // export + const ADMIN_PRODUCT_CLASS_CATEGORY_CSV_EXPORT = 'admin.product.class.category.csv.export'; + /** * Admin/Product/ClassNameController */ @@ -224,6 +227,9 @@ final class EccubeEvents // delete public const ADMIN_PRODUCT_CLASS_NAME_DELETE_COMPLETE = 'admin.product.class.name.delete.complete'; + // export + const ADMIN_PRODUCT_CLASS_NAME_CSV_EXPORT = 'admin.product.class.name.csv.export'; + /** * Admin/Product/CsvImportController */ diff --git a/src/Eccube/Resource/doctrine/import_csv/en/dtb_csv.csv b/src/Eccube/Resource/doctrine/import_csv/en/dtb_csv.csv index 92ae9e99aad..08c4a5cbf69 100644 --- a/src/Eccube/Resource/doctrine/import_csv/en/dtb_csv.csv +++ b/src/Eccube/Resource/doctrine/import_csv/en/dtb_csv.csv @@ -203,3 +203,10 @@ id,csv_type_id,creator_id,entity_name,field_name,reference_field_name,disp_name, 204,1,,Eccube\\Entity\\ProductClass,TaxRule,tax_rate,Tax Rate,"31","0","2017-03-07 10:14:00","2017-03-07 10:14:00","csv" 205,2,,Eccube\\Entity\\Customer,point,,Point,32,1,2017-03-07 10:14:00,2017-03-07 10:14:00,csv 206,1,,Eccube\\Entity\\ProductClass,visible,,Product options visible flag,32,0,2022-11-24 00:00:00,2022-11-24 00:00:00,csv +207,6,,Eccube\\Entity\\ClassName,id,,Class Name ID,1,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +208,6,,Eccube\\Entity\\ClassName,name,,Class Name,2,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +209,6,,Eccube\\Entity\\ClassName,backend_name,,Backend Name,3,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +210,7,,Eccube\\Entity\\ClassCategory,id,,Class Category ID,1,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +211,7,,Eccube\\Entity\\ClassCategory,ClassName,id,Class NameID,2,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +212,7,,Eccube\\Entity\\ClassCategory,name,,Class Category Name,3,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +213,7,,Eccube\\Entity\\ClassCategory,backend_name,,Class Category Backend Name,4,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv \ No newline at end of file diff --git a/src/Eccube/Resource/doctrine/import_csv/en/mtb_csv_type.csv b/src/Eccube/Resource/doctrine/import_csv/en/mtb_csv_type.csv index 0c0117df7b9..5c38627e153 100644 --- a/src/Eccube/Resource/doctrine/import_csv/en/mtb_csv_type.csv +++ b/src/Eccube/Resource/doctrine/import_csv/en/mtb_csv_type.csv @@ -4,3 +4,5 @@ id,name,sort_no,discriminator_type 3,Order CSV,1,csvtype 4,Delivery CSV,1,csvtype 5,Category CSV,5,csvtype +6,Class NameCSV,6,csvtype +7,Class Category CSV,7,csvtype \ No newline at end of file diff --git a/src/Eccube/Resource/doctrine/import_csv/ja/dtb_csv.csv b/src/Eccube/Resource/doctrine/import_csv/ja/dtb_csv.csv index 70e71ecb45a..e6e878bcf95 100644 --- a/src/Eccube/Resource/doctrine/import_csv/ja/dtb_csv.csv +++ b/src/Eccube/Resource/doctrine/import_csv/ja/dtb_csv.csv @@ -203,3 +203,10 @@ "204","1",,"Eccube\\Entity\\ProductClass","TaxRule","tax_rate","税率","31","0","2017-03-07 10:14:00","2017-03-07 10:14:00","csv" "205","2",,"Eccube\\Entity\\Customer","point",,"ポイント","33","1","2017-03-07 10:14:00","2017-03-07 10:14:00","csv" "206","1",,"Eccube\\Entity\\ProductClass","visible",,"商品規格表示フラグ","32","0","2022-11-24 00:00:00","2022-11-24 00:00:00","csv" +"207","6",,"Eccube\\Entity\\ClassName","id",,"規格ID","1","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"208","6",,"Eccube\\Entity\\ClassName","name",,"規格名","2","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"209","6",,"Eccube\\Entity\\ClassName","backend_name",,"管理名","3","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"210","7",,"Eccube\\Entity\\ClassCategory","id",,"規格分類ID","1","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"211","7",,"Eccube\\Entity\\ClassCategory","ClassName","id","規格ID","2","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"212","7",,"Eccube\\Entity\\ClassCategory","name",,"規格分類名","3","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"213","7",,"Eccube\\Entity\\ClassCategory","backend_name",,"分類管理名","4","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" \ No newline at end of file diff --git a/src/Eccube/Resource/doctrine/import_csv/ja/mtb_csv_type.csv b/src/Eccube/Resource/doctrine/import_csv/ja/mtb_csv_type.csv index 4015fb15f06..a01c284ebd0 100644 --- a/src/Eccube/Resource/doctrine/import_csv/ja/mtb_csv_type.csv +++ b/src/Eccube/Resource/doctrine/import_csv/ja/mtb_csv_type.csv @@ -4,3 +4,5 @@ id,name,sort_no,discriminator_type "3","受注CSV","1","csvtype" "4","配送CSV","1","csvtype" "5","カテゴリCSV","5","csvtype" +"6","規格CSV","6","csvtype" +"7","規格分類CSV","7","csvtype" \ No newline at end of file diff --git a/src/Eccube/Resource/locale/messages.en.yaml b/src/Eccube/Resource/locale/messages.en.yaml index ecd21c78965..3814214df3c 100644 --- a/src/Eccube/Resource/locale/messages.en.yaml +++ b/src/Eccube/Resource/locale/messages.en.yaml @@ -606,6 +606,8 @@ admin.product.class_category_management: Option Groups admin.product.category_management: Categories admin.product.tag_management: Tags admin.product.product_csv_upload: Product CSV +admin.product.class_name_csv_upload: Class Name CSV +admin.product.class_category_csv_upload: Class Category CSV admin.product.category_csv_upload: Category CSV # flash messages @@ -776,6 +778,28 @@ admin.product.category_csv.parent_category_id_description: "" admin.product.category_csv.delete_flag_col: Category Deletion Flag admin.product.category_csv.delete_flag_description: "Specify 0: Upload or 1: Delete. If unspecified, it is set to 0." +# Class Name CSV Templates +admin.product.class_name_csv.class_name_id_col: Class Name ID +admin.product.class_name_csv.class_name_id_description: For a new class name registration, please leave it empty. To update the registered class name, please specify the class name ID. +admin.product.class_name_csv.class_name_col: Class Name +admin.product.class_name_csv.class_name_description: '' +admin.product.class_name_csv.class_backend_name_col: Backend Name +admin.product.class_name_csv.class_backend_name_description: '' +admin.product.class_name_csv.delete_flag_col: Class Name Deletion Flag +admin.product.class_name_csv.delete_flag_description: 'Specify 0: Upload or 1: Delete. If unspecified, it is set to 0.' + +# Class Category CSV Templates +admin.product.class_category_csv.class_name_id_col: Class Name ID +admin.product.class_category_csv.class_name_id_description: Specify an existing Class Name ID. +admin.product.class_category_csv.class_category_id_col: Class Category ID +admin.product.class_category_csv.class_category_id_description: For a new class category registration, please leave it empty. To update the registered class category, please specify the class category ID. +admin.product.class_category_csv.class_category_name_col: Class Category Name +admin.product.class_category_csv.class_category_name_description: '' +admin.product.class_category_csv.class_category_backend_name_col: Class Category Backend Name +admin.product.class_category_csv.class_category_backend_name_description: '' +admin.product.class_category_csv.delete_flag_col: Class Category Deletion Flag +admin.product.class_category_csv.delete_flag_description: 'Specify 0: Upload or 1: Delete. If unspecified, it is set to 0.' + # Product CSV admin.product.product_csv_upload__title: "Upload product CSV" admin.product.product_csv_upload__message: "Upload the product CSV file. Is it OK?" @@ -1743,6 +1767,8 @@ tooltip.setting.system.system.php_info: PHP details relevant to EC-CUBE. tooltip.store.template.template_code: This code will be used as the directory name where the template is saved. tooltip.store.template.template_name: Set the name of the template to be displayed in the Admin Console. tooltip.store.template.template_file: Upload an archive file that contains a set of templates. +tooltip.class_name.csv_upload: Standards can be registered in a batch using the specified type of CSV data. +tooltip.class_name.csv_format: You can easily create CSV data of the specified type by downloading and editing the template file. #==================================================================================== # Installation diff --git a/src/Eccube/Resource/locale/messages.ja.yaml b/src/Eccube/Resource/locale/messages.ja.yaml index f504a9c1365..dc25f2d14a5 100644 --- a/src/Eccube/Resource/locale/messages.ja.yaml +++ b/src/Eccube/Resource/locale/messages.ja.yaml @@ -606,6 +606,8 @@ admin.product.class_category_management: 規格分類管理 admin.product.category_management: カテゴリ管理 admin.product.tag_management: タグ管理 admin.product.product_csv_upload: 商品CSV登録 +admin.product.class_name_csv_upload: 規格CSV登録 +admin.product.class_category_csv_upload: 規格分類CSV登録 admin.product.category_csv_upload: カテゴリCSV登録 # flashメッセージ @@ -776,6 +778,28 @@ admin.product.category_csv.parent_category_id_description: "" admin.product.category_csv.delete_flag_col: カテゴリ削除フラグ admin.product.category_csv.delete_flag_description: 0:登録 1:削除を指定します。未指定の場合、0として扱います。 +# 規格CSV雛形 +admin.product.class_name_csv.class_name_id_col: 規格ID +admin.product.class_name_csv.class_name_id_description: 新規登録の場合は空にしてください。既存の規格を更新する場合は、規格IDを指定してください。 +admin.product.class_name_csv.class_name_col: 規格名 +admin.product.class_name_csv.class_name_description: '' +admin.product.class_name_csv.class_backend_name_col: 管理名 +admin.product.class_name_csv.class_backend_name_description: '' +admin.product.class_name_csv.delete_flag_col: 規格削除フラグ +admin.product.class_name_csv.delete_flag_description: 0:登録 1:削除を指定します。未指定の場合、0として扱います。 + +# 規格分類CSV雛形 +admin.product.class_category_csv.class_name_id_col: 規格ID +admin.product.class_category_csv.class_name_id_description: 既存の規格IDを指定してください。 +admin.product.class_category_csv.class_category_id_col: 規格分類ID +admin.product.class_category_csv.class_category_id_description: 新規登録の場合は空にしてください。既存の規格分類を更新する場合は、規格分類IDを指定してください。 +admin.product.class_category_csv.class_category_name_col: 規格分類名 +admin.product.class_category_csv.class_category_name_description: '' +admin.product.class_category_csv.class_category_backend_name_col: 規格分類管理名 +admin.product.class_category_csv.class_category_backend_name_description: '' +admin.product.class_category_csv.delete_flag_col: 規格分類削除フラグ +admin.product.class_category_csv.delete_flag_description: 0:登録 1:削除を指定します。未指定の場合、0として扱います。 + # 商品CSV admin.product.product_csv_upload__title: "商品CSVをアップロードします" admin.product.product_csv_upload__message: "商品CSVファイルをアップロードします。よろしいですか?" @@ -1744,6 +1768,8 @@ tooltip.setting.system.system.php_info: このEC-CUBEに関係しているPHPの tooltip.store.template.template_code: テンプレートの格納先のディレクトリ名になります。 tooltip.store.template.template_name: 管理画面で表示するテンプレートの名前を設定します。 tooltip.store.template.template_file: テンプレート一式となるアーカイブをアップロードします。 +tooltip.class_name.csv_upload: 所定の型のCSVデータを用いて規格を一括で登録することができます。 +tooltip.class_name.csv_format: 雛形ファイルをダウンロードして編集すれば、簡単に所定の型のCSVデータを作成できます。 #==================================================================================== # インストール画面 diff --git a/src/Eccube/Resource/template/admin/Product/class_category.twig b/src/Eccube/Resource/template/admin/Product/class_category.twig index 34ef394ad4a..a10e431562a 100644 --- a/src/Eccube/Resource/template/admin/Product/class_category.twig +++ b/src/Eccube/Resource/template/admin/Product/class_category.twig @@ -142,6 +142,24 @@ file that was distributed with this source code. +
+
+ +
+
{{ 'admin.product.class_category'|trans }}
diff --git a/src/Eccube/Resource/template/admin/Product/class_name.twig b/src/Eccube/Resource/template/admin/Product/class_name.twig index 1069892eaa4..9fc4dcedaf4 100644 --- a/src/Eccube/Resource/template/admin/Product/class_name.twig +++ b/src/Eccube/Resource/template/admin/Product/class_name.twig @@ -130,6 +130,24 @@ file that was distributed with this source code. {% endblock %} {% block main %} +
diff --git a/src/Eccube/Resource/template/admin/Product/csv_class_category.twig b/src/Eccube/Resource/template/admin/Product/csv_class_category.twig new file mode 100644 index 00000000000..02c9283486b --- /dev/null +++ b/src/Eccube/Resource/template/admin/Product/csv_class_category.twig @@ -0,0 +1,129 @@ +{# +This file is part of EC-CUBE + +Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. + +http://www.ec-cube.co.jp/ + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +#} +{% extends '@admin/default_frame.twig' %} + +{% set menus = ['product', 'class_category_csv_import'] %} + +{% block title %}{{ 'admin.product.class_category_csv_upload'|trans }}{% endblock %} +{% block sub_title %}{{ 'admin.product.product_management'|trans }}{% endblock %} + +{% form_theme form '@admin/Form/bootstrap_4_horizontal_layout.html.twig' %} + +{% block javascript %} + + +{% endblock javascript %} +{% block main %} +
+
+
+
+
+
{{ 'admin.common.csv_upload'|trans }}
+
+
+
+
{{ 'admin.common.csv_select'|trans }}
+
+
+ {{ form_widget(form._token) }} +
+ {{ 'admin.common.file_select'|trans }} + {{ 'admin.common.file_select_empty'|trans }} + {{ form_widget(form.import_file, {'attr': {'accept': 'text/csv,text/tsv', 'class': 'd-none'}}) }} + {{ form_errors(form.import_file) }} +
+ + {% for error in errors %} +
{{ error }}
+ {% endfor %} +
+
+
+
+
+
+
+
+
+
+
{{ 'admin.common.csv_format'|trans }}
+
+ +
+
+
+ + + {% for header, key in headers %} + + + + + {% endfor %} + +
{{ header }} + {% if key.required %} + {{ 'admin.common.required'|trans }} + {% endif %} + + {% if key.description %} + {{ key.description|trans|raw }} + {% endif %} +
+
+
+
+
+
+{% endblock %} diff --git a/src/Eccube/Resource/template/admin/Product/csv_class_name.twig b/src/Eccube/Resource/template/admin/Product/csv_class_name.twig new file mode 100644 index 00000000000..3b72d0b43b9 --- /dev/null +++ b/src/Eccube/Resource/template/admin/Product/csv_class_name.twig @@ -0,0 +1,129 @@ +{# +This file is part of EC-CUBE + +Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. + +http://www.ec-cube.co.jp/ + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +#} +{% extends '@admin/default_frame.twig' %} + +{% set menus = ['product', 'class_name_csv_import'] %} + +{% block title %}{{ 'admin.product.class_name_csv_upload'|trans }}{% endblock %} +{% block sub_title %}{{ 'admin.product.product_management'|trans }}{% endblock %} + +{% form_theme form '@admin/Form/bootstrap_4_horizontal_layout.html.twig' %} + +{% block javascript %} + + +{% endblock javascript %} +{% block main %} +
+
+
+
+
+
{{ 'admin.common.csv_upload'|trans }}
+
+
+
+
{{ 'admin.common.csv_select'|trans }}
+
+
+ {{ form_widget(form._token) }} +
+ {{ 'admin.common.file_select'|trans }} + {{ 'admin.common.file_select_empty'|trans }} + {{ form_widget(form.import_file, {'attr': {'accept': 'text/csv,text/tsv', 'class': 'd-none'}}) }} + {{ form_errors(form.import_file) }} +
+ + {% for error in errors %} +
{{ error }}
+ {% endfor %} +
+
+
+
+
+
+
+
+
+
+
{{ 'admin.common.csv_format'|trans }}
+
+ +
+
+
+ + + {% for header, key in headers %} + + + + + {% endfor %} + +
{{ header }} + {% if key.required %} + {{ 'admin.common.required'|trans }} + {% endif %} + + {% if key.description %} + {{ key.description|trans|raw }} + {% endif %} +
+
+
+
+
+
+{% endblock %}