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;
}
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) {
'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('Автор создания записи'),
--- /dev/null
+<?php
+
+namespace yii_app\records;
+
+use Yii;
+use yii\behaviors\BlameableBehavior;
+use yii\behaviors\TimestampBehavior;
+use yii\data\ActiveDataProvider;
+use yii\db\Expression;
+
+/**
+ * This is the model class for table "equalization_remains".
+ *
+ * @property int $id ID записи
+ * @property int $shift_id ID записи передачи смены
+ * @property string $product_id ID товара с недостатком
+ * @property float $product_count Количество товара с недостатком
+ * @property float $product_price Цена товара розничная
+ * @property float $product_price_self_cost Себестоимость товара
+ * @property string $product_replacement_id Товар замена
+ * @property float $product_replacement_count Количество товара замены
+ * @property float $product_replacement_price Цена товара замены розничная
+ * @property float $product_replacement_price_self_cost Себестоимость товара замены
+ * @property float $balance Разница в сумме
+ * @property float $balance_self_cost Разница в сумме (Себестоиомость)
+ * @property string $created_at Дата создания записи
+ * @property string $updated_at Дата обновления записи
+ * @property int $created_by Автор создания записи
+ * @property int $updated_by Автор обновления записи
+ */
+class EqualizationRemains extends \yii\db\ActiveRecord
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function tableName()
+ {
+ return 'equalization_remains';
+ }
+
+
+ public function behaviors()
+ {
+ return [
+ [
+ 'class' => 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']);
+ }
+
+}
* @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}
*/
[['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],
];
}
'remains_count' => 'Remains Count',
'fact_and_1c_diff' => 'Fact And 1c Diff',
'remains_1c' => 'Remains 1c',
+ 'type' => 'Тип записи',
];
}
}
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']);
+ }
}
--- /dev/null
+<?php
+
+use unclead\multipleinput\components\BaseColumn;
+use unclead\multipleinput\MultipleInput;
+use yii\helpers\Html;
+use yii_app\records\ShiftTransfer;
+use yii\widgets\ActiveForm;
+
+/* @var $shiftTransfer ShiftTransfer */
+/* @var $storeNameById array */
+/* @var $admins array */
+/* @var $isAcceptance bool */
+
+
+$isAcceptance = false;
+$btn = '';
+if ($isAcceptance) {
+//if ($isAcceptance && Yii::$app->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;
--- /dev/null
+<?php
+
+use yii\helpers\ArrayHelper;
+use yii_app\records\Products1c;
+use yii_app\records\ProductsClass;
+
+?>
+<?= \kartik\grid\GridView::widget([
+ 'dataProvider' => 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
/* @var $shiftTransfer ShiftTransfer */
/* @var $storeNameById array */
/* @var $admins array */
+/* @var $isAcceptance bool */
?>
<div class="row">
<div class="col-12">
- <?= \kartik\grid\GridView::widget([
- 'dataProvider' => 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,
+ <?= $this->render('_transfer', [
+ 'shiftTransfer' => $shiftTransfer,
]); ?>
</div>
</div>
+ <div class="row">
+ <div class="col-12">
+ <?= $this->render('_replacement', [
+ 'shiftTransfer' => $shiftTransfer,
+ 'controlerId' => $shiftTransfer->start_shift_admin_id,
+ 'status' => $shiftTransfer->status_id,
+ 'isAcceptance' => $isAcceptance,
+ ])
+ ?>
+ </div>
+ </div>
</div>