/
chieforik
/
AgroPro
Обзор
Документация
Войти
/
chieforik
/
AgroPro
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
models/Field.php
290 строк
8 KB
Орловский Александр
Первый
25 сен 2025, 02:26
25 сен 2025, 02:26
1567008
Код
Авторство
О чём код?
<?php namespace app\models; use Yii; /** * This is the model class for table "field". * * @property int $id * @property int $user_id ID пользователя * @property string $name Название поля * @property string $district Район * @property string $desired_culture Желаемая культура * @property string $area Площадь поля (га) * @property string $soil_type Тип почвы * @property string|null $nitrogen_content Содержание азота (мг/кг) * @property string|null $phosphorus_content Содержание фосфора (мг/кг) * @property string|null $potassium_content Содержание калия (мг/кг) * @property string|null $humus_content Содержание гумуса (%) * @property string|null $ph_level Уровень pH * @property string|null $predecessor Предшественник * @property string|null $notes Примечания * @property int $created_at Дата создания * @property int $updated_at Дата обновления * * @property User $user * @property FertilizerNorms $fertilizerNorms */ class Field extends \yii\db\ActiveRecord { const DISTRICTS = [ 'Курганский' => 'Курганский', 'Шадринский' => 'Шадринский', 'Кетовский' => 'Кетовский', 'Целинный' => 'Целинный', ]; const SOIL_TYPES = [ 'Чернозем' => 'Чернозем', 'Супесчаная' => 'Супесчаная', 'Суглинистая' => 'Суглинистая', 'Глинистая' => 'Глинистая', 'Торфяная' => 'Торфяная', ]; /** * {@inheritdoc} */ public static function tableName() { return '{{%field}}'; } /** * {@inheritdoc} */ public function rules() { return [ [['user_id', 'name', 'district', 'desired_culture', 'area', 'soil_type'], 'required'], [['user_id', 'created_at', 'updated_at'], 'integer'], [['area', 'nitrogen_content', 'phosphorus_content', 'potassium_content', 'humus_content', 'ph_level'], 'number', 'min' => 0], [['notes'], 'string'], [['name', 'desired_culture'], 'string', 'max' => 150], [['district', 'soil_type', 'predecessor'], 'string', 'max' => 100], [['ph_level'], 'number', 'min' => 0, 'max' => 14], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'user_id' => 'Пользователь', 'name' => 'Название поля', 'district' => 'Район', 'desired_culture' => 'Желаемая культура', 'area' => 'Площадь (га)', 'soil_type' => 'Тип почвы', 'nitrogen_content' => 'Азот (мг/кг)', 'phosphorus_content' => 'Фосфор (мг/кг)', 'potassium_content' => 'Калий (мг/кг)', 'humus_content' => 'Гумус (%)', 'ph_level' => 'Уровень pH', 'predecessor' => 'Предшественник', 'notes' => 'Примечания', 'created_at' => 'Дата создания', 'updated_at' => 'Дата обновления', ]; } /** * {@inheritdoc} */ public function behaviors() { return [ 'timestamp' => [ 'class' => \yii\behaviors\TimestampBehavior::className(), 'createdAtAttribute' => 'created_at', 'updatedAtAttribute' => 'updated_at', ], ]; } /** * @return \yii\db\ActiveQuery */ public function getUser() { return $this->hasOne(User::className(), ['id' => 'user_id']); } /** * @return \yii\db\ActiveQuery */ public function getFertilizerNorms() { return $this->hasOne(FertilizerNorms::className(), [ 'district' => 'district', 'culture' => 'desired_culture' ]); } /** * @return array */ public function getAvailableCultures() { return FertilizerNorms::find() ->select('culture') ->where(['district' => $this->district]) ->indexBy('culture') ->column(); } /** * @return array|null */ public function getRecommendedNorms() { if ($this->fertilizerNorms) { return [ 'n' => (float)$this->fertilizerNorms->n_kg_ha, 'p2o5' => (float)$this->fertilizerNorms->p2o5_kg_ha, 'k2o' => (float)$this->fertilizerNorms->k2o_kg_ha, 'basis' => $this->fertilizerNorms->recommendation_basis, ]; } return null; } /** * @return array|null */ public function calculateFertilizerCost() { $norms = $this->getRecommendedNorms(); if (!$norms) { return null; } return FertilizerNorms::calculateFertilizerCost( $this->district, $this->desired_culture, $this->area ); } /** * @return float */ public function getYieldForecast() { $baseYield = 2.5; $nFactor = $this->nitrogen_content ? $this->nitrogen_content / 20 : 1; $pFactor = $this->phosphorus_content ? $this->phosphorus_content / 15 : 1; $kFactor = $this->potassium_content ? $this->potassium_content / 15 : 1; $yield = $baseYield * min($nFactor, $pFactor, $kFactor); return round($yield, 2); } /** * @return int */ public function getCompletionRate() { $totalFields = 10; $filledFields = 0; $filledFields += 4; if (!empty($this->nitrogen_content)) $filledFields++; if (!empty($this->phosphorus_content)) $filledFields++; if (!empty($this->potassium_content)) $filledFields++; if (!empty($this->humus_content)) $filledFields++; if (!empty($this->ph_level)) $filledFields++; if (!empty($this->predecessor)) $filledFields++; return min(100, round(($filledFields / $totalFields) * 100)); } /** * @return string */ public function getCompletionStatus() { $rate = $this->getCompletionRate(); if ($rate >= 80) return 'complete'; if ($rate >= 50) return 'partial'; return 'empty'; } /** * @return string */ public function getCompletionStatusText() { $status = $this->getCompletionStatus(); switch ($status) { case 'complete': return 'Готово'; case 'partial': return 'Частично'; default: return 'Требует данных'; } } /** * @return string */ public function getCompletionStatusClass() { $status = $this->getCompletionStatus(); switch ($status) { case 'complete': return 'bg-success'; case 'partial': return 'bg-warning'; default: return 'bg-danger'; } } /** * @return array */ public function getDashboardData() { return [ 'id' => $this->id, 'name' => $this->name, 'district' => $this->district, 'culture' => $this->desired_culture, 'area' => Yii::$app->formatter->asDecimal($this->area), 'completionRate' => $this->getCompletionRate(), 'status' => $this->getCompletionStatus(), 'statusText' => $this->getCompletionStatusText(), 'statusClass' => $this->getCompletionStatusClass(), ]; } public function getCalculations() { return $this->hasMany(FieldCalculation::class, ['field_id' => 'id'])->orderBy(['created_at' => SORT_DESC]); } /** * @return FieldCalculation|null */ public function getLastCalculation() { return $this->getCalculations()->one(); } public function getMaxProfit() { $calculation = $this->getLastCalculation(); return $calculation ? $calculation->total_profit : null; } public function getRecommendedCrop() { $calculation = $this->getLastCalculation(); return $calculation ? $calculation->best_crop : null; } }