diff --git a/api/controllers/SiteController.php b/api/controllers/SiteController.php
index b81f269c..7e42e91c 100755
--- a/api/controllers/SiteController.php
+++ b/api/controllers/SiteController.php
@@ -77,4 +77,17 @@ class SiteController extends Controller
];
}
}
-}
\ No newline at end of file
+
+ public function actionTestDbTest()
+ {
+ try {
+ $dbName = Yii::$app->dbTest
+ ->createCommand('SELECT DATABASE()')
+ ->queryScalar();
+
+ return 'Connected DB: ' . $dbName;
+ } catch (\Throwable $e) {
+ return $e->getMessage();
+ }
+ }
+}
diff --git a/backend/views/site/login.php b/backend/views/site/login.php
index 435083de..358d58dd 100755
--- a/backend/views/site/login.php
+++ b/backend/views/site/login.php
@@ -11,6 +11,7 @@ use yii\helpers\Html;
$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title;
?>
+
= Html::encode($this->title) ?>
diff --git a/common/config/main-local.php b/common/config/main-local.php
index c0b40ce6..fbc2d966 100755
--- a/common/config/main-local.php
+++ b/common/config/main-local.php
@@ -17,6 +17,21 @@ return [
'charset' => 'utf8',
],
+ 'patho' => [
+ 'class' => 'yii\db\Connection',
+ 'dsn' => 'mysql:host=161.82.188.168;dbname=prolab_main',
+ 'username' => 'apiuser',
+ 'password' => 'Aa157344121165',
+ 'charset' => 'utf8',
+ 'enableSchemaCache' => true,
+ // Duration of schema cache.
+ 'schemaCacheDuration' => 3600,
+
+ // Name of the cache component used to store schema information
+ 'schemaCache' => 'cache',
+ ],
+
+
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'viewPath' => '@common/mail',
diff --git a/common/models/CaseNonGyn.php b/common/models/CaseNonGyn.php
new file mode 100644
index 00000000..8ade6eab
--- /dev/null
+++ b/common/models/CaseNonGyn.php
@@ -0,0 +1,893 @@
+get('patho');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [['id_case', 'hospital_id', 'given_name', 'title_id'], 'required', 'on' => 'register'],
+ [['pathologist_id'], 'required', 'on' => 'update'],
+ [['is_type_specimen'], 'required', 'on' => 'cyto'],
+ [['autocomplete_patient', 'hos_ref', 'house', 'moo', 'soy', 'road', 'phone', 'email', 'post_review_diagnosis'], 'string'],
+ [['id_case'], 'unique'],
+ [['diagnosis'], 'required', 'on' => 'pathologist'],
+ [['title_id', 'is_histo_staining', 'specimen_type_id', 'specimen_id', 'is_stained', 'register_id', 'is_restain', 'is_pathologist_ot', 'specimen_adequacy', 'specimen_adequacy_1', 'specimen_adequacy_2', 'pathologist_id', 'status_id', 'is_print', 'is_critical_diagnosis', 'is_outlab', 'is_consult_outlab', 'cytotech1_id', 'hospital_id', 'lab_order_number', 'is_no_microscopic', 'is_express', 'ward_id', 'rights_id', 'doctor_id', 'organ_id', 'order_point_id', 'hospital_import_id', 'order_by_id'/*, 'smears_receive', 'smears_processed', 'is_effusion', 'is_non_gyn_direction', 'is_fna', 'is_fna_direction'*/, 'const_rights_id', 'specimen_img_update_id', 'tambon', 'amphur', 'province', 'postcode', 'marriage', 'occupation', 'religious', 'race', 'citizenship', 'is_cell_block', 'is_molecular', 'is_conference', 'is_type_specimen', 'is_provincial_hospital', 'is_review'], 'integer'],
+ [['id_case', 'given_name', 'surname', 'gender', 'nation', 'id_card', 'age_unit', 'h_n', 'a_n', 'v_n', 'o_n', 'ward', 'clinician', 'collect_method', 'organ_and_location', 'side_of_specimen', 'fluid_volume', 'fluid_appearance', 'fluid_colour', 'fluid_description', 'clinical_diagnosis', 'clinical_diagnosis_his', 'adequacy_other', 'finding', 'screener_diagnosis', 'diagnosis', 'suggestion', 'cyto_side_of_specimen', 'additional_diagnosis', 'microscopic', 'gross_description', 'cytotech1_at', 'remark', 'non_gyn_specimen_other', 'cell_block_at'/*'fna_quantity', 'fna_slide', 'non_gyn_bal', 'non_gyn_other', 'fna_neck', 'fna_lymph_node', 'fna_salivary_gland', 'fna_other'*/, 'remark_consult_outlab', 'remark_report'], 'string'],
+ [['register_at', 'birthdate', 'collected_at', 'conference_at', 'report_at', 'patient_id', 'additional_at', 'receive_at', 'express_at'/*, 'non_gyn_type', 'fna_type'*/, 'express_day', 'specimen_img_at', 'review_at'], 'safe'],
+ [['age', 'no_slide', 'no_bottle', 'no_slide_dry_smear', 'is_provisional', 'is_consult', 'is_qa'], 'number'],
+ [['his_ln', 'v_date', 'verify_date'], 'string', 'max' => 100],
+ [['express'], 'string', 'max' => 50],
+ [['outlab_report'], 'file', 'extensions' => 'pdf'],
+ [['consult_outlab_report'], 'file', 'extensions' => 'pdf'],
+ [['files'], 'file', 'extensions' => 'pdf,jpg,png,gif,doc,docx,xls,xlsx,ppt,pptx,jpeg'],
+ [['microscopic_img'], 'file', 'extensions' => 'jpeg,jpg,png,gif'],
+ [['specimen_img'], 'file', 'extensions' => 'jpeg,jpg,png,gif,tif,tiff', 'skipOnEmpty' => true, 'maxFiles' => 10],
+ [['specimen_type_id'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimenType::class, 'targetAttribute' => ['specimen_type_id' => 'id']],
+ [['status_id'], 'exist', 'skipOnError' => true, 'targetClass' => ConstStatus::class, 'targetAttribute' => ['status_id' => 'id']],
+ [['specimen_id'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimen::class, 'targetAttribute' => ['specimen_id' => 'id']],
+ [['specimen_adequacy'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimenAdequacy::class, 'targetAttribute' => ['specimen_adequacy' => 'id']],
+ //[['patient_id'], 'exist', 'skipOnError' => true, 'targetClass' => Patient::class, 'targetAttribute' => ['patient_id' => 'id']],
+ [['pathologist_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::class, 'targetAttribute' => ['pathologist_id' => 'id']],
+ ];
+ }
+
+ public function scenarios()
+ {
+ $scenarios = parent::scenarios();
+ $scenarios['register'] = [
+ 'hospital_id',
+ 'patient_id',
+ 'id_case',
+ 'a_n',
+ 'ward',
+ 'clinician',
+ 'collected_at',
+ 'collect_method',
+ 'specimen_type_id',
+ 'specimen_id',
+ 'organ_and_location',
+ 'side_of_specimen',
+ 'no_slide',
+ 'is_stained',
+ 'is_restain',
+ //'clinical_diagnosis',
+ 'is_pathologist_ot',
+ 'no_slide_dry_smear',
+ 'fluid_volume',
+ 'fluid_appearance',
+ 'fluid_colour',
+ 'cyto_side_of_specimen'
+ ];
+ $scenarios['process'] = [
+ 'patient_id',
+ 'id_case',
+ 'no_slide',
+ 'sterilize',
+ 'previous_treatment',
+ 'specimen_adequacy',
+ 'specimen_adequacy_1',
+ 'specimen_adequacy_2',
+ 'general_categorization',
+ 'general_categorization_1',
+ 'pathologist_id',
+ 'is_provisional',
+ 'is_consult',
+ 'is_qa',
+ 'is_conference',
+ 'status_id',
+ 'is_print',
+ 'finding',
+ 'clinical_finding',
+ //'clinical_diagnosis',
+ 'last_pap',
+ 'last_pregnancy',
+ 'adequacy_other',
+ 'categorization_other',
+ 'screener_diagnosis',
+ 'suggestion',
+ 'diff_qa',
+ 'hospital_id',
+ ];
+ return $scenarios;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'hospital_id' => 'หน่วยงาน',
+ //'patient_id' => 'ผู้ป่วย',
+ 'hospital' => 'หน่วยงาน',
+ 'patient' => 'ชื่อ - นามสกุล',
+ 'pathologist' => 'พยาธิแพทย์',
+ 'pathologist_id' => 'พยาธิแพทย์',
+ 'autocomplete_patient' => 'ผู้ป่วย',
+ 'id_case' => 'ID CASE',
+ 'title_id' => 'คำนำหน้า',
+ 'given_name' => 'ชื่อ',
+ 'surname' => 'นามสกุล',
+ 'gender' => 'เพศ',
+ 'nation' => 'เชื้อชาติ',
+ 'id_card' => 'หมายเลขบัตรประชาชน',
+ 'birthdate' => 'วัน/เดือน/ปี เกิด',
+ 'age' => 'อายุ',
+ 'age_unit' => 'หน่วยอายุ',
+ 'h_n' => 'HN',
+ 'a_n' => 'AN',
+ 'v_n' => 'VN',
+ 'o_n' => 'Order Number',
+ 'ward' => 'Ward',
+ 'ward_id' => 'Ward',
+ 'clinician' => 'Physician',
+ 'doctor_id' => 'Clinician',
+ 'organ_id' => 'Organ',
+ 'collected_at' => 'วันที่เก็บสิ่งส่งตรวจ',
+ 'receive_at' => 'วันที่รับสิ่งส่งตรวจ',
+ 'collect_method' => 'Collect Method',
+ 'specimen_type_id' => 'Specimen Type',
+ 'specimen_id' => 'Specimen',
+ 'organ_and_location' => 'Specimen', //Organ And Location
+ 'cyto_side_of_specimen' => 'Side Of Specimen',
+ 'cytotech1_id' => 'Cytotech',
+ 'side_of_specimen' => 'Side Of Specimen',
+ 'no_slide' => 'จำนวน Slide',
+ 'no_bottle' => 'จำนวน ขวด',
+ 'quantity' => 'quantity',
+ 'no_slide_dry_smear' => 'Slide Dry Smear',
+ 'fluid_volume' => 'Amount',
+ 'fluid_appearance' => 'Turbidity',
+ 'fluid_colour' => 'Colour',
+ 'fluid_description' => 'Description',
+ 'is_stained' => 'Stained',
+ 'is_restain' => 'Restain',
+ 'is_critical_diagnosis' => 'แจ้งแพทย์ด่วน Critical Diagnosis',
+ 'clinical_diagnosis' => 'Clinical Diagnosis',
+ 'clinical_diagnosis_his' => 'Clinical Diagnosis',
+ 'specimen_adequacy' => 'Specimen Adequacy',
+ 'specimen_adequacy_1' => 'Specimen Adequacy 1',
+ 'specimen_adequacy_2' => 'Specimen Adequacy 2',
+ 'adequacy_other' => 'Adequacy Other',
+ 'gross_description' => 'Gross Description',
+ 'microscopic' => 'MICROSCOPIC FINDINGS',
+ 'is_no_microscopic' => 'ไม่รายงาน Microscopic Description',
+ 'diagnosis' => 'CYTOLOGIC DIAGNOSIS',
+ 'additional_diagnosis' => 'Additional Diagnosis',
+ 'suggestion' => 'Suggestion',
+ 'pathologist_id' => 'Pathologist',
+ 'status_id' => 'Status',
+ 'report_at' => 'Report At',
+ 'register_at' => 'วันที่ลงทะเบียน',
+ 'register_id' => 'ผู้ลงทะเบียน',
+ 'lab_order_number' => 'Lab Order Number',
+ 'is_express' => 'ขอผลด่วน?',
+ 'express_day' => 'เลือกวันขอผลด่วน',
+ 'express_at' => 'วันที่ขอผลด่วน',
+ 'smears_receive' => 'Receive',
+ 'smears_processed' => 'Processed',
+ 'smears_remark' => 'Description',
+ 'remark' => 'Remark',
+ 'rights_id' => 'สิทธิ์การรักษา',
+ 'is_cell_block' => 'สั่ง Cell block',
+ 'cell_block_at' => 'ส่ง Cell block เมื่อ',
+ 'specimen_img' => 'Specimen Image',
+ 'is_outlab' => 'Case Outlab',
+ 'his_ln' => 'Lab Number',
+ 'house' => 'บ้านเลขที่',
+ 'moo' => 'หมู่ที่/ชุมชน',
+ 'soy' => 'ตรอก/ซอย',
+ 'road' => 'ถนน',
+ 'tambon' => 'ตำบล',
+ 'amphur' => 'อำเภอ',
+ 'province' => 'จังหวัด',
+ 'postcode' => 'รหัสไปรษณีย์',
+ 'phone' => 'หมายเลขโทรศัพท์คนไข้',
+ 'email' => 'Email',
+ 'marriage' => 'สถานภาพสมรส',
+ 'occupation' => 'อาชีพ',
+ 'religious' => 'ศาสนา',
+ 'race' => 'เชิ้อชาติ',
+ 'citizenship' => 'สัญชาติ',
+ 'is_type_specimen' => 'รายงานผล',
+ 'is_provincial_hospital' => 'รพช',
+ 'is_review' => 'Review',
+ 'is_molecular' => 'Molecular',
+ ];
+ }
+
+ /**
+ * @return string[]
+ */
+ public function attributeHints()
+ {
+ return [
+ 'collected_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'receive_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'birthdate' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y'),
+ 'conference_at' => 'วัน/เดือน/ปี ค.ศ. เช่น' . date('d/m/Y'),
+ 'no_slide' => 'กรอกเฉพาะตัวเลขเท่านั้น',
+ 'no_slide_dry_smear' => 'กรอกเฉพาะตัวเลขเท่านั้น',
+ ];
+ }
+
+ /**
+ * @return string
+ */
+ public function getFullname()
+ {
+ return Html::encode($this->given_name . ' ' . $this->surname);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatientDiag()
+ {
+ return $this->hasOne(PatientCaseDiagnosis::class, ['h_n' => 'h_n']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstWard()
+ {
+ return $this->hasOne(ConstWard::class, ['id' => 'ward_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getOrgan()
+ {
+ return $this->hasOne(ConstOrgan::class, ['id' => 'organ_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstDoctor()
+ {
+ return $this->hasOne(ConstDoctor::class, ['id' => 'doctor_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstRights()
+ {
+ return $this->hasOne(ConstRights::class, ['id' => 'rights_id']);
+ }
+
+ public function getHospital()
+ {
+ return $this->hasOne(ConstHospital::class, ['id' => 'hospital_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegister()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+
+ public function getTitle()
+ {
+ return $this->hasOne(PatientTitle::class, ['id' => 'title_id']);
+ }
+
+ public function getWard()
+ {
+ return $this->hasOne(PatientWard::class, ['id' => 'ward']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenType()
+ {
+ return $this->hasOne(CytoSpecimenType::class, ['id' => 'specimen_type_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getStatus()
+ {
+ return $this->hasOne(ConstStatus::class, ['id' => 'status_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCytotech()
+ {
+ return $this->hasOne(User::class, ['id' => 'cytotech1_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimen()
+ {
+ return $this->hasOne(CytoSpecimen::class, ['id' => 'specimen_id']);
+ }
+
+ public function getSideOfSpecimen()
+ {
+ return $this->hasOne(CytoSideOfSpecimen::class, ['id' => 'side_of_specimen']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenAdequacy()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy::class, ['id' => 'specimen_adequacy']);
+ }
+
+ public function getSpecimenAdequacy1()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy1::class, ['id' => 'specimen_adequacy_1']);
+ }
+
+ public function getSpecimenAdequacy2()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy2::class, ['id' => 'specimen_adequacy_2']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatient()
+ {
+ return $this->hasOne(Patient::class, ['id' => 'patient_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getApproveAt()
+ {
+ return $this->hasOne(User::class, ['id' => 'approve_at']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPathologist()
+ {
+ return $this->hasOne(User::class, ['id' => 'pathologist_id']);
+ }
+
+ public function getFinance()
+ {
+ return $this->hasOne(FinanceServiceCharge::class, ['id_case' => 'id_case']);
+ }
+
+ public function getCytoOperate()
+ {
+ return $this->hasOne(CytoOperate::class, ['id_case' => 'id_case']);
+ }
+
+ /**
+ * นับจำนวน Case ใหม่
+ * @return number|string
+ */
+ public static function getNewCase()
+ {
+ return CaseNonGyn::find()->where(['status_id' => 1])->count();
+ }
+
+ /**
+ * นับจำนวน Case ใหม่
+ * @return number|string
+ */
+ public static function getNewCytoCase()
+ {
+ return CaseNonGyn::find()->where(['status_id' => 6])->count();
+ }
+
+ /**
+ * นับจำนวน Case ของตัวเอง
+ * @return number|string
+ */
+ public static function getMyCase()
+ {
+ return CaseNonGyn::find()->with('')
+ ->where(['cytotech1_id' => Yii::$app->user->getId(), 'status_id' => 5])
+ ->count();
+ }
+
+ /**
+ * นับจำนวน Case ที่ทำเสร็จแล้ว
+ * @return number|string
+ */
+ public static function getMyFinishCase()
+ {
+ return CaseNonGyn::find()
+ ->with('')
+ ->where(['cytotech1_id' => Yii::$app->user->getId(), 'status_id' => 12])->count();
+ }
+
+ /*
+ * upload Files
+ */
+ public function uploadFile($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = time() . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadFile . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getFileToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /*public function getFileToArray()
+ {
+ return !empty($this->files) ? explode(',', $this->getOldAttribute('files')) : [];
+ }*/
+
+ public function getFileToArray()
+ {
+ return $this->getOldAttribute('files') ? @explode(',', $this->getOldAttribute('files')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getFiles()
+ {
+ if (empty($this->files) && !isset($this->files)) {
+ return [];
+ } else {
+ return !is_array($this->files) ? explode(',', $this->files) : [];
+ }
+ }
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLink()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a($val, Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']) . ' ';
+ }
+ }
+ return $rt;
+ }
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLinkImg()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['class' => 'img-fluid']), Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']);
+ }
+ }
+ return $rt;
+ }
+
+
+ /**
+ * @param $model
+ * @return false|string
+ * @throws \ImagickException
+ */
+ public function uploadMicro($model)
+ {
+ $files = UploadedFile::getInstances($model, 'microscopic_img');
+ if ($files) {
+ $file_names = [];
+
+ foreach ($files as $file) {
+ if ($file->extension == 'tiff' || $file->extension == 'tif') {
+ $file_name = $model->id_case . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ $image = new Imagick(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ @unlink(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ $file_name = $model->id_case . '_' . $file->baseName . '.png';
+ $image->setImageFormat('png');
+ $image->thumbnailImage(1024, 0);
+ $image->writeImage(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+ } else {
+ $file_name = $model->id_case . '_' . $file->baseName . '.' . $file->extension;
+
+ if ($file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name)) {
+ Image::getImagine()->open(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name)->thumbnail(new Box(1024, 1024))->save(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name, ['quality' => 100]);
+ }
+ }
+
+ $file_names[] = $file_name;
+ }
+ return implode(',', ArrayHelper::merge($file_names, $this->getMicroImageToArray()));
+ }
+
+ return $model->isNewRecord ? false : $model->getOldAttribute('microscopic_img');
+ }
+
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getMicroImageToArray()
+ {
+ return !empty($this->getOldAttribute('microscopic_img')) ? explode(',', $this->getOldAttribute('microscopic_img')) : [];
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getMicroImage()
+ {
+ return !empty($this->microscopic_img) ? Yii::getAlias('@web') . '/' . $this->uploadMicroFolder . '/' . $this->microscopic_img : '';
+ }
+
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReportToArray()
+ {
+ return $this->getOldAttribute('outlab_report') ? @explode(',', $this->getOldAttribute('outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReport()
+ {
+ if (empty($this->outlab_report) || !isset($this->outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->outlab_report) ? explode(',', $this->outlab_report) : [];
+ }
+ }
+
+ /****** */
+
+ /**
+ * @param $id_case
+ * @return array|mixed|\yii\db\ActiveRecord|null
+ */
+ public static function getNext($id_case)
+ {
+ $model = CaseNonGyn::findOne(['id_case' => $id_case]);
+ $surgical = CaseNonGyn::find()->where(['>', 'id', $model->id])->andWhere(['status_id' => 1])->orderBy(['id' => SORT_ASC])->one();
+ if ($surgical) {
+ return $surgical->id_case;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param null $id_case
+ * @return array|mixed|\yii\db\ActiveRecord|null
+ */
+ public static function getPrev($id_case = null)
+ {
+ $model = CaseNonGyn::findOne(['id_case' => $id_case]);
+ $surgical = CaseNonGyn::find()->where(['<', 'id', $model->id])->andWhere(['status_id' => 1])->orderBy(['id' => SORT_DESC])->one();
+ if ($surgical) {
+ return $surgical->id_case;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return bool|mixed|string|null
+ * @throws \yii\base\Exception
+ */
+ public function uploadGross($model, $attribute)
+ {
+ $grosses = UploadedFile::getInstances($model, $attribute);
+ FileHelper::createDirectory($this->getPath());
+ if ($grosses) {
+ $file_names = [];
+ foreach ($grosses as $gross) {
+ $file_name = $this->id_case . '_' . $gross->baseName . '.' . $gross->extension;
+ $gross->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadGross . '/' . $file_name);
+ $file_names[] = $file_name;
+ }
+ if ($this->isNewRecord) { //ถ้าเป็นการเพิ่ม Record ใหม่ให้บันทึกไฟล์ aaa.aaa,bbb.bbb ....
+ return implode(',', $file_names);
+ } else { //ถ้าเป็นการปรับปรุงให้เพิ่มจากของเดิม
+ return implode(',', ArrayHelper::merge($file_names, $this->getOldAttribute($attribute) ? explode(',', $this->getOldAttribute($attribute)) : []));
+ }
+ } //end files upload
+
+ return $this->isNewRecord ? false : $this->getOldAttribute($attribute); //ถ้าไม่มีการ upload ให้ใช้ข้อมูลเดิม
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getPath()
+ {
+ return Yii::getAlias('@webroot') . '/' . $this->uploadGross;
+ }
+
+ /**
+ * @return string
+ */
+ public function getFileUrl()
+ {
+ return Yii::getAlias('@web') . '/' . $this->uploadGross;
+ }
+
+
+ /**
+ * @return false|string[]
+ */
+ public function getGrosses()
+ {
+ return !is_array($this->specimen_img) ? explode(',', $this->specimen_img) : [];
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossImgs()
+ {
+ $img = '';
+ if (!empty($this->specimen_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+ /**
+ * @return string
+ */
+ public function getGrossImgsForGross()
+ {
+ $img = '';
+ if (!empty($this->specimen_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => '']), ['/surgical/gross/view-gross', 'id_case' => $this->id_case, 'specimen_img' => $gross], ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossDelImgs()
+ {
+ $img = '';
+ if (!empty($this->specimen_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= '
' . Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']) . '
' .
+ Html::a('Delete', ['delete-gross-img', 'img' => $gross, 'id_case' => $this->id_case], ['class' => 'btn btn-xs btn-danger', 'data' => ['confirm' => 'แน่ใจนะว่าต้องการลบรูปนี้?']])
+ . '
';
+ }
+ }
+ return $img;
+ }
+
+ /*********************** */
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadConsultReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadConsultReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getConsultReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getConsultReportToArray()
+ {
+ return $this->getOldAttribute('consult_outlab_report') ? @explode(',', $this->getOldAttribute('consult_outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getConsultReport()
+ {
+ if (empty($this->consult_outlab_report) || !isset($this->consult_outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->consult_outlab_report) ? explode(',', $this->consult_outlab_report) : [];
+ }
+ }
+}
diff --git a/common/models/CasePap.php b/common/models/CasePap.php
new file mode 100644
index 00000000..bcb3c5fd
--- /dev/null
+++ b/common/models/CasePap.php
@@ -0,0 +1,696 @@
+get('patho');
+ }
+
+ /**
+ * @param $insert
+ * @return bool
+ */
+ public function beforeSave($insert)
+ {
+
+ $this->specimen_adequacy_3 = serialize($this->specimen_adequacy_3);
+ $this->specimen_adequacy_4 = serialize($this->specimen_adequacy_4);
+ $this->general_categorization_2 = serialize($this->general_categorization_2);
+
+ return parent::beforeSave($insert);
+ }
+
+ /**
+ * @return void
+ */
+
+ public function afterFind()
+ {
+ $this->specimen_adequacy_3 = unserialize($this->specimen_adequacy_3);
+ $this->specimen_adequacy_4 = unserialize($this->specimen_adequacy_4);
+ $this->general_categorization_2 = unserialize($this->general_categorization_2);
+
+ parent::afterFind();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [[/*'patient_id'*/'id_case', 'hospital_id', 'given_name', 'title_id'], 'required', 'on' => 'register'],
+ [['is_specimen'], 'required', 'on' => 'cyto'],
+ [[/*'patient_id'*/'id_case', 'hospital_id', 'gender', 'given_name', 'surname', 'title_id', 'pathologist_id'], 'required', 'on' => 'approve'],
+ [['autocomplete_patient', 'hos_ref', 'cyto_type', 'case_reference', 'house', 'moo', 'soy', 'road', 'phone', 'email', 'post_review_diagnosis'], 'string'],
+ //[['pathologist_id'], 'required', 'on' => 'update'],
+ [['id_case'], 'unique'],
+ [['title_id', 'specimen_type_id', 'cytotech1_id', 'cytotech2_id', 'specimen_id', 'is_stained', 'is_restain', 'via', 'is_ot', 'is_pathologist_ot', 'specimen_adequacy', 'register_id', 'specimen_adequacy_1', 'general_categorization', 'general_categorization_1', 'pathologist_id', 'is_provisional', 'is_consult', 'is_qa', 'is_conference', 'status_id', 'is_print', 'suggestion_list', 'is_critical_diagnosis', 'class_id', 'adequacy_id', 'result_id', 'hm_id', 'suggest_id', 'is_outlab', 'is_no_comment', 'lab_order_number', 'is_express', 'ward_id', 'rights_id', 'doctor_id', 'organ_id', 'order_point_id', 'order_by_id', 'screener_qa_id', 'qa_list_id', 'const_rights_id', 'tambon', 'amphur', 'province', 'postcode', 'marriage', 'occupation', 'religious', 'race', 'citizenship', 'specimen_adequacy_2', 'is_hpv', 'is_provincial_hospital', 'is_review', 'is_specimen'], 'integer'],
+ [['id_case', 'given_name', 'surname', 'gender', 'nation', 'id_card', 'age_unit', 'h_n', 'a_n', 'ward', 'clinician', 'collect_method', 'lmp', 'para', 'sterilize', 'previous_treatment', 'clinical_finding', 'clinical_diagnosis', 'clinical_diagnosis_his', 'last_pap', 'last_pregnancy', 'adequacy_other', 'categorization_other', 'diagnosis', 'suggestion', 'diff_qa', 'adequacy_comment', 'result_comment', 'hm_comment', 'suggest_comment', /*'quantity',*/ 'specimen', 'remark', 'gyn_specimen_other', 'remark_report', 'remark_consult_outlab'], 'string'],
+ [['register_at', 'birthdate', 'collected_at', 'conference_at', 'report_at', 'patient_id', 'cytotech1_at', 'cytotech2_at', 'specimen_adequacy_3', 'specimen_adequacy_4', 'general_categorization_2', 'result_at', 'receive_at', 'express_at', 'express_day', 'review_at'], 'safe'],
+ [['no_slide', 'pathologist_id', 'hospital_id'], 'number'],
+ [['id_case'], 'required', 'on' => 'process'],
+ [['his_ln', 'v_date', 'verify_date'], 'string', 'max' => 100],
+ [['express'], 'string', 'max' => 50],
+ [['files'], 'file', 'extensions' => 'pdf,jpg,png,jpeg,gif,doc,docx,xls,xlsx,ppt,pptx'],
+ [['outlab_report'], 'file', 'extensions' => 'pdf,jpg,png,gif,doc,docx,xls,xlsx,ppt,pptx,jpeg'],
+ [['age'], 'number'],
+ [['hospital_id'], 'exist', 'skipOnError' => true, 'targetClass' => ConstHospital::class, 'targetAttribute' => ['hospital_id' => 'id']],
+ [['status_id'], 'exist', 'skipOnError' => true, 'targetClass' => ConstStatus::class, 'targetAttribute' => ['status_id' => 'id']],
+ [['specimen_id'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimen::class, 'targetAttribute' => ['specimen_id' => 'id']],
+ [['specimen_type_id'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimenType::class, 'targetAttribute' => ['specimen_type_id' => 'id']],
+ [['patient_id'], 'exist', 'skipOnError' => true, 'targetClass' => Patient::class, 'targetAttribute' => ['patient_id' => 'id']],
+ [['pathologist_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::class, 'targetAttribute' => ['pathologist_id' => 'id']],
+ ];
+ }
+
+
+ /**
+ * @inheritdoc
+ */
+
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ //'autocomplete_patient' => '',
+ //'patient_id' => 'ชื่อ นามสกุล',
+ 'hospital_id' => 'หน่วยงาน',
+ 'patient' => 'ชื่อ นามสกุล',
+ 'pathologist' => 'พยาธิแพทย์',
+ 'hospital' => 'โรงพยาบาล',
+ 'id_case' => 'ID CASE',
+ 'cyto_type' => 'Type',
+ 'cytotech1_id' => 'Cytotech1',
+ 'cytotech1_at' => 'Cytotech1 At',
+ 'cytotech2_id' => 'Cytotech2',
+ 'cytotech2_at' => 'Cytotech2 At',
+ 'title_id' => 'คำนำหน้า',
+ 'given_name' => 'ชื่อ',
+ 'surname' => 'นามสกุล',
+ 'gender' => 'เพศ',
+ 'nation' => 'เชื้อชาติ',
+ 'id_card' => 'หมายเลขบัตรประชาชน',
+ 'birthdate' => 'วัน/เดือน/ปี เกิด',
+ 'age' => 'อายุ',
+ 'age_unit' => 'หน่วยอายุ',
+ 'h_n' => 'H N',
+ 'a_n' => 'A N',
+ 'ward' => 'Ward',
+ 'ward_id' => 'Ward',
+ 'clinician' => 'Physician',
+ 'doctor_id' => 'Clinician',
+ 'organ_id' => 'Organ',
+ 'collected_at' => 'วันที่เก็บสิ่งส่งตรวจ',
+ 'receive_at' => 'วันที่รับสิ่งส่งตรวจ',
+ 'collect_method' => 'Collect Method', //Specimen Type ตอนนี้คือ Collect Method
+ 'specimen_type_id' => 'Collect Method',
+ 'specimen_id' => 'Specimen',
+ 'specimen_name' => 'Specimen',
+ 'no_slide' => 'จำนวนสไลด์',
+ 'quantity' => 'Quantity',
+ 'is_stained' => 'Stained',
+ 'is_restain' => 'Restain',
+ 'last_pregnancy' => 'Last',
+ 'lmp' => 'LMP',
+ 'para' => 'Para',
+ 'sterilize' => 'Sterilize',
+ 'previous_treatment' => 'Previous Treatment',
+ 'clinical_finding' => 'Clinical Finding',
+ 'clinical_diagnosis' => 'Clinical Information',
+ 'clinical_diagnosis_his' => 'Clinical Diagnosis',
+ 'last_pap' => 'Last Pap',
+ 'via' => 'VIA',
+ 'is_ot' => 'OT',
+ 'is_pathologist_ot' => 'Pathologist OT',
+ 'specimen_adequacy' => 'Specimen Adequacy',
+ 'specimen_adequacy_1' => 'Specimen Adequacy 1',
+ 'specimen_adequacy_2' => 'Specimen Adequacy 2',
+ 'specimen_adequacy_4' => 'Specimen Adequacy 4',
+ 'adequacy_other' => 'Adequacy Other',
+ 'general_categorization' => 'General Categorization',
+ 'general_categorization_1' => 'General Categorization 1',
+ 'categorization_other' => 'Categorization Other',
+ 'diagnosis' => 'Diagnosis',
+ 'additional_diagnosis' => 'Additional Diagnosis',
+ 'microscopic' => 'Microscopic',
+ 'gross_description' => 'Gross Description',
+ 'microscopic_img' => 'Microscopic Image',
+ 'suggestion' => 'Educational Notes And Suggestions',
+ 'pathologist_id' => 'พยาธิแพทย์',
+ 'is_provisional' => 'Provisional',
+ 'is_consult' => 'Consult',
+ 'is_qa' => 'QA',
+ 'is_conference' => 'Conference',
+ 'conference_at' => 'Conference At',
+ 'is_review' => 'Review',
+ 'status_id' => 'Status',
+ 'report_at' => 'Report At',
+ 'is_print' => 'Is Print',
+ 'diff_qa' => 'Diff Qa',
+ 'is_critical_diagnosis' => 'Critical Report',
+ 'is_first_cancer' => 'First Cancer',
+ 'files' => 'Request File',
+ 'class_id' => 'GENERAL CATEGORIZATION',
+ 'adequacy_id' => 'ADEQUACY',
+ 'adequacy_comment' => 'ADEQUACY OTHER',
+ 'result_id' => 'INTERPRETATION/ RESULT',
+ 'result_comment' => 'INTERPRETATION/RESULT OTHER',
+ 'hm_id' => 'HORMONAL EVALUATION',
+ 'hm_comment' => 'HORMONAL EVALUATION OTHER',
+ 'suggest_id' => 'SUGGESTION',
+ 'suggest_comment' => 'SUGGESTION OTHER',
+ 'register_at' => 'วันที่ลงทะเบียน',
+ 'register_id' => 'ผู้ลงทะเบียน',
+ 'is_no_comment' => 'ไม่รายงาน Comment',
+ 'lab_order_number' => 'Lab Order Number',
+ 'specimen' => 'Specimen',
+ 'is_express' => 'ขอผลด่วน?',
+ 'express_day' => 'เลือกวันขอผลด่วน',
+ 'express_at' => 'วันที่ขอผลด่วน',
+ 'remark' => 'Remark',
+ 'rights_id' => 'สิทธิ์การรักษา',
+ 'gyn_specimen_other' => 'Specimen Other',
+ 'is_outlab' => 'Case Outlab',
+ 'his_ln' => 'Lab Number',
+ 'house' => 'เลขที่บ้าน',
+ 'moo' => 'เลขที่หมู่/ชุมชน',
+ 'soy' => 'ชื่อตรอก/ซอย',
+ 'road' => 'ถนน',
+ 'tambon' => 'ตำบล',
+ 'amphur' => 'อำเภอ',
+ 'province' => 'จังหวัด',
+ 'postcode' => 'รหัสไปรษณีย์',
+ 'phone' => 'หมายเลขโทรศัพท์คนไข้',
+ 'email' => 'ที่อยู่จดหมายอิเลคทรอนิค',
+ 'marriage' => 'สภาพสมรส',
+ 'occupation' => 'อาชีพ',
+ 'religious' => 'ศาสนา',
+ 'race' => 'เชิ้อชาติ',
+ 'citizenship' => 'สัญชาติ',
+ 'is_hpv' => 'HPV',
+ 'is_provincial_hospital' => 'รพช',
+ 'is_specimen' => 'รายงานผล'
+ ];
+ }
+ public function attributeHints()
+ {
+ return [
+ 'collected_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'receive_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'birthdate' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y'),
+ 'conference_at' => 'วัน/เดือน/ปี ค.ศ. เช่น' . date('d/m/Y'),
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getStatus()
+ {
+ return $this->hasOne(ConstStatus::class, ['id' => 'status_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstWard()
+ {
+ return $this->hasOne(ConstWard::class, ['id' => 'ward_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatientDiag()
+ {
+ return $this->hasOne(PatientCaseDiagnosis::class, ['h_n' => 'h_n']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstDoctor()
+ {
+ return $this->hasOne(ConstDoctor::class, ['id' => 'doctor_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstRights()
+ {
+ return $this->hasOne(ConstRights::class, ['id' => 'rights_id']);
+ }
+ public function getTitle()
+ {
+ return $this->hasOne(PatientTitle::class, ['id' => 'title_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegister()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegisterBy()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getGeneralCategorization()
+ {
+ return $this->hasOne(CytoGeneralCategorization::class, ['id' => 'general_categorization']);
+ }
+
+ public function getGeneralCategorization1()
+ {
+ return $this->hasOne(CytoGeneralCategorization1::class, ['id' => 'general_categorization_1']);
+ }
+
+ public function getGeneralCategorization2()
+ {
+ return $this->hasOne(CytoGeneralCategorization2::class, ['id' => 'general_categorization_2']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenModel()
+ {
+ return $this->hasOne(CytoSpecimen::class, ['id' => 'specimen_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenAdequacy()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy::class, ['id' => 'specimen_adequacy']);
+ }
+
+ public function getSpecimenAdequacy1()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy1::class, ['id' => 'specimen_adequacy_1']);
+ }
+ public function getSpecimenAdequacy2()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy2::class, ['id' => 'specimen_adequacy_2']);
+ }
+ public function getSpecimenAdequacy3()
+ {
+ return $this->hasMany(CytoSpecimenAdequacyByCase::class, ['id_case' => 'id_case']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenType()
+ {
+ return $this->hasOne(CytoSpecimenType::class, ['id' => 'specimen_type_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatient()
+ {
+ return $this->hasOne(Patient::class, ['id' => 'patient_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCytotech1()
+ {
+ return $this->hasOne(User::className(), ['id' => 'cytotech1_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCytotech2()
+ {
+ return $this->hasOne(User::className(), ['id' => 'cytotech2_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPathologist()
+ {
+ return $this->hasOne(User::class, ['id' => 'pathologist_id']);
+ }
+
+ public function getlastTransferBy()
+ {
+ return $this->hasOne(User::class, ['id' => 'last_transfer_by']);
+ }
+
+ public function getCytoOperate()
+ {
+ return $this->hasOne(CytoOperate::class, ['id_case' => 'id_case']);
+ }
+ public function getServiceCharge()
+ {
+ return $this->hasOne(FinanceServiceCharge::class, ['id_case' => 'id_case']);
+ }
+
+ public function getWard()
+ {
+ return $this->hasOne(PatientWard::class, ['id' => 'ward']);
+ }
+
+ public function getHospital()
+ {
+ return $this->hasOne(ConstHospital::class, ['id' => 'hospital_id']);
+ }
+ public function getCytoSuggestion()
+ {
+ return $this->hasOne(CytoSuggestion::class, ['id' => 'suggestion_list']);
+ }
+
+ public function getClass()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'class_id']);
+ }
+
+ public function getAdequacy()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'adequacy_id']);
+ }
+ public function getResult()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'result_id']);
+ }
+ public function getHm()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'hm_id']);
+ }
+ public function getSuggest()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'suggest_id']);
+ }
+
+
+ /**
+ * นับจำนวน Case ใหม่
+ * @return number|string
+ */
+ public static function getNewCase()
+ {
+ return CasePap::find()->where(['status_id' => 1])->count();
+ }
+
+ /**
+ * นับจำนวน Case ของตัวเอง
+ * @return number|string
+ */
+ /* public static function getMyCase()
+ {
+ return CasePap::find()->with('')
+ ->where(['cytotech_id' => Yii::$app->user->getId(), 'status_id' => 5])
+ ->count();
+ }*/
+
+ /**
+ * นับจำนวน Case ที่ทำเสร็จแล้ว
+ * @return number|string
+ */
+ public static function getMyFinishCase()
+ {
+ return CasePap::find()
+ ->with('')
+ ->where(['cytotech_id' => Yii::$app->user->getId(), 'status_id' => 12])->count();
+ }
+
+ public function getCollectMethod()
+ {
+ return $this->hasOne(CytoCollectMethod::class, ['id' => 'collect_method']);
+ }
+
+ /*
+ * upload Files
+ */
+ public function uploadFile($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = time() . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadFile . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getFileToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getFiles()
+ {
+ if (empty($this->files) && !isset($this->files)) {
+ return [];
+ } else {
+ return !is_array($this->files) ? explode(',', $this->files) : [];
+ }
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getFileToArray()
+ {
+ return $this->getOldAttribute('files') ? @explode(',', $this->getOldAttribute('files')) : [];
+ }
+
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLink()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a($val, Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']) . ' ';
+ }
+ }
+ return $rt;
+ }
+
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLinkImg()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['class' => 'img-fluid']), Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']);
+ }
+ }
+ return $rt;
+ }
+
+
+ /**
+ * @param $model
+ * @return string
+ */
+ public function uploadMicro($model)
+ {
+ $file = UploadedFile::getInstance($model, 'microscopic_img');
+ if ($file) {
+ $file_name = $model->id_case . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+ return $file_name;
+ }
+
+ return $model->getOldAttribute('microscopic_img');
+ }
+
+ /**
+ * @return string
+ */
+ public function getMicroImage()
+ {
+ return !empty($this->microscopic_img) ? Yii::getAlias('@web') . '/' . $this->uploadMicroFolder . '/' . $this->microscopic_img : '';
+ }
+
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReportToArray()
+ {
+ return !empty($this->getOldAttribute('outlab_report')) ? @explode(',', $this->getOldAttribute('outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReport()
+ {
+ if (empty($this->outlab_report) || !isset($this->outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->outlab_report) ? explode(',', $this->outlab_report) : [];
+ }
+ }
+
+ public function getFullname()
+ {
+ return Html::encode($this->given_name . ' ' . $this->surname);
+ }
+
+ public function getTitleFullname()
+ {
+ return Html::encode(((!empty($this->title_id) ? $this->title->name : '') . $this->given_name . ' ' . $this->surname));
+ }
+}
diff --git a/common/models/CaseSurgical.php b/common/models/CaseSurgical.php
new file mode 100644
index 00000000..15cfa29c
--- /dev/null
+++ b/common/models/CaseSurgical.php
@@ -0,0 +1,866 @@
+get('patho');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [['id_case', 'hospital_id', 'given_name', 'title_id'], 'required'],
+ [['id_case', 'hospital_id'], 'required', 'on' => 'register'],
+ [['pathologist_id'], 'required', 'on' => 'update'],
+ [['is_stat_flesh'], 'required', 'on' => 'gross'],
+ [['id_case'], 'unique'],
+ [['autocomplete_hospital', 'autocomplete_patient', 'autocomplete_ward', /*'frozen_id_case', 'cons_pathologist',*/ 'hos_ref' /*'case_reference'*/, 'house', 'moo', 'soy', 'road', 'phone', 'email', /*'review_remark'*/], 'string'],
+ [['patient_id', 'title_id', 'is_immuno_staining', 'is_histo_staining', 'register_id', 'amount', 'block_type_id', 'pathologist_id', 'is_consult', 'status_id', 'hospital_id', 'gross_id', /*'cons_pathologist_id', 'consultant_id', 'center_box_open_id',*/ 'is_critical_diagnosis', 'is_pathologist_ot', 'gross_img_update_id', 'is_no_microscopic', 'is_outlab', 'is_consult_outlab', 'charge_user_id', 'bone', 'is_kidney', 'note_id', 'cut_id', 'is_express', 'ward_id', 'rights_id', 'doctor_id', 'organ_id', 'order_point_id', 'order_by_id', 'hospital_import_id', 'amount_in', 'const_rights_id', 'is_molecular', 'is_dish', 'is_frozen', 'is_necropsy', 'tambon', 'amphur', 'province', 'postcode', 'marriage', 'occupation', 'religious', 'race', 'citizenship', 'is_flesh', 'bag', 'is_conference', 'is_review', 'is_smc', 'is_stat_smc', 'is_provincial_hospital', /*'block_no', 'slide_no',*/ 'is_slide_review', 'is_pathologist_review'], 'integer'],
+ [['id_case', 'hos_ref', 'given_name', 'surname', 'gender', 'nation', 'id_card', 'age_unit', 'h_n', 'a_n', 'ward', 'clinician', 'specimen', 'section_label', 'clinical_diagnosis', 'clinical_diagnosis_his', 'gross_description', 'microscopic_description', 'patho_remark', 'diagnosis', 'additional_diagnosis', /*'cons',*/ 'patho_remark', 'bone_note', 'lab_order_number', 'remark', 'remark_outlab', 'remark_consult_outlab', 'remark_report', 'post_review_diagnosis'], 'string'],
+ [['his_ln', 'verify_date'], 'string', 'max' => 100],
+ [['register_at', 'birthdate', 'collected_at', 'conference_at', 'report_at', 'id_case', 'gross_at', 'decal_end_date', 'items'/*, 'slides'*/, 'additional_at', 'status_at', 'cut_at', 'receive_at', 'express_at', 'finance_immuno', 'finance_histo', 'outlab_report', 'decal_block', 'finance_dish'], 'safe'],
+ [['files'], 'file', 'extensions' => 'pdf,jpg,png,gif,doc,docx,xls,xlsx,ppt,pptx,jpeg'],
+ [['gross_img', 'microscopic_img'], 'file', 'extensions' => 'jpeg,jpg,png,gif,tif,tiff', 'skipOnEmpty' => true, 'maxFiles' => 10],
+ [['diagnosis', 'gross_description'], 'required', 'on' => 'pathologist'],
+ [['microscopic_description', 'gross_description'], 'required', 'on' => 'additional'],
+ [['cut_id', 'note_id', 'is_flesh'], 'required', 'on' => 'new'],
+ [['is_re_reference', 'v_date', 'express_day', 'review_at'], 'safe'],
+ [['outlab_report'], 'file', 'extensions' => 'pdf'],
+ [['consult_outlab_report'], 'file', 'extensions' => 'pdf'],
+ [['age'], 'number'],
+ [['slides'], 'string', 'max' => 30],
+ [['o_n', 'v_n', 'a_n', 'express'], 'string', 'max' => 50]
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'patient_id' => 'Patient Id',
+ 'patient' => 'Patient',
+ 'hospital_id' => 'หน่วยงาน',
+ 'hospital' => 'หน่วยงาน',
+ 'id_case' => 'ID CASE',
+ 'case_reference' => 'Case Reference',
+ 'hos_ref' => 'Hospital Reference NO.',
+ 'title_id' => 'คำนำหน้า',
+ 'given_name' => 'ชื่อ',
+ 'surname' => 'นามสกุล',
+ 'gender' => 'เพศ',
+ 'nation' => 'เชื้อชาติ',
+ 'id_card' => 'หมายเลขบัตรประชาชน',
+ 'birthdate' => 'วัน/เดือน/ปี เกิด',
+ 'age' => 'อายุ',
+ 'age_unit' => 'หน่วยอายุ',
+ 'h_n' => 'H N',
+ 'a_n' => 'A N',
+ 'ward' => 'Ward',
+ 'ward_id' => 'Ward',
+ 'clinician' => 'Physician',
+ 'collected_at' => 'วันที่เก็บสิ่งส่งตรวจ',
+ 'receive_at' => 'วันที่รับสิ่งส่งตรวจ',
+ 'specimen' => 'Specimen',
+ 'section_label' => 'Section Label',
+ 'amount' => 'จำนวน Block',
+ 'amount_in' => 'ช่องจำนวนชิ้นเนื้อ',
+ 'cut_at' => 'วันตัดเนื้อ',
+ 'note_id' => 'ผู้จด',
+ 'cut_id' => 'ผู้ตัด',
+ 'bone' => 'bone',
+ 'bone_note' => 'bone_note',
+ 'block_type_id' => 'Block Type ID',
+ 'gross_img' => 'Gross Img',
+ 'clinical_diagnosis' => 'Clinical Information',
+ 'gross_description' => 'Gross Description',
+ 'gross_id' => 'ผู้พิมพ์ Gross',
+ 'gross_at' => 'พิมพ์ Gross เมื่อ',
+ 'microscopic_description' => 'Microscopic Description',
+ 'is_no_microscopic' => 'ไม่รายงาน Microscopic',
+ 'diagnosis' => 'Diagnosis',
+ 'additional_diagnosis' => 'Additional Report',
+ 'additional_at',
+ 'pathologist_id' => 'พยาธิแพทย์',
+ //'is_photograph' => 'Is Photograph',
+ //'is_museum' => 'Is Museum',
+ //'is_provisional' => 'Is Provisional',
+ 'is_consult' => 'Is Consult',
+ //'is_qa' => 'Is Qa',
+ 'is_conference' => 'Conference',
+ 'conference_at' => 'Conference At',
+ 'is_review' => 'Review',
+ 'status_id' => 'สถานะ',
+ 'doctor_id' => 'Clinician',
+ 'organ_id' => 'Organ',
+ 'report_at' => 'วันที่ออกผล',
+ 'decal_end_date' => 'วันสิ้นสุดการ Decal',
+ 'microscopic_img' => 'Microscopic Img',
+ 'register_id' => 'ผู้ลงทะเบียน',
+ 'register_at' => 'วันที่ลงทะเบียน',
+ 'autocomplete_hospital' => 'โรงพยาบาล',
+ 'autocomplete_patient' => 'ชื่อ นามสกุล',
+ 'autocomplete_ward' => 'Ward',
+ //'frozen_id_case' => 'Frozen ID Case',
+ 'is_immuno_staining' => 'ส่งย้อม Immuno',
+ 'is_histo_staining' => 'ส่งย้อม Histo',
+ //'center_box_open_id' => 'รายการเปิดกล่อง',
+ 'is_critical_diagnosis' => 'แจ้งแพทย์ด่วน Critical Diagnosis',
+ /*'consultant_id' => 'Consultant',
+ 'cons_pathologist_id' => 'Pathologist',
+ 'cons_pathologist' => 'Pathologist (ภายนอก)',*/
+ 'is_re_reference' => 'ดึงข้อมูลผลการตรวจเดิมอีกครั้ง',
+ 'is_outlab' => 'Case Outlab',
+ 'outlab_report' => 'Outlab Report File (PDF)',
+ 'is_consult_outlab' => 'Case Consult Outlab',
+ 'consult_outlab_report' => 'Consult Outlab Report File (PDF)',
+ 'charge_user_id' => 'ผู้ให้ราคา',
+ 'lab_order_number' => 'Lab order Number',
+ 'is_express' => 'ขอผลด่วน?',
+ 'express_at' => 'วันที่ขอผลด่วน',
+ 'express_day' => 'เลือกวันขอผลด่วน',
+ 'remark' => 'Remark',
+ 'rights_id' => 'สิทธิ์การรักษา',
+ 'is_molecular' => 'Molecular',
+ 'is_dish' => 'DISH',
+ 'is_frozen' => 'Frozen',
+ 'is_necropsy' => 'Necropsy',
+ 'remark_outlab' => 'Remark Outlab',
+ 'his_ln' => 'Lab Number',
+ 'house' => 'เลขที่บ้าน',
+ 'moo' => 'เลขที่หมู่/ชุมชน',
+ 'soy' => 'ชื่อตรอก/ซอย',
+ 'road' => 'ถนน',
+ 'tambon' => 'ตำบล',
+ 'amphur' => 'อำเภอ',
+ 'province' => 'จังหวัด',
+ 'postcode' => 'รหัสไปรษณีย์',
+ 'phone' => 'หมายเลขโทรศัพท์คนไข้',
+ 'email' => 'ที่อยู่จดหมายอิเลคทรอนิค',
+ 'marriage' => 'สภาพสมรส',
+ 'occupation' => 'อาชีพ',
+ 'religious' => 'ศาสนา',
+ 'race' => 'เชิ้อชาติ',
+ 'citizenship' => 'สัญชาติ',
+ 'is_flesh' => 'สถิติประกันชันสูตร',
+ 'is_stat_flesh' => 'ขนาดชิ้นเนื้อ',
+ 'bag' => 'จำนวนถุงชิ้นเนื้อ',
+ 'is_provincial_hospital' => 'รพช',
+ ];
+ }
+
+ public function attributeHints()
+ {
+ return [
+ 'collected_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'receive_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'cut_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'birthdate' => 'วัน/เดือน/ปี ค.ศ. เช่น 22/05/' . date('Y'),
+ 'conference_at' => 'วัน/เดือน/ปี ค.ศ. เช่น' . date('d/m/Y'),
+ 'decal_end_date' => 'วัน/เดือน/ปี ค.ศ เช่น 22/05/' . (date('Y')) . ' 09:10:07',
+ ];
+ }
+
+ public static function getNewTask()
+ {
+ return self::find()->where(['status_id' => 1])->count();
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstWard()
+ {
+ return $this->hasOne(ConstWard::class, ['id' => 'ward_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstDoctor()
+ {
+ return $this->hasOne(ConstDoctor::class, ['id' => 'doctor_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstRights()
+ {
+ return $this->hasOne(ConstRights::class, ['id' => 'rights_id']);
+ }
+
+ /**
+ * @return string
+ */
+ public function getFullname()
+ {
+ return Html::encode($this->given_name . ' ' . $this->surname);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegister()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getChangUser()
+ {
+ return $this->hasOne(User::class, ['id' => 'charge_user_id']);
+ }
+
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getGender()
+ {
+ return $this->hasOne(User::class, ['id' => 'gender_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPathologist()
+ {
+ return $this->hasOne(User::class, ['id' => 'pathologist_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegisterBy()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRepotType()
+ {
+ return $this->hasOne(ConstStatusReport::class, ['id' => 'name']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getTitle()
+ {
+ return $this->hasOne(PatientTitle::class, ['id' => 'title_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getLookUp()
+ {
+ return $this->hasOne(ConstLookup::class, ['lookuptypeid' => 'marriage']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatient()
+ {
+ return $this->hasOne(Patient::class, ['id' => 'patient_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getStatus()
+ {
+ return $this->hasOne(ConstStatus::class, ['id' => 'status_id']);
+ }
+
+ public function getWard()
+ {
+ return $this->hasOne(PatientWard::class, ['id' => 'ward']);
+ }
+
+ public function getGross()
+ {
+ return $this->hasOne(User::class, ['id' => 'gross_id']);
+ }
+
+ public function getSurgicalOperate()
+ {
+ return $this->hasOne(SurgicalOperate::class, ['id_case' => 'id_case']);
+ }
+
+ public function getSurgicalDiscard()
+ {
+ return $this->hasOne(SurgicalDiscard::class, ['id_case' => 'id_case']);
+ }
+
+ public function getHospital()
+ {
+ return $this->hasOne(ConstHospital::class, ['id' => 'hospital_id']);
+ }
+
+ public function getGrossEditBy()
+ {
+ return $this->hasOne(User::class, ['id' => 'gross_edit_by']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getChargeUser()
+ {
+ return $this->hasOne(User::class, ['id' => 'charge_user_id']);
+ }
+
+ public function getHospitals()
+ {
+ return $this->hasOne(ConstHospital::class, ['id' => 'hospital_id']);
+ }
+
+
+ /**
+ * @param $model
+ * @return false|string
+ * @throws \ImagickException
+ */
+ public function uploadMicro($model)
+ {
+ $files = UploadedFile::getInstances($model, 'microscopic_img');
+ if ($files) {
+ $file_names = [];
+
+ foreach ($files as $file) {
+ if ($file->extension == 'tiff' || $file->extension == 'tif') {
+ $file_name = $model->id_case . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ $image = new common\models\Imagick(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ @unlink(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ $file_name = $model->id_case . '_' . $file->baseName . '.png';
+ $image->setImageFormat('png');
+ $image->thumbnailImage(1024, 0);
+ $image->writeImage(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+ } else {
+ $file_name = $model->id_case . '_' . $file->baseName . '.' . $file->extension;
+
+ if ($file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name)) {
+ Image::getImagine()->open(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name)->thumbnail(new Box(1024, 1024))->save(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name, ['quality' => 100]);
+ }
+ }
+
+ $file_names[] = $file_name;
+ }
+ return implode(',', (ArrayHelper::merge($file_names, $this->getMicroImageToArray())));
+ }
+
+ return $model->isNewRecord ? false : $model->getOldAttribute('microscopic_img');
+ }
+
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getMicroImageToArray()
+ {
+ return !empty($this->getOldAttribute('microscopic_img')) ? explode(',', $this->getOldAttribute('microscopic_img')) : [];
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getMicroImage()
+ {
+ return !empty($this->microscopic_img) ? Yii::getAlias('@web') . '/' . $this->uploadMicroFolder . '/' . $this->microscopic_img : '';
+ }
+
+
+ /*
+ * upload Files
+ */
+ public function uploadFile($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = time() . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadFile . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getFileToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+
+ /**
+ * ขอชื่อไฟล์ทั้งหมด
+ */
+ public function getFiles()
+ {
+ if (empty($this->files) && !isset($this->files)) {
+ return [];
+ } else {
+ return !is_array($this->files) ? explode(',', $this->files) : [];
+ }
+ }
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLink()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a($val, Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']) . ' ';
+ }
+ }
+ return $rt;
+ }
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLinkImg()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['class' => 'img-fluid']), Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']);
+ }
+ }
+ return $rt;
+ }
+
+
+ /**
+ * นำไฟล์มาใส่ใน Array
+ */
+ public function getFileToArray()
+ {
+ return $this->getOldAttribute('files') ? @explode(',', $this->getOldAttribute('files')) : [];
+ }
+
+ /**
+ * @param $id_case
+ * @return array|mixed|\yii\db\ActiveRecord|null
+ */
+ public static function getNext($id_case)
+ {
+ $model = CaseSurgical::findOne(['id_case' => $id_case]);
+ $surgical = CaseSurgical::find()->where(['>', 'id', $model->id])->andWhere(['status_id' => 1])->orderBy(['id' => SORT_ASC])->one();
+ if ($surgical) {
+ return $surgical->id_case;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param null $id_case
+ * @return array|mixed|\yii\db\ActiveRecord|null
+ */
+ public static function getPrev($id_case = null)
+ {
+ $model = CaseSurgical::findOne(['id_case' => $id_case]);
+ $surgical = CaseSurgical::find()->where(['<', 'id', $model->id])->andWhere(['status_id' => 1])->orderBy(['id' => SORT_DESC])->one();
+ if ($surgical) {
+ return $surgical->id_case;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return bool|mixed|string|null
+ * @throws \yii\base\Exception
+ */
+ public function uploadGross($model, $attribute)
+ {
+ $grosses = UploadedFile::getInstances($model, $attribute);
+ FileHelper::createDirectory($this->getPath());
+ if ($grosses) {
+ $file_names = [];
+ foreach ($grosses as $gross) {
+ $file_name = $this->id_case . '_' . $gross->baseName . '.' . $gross->extension;
+ $gross->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadGross . '/' . $file_name);
+ $file_names[] = $file_name;
+ }
+ if ($this->isNewRecord) { //ถ้าเป็นการเพิ่ม Record ใหม่ให้บันทึกไฟล์ aaa.aaa,bbb.bbb ....
+ return implode(',', $file_names);
+ } else { //ถ้าเป็นการปรับปรุงให้เพิ่มจากของเดิม
+ return implode(',', ArrayHelper::merge($file_names, $this->getOldAttribute($attribute) ? explode(',', $this->getOldAttribute($attribute)) : []));
+ }
+ } //end files upload
+
+ return $this->isNewRecord ? false : $this->getOldAttribute($attribute); //ถ้าไม่มีการ upload ให้ใช้ข้อมูลเดิม
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getPath()
+ {
+ return Yii::getAlias('@webroot') . '/' . $this->uploadGross;
+ }
+
+ /**
+ * @return string
+ */
+ public function getFileUrl()
+ {
+ return Yii::getAlias('@web') . '/' . $this->uploadGross;
+ }
+
+
+ /**
+ * @return false|string[]
+ */
+ public function getGrosses()
+ {
+ return !is_array($this->gross_img) ? explode(',', $this->gross_img) : [];
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossImgs()
+ {
+ $img = '';
+ if (!empty($this->gross_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+ /**
+ * @return string
+ */
+ public function getGrossImgsForGross()
+ {
+ $img = '';
+ if (!empty($this->gross_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => '']), ['/surgical/gross/view-gross', 'id_case' => $this->id_case, 'gross_img' => $gross], ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossDelImgs()
+ {
+ $img = '';
+ if (!empty($this->gross_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= '
' . Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']) . '
' .
+ Html::a('Delete', ['delete-gross-img', 'img' => $gross, 'id_case' => $this->id_case], ['class' => 'btn btn-xs btn-danger', 'data' => ['confirm' => 'แน่ใจนะว่าต้องการลบรูปนี้?']])
+ . '
';
+ }
+ }
+ return $img;
+ }
+
+ /**
+ * @return string
+ */
+ public function getGrossCameraDelImgs()
+ {
+ $img = '';
+ $directoryPath = Yii::getAlias('@webroot') . '/uploads/surgical/gross/' . $this->id_case;
+
+ if (is_dir($directoryPath)) {
+ $files = \yii\helpers\FileHelper::findFiles($directoryPath);
+
+ if (!empty($files)) {
+ foreach ($files as $index => $file) {
+ $nameFicheiro = basename($file);
+ $filePath = Yii::getAlias('@web') . '/uploads/surgical/gross/' . $this->id_case . '/' . $nameFicheiro;
+ $img .= '
' . Html::a(Html::img($filePath, ['class' => 'img-fluid']), $filePath, ['target' => '_blank']) .
+ Html::a('Delete', ['delete-gross-img', 'img' => $nameFicheiro, 'id_case' => $this->id_case], ['class' => 'btn btn-xs btn-danger'])
+ . '
';
+ }
+ }
+ return $img;
+ }
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCaseRef()
+ {
+ return $this->hasOne(CaseSurgical::class, ['id_case' => 'id_case']);
+ }
+
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReportToArray()
+ {
+ return $this->getOldAttribute('outlab_report') ? @explode(',', $this->getOldAttribute('outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReport()
+ {
+ if (empty($this->outlab_report) || !isset($this->outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->outlab_report) ? explode(',', $this->outlab_report) : [];
+ }
+ }
+
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadConsultReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadConsultReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getConsultReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getConsultReportToArray()
+ {
+ return $this->getOldAttribute('consult_outlab_report') ? @explode(',', $this->getOldAttribute('consult_outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getConsultReport()
+ {
+ if (empty($this->consult_outlab_report) || !isset($this->consult_outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->consult_outlab_report) ? explode(',', $this->consult_outlab_report) : [];
+ }
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCut()
+ {
+ return $this->hasOne(User::class, ['id' => 'cut_id']);
+ }
+ public function getIsExpress()
+ {
+ return $this->hasOne(CaseSurgical::class, ['id' => 'is_express']);
+ }
+}
diff --git a/console/controllers/LisSendPathoController.php b/console/controllers/LisSendPathoController.php
new file mode 100644
index 00000000..65c39f6d
--- /dev/null
+++ b/console/controllers/LisSendPathoController.php
@@ -0,0 +1,557 @@
+where(['LabNo', ['LabNo' => null]])
+ ->where(['LabNo' => 'OR25121300814'])
+ ->andWhere(['not', ['HN' => null]])
+ ->andWhere(['<>', 'LabNo', ''])
+ ->andWhere(['<>', 'HN', ''])
+ ->asArray()
+ ->orderBy(['ID' => SORT_DESC])
+ ->one();
+
+ error_log("Total records: " . count($query));
+
+ $sendMapping = [];
+
+ // config
+ /*$cfg = Yii::$app->params['external_api'] ?? null;
+ if (!$cfg || empty($cfg['receiveUrl'])) {
+ error_log("Missing external_api config or receiveUrl");
+ return 1;
+ }
+
+ // get token
+ $tokenError = null;
+ $token = $this->getValidApiToken($cfg, $tokenError);
+ if (empty($token)) {
+ error_log("Cannot obtain valid API token: " .
+ (is_array($tokenError) ? json_encode($tokenError) : ($tokenError ?? 'unknown')));
+ return 1;
+ }
+
+ $url = $cfg['receiveUrl'];
+ error_log("Using API token (ready to send)");*/
+
+ // ---------- build grouped payloads ----------
+ $groupedByLabNo = [];
+ $groupedRows = []; // เก็บแถวต้นฉบับต่อ labNo เพื่อใช้บันทึก LisResult ทีหลัง
+
+ $labNo = $query['LabNo'];
+ $labNoNumeric = substr($labNo, 2);
+
+ $query_lab = PatientCaseApprove::find()
+ ->alias('pc')
+ ->select([
+ 'pc.id_case',
+ 'pc.ln',
+ 'pc.h_n',
+ 'pc.report_at',
+ 'pc.approve_at',
+ 'pc.pathologist',
+ 'pc.approve_status',
+
+ 'hr.ID AS HisRequestID',
+ 'hr.LabNo AS HisLabNo',
+
+ 'tl.TestCode',
+ 'tl.TestName',
+ ])
+ ->leftJoin(
+ ['hr' => 'HisRequest'],
+ 'hr.LabNo LIKE CONCAT("%", :labno, "%")',
+ [':labno' => $labNoNumeric]
+ )
+ ->leftJoin(
+ ['tl' => 'HisRequestTestList'],
+ 'tl.HisRequestID = hr.ID'
+ )
+ ->where(['not', ['pc.id_case' => null]])
+ ->andWhere(['<>', 'pc.id_case', ''])
+ ->andWhere(['like', 'pc.ln', $labNoNumeric])
+ ->andWhere(['not', ['pc.report_at' => null]])
+ ->andWhere(['<>', 'pc.report_at', ''])
+ ->andWhere(['not', ['pc.approve_at' => null]])
+ ->andWhere(['<>', 'pc.approve_at', ''])
+ ->andWhere(['pc.approve_status' => 4])
+ ->orderBy(['pc.approve_at' => SORT_DESC])
+ ->asArray()
+ ->all();
+
+
+ foreach ($query_lab as $rows) {
+ $filesData = [];
+ $timestamp = date('dmYHis');
+ $labNo = $rows['LabNo'] ?? '';
+ $idCase = $rows['id_case'] ?? '';
+ $hn = $rows['h_n'] ?? '';
+
+ if (!empty($idCase)) {
+ $LisResultUrl = "https://pathology.prolab.co.th/reports/H1263/{$labNo}_{$hn}_Prolab-{$idCase}.pdf";
+ $pdfContent = $this->fetchUrl($LisResultUrl, 20);
+ if ($pdfContent !== false && strlen($pdfContent) > 0) {
+ $filesData[] = [
+ 'FileName' => "{$labNo}_{$timestamp}.pdf",
+ 'Filebase64' => base64_encode($pdfContent),
+ ];
+ }
+ }
+
+ // build test item
+ $testItem = [
+ 'TestCode' => (string)($rows['TestCode'] ?? ''),
+ 'TestName' => (string)($rows['TestName'] ?? ''),
+ 'TestRemark' => '',
+ 'InformCriticalByCode' => '',
+ 'InformCriticalBy' => '',
+ 'InformCriticalTo' => '',
+ 'InformCriticalDateTime' => '',
+ 'CriticalFlag' => '',
+ 'ReportResultByCode' => '',
+ 'ReportResultBy' => (string)($rows['pathologist'] ?? ''),
+ 'ReportResultDateTime' => $this->dateTimeFormat($rows['report_at'] ?? ''),
+ 'ApproveResultByCode' => '',
+ 'ApproveResultBy' => (string)($rows['pathologist'] ?? ''),
+ 'ApproveResultDateTime' => $this->dateTimeFormat($rows['approve_at'] ?? ''),
+ 'Filedata' => $filesData,
+ 'ResultList' => [[
+ 'ResultCode' => (string)($rows['ResultCode'] ?? ''),
+ 'ResultName' => (string)($rows['ResultName'] ?? ''),
+ 'ResultValue' => '',
+ 'ResultUnit' => '',
+ 'ResultFlag' => '',
+ 'ReferenceRange' => '',
+ 'ResultRemark' => '',
+ ]],
+ ];
+
+ if (!isset($groupedByLabNo[$labNo])) {
+ $groupedByLabNo[$labNo] = [
+ 'LabNo' => $labNo,
+ 'RequestRemark' => '',
+ 'ResultStatus' => '',
+ 'TestList' => [],
+ ];
+ }
+
+ $groupedByLabNo[$labNo]['TestList'][] = $testItem;
+ $groupedRows[$labNo][] = $rows; // เก็บแถวต้นฉบับต่อ lab
+ $sendMapping[$rows['id_case']] = $rows['id_case'];
+ } // end foreach build
+
+ // ---------- ส่งแต่ละ payload ที่ grouped ----------
+ /*foreach ($groupedByLabNo as $labNo => $payload) {
+ if (empty($payload) || !isset($payload['LabNo'])) {
+ $labKey = $payload['LabNo'] ?? ($labNo ?? '(unknown)');
+ error_log("Skipping send: payload missing LabNo for key={$labKey}");
+ continue;
+ }
+
+ $payloadJson = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
+ $payloadJson = ($payloadJson === false) ? var_export($payload, true) : $payloadJson;
+ error_log("Payload (truncated): " . $this->truncateForLog($payloadJson, 8192));
+
+ $tests = array_map(function ($t) {
+ $code = $t['TestCode'] ?? '(noCode)';
+ $name = $t['TestName'] ?? '(noName)';
+ return $code . ':' . $name;
+ }, $payload['TestList'] ?? []);
+
+ error_log("Sending payload for LabNo={$labNo} (tests=" . json_encode($tests, JSON_UNESCAPED_UNICODE) . ")");
+
+ $response = $this->postJsonCurl($url, $payload, [
+ 'Authorization' => "Bearer {$token}",
+ 'Content-Type' => 'application/json',
+ ]);
+
+ $lastResponse = $response;
+ $rawResp = $response['response'] ?? '';
+ $httpCode = (int)($response['http_code'] ?? 0);
+ $curlErr = $response['curl_error'] ?? null;
+
+ if (!empty($curlErr)) {
+ error_log("WARNING: cURL error: {$curlErr}");
+ }
+
+ if ($httpCode === 401) {
+ error_log("401 Unauthorized received — refreshing token and retrying");
+ $token = $this->getValidApiToken($cfg, $tokenError);
+ if (!empty($token)) {
+ error_log("Retrying with refreshed token. Payload (truncated): " . $this->truncateForLog($payloadJson, 8192));
+ $response = $this->postJsonCurl($url, $payload, [
+ 'Authorization' => "Bearer {$token}",
+ 'Content-Type' => 'application/json',
+ ]);
+ $lastResponse = $response;
+ $rawResp = $response['response'] ?? '';
+ $httpCode = (int)($response['http_code'] ?? 0);
+ $curlErr = $response['curl_error'] ?? null;
+ if (!empty($curlErr)) {
+ error_log("WARNING: cURL error on retry: {$curlErr}");
+ }
+ } else {
+ error_log("ERROR: Failed to refresh token after 401");
+ }
+ }
+
+ error_log("Response (http={$httpCode}): " . $this->truncateForLog((string)$rawResp, 8192));
+
+ // decode and check success
+ $decoded = json_decode($rawResp, true);
+ $statusVal = $decoded['Status'] ?? $decoded['status'] ?? null;
+ $messageVal = $decoded['Message'] ?? $decoded['message'] ?? '';
+
+ $success = false;
+ if (is_numeric($statusVal)) {
+ $success = (intval($statusVal) === 0);
+ } elseif (is_string($statusVal) && strtolower($statusVal) === 'success') {
+ $success = true;
+ } elseif (is_string($messageVal) && strpos(strtolower($messageVal), 'success') !== false) {
+ $success = true;
+ } elseif (is_string($rawResp) && strpos(strtolower($rawResp), '"status":0') !== false) {
+ $success = true;
+ }
+
+ if ($success) {
+ error_log("Success LabNo={$labNo}");
+
+ // บันทึก LisResult สำหรับทุก TestList ใน lab นี้
+ $testList = $payload['TestList'] ?? [];
+ foreach ($testList as $testItem) {
+ $testCode = (string)($testItem['TestCode'] ?? '');
+ $testName = (string)($testItem['TestName'] ?? '');
+ $resultValue = $testItem['ResultList'][0]['ResultValue'] ?? '';
+ $resultUnit = $testItem['ResultList'][0]['ResultUnit'] ?? '';
+ $referenceRange = $testItem['ResultList'][0]['ReferenceRange'] ?? '';
+
+ // หาแถวต้นฉบับที่ตรงกับ testCode เพื่อดึง CustID/HN/RiaHDocID ถ้ามี
+ $matchRow = null;
+ if (!empty($groupedRows[$labNo])) {
+ foreach ($groupedRows[$labNo] as $r) {
+ if ((string)($r['TestCode'] ?? '') === $testCode) {
+ $matchRow = $r;
+ break;
+ }
+ }
+ }
+ // ถ้าไม่พบ ให้ใช้แถวแรกเป็น fallback (ถ้ามี)
+ if ($matchRow === null && !empty($groupedRows[$labNo])) {
+ $matchRow = $groupedRows[$labNo][0];
+ }
+
+ $custId = $matchRow['CustID'] ?? null;
+ $hn = $matchRow['PatHN'] ?? null;
+ $riahDocId = $matchRow['RiaHDocID'] ?? null;
+ $riahDocDate = $matchRow['RiaHDocDate'] ?? null;
+
+ // ตรวจสอบว่ามีอยู่แล้วหรือยัง (ใช้ lab_no + test_code + cust_id + hn)
+ $existsQuery = [
+ 'lab_no' => $labNo,
+ 'test_code' => $testCode,
+ ];
+ if ($custId !== null) $existsQuery['cust_id'] = $custId;
+ if ($hn !== null) $existsQuery['hn'] = $hn;
+
+ $exists = LisResult::find()->where($existsQuery)->exists();
+
+ if (!$exists) {
+ $LisResult = new LisResult([
+ 'lab_no' => $labNo,
+ 'riah_doc_id' => $riahDocId ?? '',
+ 'riah_doc_date' => $riahDocDate ?? '',
+ 'test_code' => $testCode,
+ 'test_name' => $testName,
+ 'cust_id' => $custId ?? '',
+ 'hn' => $hn,
+ 'result_value' => $resultValue ?? '',
+ 'result_unit' => $resultUnit ?? '',
+ 'reference_range' => $referenceRange ?? '',
+ 'status' => 1,
+ ]);
+ $LisResult->save(false);
+ } else {
+ trigger_error("Record already exists in LisResult, skipping insert: LabNo={$labNo}, TestCode={$testCode}, CustID={$custId}, HN={$hn}", E_USER_WARNING);
+ }
+ } // end foreach testList
+ } else {
+ $msg = $lastResponse['response'] ?? ($lastResponse['curl_error'] ?? 'ไม่พบข้อมูลตอบกลับ');
+ error_log("FAIL LabNo={$labNo}; last_http=" . ($lastResponse['http_code'] ?? 'ไม่พบข้อมูลตอบกลับ') . "; message=" . $this->truncateForLog($msg, 1024));
+ }
+
+ // optional small delay: usleep(200000);
+ } // end foreach groupedByLabNo*/
+
+ error_log("=== Hanuman Result Sikarin Patho END ===");
+
+ var_dump($groupedByLabNo);
+ die();
+ //return 0;
+ }
+
+ /** helper: ส่ง JSON ผ่าน cURL (คืนข้อมูล debug เต็ม) */
+ protected function postJsonCurl($url, $payload, $headers = [])
+ {
+ $ch = curl_init($url);
+ $jsonPayload = json_encode($payload, JSON_UNESCAPED_UNICODE);
+
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonPayload);
+
+ // security: allow config to control SSL verify
+ $verifySsl = Yii::$app->params['external_api']['verify_ssl'] ?? true;
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verifySsl);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $verifySsl ? 2 : 0);
+
+ curl_setopt($ch, CURLOPT_TIMEOUT, 60);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+
+ $curlHeaders = ['Content-Type: application/json', 'Accept: application/json', 'Expect:', 'User-Agent: MyLabSender/1.0'];
+ foreach ($headers as $k => $v) {
+ if (is_int($k)) {
+ $curlHeaders[] = $v;
+ } else {
+ $curlHeaders[] = "{$k}: {$v}";
+ }
+ }
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders);
+
+ $response = curl_exec($ch);
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ $curlErrno = curl_errno($ch);
+ $curlError = $curlErrno ? curl_error($ch) : null;
+ curl_close($ch);
+
+ return [
+ 'http_code' => $httpCode,
+ 'response' => $response,
+ 'curl_error' => $curlError,
+ 'curl_errno' => $curlErrno,
+ 'url' => $url,
+ 'payload_size' => strlen($jsonPayload),
+ ];
+ }
+
+ /**
+ * helper: fetch URL via cURL (robust)
+ */
+ protected function fetchUrl($url, $timeout = 10)
+ {
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ $data = curl_exec($ch);
+ $http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ $err = curl_errno($ch) ? curl_error($ch) : null;
+ curl_close($ch);
+
+ if ($data === false || $http >= 400) {
+ //$this->logConsole("fetchUrl failed: {$url} http={$http} err=" . ($err ?? 'none'), 'warning');
+ error_log("fetchUrl failed: {$url} http={$http} err=" . ($err ?? 'none'), 'warning');
+ return false;
+ }
+ return $data;
+ }
+
+ /**
+ * Log helper — writes to STDOUT with timestamp and also to Yii log.
+ * $level: 'info'|'warning'|'error'
+ */
+ protected function logConsole($message, $level = 'info')
+ {
+ $time = date('Y-m-d H:i:s');
+ $line = "[{$time}] {$message}" . PHP_EOL;
+ // write to console
+ $this->stdout($line);
+ // write to Yii logger with appropriate level
+ switch (strtolower($level)) {
+ case 'error':
+ Yii::error($message, __METHOD__);
+ break;
+ case 'warning':
+ Yii::warning($message, __METHOD__);
+ break;
+ default:
+ Yii::info($message, __METHOD__);
+ }
+ }
+
+ /**
+ * Truncate long strings for logging. $maxBytes = null => no truncation.
+ */
+ protected function truncateForLog($text, $maxBytes = 4096)
+ {
+ if ($text === null) return '';
+ if ($maxBytes === null) return $text;
+ $len = strlen($text);
+ if ($len <= $maxBytes) return $text;
+ $prefix = substr($text, 0, $maxBytes);
+ return $prefix . "\n...TRUNCATED... (original_length={$len})";
+ }
+
+ /** helper: แปลง datetime เป็น dd/mm/YYYY H:i:s */
+ public function dateTimeFormat($value)
+ {
+ if (empty($value)) return '';
+ try {
+ $dt = new \DateTime($value);
+ return $dt->format('d/m/Y H:i:s');
+ } catch (\Throwable $e) {
+ return '';
+ }
+ }
+
+ /**
+ * ขอ token จาก API (คืนค่า associative array แบบ {ok, token, expires_at, http_code, raw, error})
+ */
+ protected function getApiToken($cfg)
+ {
+ $tokenUrl = $cfg['tokenUrl'] ?? Yii::$app->params['external_api']['tokenUrl'] ?? null;
+ $username = $cfg['username'] ?? Yii::$app->params['external_api']['username'] ?? null;
+ $password = $cfg['password'] ?? Yii::$app->params['external_api']['password'] ?? null;
+
+ $payload = ['username' => $username, 'password' => $password];
+
+ $ch = curl_init($tokenUrl);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
+ curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json']);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 15);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+
+ $raw = curl_exec($ch);
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ $curlErr = curl_errno($ch) ? curl_error($ch) : null;
+ curl_close($ch);
+
+ $result = ['ok' => false, 'token' => null, 'expires_at' => null, 'http_code' => $httpCode, 'raw' => $raw, 'error' => null];
+
+ if ($raw === false || $curlErr) {
+ $result['error'] = 'cURL error: ' . ($curlErr ?? 'unknown');
+ return $result;
+ }
+
+ $decoded = json_decode($raw, true);
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ $result['error'] = 'Invalid JSON response from token endpoint';
+ return $result;
+ }
+
+ if (!empty($decoded['access_token'])) {
+ $result['ok'] = true;
+ $result['token'] = $decoded['access_token'];
+ $expiresIn = intval($decoded['expires_in'] ?? 3600);
+ $result['expires_at'] = date('Y-m-d H:i:s', time() + $expiresIn);
+ } elseif (!empty($decoded['token'])) {
+ $result['ok'] = true;
+ $result['token'] = $decoded['token'];
+ $expiresIn = intval($decoded['expires_in'] ?? 3600);
+ $result['expires_at'] = date('Y-m-d H:i:s', time() + $expiresIn);
+ } else {
+ $result['error'] = $decoded['error'] ?? ($decoded['message'] ?? 'No token in response');
+ }
+
+ return $result;
+ }
+
+ /**
+ * ดึง token ที่ valid (คืน token string หรือ null และตั้ง $tokenError หากมีปัญหา)
+ * พร้อม debug log วันที่หมดอายุของ Token
+ */
+ protected function getValidApiToken($cfg, &$tokenError = null)
+ {
+ $apiName = $cfg['apiName'] ?? 'gems_api';
+ $tokenModel = ApiToken::find()->where(['api_name' => $apiName])->one();
+ $token = null;
+ $nowTs = time();
+ $refreshMargin = $cfg['refreshMargin'] ?? 300; // 5 นาที
+
+ $needRequest = !$tokenModel || (strtotime($tokenModel->expires_at) <= ($nowTs + $refreshMargin));
+
+ if ($tokenModel) {
+ //$this->logConsole("Token in DB found for {$apiName}: expires_at={$tokenModel->expires_at}, token_prefix=" . substr($tokenModel->token ?? '', 0, 15) . "...");
+ error_log("Token in DB found for {$apiName}: expires_at={$tokenModel->expires_at}, token_prefix=" . substr($tokenModel->token ?? '', 0, 15) . "...");
+ } else {
+ error_log("No token found in DB for {$apiName}, will request new token");
+ //$this->logConsole("No token found in DB for {$apiName}, will request new token");
+ }
+
+ if ($needRequest) {
+ $tokenResp = $this->getApiToken($cfg);
+
+ if (empty($tokenResp) || empty($tokenResp['ok'])) {
+ $tokenError = [
+ 'message' => 'Failed to get token from API',
+ 'tokenUrl' => $cfg['tokenUrl'] ?? null,
+ 'error' => $tokenResp['error'] ?? 'Unknown error',
+ 'http_code' => $tokenResp['http_code'] ?? 0,
+ 'raw' => $tokenResp['raw'] ?? null,
+ ];
+
+ if ($tokenModel && !empty($tokenModel->token)) {
+ error_log("Using old token as fallback (expires_at={$tokenModel->expires_at})");
+ //$this->logConsole("Using old token as fallback (expires_at={$tokenModel->expires_at})");
+ return $tokenModel->token; // fallback
+ }
+
+ return null;
+ }
+
+ $token = $tokenResp['token'];
+ $expiresAt = $tokenResp['expires_at'] ?? date('Y-m-d H:i:s', time() + 3600);
+
+ if (!$tokenModel) {
+ $tokenModel = new ApiToken();
+ $tokenModel->api_name = $apiName;
+ }
+
+ $tokenModel->token = $token;
+ $tokenModel->expires_at = $expiresAt;
+
+ try {
+ $tokenModel->save(false);
+ error_log("New token saved: api_name={$apiName}, expires_at={$expiresAt}, token_prefix=" . substr($token ?? '', 0, 15) . "...");
+ //$this->logConsole("New token saved: api_name={$apiName}, expires_at={$expiresAt}, token_prefix=" . substr($token, 0, 15) . "...");
+ } catch (\Throwable $e) {
+ //$this->logConsole("Error saving new token: " . $e->getMessage(), 'error');
+ error_log("Error saving new token: " . $e->getMessage(), 'error');
+ if ($tokenModel && !empty($tokenModel->token)) {
+ return $tokenModel->token; // fallback
+ }
+ $tokenError = $e->getMessage();
+ return null;
+ }
+ } else {
+ $token = $tokenModel->token;
+ //$this->logConsole("Reusing valid token: expires_at={$tokenModel->expires_at}, token_prefix=" . substr($token, 0, 15) . "...");
+ error_log("Reusing valid token: expires_at={$tokenModel->expires_at}, token_prefix=" . substr($token, 0, 15) . "...");
+ }
+ return $token;
+ }
+}
diff --git a/console/models/CaseNonGyn.php b/console/models/CaseNonGyn.php
new file mode 100644
index 00000000..4bb50801
--- /dev/null
+++ b/console/models/CaseNonGyn.php
@@ -0,0 +1,893 @@
+get('patho');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [['id_case', 'hospital_id', 'given_name', 'title_id'], 'required', 'on' => 'register'],
+ [['pathologist_id'], 'required', 'on' => 'update'],
+ [['is_type_specimen'], 'required', 'on' => 'cyto'],
+ [['autocomplete_patient', 'hos_ref', 'house', 'moo', 'soy', 'road', 'phone', 'email', 'post_review_diagnosis'], 'string'],
+ [['id_case'], 'unique'],
+ [['diagnosis'], 'required', 'on' => 'pathologist'],
+ [['title_id', 'is_histo_staining', 'specimen_type_id', 'specimen_id', 'is_stained', 'register_id', 'is_restain', 'is_pathologist_ot', 'specimen_adequacy', 'specimen_adequacy_1', 'specimen_adequacy_2', 'pathologist_id', 'status_id', 'is_print', 'is_critical_diagnosis', 'is_outlab', 'is_consult_outlab', 'cytotech1_id', 'hospital_id', 'lab_order_number', 'is_no_microscopic', 'is_express', 'ward_id', 'rights_id', 'doctor_id', 'organ_id', 'order_point_id', 'hospital_import_id', 'order_by_id'/*, 'smears_receive', 'smears_processed', 'is_effusion', 'is_non_gyn_direction', 'is_fna', 'is_fna_direction'*/, 'const_rights_id', 'specimen_img_update_id', 'tambon', 'amphur', 'province', 'postcode', 'marriage', 'occupation', 'religious', 'race', 'citizenship', 'is_cell_block', 'is_molecular', 'is_conference', 'is_type_specimen', 'is_provincial_hospital', 'is_review'], 'integer'],
+ [['id_case', 'given_name', 'surname', 'gender', 'nation', 'id_card', 'age_unit', 'h_n', 'a_n', 'v_n', 'o_n', 'ward', 'clinician', 'collect_method', 'organ_and_location', 'side_of_specimen', 'fluid_volume', 'fluid_appearance', 'fluid_colour', 'fluid_description', 'clinical_diagnosis', 'clinical_diagnosis_his', 'adequacy_other', 'finding', 'screener_diagnosis', 'diagnosis', 'suggestion', 'cyto_side_of_specimen', 'additional_diagnosis', 'microscopic', 'gross_description', 'cytotech1_at', 'remark', 'non_gyn_specimen_other', 'cell_block_at'/*'fna_quantity', 'fna_slide', 'non_gyn_bal', 'non_gyn_other', 'fna_neck', 'fna_lymph_node', 'fna_salivary_gland', 'fna_other'*/, 'remark_consult_outlab', 'remark_report'], 'string'],
+ [['register_at', 'birthdate', 'collected_at', 'conference_at', 'report_at', 'patient_id', 'additional_at', 'receive_at', 'express_at'/*, 'non_gyn_type', 'fna_type'*/, 'express_day', 'specimen_img_at', 'review_at'], 'safe'],
+ [['age', 'no_slide', 'no_bottle', 'no_slide_dry_smear', 'is_provisional', 'is_consult', 'is_qa'], 'number'],
+ [['his_ln', 'v_date', 'verify_date'], 'string', 'max' => 100],
+ [['express'], 'string', 'max' => 50],
+ [['outlab_report'], 'file', 'extensions' => 'pdf'],
+ [['consult_outlab_report'], 'file', 'extensions' => 'pdf'],
+ [['files'], 'file', 'extensions' => 'pdf,jpg,png,gif,doc,docx,xls,xlsx,ppt,pptx,jpeg'],
+ [['microscopic_img'], 'file', 'extensions' => 'jpeg,jpg,png,gif'],
+ [['specimen_img'], 'file', 'extensions' => 'jpeg,jpg,png,gif,tif,tiff', 'skipOnEmpty' => true, 'maxFiles' => 10],
+ [['specimen_type_id'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimenType::class, 'targetAttribute' => ['specimen_type_id' => 'id']],
+ [['status_id'], 'exist', 'skipOnError' => true, 'targetClass' => ConstStatus::class, 'targetAttribute' => ['status_id' => 'id']],
+ [['specimen_id'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimen::class, 'targetAttribute' => ['specimen_id' => 'id']],
+ [['specimen_adequacy'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimenAdequacy::class, 'targetAttribute' => ['specimen_adequacy' => 'id']],
+ //[['patient_id'], 'exist', 'skipOnError' => true, 'targetClass' => Patient::class, 'targetAttribute' => ['patient_id' => 'id']],
+ [['pathologist_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::class, 'targetAttribute' => ['pathologist_id' => 'id']],
+ ];
+ }
+
+ public function scenarios()
+ {
+ $scenarios = parent::scenarios();
+ $scenarios['register'] = [
+ 'hospital_id',
+ 'patient_id',
+ 'id_case',
+ 'a_n',
+ 'ward',
+ 'clinician',
+ 'collected_at',
+ 'collect_method',
+ 'specimen_type_id',
+ 'specimen_id',
+ 'organ_and_location',
+ 'side_of_specimen',
+ 'no_slide',
+ 'is_stained',
+ 'is_restain',
+ //'clinical_diagnosis',
+ 'is_pathologist_ot',
+ 'no_slide_dry_smear',
+ 'fluid_volume',
+ 'fluid_appearance',
+ 'fluid_colour',
+ 'cyto_side_of_specimen'
+ ];
+ $scenarios['process'] = [
+ 'patient_id',
+ 'id_case',
+ 'no_slide',
+ 'sterilize',
+ 'previous_treatment',
+ 'specimen_adequacy',
+ 'specimen_adequacy_1',
+ 'specimen_adequacy_2',
+ 'general_categorization',
+ 'general_categorization_1',
+ 'pathologist_id',
+ 'is_provisional',
+ 'is_consult',
+ 'is_qa',
+ 'is_conference',
+ 'status_id',
+ 'is_print',
+ 'finding',
+ 'clinical_finding',
+ //'clinical_diagnosis',
+ 'last_pap',
+ 'last_pregnancy',
+ 'adequacy_other',
+ 'categorization_other',
+ 'screener_diagnosis',
+ 'suggestion',
+ 'diff_qa',
+ 'hospital_id',
+ ];
+ return $scenarios;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'hospital_id' => 'หน่วยงาน',
+ //'patient_id' => 'ผู้ป่วย',
+ 'hospital' => 'หน่วยงาน',
+ 'patient' => 'ชื่อ - นามสกุล',
+ 'pathologist' => 'พยาธิแพทย์',
+ 'pathologist_id' => 'พยาธิแพทย์',
+ 'autocomplete_patient' => 'ผู้ป่วย',
+ 'id_case' => 'ID CASE',
+ 'title_id' => 'คำนำหน้า',
+ 'given_name' => 'ชื่อ',
+ 'surname' => 'นามสกุล',
+ 'gender' => 'เพศ',
+ 'nation' => 'เชื้อชาติ',
+ 'id_card' => 'หมายเลขบัตรประชาชน',
+ 'birthdate' => 'วัน/เดือน/ปี เกิด',
+ 'age' => 'อายุ',
+ 'age_unit' => 'หน่วยอายุ',
+ 'h_n' => 'HN',
+ 'a_n' => 'AN',
+ 'v_n' => 'VN',
+ 'o_n' => 'Order Number',
+ 'ward' => 'Ward',
+ 'ward_id' => 'Ward',
+ 'clinician' => 'Physician',
+ 'doctor_id' => 'Clinician',
+ 'organ_id' => 'Organ',
+ 'collected_at' => 'วันที่เก็บสิ่งส่งตรวจ',
+ 'receive_at' => 'วันที่รับสิ่งส่งตรวจ',
+ 'collect_method' => 'Collect Method',
+ 'specimen_type_id' => 'Specimen Type',
+ 'specimen_id' => 'Specimen',
+ 'organ_and_location' => 'Specimen', //Organ And Location
+ 'cyto_side_of_specimen' => 'Side Of Specimen',
+ 'cytotech1_id' => 'Cytotech',
+ 'side_of_specimen' => 'Side Of Specimen',
+ 'no_slide' => 'จำนวน Slide',
+ 'no_bottle' => 'จำนวน ขวด',
+ 'quantity' => 'quantity',
+ 'no_slide_dry_smear' => 'Slide Dry Smear',
+ 'fluid_volume' => 'Amount',
+ 'fluid_appearance' => 'Turbidity',
+ 'fluid_colour' => 'Colour',
+ 'fluid_description' => 'Description',
+ 'is_stained' => 'Stained',
+ 'is_restain' => 'Restain',
+ 'is_critical_diagnosis' => 'แจ้งแพทย์ด่วน Critical Diagnosis',
+ 'clinical_diagnosis' => 'Clinical Diagnosis',
+ 'clinical_diagnosis_his' => 'Clinical Diagnosis',
+ 'specimen_adequacy' => 'Specimen Adequacy',
+ 'specimen_adequacy_1' => 'Specimen Adequacy 1',
+ 'specimen_adequacy_2' => 'Specimen Adequacy 2',
+ 'adequacy_other' => 'Adequacy Other',
+ 'gross_description' => 'Gross Description',
+ 'microscopic' => 'MICROSCOPIC FINDINGS',
+ 'is_no_microscopic' => 'ไม่รายงาน Microscopic Description',
+ 'diagnosis' => 'CYTOLOGIC DIAGNOSIS',
+ 'additional_diagnosis' => 'Additional Diagnosis',
+ 'suggestion' => 'Suggestion',
+ 'pathologist_id' => 'Pathologist',
+ 'status_id' => 'Status',
+ 'report_at' => 'Report At',
+ 'register_at' => 'วันที่ลงทะเบียน',
+ 'register_id' => 'ผู้ลงทะเบียน',
+ 'lab_order_number' => 'Lab Order Number',
+ 'is_express' => 'ขอผลด่วน?',
+ 'express_day' => 'เลือกวันขอผลด่วน',
+ 'express_at' => 'วันที่ขอผลด่วน',
+ 'smears_receive' => 'Receive',
+ 'smears_processed' => 'Processed',
+ 'smears_remark' => 'Description',
+ 'remark' => 'Remark',
+ 'rights_id' => 'สิทธิ์การรักษา',
+ 'is_cell_block' => 'สั่ง Cell block',
+ 'cell_block_at' => 'ส่ง Cell block เมื่อ',
+ 'specimen_img' => 'Specimen Image',
+ 'is_outlab' => 'Case Outlab',
+ 'his_ln' => 'Lab Number',
+ 'house' => 'บ้านเลขที่',
+ 'moo' => 'หมู่ที่/ชุมชน',
+ 'soy' => 'ตรอก/ซอย',
+ 'road' => 'ถนน',
+ 'tambon' => 'ตำบล',
+ 'amphur' => 'อำเภอ',
+ 'province' => 'จังหวัด',
+ 'postcode' => 'รหัสไปรษณีย์',
+ 'phone' => 'หมายเลขโทรศัพท์คนไข้',
+ 'email' => 'Email',
+ 'marriage' => 'สถานภาพสมรส',
+ 'occupation' => 'อาชีพ',
+ 'religious' => 'ศาสนา',
+ 'race' => 'เชิ้อชาติ',
+ 'citizenship' => 'สัญชาติ',
+ 'is_type_specimen' => 'รายงานผล',
+ 'is_provincial_hospital' => 'รพช',
+ 'is_review' => 'Review',
+ 'is_molecular' => 'Molecular',
+ ];
+ }
+
+ /**
+ * @return string[]
+ */
+ public function attributeHints()
+ {
+ return [
+ 'collected_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'receive_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'birthdate' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y'),
+ 'conference_at' => 'วัน/เดือน/ปี ค.ศ. เช่น' . date('d/m/Y'),
+ 'no_slide' => 'กรอกเฉพาะตัวเลขเท่านั้น',
+ 'no_slide_dry_smear' => 'กรอกเฉพาะตัวเลขเท่านั้น',
+ ];
+ }
+
+ /**
+ * @return string
+ */
+ public function getFullname()
+ {
+ return Html::encode($this->given_name . ' ' . $this->surname);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatientDiag()
+ {
+ return $this->hasOne(PatientCaseDiagnosis::class, ['h_n' => 'h_n']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstWard()
+ {
+ return $this->hasOne(ConstWard::class, ['id' => 'ward_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getOrgan()
+ {
+ return $this->hasOne(ConstOrgan::class, ['id' => 'organ_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstDoctor()
+ {
+ return $this->hasOne(ConstDoctor::class, ['id' => 'doctor_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstRights()
+ {
+ return $this->hasOne(ConstRights::class, ['id' => 'rights_id']);
+ }
+
+ public function getHospital()
+ {
+ return $this->hasOne(ConstHospital::class, ['id' => 'hospital_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegister()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+
+ public function getTitle()
+ {
+ return $this->hasOne(PatientTitle::class, ['id' => 'title_id']);
+ }
+
+ public function getWard()
+ {
+ return $this->hasOne(PatientWard::class, ['id' => 'ward']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenType()
+ {
+ return $this->hasOne(CytoSpecimenType::class, ['id' => 'specimen_type_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getStatus()
+ {
+ return $this->hasOne(ConstStatus::class, ['id' => 'status_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCytotech()
+ {
+ return $this->hasOne(User::class, ['id' => 'cytotech1_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimen()
+ {
+ return $this->hasOne(CytoSpecimen::class, ['id' => 'specimen_id']);
+ }
+
+ public function getSideOfSpecimen()
+ {
+ return $this->hasOne(CytoSideOfSpecimen::class, ['id' => 'side_of_specimen']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenAdequacy()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy::class, ['id' => 'specimen_adequacy']);
+ }
+
+ public function getSpecimenAdequacy1()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy1::class, ['id' => 'specimen_adequacy_1']);
+ }
+
+ public function getSpecimenAdequacy2()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy2::class, ['id' => 'specimen_adequacy_2']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatient()
+ {
+ return $this->hasOne(Patient::class, ['id' => 'patient_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getApproveAt()
+ {
+ return $this->hasOne(User::class, ['id' => 'approve_at']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPathologist()
+ {
+ return $this->hasOne(User::class, ['id' => 'pathologist_id']);
+ }
+
+ public function getFinance()
+ {
+ return $this->hasOne(FinanceServiceCharge::class, ['id_case' => 'id_case']);
+ }
+
+ public function getCytoOperate()
+ {
+ return $this->hasOne(CytoOperate::class, ['id_case' => 'id_case']);
+ }
+
+ /**
+ * นับจำนวน Case ใหม่
+ * @return number|string
+ */
+ public static function getNewCase()
+ {
+ return CaseNonGyn::find()->where(['status_id' => 1])->count();
+ }
+
+ /**
+ * นับจำนวน Case ใหม่
+ * @return number|string
+ */
+ public static function getNewCytoCase()
+ {
+ return CaseNonGyn::find()->where(['status_id' => 6])->count();
+ }
+
+ /**
+ * นับจำนวน Case ของตัวเอง
+ * @return number|string
+ */
+ public static function getMyCase()
+ {
+ return CaseNonGyn::find()->with('')
+ ->where(['cytotech1_id' => Yii::$app->user->getId(), 'status_id' => 5])
+ ->count();
+ }
+
+ /**
+ * นับจำนวน Case ที่ทำเสร็จแล้ว
+ * @return number|string
+ */
+ public static function getMyFinishCase()
+ {
+ return CaseNonGyn::find()
+ ->with('')
+ ->where(['cytotech1_id' => Yii::$app->user->getId(), 'status_id' => 12])->count();
+ }
+
+ /*
+ * upload Files
+ */
+ public function uploadFile($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = time() . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadFile . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getFileToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /*public function getFileToArray()
+ {
+ return !empty($this->files) ? explode(',', $this->getOldAttribute('files')) : [];
+ }*/
+
+ public function getFileToArray()
+ {
+ return $this->getOldAttribute('files') ? @explode(',', $this->getOldAttribute('files')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getFiles()
+ {
+ if (empty($this->files) && !isset($this->files)) {
+ return [];
+ } else {
+ return !is_array($this->files) ? explode(',', $this->files) : [];
+ }
+ }
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLink()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a($val, Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']) . ' ';
+ }
+ }
+ return $rt;
+ }
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLinkImg()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['class' => 'img-fluid']), Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']);
+ }
+ }
+ return $rt;
+ }
+
+
+ /**
+ * @param $model
+ * @return false|string
+ * @throws \ImagickException
+ */
+ public function uploadMicro($model)
+ {
+ $files = UploadedFile::getInstances($model, 'microscopic_img');
+ if ($files) {
+ $file_names = [];
+
+ foreach ($files as $file) {
+ if ($file->extension == 'tiff' || $file->extension == 'tif') {
+ $file_name = $model->id_case . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ $image = new Imagick(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ @unlink(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ $file_name = $model->id_case . '_' . $file->baseName . '.png';
+ $image->setImageFormat('png');
+ $image->thumbnailImage(1024, 0);
+ $image->writeImage(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+ } else {
+ $file_name = $model->id_case . '_' . $file->baseName . '.' . $file->extension;
+
+ if ($file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name)) {
+ Image::getImagine()->open(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name)->thumbnail(new Box(1024, 1024))->save(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name, ['quality' => 100]);
+ }
+ }
+
+ $file_names[] = $file_name;
+ }
+ return implode(',', ArrayHelper::merge($file_names, $this->getMicroImageToArray()));
+ }
+
+ return $model->isNewRecord ? false : $model->getOldAttribute('microscopic_img');
+ }
+
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getMicroImageToArray()
+ {
+ return !empty($this->getOldAttribute('microscopic_img')) ? explode(',', $this->getOldAttribute('microscopic_img')) : [];
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getMicroImage()
+ {
+ return !empty($this->microscopic_img) ? Yii::getAlias('@web') . '/' . $this->uploadMicroFolder . '/' . $this->microscopic_img : '';
+ }
+
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReportToArray()
+ {
+ return $this->getOldAttribute('outlab_report') ? @explode(',', $this->getOldAttribute('outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReport()
+ {
+ if (empty($this->outlab_report) || !isset($this->outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->outlab_report) ? explode(',', $this->outlab_report) : [];
+ }
+ }
+
+ /****** */
+
+ /**
+ * @param $id_case
+ * @return array|mixed|\yii\db\ActiveRecord|null
+ */
+ public static function getNext($id_case)
+ {
+ $model = CaseNonGyn::findOne(['id_case' => $id_case]);
+ $surgical = CaseNonGyn::find()->where(['>', 'id', $model->id])->andWhere(['status_id' => 1])->orderBy(['id' => SORT_ASC])->one();
+ if ($surgical) {
+ return $surgical->id_case;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param null $id_case
+ * @return array|mixed|\yii\db\ActiveRecord|null
+ */
+ public static function getPrev($id_case = null)
+ {
+ $model = CaseNonGyn::findOne(['id_case' => $id_case]);
+ $surgical = CaseNonGyn::find()->where(['<', 'id', $model->id])->andWhere(['status_id' => 1])->orderBy(['id' => SORT_DESC])->one();
+ if ($surgical) {
+ return $surgical->id_case;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return bool|mixed|string|null
+ * @throws \yii\base\Exception
+ */
+ public function uploadGross($model, $attribute)
+ {
+ $grosses = UploadedFile::getInstances($model, $attribute);
+ FileHelper::createDirectory($this->getPath());
+ if ($grosses) {
+ $file_names = [];
+ foreach ($grosses as $gross) {
+ $file_name = $this->id_case . '_' . $gross->baseName . '.' . $gross->extension;
+ $gross->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadGross . '/' . $file_name);
+ $file_names[] = $file_name;
+ }
+ if ($this->isNewRecord) { //ถ้าเป็นการเพิ่ม Record ใหม่ให้บันทึกไฟล์ aaa.aaa,bbb.bbb ....
+ return implode(',', $file_names);
+ } else { //ถ้าเป็นการปรับปรุงให้เพิ่มจากของเดิม
+ return implode(',', ArrayHelper::merge($file_names, $this->getOldAttribute($attribute) ? explode(',', $this->getOldAttribute($attribute)) : []));
+ }
+ } //end files upload
+
+ return $this->isNewRecord ? false : $this->getOldAttribute($attribute); //ถ้าไม่มีการ upload ให้ใช้ข้อมูลเดิม
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getPath()
+ {
+ return Yii::getAlias('@webroot') . '/' . $this->uploadGross;
+ }
+
+ /**
+ * @return string
+ */
+ public function getFileUrl()
+ {
+ return Yii::getAlias('@web') . '/' . $this->uploadGross;
+ }
+
+
+ /**
+ * @return false|string[]
+ */
+ public function getGrosses()
+ {
+ return !is_array($this->specimen_img) ? explode(',', $this->specimen_img) : [];
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossImgs()
+ {
+ $img = '';
+ if (!empty($this->specimen_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+ /**
+ * @return string
+ */
+ public function getGrossImgsForGross()
+ {
+ $img = '';
+ if (!empty($this->specimen_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => '']), ['/surgical/gross/view-gross', 'id_case' => $this->id_case, 'specimen_img' => $gross], ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossDelImgs()
+ {
+ $img = '';
+ if (!empty($this->specimen_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= '
' . Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']) . '
' .
+ Html::a('Delete', ['delete-gross-img', 'img' => $gross, 'id_case' => $this->id_case], ['class' => 'btn btn-xs btn-danger', 'data' => ['confirm' => 'แน่ใจนะว่าต้องการลบรูปนี้?']])
+ . '
';
+ }
+ }
+ return $img;
+ }
+
+ /*********************** */
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadConsultReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadConsultReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getConsultReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getConsultReportToArray()
+ {
+ return $this->getOldAttribute('consult_outlab_report') ? @explode(',', $this->getOldAttribute('consult_outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getConsultReport()
+ {
+ if (empty($this->consult_outlab_report) || !isset($this->consult_outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->consult_outlab_report) ? explode(',', $this->consult_outlab_report) : [];
+ }
+ }
+}
diff --git a/console/models/CasePap.php b/console/models/CasePap.php
new file mode 100644
index 00000000..07df739d
--- /dev/null
+++ b/console/models/CasePap.php
@@ -0,0 +1,696 @@
+get('patho');
+ }
+
+ /**
+ * @param $insert
+ * @return bool
+ */
+ public function beforeSave($insert)
+ {
+
+ $this->specimen_adequacy_3 = serialize($this->specimen_adequacy_3);
+ $this->specimen_adequacy_4 = serialize($this->specimen_adequacy_4);
+ $this->general_categorization_2 = serialize($this->general_categorization_2);
+
+ return parent::beforeSave($insert);
+ }
+
+ /**
+ * @return void
+ */
+
+ public function afterFind()
+ {
+ $this->specimen_adequacy_3 = unserialize($this->specimen_adequacy_3);
+ $this->specimen_adequacy_4 = unserialize($this->specimen_adequacy_4);
+ $this->general_categorization_2 = unserialize($this->general_categorization_2);
+
+ parent::afterFind();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [[/*'patient_id'*/'id_case', 'hospital_id', 'given_name', 'title_id'], 'required', 'on' => 'register'],
+ [['is_specimen'], 'required', 'on' => 'cyto'],
+ [[/*'patient_id'*/'id_case', 'hospital_id', 'gender', 'given_name', 'surname', 'title_id', 'pathologist_id'], 'required', 'on' => 'approve'],
+ [['autocomplete_patient', 'hos_ref', 'cyto_type', 'case_reference', 'house', 'moo', 'soy', 'road', 'phone', 'email', 'post_review_diagnosis'], 'string'],
+ //[['pathologist_id'], 'required', 'on' => 'update'],
+ [['id_case'], 'unique'],
+ [['title_id', 'specimen_type_id', 'cytotech1_id', 'cytotech2_id', 'specimen_id', 'is_stained', 'is_restain', 'via', 'is_ot', 'is_pathologist_ot', 'specimen_adequacy', 'register_id', 'specimen_adequacy_1', 'general_categorization', 'general_categorization_1', 'pathologist_id', 'is_provisional', 'is_consult', 'is_qa', 'is_conference', 'status_id', 'is_print', 'suggestion_list', 'is_critical_diagnosis', 'class_id', 'adequacy_id', 'result_id', 'hm_id', 'suggest_id', 'is_outlab', 'is_no_comment', 'lab_order_number', 'is_express', 'ward_id', 'rights_id', 'doctor_id', 'organ_id', 'order_point_id', 'order_by_id', 'screener_qa_id', 'qa_list_id', 'const_rights_id', 'tambon', 'amphur', 'province', 'postcode', 'marriage', 'occupation', 'religious', 'race', 'citizenship', 'specimen_adequacy_2', 'is_hpv', 'is_provincial_hospital', 'is_review', 'is_specimen'], 'integer'],
+ [['id_case', 'given_name', 'surname', 'gender', 'nation', 'id_card', 'age_unit', 'h_n', 'a_n', 'ward', 'clinician', 'collect_method', 'lmp', 'para', 'sterilize', 'previous_treatment', 'clinical_finding', 'clinical_diagnosis', 'clinical_diagnosis_his', 'last_pap', 'last_pregnancy', 'adequacy_other', 'categorization_other', 'diagnosis', 'suggestion', 'diff_qa', 'adequacy_comment', 'result_comment', 'hm_comment', 'suggest_comment', /*'quantity',*/ 'specimen', 'remark', 'gyn_specimen_other', 'remark_report', 'remark_consult_outlab'], 'string'],
+ [['register_at', 'birthdate', 'collected_at', 'conference_at', 'report_at', 'patient_id', 'cytotech1_at', 'cytotech2_at', 'specimen_adequacy_3', 'specimen_adequacy_4', 'general_categorization_2', 'result_at', 'receive_at', 'express_at', 'express_day', 'review_at'], 'safe'],
+ [['no_slide', 'pathologist_id', 'hospital_id'], 'number'],
+ [['id_case'], 'required', 'on' => 'process'],
+ [['his_ln', 'v_date', 'verify_date'], 'string', 'max' => 100],
+ [['express'], 'string', 'max' => 50],
+ [['files'], 'file', 'extensions' => 'pdf,jpg,png,jpeg,gif,doc,docx,xls,xlsx,ppt,pptx'],
+ [['outlab_report'], 'file', 'extensions' => 'pdf,jpg,png,gif,doc,docx,xls,xlsx,ppt,pptx,jpeg'],
+ [['age'], 'number'],
+ [['hospital_id'], 'exist', 'skipOnError' => true, 'targetClass' => ConstHospital::class, 'targetAttribute' => ['hospital_id' => 'id']],
+ [['status_id'], 'exist', 'skipOnError' => true, 'targetClass' => ConstStatus::class, 'targetAttribute' => ['status_id' => 'id']],
+ [['specimen_id'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimen::class, 'targetAttribute' => ['specimen_id' => 'id']],
+ [['specimen_type_id'], 'exist', 'skipOnError' => true, 'targetClass' => CytoSpecimenType::class, 'targetAttribute' => ['specimen_type_id' => 'id']],
+ [['patient_id'], 'exist', 'skipOnError' => true, 'targetClass' => Patient::class, 'targetAttribute' => ['patient_id' => 'id']],
+ [['pathologist_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::class, 'targetAttribute' => ['pathologist_id' => 'id']],
+ ];
+ }
+
+
+ /**
+ * @inheritdoc
+ */
+
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ //'autocomplete_patient' => '',
+ //'patient_id' => 'ชื่อ นามสกุล',
+ 'hospital_id' => 'หน่วยงาน',
+ 'patient' => 'ชื่อ นามสกุล',
+ 'pathologist' => 'พยาธิแพทย์',
+ 'hospital' => 'โรงพยาบาล',
+ 'id_case' => 'ID CASE',
+ 'cyto_type' => 'Type',
+ 'cytotech1_id' => 'Cytotech1',
+ 'cytotech1_at' => 'Cytotech1 At',
+ 'cytotech2_id' => 'Cytotech2',
+ 'cytotech2_at' => 'Cytotech2 At',
+ 'title_id' => 'คำนำหน้า',
+ 'given_name' => 'ชื่อ',
+ 'surname' => 'นามสกุล',
+ 'gender' => 'เพศ',
+ 'nation' => 'เชื้อชาติ',
+ 'id_card' => 'หมายเลขบัตรประชาชน',
+ 'birthdate' => 'วัน/เดือน/ปี เกิด',
+ 'age' => 'อายุ',
+ 'age_unit' => 'หน่วยอายุ',
+ 'h_n' => 'H N',
+ 'a_n' => 'A N',
+ 'ward' => 'Ward',
+ 'ward_id' => 'Ward',
+ 'clinician' => 'Physician',
+ 'doctor_id' => 'Clinician',
+ 'organ_id' => 'Organ',
+ 'collected_at' => 'วันที่เก็บสิ่งส่งตรวจ',
+ 'receive_at' => 'วันที่รับสิ่งส่งตรวจ',
+ 'collect_method' => 'Collect Method', //Specimen Type ตอนนี้คือ Collect Method
+ 'specimen_type_id' => 'Collect Method',
+ 'specimen_id' => 'Specimen',
+ 'specimen_name' => 'Specimen',
+ 'no_slide' => 'จำนวนสไลด์',
+ 'quantity' => 'Quantity',
+ 'is_stained' => 'Stained',
+ 'is_restain' => 'Restain',
+ 'last_pregnancy' => 'Last',
+ 'lmp' => 'LMP',
+ 'para' => 'Para',
+ 'sterilize' => 'Sterilize',
+ 'previous_treatment' => 'Previous Treatment',
+ 'clinical_finding' => 'Clinical Finding',
+ 'clinical_diagnosis' => 'Clinical Information',
+ 'clinical_diagnosis_his' => 'Clinical Diagnosis',
+ 'last_pap' => 'Last Pap',
+ 'via' => 'VIA',
+ 'is_ot' => 'OT',
+ 'is_pathologist_ot' => 'Pathologist OT',
+ 'specimen_adequacy' => 'Specimen Adequacy',
+ 'specimen_adequacy_1' => 'Specimen Adequacy 1',
+ 'specimen_adequacy_2' => 'Specimen Adequacy 2',
+ 'specimen_adequacy_4' => 'Specimen Adequacy 4',
+ 'adequacy_other' => 'Adequacy Other',
+ 'general_categorization' => 'General Categorization',
+ 'general_categorization_1' => 'General Categorization 1',
+ 'categorization_other' => 'Categorization Other',
+ 'diagnosis' => 'Diagnosis',
+ 'additional_diagnosis' => 'Additional Diagnosis',
+ 'microscopic' => 'Microscopic',
+ 'gross_description' => 'Gross Description',
+ 'microscopic_img' => 'Microscopic Image',
+ 'suggestion' => 'Educational Notes And Suggestions',
+ 'pathologist_id' => 'พยาธิแพทย์',
+ 'is_provisional' => 'Provisional',
+ 'is_consult' => 'Consult',
+ 'is_qa' => 'QA',
+ 'is_conference' => 'Conference',
+ 'conference_at' => 'Conference At',
+ 'is_review' => 'Review',
+ 'status_id' => 'Status',
+ 'report_at' => 'Report At',
+ 'is_print' => 'Is Print',
+ 'diff_qa' => 'Diff Qa',
+ 'is_critical_diagnosis' => 'Critical Report',
+ 'is_first_cancer' => 'First Cancer',
+ 'files' => 'Request File',
+ 'class_id' => 'GENERAL CATEGORIZATION',
+ 'adequacy_id' => 'ADEQUACY',
+ 'adequacy_comment' => 'ADEQUACY OTHER',
+ 'result_id' => 'INTERPRETATION/ RESULT',
+ 'result_comment' => 'INTERPRETATION/RESULT OTHER',
+ 'hm_id' => 'HORMONAL EVALUATION',
+ 'hm_comment' => 'HORMONAL EVALUATION OTHER',
+ 'suggest_id' => 'SUGGESTION',
+ 'suggest_comment' => 'SUGGESTION OTHER',
+ 'register_at' => 'วันที่ลงทะเบียน',
+ 'register_id' => 'ผู้ลงทะเบียน',
+ 'is_no_comment' => 'ไม่รายงาน Comment',
+ 'lab_order_number' => 'Lab Order Number',
+ 'specimen' => 'Specimen',
+ 'is_express' => 'ขอผลด่วน?',
+ 'express_day' => 'เลือกวันขอผลด่วน',
+ 'express_at' => 'วันที่ขอผลด่วน',
+ 'remark' => 'Remark',
+ 'rights_id' => 'สิทธิ์การรักษา',
+ 'gyn_specimen_other' => 'Specimen Other',
+ 'is_outlab' => 'Case Outlab',
+ 'his_ln' => 'Lab Number',
+ 'house' => 'เลขที่บ้าน',
+ 'moo' => 'เลขที่หมู่/ชุมชน',
+ 'soy' => 'ชื่อตรอก/ซอย',
+ 'road' => 'ถนน',
+ 'tambon' => 'ตำบล',
+ 'amphur' => 'อำเภอ',
+ 'province' => 'จังหวัด',
+ 'postcode' => 'รหัสไปรษณีย์',
+ 'phone' => 'หมายเลขโทรศัพท์คนไข้',
+ 'email' => 'ที่อยู่จดหมายอิเลคทรอนิค',
+ 'marriage' => 'สภาพสมรส',
+ 'occupation' => 'อาชีพ',
+ 'religious' => 'ศาสนา',
+ 'race' => 'เชิ้อชาติ',
+ 'citizenship' => 'สัญชาติ',
+ 'is_hpv' => 'HPV',
+ 'is_provincial_hospital' => 'รพช',
+ 'is_specimen' => 'รายงานผล'
+ ];
+ }
+ public function attributeHints()
+ {
+ return [
+ 'collected_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'receive_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'birthdate' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y'),
+ 'conference_at' => 'วัน/เดือน/ปี ค.ศ. เช่น' . date('d/m/Y'),
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getStatus()
+ {
+ return $this->hasOne(ConstStatus::class, ['id' => 'status_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstWard()
+ {
+ return $this->hasOne(ConstWard::class, ['id' => 'ward_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatientDiag()
+ {
+ return $this->hasOne(PatientCaseDiagnosis::class, ['h_n' => 'h_n']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstDoctor()
+ {
+ return $this->hasOne(ConstDoctor::class, ['id' => 'doctor_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstRights()
+ {
+ return $this->hasOne(ConstRights::class, ['id' => 'rights_id']);
+ }
+ public function getTitle()
+ {
+ return $this->hasOne(PatientTitle::class, ['id' => 'title_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegister()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegisterBy()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getGeneralCategorization()
+ {
+ return $this->hasOne(CytoGeneralCategorization::class, ['id' => 'general_categorization']);
+ }
+
+ public function getGeneralCategorization1()
+ {
+ return $this->hasOne(CytoGeneralCategorization1::class, ['id' => 'general_categorization_1']);
+ }
+
+ public function getGeneralCategorization2()
+ {
+ return $this->hasOne(CytoGeneralCategorization2::class, ['id' => 'general_categorization_2']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenModel()
+ {
+ return $this->hasOne(CytoSpecimen::class, ['id' => 'specimen_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenAdequacy()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy::class, ['id' => 'specimen_adequacy']);
+ }
+
+ public function getSpecimenAdequacy1()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy1::class, ['id' => 'specimen_adequacy_1']);
+ }
+ public function getSpecimenAdequacy2()
+ {
+ return $this->hasOne(CytoSpecimenAdequacy2::class, ['id' => 'specimen_adequacy_2']);
+ }
+ public function getSpecimenAdequacy3()
+ {
+ return $this->hasMany(CytoSpecimenAdequacyByCase::class, ['id_case' => 'id_case']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getSpecimenType()
+ {
+ return $this->hasOne(CytoSpecimenType::class, ['id' => 'specimen_type_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatient()
+ {
+ return $this->hasOne(Patient::class, ['id' => 'patient_id']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCytotech1()
+ {
+ return $this->hasOne(User::className(), ['id' => 'cytotech1_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCytotech2()
+ {
+ return $this->hasOne(User::className(), ['id' => 'cytotech2_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPathologist()
+ {
+ return $this->hasOne(User::class, ['id' => 'pathologist_id']);
+ }
+
+ public function getlastTransferBy()
+ {
+ return $this->hasOne(User::class, ['id' => 'last_transfer_by']);
+ }
+
+ public function getCytoOperate()
+ {
+ return $this->hasOne(CytoOperate::class, ['id_case' => 'id_case']);
+ }
+ public function getServiceCharge()
+ {
+ return $this->hasOne(FinanceServiceCharge::class, ['id_case' => 'id_case']);
+ }
+
+ public function getWard()
+ {
+ return $this->hasOne(PatientWard::class, ['id' => 'ward']);
+ }
+
+ public function getHospital()
+ {
+ return $this->hasOne(ConstHospital::class, ['id' => 'hospital_id']);
+ }
+ public function getCytoSuggestion()
+ {
+ return $this->hasOne(CytoSuggestion::class, ['id' => 'suggestion_list']);
+ }
+
+ public function getClass()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'class_id']);
+ }
+
+ public function getAdequacy()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'adequacy_id']);
+ }
+ public function getResult()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'result_id']);
+ }
+ public function getHm()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'hm_id']);
+ }
+ public function getSuggest()
+ {
+ return $this->hasOne(CytoPapDiagnosis::class, ['id' => 'suggest_id']);
+ }
+
+
+ /**
+ * นับจำนวน Case ใหม่
+ * @return number|string
+ */
+ public static function getNewCase()
+ {
+ return CasePap::find()->where(['status_id' => 1])->count();
+ }
+
+ /**
+ * นับจำนวน Case ของตัวเอง
+ * @return number|string
+ */
+ /* public static function getMyCase()
+ {
+ return CasePap::find()->with('')
+ ->where(['cytotech_id' => Yii::$app->user->getId(), 'status_id' => 5])
+ ->count();
+ }*/
+
+ /**
+ * นับจำนวน Case ที่ทำเสร็จแล้ว
+ * @return number|string
+ */
+ public static function getMyFinishCase()
+ {
+ return CasePap::find()
+ ->with('')
+ ->where(['cytotech_id' => Yii::$app->user->getId(), 'status_id' => 12])->count();
+ }
+
+ public function getCollectMethod()
+ {
+ return $this->hasOne(CytoCollectMethod::class, ['id' => 'collect_method']);
+ }
+
+ /*
+ * upload Files
+ */
+ public function uploadFile($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = time() . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadFile . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getFileToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getFiles()
+ {
+ if (empty($this->files) && !isset($this->files)) {
+ return [];
+ } else {
+ return !is_array($this->files) ? explode(',', $this->files) : [];
+ }
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getFileToArray()
+ {
+ return $this->getOldAttribute('files') ? @explode(',', $this->getOldAttribute('files')) : [];
+ }
+
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLink()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a($val, Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']) . ' ';
+ }
+ }
+ return $rt;
+ }
+
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLinkImg()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['class' => 'img-fluid']), Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']);
+ }
+ }
+ return $rt;
+ }
+
+
+ /**
+ * @param $model
+ * @return string
+ */
+ public function uploadMicro($model)
+ {
+ $file = UploadedFile::getInstance($model, 'microscopic_img');
+ if ($file) {
+ $file_name = $model->id_case . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+ return $file_name;
+ }
+
+ return $model->getOldAttribute('microscopic_img');
+ }
+
+ /**
+ * @return string
+ */
+ public function getMicroImage()
+ {
+ return !empty($this->microscopic_img) ? Yii::getAlias('@web') . '/' . $this->uploadMicroFolder . '/' . $this->microscopic_img : '';
+ }
+
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReportToArray()
+ {
+ return !empty($this->getOldAttribute('outlab_report')) ? @explode(',', $this->getOldAttribute('outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReport()
+ {
+ if (empty($this->outlab_report) || !isset($this->outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->outlab_report) ? explode(',', $this->outlab_report) : [];
+ }
+ }
+
+ public function getFullname()
+ {
+ return Html::encode($this->given_name . ' ' . $this->surname);
+ }
+
+ public function getTitleFullname()
+ {
+ return Html::encode(((!empty($this->title_id) ? $this->title->name : '') . $this->given_name . ' ' . $this->surname));
+ }
+}
diff --git a/console/models/CaseSurgical.php b/console/models/CaseSurgical.php
new file mode 100644
index 00000000..1090eba8
--- /dev/null
+++ b/console/models/CaseSurgical.php
@@ -0,0 +1,866 @@
+get('patho');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [['id_case', 'hospital_id', 'given_name', 'title_id'], 'required'],
+ [['id_case', 'hospital_id'], 'required', 'on' => 'register'],
+ [['pathologist_id'], 'required', 'on' => 'update'],
+ [['is_stat_flesh'], 'required', 'on' => 'gross'],
+ [['id_case'], 'unique'],
+ [['autocomplete_hospital', 'autocomplete_patient', 'autocomplete_ward', /*'frozen_id_case', 'cons_pathologist',*/ 'hos_ref' /*'case_reference'*/, 'house', 'moo', 'soy', 'road', 'phone', 'email', /*'review_remark'*/], 'string'],
+ [['patient_id', 'title_id', 'is_immuno_staining', 'is_histo_staining', 'register_id', 'amount', 'block_type_id', 'pathologist_id', 'is_consult', 'status_id', 'hospital_id', 'gross_id', /*'cons_pathologist_id', 'consultant_id', 'center_box_open_id',*/ 'is_critical_diagnosis', 'is_pathologist_ot', 'gross_img_update_id', 'is_no_microscopic', 'is_outlab', 'is_consult_outlab', 'charge_user_id', 'bone', 'is_kidney', 'note_id', 'cut_id', 'is_express', 'ward_id', 'rights_id', 'doctor_id', 'organ_id', 'order_point_id', 'order_by_id', 'hospital_import_id', 'amount_in', 'const_rights_id', 'is_molecular', 'is_dish', 'is_frozen', 'is_necropsy', 'tambon', 'amphur', 'province', 'postcode', 'marriage', 'occupation', 'religious', 'race', 'citizenship', 'is_flesh', 'bag', 'is_conference', 'is_review', 'is_smc', 'is_stat_smc', 'is_provincial_hospital', /*'block_no', 'slide_no',*/ 'is_slide_review', 'is_pathologist_review'], 'integer'],
+ [['id_case', 'hos_ref', 'given_name', 'surname', 'gender', 'nation', 'id_card', 'age_unit', 'h_n', 'a_n', 'ward', 'clinician', 'specimen', 'section_label', 'clinical_diagnosis', 'clinical_diagnosis_his', 'gross_description', 'microscopic_description', 'patho_remark', 'diagnosis', 'additional_diagnosis', /*'cons',*/ 'patho_remark', 'bone_note', 'lab_order_number', 'remark', 'remark_outlab', 'remark_consult_outlab', 'remark_report', 'post_review_diagnosis'], 'string'],
+ [['his_ln', 'verify_date'], 'string', 'max' => 100],
+ [['register_at', 'birthdate', 'collected_at', 'conference_at', 'report_at', 'id_case', 'gross_at', 'decal_end_date', 'items'/*, 'slides'*/, 'additional_at', 'status_at', 'cut_at', 'receive_at', 'express_at', 'finance_immuno', 'finance_histo', 'outlab_report', 'decal_block', 'finance_dish'], 'safe'],
+ [['files'], 'file', 'extensions' => 'pdf,jpg,png,gif,doc,docx,xls,xlsx,ppt,pptx,jpeg'],
+ [['gross_img', 'microscopic_img'], 'file', 'extensions' => 'jpeg,jpg,png,gif,tif,tiff', 'skipOnEmpty' => true, 'maxFiles' => 10],
+ [['diagnosis', 'gross_description'], 'required', 'on' => 'pathologist'],
+ [['microscopic_description', 'gross_description'], 'required', 'on' => 'additional'],
+ [['cut_id', 'note_id', 'is_flesh'], 'required', 'on' => 'new'],
+ [['is_re_reference', 'v_date', 'express_day', 'review_at'], 'safe'],
+ [['outlab_report'], 'file', 'extensions' => 'pdf'],
+ [['consult_outlab_report'], 'file', 'extensions' => 'pdf'],
+ [['age'], 'number'],
+ [['slides'], 'string', 'max' => 30],
+ [['o_n', 'v_n', 'a_n', 'express'], 'string', 'max' => 50]
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'patient_id' => 'Patient Id',
+ 'patient' => 'Patient',
+ 'hospital_id' => 'หน่วยงาน',
+ 'hospital' => 'หน่วยงาน',
+ 'id_case' => 'ID CASE',
+ 'case_reference' => 'Case Reference',
+ 'hos_ref' => 'Hospital Reference NO.',
+ 'title_id' => 'คำนำหน้า',
+ 'given_name' => 'ชื่อ',
+ 'surname' => 'นามสกุล',
+ 'gender' => 'เพศ',
+ 'nation' => 'เชื้อชาติ',
+ 'id_card' => 'หมายเลขบัตรประชาชน',
+ 'birthdate' => 'วัน/เดือน/ปี เกิด',
+ 'age' => 'อายุ',
+ 'age_unit' => 'หน่วยอายุ',
+ 'h_n' => 'H N',
+ 'a_n' => 'A N',
+ 'ward' => 'Ward',
+ 'ward_id' => 'Ward',
+ 'clinician' => 'Physician',
+ 'collected_at' => 'วันที่เก็บสิ่งส่งตรวจ',
+ 'receive_at' => 'วันที่รับสิ่งส่งตรวจ',
+ 'specimen' => 'Specimen',
+ 'section_label' => 'Section Label',
+ 'amount' => 'จำนวน Block',
+ 'amount_in' => 'ช่องจำนวนชิ้นเนื้อ',
+ 'cut_at' => 'วันตัดเนื้อ',
+ 'note_id' => 'ผู้จด',
+ 'cut_id' => 'ผู้ตัด',
+ 'bone' => 'bone',
+ 'bone_note' => 'bone_note',
+ 'block_type_id' => 'Block Type ID',
+ 'gross_img' => 'Gross Img',
+ 'clinical_diagnosis' => 'Clinical Information',
+ 'gross_description' => 'Gross Description',
+ 'gross_id' => 'ผู้พิมพ์ Gross',
+ 'gross_at' => 'พิมพ์ Gross เมื่อ',
+ 'microscopic_description' => 'Microscopic Description',
+ 'is_no_microscopic' => 'ไม่รายงาน Microscopic',
+ 'diagnosis' => 'Diagnosis',
+ 'additional_diagnosis' => 'Additional Report',
+ 'additional_at',
+ 'pathologist_id' => 'พยาธิแพทย์',
+ //'is_photograph' => 'Is Photograph',
+ //'is_museum' => 'Is Museum',
+ //'is_provisional' => 'Is Provisional',
+ 'is_consult' => 'Is Consult',
+ //'is_qa' => 'Is Qa',
+ 'is_conference' => 'Conference',
+ 'conference_at' => 'Conference At',
+ 'is_review' => 'Review',
+ 'status_id' => 'สถานะ',
+ 'doctor_id' => 'Clinician',
+ 'organ_id' => 'Organ',
+ 'report_at' => 'วันที่ออกผล',
+ 'decal_end_date' => 'วันสิ้นสุดการ Decal',
+ 'microscopic_img' => 'Microscopic Img',
+ 'register_id' => 'ผู้ลงทะเบียน',
+ 'register_at' => 'วันที่ลงทะเบียน',
+ 'autocomplete_hospital' => 'โรงพยาบาล',
+ 'autocomplete_patient' => 'ชื่อ นามสกุล',
+ 'autocomplete_ward' => 'Ward',
+ //'frozen_id_case' => 'Frozen ID Case',
+ 'is_immuno_staining' => 'ส่งย้อม Immuno',
+ 'is_histo_staining' => 'ส่งย้อม Histo',
+ //'center_box_open_id' => 'รายการเปิดกล่อง',
+ 'is_critical_diagnosis' => 'แจ้งแพทย์ด่วน Critical Diagnosis',
+ /*'consultant_id' => 'Consultant',
+ 'cons_pathologist_id' => 'Pathologist',
+ 'cons_pathologist' => 'Pathologist (ภายนอก)',*/
+ 'is_re_reference' => 'ดึงข้อมูลผลการตรวจเดิมอีกครั้ง',
+ 'is_outlab' => 'Case Outlab',
+ 'outlab_report' => 'Outlab Report File (PDF)',
+ 'is_consult_outlab' => 'Case Consult Outlab',
+ 'consult_outlab_report' => 'Consult Outlab Report File (PDF)',
+ 'charge_user_id' => 'ผู้ให้ราคา',
+ 'lab_order_number' => 'Lab order Number',
+ 'is_express' => 'ขอผลด่วน?',
+ 'express_at' => 'วันที่ขอผลด่วน',
+ 'express_day' => 'เลือกวันขอผลด่วน',
+ 'remark' => 'Remark',
+ 'rights_id' => 'สิทธิ์การรักษา',
+ 'is_molecular' => 'Molecular',
+ 'is_dish' => 'DISH',
+ 'is_frozen' => 'Frozen',
+ 'is_necropsy' => 'Necropsy',
+ 'remark_outlab' => 'Remark Outlab',
+ 'his_ln' => 'Lab Number',
+ 'house' => 'เลขที่บ้าน',
+ 'moo' => 'เลขที่หมู่/ชุมชน',
+ 'soy' => 'ชื่อตรอก/ซอย',
+ 'road' => 'ถนน',
+ 'tambon' => 'ตำบล',
+ 'amphur' => 'อำเภอ',
+ 'province' => 'จังหวัด',
+ 'postcode' => 'รหัสไปรษณีย์',
+ 'phone' => 'หมายเลขโทรศัพท์คนไข้',
+ 'email' => 'ที่อยู่จดหมายอิเลคทรอนิค',
+ 'marriage' => 'สภาพสมรส',
+ 'occupation' => 'อาชีพ',
+ 'religious' => 'ศาสนา',
+ 'race' => 'เชิ้อชาติ',
+ 'citizenship' => 'สัญชาติ',
+ 'is_flesh' => 'สถิติประกันชันสูตร',
+ 'is_stat_flesh' => 'ขนาดชิ้นเนื้อ',
+ 'bag' => 'จำนวนถุงชิ้นเนื้อ',
+ 'is_provincial_hospital' => 'รพช',
+ ];
+ }
+
+ public function attributeHints()
+ {
+ return [
+ 'collected_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'receive_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'cut_at' => 'วัน/เดือน/ปี ค.ศ. เช่น ' . date('d/m/Y H:i:s'),
+ 'birthdate' => 'วัน/เดือน/ปี ค.ศ. เช่น 22/05/' . date('Y'),
+ 'conference_at' => 'วัน/เดือน/ปี ค.ศ. เช่น' . date('d/m/Y'),
+ 'decal_end_date' => 'วัน/เดือน/ปี ค.ศ เช่น 22/05/' . (date('Y')) . ' 09:10:07',
+ ];
+ }
+
+ public static function getNewTask()
+ {
+ return self::find()->where(['status_id' => 1])->count();
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstWard()
+ {
+ return $this->hasOne(ConstWard::class, ['id' => 'ward_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstDoctor()
+ {
+ return $this->hasOne(ConstDoctor::class, ['id' => 'doctor_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getConstRights()
+ {
+ return $this->hasOne(ConstRights::class, ['id' => 'rights_id']);
+ }
+
+ /**
+ * @return string
+ */
+ public function getFullname()
+ {
+ return Html::encode($this->given_name . ' ' . $this->surname);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegister()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getChangUser()
+ {
+ return $this->hasOne(User::class, ['id' => 'charge_user_id']);
+ }
+
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getGender()
+ {
+ return $this->hasOne(User::class, ['id' => 'gender_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPathologist()
+ {
+ return $this->hasOne(User::class, ['id' => 'pathologist_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRegisterBy()
+ {
+ return $this->hasOne(User::class, ['id' => 'register_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRepotType()
+ {
+ return $this->hasOne(ConstStatusReport::class, ['id' => 'name']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getTitle()
+ {
+ return $this->hasOne(PatientTitle::class, ['id' => 'title_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getLookUp()
+ {
+ return $this->hasOne(ConstLookup::class, ['lookuptypeid' => 'marriage']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getPatient()
+ {
+ return $this->hasOne(Patient::class, ['id' => 'patient_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getStatus()
+ {
+ return $this->hasOne(ConstStatus::class, ['id' => 'status_id']);
+ }
+
+ public function getWard()
+ {
+ return $this->hasOne(PatientWard::class, ['id' => 'ward']);
+ }
+
+ public function getGross()
+ {
+ return $this->hasOne(User::class, ['id' => 'gross_id']);
+ }
+
+ public function getSurgicalOperate()
+ {
+ return $this->hasOne(SurgicalOperate::class, ['id_case' => 'id_case']);
+ }
+
+ public function getSurgicalDiscard()
+ {
+ return $this->hasOne(SurgicalDiscard::class, ['id_case' => 'id_case']);
+ }
+
+ public function getHospital()
+ {
+ return $this->hasOne(ConstHospital::class, ['id' => 'hospital_id']);
+ }
+
+ public function getGrossEditBy()
+ {
+ return $this->hasOne(User::class, ['id' => 'gross_edit_by']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getChargeUser()
+ {
+ return $this->hasOne(User::class, ['id' => 'charge_user_id']);
+ }
+
+ public function getHospitals()
+ {
+ return $this->hasOne(ConstHospital::class, ['id' => 'hospital_id']);
+ }
+
+
+ /**
+ * @param $model
+ * @return false|string
+ * @throws \ImagickException
+ */
+ public function uploadMicro($model)
+ {
+ $files = UploadedFile::getInstances($model, 'microscopic_img');
+ if ($files) {
+ $file_names = [];
+
+ foreach ($files as $file) {
+ if ($file->extension == 'tiff' || $file->extension == 'tif') {
+ $file_name = $model->id_case . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ $image = new common\models\Imagick(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ @unlink(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+
+ $file_name = $model->id_case . '_' . $file->baseName . '.png';
+ $image->setImageFormat('png');
+ $image->thumbnailImage(1024, 0);
+ $image->writeImage(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name);
+ } else {
+ $file_name = $model->id_case . '_' . $file->baseName . '.' . $file->extension;
+
+ if ($file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name)) {
+ Image::getImagine()->open(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name)->thumbnail(new Box(1024, 1024))->save(Yii::getAlias('@webroot') . '/' . $this->uploadMicroFolder . '/' . $file_name, ['quality' => 100]);
+ }
+ }
+
+ $file_names[] = $file_name;
+ }
+ return implode(',', (ArrayHelper::merge($file_names, $this->getMicroImageToArray())));
+ }
+
+ return $model->isNewRecord ? false : $model->getOldAttribute('microscopic_img');
+ }
+
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getMicroImageToArray()
+ {
+ return !empty($this->getOldAttribute('microscopic_img')) ? explode(',', $this->getOldAttribute('microscopic_img')) : [];
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getMicroImage()
+ {
+ return !empty($this->microscopic_img) ? Yii::getAlias('@web') . '/' . $this->uploadMicroFolder . '/' . $this->microscopic_img : '';
+ }
+
+
+ /*
+ * upload Files
+ */
+ public function uploadFile($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = time() . '_' . $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadFile . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getFileToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+
+ /**
+ * ขอชื่อไฟล์ทั้งหมด
+ */
+ public function getFiles()
+ {
+ if (empty($this->files) && !isset($this->files)) {
+ return [];
+ } else {
+ return !is_array($this->files) ? explode(',', $this->files) : [];
+ }
+ }
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLink()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a($val, Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']) . ' ';
+ }
+ }
+ return $rt;
+ }
+
+ /**
+ * Get files with html link function
+ *
+ * @return string
+ */
+ public function getFileLinkImg()
+ {
+ $rt = '';
+ if (!empty($this->files)) {
+ foreach ($this->getFiles() as $key => $val) {
+ $rt .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['class' => 'img-fluid']), Yii::getAlias('@web') . '/' . $this->uploadFile . '/' . $val, ['target' => '_blank', 'class' => 'linksWithTarget']);
+ }
+ }
+ return $rt;
+ }
+
+
+ /**
+ * นำไฟล์มาใส่ใน Array
+ */
+ public function getFileToArray()
+ {
+ return $this->getOldAttribute('files') ? @explode(',', $this->getOldAttribute('files')) : [];
+ }
+
+ /**
+ * @param $id_case
+ * @return array|mixed|\yii\db\ActiveRecord|null
+ */
+ public static function getNext($id_case)
+ {
+ $model = CaseSurgical::findOne(['id_case' => $id_case]);
+ $surgical = CaseSurgical::find()->where(['>', 'id', $model->id])->andWhere(['status_id' => 1])->orderBy(['id' => SORT_ASC])->one();
+ if ($surgical) {
+ return $surgical->id_case;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param null $id_case
+ * @return array|mixed|\yii\db\ActiveRecord|null
+ */
+ public static function getPrev($id_case = null)
+ {
+ $model = CaseSurgical::findOne(['id_case' => $id_case]);
+ $surgical = CaseSurgical::find()->where(['<', 'id', $model->id])->andWhere(['status_id' => 1])->orderBy(['id' => SORT_DESC])->one();
+ if ($surgical) {
+ return $surgical->id_case;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return bool|mixed|string|null
+ * @throws \yii\base\Exception
+ */
+ public function uploadGross($model, $attribute)
+ {
+ $grosses = UploadedFile::getInstances($model, $attribute);
+ FileHelper::createDirectory($this->getPath());
+ if ($grosses) {
+ $file_names = [];
+ foreach ($grosses as $gross) {
+ $file_name = $this->id_case . '_' . $gross->baseName . '.' . $gross->extension;
+ $gross->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadGross . '/' . $file_name);
+ $file_names[] = $file_name;
+ }
+ if ($this->isNewRecord) { //ถ้าเป็นการเพิ่ม Record ใหม่ให้บันทึกไฟล์ aaa.aaa,bbb.bbb ....
+ return implode(',', $file_names);
+ } else { //ถ้าเป็นการปรับปรุงให้เพิ่มจากของเดิม
+ return implode(',', ArrayHelper::merge($file_names, $this->getOldAttribute($attribute) ? explode(',', $this->getOldAttribute($attribute)) : []));
+ }
+ } //end files upload
+
+ return $this->isNewRecord ? false : $this->getOldAttribute($attribute); //ถ้าไม่มีการ upload ให้ใช้ข้อมูลเดิม
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getPath()
+ {
+ return Yii::getAlias('@webroot') . '/' . $this->uploadGross;
+ }
+
+ /**
+ * @return string
+ */
+ public function getFileUrl()
+ {
+ return Yii::getAlias('@web') . '/' . $this->uploadGross;
+ }
+
+
+ /**
+ * @return false|string[]
+ */
+ public function getGrosses()
+ {
+ return !is_array($this->gross_img) ? explode(',', $this->gross_img) : [];
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossImgs()
+ {
+ $img = '';
+ if (!empty($this->gross_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+ /**
+ * @return string
+ */
+ public function getGrossImgsForGross()
+ {
+ $img = '';
+ if (!empty($this->gross_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => '']), ['/surgical/gross/view-gross', 'id_case' => $this->id_case, 'gross_img' => $gross], ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossDelImgs()
+ {
+ $img = '';
+ if (!empty($this->gross_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= '
' . Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']) . '
' .
+ Html::a('Delete', ['delete-gross-img', 'img' => $gross, 'id_case' => $this->id_case], ['class' => 'btn btn-xs btn-danger', 'data' => ['confirm' => 'แน่ใจนะว่าต้องการลบรูปนี้?']])
+ . '
';
+ }
+ }
+ return $img;
+ }
+
+ /**
+ * @return string
+ */
+ public function getGrossCameraDelImgs()
+ {
+ $img = '';
+ $directoryPath = Yii::getAlias('@webroot') . '/uploads/surgical/gross/' . $this->id_case;
+
+ if (is_dir($directoryPath)) {
+ $files = \yii\helpers\FileHelper::findFiles($directoryPath);
+
+ if (!empty($files)) {
+ foreach ($files as $index => $file) {
+ $nameFicheiro = basename($file);
+ $filePath = Yii::getAlias('@web') . '/uploads/surgical/gross/' . $this->id_case . '/' . $nameFicheiro;
+ $img .= '
' . Html::a(Html::img($filePath, ['class' => 'img-fluid']), $filePath, ['target' => '_blank']) .
+ Html::a('Delete', ['delete-gross-img', 'img' => $nameFicheiro, 'id_case' => $this->id_case], ['class' => 'btn btn-xs btn-danger'])
+ . '
';
+ }
+ }
+ return $img;
+ }
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCaseRef()
+ {
+ return $this->hasOne(CaseSurgical::class, ['id_case' => 'id_case']);
+ }
+
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReportToArray()
+ {
+ return $this->getOldAttribute('outlab_report') ? @explode(',', $this->getOldAttribute('outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReport()
+ {
+ if (empty($this->outlab_report) || !isset($this->outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->outlab_report) ? explode(',', $this->outlab_report) : [];
+ }
+ }
+
+
+ /**
+ * @param $model
+ * @param $attribute
+ * @return false|string
+ */
+ public function uploadConsultReport($model, $attribute)
+ {
+ $files = UploadedFile::getInstances($model, $attribute);
+ if (!empty($files)) {
+ $files_name = [];
+ foreach ($files as $file) {
+ $file_name = $file->baseName . '.' . $file->extension;
+ $file->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadConsultReportFolder . '/' . $file_name);
+ $files_name[] = $file_name;
+ }
+
+ if ($model->isNewRecord) {
+ return implode(',', $files_name);
+ } else {
+ return implode(',', (ArrayHelper::merge($files_name, $this->getConsultReportToArray())));
+ }
+ }
+ return $model->isNewRecord ? false : $model->getOldAttribute($attribute);
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getConsultReportToArray()
+ {
+ return $this->getOldAttribute('consult_outlab_report') ? @explode(',', $this->getOldAttribute('consult_outlab_report')) : [];
+ }
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getConsultReport()
+ {
+ if (empty($this->consult_outlab_report) || !isset($this->consult_outlab_report)) {
+ return [];
+ } else {
+ return !is_array($this->consult_outlab_report) ? explode(',', $this->consult_outlab_report) : [];
+ }
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCut()
+ {
+ return $this->hasOne(User::class, ['id' => 'cut_id']);
+ }
+ public function getIsExpress()
+ {
+ return $this->hasOne(CaseSurgical::class, ['id' => 'is_express']);
+ }
+}
diff --git a/console/models/HisRequestTestList.php b/console/models/HisRequestTestList.php
new file mode 100644
index 00000000..e8bc2d5f
--- /dev/null
+++ b/console/models/HisRequestTestList.php
@@ -0,0 +1,65 @@
+ 20],
+ [['TestName', 'SpacimenName'], 'string', 'max' => 120],
+ [['TestType', 'TestStatus'], 'string', 'max' => 1],
+ [['TestRemark'], 'string', 'max' => 4000],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'ID' => 'ID',
+ 'HisRequestID' => 'His Request ID',
+ 'TestCode' => 'Test Code',
+ 'TestName' => 'Test Name',
+ 'TestType' => 'Test Type',
+ 'SpacimenCode' => 'Spacimen Code',
+ 'SpacimenName' => 'Spacimen Name',
+ 'TestStatus' => 'Test Status',
+ 'CollectionDateTime' => 'Collection Date Time',
+ 'TestRemark' => 'Test Remark',
+ ];
+ }
+}
diff --git a/console/models/PatientCase.php b/console/models/PatientCase.php
new file mode 100644
index 00000000..9acc0a17
--- /dev/null
+++ b/console/models/PatientCase.php
@@ -0,0 +1,310 @@
+get('patho');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [['id_case', 'title', 'given_name', 'surname', 'gender', 'age', 'hospital_id', 'hospital', 'status_id', 'status'], 'required'],
+ [['id_case', 'title', 'given_name', 'surname', 'age_unit', 'hospital_name', 'status', 'pathologist', 'diagnosis', 'additional_diagnosis', 'gross_img'], 'string'],
+ [['gender', 'hospital_id', 'status_id', 'pathologist_id', 'is_outlab', 'cnt_critical'], 'integer'],
+ [['birthdate', 'collect_at', 'register_at', 'cut_at', 'report_at', 'center_out_at', 'id_case', 'bex', 'bin', 'additional_at', 'h_n', 'his_ln'], 'safe'],
+ [['age'], 'number']
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id_case' => 'Case',
+ 'title' => 'คำนำหน้า',
+ 'patient_name' => 'ชื่อ นามสกุล',
+ //'patient' => 'ชื่อ - นามสกุล',
+ //'name' => 'ชื่อ นามสกุล',
+ 'gender' => 'เพศ',
+ 'birthdate' => 'วดป เกิด',
+ 'age' => 'อายุ',
+ 'age_unit' => 'หน่วยอายุ',
+ 'hospital_id' => 'Hospital ID',
+ 'hospital_name' => 'หน่วยงาน',
+ 'collect_at' => 'Collect At',
+ 'register_at' => 'วันที่ลงทะเบียน',
+ 'cut_at' => 'Cut At',
+ 'status_id' => 'สถานะ',
+ 'status' => 'สถานะ',
+ 'pathologist_id' => 'Pathologist ID',
+ 'pathologist' => 'พยาธิแพทย์',
+ 'report_at' => 'วันที่ออกผล',
+ 'diagnosis' => 'Diagnosis',
+ 'center_out_at' => 'Center Out At',
+ 'bex' => 'Block Ex',
+ 'bin' => 'Block In',
+ 'is_outlab' => 'Case Outlab',
+ 'cnt_critical' => 'Is Critical Diagnosis',
+ 'h_n' => 'H N',
+ 'his_ln' => 'Lab Number'
+ ];
+ }
+
+
+ public function getCaseBlock()
+ {
+ return $this->hasOne(CaseBlock::class, ['id_case' => 'id_case']);
+ }
+
+
+ public function getCenterOut()
+ {
+ return $this->hasOne(CenterOut::class, ['id_case' => 'id_case']);
+ }
+ public function getHospitals()
+ {
+ return $this->hasOne(ConstHospital::class, ['id' => 'hospital_id']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getHospitalCaseOpen()
+ {
+ return $this->hasOne(HospitalCaseOpen::class, ['id_case' => 'id_case']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCoder()
+ {
+ return $this->hasOne(Coder::class, ['id_case' => 'id_case']);
+ }
+
+
+ /**
+ * @return array|false|string[]
+ */
+ public function getReport()
+ {
+ $case = false;
+ $case_type = Yii::$app->pathology->getCaseType($this->id_case);
+ if ($case_type == 'surgical') {
+ $case = CaseSurgical::findOne(['id_case' => $this->id_case]);
+ }
+ if ($case_type == 'non-gyn') {
+ $case = CaseNonGyn::findOne(['id_case' => $this->id_case]);
+ }
+ if ($case_type == 'pap') {
+ $case = CasePap::findOne(['id_case' => $this->id_case]);
+ }
+
+ return $case;
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getApprove()
+ {
+ return $this->hasOne(PatientCaseApprove::class, ['id_case' => 'id_case']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getAdd()
+ {
+ return $this->hasOne(SurgicalAdd::class, ['id' => 'add_id']);
+ }
+
+
+
+ public function uploadGross($model, $attribute)
+ {
+ $grosses = UploadedFile::getInstances($model, $attribute);
+ FileHelper::createDirectory($this->getPath());
+ if ($grosses) {
+ $file_names = [];
+ foreach ($grosses as $gross) {
+ $file_name = $this->id_case . '_' . $gross->baseName . '.' . $gross->extension;
+ $gross->saveAs(Yii::getAlias('@webroot') . '/' . $this->uploadGross . '/' . $file_name);
+ $file_names[] = $file_name;
+ }
+ if ($this->isNewRecord) { //ถ้าเป็นการเพิ่ม Record ใหม่ให้บันทึกไฟล์ aaa.aaa,bbb.bbb ....
+ return implode(',', $file_names);
+ } else { //ถ้าเป็นการปรับปรุงให้เพิ่มจากของเดิม
+ return implode(',', ArrayHelper::merge($file_names, $this->getOldAttribute($attribute) ? explode(',', $this->getOldAttribute($attribute)) : []));
+ }
+ } //end files upload
+
+ return $this->isNewRecord ? false : $this->getOldAttribute($attribute); //ถ้าไม่มีการ upload ให้ใช้ข้อมูลเดิม
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getPath()
+ {
+ return Yii::getAlias('@webroot') . '/' . $this->uploadGross;
+ }
+
+ /**
+ * @return string
+ */
+ public function getFileUrl()
+ {
+ return Yii::getAlias('@web') . '/' . $this->uploadGross;
+ }
+
+
+ /**
+ * @return false|string[]
+ */
+ public function getGrosses()
+ {
+ return !is_array($this->gross_img) ? explode(',', $this->gross_img) : [];
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossImgs()
+ {
+ $img = '';
+ if (!empty($this->gross_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+ /**
+ * @return string
+ */
+ public function getGrossImgsForGross()
+ {
+ $img = '';
+ if (!empty($this->gross_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => '']), ['/surgical/gross/view-gross', 'id_case' => $this->id_case, 'gross_img' => $gross], ['target' => '_blank']);
+ }
+ }
+ return $img;
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getGrossDelImgs()
+ {
+ $img = '';
+ if (!empty($this->gross_img)) {
+ foreach ($this->getGrosses() as $gross) {
+ $img .= '
' . Html::a(Html::img(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, ['width' => 200, 'class' => 'img-fluid']), Url::to(Yii::getAlias('@web') . '/' . $this->uploadGross . '/' . $gross, true), ['target' => '_blank']) . '
' .
+ Html::a('Delete', ['delete-gross-img', 'img' => $gross, 'id_case' => $this->id_case], ['class' => 'btn btn-xs btn-danger', 'data' => ['confirm' => 'แน่ใจนะว่าต้องการลบรูปนี้?']])
+ . '
';
+ }
+ }
+ return $img;
+ }
+
+ public function getCaseSurgical()
+ {
+ return $this->hasOne(CaseSurgical::class, ['id_case' => 'id_case']);
+ }
+
+ public function getNonGynConsult()
+ {
+ return $this->hasOne(CytoNonGynConsult::class, ['id_case' => 'id_case']);
+ }
+
+ public function getNonGynApprove()
+ {
+ return $this->hasOne(CenterApprove::class, ['id_case' => 'id_case']);
+ }
+
+ public function getGynConsult()
+ {
+ return $this->hasOne(CytoPapConsult::class, ['id_case' => 'id_case']);
+ }
+
+ public function getGynApprove()
+ {
+ return $this->hasOne(CenterApprove::class, ['id_case' => 'id_case']);
+ }
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCytotech1()
+ {
+ return $this->hasOne(User::className(), ['id' => 'cytotech1_id']);
+ }
+}
diff --git a/console/models/PatientCaseApprove.php b/console/models/PatientCaseApprove.php
new file mode 100644
index 00000000..009dd2e1
--- /dev/null
+++ b/console/models/PatientCaseApprove.php
@@ -0,0 +1,122 @@
+get('patho');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rules()
+ {
+ return [
+ [['gender', 'hospital_id', 'status_id', 'pathologist_id', 'approve_status', 'approve_by', 'approve_id', 'is_send_request', 'is_critical_diagnosis'], 'integer'],
+ [['birthdate', 'collect_at', 'register_at', 'cut_at', 'report_at', 'approve_at', 'send_request_at'], 'safe'],
+ [['age'], 'number'],
+ [['diagnosis'], 'string'],
+ [['id_case'], 'string', 'max' => 12],
+ [['title'], 'string', 'max' => 100],
+ [['name'], 'string', 'max' => 1000],
+ [['age_unit'], 'string', 'max' => 15],
+ [['hospital'], 'string', 'max' => 400],
+ [['status'], 'string', 'max' => 500],
+ [['pathologist'], 'string', 'max' => 600],
+ [['remark'], 'string', 'max' => 300],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id_case' => 'Id Case',
+ 'title' => 'Title',
+ 'name' => 'Name',
+ 'gender' => 'Gender',
+ 'birthdate' => 'Birthdate',
+ 'age' => 'Age',
+ 'age_unit' => 'Age Unit',
+ 'hospital_id' => 'Hospital ID',
+ 'hospital' => 'Hospital',
+ 'collect_at' => 'Collect At',
+ 'register_at' => 'Register At',
+ 'cut_at' => 'Cut At',
+ 'status_id' => 'Status ID',
+ 'status' => 'Status',
+ 'pathologist_id' => 'Pathologist ID',
+ 'pathologist' => 'Pathologist',
+ 'report_at' => 'Report At',
+ 'diagnosis' => 'Diagnosis',
+ 'approve_status' => 'Approve Status',
+ 'approve_by' => 'Approve By',
+ 'approve_at' => 'Approve At',
+ 'remark' => 'Remark',
+ 'approve_id' => 'Approve ID',
+ 'is_send_request' => 'Is Send Request',
+ 'is_critical_diagnosis' => 'Is Critical Diagnosis',
+ 'send_request_at' => 'Send Request At',
+ ];
+ }
+
+ public function getApproveBy()
+ {
+ return $this->hasOne(User::class, ['id' => 'approve_by']);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getApproveAt()
+ {
+ return $this->hasOne(User::class, ['id' => 'approve_at']);
+ }
+}