namespace yii_app\actions\motivation;
+use PhpOffice\PhpSpreadsheet\IOFactory;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use Yii;
use yii\base\Action;
use yii\base\DynamicModel;
use yii\helpers\ArrayHelper;
+use yii\web\UploadedFile;
use yii_app\records\CityStore;
+use yii_app\records\MotivationCostsItem;
class IndexAction extends Action
{
public function run() {
+ if (Yii::$app->request->isPost) {
+ $file = UploadedFile::getInstanceByName('myfile');
+ if ($file) {
+ $path = Yii::getAlias('@uploads') . '/template_plan.xslx';
+ $file->saveAs($path);
+
+ $motivationCostsItems = MotivationCostsItem::find()->indexBy('code')->all();
+ $spreadsheets = IOFactory::load($path);
+ $sheets = [];
+ $errors = [];
+ foreach ($spreadsheets->getAllSheets() as $spreadSheet) {
+ $rows = [];
+ $finish = false;
+ $storeStr = true;
+ $error = '';
+ foreach ($spreadSheet->getRowIterator() as $ind => $spreadSheetRow) {
+ $row = [];
+ foreach ($spreadSheetRow->getCellIterator() as $spreadSheetRowCell) {
+ $value = $spreadSheetRowCell->getValue();
+ if ($value == '###') {
+ $finish = true;
+ break;
+ }
+ $row []= $value;
+ }
+ if ($finish) {
+ break;
+ }
+ if ($storeStr) {
+ $store = CityStore::find()->where(['id' => $row[0] ?? -1])->one();
+ if (!$store) {
+ $error = "Не найден магазин с таким индексом [0,0]";
+ break;
+ } elseif ($store->name != ($row[1] ?? 'NO_NAME')) {
+ $error = "Не найден магазин с таким названием [1,0]" . $row[1] . ' ' . $store->name;
+ break;
+ }
+ $year = ((int)$row[2]) ?? -1;
+ $month = ((int)$row[3]) ?? -1;
+ if ($year > 2030 || $year < 2023) {
+ $error = "Не корректно указан год [2,0]";
+ break;
+ }
+ if ($month < 1 || $month > 12) {
+ $error = "Не корректно указан месяц [3,0]";
+ break;
+ }
+ $storeStr = false;
+ } else {
+ if (!isset($motivationCostsItems[$row[0] ?? -1])) {
+ $error = "Не корректен код элемента " . ($row[0] ?? '') . "[$ind,0]";
+ break;
+ }
+ /** @var $motivationCostsItems MotivationCostsItem[] */
+ if ($motivationCostsItems[$row[0]]->name != ($row[1] ?? 'NO_NAME')) {
+ $error = "Не корректно название элемента " . ($row[1] ?? '') . "[$ind,1]";
+ break;
+ }
+ if (($row[2] ?? 'NO_NAME') == 'NO_NAME') {
+ $error = "Не корректно значение элемента [$ind,2]";
+ break;
+ }
+ switch ($motivationCostsItems[$row[0]]->data_type) {
+ case MotivationCostsItem::DATA_TYPE_INT: { if (is_int($row[2])) { $value = (int)$row[2]; } else { $error = "Не инт [$ind,2]"; }; break; }
+ case MotivationCostsItem::DATA_TYPE_FLOAT: { if (is_int($row[2]) || is_float($row[2])) { $value = (float)$row[2]; } else {$error = "Не флот [$ind,2]"; } break; }
+ case MotivationCostsItem::DATA_TYPE_STRING: { $value = $row[2]; break; }
+ }
+ if (!empty($error)) {
+ break;
+ }
+ }
+ $rows []= $row;
+ }
+ $errors []= empty($error) ? '' : $error;
+ $sheets []= $rows;
+ }
+
+ return implode('<br>', $errors);
+ } else {
+ return 'not ok';
+ }
+ }
+
$model = DynamicModel::validateData([
'store_id' => null, 'year' => null, 'month' => null
], [
"kartik-v/yii2-widget-fileinput": "dev-master",
"yiisoft/yii2-imagine": "^2.3",
"kartik-v/yii2-builder": "dev-master",
- "box/spout": "^3.3"
+ "phpoffice/phpspreadsheet": "^1.12"
},
"require-dev": {
"yiisoft/yii2-debug": "~2.1.0",
public function actions() {
return [
'index' => \yii_app\actions\motivation\IndexAction::class,
- 'upload-xlsx' => \yii_app\actions\motivation\UploadXlsxAction::class,
+ //'upload-xlsx' => \yii_app\actions\motivation\UploadXlsxAction::class,
'values' => \yii_app\actions\motivation\ValuesAction::class,
'create-value' => \yii_app\actions\motivation\CreateValueAction::class,
'update-value' => \yii_app\actions\motivation\UpdateValueAction::class,
/** @var $years array */
/** @var $months array */
+$this->registerJsFile('/js/motivation/index.js', ['position' => \yii\web\View::POS_END]);
+
?>
<div class="motivationIndex m-5">
<div class="d-flex justify-content-around align-items-center gap-2">
<div class="mb-3"><?= Html::submitButton('Применить', ['class' => 'btn btn-secondary btn-sm'])?></div>
</div>
+ <div class="d-flex justify-content-around align-items-center gap-2">
+ <div class="mb-3"><?= Html::button('Загрузить плановых значений', ['class' => 'btn btn-success btn-sm',
+ 'onclick' => 'openUploadDictionary();'])?></div>
+ </div>
</div>
</div>
--- /dev/null
+/* jshint esversion: 8 */
+
+const param10 = $("meta[name=csrf-param]").attr("content");
+const token10 = $("meta[name=csrf-token]").attr("content");
+
+/* jshint unused: false */
+function openUploadDictionary() {
+ 'use strict'
+ const $mainModal = $('#mainModal');
+ const $modalBody = $mainModal.find('.modal-body');
+ const $modalFooter = $mainModal.find('.modal-footer');
+ $mainModal.find('.close').on('click', () => { $mainModal.modal('hide'); });
+ $mainModal.find('.modal-title').html('Загрузка плановых значений');
+ $modalFooter.html('');
+ $modalBody.html('<div class="row"><div class="col-12"><form class="d-flex justify-content-left align-items-center" enctype="multipart/form-data"><div class="d-none"><input type="file" name="myfile" accept=".xlsx"/></div><div><input class="btn btn-success btn-sm" type="submit" value="Загрузить" /></div></form></div></div><div class="row"><div class="col-12" id="infoModal"</div>');
+ const browse = $modalBody.find('input[type=file]').get(0);
+ const btn = $modalBody.find('input[type=submit]').get(0);
+ const info = $modalBody.find('#infoModal').get(0);
+ const form = $modalBody.find('form').get(0);
+ async function UploadDict() {
+ const formData = new FormData(form);
+ formData.append(param10, token10);
+ try {
+ const response = await fetch("/motivation/index", {
+ method: "POST",
+ body: formData,
+ });
+ const text = await response.text();
+ if (text === 'not ok') {
+ info.innerHTML = '<span style="color:red">Не смог загрузить файл</span>';
+ } else if (text.replaceAll('<br>', '') === '') {
+ info.innerHTML = '<span style="color:green">Успешно загружен</span>';
+ } else {
+ info.innerHTML = '<span style="color:red">' + text + '</span>';
+ }
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ browse.addEventListener('change', (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ UploadDict();
+ })
+
+ btn.addEventListener('click', (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ browse.click();
+ })
+
+ $mainModal.modal('show');
+}
\ No newline at end of file