HEX
Server: LiteSpeed
System: Linux premium260.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
User: aliazzsr (627)
PHP: 7.4.33
Disabled: NONE
Upload Files
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")
 *       )
 *     }
 * )
 */