/** * Пошук із врахування зовнішніх реляційних відношень. * Enjoy this code with smiles / %) %) %) /. * @param bool $return_array_of_models default false * @return \CActiveDataProvider */ public function search_rel($return_array_of_models = false) { Yii::import('application.models.Qualifications'); $rating_order_mode = 0; $page_size = 3; if (is_numeric($this->rating_order_mode)) { $rating_order_mode = $this->rating_order_mode; } if (is_numeric($this->page_size) && $this->page_size > 0) { $page_size = $this->page_size; } $criteria = new CDbCriteria(); //З якими відношеннями маємо справу $with_rel = array(); array_push($with_rel, 'sepciality'); array_push($with_rel, 'person'); array_push($with_rel, 'olymp'); array_push($with_rel, 'entrantdoc'); array_push($with_rel, 'educationForm'); array_push($with_rel, 'edbo'); array_push($with_rel, 'documentSubject1'); array_push($with_rel, 'documentSubject2'); array_push($with_rel, 'documentSubject3'); array_push($with_rel, 'documentSubject1.subject1'); array_push($with_rel, 'documentSubject2.subject2'); array_push($with_rel, 'documentSubject3.subject3'); //array_push($with_rel, 'ZnoKoef1'); //array_push($with_rel, 'ZnoKoef2'); //array_push($with_rel, 'ZnoKoef3'); $with_rel['sepciality.facultet'] = array('select' => false); $with_rel['person.country'] = array('select' => false); $with_rel['status'] = array('select' => false); $with_rel['pbenefits'] = array('select' => false); $with_rel['pbenefits.psbenefit'] = array('select' => false); $with_rel['pbenefits.psbenefit.benefit'] = array('select' => false); $criteria->with = $with_rel; //також йде вибірка :: // ПІБ персон і спеціальності, // формат поля спеціальності: (( код_спеціальності назва_спеціальності[ (назва_напряму)] , форма: назва_форми )) // загальна сума балів для рейтингу, // кількість пільг, // список назв пільг (являє собою рядок із сепаратором : ";;"), // список ID пільг (являє собою рядок із сепаратором : ";;"), // список значень у документах (поле : AtestatValue, являє собою рядок із сепаратором : ";"), // список типів документів (являє собою рядок із сепаратором : ";"), // відмітка про позаконкурсний вступ або ж про те, що є відповідна пільга, // відмітка про першочерговий вступ або ж про те, що є відповідна пільга, // список відміток про позаконкурсний вступ (до відповідних пільг), // список відміток про першочерговий вступ (до відповідних пільг). // Остання редакція: Жиленко О.С. ЕПК $criteria->select = array('*', new CDbExpression("concat_ws(' ',trim(person.LastName),trim(person.FirstName),trim(person.MiddleName)) AS NAME"), new CDbExpression("concat_ws(' '," . "sepciality.SpecialityClasifierCode," . "(case substr(sepciality.SpecialityClasifierCode,1,1) when '6' then " . "sepciality.SpecialityDirectionName else sepciality.SpecialityName end)," . "(case sepciality.SpecialitySpecializationName when '' then '' " . " else concat('(',sepciality.SpecialitySpecializationName,')') end)" . ",',',concat('форма: ',educationForm.PersonEducationFormName)) AS SPEC"), new CDbExpression('ROUND( IF( ISNULL(entrantdoc.AtestatValue), 0.0, IF( t.QualificationID = ' . Qualifications::$bakalavr . ', set_bal(entrantdoc.AtestatValue)* ' . Yii::app()->params['scoreweight_AtestatValue'] . ' , entrantdoc.AtestatValue ) ) ,2) AS ZnoDocValue'), new CDbExpression('ROUND( IF(ISNULL(entrantdoc.AtestatValue),0.0,entrantdoc.AtestatValue),2) AS PointDocValue'), new CDbExpression('(ROUND(( ROUND( IF( ISNULL(entrantdoc.AtestatValue), 0.0, IF( t.QualificationID = ' . Qualifications::$bakalavr . ', set_bal(entrantdoc.AtestatValue)* ' . Yii::app()->params['scoreweight_AtestatValue'] . ' , entrantdoc.AtestatValue ) ),2)+ IF(ISNULL(documentSubject1.SubjectValue),0.0,documentSubject1.SubjectValue*sepciality.ZnoKoef1)+ IF(ISNULL(documentSubject2.SubjectValue),0.0,documentSubject2.SubjectValue*sepciality.ZnoKoef2)+ IF(ISNULL(documentSubject3.SubjectValue),0.0,documentSubject3.SubjectValue*sepciality.ZnoKoef3)+ IF(ISNULL(t.AdditionalBall),0.0,t.AdditionalBall)+ IF(ISNULL(t.CoursedpBall),0.0,t.CoursedpBall* ' . Yii::app()->params['scoreweight_CoursedpBall'] . ')+ IF(ISNULL(olymp.OlympiadAwardBonus),0.0,olymp.OlympiadAwardBonus)+ IF(ISNULL(t.Exam1Ball),0.0,t.Exam1Ball*sepciality.ZnoKoef1)+ IF(ISNULL(t.Exam2Ball),0.0,t.Exam2Ball*sepciality.ZnoKoef2)+ IF(ISNULL(t.Exam3Ball),0.0,t.Exam3Ball*sepciality.ZnoKoef3)),2)) AS ComputedPoints'), new CDbExpression('COUNT(DISTINCT benefit.idBenefit) AS cntBenefit'), new CDbExpression('IF(documentSubject1.SubjectID IN(SELECT ssj.SubjectID FROM specialitysubjects ssj WHERE ssj.isProfile=1 AND ssj.SpecialityID=t.SepcialityID), documentSubject1.SubjectValue, IF(documentSubject2.SubjectID IN(SELECT ssj.SubjectID FROM specialitysubjects ssj WHERE ssj.isProfile=1 AND ssj.SpecialityID=t.SepcialityID), documentSubject2.SubjectValue, IF(documentSubject3.SubjectID IN(SELECT ssj.SubjectID FROM specialitysubjects ssj WHERE ssj.isProfile=1 AND ssj.SpecialityID=t.SepcialityID),documentSubject3.SubjectValue, 0 ) ) ) AS ProfileSubjectValue'), new CDbExpression('GROUP_CONCAT(benefit.BenefitName ' . 'ORDER BY benefit.BenefitName ASC SEPARATOR \';;\') AS BenefitList'), new CDbExpression('GROUP_CONCAT(benefit.idBenefit ' . 'ORDER BY benefit.BenefitName ASC SEPARATOR \';;\') AS idBenefitList'), new CDbExpression('if(sum(benefit.isPZK)>0,1,0) AS isOutOfComp'), new CDbExpression('if(sum(benefit.isPV)>0,1,0) AS isExtraEntry'), new CDbExpression('GROUP_CONCAT(benefit.isPZK ' . 'ORDER BY benefit.BenefitName ASC SEPARATOR \';;\') AS isOutOfCompList'), new CDbExpression('GROUP_CONCAT(benefit.isPV ' . 'ORDER BY benefit.BenefitName ASC SEPARATOR \';;\') AS isExtraEntryList'), new CDbExpression('(SELECT SUM(IF((ISNULL(prsp.isCopyEntrantDoc) OR prsp.isCopyEntrantDoc = 0),1,0)) FROM personspeciality prsp WHERE prsp.PersonID=t.PersonID) AS AnyOriginal'), new CDbExpression('(IF(ISNULL(documentSubject1.SubjectValue),0.0,documentSubject1.SubjectValue)+ IF(ISNULL(documentSubject2.SubjectValue),0.0,documentSubject2.SubjectValue)+ IF(ISNULL(documentSubject3.SubjectValue),0.0,documentSubject3.SubjectValue)) AS ZNOSum'), new CDbExpression('lower(IF(ISNULL(edbo.DocSeria),"none",edbo.DocSeria)) AS tDocSeria'), new CDbExpression('lower(IF(ISNULL(entrantdoc.Series),"none",transliterate(entrantdoc.Series))) AS tDocSeries'), new CDbExpression('CONCAT((CASE t.QualificationID WHEN 1 THEN "Б" WHEN 2 THEN "СМ" WHEN 3 THEN "СМ" WHEN 4 THEN "МС" END), t.CourseID, "-", LPAD(t.PersonRequestNumber,5,"0")) AS PersonCase')); //оформлення єдиного запиту на вибірку $criteria->together = true; //якщо прийшов searchID, то пошукати на співпадання з ID заявки, персони і ЄДЕБО if (is_numeric($this->searchID)) { $criteria->addCondition('(t.idPersonSpeciality=' . $this->searchID . ') ' . 'OR (person.idPerson=' . $this->searchID . ') ' . 'OR (t.edboID=' . $this->searchID . ')'); } else { if (strlen($this->searchID) > 2) { $criteria->compare('status.PersonRequestStatusTypeName', $this->searchID, true); } } //пошук факультету з використанням частини рядка його назви $criteria->compare('facultet.FacultetFullName', $this->searchFaculty->FacultetFullName, true); // Yii::log("abit-ext-param:".$this->ext_param, CLogger::LEVEL_INFO, 'system.db.x'); switch ($this->ext_param) { case 1: //якщо встановлений прапорець, щоб шукати лише неточності (неспівпадання у нас і даними ЄДЕБО) // тоді додаткові умови :: // щоб сума усіх балів не співпадала // щоб ПІБ не співпадало // щоб країна громадянства не співпадала // щоб відмітка у документі (атестат або диплом) не співпадала // щоб номер і серія документа (атестата або диплому) не співпадали // щоб відмітка першочерговості не співпадала // щоб відмітка позаконкурсного вступу не співпадала // щоб відмітка вступу за цільовим направленням не співпадала // щоб відмітка копії/оригінала не співпадала // щоб напрям або спеціальність або форма не співпадали // щоб статус заяви не співпадав // --! щоб серія документа вступу не співпадала // OR (lower(IF(ISNULL(entrantdoc.Series),"none",entrantdoc.Series)) COLLATE utf8_unicode_ci // NOT LIKE lower(IF(ISNULL(edbo.DocSeria),"none",edbo.DocSeria)) COLLATE utf8_unicode_ci) // Qualifications::$bakalavr // Yii::log(" Qualifications::bakalavr:", CLogger::LEVEL_INFO, 'system.db.x'); // Yii::log(" Qualifications::bakalavr:". Qualifications::$bakalavr, CLogger::LEVEL_INFO, 'system.db.x'); $criteria->addCondition(' ( ABS( ( IF( ISNULL(entrantdoc.AtestatValue), 0.0, IF( t.QualificationID = ' . Qualifications::$bakalavr . ', set_bal(entrantdoc.AtestatValue)* ' . Yii::app()->params['scoreweight_AtestatValue'] . ' , entrantdoc.AtestatValue ) ) + IF(ISNULL(documentSubject1.SubjectValue),0.0,documentSubject1.SubjectValue*sepciality.ZnoKoef1)+ IF(ISNULL(documentSubject2.SubjectValue),0.0,documentSubject2.SubjectValue*sepciality.ZnoKoef2)+ IF(ISNULL(documentSubject3.SubjectValue),0.0,documentSubject3.SubjectValue*sepciality.ZnoKoef3)+ IF(ISNULL(t.AdditionalBall),0.0,t.AdditionalBall)+ IF(ISNULL(t.CoursedpBall),0.0,t.CoursedpBall*' . Yii::app()->params['scoreweight_CoursedpBall'] . ')+ IF(ISNULL(olymp.OlympiadAwardBonus),0.0,olymp.OlympiadAwardBonus)+ IF(ISNULL(t.Exam1Ball),0.0,t.Exam1Ball*sepciality.ZnoKoef1)+ IF(ISNULL(t.Exam2Ball),0.0,t.Exam2Ball*sepciality.ZnoKoef2)+ IF( ISNULL(t.Exam3Ball),0.0,t.Exam3Ball*sepciality.ZnoKoef3) ) - edbo.RatingPoints ) > 0.001 OR ( REPLACE( REPLACE( REPLACE( concat_ws(\' \',trim(person.LastName),trim(person.FirstName),trim(person.MiddleName)), " ", " " ), " ", " " ), " ", " " ) NOT LIKE REPLACE( REPLACE( REPLACE( edbo.PIB, " ", " " ), " ", " " ), " ", " " ) ) OR (edbo.Country NOT LIKE country.CountryName) OR (ROUND(edbo.DocPoint,2) <> ROUND( IF(ISNULL(entrantdoc.AtestatValue),0.0,entrantdoc.AtestatValue),2)) OR (edbo.DocNumber NOT LIKE entrantdoc.Numbers) OR (edbo.Benefit <> if(isnull(benefit.isPZK),0,benefit.isPZK)) OR (edbo.PriorityEntry <> if(isnull(benefit.isPV),0,benefit.isPV)) OR (edbo.Quota=0 AND t.QuotaID > 0) OR (edbo.Quota=1 AND (t.QuotaID IS NULL OR t.QuotaID = 0)) OR (edbo.OD=1 AND t.isCopyEntrantDoc=1) OR (edbo.OD=0 AND (t.isCopyEntrantDoc IS NULL OR t.isCopyEntrantDoc = 0)) OR ( (edbo.EduForm NOT LIKE educationForm.PersonEducationFormName) OR (edbo.Direction NOT LIKE sepciality.SpecialityDirectionName AND t.QualificationID = 1) OR (edbo.Speciality NOT LIKE sepciality.SpecialityName AND t.QualificationID > 1) OR (sepciality.SpecialitySpecializationName NOT LIKE CONCAT("%",edbo.Specialization,"%")) ) OR ( MID(status.PersonRequestStatusTypeName,1,6) COLLATE utf8_unicode_ci NOT LIKE MID(edbo.Status,1,6) ) ) AND edbo.ID IS NOT NULL'); break; case 4: //якщо встановлений прапорець, щоб шукати лише неточності в оригіналах // тоді додаткові умови :: // щоб відмітка копії/оригінала не співпадала $criteria->addCondition('( (edbo.OD=1 AND t.isCopyEntrantDoc=1) OR (edbo.OD=0 AND (t.isCopyEntrantDoc IS NULL OR t.isCopyEntrantDoc = 0)))'); break; case 5: //якщо встановлений прапорець, щоб шукати лише неточності в балах // тоді додаткові умови :: // щоб відмітка у документі (атестат або диплом) не співпадала $criteria->addCondition('( (ROUND(edbo.DocPoint,2) <> ROUND( IF(ISNULL(entrantdoc.AtestatValue),0.0,entrantdoc.AtestatValue),2)))'); break; case 6: //якщо встановлений прапорець, щоб шукати лише неточності у відмітках пільгового вступу // тоді додаткові умови :: // ??????щоб відмітка першочерговості не співпадала // щоб відмітка позаконкурсного вступу не співпадала // щоб відмітка вступу за цільовим направленням не співпадала $conditionPart = '( ( edbo.Benefit <> BIT_OR(IFNULL(benefit.isPZK,0)) ) OR (edbo.PriorityEntry <> BIT_OR(IFNULL(benefit.isPV,0)) ) OR (edbo.Quota=0 AND t.QuotaID > 0) OR (edbo.Quota=1 AND (t.QuotaID IS NULL OR t.QuotaID = 0)))'; if (strlen($criteria->having) > 0) { $criteria->having .= ' AND ' . $conditionPart; } else { $criteria->having = $conditionPart; } break; case 7: //якщо встановлений прапорець, щоб шукати лише неточності в сумі балів ЗНО // тоді додаткові умови :: // $criteria->addCondition('( ABS( - SUBSTRING(LEFT(edbo.DetailPoints,LOCATE("+Е:",edbo.DetailPoints)-1),LOCATE("+ЗНО:",edbo.DetailPoints)+5) + ( IF(ISNULL(documentSubject1.SubjectValue),0.0,documentSubject1.SubjectValue*sepciality.ZnoKoef1) + IF(ISNULL(documentSubject2.SubjectValue),0.0,documentSubject2.SubjectValue*sepciality.ZnoKoef2) + IF(ISNULL(documentSubject3.SubjectValue),0.0,documentSubject3.SubjectValue*sepciality.ZnoKoef3) ) ) > 0.001 )'); break; case 8: //якщо встановлений прапорець, щоб шукати лише неточності для країни громадянства // тоді додаткові умови :: // $criteria->addCondition('(edbo.Country NOT LIKE country.CountryName)'); break; //якщо встановлений прапорець, щоб шукати лише неточності для аттестату // Жиленко О.С. //якщо встановлений прапорець, щоб шукати лише неточності для аттестату // Жиленко О.С. case 9: $criteria->addCondition('(entrantdoc.TypeID = 2) AND ' . '(' . '(lower(transliterate(edbo.DocSeria)) <> lower(transliterate(entrantdoc.Series)))' . 'OR (edbo.DocNumber <> entrantdoc.numbers)' . 'OR (ROUND(edbo.DocPoint,2) <> ROUND(IF(ISNULL(entrantdoc.AtestatValue),0.0,entrantdoc.AtestatValue),2))' . 'OR (edbo.DocDate <> STR_TO_DATE(entrantdoc.DateGet, \'%Y/%m/%d\'))' . ')'); break; } if ($rating_order_mode) { //якщо сортувати для рейтингу, тоді відібрати лише потрібні статуси заявок $status_in = '('; $status_ids = array(); if ($this->status_confirmed) { $status_ids[] = '4'; } if ($this->status_committed) { $status_ids[] = '5'; } if ($this->status_submitted) { $status_ids[] = '7'; } $status_in .= implode(',', $status_ids) . ')'; if ($status_in != '()') { $criteria->addCondition('t.StatusID IN ' . $status_in); } else { $criteria->addCondition('t.StatusID IN (1,4,5,7,8)'); } } if ($this->ext_param == 3) { //якщо потрібно вибрати тільки ті дані, що відповідають даним з таблиці edbo_data $criteria->addCondition('edbo.ID IS NOT NULL'); } if ($this->ext_param == 2) { //якщо потрібно вибрати тільки ті дані, що не відповідають даним з таблиці edbo_data $criteria->addCondition('edbo.ID IS NULL'); } if ($this->ForeignOnly) { $criteria->addCondition('country.CountryName NOT LIKE "Україна"'); } if (is_numeric($this->searchBenefit->BenefitName)) { //якщо частина назви пільги - число, то сприймати це як кількість пільг $criteria->having = 'cntBenefit=' . $this->searchBenefit->BenefitName; if ($this->searchBenefit->BenefitName > 1) { $page_size = 1000; } } if (!is_numeric($this->searchBenefit->BenefitName)) { //пошук за частиною назви пільги $criteria->compare('benefit.BenefitName', $this->searchBenefit->BenefitName, true); } if ($this->NAME) { //пошук прізвища $name_keys = explode(' ', $this->NAME); foreach ($name_keys as $key) { $criteria->addCondition('concat_ws(" ",person.LastName,person.FirstName,person.MiddleName) ' . 'LIKE "%' . $key . '%"'); } } if (is_numeric($this->QualificationID) && $this->QualificationID > 0 && !$rating_order_mode) { $criteria->compare('t.QualificationID', $this->QualificationID); } if (is_numeric($this->CourseID) && $this->CourseID > 0 && !$rating_order_mode) { $criteria->compare('t.CourseID', $this->CourseID); } if ($this->DateFrom && $this->DateTo && !$rating_order_mode) { $condition_date1 = date('Y-m-d', strtotime(str_replace('.', '-', $this->DateFrom))) . ' 00:00:00'; $condition_date2 = date('Y-m-d', strtotime(str_replace('.', '-', $this->DateTo))) . ' 23:59:59'; $criteria->addCondition("t.CreateDate BETWEEN '" . $condition_date1 . "' " . "AND '" . $condition_date2 . "'"); } if ($this->SPEC && !$rating_order_mode) { //пошук спеціальності та спеціалізації $keys = explode(' ', $this->SPEC); foreach ($keys as $key) { $criteria->addCondition("concat_ws(' '," . "sepciality.SpecialityClasifierCode," . "(case substr(sepciality.SpecialityClasifierCode,1,1) when '6' then " . "sepciality.SpecialityDirectionName else sepciality.SpecialityName end)," . "(case sepciality.SpecialitySpecializationName when '' then '' " . " else concat('(',sepciality.SpecialitySpecializationName,')') end)" . ",',',concat('форма: ',educationForm.PersonEducationFormName)) LIKE '%" . $key . "%'"); } } else { if ($rating_order_mode) { $criteria->compare("t.SepcialityID", $this->SepcialityID); } } //дані групуються по ІД заявки $criteria->group = "t.idPersonSpeciality"; //параметр сортування даних для формування рейтингу $rating_order = 'isOutOfComp DESC,' . 'IF (t.QuotaID IS NULL, 0, t.QuotaID) DESC,' . 'ComputedPoints DESC,' . 'IF(SUM(benefit.isPV)>0,1,0) DESC, IF(ISNULL(entrantdoc.PersonDocumentsAwardsTypesID),0,10-entrantdoc.PersonDocumentsAwardsTypesID) DESC, ProfileSubjectValue DESC'; //якщо є відмітка першочергового вступу - що ж... нехай щастить! if ($rating_order_mode > 0) { //якщо сортувати треба для формування рейтингу $criteria->order = $rating_order; //відобразаити усі записи на одній сторінці $page_size = 50000; Personspeciality::$is_rating_order = true; } if ($return_array_of_models) { //для формування рейтингу в Excel-файлі return Personspeciality::model()->findAll($criteria); } //стандартно повертається джерело даних $dataProvider = new CActiveDataProvider($this, array('criteria' => $criteria, 'sort' => array('defaultOrder' => array('idPersonSpeciality' => CSort::SORT_DESC), 'attributes' => array('NAME' => array('asc' => 'NAME', 'desc' => 'NAME DESC'), 'SPEC' => array('asc' => 'SPEC', 'desc' => 'SPEC DESC'), 'benefit.BenefitName' => array('asc' => 'benefit.BenefitName', 'desc' => 'benefit.BenefitName DESC'), 'facultet.FacultetFullName' => array('asc' => 'facultet.FacultetFullName', 'desc' => 'facultet.FacultetFullName DESC'), '*')), 'pagination' => array('pageSize' => $page_size))); //$dataProvider->setTotalItemCount(count($this->findAll($criteria))); return $dataProvider; }