File: //home/aliazzsr/api.crm.vqode.com/models/core/Project.php
<?php
namespace app\models\core;
use app\components\BaseModel;
use app\components\helpers\ValueHelper;
use app\models\enums\CompanyProjectRelType;
use app\models\enums\StageEnum;
use app\components\formatters\DateFormatter;
use app\models\forms\RelatedCompany;
use yii\behaviors\AttributeTypecastBehavior;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveQuery;
/**
* Class Project
* @package app\models\core
* @property integer $id unique identifier
* @property string $created
* @property string $revised
*/
class Project extends BaseModel
{
/** @var array */
public $relatedCompanies;
/** @var RelatedCompany[] */
public $_companies;
/** @inheritdoc */
protected static $attributesToRefresh = [
'created',
];
protected static $safeAttributes = [
'name', 'revised', 'latest_revision', 'riba_id', 'location',
'street', 'building_no', 'city', 'country', 'postcode', 'sector_id',
'stage_id', 'number', 'responsible_office', 'office_postcode', 'value', 'edv',
'order_at', 'next_action_at', 'efv', 'notes', 'owner_id', 'reference',
'longitude', 'latitude', 'priority_id',
'relatedCompanies',
];
public static $extraFields = [
'companies',
'companyProjects',
'contacts',
'creator',
'primaryCompany',
'priority',
'riba',
'sector',
'stage',
'owner',
];
public static function findWithJoin()
{
return parent::find()
->joinWith([
'sector as sector',
'riba as riba',
'stage as stage',
'creator as creator',
'owner as owner',
]);
}
public static function tableName()
{
return 'project';
}
public function rules()
{
return [
[['name', 'sector_id', 'value', 'edv', 'efv', 'stage_id',], 'required'],
[[
'name', 'latest_revision', 'location', 'building_no', 'street', 'city', 'country',
'postcode', 'number', 'responsible_office', 'office_postcode', 'notes',
], 'string', 'max' => 255],
[['stage_id'], 'default', 'value' => StageEnum::ST_IDEA],
[['revised', 'order_at', 'next_action_at'], 'date', 'format' => 'php:d/m/Y', 'message' => 'Date should be in format DD/MM/YYYY',],
[['value', 'edv', 'efv',], 'double', 'min' => 0],
[['riba_id'], 'exist', 'targetClass' => 'app\models\core\Riba', 'targetAttribute' => 'id'],
[['stage_id'], 'exist', 'targetClass' => 'app\models\core\Stage', 'targetAttribute' => 'id'],
[['sector_id'], 'exist', 'targetClass' => 'app\models\core\Sector', 'targetAttribute' => 'id'],
[['owner_id'], 'exist', 'targetClass' => 'app\models\core\User', 'targetAttribute' => 'id'],
[self::$safeAttributes, 'safe'],
[
'name',
'unique',
'message' => 'A duplicate project with the same name has been found',
'on' => self::SCENARIO_STRICT_VALIDATE,
],
];
}
/** @todo is it ok? */
public function safeAttributes()
{
return self::$safeAttributes;
}
public function behaviors()
{
$projectBehaviors = [
'project_created' => [
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created',
'updatedAtAttribute' => null,
'value' => ValueHelper::now(),
],
'typecast' => [
'class' => AttributeTypecastBehavior::className(),
'attributeTypes' => [
'sector_id' => AttributeTypecastBehavior::TYPE_INTEGER,
'stage_id' => AttributeTypecastBehavior::TYPE_INTEGER,
'riba_id' => AttributeTypecastBehavior::TYPE_INTEGER,
'value' => AttributeTypecastBehavior::TYPE_FLOAT,
'edv' => AttributeTypecastBehavior::TYPE_FLOAT,
'efv' => AttributeTypecastBehavior::TYPE_FLOAT,
],
'typecastAfterValidate' => true,
'typecastBeforeSave' => true,
'typecastAfterFind' => true,
],
'typecast_afterFind' => [
'class' => AttributeTypecastBehavior::className(),
'attributeTypes' => [
'created' => ['app\components\formatters\DateFormatter', 'toString'],
'revised' => ['app\components\formatters\DateFormatter', 'toString'],
'order_at' => ['app\components\formatters\DateFormatter', 'toString'],
'next_action_at' => ['app\components\formatters\DateFormatter', 'toString'],
],
'typecastAfterValidate' => false,
'typecastBeforeSave' => false,
'typecastAfterFind' => true,
],
'typecast_beforeSave' => [
'class' => AttributeTypecastBehavior::className(),
'attributeTypes' => [
'created' => ['app\components\formatters\DateFormatter', 'toMysql'],
'revised' => ['app\components\formatters\DateFormatter', 'toMysql'],
'order_at' => ['app\components\formatters\DateFormatter', 'toMysql'],
'next_action_at' => ['app\components\formatters\DateFormatter', 'toMysql'],
],
'typecastAfterValidate' => false,
'typecastBeforeSave' => true,
'typecastAfterFind' => false,
],
];
return array_merge(parent::behaviors(), $projectBehaviors);
}
public function beforeSave($insert)
{
$this->_companies = [];
if (!empty($this->relatedCompanies) && is_array($this->relatedCompanies)) {
foreach ($this->relatedCompanies as $company) {
$relCompany = new RelatedCompany();
$relCompany->load($company);
if (!$relCompany->validate()) {
$errors = $relCompany->getFirstErrors();
$this->addError('companies', reset($errors));
return false;
}
$this->_companies[] = $relCompany;
}
}
return parent::beforeSave($insert);
}
/**
* @inheritdoc
* @throws
*/
public function save($runValidation = true, $attributeNames = null)
{
$transaction = static::getDb()->beginTransaction();
if (!parent::save($runValidation, $attributeNames)) {
$transaction->rollBack();
return false;
}
if (!empty($this->_companies)) {
CompanyProject::deleteAll(['project_id' => $this->id]);
foreach ($this->_companies as $_i => $company) {
$company->project_id = $this->id;
if (!$company->save()) {
$errors = $company->getFirstErrors();
$this->addError('companies', "Company #{$_i}: " . reset($errors));
$transaction->rollBack();
return false;
}
}
}
$transaction->commit();
return true;
}
/**
* @inheritdoc
*/
public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
$this->created = $this->created ? DateFormatter::toString($this->created) : null;
$this->revised = $this->revised ? DateFormatter::toString($this->revised) : null;
}
public function attributeLabels()
{
return [
'name' => 'Project name',
'latest_revision' => 'Latest revision',
'riba_id' => 'RIBA plan of work',
'location' => 'Project location',
'street' => 'Street name',
'building_no' => 'Building no. or name',
'postcode' => 'Project postcode',
'sector_id' => 'Project sector',
'number' => 'Project number',
'responsible_office' => 'Responsible office',
'office_postcode' => 'Office postcode',
'value' => 'Project value',
'edv' => 'Estimated drywall value',
'stage_id' => 'Stage',
'owner_id' => 'Owner',
];
}
/**
* @return \yii\db\ActiveQuery
*/
public function getSector()
{
return $this->hasOne(Sector::className(), ['id' => 'sector_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getCreator()
{
return $this->hasOne(User::className(), ['id' => 'created_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getOwner()
{
return $this->hasOne(User::className(), ['id' => 'owner_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getRiba()
{
return $this->hasOne(Riba::className(), ['id' => 'riba_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getStage()
{
return $this->hasOne(Stage::className(), ['id' => 'stage_id']);
}
/**
* @return ActiveQuery
*/
public function getCompanies()
{
return $this->hasMany(Company::className(), ['id' => 'company_id'])
->viaTable(CompanyProject::tableName(), ['project_id' => 'id']);
}
/**
* @return ActiveQuery
*/
public function getCompanyProjects()
{
return $this->hasMany(CompanyProject::className(), ['project_id' => 'id']);
}
/**
* @return ActiveQuery
*/
public function getPrimaryCompany()
{
return $this->hasOne(Company::className(), ['id' => 'company_id'])
->viaTable(CompanyProject::tableName(), ['project_id' => 'id'], function($query) {
/** @var ActiveQuery $query */
$query->andWhere(['reltype_id' => CompanyProjectRelType::PRIMARY]);
});
}
/**
* @return ActiveQuery
*/
public function getContacts()
{
return $this->hasMany(CompanyContact::className(), ['id' => 'contact_id'])
->viaTable(ProjectContact::tableName(), ['project_id' => 'id']);
}
/**
* @return ActiveQuery
*/
public function getPriority()
{
return $this->hasOne(Priority::className(), ['id' => 'priority_id']);
}
public function beforeDelete()
{
if (!parent::beforeDelete()) {
return false;
}
$isValid = true;
try {
ProjectContact::deleteAll(['project_id' => $this->id]);
CompanyProject::deleteAll(['project_id' => $this->id]);
} catch (\Throwable $e) {
$isValid = false;
}
return $isValid;
}
public function transactions()
{
return [
self::SCENARIO_DEFAULT => self::OP_DELETE,
];
}
}
/**
* @SWG\Definition(
* definition="Project",
* type="object",
* description="Project model",
* allOf={
* @SWG\Schema(
* required={"name", "sector_id", "stage_id", "value", "edv", "efv"},
* @SWG\Property(property="id", type="integer", example=7),
* @SWG\Property(property="name", type="string", example="Howe PLC"),
* @SWG\Property(property="created", type="string", example="23/03/2018", description="Filled automatically with the date record created, readonly"),
* @SWG\Property(property="revised", type="string", example="25/03/2018"),
* @SWG\Property(property="latest_revision", type="string", example="12"),
* @SWG\Property(property="riba_id", type="integer", example=3),
* @SWG\Property(property="location", type="string", example="5765 Jordane Freeway Suite 517"),
* @SWG\Property(property="longitude", type="double", example=0.12345, description="Project location, longitude"),
* @SWG\Property(property="latitude", type="double", example=-51.5083896, description="Project location, latitude"),
* @SWG\Property(property="street", type="string", example="164 Jessika Circles"),
* @SWG\Property(property="building_no", type="string", example="222b"),
* @SWG\Property(property="city", type="string", example="Glenville"),
* @SWG\Property(property="country", type="string", example="UK"),
* @SWG\Property(property="postcode", type="string", example="SW10 0XF"),
* @SWG\Property(property="sector_id", type="integer", example=3),
* @SWG\Property(property="stage_id", type="integer", example=3, description="Project stage, 1 by default (Idea)"),
* @SWG\Property(property="number", type="string", example="124/4"),
* @SWG\Property(property="responsible_office", type="string", example="BDP, Ducie Street, Manchester"),
* @SWG\Property(property="office_postcode", type="string"),
* @SWG\Property(property="value", type="float", example=123420440.00),
* @SWG\Property(property="edv", type="float", example=12342.44),
* @SWG\Property(property="order_at", type="string", example="29/04/2018", description="Order date"),
* @SWG\Property(property="priority_id", type="integer", example=2, description="Priority identifier"),
* @SWG\Property(property="next_action_at", type="string", example="30/04/2018", description="Next action date"),
* @SWG\Property(property="efv", type="float", example=125.00, description="Estimated flooring value"),
* @SWG\Property(property="reference", type="string", example="", description="External reference (SAP Reference, for example)"),
* @SWG\Property(property="owner_id", type="integer", example=34, description="Project owner"),
* @SWG\Property(property="notes", type="string", example="Tempore qui velit voluptatum vel quasi commodi", description="Project notes")
* )
* }
* )
*/