{#
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', 'product_csv_import'] %}
{% block title %}{{ 'admin.product.product_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 %}
<script>
$(function() {
$('#importCsv').on('click', function() {
var setupModal = function (modal) {
modal.find('button').attr('disabled', 'disabled');
$('.modal-body p', modal).text("{{ 'admin.common.csv_upload_in_progress'|trans }}");
$('.progress', modal).show();
return (new $.Deferred).resolve().promise();
}
var addError = function(message) {
$('<li><span class="badge bg-danger">ERROR</span> </li>')
.append($('<span></span>').text(message))
.prependTo('#bulkMessages');
$('#bulkMessages li:nth-child(n+2)').hide()
};
var addSuccess = function(message) {
$('<li><span class="badge bg-success">SUCCESS</span> </li>')
.append($('<span></span>').text(message))
.prependTo('#bulkMessages');
$('#bulkMessages li:nth-child(n+2)').hide()
};
var split = function(formData) {
return function() {
var d = new $.Deferred();
$.ajax({
url: '{{ url('admin_product_csv_split') }}',
type: 'POST',
data: formData,
processData: false,
contentType: false,
cache: false,
})
.then(function(data) {
if (data.success) {
d.resolve(data)
} else {
data.message.forEach(function(error) {
addError(error.message)
})
d.reject(data)
}
})
.catch(function() {
d.reject()
})
return d.promise();
}
}
var upload = function(file_name, current, total) {
return function() {
var d = new $.Deferred();
$.ajax({
url: '{{ url('admin_product_csv_split_import') }}',
type: 'POST',
data: {
file_name: file_name + current + '.csv',
file_no: current
},
})
.then(function(data) {
if (data.success) {
addSuccess(data.success_message)
$('.progress-bar', modal).css('width', (current / total * 100) + '%');
d.resolve(data)
} else {
$('.modal-body p', modal)
.text(data.error_message)
data.errors.forEach(function (error) {
addError(error)
});
$('.progress-bar', modal)
.clone()
.addClass('bg-danger')
.css('width', 100 - ((current - 1) / total * 100) + '%')
.appendTo('.progress', modal)
$('.progress-bar', modal).addClass('bg-success')
// エラー発生以降の分割ファイルをクリア
var files = []
for (var i = current + 1; i <= total; i++) {
files.push(file_name + i + '.csv')
}
if (files.length > 0) {
$.post('{{ url('admin_product_csv_split_cleanup') }}', { files: files })
}
d.reject(data);
}
}, function(data) {
d.reject(data)
})
return d.promise()
}
}
var modal = $('#importCsvModal')
var formData = new FormData($('#upload-form').get(0))
setupModal(modal)
// CSV分割
.then(split(formData))
.catch(function() {
$('.modal-body p', modal).text("{{ 'admin.common.csv_upload_error'|trans }}")
$('.progress-bar', modal).css('width', '100%')
$('.progress-bar', modal).addClass('bg-danger')
return $.Deferred().reject();
})
// 分割したCSVを登録
.then(function(data) {
var d = $.Deferred().resolve();
for (var i = 1; i <= data.max_file_no; i++) {
d = d.then(upload(data.file_name, i, data.max_file_no))
}
return d.promise()
})
// 完了メッセージ
.then(function() {
$('.modal-body p', modal).text("{{ 'admin.common.csv_upload_complete'|trans }}")
$('.progress-bar', modal).addClass('bg-success');
})
// モーダルのロック解除
.always(function() {
$('.progress-bar', modal).removeClass('progress-bar-animated')
// メッセージ行が複数ある場合に詳細表示
if ($('#bulkMessages li').length > 1) {
$('#toggleMessages').show()
}
modal.find('button').removeAttr('disabled').toggle()
})
})
$('#toggleMessages').on('click', function() {
var display = $('#bulkMessages li:last').css('display')
if (display == 'none') {
$('#bulkMessages li').show();
$('#toggleMessages span').text("{{ 'admin.common.close_detail'|trans }}")
$('#toggleMessages i').removeClass('fa-plus-square-o')
$('#toggleMessages i').addClass('fa-minus-square-o')
} else {
$('#bulkMessages li:nth-child(n+2)').hide()
$('#toggleMessages span').text("{{ 'admin.common.open_detail'|trans }}")
$('#toggleMessages i').removeClass('fa-minus-square-o')
$('#toggleMessages i').addClass('fa-plus-square-o')
}
})
$('#importCsvDone').on('click', function() {
location.reload(true);
});
$('#file-select').click(function() {
$('#admin_csv_import_import_file').click();
$('#admin_csv_import_import_file').on('change', function() {
var files = $(this).prop('files');
if (files.length) {
$('#admin_csv_import_import_file_name').text(files[0].name);
$('#upload-button').prop('disabled', false);
}
});
});
});
</script>
{% endblock javascript %}
{% block main %}
<div class="c-contentsArea__cols">
<div class="c-contentsArea__primaryCol">
<div class="c-primaryCol">
<div class="card rounded border-0 mb-4">
<div class="card-header">
<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>
</div>
<div id="ex-csv_product-upload" class="card-body">
<div class="row">
<div class="col-2"><span>{{ 'admin.common.csv_select'|trans }}</span></div>
<div class="col">
<form id="upload-form" method="post" action="{{ url('admin_product_csv_split') }}" enctype="multipart/form-data">
{{ form_widget(form._token) }}
<div class="mb-2">
<span id="file-select" class="btn btn-ec-regular me-2">{{ 'admin.common.file_select'|trans }}</span>
<span id="admin_csv_import_import_file_name">{{ 'admin.common.file_select_empty'|trans }}</span>
{{ form_widget(form.import_file, {'attr': {'accept': 'text/csv,text/tsv', 'class': 'd-none'}}) }}
{{ form_errors(form.import_file) }}
</div>
<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>
{% for error in errors %}
<div class="text-danger">{{ error }}</div>
{% endfor %}
</form>
</div>
</div>
</div>
</div>
<div class="card rounded border-0 mb-4">
<div class="card-header">
<div class="row justify-content-between">
<div class="col-6">
<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>
</div>
<div class="col-4 text-end">
<a href="{{ url('admin_product_csv_template', {'type': 'product'}) }}" class="btn btn-ec-regular" id="download-button">{{ 'admin.common.csv_skeleton_download'|trans }}</a>
</div>
</div>
</div>
<div id="ex-csv_product-format" class="card-body">
<table class="table table-striped table-bordered">
<tbody>
{% for header, key in headers %}
<tr>
<th class="w-25 align-middle table-ec-lightGray" id="file_format_box__header--{{ loop.index }}">{{ header }}
{% if key.required %}
<span class="badge bg-primary ms-1">{{ 'admin.common.required'|trans }}</span>
{% endif %}
</th>
<td class="align-middle">
{% if key.description %}
{{ key.description|trans }}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="importCsvModal" tabindex="-1" role="dialog" aria-labelledby="importCsvModal" aria-hidden="true" data-bs-keyboard="false" data-bs-backdrop="static">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title fw-bold">{{ 'admin.product.product_csv_upload__title'|trans }}</h5>
<button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-start">
<span class="badge"></span>
<p class="text-start">{{ 'admin.product.product_csv_upload__message'|trans }}</p>
<div class="progress mb-1" style="display: none">
<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>
</div>
<ul id="bulkMessages"></ul>
<div id="toggleMessages" style="display: none;">
<i class="fa fw-bold me-1 fa-plus-square-o"></i><span>{{ 'admin.common.open_detail'|trans }}</span>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ec-sub" type="button" data-bs-dismiss="modal">{{ 'admin.common.cancel'|trans }}</button>
<button class="btn btn-ec-conversion" type="button" id="importCsv">{{ 'admin.common.bulk_registration' | trans }}</button>
<button class="btn btn-ec-regular" id="importCsvDone" style="display: none" type="button" data-bs-dismiss="modal">{{ 'admin.common.close'|trans }}</button>
</div>
</div>
</div>
</div>
{% endblock %}