From 70b558362241fdbbdfd30e0f6994d8568c6708b4 Mon Sep 17 00:00:00 2001 From: marina Date: Fri, 29 Nov 2024 09:45:31 +0300 Subject: [PATCH] =?utf8?q?ERP-243=20=D0=94=D0=B5=D0=B9=D1=81=D1=82=D0=B2?= =?utf8?q?=D0=B8=D1=8F=20=D0=BF=D0=BE=20=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD?= =?utf8?q?=D0=B5=20(II=20=D1=8D=D1=82=D0=B0=D0=BF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- erp24/controllers/ShiftTransferController.php | 12 +- ...5457_create_equalization_remains_table.php | 5 +- erp24/records/EqualizationRemains.php | 243 ++++++++++++++++++ erp24/records/ShiftRemains.php | 9 + erp24/records/ShiftTransfer.php | 8 + erp24/views/shift-transfer/_replacement.php | 84 ++++++ erp24/views/shift-transfer/_transfer.php | 96 +++++++ erp24/views/shift-transfer/view.php | 96 +------ 8 files changed, 468 insertions(+), 85 deletions(-) create mode 100644 erp24/records/EqualizationRemains.php create mode 100644 erp24/views/shift-transfer/_replacement.php create mode 100644 erp24/views/shift-transfer/_transfer.php diff --git a/erp24/controllers/ShiftTransferController.php b/erp24/controllers/ShiftTransferController.php index 176b6c0f..7f30bc6a 100644 --- a/erp24/controllers/ShiftTransferController.php +++ b/erp24/controllers/ShiftTransferController.php @@ -8,6 +8,7 @@ use yii\web\Controller; use yii\web\Response; use yii_app\records\Admin; use yii_app\records\Balances; +use yii_app\records\EqualizationRemains; use yii_app\records\ExportImportTable; use yii_app\records\MultipleModel; use yii_app\records\Prices; @@ -125,14 +126,23 @@ class ShiftTransferController extends Controller } public function actionView($id) { + + if (Yii::$app->request->post()) { + ShiftRemains::updateAll(['type' => ShiftRemains::ARCHIVE_RECORD, ['shift_transfer_id' => $id]]); + } + $shiftTransfer = ShiftTransfer::findOne($id); $storeNameById = TaskService::getEntitiesByAlias('store'); $admins = ArrayHelper::map(Admin::find()->all(), 'id', 'name'); + $isAcceptance = in_array($shiftTransfer->status_id, [ShiftTransfer::STATUS_ID_TRANSFER_ACTIONS, ShiftTransfer::STATUS_ID_INPUT_FACT_REMAINS]); + + EqualizationRemains::getEqualizationTable($shiftTransfer); + return $this->render('view', - compact('shiftTransfer', 'storeNameById', 'admins')); + compact('shiftTransfer', 'storeNameById', 'admins', 'isAcceptance')); } public function actionDelete($id) { diff --git a/erp24/migrations/m241127_065457_create_equalization_remains_table.php b/erp24/migrations/m241127_065457_create_equalization_remains_table.php index 4eb99356..7accc9e6 100644 --- a/erp24/migrations/m241127_065457_create_equalization_remains_table.php +++ b/erp24/migrations/m241127_065457_create_equalization_remains_table.php @@ -18,12 +18,13 @@ class m241127_065457_create_equalization_remains_table extends Migration 'product_id' => $this->string()->comment('ID товара с недостатком'), 'product_count' => $this->float()->comment('Количество товара с недостатком'), 'product_price' => $this->float()->comment('Цена товара розничная'), - 'product_price_seft_cost' => $this->float()->comment('Себестоимость товара'), + 'product_price_self_cost' => $this->float()->comment('Себестоимость товара'), 'product_replacement_id' => $this->string()->comment('Товар замена'), 'product_replacement_count' => $this->float()->comment('Количество товара замены'), 'product_replacement_price' => $this->float()->comment('Цена товара замены розничная'), - 'product_replacement_price_seft_cost' => $this->float()->comment('Себестоимость товара замены'), + 'product_replacement_price_self_cost' => $this->float()->comment('Себестоимость товара замены'), 'balance' => $this->float()->comment('Разница в сумме'), + 'balance_self_cost' => $this->float()->comment('Разница в сумме (себестоимость)'), 'created_at' => $this->dateTime()->comment('Дата создания записи'), 'updated_at' => $this->dateTime()->comment('Дата обновления записи'), 'created_by' => $this->integer()->comment('Автор создания записи'), diff --git a/erp24/records/EqualizationRemains.php b/erp24/records/EqualizationRemains.php new file mode 100644 index 00000000..cc933c3d --- /dev/null +++ b/erp24/records/EqualizationRemains.php @@ -0,0 +1,243 @@ + TimestampBehavior::class, + 'createdAtAttribute' => 'created_at', + 'updatedAtAttribute' => 'updated_at', + 'value' => new Expression('NOW()'), + ], + [ + 'class' => BlameableBehavior::class, + 'createdByAttribute' => 'created_by', + 'updatedByAttribute' => 'updated_by', + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['shift_id', 'created_by', 'updated_by'], 'integer'], + [['product_count', 'product_price', 'product_price_self_cost', 'product_replacement_count', 'product_replacement_price', 'product_replacement_price_self_cost', 'balance', 'balance_self_cost'], 'number'], + [['created_at', 'updated_at'], 'safe'], + [['product_id', 'product_replacement_id'], 'string', 'max' => 255], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID записи', + 'shift_id' => 'ID записи передачи смены', + 'product_id' => 'ID товара с недостатком', + 'product_count' => 'Количество товара с недостатком', + 'product_price' => 'Цена товара розничная', + 'product_price_self_cost' => 'Себестоимость товара', + 'product_replacement_id' => 'Товар замена', + 'product_replacement_count' => 'Количество товара замены', + 'product_replacement_price' => 'Цена товара замены розничная', + 'product_replacement_price_self_cost' => 'Себестоимость товара замены', + 'balance' => 'Разница в сумме', + 'balance_self_cost' => 'Разница в сумме (Себестоимость)', + 'created_at' => 'Дата создания записи', + 'updated_at' => 'Дата обновления записи', + 'created_by' => 'Автор создания записи', + 'updated_by' => 'Автор обновления записи', + ]; + } + + public static function getEqualizationTable(ShiftTransfer $shiftTransfer) + { + $existingReplacement = self::findAll(['shift_id' => $shiftTransfer->id]); + + // Если записи уже существуют, возвращаем их + if (!empty($existingReplacement)) { + return $existingReplacement; + } + + // Если записей нет, создаем их + $replacementArray = []; + $storeGuid = $shiftTransfer->store_guid; + $storeId = array_flip(array_map('strval', CityStore::getAllActiveGuidId()))[$storeGuid]; + $date = $shiftTransfer->date; + + foreach ($shiftTransfer->shiftRemains as $product) { + $productGuid = $product->product_guid; + $productReplacement = Product1cReplacement::findAll(['guid' => $productGuid]); + + // Для каждого продукта находим замены + foreach ($productReplacement as $pr) { + $replacement = Balances::findOne(['store_id' => $storeGuid, 'product_id' => $pr->guid_replacement]); + + // Проверяем условие замены (не хватка товаров) + if ($replacement && ($replacement->quantity + array_sum(array_column($replacementArray, 'count'))) < $product->remains_count) { + // Собираем все данные в один массив + $productPrice = Prices::findOne(['product_id' => $productGuid]); + $productSelfCost = SelfCostProduct::findOne(['product_guid' => $productGuid, 'store' => $storeId, 'date' => $date]); + $replacementPrice = Prices::findOne(['product_id' => $pr->guid_replacement]); + $replacementSelfCost = SelfCostProduct::findOne(['product_guid' => $pr->guid_replacement, 'store' => $storeId, 'date' => $date]); + + // Если все данные найдены, добавляем информацию о балансе + if ($productPrice && $productSelfCost && $replacementPrice && $replacementSelfCost) { + $replacementArray[] = [ + 'count' => $replacement->quantity, + 'product_price' => $productPrice->price, + 'product_self_cost' => $productSelfCost->price, + 'product_replacement' => $replacement->product_id, + 'product_replacement_price' => $replacementPrice->price, + 'product_replacement_self_cost' => $replacementSelfCost->price, + 'balance' => $replacement->quantity * ($productPrice->price - $replacementPrice->price), + 'balance_self_cost' => $replacement->quantity * ($productSelfCost->price - $replacementSelfCost->price), + ]; + } + } else { + // Если товаров достаточно, прерываем цикл + break; + } + } + } + + // Теперь сохраняем данные о выравнивании + foreach ($replacementArray as $replacementData) { + $equalizationRemains = new EqualizationRemains(); + $equalizationRemains->setAttributes([ + 'shift_id' => $shiftTransfer->id, + 'product_id' => $replacementData['product_id'], + 'product_count' => $replacementData['count'], + 'product_price' => $replacementData['product_price'], + 'product_self_cost' => $replacementData['product_self_cost'], + 'product_replacement' => $replacementData['product_replacement'], + 'product_replacement_count' => $replacementData['count'], + 'product_replacement_price' => $replacementData['product_replacement_price'], + 'product_replacement_self_cost' => $replacementData['product_replacement_self_cost'], + 'balance' => $replacementData['balance'], + 'balance_self_cost' => $replacementData['balance_self_cost'], + ]); + $equalizationRemains->save(); + } + + return self::findAll(['shift_id' => $shiftTransfer->id]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getProduct() + { + return $this->hasOne(Products1c::class, ['id' => 'product_id', 'tip' => 'products']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getProductReplacement() + { + return $this->hasOne(Products1c::class, ['id' => 'product_replacement_id', 'tip' => 'products']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getProductPrice() + { + return $this->hasOne(Prices::class, ['product_id' => 'product_id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getProductReplacementPrice() + { + return $this->hasOne(Prices::class, ['product_id' => 'product_replacement_id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getProductPriceSelfCost() + { + return $this->hasOne(SelfCostProduct::class, ['product_guid' => 'product_id', 'date' => $this->shiftRemains->shiftTransfer->date]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getProductReplacementPriceSelfCost() + { + return $this->hasOne(SelfCostProduct::class, ['product_guid' => 'product_replacement_id', 'date' => $this->shiftRemains->shiftTransfer->date]); + } + + + /** + * @return \yii\db\ActiveQuery + */ + public function getShiftTransfer() + { + return $this->hasMany(ShiftTransfer::class, ['id' => 'shift_id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getCreatedBy() + { + return $this->hasOne(Admin::class, ['id' => 'created_by']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getUpdatedBy() + { + return $this->hasOne(Admin::class, ['id' => 'updated_by']); + } + +} diff --git a/erp24/records/ShiftRemains.php b/erp24/records/ShiftRemains.php index 467167b0..f4c9aa04 100644 --- a/erp24/records/ShiftRemains.php +++ b/erp24/records/ShiftRemains.php @@ -17,9 +17,16 @@ use Yii; * @property float $remains_count Фактические остатки кол-во * @property float $fact_and_1c_diff Разница факт и по программе 1с может быть и минус (- недостача, + излишек) 0 - соответствие. * @property float $remains_1c остатки по 1с (текущие) + * @property int $type тип записи архивная/временная */ class ShiftRemains extends \yii\db\ActiveRecord { + + //Архивная запись (после подтверждения) + const ARCHIVE_RECORD = 2; + //Временная запись (после создания) + const TEMPORARY_RECORD = 1; + /** * {@inheritdoc} */ @@ -40,6 +47,7 @@ class ShiftRemains extends \yii\db\ActiveRecord [['retail_price', 'self_cost', 'remains_summ', 'remains_count', 'fact_and_1c_diff', 'remains_1c'], 'number'], [['group_label'], 'string', 'max' => 40], [['product_guid'], 'string', 'max' => 36], + [['type'], 'default', 'value' => self::TEMPORARY_RECORD], ]; } @@ -59,6 +67,7 @@ class ShiftRemains extends \yii\db\ActiveRecord 'remains_count' => 'Remains Count', 'fact_and_1c_diff' => 'Fact And 1c Diff', 'remains_1c' => 'Remains 1c', + 'type' => 'Тип записи', ]; } } diff --git a/erp24/records/ShiftTransfer.php b/erp24/records/ShiftTransfer.php index 49589dc9..2fa6b646 100644 --- a/erp24/records/ShiftTransfer.php +++ b/erp24/records/ShiftTransfer.php @@ -88,4 +88,12 @@ class ShiftTransfer extends \yii\db\ActiveRecord public function getShiftRemains() { return $this->hasMany(ShiftRemains::class, ['shift_transfer_id' => 'id']); } + + /** + * @return \yii\db\ActiveQuery + */ + public function getEqualizationRemains() + { + return $this->hasMany(EqualizationRemains::class, ['shift_id' => 'id']); + } } diff --git a/erp24/views/shift-transfer/_replacement.php b/erp24/views/shift-transfer/_replacement.php new file mode 100644 index 00000000..317243ac --- /dev/null +++ b/erp24/views/shift-transfer/_replacement.php @@ -0,0 +1,84 @@ +user->id === $controlerId) { + $btn = Html::submitButton('Принять', ['class' => 'btn btn-primary']); +} +//else if () { +// $btn = Html::submitButton('Сохранить', ['class' => 'btn btn-primary']); +//} + +if ($isAcceptance) { + $buttonOptions = [ + 'class' => 'btn btn-success visible d-none', + ]; +} else { + $buttonOptions = [ + 'class' => 'btn btn-success visible', + 'style' => 'display:block; width: 250px;', + ]; +} + +$form = \yii\widgets\ActiveForm::begin(); +echo $form->field($shiftTransfer, 'equalizationRemains')->widget(MultipleInput::class, [ + 'min' => 0, + 'max' => 100, + 'columns' => [ + [ + 'name' => 'product_count', + 'type' => BaseColumn::TYPE_TEXT_INPUT, + 'options' => ['type' => 'number', 'step' => 0.01], + 'title' => 'Заменяемый товар', + ], + [ + 'name' => 'product_price', + 'type' => BaseColumn::TYPE_TEXT_INPUT, + 'options' => ['type' => 'number', 'step' => 0.01, 'readonly' => true,], + 'title' => 'Цена товара', + ], + [ + 'title' => 'Замещающей товар', + 'name' => 'product_replacement_id', + 'enableError' => true, + 'options' => ['class' => 'form-control'], + ], + [ + 'name' => 'product_replacement_price', + 'type' => BaseColumn::TYPE_TEXT_INPUT, + 'options' => ['type' => 'number', 'step' => 0.01, 'readonly' => true,], + 'title' => 'Цена замещающего товара', + ], + [ + 'name' => 'product_replacement_count', + 'type' => BaseColumn::TYPE_TEXT_INPUT, + 'options' => ['type' => 'number', 'step' => 1], + 'title' => 'Количество', + ], + [ + 'name' => 'balance', + 'title' => 'Баланс', + 'type' => BaseColumn::TYPE_TEXT_INPUT, + 'options' => ['type' => 'number', 'step' => 0.01, 'readonly' => true,], + ], + ], + 'addButtonPosition' => MultipleInput::POS_FOOTER, + 'addButtonOptions' => $buttonOptions, + 'iconSource' => 'fa', +])->label('Таблица возможных замен'); + +ActiveForm::end(); +echo $btn; diff --git a/erp24/views/shift-transfer/_transfer.php b/erp24/views/shift-transfer/_transfer.php new file mode 100644 index 00000000..61b2b7ee --- /dev/null +++ b/erp24/views/shift-transfer/_transfer.php @@ -0,0 +1,96 @@ + + new \yii\data\ArrayDataProvider([ + 'allModels' => $shiftTransfer->shiftRemains + ]), +// 'showFooter' => true, + 'columns' => [ + [ + 'attribute' => 'group_label', + 'label' => 'Название группы', +// 'footer' => 'Итого:', + 'pageSummary' => 'Итого:', + 'value' => function($data) { + return ProductsClass::getHints()[$data['group_label']] ?? ''; + }, + ], + [ + 'attribute' => 'product_guid', + 'label' => 'Продукт', + 'value' => function($data) { + $productsClass = ProductsClass::find()->select('category_id') + ->where(['tip' => $data['group_label'] ?? null])->column(); + + $products = ArrayHelper::map(Products1c::find()->select(['id', 'name']) + ->where(['parent_id' => $productsClass])->all(), 'id', 'name'); + + return $products[$data['product_guid']] ?? ''; + }, + ], + [ + 'attribute' => 'retail_price', + 'label' => 'Розничная цена, руб', + 'value' => function($data) { + return $data['retail_price'] ?? ''; + }, + ], + [ + 'attribute' => 'self_cost', + 'label' => 'Себестоимость, руб', +// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'self_cost')), + 'pageSummary' => true, + 'value' => function($data) { + return $data['self_cost'] ?? ''; + }, + ], + [ + 'attribute' => 'remains_summ', + 'label' => 'Сумма остатков (недостача или излишек), руб', + 'pageSummary' => true, +// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'remains_summ')), + 'value' => function($data) { + return $data['remains_summ'] ?? ''; + }, + ], + [ + 'attribute' => 'remains_count', + 'label' => 'Фактические остатки кол-во, шт', + 'pageSummary' => true, +// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'remains_count')), + 'value' => function($data) { + return $data['remains_count'] ?? ''; + }, + ], + [ + 'attribute' => 'fact_and_1c_diff', + 'label' => 'Разница факт и по программе 1с, шт', + 'pageSummary' => true, +// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'fact_and_1c_diff')), + 'value' => function($data) { + return $data['fact_and_1c_diff'] ?? ''; + }, + ], + [ + 'attribute' => 'remains_1c', + 'label' => 'Остатки по 1с, шт', + 'pageSummary' => true, +// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'remains_1c')), + 'value' => function($data) { + return $data['remains_1c'] ?? ''; + }, + ], + [ + 'attribute' => 'type', + 'value' => function ($model) { + return $model->type === \yii_app\records\ShiftRemains::ARCHIVE_RECORD ? 'Архивная запись' : 'Временная запись'; + } + ], + ], + 'showPageSummary' => true, +]); ?> \ No newline at end of file diff --git a/erp24/views/shift-transfer/view.php b/erp24/views/shift-transfer/view.php index cd485d1b..26f67c94 100644 --- a/erp24/views/shift-transfer/view.php +++ b/erp24/views/shift-transfer/view.php @@ -10,6 +10,7 @@ use yii_app\records\Products1c; /* @var $shiftTransfer ShiftTransfer */ /* @var $storeNameById array */ /* @var $admins array */ +/* @var $isAcceptance bool */ ?> @@ -61,90 +62,21 @@ use yii_app\records\Products1c;
- new \yii\data\ArrayDataProvider([ - 'allModels' => $shiftTransfer->shiftRemains - ]), -// 'showFooter' => true, - 'columns' => [ - [ - 'attribute' => 'group_label', - 'label' => 'Название группы', -// 'footer' => 'Итого:', - 'pageSummary' => 'Итого:', - 'value' => function($data) { - return ProductsClass::getHints()[$data['group_label']] ?? ''; - }, - ], - [ - 'attribute' => 'product_guid', - 'label' => 'Продукт', - 'value' => function($data) { - $productsClass = ProductsClass::find()->select('category_id') - ->where(['tip' => $data['group_label'] ?? null])->column(); - - $products = ArrayHelper::map(Products1c::find()->select(['id', 'name']) - ->where(['parent_id' => $productsClass])->all(), 'id', 'name'); - - return $products[$data['product_guid']] ?? ''; - }, - ], - [ - 'attribute' => 'retail_price', - 'label' => 'Розничная цена, руб', - 'value' => function($data) { - return $data['retail_price'] ?? ''; - }, - ], - [ - 'attribute' => 'self_cost', - 'label' => 'Себестоимость, руб', -// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'self_cost')), - 'pageSummary' => true, - 'value' => function($data) { - return $data['self_cost'] ?? ''; - }, - ], - [ - 'attribute' => 'remains_summ', - 'label' => 'Сумма остатков (недостача или излишек), руб', - 'pageSummary' => true, -// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'remains_summ')), - 'value' => function($data) { - return $data['remains_summ'] ?? ''; - }, - ], - [ - 'attribute' => 'remains_count', - 'label' => 'Фактические остатки кол-во, шт', - 'pageSummary' => true, -// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'remains_count')), - 'value' => function($data) { - return $data['remains_count'] ?? ''; - }, - ], - [ - 'attribute' => 'fact_and_1c_diff', - 'label' => 'Разница факт и по программе 1с, шт', - 'pageSummary' => true, -// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'fact_and_1c_diff')), - 'value' => function($data) { - return $data['fact_and_1c_diff'] ?? ''; - }, - ], - [ - 'attribute' => 'remains_1c', - 'label' => 'Остатки по 1с, шт', - 'pageSummary' => true, -// 'footer' => array_sum(array_column($shiftTransfer->shiftRemains, 'remains_1c')), - 'value' => function($data) { - return $data['remains_1c'] ?? ''; - }, - ], - ], - 'showPageSummary' => true, + render('_transfer', [ + 'shiftTransfer' => $shiftTransfer, ]); ?>
+
+
+ render('_replacement', [ + 'shiftTransfer' => $shiftTransfer, + 'controlerId' => $shiftTransfer->start_shift_admin_id, + 'status' => $shiftTransfer->status_id, + 'isAcceptance' => $isAcceptance, + ]) + ?> +
+
-- 2.39.5