src/Eccube/Resource/template/admin/Product/csv_product.twig line 1

Open in your IDE?
  1. {#
  2. This file is part of EC-CUBE
  3. Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  4. http://www.ec-cube.co.jp/
  5. For the full copyright and license information, please view the LICENSE
  6. file that was distributed with this source code.
  7. #}
  8. {% extends '@admin/default_frame.twig' %}
  9. {% set menus = ['product', 'product_csv_import'] %}
  10. {% block title %}{{ 'admin.product.product_csv_upload'|trans }}{% endblock %}
  11. {% block sub_title %}{{ 'admin.product.product_management'|trans }}{% endblock %}
  12. {% form_theme form '@admin/Form/bootstrap_4_horizontal_layout.html.twig' %}
  13. {% block javascript %}
  14.     <script>
  15.         $(function() {
  16.             $('#importCsv').on('click', function() {
  17.                 var setupModal = function (modal) {
  18.                     modal.find('button').attr('disabled', 'disabled');
  19.                     $('.modal-body p', modal).text("{{ 'admin.common.csv_upload_in_progress'|trans }}");
  20.                     $('.progress', modal).show();
  21.                     return (new $.Deferred).resolve().promise();
  22.                 }
  23.                 var addError = function(message) {
  24.                     $('<li><span class="badge bg-danger">ERROR</span> </li>')
  25.                         .append($('<span></span>').text(message))
  26.                         .prependTo('#bulkMessages');
  27.                     $('#bulkMessages li:nth-child(n+2)').hide()
  28.                 };
  29.                 var addSuccess = function(message) {
  30.                     $('<li><span class="badge bg-success">SUCCESS</span> </li>')
  31.                         .append($('<span></span>').text(message))
  32.                         .prependTo('#bulkMessages');
  33.                     $('#bulkMessages li:nth-child(n+2)').hide()
  34.                 };
  35.                 var split = function(formData) {
  36.                     return function() {
  37.                         var d = new $.Deferred();
  38.                         $.ajax({
  39.                             url: '{{ url('admin_product_csv_split') }}',
  40.                             type: 'POST',
  41.                             data: formData,
  42.                             processData: false,
  43.                             contentType: false,
  44.                             cache: false,
  45.                         })
  46.                         .then(function(data) {
  47.                             if (data.success) {
  48.                                 d.resolve(data)
  49.                             } else {
  50.                                 data.message.forEach(function(error) {
  51.                                     addError(error.message)
  52.                                 })
  53.                                 d.reject(data)
  54.                             }
  55.                         })
  56.                         .catch(function() {
  57.                             d.reject()
  58.                         })
  59.                         return d.promise();
  60.                     }
  61.                 }
  62.                 var upload = function(file_name, current, total) {
  63.                     return function() {
  64.                         var d = new $.Deferred();
  65.                         $.ajax({
  66.                             url: '{{ url('admin_product_csv_split_import') }}',
  67.                             type: 'POST',
  68.                             data: {
  69.                                 file_name: file_name + current + '.csv',
  70.                                 file_no: current
  71.                             },
  72.                         })
  73.                         .then(function(data) {
  74.                             if (data.success) {
  75.                                 addSuccess(data.success_message)
  76.                                 $('.progress-bar', modal).css('width', (current / total * 100) + '%');
  77.                                 d.resolve(data)
  78.                             } else {
  79.                                 $('.modal-body p', modal)
  80.                                     .text(data.error_message)
  81.                                 data.errors.forEach(function (error) {
  82.                                     addError(error)
  83.                                 });
  84.                                 $('.progress-bar', modal)
  85.                                     .clone()
  86.                                     .addClass('bg-danger')
  87.                                     .css('width', 100 - ((current - 1) / total * 100) + '%')
  88.                                     .appendTo('.progress', modal)
  89.                                 $('.progress-bar', modal).addClass('bg-success')
  90.                                 // エラー発生以降の分割ファイルをクリア
  91.                                 var files = []
  92.                                 for (var i = current + 1; i <= total; i++) {
  93.                                     files.push(file_name + i + '.csv')
  94.                                 }
  95.                                 if (files.length > 0) {
  96.                                     $.post('{{ url('admin_product_csv_split_cleanup') }}', { files: files })
  97.                                 }
  98.                                 d.reject(data);
  99.                             }
  100.                         }, function(data) {
  101.                             d.reject(data)
  102.                         })
  103.                         return d.promise()
  104.                     }
  105.                 }
  106.                 var modal = $('#importCsvModal')
  107.                 var formData = new FormData($('#upload-form').get(0))
  108.                 setupModal(modal)
  109.                     // CSV分割
  110.                     .then(split(formData))
  111.                     .catch(function() {
  112.                         $('.modal-body p', modal).text("{{ 'admin.common.csv_upload_error'|trans }}")
  113.                         $('.progress-bar', modal).css('width', '100%')
  114.                         $('.progress-bar', modal).addClass('bg-danger')
  115.                         return $.Deferred().reject();
  116.                     })
  117.                     // 分割したCSVを登録
  118.                     .then(function(data) {
  119.                         var d = $.Deferred().resolve();
  120.                         for (var i = 1; i <= data.max_file_no; i++) {
  121.                             d = d.then(upload(data.file_name, i, data.max_file_no))
  122.                         }
  123.                         return d.promise()
  124.                     })
  125.                     // 完了メッセージ
  126.                     .then(function() {
  127.                         $('.modal-body p', modal).text("{{ 'admin.common.csv_upload_complete'|trans }}")
  128.                         $('.progress-bar', modal).addClass('bg-success');
  129.                     })
  130.                     // モーダルのロック解除
  131.                     .always(function() {
  132.                         $('.progress-bar', modal).removeClass('progress-bar-animated')
  133.                         // メッセージ行が複数ある場合に詳細表示
  134.                         if ($('#bulkMessages li').length > 1) {
  135.                             $('#toggleMessages').show()
  136.                         }
  137.                         modal.find('button').removeAttr('disabled').toggle()
  138.                     })
  139.             })
  140.             $('#toggleMessages').on('click', function() {
  141.                 var display = $('#bulkMessages li:last').css('display')
  142.                 if (display == 'none') {
  143.                     $('#bulkMessages li').show();
  144.                     $('#toggleMessages span').text("{{ 'admin.common.close_detail'|trans }}")
  145.                     $('#toggleMessages i').removeClass('fa-plus-square-o')
  146.                     $('#toggleMessages i').addClass('fa-minus-square-o')
  147.                 } else {
  148.                     $('#bulkMessages li:nth-child(n+2)').hide()
  149.                     $('#toggleMessages span').text("{{ 'admin.common.open_detail'|trans }}")
  150.                     $('#toggleMessages i').removeClass('fa-minus-square-o')
  151.                     $('#toggleMessages i').addClass('fa-plus-square-o')
  152.                 }
  153.             })
  154.             $('#importCsvDone').on('click', function() {
  155.                 location.reload(true);
  156.             });
  157.             $('#file-select').click(function() {
  158.                 $('#admin_csv_import_import_file').click();
  159.                 $('#admin_csv_import_import_file').on('change', function() {
  160.                     var files = $(this).prop('files');
  161.                     if (files.length) {
  162.                         $('#admin_csv_import_import_file_name').text(files[0].name);
  163.                         $('#upload-button').prop('disabled', false);
  164.                     }
  165.                 });
  166.             });
  167.         });
  168.     </script>
  169. {% endblock javascript %}
  170. {% block main %}
  171.     <div class="c-contentsArea__cols">
  172.         <div class="c-contentsArea__primaryCol">
  173.             <div class="c-primaryCol">
  174.                 <div class="card rounded border-0 mb-4">
  175.                     <div class="card-header">
  176.                         <div class="d-inline-block" data-bs-toggle="tooltip" data-bs-placement="top" title="{{ 'tooltip.product.csv_upload'|trans }}"><span>{{ 'admin.common.csv_upload'|trans }}</span><i class="fa fa-question-circle fa-lg fa-lg ms-1"></i></div>
  177.                     </div>
  178.                     <div id="ex-csv_product-upload" class="card-body">
  179.                         <div class="row">
  180.                             <div class="col-2"><span>{{ 'admin.common.csv_select'|trans }}</span></div>
  181.                             <div class="col">
  182.                                 <form id="upload-form" method="post" action="{{ url('admin_product_csv_split') }}" enctype="multipart/form-data">
  183.                                     {{ form_widget(form._token) }}
  184.                                     <div class="mb-2">
  185.                                         <span id="file-select" class="btn btn-ec-regular me-2">{{ 'admin.common.file_select'|trans }}</span>
  186.                                         <span id="admin_csv_import_import_file_name">{{ 'admin.common.file_select_empty'|trans }}</span>
  187.                                         {{ form_widget(form.import_file, {'attr': {'accept': 'text/csv,text/tsv', 'class': 'd-none'}}) }}
  188.                                         {{ form_errors(form.import_file) }}
  189.                                     </div>
  190.                                     <button class="btn btn-ec-conversion" id="upload-button" type="button" data-bs-toggle="modal" data-bs-target="#importCsvModal" disabled>{{ 'admin.common.bulk_registration'|trans }}</button>
  191.                                     {% for error in errors %}
  192.                                         <div class="text-danger">{{ error }}</div>
  193.                                     {% endfor %}
  194.                                 </form>
  195.                             </div>
  196.                         </div>
  197.                     </div>
  198.                 </div>
  199.                 <div class="card rounded border-0 mb-4">
  200.                     <div class="card-header">
  201.                         <div class="row justify-content-between">
  202.                             <div class="col-6">
  203.                                 <div class="d-inline-block" data-bs-toggle="tooltip" data-bs-placement="top" title="{{ 'tooltip.product.csv_format'|trans }}"><span class="align-middle">{{ 'admin.common.csv_format'|trans }}</span><i class="fa fa-question-circle fa-lg fa-lg ms-1"></i></div>
  204.                             </div>
  205.                             <div class="col-4 text-end">
  206.                                 <a href="{{ url('admin_product_csv_template', {'type': 'product'}) }}" class="btn btn-ec-regular" id="download-button">{{ 'admin.common.csv_skeleton_download'|trans }}</a>
  207.                             </div>
  208.                         </div>
  209.                     </div>
  210.                     <div id="ex-csv_product-format" class="card-body">
  211.                         <table class="table table-striped table-bordered">
  212.                             <tbody>
  213.                             {% for header, key in headers %}
  214.                                 <tr>
  215.                                     <th class="w-25 align-middle table-ec-lightGray" id="file_format_box__header--{{ loop.index }}">{{ header }}
  216.                                         {% if key.required %}
  217.                                             <span class="badge bg-primary ms-1">{{ 'admin.common.required'|trans }}</span>
  218.                                         {% endif %}
  219.                                     </th>
  220.                                     <td class="align-middle">
  221.                                         {% if key.description %}
  222.                                             {{ key.description|trans }}
  223.                                         {% endif %}
  224.                                     </td>
  225.                                 </tr>
  226.                             {% endfor %}
  227.                             </tbody>
  228.                         </table>
  229.                     </div>
  230.                 </div>
  231.             </div>
  232.         </div>
  233.     </div>
  234.     <div class="modal fade" id="importCsvModal" tabindex="-1" role="dialog" aria-labelledby="importCsvModal" aria-hidden="true" data-bs-keyboard="false" data-bs-backdrop="static">
  235.         <div class="modal-dialog" role="document">
  236.             <div class="modal-content">
  237.                 <div class="modal-header">
  238.                     <h5 class="modal-title fw-bold">{{ 'admin.product.product_csv_upload__title'|trans }}</h5>
  239.                     <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button>
  240.                 </div>
  241.                 <div class="modal-body text-start">
  242.                     <span class="badge"></span>
  243.                     <p class="text-start">{{ 'admin.product.product_csv_upload__message'|trans }}</p>
  244.                     <div class="progress mb-1" style="display: none">
  245.                         <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
  246.                     </div>
  247.                     <ul id="bulkMessages"></ul>
  248.                     <div id="toggleMessages" style="display: none;">
  249.                         <i class="fa fw-bold me-1 fa-plus-square-o"></i><span>{{ 'admin.common.open_detail'|trans }}</span>
  250.                     </div>
  251.                 </div>
  252.                 <div class="modal-footer">
  253.                     <button class="btn btn-ec-sub" type="button" data-bs-dismiss="modal">{{ 'admin.common.cancel'|trans }}</button>
  254.                     <button class="btn btn-ec-conversion" type="button" id="importCsv">{{ 'admin.common.bulk_registration' | trans }}</button>
  255.                     <button class="btn btn-ec-regular" id="importCsvDone" style="display: none" type="button" data-bs-dismiss="modal">{{ 'admin.common.close'|trans }}</button>
  256.                 </div>
  257.             </div>
  258.         </div>
  259.     </div>
  260. {% endblock %}