From: Vladimir Fomichev Date: Mon, 18 Aug 2025 11:20:14 +0000 (+0300) Subject: Перенос списаний X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=bb1a9aa4c2a0c66aa43438f72b6e836358ff755e;p=erp24_rep%2Fyii-erp24%2F.git Перенос списаний --- diff --git a/erp24/api2/controllers/DataController.php b/erp24/api2/controllers/DataController.php index 3abedf76..4e09fd5b 100644 --- a/erp24/api2/controllers/DataController.php +++ b/erp24/api2/controllers/DataController.php @@ -1428,7 +1428,7 @@ class DataController extends BaseController } if (!empty($writeOffsErp)) { /** @var WriteOffsErp $writeOffsErp */ - $writeOffsErp->status = WriteOffsErp::STATUS_ERROR_1С; + $writeOffsErp->status = WriteOffsErp::STATUS_ERROR_1C; $writeOffsErp->error_text = $errorText; $writeOffsErp->save(); if ($writeOffsErp->getErrors()) { @@ -1442,7 +1442,7 @@ class DataController extends BaseController } if (!empty($waybillWriteOffsErp)) { /** @var WaybillWriteOffs $waybillWriteOffsErp */ - $waybillWriteOffsErp->status = WriteOffsErp::STATUS_ERROR_1С; + $waybillWriteOffsErp->status = WriteOffsErp::STATUS_ERROR_1C; $waybillWriteOffsErp->error_text = $errorText; $waybillWriteOffsErp->save(); if ($waybillWriteOffsErp->getErrors()) { @@ -1458,7 +1458,7 @@ class DataController extends BaseController } else { if (!empty($writeOffsErp)) { /** @var WriteOffsErp $writeOffsErp */ - $writeOffsErp->status = WriteOffsErp::STATUS_CREATED_1С; + $writeOffsErp->status = WriteOffsErp::STATUS_CREATED_1C; $writeOffsErp->number_1c = $arr["number"] ?? ''; $writeOffsErp->save(); if ($writeOffsErp->getErrors()) { @@ -1475,7 +1475,7 @@ class DataController extends BaseController } if (!empty($waybillWriteOffsErp) && isset($arr["held"]) && $arr["held"]) { /** @var WaybillWriteOffs $waybillWriteOffsErp */ - $waybillWriteOffsErp->status = WriteOffsErp::STATUS_CREATED_1С; + $waybillWriteOffsErp->status = WriteOffsErp::STATUS_CREATED_1C; $waybillWriteOffsErp->name_1c = $arr["name"] ?? ''; $waybillWriteOffsErp->save(); if ($waybillWriteOffsErp->getErrors()) { @@ -1565,7 +1565,7 @@ class DataController extends BaseController } /** @var WaybillIncoming $waybillIncoming */ - $waybillIncoming->status = WriteOffsErp::STATUS_ERROR_1С; + $waybillIncoming->status = WriteOffsErp::STATUS_ERROR_1C; $waybillIncoming->error_text = $errorText; $waybillIncoming->save(); if ($waybillIncoming->getErrors()) { @@ -1579,7 +1579,7 @@ class DataController extends BaseController } else { if (isset($arr["held"]) && $arr["held"]) { /** @var WaybillIncoming $waybillIncoming */ - $waybillIncoming->status = WriteOffsErp::STATUS_CREATED_1С; + $waybillIncoming->status = WriteOffsErp::STATUS_CREATED_1C; $waybillIncoming->number_1c = $arr["name"] ?? ''; $waybillIncoming->save(); if ($waybillIncoming->getErrors()) { @@ -1645,7 +1645,7 @@ class DataController extends BaseController } /** @var ReplacementInvoice $replacementInvoice */ - $replacementInvoice->status = WriteOffsErp::STATUS_ERROR_1С; + $replacementInvoice->status = WriteOffsErp::STATUS_ERROR_1C; $replacementInvoice->error_text = $errorText; $replacementInvoice->save(); if ($replacementInvoice->getErrors()) { @@ -1660,7 +1660,7 @@ class DataController extends BaseController } else { if (isset($arr["held"]) && $arr["held"]) { /** @var ReplacementInvoice $replacementInvoice */ - $replacementInvoice->status = WriteOffsErp::STATUS_CREATED_1С; + $replacementInvoice->status = WriteOffsErp::STATUS_CREATED_1C; $replacementInvoice->number_1c = $arr["name"] ?? ''; $replacementInvoice->save(); if ($replacementInvoice->getErrors()) { @@ -1706,7 +1706,7 @@ class DataController extends BaseController if (empty($arr["error"]) && !empty($arr["id"])) { $writeOffsErp = WriteOffsErp::find()->where(['guid' => $arr["id"]])->one(); if ($writeOffsErp) { - $writeOffsErp->status = WriteOffsErp::STATUS_CREATED_1С; + $writeOffsErp->status = WriteOffsErp::STATUS_CREATED_1C; $writeOffsErp->number_1c = $arr["number"]; $writeOffsErp->save(); if ($writeOffsErp->getErrors()) { @@ -1715,7 +1715,7 @@ class DataController extends BaseController } else { $waybillWriteOffsErp = WaybillWriteOffs::find()->where(['guid' => $arr["id"]])->one(); if ($waybillWriteOffsErp) { - $waybillWriteOffsErp->status = WriteOffsErp::STATUS_CREATED_1С; + $waybillWriteOffsErp->status = WriteOffsErp::STATUS_CREATED_1C; $waybillWriteOffsErp->number_1c = $arr["number"]; $waybillWriteOffsErp->save(); if ($waybillWriteOffsErp->getErrors()) { diff --git a/erp24/controllers/BouquetController.php b/erp24/controllers/BouquetController.php index 5bf10532..b9f76cd1 100644 --- a/erp24/controllers/BouquetController.php +++ b/erp24/controllers/BouquetController.php @@ -47,8 +47,8 @@ class BouquetController extends Controller if (!Yii::$app->user->can('notOnlyApprovedAndCreatedIn1C001')) { $query->andWhere(['status' => [ WriteOffsErp::STATUS_CONFIRM, - WriteOffsErp::STATUS_CREATED_1С, - WriteOffsErp::STATUS_ERROR_1С + WriteOffsErp::STATUS_CREATED_1C, + WriteOffsErp::STATUS_ERROR_1C ]]); } diff --git a/erp24/controllers/WriteOffsErpController.php b/erp24/controllers/WriteOffsErpController.php index b7a4dc44..b698189b 100644 --- a/erp24/controllers/WriteOffsErpController.php +++ b/erp24/controllers/WriteOffsErpController.php @@ -659,7 +659,7 @@ class WriteOffsErpController extends Controller 'write_offs_erp.active' => 1, ]) ->andWhere([ - '<>', 'status', WriteOffsErp::STATUS_CREATED_1С + '<>', 'status', WriteOffsErp::STATUS_CREATED_1C ]) ->with('writeOffsProductsErps'); @@ -697,7 +697,7 @@ class WriteOffsErpController extends Controller 'active' => 1, ]) ->andWhere([ - '<>', 'status', WriteOffsErp::STATUS_CREATED_1С + '<>', 'status', WriteOffsErp::STATUS_CREATED_1C ]) ->joinWith('writeOffsProductsErps') ->asArray() @@ -712,6 +712,73 @@ class WriteOffsErpController extends Controller if ($this->request->isPost && $model->load($this->request->post())) { + $isTransfer = (bool)Yii::$app->request->post('do_transfer', 0); + $postModels = Yii::$app->request->post('WriteOffsErp')['modelsProducts'] ?? []; + $transferIds = []; + foreach ($postModels as $row) { + if (!empty($row['transfer']) && !empty($row['id'])) { + $transferIds[] = (int)$row['id']; + } + } + $transferIds = array_unique(array_filter($transferIds)); + + if ($isTransfer) { + $transaction = \Yii::$app->db->beginTransaction(); + try { + $new = WriteOffsErp::newFromBase($model, $adminId); + + if (!$new->save(false)) { + Yii::error('Ошибка' . json_encode($new->getErrors(), JSON_UNESCAPED_UNICODE)); + throw new \RuntimeException('Не удалось создать новый документ списания.' . json_encode($new->getErrors(), JSON_UNESCAPED_UNICODE)); + } + + if (empty($new)) { + throw new \RuntimeException('Не выбраны позиции для переноса.'); + } + $rowsToMove = WriteOffsProductsErp::find() + ->where(['id' => $transferIds, 'active_product' => 1, 'write_offs_erp_id' => $model->id]) + ->orderBy(['num_row' => SORT_ASC]) + ->all(); + + if (!$rowsToMove) { + throw new \RuntimeException('Не найдены активные строки для переноса.'); + } + + $newNum = 1; + + foreach ($rowsToMove as $row) { + $row->setWriteOffsErpId($new->id); + $row->setNumRow($newNum++); + $row->setUpdatedAdminId($adminId); + $row->setUpdatedAt(); + if (!$row->save(false)) { + throw new \RuntimeException('Ошибка при переносе позиции ID=' . $row->id); + } + + ImageDocumentLink::updateAll( + ['document_id' => $new->id], + [ + 'document_group_id' => $documentGroupId, + 'document_id' => $model->id, + 'document_item_id' => $row->id, + ] + ); + } + + + WriteOffsErp::recalcTotals($model); + WriteOffsErp::recalcTotals($new); + + $transaction->commit(); + Yii::$app->session->setFlash('success', 'Перенесено в новый документ №' . ($new->number ?? $new->id)); + return $this->redirect(['/write-offs-erp/view', 'id' => $new->id]); + } catch (\Throwable $e) { + if (isset($transaction) && $transaction->isActive) { + $transaction->rollBack(); + } + Yii::$app->session->setFlash('error', 'Ошибка переноса: ' . $e->getMessage()); + } + } $modelsProducts = MultipleModel::createMultipleModel(WriteOffsProductsErp::classname(), 'WriteOffsErp', 'modelsProducts', $modelWriteOffsProductsErps); MultipleModel::loadMultipleFromArray($modelsProducts, $model->modelsProducts, ''); @@ -1010,7 +1077,7 @@ class WriteOffsErpController extends Controller $model = WriteOffsErp::find()->andWhere([ 'write_offs_erp.id' => $id, 'active' => 1, - 'status' => [WriteOffsErp::STATUS_SEND, WriteOffsErp::STATUS_ERROR_1С], + 'status' => [WriteOffsErp::STATUS_SEND, WriteOffsErp::STATUS_ERROR_1C], ]) ->joinWith(['writeOffsProductsErps']) ->one(); @@ -1064,7 +1131,7 @@ class WriteOffsErpController extends Controller $modelStatus = $model->getStatus(); - if (in_array($modelStatus, [WriteOffsErp::STATUS_SEND, WriteOffsErp::STATUS_ERROR_1С])) { + if (in_array($modelStatus, [WriteOffsErp::STATUS_SEND, WriteOffsErp::STATUS_ERROR_1C])) { $model->setStatusConfirm(); $model->resetSendAt(); $model->save(false); diff --git a/erp24/records/WriteOffsErp.php b/erp24/records/WriteOffsErp.php index 477b7a2c..fc2d2dd0 100644 --- a/erp24/records/WriteOffsErp.php +++ b/erp24/records/WriteOffsErp.php @@ -115,8 +115,8 @@ class WriteOffsErp extends \yii\db\ActiveRecord const STATUS_CREATED = 1; const STATUS_CONFIRM = 2; const STATUS_SEND = 3; - const STATUS_CREATED_1С = 4; - const STATUS_ERROR_1С = 8; + const STATUS_CREATED_1C = 4; + const STATUS_ERROR_1C = 8; const STATUS_DISABLE = 5; const WRITE_OFFS_TYPE_BRAK = "Брак"; const WRITE_OFFS_TYPE_RETURN_KALUGA = "Возврат нереализованного товара (Калуга)"; @@ -128,9 +128,9 @@ class WriteOffsErp extends \yii\db\ActiveRecord self::STATUS_CREATED => "Создан", self::STATUS_CONFIRM => "Одобрен", self::STATUS_SEND => "Отправлен в 1С", - self::STATUS_CREATED_1С => "Создан в 1С", + self::STATUS_CREATED_1C => "Создан в 1С", self::STATUS_DISABLE => "Отклонен", - self::STATUS_ERROR_1С => "Ошибка в 1С", + self::STATUS_ERROR_1C => "Ошибка в 1С", ]; public const TEST_STORES = [ @@ -722,9 +722,9 @@ class WriteOffsErp extends \yii\db\ActiveRecord self::STATUS_CREATED => 'Ожидает согласования', self::STATUS_CONFIRM => 'Согласован', self::STATUS_SEND => 'Отправлен в 1с', - self::STATUS_CREATED_1С => 'Создан в 1с', + self::STATUS_CREATED_1C => 'Создан в 1с', self::STATUS_DISABLE => 'Отключен', - self::STATUS_ERROR_1С => 'Ошибка загрузки в 1с', + self::STATUS_ERROR_1C => 'Ошибка загрузки в 1с', ]; } @@ -796,4 +796,71 @@ class WriteOffsErp extends \yii\db\ActiveRecord } return (in_array($storeId, self::TEST_STORES)); } + + /** + * Инициализация нового документа на основе исходного. + * Использует те же сеттеры, что и actionCreate. + */ + public static function newFromBase(WriteOffsErp $base, int $adminId): WriteOffsErp + { + $new = new WriteOffsErp(); + $new->loadDefaultValues(); + $attrsToCopy = [ + 'status', + 'store_id', + 'write_offs_type', + 'comment', + 'cause_group_id', + 'cause_id' + ]; + foreach ($attrsToCopy as $attr) { + if ($base->hasProperty($attr)) { + $new->$attr = $base->$attr; + } + } + + $new->setGuidCreated(); + $new->setNumberDefault(); + $new->setStatusCreated(); + $new->setCreatedDate(); + $new->setStoreGuidCreated(); + $new->setCreatedAt(); + $new->setCauseGroupId(); + $new->setCreatedAdminId($adminId); + + $new->setNumberCreated(); + $new->setUpdatedAdminId($adminId); + $new->setQuantity(0); + $new->setSumm(0); + $new->setSummRetail(0); + + return $new; + } + + + /** + * Пересчёт сумм документа по его активным строкам. + */ + public static function recalcTotals(WriteOffsErp $doc): void + { + $items = WriteOffsProductsErp::find() + ->where(['write_offs_erp_id' => $doc->id, 'active_product' => 1]) + ->all(); + + $sum = 0.0; + $qty = 0.0; + foreach ($items as $it) { + $sum += (float)$it->summ; + $qty += (float)$it->quantity; + } + $doc->setSumm($sum); + $doc->setSummRetail($sum); // как в create + $doc->setQuantity($qty); + $doc->setUpdatedAt(); + $doc->setUpdatedAdminId($doc->getUpdatedAdminId() ?: $doc->getCreatedAdminId()); + + if (!$doc->save()) { + Yii::error('Ошибка сохранения документа списания ' . json_encode($doc->getErrors(),JSON_UNESCAPED_UNICODE)); + } + } } diff --git a/erp24/services/StorePlanService.php b/erp24/services/StorePlanService.php index 9d2200e6..a2319069 100755 --- a/erp24/services/StorePlanService.php +++ b/erp24/services/StorePlanService.php @@ -1091,7 +1091,7 @@ class StorePlanService ->groupBy(['bouquet_composition.id', 'bf.year', 'bf.month']) ->andWhere(['status' => [ - WriteOffsErp::STATUS_CREATED_1С, + WriteOffsErp::STATUS_CREATED_1C, ]]) ->innerJoinWith(['bouquetForecast bf' => function($query) use ($year, $month) { diff --git a/erp24/views/bouquet/_form.php b/erp24/views/bouquet/_form.php index 8a6c9cbe..7bd07ccb 100644 --- a/erp24/views/bouquet/_form.php +++ b/erp24/views/bouquet/_form.php @@ -104,10 +104,10 @@ $form = ActiveForm::begin([ status) { WriteOffsErp::STATUS_CREATED => 'bg-info', WriteOffsErp::STATUS_CONFIRM, - WriteOffsErp::STATUS_CREATED_1С => 'bg-success', + WriteOffsErp::STATUS_CREATED_1C => 'bg-success', WriteOffsErp::STATUS_SEND => 'bg-warning', WriteOffsErp::STATUS_DISABLE, - WriteOffsErp::STATUS_ERROR_1С => 'bg-danger', + WriteOffsErp::STATUS_ERROR_1C => 'bg-danger', default => 'bg-secondary', } ?> fs-5 text-white px-7 w-100 mb-4 text-center"> status ? \yii_app\records\WriteOffsErp::STATUSES[$model->status] : null) ?> diff --git a/erp24/views/bouquet/index.php b/erp24/views/bouquet/index.php index a2a14bf5..db34e334 100644 --- a/erp24/views/bouquet/index.php +++ b/erp24/views/bouquet/index.php @@ -242,10 +242,10 @@ $this->title = 'Содержание матрицы'; match ($model->status) { WriteOffsErp::STATUS_CREATED => 'bg-info', WriteOffsErp::STATUS_CONFIRM, - WriteOffsErp::STATUS_CREATED_1С => 'bg-success', + WriteOffsErp::STATUS_CREATED_1C => 'bg-success', WriteOffsErp::STATUS_SEND => 'bg-warning', WriteOffsErp::STATUS_DISABLE, - WriteOffsErp::STATUS_ERROR_1С => 'bg-danger', + WriteOffsErp::STATUS_ERROR_1C => 'bg-danger', default => 'bg-secondary', } . " fs-6 text-white px-7 w-100 mb-4 d-block'> diff --git a/erp24/views/waybill-write-offs/view.php b/erp24/views/waybill-write-offs/view.php index 953e86a0..556293dd 100644 --- a/erp24/views/waybill-write-offs/view.php +++ b/erp24/views/waybill-write-offs/view.php @@ -54,9 +54,9 @@ $this->params['breadcrumbs'][] = $this->title; 'label' => 'Текст ошибки', 'attribute' => 'error_text', 'value' => function ($model) { - return $model->status == \yii_app\records\WriteOffsErp::STATUS_ERROR_1С ? $model->error_text : ''; + return $model->status == \yii_app\records\WriteOffsErp::STATUS_ERROR_1C ? $model->error_text : ''; }, - 'visible' => $model->status == \yii_app\records\WriteOffsErp::STATUS_ERROR_1С, + 'visible' => $model->status == \yii_app\records\WriteOffsErp::STATUS_ERROR_1C, ], [ 'label' => 'Номер документа в 1С', @@ -70,10 +70,10 @@ $this->params['breadcrumbs'][] = $this->title; 'attribute' => 'name_1c', 'value' => function ($model) { return - $model->status == \yii_app\records\WriteOffsErp::STATUS_CREATED_1С ? + $model->status == \yii_app\records\WriteOffsErp::STATUS_CREATED_1C ? $model->name_1c : ''; }, - 'visible' => $model->status == \yii_app\records\WriteOffsErp::STATUS_CREATED_1С, + 'visible' => $model->status == \yii_app\records\WriteOffsErp::STATUS_CREATED_1C, ], [ 'label' => 'Отправлено в 1С', diff --git a/erp24/views/write_offs_erp/_form.php b/erp24/views/write_offs_erp/_form.php index 76c9ada5..dba747d1 100644 --- a/erp24/views/write_offs_erp/_form.php +++ b/erp24/views/write_offs_erp/_form.php @@ -150,6 +150,14 @@ $this->registerJsFile('/js/heic_to_jpg_replace.js', ['position' => \yii\web\View ], 'items' => $listProductsDict, ], + [ + 'name' => 'transfer', + 'type' => 'checkbox', + 'title' => 'Перенести', + 'options' => [ + 'class' => 'transfer-checkbox', + ], + ], [ 'name' => 'quantity', 'type' => 'textInput', @@ -331,7 +339,7 @@ $this->registerJsFile('/js/heic_to_jpg_replace.js', ['position' => \yii\web\View status, [\yii_app\records\WriteOffsErp::STATUS_CREATED, \yii_app\records\WriteOffsErp::STATUS_ERROR_1С])) { + if (in_array($model->status, [\yii_app\records\WriteOffsErp::STATUS_CREATED, \yii_app\records\WriteOffsErp::STATUS_ERROR_1C])) { ?>
'btn btn-success submitter']) ?> @@ -342,8 +350,18 @@ $this->registerJsFile('/js/heic_to_jpg_replace.js', ['position' => \yii\web\View + 'do-transfer']) ?> + +
+ 'btn btn-warning', + 'id' => 'btn-transfer', + 'type' => 'button', + 'title' => 'Создать новый документ и переместить в него отмеченные позиции', + ]) ?> +
isNewRecord) { @@ -351,5 +369,4 @@ $this->registerJsFile('/js/heic_to_jpg_replace.js', ['position' => \yii\web\View } ?> -
diff --git a/erp24/views/write_offs_erp/index.php b/erp24/views/write_offs_erp/index.php index c9551293..575be3bd 100644 --- a/erp24/views/write_offs_erp/index.php +++ b/erp24/views/write_offs_erp/index.php @@ -76,7 +76,7 @@ $columns = [ 'visibleButtons' => [ 'view' => true, 'update' => function($model) { - if ($model->status == WriteOffsErp::STATUS_CREATED || $model->status == WriteOffsErp::STATUS_ERROR_1С) { + if ($model->status == WriteOffsErp::STATUS_CREATED || $model->status == WriteOffsErp::STATUS_ERROR_1C) { return true; } else { return false; diff --git a/erp24/views/write_offs_erp/update.php b/erp24/views/write_offs_erp/update.php index 3b86a502..b3de7d41 100644 --- a/erp24/views/write_offs_erp/update.php +++ b/erp24/views/write_offs_erp/update.php @@ -15,6 +15,8 @@ $this->title = 'Изменение документа списания номе $this->params['breadcrumbs'][] = ['label' => 'Write Offs Erps', 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]]; $this->params['breadcrumbs'][] = 'Update'; +$this->registerJsFile('/js/write-offs-erp/update.js', ['position' => \yii\web\View::POS_END]); +?> ?>
diff --git a/erp24/views/write_offs_erp/view.php b/erp24/views/write_offs_erp/view.php index 7cc37b76..57c4c8c1 100644 --- a/erp24/views/write_offs_erp/view.php +++ b/erp24/views/write_offs_erp/view.php @@ -242,7 +242,7 @@ $this->registerCssFile('/css/write-offs-erp.css', ['position' => \yii\web\View:: status == WriteOffsErp::STATUS_SEND || $model->status == WriteOffsErp::STATUS_ERROR_1С) && $allowShowReSendButton) { + if (($model->status == WriteOffsErp::STATUS_SEND || $model->status == WriteOffsErp::STATUS_ERROR_1C) && $allowShowReSendButton) { ?>

0; + if (!anyChecked) { + e.preventDefault(); + e.stopImmediatePropagation(); + alert('Отметьте хотя бы одну позицию для переноса.'); + $('#do-transfer').val(0); + return false; + } + } + }); + $('#btn-transfer').on('click', function(e){ + e.preventDefault(); + e.stopImmediatePropagation(); + + const anyChecked = $('.transfer-checkbox:checked').length > 0; + if (!anyChecked) { + alert('Отметьте хотя бы одну позицию для переноса.'); + return false; + } + + + if(!confirm('Перенести отмеченные позиции в новый документ?')){ + return; + } + + $('#do-transfer').val(1); + form.trigger('submit'); + }); + + $('.submitter').on('click', function(e){ + $('#do-transfer').val(0); + $('#dynamic-form').trigger('submit'); + }); +})(); \ No newline at end of file