VendorInfluencerMappingModel.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <?php
  2. namespace App\Models;
  3. use CodeIgniter\Model;
  4. class VendorInfluencerMappingModel extends Model
  5. {
  6. protected $table = 'VENDOR_INFLUENCER_MAPPING';
  7. protected $primaryKey = 'SEQ';
  8. protected $useAutoIncrement = true;
  9. protected $returnType = 'array';
  10. protected $useSoftDeletes = false;
  11. protected $protectFields = true;
  12. protected $allowedFields = [
  13. 'VENDOR_SEQ',
  14. 'INFLUENCER_SEQ',
  15. 'REQUEST_TYPE',
  16. 'REQUEST_MESSAGE',
  17. 'RESPONSE_MESSAGE',
  18. 'REQUESTED_BY',
  19. 'APPROVED_BY',
  20. 'REQUEST_DATE',
  21. 'RESPONSE_DATE',
  22. 'EXPIRED_DATE',
  23. 'PARTNERSHIP_START_DATE',
  24. 'PARTNERSHIP_END_DATE',
  25. 'COMMISSION_RATE',
  26. 'SPECIAL_CONDITIONS',
  27. 'IS_ACT',
  28. 'REG_DATE',
  29. 'MOD_DATE',
  30. 'ADD_INFO1',
  31. 'ADD_INFO2',
  32. 'ADD_INFO3'
  33. ];
  34. // Dates
  35. protected $useTimestamps = false;
  36. protected $dateFormat = 'datetime';
  37. protected $createdField = 'REG_DATE';
  38. protected $updatedField = 'MOD_DATE';
  39. protected $deletedField = '';
  40. // Validation
  41. protected $validationRules = [
  42. 'VENDOR_SEQ' => 'required|integer',
  43. 'INFLUENCER_SEQ' => 'required|integer',
  44. 'REQUEST_TYPE' => 'required|in_list[INFLUENCER_REQUEST,VENDOR_INVITE,INFLUENCER_REAPPLY,VENDOR_PROPOSAL]',
  45. 'REQUESTED_BY' => 'required|integer',
  46. 'IS_ACT' => 'required|in_list[Y,N]'
  47. ];
  48. protected $validationMessages = [
  49. 'VENDOR_SEQ' => [
  50. 'required' => '벤더사 SEQ는 필수입니다.',
  51. 'integer' => '벤더사 SEQ는 정수여야 합니다.'
  52. ],
  53. 'INFLUENCER_SEQ' => [
  54. 'required' => '인플루언서 SEQ는 필수입니다.',
  55. 'integer' => '인플루언서 SEQ는 정수여야 합니다.'
  56. ],
  57. 'REQUEST_TYPE' => [
  58. 'required' => '요청 타입은 필수입니다.',
  59. 'in_list' => '유효하지 않은 요청 타입입니다.'
  60. ],
  61. 'REQUESTED_BY' => [
  62. 'required' => '요청자는 필수입니다.',
  63. 'integer' => '요청자 SEQ는 정수여야 합니다.'
  64. ]
  65. ];
  66. protected $skipValidation = false;
  67. protected $cleanValidationRules = true;
  68. // Callbacks
  69. protected $allowCallbacks = true;
  70. protected $beforeInsert = ['beforeInsert'];
  71. protected $afterInsert = ['afterInsert'];
  72. protected $beforeUpdate = ['beforeUpdate'];
  73. protected $afterUpdate = [];
  74. protected $beforeFind = [];
  75. protected $afterFind = [];
  76. protected $beforeDelete = [];
  77. protected $afterDelete = [];
  78. // 히스토리 모델
  79. protected $statusHistoryModel;
  80. public function __construct()
  81. {
  82. parent::__construct();
  83. $this->statusHistoryModel = new VendorInfluencerStatusHistoryModel();
  84. }
  85. /**
  86. * 삽입 전 처리
  87. */
  88. protected function beforeInsert(array $data)
  89. {
  90. if (!isset($data['data']['REG_DATE'])) {
  91. $data['data']['REG_DATE'] = date('Y-m-d H:i:s');
  92. }
  93. if (!isset($data['data']['MOD_DATE'])) {
  94. $data['data']['MOD_DATE'] = date('Y-m-d H:i:s');
  95. }
  96. if (!isset($data['data']['IS_ACT'])) {
  97. $data['data']['IS_ACT'] = 'Y';
  98. }
  99. return $data;
  100. }
  101. /**
  102. * 삽입 후 처리 - 초기 상태 히스토리 생성
  103. */
  104. protected function afterInsert(array $data)
  105. {
  106. $mappingSeq = $data['id'];
  107. $insertData = $data['data'];
  108. // 초기 상태를 PENDING으로 설정
  109. $this->statusHistoryModel->changeStatus(
  110. $mappingSeq,
  111. 'PENDING',
  112. $insertData['REQUEST_MESSAGE'] ?? '',
  113. $insertData['REQUESTED_BY']
  114. );
  115. return $data;
  116. }
  117. /**
  118. * 업데이트 전 처리
  119. */
  120. protected function beforeUpdate(array $data)
  121. {
  122. $data['data']['MOD_DATE'] = date('Y-m-d H:i:s');
  123. return $data;
  124. }
  125. /**
  126. * 현재 상태와 함께 매핑 정보 조회
  127. */
  128. public function getWithCurrentStatus($mappingSeq)
  129. {
  130. $builder = $this->builder();
  131. return $builder->select('VENDOR_INFLUENCER_MAPPING.*,
  132. VENDOR_INFLUENCER_STATUS_HISTORY.STATUS as CURRENT_STATUS,
  133. VENDOR_INFLUENCER_STATUS_HISTORY.STATUS_MESSAGE as CURRENT_STATUS_MESSAGE,
  134. VENDOR_INFLUENCER_STATUS_HISTORY.CHANGED_DATE as STATUS_CHANGED_DATE')
  135. ->join('VENDOR_INFLUENCER_STATUS_HISTORY',
  136. 'VENDOR_INFLUENCER_STATUS_HISTORY.MAPPING_SEQ = VENDOR_INFLUENCER_MAPPING.SEQ AND VENDOR_INFLUENCER_STATUS_HISTORY.IS_CURRENT = "Y"')
  137. ->where('VENDOR_INFLUENCER_MAPPING.SEQ', $mappingSeq)
  138. ->where('VENDOR_INFLUENCER_MAPPING.IS_ACT', 'Y')
  139. ->get()
  140. ->getRowArray();
  141. }
  142. /**
  143. * 상태 변경 (히스토리 모델 위임)
  144. */
  145. public function changePartnershipStatus($mappingSeq, $newStatus, $statusMessage = '', $changedBy = null)
  146. {
  147. return $this->statusHistoryModel->changeStatus($mappingSeq, $newStatus, $statusMessage, $changedBy);
  148. }
  149. /**
  150. * 특정 상태의 파트너십 조회
  151. */
  152. public function getPartnershipsByStatus($status)
  153. {
  154. return $this->statusHistoryModel->getMappingsByStatus($status);
  155. }
  156. /**
  157. * 중복 요청 확인 (특정 벤더사-인플루언서 조합에서 PENDING 상태 확인)
  158. */
  159. public function checkExistingPendingRequest($vendorSeq, $influencerSeq)
  160. {
  161. $builder = $this->builder();
  162. return $builder->select('VENDOR_INFLUENCER_MAPPING.SEQ')
  163. ->join('VENDOR_INFLUENCER_STATUS_HISTORY',
  164. 'VENDOR_INFLUENCER_STATUS_HISTORY.MAPPING_SEQ = VENDOR_INFLUENCER_MAPPING.SEQ AND VENDOR_INFLUENCER_STATUS_HISTORY.IS_CURRENT = "Y"')
  165. ->where('VENDOR_INFLUENCER_MAPPING.VENDOR_SEQ', $vendorSeq)
  166. ->where('VENDOR_INFLUENCER_MAPPING.INFLUENCER_SEQ', $influencerSeq)
  167. ->where('VENDOR_INFLUENCER_STATUS_HISTORY.STATUS', 'PENDING')
  168. ->where('VENDOR_INFLUENCER_MAPPING.IS_ACT', 'Y')
  169. ->get()
  170. ->getRowArray();
  171. }
  172. /**
  173. * 재승인 가능한 파트너십 확인 (TERMINATED 또는 REJECTED 상태)
  174. */
  175. public function checkReapplyEligiblePartnership($vendorSeq, $influencerSeq)
  176. {
  177. $builder = $this->builder();
  178. return $builder->select('VENDOR_INFLUENCER_MAPPING.*, VENDOR_INFLUENCER_STATUS_HISTORY.STATUS as CURRENT_STATUS')
  179. ->join('VENDOR_INFLUENCER_STATUS_HISTORY',
  180. 'VENDOR_INFLUENCER_STATUS_HISTORY.MAPPING_SEQ = VENDOR_INFLUENCER_MAPPING.SEQ AND VENDOR_INFLUENCER_STATUS_HISTORY.IS_CURRENT = "Y"')
  181. ->where('VENDOR_INFLUENCER_MAPPING.VENDOR_SEQ', $vendorSeq)
  182. ->where('VENDOR_INFLUENCER_MAPPING.INFLUENCER_SEQ', $influencerSeq)
  183. ->whereIn('VENDOR_INFLUENCER_STATUS_HISTORY.STATUS', ['TERMINATED', 'REJECTED'])
  184. ->where('VENDOR_INFLUENCER_MAPPING.IS_ACT', 'Y')
  185. ->orderBy('VENDOR_INFLUENCER_MAPPING.REG_DATE', 'DESC')
  186. ->get()
  187. ->getRowArray();
  188. }
  189. /**
  190. * 기본 매핑 정보 조회 (조인 없이)
  191. */
  192. public function getBasicMapping($mappingSeq)
  193. {
  194. return $this->where('SEQ', $mappingSeq)
  195. ->where('IS_ACT', 'Y')
  196. ->first();
  197. }
  198. /**
  199. * 벤더사-인플루언서 조합의 기존 매핑 조회
  200. */
  201. public function getExistingMapping($vendorSeq, $influencerSeq, $excludeStatuses = [])
  202. {
  203. $builder = $this->builder();
  204. $query = $builder->select('VENDOR_INFLUENCER_MAPPING.*, VENDOR_INFLUENCER_STATUS_HISTORY.STATUS as CURRENT_STATUS')
  205. ->join('VENDOR_INFLUENCER_STATUS_HISTORY',
  206. 'VENDOR_INFLUENCER_STATUS_HISTORY.MAPPING_SEQ = VENDOR_INFLUENCER_MAPPING.SEQ AND VENDOR_INFLUENCER_STATUS_HISTORY.IS_CURRENT = "Y"')
  207. ->where('VENDOR_INFLUENCER_MAPPING.VENDOR_SEQ', $vendorSeq)
  208. ->where('VENDOR_INFLUENCER_MAPPING.INFLUENCER_SEQ', $influencerSeq)
  209. ->where('VENDOR_INFLUENCER_MAPPING.IS_ACT', 'Y');
  210. if (!empty($excludeStatuses)) {
  211. $query->whereNotIn('VENDOR_INFLUENCER_STATUS_HISTORY.STATUS', $excludeStatuses);
  212. }
  213. return $query->orderBy('VENDOR_INFLUENCER_MAPPING.REG_DATE', 'DESC')
  214. ->get()
  215. ->getResultArray();
  216. }
  217. /**
  218. * 매핑 비활성화
  219. */
  220. public function deactivateMapping($mappingSeq, $reason = '')
  221. {
  222. return $this->update($mappingSeq, [
  223. 'IS_ACT' => 'N',
  224. 'ADD_INFO3' => $reason,
  225. 'MOD_DATE' => date('Y-m-d H:i:s')
  226. ]);
  227. }
  228. /**
  229. * 만료일 설정
  230. */
  231. public function setExpiredDate($mappingSeq, $expiredDate)
  232. {
  233. return $this->update($mappingSeq, [
  234. 'EXPIRED_DATE' => $expiredDate,
  235. 'MOD_DATE' => date('Y-m-d H:i:s')
  236. ]);
  237. }
  238. }