$model = BouquetComposition::findModel($id);
if (Yii::$app->request->isPost && $products = Yii::$app->request->post('products_quantity')) {
+ $cost = Yii::$app->request->post('cost-value');
+ $model->setCost($cost);
BouquetCompositionProducts::updateProducts($model->id, $products);
return $this->redirect(['view', 'id' => $id]);
}
]);
}
- public function actionGetCalculates()
+ public function actionDefaultCalculates()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$data = json_decode(Yii::$app->request->getRawBody(), true);
- $model = new BouquetComposition();
+ $model = BouquetComposition::findOne($data['bouquetId']);
return [
'selfcost' => round($model->getSelfCost($data), 2),
- 'cost' => round($model->getCost($data), 2),
- 'markup' => $model->getMarkUp($data),
+ 'cost' => round($model->getBouquetCost($data), 2),
+ 'markup' => round($model->getBouquetCostMarkup($data), 2),
];
}
return $this->redirect(Yii::$app->request->referrer);
}
-}
\ No newline at end of file
+}
return $this->hasMany(BouquetForecast::class, ['bouquet_id' => 'id']);
}
- /**
- * Рассчитывает стоимость букета.
- *
- * @param array|null $data Данные продуктов (опционально)
- * @return float Стоимость
- */
- public function getCost(?array $data = null): float
- {
- $cost = 0;
- $compositionProducts = $this->bouquetCompositionProducts;
-
- if (!$compositionProducts) {
- $compositionProducts = $data;
- if (empty($data)) {
- return $cost;
- }
- }
-
- foreach ($compositionProducts as $item) {
- if (!$item || !isset($item['product_guid'])) {
- continue;
- }
-
- $priceModel = PricesDynamic::find()
- ->where(['product_id' => $item['product_guid']])
- ->andWhere(['=', 'active', PricesDynamic::ACTIVE])
- ->one();
-
- if ($priceModel) {
- $cost += $priceModel->price * $item['count'];
- }
+// /**
+// * Рассчитывает стоимость букета.
+// *
+// * @param array|null $data Данные продуктов (опционально)
+// * @return float Стоимость
+// */
+// public function getCost(?array $data = null): float
+// {
+// $cost = 0;
+// $compositionProducts = $this->bouquetCompositionProducts;
+//
+// if (!$compositionProducts) {
+// $compositionProducts = $data;
+// if (empty($data)) {
+// return $cost;
+// }
+// }
+//
+// foreach ($compositionProducts as $item) {
+// if (!$item || !isset($item['product_guid'])) {
+// continue;
+// }
+//
+// $priceModel = PricesDynamic::find()
+// ->where(['product_id' => $item['product_guid']])
+// ->andWhere(['=', 'active', PricesDynamic::ACTIVE])
+// ->one();
+//
+// if ($priceModel) {
+// $cost += $priceModel->price * $item['count'];
+// }
+// }
+//
+// return $cost;
+// }
+
+ public function setCost($cost) {
+ $priceModel = PricesDynamic::find()
+ ->where(['product_id' => $this->guid])
+ ->andWhere(['=', 'active', PricesDynamic::ACTIVE])
+ ->one();
+ /* @var PricesDynamic $priceModel */
+ if ($priceModel) {
+ $priceModel->date_to = date('Y-m-d H:i:s');
+ $priceModel->active = PricesDynamic::NOT_ACTIVE;
+ $priceModel->save();
}
+ $newPriceDynamic = new PricesDynamic;
+ $newPriceDynamic->product_id = $this->guid;
+ $newPriceDynamic->active = PricesDynamic::ACTIVE;
+ $newPriceDynamic->date_from = date('Y-m-d H:i:s');
+ $newPriceDynamic->date_to = date('2100-01-01 00:00:00');
+ $newPriceDynamic->price = $cost;
+ $newPriceDynamic->save();
+ }
- return $cost;
+ public function getBouquetCost($data = null) {
+ $priceModel = PricesDynamic::find()
+ ->where(['product_id' => $this->guid])
+ ->andWhere(['=', 'active', PricesDynamic::ACTIVE])
+ ->one();
+ /* @var PricesDynamic $priceModel */
+ return $priceModel ? $priceModel->price : $this->getSelfCost($data) * 1.3 * 1.15;
}
- /**
- * Рассчитывает наценку на букет.
- *
- * @param array|null $data Данные продуктов (опционально)
- * @return string Наценка в формате "+X.XX% / +X.XX"
- */
- public function getMarkUp(?array $data = null): string
- {
+ public function getBouquetCostMarkup($data = null) {
$selfCost = $this->getSelfCost($data);
- $cost = $this->getCost($data);
-
- if ($selfCost == 0 || $cost == 0) {
- return '0';
- }
-
- return sprintf("+%.2f%% / +%.2f",
- ($cost / $selfCost - 1) * 100,
- $cost - $selfCost
- );
+ return $selfCost > 0 ? ($this->getBouquetCost($data) / (1.3 * $selfCost) - 1) * 100 : 0;
}
+// /**
+// * Рассчитывает наценку на букет.
+// *
+// * @param array|null $data Данные продуктов (опционально)
+// * @return string Наценка в формате "+X.XX% / +X.XX"
+// */
+// public function getMarkUp(?array $data = null): string
+// {
+// $selfCost = $this->getSelfCost($data);
+// $cost = $this->getCost($data);
+//
+// if ($selfCost == 0 || $cost == 0) {
+// return '0';
+// }
+//
+// return sprintf("+%.2f%% / +%.2f",
+// ($cost / $selfCost - 1) * 100,
+// $cost - $selfCost
+// );
+// }
+
/**
* Рассчитывает себестоимость букета.
*
class PricesDynamic extends \yii\db\ActiveRecord
{
public const ACTIVE = 1;
+ public const NOT_ACTIVE = 0;
/**
* {@inheritdoc}
*/
use yii\helpers\Html;
use yii_app\records\BouquetComposition;
+$this->registerCSS('.cost-value {max-width: 75px}');
+
?>
<?= DualList::widget([
'name' => 'products',
<div class="spinner-border text-primary" role="status"></div>
</div>
<p class="mb-1"><strong>Себестоимость:</strong> <span class="selfcost-value"><?= $selfCost ?? 0 ?></span> ₽</p>
- <p class="mb-1"><strong>Наценка:</strong> <span class="markup-value"><?= $markUp ?? 0 ?></span></p>
- <p class="mb-0"><strong>Цена:</strong> <span class="cost-value"><?= $cost ?? 0 ?></span> ₽</p>
+ <p class="mb-1"><strong>Наценка:</strong> +30% / +<span class="markup-value"><?= 0.3 * ($selfCost ?? 0) ?></span>₽</p>
+ <p class="mb-0"><strong>Цена:</strong> <input type="number" name="cost-value" class="cost-value" value="<?= $cost ?>"
+ min="<?= 1.3 * ($selfCost ?? 0) ?>" />₽. +<span class="markup-cost-value"><?= $markUp ?></span>%</p>
</div>
</div>
<div class="col-md-8">
<strong>Нижегородская область</strong>
<div class='self-cost pt-3' style='display: flex; gap: 10px;'>
- Себестоимость: <?= $model->getSelfCost() ?> <br>
- Наценка: <?= $model->getMarkUp() ?> <br>
- Цена: <?= $model->getCost() ?><br>
+ Себестоимость: <?= $model->getSelfCost() ?><br>
+ Наценка: +30% / +<?= (0.3 * $model->getSelfCost()) ?><br>
+ Цена: <?= $model->getBouquetCost() ?>р. +<?= $model->getBouquetCostMarkup() ?>%<br>
</div>
</div>
<div class="col-md-4">
</div>
<div class='self-cost pt-3' style='display: flex; gap: 10px;'>
Себестоимость: " . $model->getSelfCost() . "<br>
- Наценка: " . $model->getMarkUp() . "<br>
- Цена: " . $model->getCost() . "<br>
+ Наценка: +30% / +" . (0.3 * $model->getSelfCost()) . "<br>
+ Цена: " . $model->getBouquetCost() . "р. +" . $model->getBouquetCostMarkup() . "%<br>
</div>
</div>
$this->params['breadcrumbs'][] = ['label' => 'Букеты', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
+$this->registerJSVar('bouquetId', $model->id);
$this->registerJsFile('/js/bouquet/bouquet.js', ['position' => \yii\web\View::POS_END]);
?>
'isCreate' => false,
'listContainerSize' => [],
'selfCost' => $model->getSelfCost(),
- 'cost' => $model->getCost(),
- 'markUp' => $model->getMarkUp(),
+ 'cost' => $model->getBouquetCost(),
+ 'markUp' => $model->getBouquetCostMarkup(),
]); ?>
<?php ActiveForm::end(); ?>
</div>
\ No newline at end of file
+/* jshint esversion: 6 */
+
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.video-preview').forEach(video => {
video.addEventListener('click', function () {
});
$(document).on('click', '.calculate-btn, .btn-add-item, .btn-remove-item', function () {
- $('.cost-value, .selfcost-value, .markup-value').text('');
+ $('.cost-value, .selfcost-value, .markup-value, .markup-cost-value').text('');
});
$(document).on('input change', '.quantity-input', function () {
});
+$('.cost-value').on('change', function () {
+ const selfCost = $('.selfcost-value');
+ $('.markup-cost-value').text(+selfCost.text() > 0 ? Math.round((this.value / (1.3 * (+selfCost.text())) - 1)*10000) / 100 : 0);
+});
+
$('.calculate-btn').on('click', function () {
let data = [];
$(".content-wrapper").addClass("position-relative");
$.ajax({
- url: '/bouquet/get-calculates',
+ url: '/bouquet/default-calculates',
type: 'POST',
contentType: 'application/json',
- data: JSON.stringify(data),
+ data: JSON.stringify({ data, bouquetId }),
dataType: 'json',
success: function (response) {
if (response) {
if (response.cost !== undefined) {
- $('.cost-value').text(response.cost);
+ $('.cost-value').val(+response.cost);
}
if (response.selfcost !== undefined) {
$('.selfcost-value').text(response.selfcost);
+ $('.markup-value').text(0.3 * (+response.selfcost));
+ $('.cost-value').attr('min', 1.3 * (+response.selfcost));
}
if (response.markup !== undefined) {
- $('.markup-value').text(response.markup);
+ $('.markup-cost-value').text(+response.markup);
}
}
},