Deli.php 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. <?php
  2. namespace App\Controllers;
  3. use CodeIgniter\RESTful\ResourceController;
  4. class Deli extends ResourceController
  5. {
  6. // New: 공동구매 주문 내역 리스트
  7. public function orderList()
  8. {
  9. $db = \Config\Database::connect();
  10. $request = $this->request->getJSON(true);
  11. $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
  12. $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
  13. $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
  14. $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
  15. // ITEM_ORDER_LIST와 ITEM_LIST를 JOIN해서 주문 목록 조회
  16. $builder = $db->table('ITEM_ORDER_LIST IOL')
  17. ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2, IL.TYPE as ITEM_TYPE, IL.THUMB_FILE')
  18. ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner')
  19. ->where('IL.DEL_YN', 'N'); // 삭제되지 않은 아이템만
  20. // 아이템 타입 필터링
  21. if (!empty($itemType)) {
  22. $builder->where('IL.TYPE', $itemType);
  23. }
  24. // 사용자 타입에 따른 필터링
  25. if ($memberType === 'VENDOR' && !empty($companyNumber)) {
  26. // 벤더사: 자사 아이템의 주문만
  27. $builder->where('IL.COMPANY_NUMBER', $companyNumber);
  28. } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
  29. // 인플루언서: 자신이 담당하는 주문만
  30. $builder->where('IOL.INF_SEQ', $infSeq);
  31. } elseif ($memberType === 'BRAND' && !empty($infSeq)) {
  32. // 브랜드사: 자사가 담당하는 아이템의 주문만
  33. $builder->where('IL.CONTACT_BRD', $infSeq);
  34. }
  35. // 주문일 기준으로 최신순 정렬
  36. $builder->orderBy('IOL.ORDER_DATE', 'DESC');
  37. $lists = $builder->get()->getResultArray();
  38. return $this->respond($lists, 200);
  39. }
  40. // New: 공동구매 주문 내역 등록/업데이트
  41. public function orderRegister()
  42. {
  43. // 한국 시간으로 설정
  44. date_default_timezone_set('Asia/Seoul');
  45. $db = \Config\Database::connect();
  46. $request = $this->request->getJSON(true);
  47. $itemSeq = isset($request['item_seq']) ? $request['item_seq'] : null;
  48. $infSeq = isset($request['inf_seq']) ? $request['inf_seq'] : null;
  49. $orderList = $request['orderList'] ?? [];
  50. if (!$itemSeq) {
  51. return $this->fail('필수 파라미터가 누락되었습니다.', 400);
  52. }
  53. // orderList가 비어있으면 해당 item_seq의 모든 데이터 삭제만 수행
  54. if (empty($orderList)) {
  55. $db->transBegin();
  56. try {
  57. // 기존 데이터 모두 삭제
  58. $deletedCount = $db->table('ITEM_ORDER_LIST')
  59. ->where('ITEM_SEQ', $itemSeq)
  60. ->delete();
  61. $db->transCommit();
  62. return $this->respond([
  63. 'message' => '주문 내역이 성공적으로 처리되었습니다.',
  64. 'updated_count' => 0,
  65. 'new_count' => 0,
  66. 'deleted_count' => $deletedCount,
  67. 'errors' => []
  68. ], 200);
  69. } catch (\Exception $e) {
  70. $db->transRollback();
  71. return $this->fail('주문 내역 처리 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
  72. }
  73. }
  74. // 빈 데이터나 변경사항 없는 경우 먼저 체크
  75. $hasValidData = false;
  76. foreach ($orderList as $order) {
  77. if (!empty($order['ORDER_NUMB']) && !empty($order['BUYER_NAME'])) {
  78. $hasValidData = true;
  79. break;
  80. }
  81. }
  82. // 유효한 데이터가 없으면 기존 데이터와 비교해서 변경사항 확인
  83. if (!$hasValidData) {
  84. $existingCount = $db->table('ITEM_ORDER_LIST')
  85. ->where('ITEM_SEQ', $itemSeq)
  86. ->countAllResults();
  87. // 기존 데이터도 없고 새로운 유효 데이터도 없으면 변경사항 없음
  88. if ($existingCount == 0) {
  89. return $this->respond([
  90. 'message' => '저장할 데이터가 없습니다.',
  91. 'updated_count' => 0,
  92. 'new_count' => 0,
  93. 'deleted_count' => 0,
  94. 'errors' => []
  95. ], 200);
  96. }
  97. }
  98. // 유효성 검사 (유효한 데이터가 있을 때만)
  99. foreach ($orderList as $index => $order) {
  100. // 빈 행은 건너뛰기
  101. if (empty($order['ORDER_NUMB']) && empty($order['BUYER_NAME'])) {
  102. continue;
  103. }
  104. $requiredFields = ['ORDER_NUMB', 'BUYER_NAME'];
  105. foreach ($requiredFields as $field) {
  106. if (!isset($order[$field]) || $order[$field] === '') {
  107. return $this->fail("orderList[$index] 항목의 '{$field}' 값이 누락되었습니다.", 400);
  108. }
  109. }
  110. }
  111. $db->transBegin();
  112. $updatedCount = 0;
  113. $newCount = 0;
  114. $deletedCount = 0;
  115. $errors = [];
  116. try {
  117. // 1. 먼저 해당 item_seq의 기존 데이터를 모두 조회
  118. $existingOrders = $db->table('ITEM_ORDER_LIST')
  119. ->where('ITEM_SEQ', $itemSeq)
  120. ->get()->getResultArray();
  121. // 2. 현재 전송된 데이터 목록에서 ORDER_NUMB + BUYER_NAME 조합 추출
  122. $currentOrderKeys = [];
  123. foreach ($orderList as $order) {
  124. if (!empty($order['ORDER_NUMB']) && !empty($order['BUYER_NAME'])) {
  125. $currentOrderKeys[] = $order['ORDER_NUMB'] . '_' . $order['BUYER_NAME'];
  126. }
  127. }
  128. // 3. 기존 데이터 중 현재 목록에 없는 항목들 삭제
  129. foreach ($existingOrders as $existingOrder) {
  130. $existingKey = $existingOrder['ORDER_NUMB'] . '_' . $existingOrder['BUYER_NAME'];
  131. if (!in_array($existingKey, $currentOrderKeys)) {
  132. $deleteResult = $db->table('ITEM_ORDER_LIST')
  133. ->where('SEQ', $existingOrder['SEQ'])
  134. ->delete();
  135. if ($deleteResult) {
  136. $deletedCount++;
  137. }
  138. }
  139. }
  140. // 4. 업데이트 또는 신규 추가 처리
  141. foreach ($orderList as $order) {
  142. $metadata = $order['_metadata'] ?? [];
  143. $isUpdated = $metadata['isUpdated'] ?? false;
  144. $isNew = $metadata['isNew'] ?? false;
  145. // 메타데이터가 없는 경우 DB에서 기존 데이터 확인
  146. if (!$isUpdated && !$isNew) {
  147. $existingRecord = $db->table('ITEM_ORDER_LIST')
  148. ->where('ITEM_SEQ', $itemSeq)
  149. ->where('ORDER_NUMB', $order['ORDER_NUMB'])
  150. ->where('BUYER_NAME', $order['BUYER_NAME'])
  151. ->get()->getRowArray();
  152. if ($existingRecord) {
  153. $isUpdated = true;
  154. } else {
  155. // 주문번호+구매자명이 정확히 일치하지 않으면 신규 추가
  156. $isNew = true;
  157. }
  158. }
  159. if ($isUpdated) {
  160. // 기존 데이터 조회하여 변경사항 확인
  161. $existingRecord = $db->table('ITEM_ORDER_LIST')
  162. ->where('ITEM_SEQ', $itemSeq)
  163. ->where('ORDER_NUMB', $order['ORDER_NUMB'])
  164. ->where('BUYER_NAME', $order['BUYER_NAME'])
  165. ->get()->getRowArray();
  166. if ($existingRecord) {
  167. $updateData = [];
  168. $hasChanges = false;
  169. // 각 필드별로 변경사항 확인
  170. if (($existingRecord['PHONE'] ?? '') !== ($order['PHONE'] ?? '')) {
  171. $updateData['PHONE'] = $order['PHONE'] ?? '';
  172. $hasChanges = true;
  173. }
  174. if (($existingRecord['QTY'] ?? 0) != ($order['QTY'] ?? 0)) {
  175. $updateData['QTY'] = $order['QTY'] ?? 0;
  176. $hasChanges = true;
  177. }
  178. if (($existingRecord['ADDRESS'] ?? '') != ($order['ADDRESS'] ?? 0)) {
  179. $updateData['ADDRESS'] = $order['ADDRESS'] ?? 0;
  180. $hasChanges = true;
  181. }
  182. if (($existingRecord['DELI_COMP'] ?? '') !== ($order['DELI_COMP'] ?? '')) {
  183. $updateData['DELI_COMP'] = $order['DELI_COMP'] ?? '';
  184. $hasChanges = true;
  185. }
  186. if (($existingRecord['DELI_NUMB'] ?? '') !== ($order['DELI_NUMB'] ?? '')) {
  187. $updateData['DELI_NUMB'] = $order['DELI_NUMB'] ?? '';
  188. $hasChanges = true;
  189. }
  190. // 실제 변경사항이 있을 때만 UPDATE_DATE 갱신
  191. if ($hasChanges) {
  192. $updateData['UPDATE_DATE'] = date('Y-m-d H:i:s');
  193. $result = $db->table('ITEM_ORDER_LIST')
  194. ->where('ITEM_SEQ', $itemSeq)
  195. ->where('ORDER_NUMB', $order['ORDER_NUMB'])
  196. ->where('BUYER_NAME', $order['BUYER_NAME'])
  197. ->update($updateData);
  198. if ($result) {
  199. $updatedCount++;
  200. } else {
  201. $errors[] = "업데이트 실패: {$order['ORDER_NUMB']} - {$order['BUYER_NAME']}";
  202. }
  203. }
  204. // 변경사항이 없으면 업데이트하지 않음
  205. } else {
  206. // 기존 데이터를 찾을 수 없으면 신규로 처리
  207. $isNew = true;
  208. }
  209. }
  210. if ($isNew) {
  211. // 신규 데이터 추가
  212. $insertData = [
  213. 'ITEM_SEQ' => $itemSeq,
  214. 'ORDER_NUMB' => $order['ORDER_NUMB'],
  215. 'BUYER_NAME' => $order['BUYER_NAME'],
  216. 'PHONE' => $order['PHONE'] ?? '',
  217. 'QTY' => $order['QTY'] ?? 0,
  218. 'ADDRESS' => $order['ADDRESS'] ?? '',
  219. 'INF_SEQ' => $infSeq,
  220. 'DELI_COMP' => $order['DELI_COMP'] ?? '',
  221. 'DELI_NUMB' => $order['DELI_NUMB'] ?? '',
  222. 'REG_DATE' => $metadata['originalCreatedAt'] ?? date('Y-m-d H:i:s'),
  223. 'UPDATE_DATE' => $metadata['lastModifiedAt'] ?? date('Y-m-d H:i:s'),
  224. ];
  225. $result = $db->table('ITEM_ORDER_LIST')->insert($insertData);
  226. if ($result) {
  227. $newCount++;
  228. } else {
  229. $errors[] = "삽입 실패: {$order['ORDER_NUMB']} - {$order['BUYER_NAME']}";
  230. }
  231. }
  232. }
  233. // 에러가 있으면 실패로 처리
  234. if (count($errors) > 0) {
  235. $db->transRollback();
  236. return $this->fail(implode(' | ', $errors), 400);
  237. }
  238. if ($updatedCount > 0 || $newCount > 0 || $deletedCount > 0) {
  239. $db->transCommit();
  240. return $this->respond([
  241. 'message' => '주문 내역이 성공적으로 처리되었습니다.',
  242. 'updated_count' => $updatedCount,
  243. 'new_count' => $newCount,
  244. 'deleted_count' => $deletedCount,
  245. 'errors' => $errors
  246. ], 200);
  247. } else {
  248. $db->transRollback();
  249. return $this->fail('처리할 수 있는 데이터가 없습니다.', 400);
  250. }
  251. } catch (\Exception $e) {
  252. $db->transRollback();
  253. return $this->fail('주문 내역 처리 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
  254. }
  255. }
  256. //아이템 리스트
  257. public function itemlist()
  258. {
  259. $db = \Config\Database::connect();
  260. // POST JSON 파라미터 받기
  261. $request = $this->request->getJSON(true);
  262. $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
  263. $showYn = isset($request['SHOW_YN']) ? $request['SHOW_YN'] : null;
  264. $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
  265. $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
  266. $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
  267. // 서브쿼리: 사용자 타입에 따른 주문 집계
  268. $subQuery = $db->table('ITEM_ORDER_LIST')
  269. ->select('ITEM_SEQ, SUM(QTY) AS sum_qty, SUM(TOTAL) AS sum_total, MAX(REG_DATE) AS latest_reg_date');
  270. // 인플루언서: 본인이 받은 주문만
  271. if ($memberType === 'INFLUENCER') {
  272. if (is_null($infSeq)) {
  273. // INF_SEQ가 없으면 빈 결과 반환
  274. return $this->respond([], 200);
  275. }
  276. $subQuery->where('INF_SEQ', $infSeq);
  277. }
  278. // 배송정보가 등록되지 않은 주문만 (배송관리 페이지용)
  279. // 배송업체와 송장번호가 모두 비어있는 경우만 포함 (AND 조건)
  280. $subQuery->where('(DELI_COMP IS NULL OR DELI_COMP = "")')
  281. ->where('(DELI_NUMB IS NULL OR DELI_NUMB = "")');
  282. $subQuery->groupBy('ITEM_SEQ');
  283. // 메인 쿼리: ITEM_LIST와 위 서브쿼리 조인 (실제 주문이 있는 제품만)
  284. $builder = $db->table('ITEM_LIST I')
  285. ->select('I.*, O.sum_qty, O.sum_total, O.latest_reg_date')
  286. ->join("(" . $subQuery->getCompiledSelect() . ") O", 'I.SEQ = O.ITEM_SEQ', 'inner')
  287. ->where('I.DEL_YN', 'N');
  288. // 벤더: 자사 제품만 필터링
  289. if ($memberType === 'VENDOR') {
  290. if (empty($companyNumber)) {
  291. // COMPANY_NUMBER가 없으면 빈 결과 반환
  292. return $this->respond([], 200);
  293. }
  294. $builder->where('I.COMPANY_NUMBER', $companyNumber);
  295. }
  296. if (!is_null($showYn) && $showYn !== '') {
  297. $builder->where('I.SHOW_YN', $showYn);
  298. }
  299. $builder->where('I.TYPE', $itemType);
  300. $builder->orderBy('I.UDPDATE', 'DESC');
  301. $lists = $builder->get()->getResultArray();
  302. return $this->respond($lists, 200);
  303. }
  304. //아이템 검색
  305. public function deliSearch()
  306. {
  307. $db = \Config\Database::connect();
  308. // 요청 바디에서 filter와 keyword 추출
  309. $request = $this->request->getJSON(true);
  310. $filter = isset($request['filter']) ? $request['filter'] : null;
  311. $keyword = isset($request['keyword']) ? $request['keyword'] : null;
  312. $startDate = $request['startDate'] ?? null;
  313. $endDate = $request['endDate'] ?? null;
  314. $showYN = $request['showYN'] ?? null;
  315. $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
  316. $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
  317. $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
  318. $memberSeq = isset($request['MEMBER_SEQ']) ? $request['MEMBER_SEQ'] : null;
  319. $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
  320. $filterMap = [
  321. 'name' => 'I.NAME',
  322. ];
  323. // 서브쿼리: 사용자 타입에 따른 주문 집계
  324. $subQuery = $db->table('ITEM_ORDER_LIST')
  325. ->select('ITEM_SEQ, SUM(QTY) AS sum_qty, SUM(TOTAL) AS sum_total, MAX(REG_DATE) AS latest_reg_date');
  326. // 인플루언서: 본인이 받은 주문만
  327. if ($memberType === 'INFLUENCER') {
  328. if (is_null($infSeq)) {
  329. // INF_SEQ가 없으면 빈 결과 반환
  330. return $this->respond([], 200);
  331. }
  332. $subQuery->where('INF_SEQ', $infSeq);
  333. }
  334. // 배송정보가 등록되지 않은 주문만 (배송관리 페이지용)
  335. $subQuery->where('(DELI_COMP IS NULL OR DELI_COMP = "")')
  336. ->where('(DELI_NUMB IS NULL OR DELI_NUMB = "")');
  337. $subQuery->groupBy('ITEM_SEQ');
  338. // 메인 쿼리: ITEM_LIST와 위 서브쿼리 조인 (실제 주문이 있는 제품만)
  339. $builder = $db->table('ITEM_LIST I')
  340. ->select('I.*, O.sum_qty, O.sum_total, O.latest_reg_date')
  341. ->join("(" . $subQuery->getCompiledSelect() . ") O", 'I.SEQ = O.ITEM_SEQ', 'inner')
  342. ->where('I.DEL_YN', 'N');
  343. // 사용자 타입별 필터링
  344. if ($memberType === 'VENDOR' && !empty($companyNumber)) {
  345. // 벤더사의 경우: 자사 제품만 검색
  346. $builder->where('I.COMPANY_NUMBER', $companyNumber);
  347. } elseif ($memberType === 'INFLUENCER' && !empty($memberSeq)) {
  348. // 인플루언서의 경우: 파트너십이 체결된 벤더사의 제품만 검색
  349. $builder->select('I.*, O.sum_qty, O.sum_total, O.latest_reg_date, VIP.STATUS as PARTNERSHIP_STATUS');
  350. $builder->join('VENDOR_LIST VL', 'I.COMPANY_NUMBER = VL.COMPANY_NUMBER', 'inner');
  351. $builder->join('VENDOR_INFLUENCER_PARTNERSHIP VIP', 'VL.SEQ = VIP.VENDOR_SEQ', 'inner');
  352. $builder->where('VIP.INFLUENCER_SEQ', $memberSeq);
  353. $builder->where('VIP.STATUS', 'APPROVED');
  354. $builder->where('VIP.IS_ACTIVE', 'Y');
  355. }
  356. // 키워드 검색
  357. if (!empty($keyword)) {
  358. if (empty($filter)) {
  359. // 필터를 선택 안했으면 전체 검색
  360. $first = true;
  361. foreach ($filterMap as $column) {
  362. if ($first) {
  363. $builder->like($column, $keyword);
  364. $first = false;
  365. } else {
  366. $builder->orLike($column, $keyword);
  367. }
  368. }
  369. } elseif (isset($filterMap[$filter])) {
  370. // 특정 필터 검색
  371. $builder->like($filterMap[$filter], $keyword);
  372. }
  373. }
  374. // 노출중, 비노출 여부 확인
  375. if (!empty($showYN)) {
  376. $builder->where('I.SHOW_YN', $showYN);
  377. }
  378. if (!empty($itemType)) {
  379. $builder->where('I.TYPE', $itemType);
  380. }
  381. // INF_SEQ 조건 추가 (값이 있을 때만)
  382. if (!empty($infSeq)) {
  383. $builder->where('I.CONTACT_INF', $infSeq);
  384. }
  385. // 날짜 범위 검색 (latest_reg_date 기준)
  386. if (!empty($startDate)) {
  387. $builder->where('O.latest_reg_date >=', $startDate . ' 00:00:00');
  388. }
  389. if (!empty($endDate)) {
  390. $builder->where('O.latest_reg_date <=', $endDate . ' 23:59:59');
  391. }
  392. $builder->orderBy('I.UDPDATE', 'DESC');
  393. // 조회
  394. $lists = $builder->get()->getResultArray();
  395. return $this->respond($lists, 200);
  396. }
  397. //배송중 검색
  398. public function shippingSearch()
  399. {
  400. $db = \Config\Database::connect();
  401. $request = $this->request->getJSON(true);
  402. $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
  403. $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
  404. $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
  405. $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
  406. $filter = isset($request['filter']) ? $request['filter'] : null;
  407. $keyword = isset($request['keyword']) ? $request['keyword'] : null;
  408. $startDate = isset($request['startDate']) ? $request['startDate'] : null;
  409. $endDate = isset($request['endDate']) ? $request['endDate'] : null;
  410. $builder = $db->table('ITEM_ORDER_LIST IOL')
  411. ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2')
  412. ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner')
  413. ->where('IOL.DELI_COMP !=', '')
  414. ->where('IOL.DELI_NUMB !=', '')
  415. ->where('IOL.DELI_COMP IS NOT NULL')
  416. ->where('IOL.DELI_NUMB IS NOT NULL');
  417. // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 조건 추가
  418. $columns = $db->getFieldNames('ITEM_ORDER_LIST');
  419. if (in_array('DELIVERY_STATUS', $columns)) {
  420. $builder->where('IOL.DELIVERY_STATUS', 'SHIPPING');
  421. } else {
  422. // DELIVERY_STATUS 컬럼이 없으면 배송업체와 송장번호가 있는 것을 배송중으로 간주
  423. // 단, 배송완료된 것은 제외 (DELIVERED_DATE가 없는 것만)
  424. if (in_array('DELIVERED_DATE', $columns)) {
  425. $builder->where('IOL.DELIVERED_DATE IS NULL');
  426. }
  427. }
  428. // 아이템 타입 필터링
  429. if (!empty($itemType)) {
  430. $builder->where('IL.TYPE', $itemType);
  431. }
  432. // 검색 조건 추가
  433. if (!empty($keyword)) {
  434. if ($filter === 'name') {
  435. $builder->like('IL.NAME', $keyword);
  436. } elseif ($filter === 'buyer') {
  437. $builder->like('IOL.BUYER_NAME', $keyword);
  438. } else {
  439. // 전체 검색
  440. $builder->groupStart()
  441. ->like('IL.NAME', $keyword)
  442. ->orLike('IOL.BUYER_NAME', $keyword)
  443. ->groupEnd();
  444. }
  445. }
  446. // 날짜 범위 검색
  447. if (!empty($startDate)) {
  448. $builder->where('DATE(IOL.SHIPPING_DATE) >=', $startDate);
  449. }
  450. if (!empty($endDate)) {
  451. $builder->where('DATE(IOL.SHIPPING_DATE) <=', $endDate);
  452. }
  453. // 사용자 타입에 따른 필터링
  454. if ($memberType === 'VENDOR' && !empty($companyNumber)) {
  455. $builder->where('IL.COMPANY_NUMBER', $companyNumber);
  456. } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
  457. $builder->where('IOL.INF_SEQ', $infSeq);
  458. }
  459. $builder->orderBy('IOL.REG_DATE', 'DESC');
  460. $lists = $builder->get()->getResultArray();
  461. return $this->respond($lists, 200);
  462. }
  463. //구매자 리스트
  464. public function delilist()
  465. {
  466. $db = \Config\Database::connect();
  467. $request = $this->request->getJSON(true);
  468. $itemSeq = isset($request['item_seq']) ? $request['item_seq'] : null;
  469. $infSeq = isset($request['inf_seq']) ? $request['inf_seq'] : null;
  470. // 쿼리 빌더
  471. $builder = $db->table('ITEM_ORDER_LIST I');
  472. $builder->select('I.*, U.NICK_NAME');
  473. $builder->join('USER_LIST U', 'I.INF_SEQ = U.SEQ', 'left');
  474. $builder->where('I.ITEM_SEQ', $itemSeq);
  475. if ($infSeq) {
  476. $builder->where('I.INF_SEQ', $infSeq);
  477. }
  478. // 배송정보가 등록되지 않은 주문만 표시 (송장번호 등록용)
  479. // 배송업체와 송장번호가 모두 비어있는 경우만 포함
  480. $builder->where('(I.DELI_COMP IS NULL OR I.DELI_COMP = "")')
  481. ->where('(I.DELI_NUMB IS NULL OR I.DELI_NUMB = "")');
  482. // 주문일 기준으로 정렬
  483. $builder->orderBy('I.ORDER_DATE', 'DESC');
  484. $lists = $builder->get()->getResultArray();
  485. return $this->respond($lists, 200);
  486. }
  487. //구매자 등록
  488. public function deliRegister()
  489. {
  490. $db = \Config\Database::connect();
  491. $request = $this->request->getJSON(true);
  492. $itemSeq = isset($request['item_seq']) ? $request['item_seq'] : null;
  493. $infSeq = isset($request['inf_seq']) ? $request['inf_seq'] : null;
  494. $deliveryList = $request['deliveryList'] ?? [];
  495. // 🔍 먼저 전체 유효성 검사
  496. foreach ($deliveryList as $index => $delivery) {
  497. $requiredFields = ['buyerName', 'address', 'phone', 'qty', 'total', 'orderDate'];
  498. foreach ($requiredFields as $field) {
  499. if (!isset($delivery[$field]) || $delivery[$field] === '') {
  500. return $this->fail("deliveryList[$index] 항목의 '{$field}' 값이 누락되었습니다.", 400);
  501. }
  502. }
  503. }
  504. // ✅ 유효성 통과 후 삭제 + 삽입
  505. $db->table('ITEM_ORDER_LIST')
  506. ->where('ITEM_SEQ', $itemSeq)
  507. ->where('INF_SEQ', $infSeq)
  508. ->delete();
  509. foreach ($deliveryList as $delivery) {
  510. $data = [
  511. 'ITEM_SEQ' => $itemSeq,
  512. 'INF_SEQ' => $infSeq,
  513. 'BUYER_NAME' => $delivery['buyerName'],
  514. 'ADDRESS' => $delivery['address'],
  515. 'PHONE' => $delivery['phone'],
  516. 'EMAIL' => $delivery['email'],
  517. 'QTY' => $delivery['qty'],
  518. 'TOTAL' => $delivery['total'],
  519. 'DELI_COMP' => $delivery['deliComp'] ?? '',
  520. 'DELI_NUMB' => $delivery['deliNumb'] ?? '',
  521. 'ORDER_DATE' => date('Y-m-d H:i:s', strtotime($delivery['orderDate'])),
  522. 'REG_DATE' => date('Y-m-d'),
  523. ];
  524. $db->table('ITEM_ORDER_LIST')->insert($data);
  525. }
  526. return $this->respond(['message' => '배송 데이터가 성공적으로 저장되었습니다.'], 200);
  527. }
  528. //벤더사용 배송정보 업데이트
  529. public function updateDeliveryInfo()
  530. {
  531. $db = \Config\Database::connect();
  532. $request = $this->request->getJSON(true);
  533. $itemSeq = isset($request['item_seq']) ? $request['item_seq'] : null;
  534. $deliveryUpdates = $request['deliveryUpdates'] ?? [];
  535. if (!$itemSeq || empty($deliveryUpdates)) {
  536. return $this->fail('필수 파라미터가 누락되었습니다.', 400);
  537. }
  538. $db->transBegin();
  539. $updatedCount = 0;
  540. $errors = [];
  541. try {
  542. foreach ($deliveryUpdates as $update) {
  543. $buyerName = $update['buyerName'] ?? '';
  544. $phone = $update['phone'] ?? '';
  545. $deliComp = $update['deliComp'] ?? '';
  546. $deliNumb = $update['deliNumb'] ?? '';
  547. if (!$buyerName || !$phone) {
  548. $errors[] = "구매자명과 연락처는 필수입니다.";
  549. continue;
  550. }
  551. // 업데이트할 데이터 준비
  552. $updateData = [
  553. 'DELI_COMP' => $deliComp,
  554. 'DELI_NUMB' => $deliNumb
  555. ];
  556. // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 추가
  557. $columns = $db->getFieldNames('ITEM_ORDER_LIST');
  558. if (in_array('DELIVERY_STATUS', $columns)) {
  559. $updateData['DELIVERY_STATUS'] = 'SHIPPING';
  560. }
  561. if (in_array('SHIPPING_DATE', $columns)) {
  562. $updateData['SHIPPING_DATE'] = date('Y-m-d H:i:s');
  563. }
  564. // 구매자명과 연락처로 해당 주문 찾기
  565. $result = $db->table('ITEM_ORDER_LIST')
  566. ->where('ITEM_SEQ', $itemSeq)
  567. ->where('BUYER_NAME', $buyerName)
  568. ->where('PHONE', $phone)
  569. ->update($updateData);
  570. if ($result) {
  571. $updatedCount++;
  572. } else {
  573. $errors[] = "매칭되는 주문을 찾을 수 없습니다: {$buyerName}({$phone})";
  574. }
  575. }
  576. if ($updatedCount > 0) {
  577. $db->transCommit();
  578. return $this->respond([
  579. 'message' => "배송정보가 성공적으로 업데이트되었습니다.",
  580. 'updated_count' => $updatedCount,
  581. 'errors' => $errors
  582. ], 200);
  583. } else {
  584. $db->transRollback();
  585. return $this->fail('업데이트할 수 있는 데이터가 없습니다.', 400);
  586. }
  587. } catch (\Exception $e) {
  588. $db->transRollback();
  589. return $this->fail('배송정보 업데이트 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
  590. }
  591. }
  592. //아이템 상세
  593. public function itemDetail($seq)
  594. {
  595. // DB 객체 얻기
  596. $db = \Config\Database::connect();
  597. $builder = $db->table('ITEM_LIST');
  598. $item = $builder->where('seq', $seq)->get()->getRowArray();
  599. if($item){
  600. return $this->respond($item, 200);
  601. } else {
  602. return $this->respond([
  603. 'status' => 'fail',
  604. 'message' => '유효하지 않은 seq입니다.'
  605. ], 404);
  606. }
  607. }
  608. //아이템 삭제
  609. public function itemDelete($seq)
  610. {
  611. $db = \Config\Database::connect();
  612. $db->transBegin();
  613. //아이템 삭제
  614. $deleted = $db->table('ITEM_LIST')
  615. ->where('SEQ', $seq)
  616. ->update(['DEL_YN' => 'Y']);
  617. if ($db->transStatus() === false || !$deleted) {
  618. $db->transRollback();
  619. return $this->respond(['status' => 'fail', 'message' => '이벤트 삭제 중 오류가 발생했습니다.']);
  620. }
  621. $db->transCommit();
  622. return $this->respond(['status' => 'success', 'message' => '이벤트가 삭제되었습니다.'], 200);
  623. }
  624. // 배송중 리스트 조회
  625. public function getShippingList()
  626. {
  627. $db = \Config\Database::connect();
  628. $request = $this->request->getJSON(true);
  629. $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
  630. $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
  631. $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
  632. $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
  633. $builder = $db->table('ITEM_ORDER_LIST IOL')
  634. ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2')
  635. ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner')
  636. ->where('IOL.DELI_COMP !=', '')
  637. ->where('IOL.DELI_NUMB !=', '')
  638. ->where('IOL.DELI_COMP IS NOT NULL')
  639. ->where('IOL.DELI_NUMB IS NOT NULL');
  640. // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 조건 추가
  641. $columns = $db->getFieldNames('ITEM_ORDER_LIST');
  642. if (in_array('DELIVERY_STATUS', $columns)) {
  643. $builder->where('IOL.DELIVERY_STATUS', 'SHIPPING');
  644. } else {
  645. // DELIVERY_STATUS 컬럼이 없으면 배송업체와 송장번호가 있는 것을 배송중으로 간주
  646. // 단, 배송완료된 것은 제외 (DELIVERED_DATE가 없는 것만)
  647. if (in_array('DELIVERED_DATE', $columns)) {
  648. $builder->where('IOL.DELIVERED_DATE IS NULL');
  649. }
  650. }
  651. // 아이템 타입 필터링
  652. if (!empty($itemType)) {
  653. $builder->where('IL.TYPE', $itemType);
  654. }
  655. // 사용자 타입에 따른 필터링
  656. if ($memberType === 'VENDOR' && !empty($companyNumber)) {
  657. $builder->where('IL.COMPANY_NUMBER', $companyNumber);
  658. } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
  659. $builder->where('IOL.INF_SEQ', $infSeq);
  660. }
  661. $builder->orderBy('IOL.REG_DATE', 'DESC');
  662. $lists = $builder->get()->getResultArray();
  663. return $this->respond($lists, 200);
  664. }
  665. // 배송완료 리스트 조회
  666. public function getDeliveredList()
  667. {
  668. $db = \Config\Database::connect();
  669. $request = $this->request->getJSON(true);
  670. $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
  671. $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
  672. $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
  673. $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
  674. $builder = $db->table('ITEM_ORDER_LIST IOL')
  675. ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2')
  676. ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner');
  677. // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 조건 추가
  678. $columns = $db->getFieldNames('ITEM_ORDER_LIST');
  679. if (in_array('DELIVERY_STATUS', $columns)) {
  680. $builder->where('IOL.DELIVERY_STATUS', 'DELIVERED');
  681. } else {
  682. // DELIVERY_STATUS 컬럼이 없으면 배송업체와 송장번호가 있는 것을 배송완료로 간주
  683. $builder->where('IOL.DELI_COMP !=', '')
  684. ->where('IOL.DELI_NUMB !=', '')
  685. ->where('IOL.DELI_COMP IS NOT NULL')
  686. ->where('IOL.DELI_NUMB IS NOT NULL');
  687. }
  688. // 아이템 타입 필터링
  689. if (!empty($itemType)) {
  690. $builder->where('IL.TYPE', $itemType);
  691. }
  692. // 정산완료되지 않은 주문만 표시 (배송완료 페이지용)
  693. if (in_array('SETTLEMENT_STATUS', $columns)) {
  694. $builder->where('(IOL.SETTLEMENT_STATUS IS NULL OR IOL.SETTLEMENT_STATUS != "COMPLETED")');
  695. }
  696. // 사용자 타입에 따른 필터링
  697. if ($memberType === 'VENDOR' && !empty($companyNumber)) {
  698. $builder->where('IL.COMPANY_NUMBER', $companyNumber);
  699. } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
  700. $builder->where('IOL.INF_SEQ', $infSeq);
  701. }
  702. // 정렬을 안전하게 처리
  703. if (in_array('DELIVERED_DATE', $columns)) {
  704. $builder->orderBy('IOL.DELIVERED_DATE', 'DESC');
  705. } else {
  706. $builder->orderBy('IOL.REG_DATE', 'DESC');
  707. }
  708. $lists = $builder->get()->getResultArray();
  709. return $this->respond($lists, 200);
  710. }
  711. // 배송완료 처리
  712. public function markAsDelivered()
  713. {
  714. $db = \Config\Database::connect();
  715. $request = $this->request->getJSON(true);
  716. $orderIds = isset($request['order_ids']) ? $request['order_ids'] : [];
  717. if (empty($orderIds)) {
  718. return $this->fail('처리할 주문이 선택되지 않았습니다.', 400);
  719. }
  720. $db->transBegin();
  721. try {
  722. foreach ($orderIds as $orderId) {
  723. $db->table('ITEM_ORDER_LIST')
  724. ->where('SEQ', $orderId)
  725. ->update([
  726. 'DELIVERY_STATUS' => 'DELIVERED',
  727. 'DELIVERED_DATE' => date('Y-m-d H:i:s')
  728. ]);
  729. }
  730. $db->transCommit();
  731. return $this->respond(['message' => '배송완료 처리되었습니다.'], 200);
  732. } catch (\Exception $e) {
  733. $db->transRollback();
  734. return $this->fail('배송완료 처리 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
  735. }
  736. }
  737. // 정산완료 처리
  738. public function markAsSettled()
  739. {
  740. $db = \Config\Database::connect();
  741. $request = $this->request->getJSON(true);
  742. $orderIds = isset($request['order_ids']) ? $request['order_ids'] : [];
  743. if (empty($orderIds)) {
  744. return $this->fail('처리할 주문이 선택되지 않았습니다.', 400);
  745. }
  746. $db->transBegin();
  747. try {
  748. foreach ($orderIds as $orderId) {
  749. $db->table('ITEM_ORDER_LIST')
  750. ->where('SEQ', $orderId)
  751. ->update([
  752. 'SETTLEMENT_STATUS' => 'COMPLETED',
  753. 'SETTLED_DATE' => date('Y-m-d H:i:s')
  754. ]);
  755. }
  756. $db->transCommit();
  757. return $this->respond(['message' => '정산완료 처리되었습니다.'], 200);
  758. } catch (\Exception $e) {
  759. $db->transRollback();
  760. return $this->fail('정산완료 처리 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
  761. }
  762. }
  763. // 정산관리 리스트 조회
  764. public function getSettlementList()
  765. {
  766. $db = \Config\Database::connect();
  767. $request = $this->request->getJSON(true);
  768. $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
  769. $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
  770. $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
  771. $settlementStatus = isset($request['SETTLEMENT_STATUS']) ? $request['SETTLEMENT_STATUS'] : null;
  772. $builder = $db->table('ITEM_ORDER_LIST IOL')
  773. ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2, IL.TYPE as ITEM_TYPE, UL.NICK_NAME as INF_NICK_NAME')
  774. ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner')
  775. ->join('USER_LIST UL', 'IOL.INF_SEQ = UL.SEQ', 'left');
  776. // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 조건 추가
  777. $columns = $db->getFieldNames('ITEM_ORDER_LIST');
  778. if (in_array('DELIVERY_STATUS', $columns)) {
  779. $builder->where('IOL.DELIVERY_STATUS', 'DELIVERED');
  780. } else {
  781. // DELIVERY_STATUS 컬럼이 없으면 배송업체와 송장번호가 있는 것을 대상으로 함
  782. $builder->where('IOL.DELI_COMP !=', '')
  783. ->where('IOL.DELI_NUMB !=', '')
  784. ->where('IOL.DELI_COMP IS NOT NULL')
  785. ->where('IOL.DELI_NUMB IS NOT NULL');
  786. }
  787. // 정산 상태 필터링 (SETTLEMENT_STATUS 컬럼이 존재하는 경우만)
  788. if ($settlementStatus && in_array('SETTLEMENT_STATUS', $columns)) {
  789. $builder->where('IOL.SETTLEMENT_STATUS', $settlementStatus);
  790. }
  791. // 사용자 타입에 따른 필터링
  792. if ($memberType === 'VENDOR' && !empty($companyNumber)) {
  793. $builder->where('IL.COMPANY_NUMBER', $companyNumber);
  794. } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
  795. $builder->where('IOL.INF_SEQ', $infSeq);
  796. }
  797. $builder->orderBy('IOL.DELIVERED_DATE', 'DESC');
  798. $lists = $builder->get()->getResultArray();
  799. return $this->respond($lists, 200);
  800. }
  801. }