From d75fe7d74067f840f0df50d1a17fdbeb4ec8595c Mon Sep 17 00:00:00 2001 From: "kenshiro.sawamura" Date: Tue, 18 May 2021 10:55:52 +0900 Subject: [PATCH 1/6] =?UTF-8?q?=E8=A6=8F=E6=A0=BC=E3=83=BB=E8=A6=8F?= =?UTF-8?q?=E6=A0=BC=E5=88=86=E9=A1=9E=EF=BC=9A=E3=80=8CCSV=E7=99=BB?= =?UTF-8?q?=E9=8C=B2=E3=80=8D=E4=BD=9C=E6=88=90,=20=E3=80=8CCSV=E3=83=80?= =?UTF-8?q?=E3=82=A6=E3=83=B3=E3=83=AD=E3=83=BC=E3=83=89=E3=83=BBCSV?= =?UTF-8?q?=E5=87=BA=E5=8A=9B=E9=A0=85=E7=9B=AE=E8=A8=AD=E5=AE=9A=E3=80=8D?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Admin/Product/ClassCategoryController.php | 86 ++++- .../Admin/Product/ClassNameController.php | 89 ++++- .../Admin/Product/CsvImportController.php | 344 ++++++++++++++++++ src/Eccube/Entity/Master/CsvType.php | 11 + src/Eccube/Event/EccubeEvents.php | 6 + .../doctrine/import_csv/en/dtb_csv.csv | 7 + .../doctrine/import_csv/en/mtb_csv_type.csv | 2 + .../doctrine/import_csv/ja/dtb_csv.csv | 7 + .../doctrine/import_csv/ja/mtb_csv_type.csv | 2 + src/Eccube/Resource/locale/messages.en.yaml | 26 ++ src/Eccube/Resource/locale/messages.ja.yaml | 26 ++ .../admin/Product/class_category.twig | 18 + .../template/admin/Product/class_name.twig | 18 + .../admin/Product/csv_class_category.twig | 129 +++++++ .../admin/Product/csv_class_name.twig | 129 +++++++ 15 files changed, 897 insertions(+), 3 deletions(-) create mode 100644 src/Eccube/Resource/template/admin/Product/csv_class_category.twig create mode 100644 src/Eccube/Resource/template/admin/Product/csv_class_name.twig diff --git a/src/Eccube/Controller/Admin/Product/ClassCategoryController.php b/src/Eccube/Controller/Admin/Product/ClassCategoryController.php index c34974fd9d1..fc4824e7906 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 f4a57248abf..440f92ae85c 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 24c6b387c14..5551965f73c 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; @@ -79,6 +82,11 @@ class CsvImportController extends AbstractCsvImportController */ protected $classCategoryRepository; + /** + * @var ClassNameRepository + */ + protected $classNameRepository; + /** * @var ProductImageRepository */ @@ -124,6 +132,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 @@ -139,6 +148,7 @@ public function __construct( SaleTypeRepository $saleTypeRepository, TagRepository $tagRepository, CategoryRepository $categoryRepository, + ClassNameRepository $classNameRepository, ClassCategoryRepository $classCategoryRepository, ProductImageRepository $productImageRepository, ProductStatusRepository $productStatusRepository, @@ -151,6 +161,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; @@ -841,6 +852,270 @@ 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::isBlank($row[$headerByKey['backend_name']])) { + $this->addErrors(($data->key() + 1).'行目規格名が設定されていません。'); + + return $this->renderWithError($form, $headers); + } else { + $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アップロード + * + * @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::isBlank($row[$headerByKey['backend_name']])) { + $this->addErrors(($data->key() + 1).'行目規格分類管理名が設定されていません。'); + + return $this->renderWithError($form, $headers); + } else { + $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雛形ファイルダウンロード * @@ -858,6 +1133,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(); } @@ -1586,6 +1867,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 07123a77f79..dc04cc48258 100644 --- a/src/Eccube/Entity/Master/CsvType.php +++ b/src/Eccube/Entity/Master/CsvType.php @@ -52,5 +52,16 @@ class CsvType extends \Eccube\Entity\Master\AbstractMasterEntity * @var integer */ const CSV_TYPE_CATEGORY = 5; + + /** + * @var integer + */ + const CSV_TYPE_CLASS_NAME = 6; + + /** + * @var integer + */ + const CSV_TYPE_CLASS_CATEGORY = 7; + } } diff --git a/src/Eccube/Event/EccubeEvents.php b/src/Eccube/Event/EccubeEvents.php index 7b33dbf6a1b..d7b017807ea 100644 --- a/src/Eccube/Event/EccubeEvents.php +++ b/src/Eccube/Event/EccubeEvents.php @@ -214,6 +214,9 @@ final class EccubeEvents // delete 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 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 f10f2022d58..8ac3cd72929 100644 --- a/src/Eccube/Resource/doctrine/import_csv/en/dtb_csv.csv +++ b/src/Eccube/Resource/doctrine/import_csv/en/dtb_csv.csv @@ -202,3 +202,10 @@ id,csv_type_id,creator_id,entity_name,field_name,reference_field_name,disp_name, 203,5,,Eccube\\Entity\\Category,level,,Level,5,1,2017-03-07 10:14:00,2017-03-07 10:14:00,csv 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,6,,Eccube\\Entity\\ClassName,id,,Class Name ID,1,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +207,6,,Eccube\\Entity\\ClassName,name,,Class Name,2,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +208,6,,Eccube\\Entity\\ClassName,backend_name,,Backend Name,3,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +209,7,,Eccube\\Entity\\ClassCategory,id,,Class Category ID,1,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +210,7,,Eccube\\Entity\\ClassCategory,ClassName,id,Class NameID,2,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +211,7,,Eccube\\Entity\\ClassCategory,name,,Class Category Name,3,1,2021-05-18 01:26:41,2021-05-18 01:26:41,csv +212,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 e11c0b97144..6d3d0f6ab7c 100644 --- a/src/Eccube/Resource/doctrine/import_csv/ja/dtb_csv.csv +++ b/src/Eccube/Resource/doctrine/import_csv/ja/dtb_csv.csv @@ -202,3 +202,10 @@ "203","5",,"Eccube\\Entity\\Category","level",,"階層","5","1","2017-03-07 10:14:00","2017-03-07 10:14:00","csv" "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","6",,"Eccube\\Entity\\ClassName","id",,"規格ID","1","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"207","6",,"Eccube\\Entity\\ClassName","name",,"規格名","2","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"208","6",,"Eccube\\Entity\\ClassName","backend_name",,"管理名","3","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"209","7",,"Eccube\\Entity\\ClassCategory","id",,"規格分類ID","1","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"210","7",,"Eccube\\Entity\\ClassCategory","ClassName","id","規格ID","2","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"211","7",,"Eccube\\Entity\\ClassCategory","name",,"規格分類名","3","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" +"212","7",,"Eccube\\Entity\\ClassCategory","backend_name",,"分類管理名","4","1","2021-05-18 01:26:41","2021-05-18 01:26:41","csv" 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 98b8153f751..c901e7ccde8 100644 --- a/src/Eccube/Resource/locale/messages.en.yaml +++ b/src/Eccube/Resource/locale/messages.en.yaml @@ -596,6 +596,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 @@ -764,6 +766,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?' @@ -1698,6 +1722,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 c3af4452846..d4ac9b9bdf4 100644 --- a/src/Eccube/Resource/locale/messages.ja.yaml +++ b/src/Eccube/Resource/locale/messages.ja.yaml @@ -596,6 +596,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メッセージ @@ -764,6 +766,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ファイルをアップロードします。よろしいですか?' @@ -1698,6 +1722,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 644933b60ec..82ddc3fe50e 100644 --- a/src/Eccube/Resource/template/admin/Product/class_category.twig +++ b/src/Eccube/Resource/template/admin/Product/class_category.twig @@ -152,6 +152,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 d0a20064ad7..12eeb5c2f93 100644 --- a/src/Eccube/Resource/template/admin/Product/class_name.twig +++ b/src/Eccube/Resource/template/admin/Product/class_name.twig @@ -140,6 +140,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..581950ac9a5 --- /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..a095483ce46 --- /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 %} From 1b463dae878c0021adf9f7544163547d9693aa7b Mon Sep 17 00:00:00 2001 From: "kenshiro.sawamura" Date: Mon, 24 May 2021 09:52:50 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=94=BB=E9=9D=A2?= =?UTF-8?q?=EF=BC=9A=E8=A6=8F=E6=A0=BC=E3=83=BB=E8=A6=8F=E6=A0=BC=E5=88=86?= =?UTF-8?q?=E9=A1=9E=E3=80=8CCSV=E7=99=BB=E9=8C=B2=E3=80=8D=E3=83=A1?= =?UTF-8?q?=E3=83=8B=E3=83=A5=E3=83=BC=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/config/eccube/packages/eccube_nav.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/config/eccube/packages/eccube_nav.yaml b/app/config/eccube/packages/eccube_nav.yaml index 2f88c1e1582..8d9dde1cc0c 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 From 67f8d846b5417b0c2d1fcda9ca9e8c400f44c58b Mon Sep 17 00:00:00 2001 From: carkn Date: Fri, 10 Jun 2022 16:02:58 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=E3=83=9E=E3=82=A4=E3=82=B0=E3=83=AC?= =?UTF-8?q?=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Version20220603074035.php | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 app/DoctrineMigrations/Version20220603074035.php 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 + + } +} From 05368323bd77823737a869a7ff9e9dc0715e65c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=A0=20=E6=81=A9=E6=A8=B9?= Date: Mon, 8 Apr 2024 11:35:23 +0900 Subject: [PATCH 4/6] =?UTF-8?q?=E5=BF=85=E9=A0=88=E3=83=90=E3=83=83?= =?UTF-8?q?=E3=83=81=E3=81=AECSS=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Resource/template/admin/Product/csv_class_category.twig | 2 +- src/Eccube/Resource/template/admin/Product/csv_class_name.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Eccube/Resource/template/admin/Product/csv_class_category.twig b/src/Eccube/Resource/template/admin/Product/csv_class_category.twig index 581950ac9a5..02c9283486b 100644 --- a/src/Eccube/Resource/template/admin/Product/csv_class_category.twig +++ b/src/Eccube/Resource/template/admin/Product/csv_class_category.twig @@ -109,7 +109,7 @@ file that was distributed with this source code. {{ header }} {% if key.required %} - {{ 'admin.common.required'|trans }} + {{ 'admin.common.required'|trans }} {% endif %} diff --git a/src/Eccube/Resource/template/admin/Product/csv_class_name.twig b/src/Eccube/Resource/template/admin/Product/csv_class_name.twig index a095483ce46..3b72d0b43b9 100644 --- a/src/Eccube/Resource/template/admin/Product/csv_class_name.twig +++ b/src/Eccube/Resource/template/admin/Product/csv_class_name.twig @@ -109,7 +109,7 @@ file that was distributed with this source code. {{ header }} {% if key.required %} - {{ 'admin.common.required'|trans }} + {{ 'admin.common.required'|trans }} {% endif %} From ded53feff2da295b43fb764c536dfe8a96af3558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=A0=20=E6=81=A9=E6=A8=B9?= Date: Wed, 10 Apr 2024 09:06:28 +0900 Subject: [PATCH 5/6] =?UTF-8?q?CSV=E3=83=86=E3=82=B9=E3=83=88=E3=82=B1?= =?UTF-8?q?=E3=83=BC=E3=82=B9=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codeception/_data/class_category.csv | 4 + codeception/_data/class_name.csv | 4 + .../Page/Admin/ClassCategoryCsvUploadPage.php | 55 ++++++++++++ .../Page/Admin/ClassCategoryManagePage.php | 17 ++++ .../Page/Admin/ClassNameCsvUploadPage.php | 55 ++++++++++++ .../Page/Admin/ClassNameManagePage.php | 24 +++++ codeception/acceptance/EA03ProductCest.php | 88 +++++++++++++++++++ .../Admin/Product/CsvImportController.php | 16 +--- 8 files changed, 251 insertions(+), 12 deletions(-) create mode 100644 codeception/_data/class_category.csv create mode 100644 codeception/_data/class_name.csv create mode 100644 codeception/_support/Page/Admin/ClassCategoryCsvUploadPage.php create mode 100644 codeception/_support/Page/Admin/ClassNameCsvUploadPage.php 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/CsvImportController.php b/src/Eccube/Controller/Admin/Product/CsvImportController.php index 8a07682a812..6892a7e85e7 100644 --- a/src/Eccube/Controller/Admin/Product/CsvImportController.php +++ b/src/Eccube/Controller/Admin/Product/CsvImportController.php @@ -949,11 +949,7 @@ public function csvClassName(Request $request, CacheUtil $cacheUtil) $ClassName->setName(StringUtil::trimAll($row[$headerByKey['name']])); } - if (!isset($row[$headerByKey['backend_name']]) || StringUtil::isBlank($row[$headerByKey['backend_name']])) { - $this->addErrors(($data->key() + 1).'行目規格名が設定されていません。'); - - return $this->renderWithError($form, $headers); - } else { + if (isset($row[$headerByKey['backend_name']]) && StringUtil::isNotBlank($row[$headerByKey['backend_name']])) { $ClassName->setBackendName(StringUtil::trimAll($row[$headerByKey['backend_name']])); } @@ -979,7 +975,7 @@ public function csvClassName(Request $request, CacheUtil $cacheUtil) /** - * カテゴリ登録CSVアップロード + * 規格分類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") @@ -1089,12 +1085,8 @@ public function csvClassCategory(Request $request, CacheUtil $cacheUtil) $ClassCategory->setName(StringUtil::trimAll($row[$headerByKey['name']])); } - if (!isset($row[$headerByKey['backend_name']]) || StringUtil::isBlank($row[$headerByKey['backend_name']])) { - $this->addErrors(($data->key() + 1).'行目規格分類管理名が設定されていません。'); - - return $this->renderWithError($form, $headers); - } else { - $ClassCategory->setBackendName(StringUtil::trimAll($row[$headerByKey['backend_name']])); + if (isset($row[$headerByKey['backend_name']]) && StringUtil::isNotBlank($row[$headerByKey['backend_name']])) { + $ClassName->setBackendName(StringUtil::trimAll($row[$headerByKey['backend_name']])); } if ($this->hasErrors()) { From 15c7561e15406ffd09099849611f632e1230efc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=A0=20=E6=81=A9=E6=A8=B9?= Date: Wed, 10 Apr 2024 09:22:17 +0900 Subject: [PATCH 6/6] =?UTF-8?q?ClassName=E3=81=AE=E5=AE=9A=E7=BE=A9?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Eccube/Controller/Admin/Product/CsvImportController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Eccube/Controller/Admin/Product/CsvImportController.php b/src/Eccube/Controller/Admin/Product/CsvImportController.php index 6892a7e85e7..c5bbd06caf6 100644 --- a/src/Eccube/Controller/Admin/Product/CsvImportController.php +++ b/src/Eccube/Controller/Admin/Product/CsvImportController.php @@ -1086,7 +1086,7 @@ public function csvClassCategory(Request $request, CacheUtil $cacheUtil) } if (isset($row[$headerByKey['backend_name']]) && StringUtil::isNotBlank($row[$headerByKey['backend_name']])) { - $ClassName->setBackendName(StringUtil::trimAll($row[$headerByKey['backend_name']])); + $ClassCategory->setBackendName(StringUtil::trimAll($row[$headerByKey['backend_name']])); } if ($this->hasErrors()) {