1344 lines
71 KiB
Java
1344 lines
71 KiB
Java
package com.bizcare.agent;
|
|
|
|
import jakarta.persistence.EntityManager;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.springframework.core.io.Resource;
|
|
import org.springframework.http.HttpHeaders;
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.net.URLEncoder;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.time.*;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* 접수관리 — billing_react /order(전체 리스트) 기능을 Care Homes 에 이식.
|
|
*/
|
|
@RestController
|
|
@RequestMapping("/api/agent/homes")
|
|
@RequiredArgsConstructor
|
|
class CareReceptionController {
|
|
private final EntityManager em;
|
|
private final FileStorageService fileStorage;
|
|
|
|
static final List<String> PROGRESS_STATUSES = ReceptionStatuses.progressCodes();
|
|
static final List<String> SETTLE_STATUSES = ReceptionStatuses.centerCodes();
|
|
static final List<String> GIFT_STATUSES = ReceptionStatuses.giftCodes();
|
|
static final List<String> CARRIERS = List.of("KT", "SKB", "LGU+", "SKT", "기타");
|
|
static final List<String> REGIONS = List.of(
|
|
"서울", "경기", "인천", "강원", "충북", "충남", "대전", "전북", "전남", "광주",
|
|
"경북", "대구", "경남", "울산", "부산", "제주");
|
|
|
|
@GetMapping("/receptions")
|
|
ApiResponse list(@AuthenticationPrincipal JwtUser u,
|
|
@RequestParam Map<String, String> f,
|
|
@RequestParam(defaultValue = "0") int page,
|
|
@RequestParam(defaultValue = "50") int size) {
|
|
List<HomesReception> filtered = filterReceptions(u, f);
|
|
Map<String, Long> counts = new LinkedHashMap<>();
|
|
counts.put("ALL", (long) filtered.size());
|
|
for (String st : PROGRESS_STATUSES) {
|
|
counts.put(st, filtered.stream()
|
|
.filter(r -> st.equals(ReceptionStatuses.normalizeProgress(r.getProgressStatus())))
|
|
.count());
|
|
}
|
|
int fromIdx = Math.max(0, page) * Math.max(1, size);
|
|
int limit = Math.min(Math.max(size, 1), 200);
|
|
List<Map<String, Object>> list = filtered.stream().skip(fromIdx).limit(limit)
|
|
.map(this::toMap).toList();
|
|
Map<String, Object> data = new LinkedHashMap<>();
|
|
data.put("total", filtered.size());
|
|
data.put("list", list);
|
|
data.put("counts", counts);
|
|
data.put("progressStatuses", PROGRESS_STATUSES);
|
|
data.put("settleStatuses", SETTLE_STATUSES);
|
|
data.put("giftStatuses", GIFT_STATUSES);
|
|
data.put("progressStatusLabels", ReceptionStatuses.PROGRESS);
|
|
data.put("giftStatusLabels", ReceptionStatuses.GIFT);
|
|
data.put("settleStatusLabels", ReceptionStatuses.CENTER);
|
|
data.put("giftPlaceLabels", ReceptionStatuses.GIFT_PLACE);
|
|
data.put("carriers", distinct(filtered, HomesReception::getCarrier, CARRIERS));
|
|
data.put("branches", distinct(filtered, HomesReception::getBranch, List.of()));
|
|
data.put("counselors", distinct(filtered, HomesReception::getCounselor, List.of()));
|
|
data.put("processors", distinct(filtered, HomesReception::getProcessor, List.of()));
|
|
data.put("regions", REGIONS);
|
|
data.put("giftCategories", distinct(filtered, HomesReception::getGiftCategory, List.of()));
|
|
data.put("productCategories", distinct(filtered, HomesReception::getProductCategory, List.of()));
|
|
return ApiResponse.ok(data);
|
|
}
|
|
|
|
@GetMapping(value = "/receptions/excel", produces = "text/csv; charset=UTF-8")
|
|
org.springframework.http.ResponseEntity<String> excel(@AuthenticationPrincipal JwtUser u,
|
|
@RequestParam Map<String, String> f) {
|
|
List<HomesReception> filtered = filterReceptions(u, f);
|
|
StringBuilder csv = new StringBuilder("\uFEFF");
|
|
csv.append("접수번호,접수일,상담자,지점,통신사,사은품분류,상품분류,상품명,고객명,연락처,지역,진행상황,주문번호,입고정보,처리자,세부진행,지급구분,금액,정산상태,개통일,사은품일,사은품진행,지급처,약정,개통번호,메모\n");
|
|
for (HomesReception r : filtered) {
|
|
csv.append(csvCell(r.getId())).append(',')
|
|
.append(csvCell(fmtDt(r.getOrderDate()))).append(',')
|
|
.append(csvCell(r.getCounselor())).append(',')
|
|
.append(csvCell(r.getBranch())).append(',')
|
|
.append(csvCell(r.getCarrier())).append(',')
|
|
.append(csvCell(r.getGiftCategory())).append(',')
|
|
.append(csvCell(r.getProductCategory())).append(',')
|
|
.append(csvCell(r.getProductName())).append(',')
|
|
.append(csvCell(r.getCustomerName())).append(',')
|
|
.append(csvCell(r.getPhone())).append(',')
|
|
.append(csvCell(r.getRegion())).append(',')
|
|
.append(csvCell(r.getProgressStatus())).append(',')
|
|
.append(csvCell(r.getOrderNumber())).append(',')
|
|
.append(csvCell(r.getInboundInfo())).append(',')
|
|
.append(csvCell(r.getProcessor())).append(',')
|
|
.append(csvCell(r.getDetailProgress())).append(',')
|
|
.append(csvCell(r.getPaymentType())).append(',')
|
|
.append(csvCell(r.getAmount())).append(',')
|
|
.append(csvCell(r.getSettleStatus())).append(',')
|
|
.append(csvCell(r.getOpenDate())).append(',')
|
|
.append(csvCell(r.getGiftDate())).append(',')
|
|
.append(csvCell(r.getGiftStatus())).append(',')
|
|
.append(csvCell(r.getGiftPlace())).append(',')
|
|
.append(csvCell(r.getAgreementName())).append(',')
|
|
.append(csvCell(r.getContractNumber())).append(',')
|
|
.append(csvCell(r.getMemo())).append('\n');
|
|
}
|
|
return org.springframework.http.ResponseEntity.ok()
|
|
.header(org.springframework.http.HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=receptions.csv")
|
|
.body(csv.toString());
|
|
}
|
|
|
|
@GetMapping("/receptions/{id}")
|
|
ApiResponse get(@PathVariable Long id, @AuthenticationPrincipal JwtUser u) {
|
|
HomesReception r = findOwned(id, u);
|
|
if (r == null) return ApiResponse.fail("접수를 찾을 수 없습니다.");
|
|
return ApiResponse.ok(toProgressDetail(r, u));
|
|
}
|
|
|
|
/** 업무 진행내역 저장 — billing_react POST /order/{id}/progress */
|
|
@PostMapping("/receptions/{id}/progress")
|
|
@Transactional
|
|
ApiResponse progress(@PathVariable Long id, @RequestBody Map<String, Object> body, @AuthenticationPrincipal JwtUser u) {
|
|
HomesReception r = findOwned(id, u);
|
|
if (r == null) return ApiResponse.fail("접수를 찾을 수 없습니다.");
|
|
|
|
if (body.containsKey("postIt")) r.setPostIt(str(body.get("postIt")));
|
|
if (body.containsKey("postAdd")) r.setPostAdd(str(body.get("postAdd")));
|
|
if (body.containsKey("contractNumber")) r.setContractNumber(str(body.get("contractNumber")));
|
|
if (body.containsKey("installSchedule")) r.setInstallSchedule(str(body.get("installSchedule")));
|
|
if (body.containsKey("customerLoginId") || body.containsKey("customerid")) {
|
|
Object v = body.containsKey("customerLoginId") ? body.get("customerLoginId") : body.get("customerid");
|
|
r.setCustomerLoginId(str(v));
|
|
}
|
|
if (body.containsKey("newTel")) r.setNewTel(str(body.get("newTel")));
|
|
if (body.containsKey("multiLine")) r.setMultiLine(Boolean.TRUE.equals(body.get("multiLine")) || "true".equalsIgnoreCase(String.valueOf(body.get("multiLine"))));
|
|
if (body.containsKey("addPayer")) r.setAddPayer(Boolean.TRUE.equals(body.get("addPayer")) || "true".equalsIgnoreCase(String.valueOf(body.get("addPayer"))));
|
|
if (body.containsKey("record") || body.containsKey("recordFlag")) {
|
|
Object v = body.containsKey("recordFlag") ? body.get("recordFlag") : body.get("record");
|
|
r.setRecordFlag(Boolean.TRUE.equals(v) || "true".equalsIgnoreCase(String.valueOf(v)));
|
|
}
|
|
if (body.containsKey("adminMemo")) r.setAdminMemo(str(body.get("adminMemo")));
|
|
if (body.containsKey("openDate") || body.containsKey("opended")) {
|
|
Object v = body.containsKey("openDate") ? body.get("openDate") : body.get("opended");
|
|
r.setOpenDate(parseDate(str(v)));
|
|
}
|
|
if (body.containsKey("cancelDate") || body.containsKey("canceled")) {
|
|
Object v = body.containsKey("cancelDate") ? body.get("cancelDate") : body.get("canceled");
|
|
r.setCancelDate(parseDate(str(v)));
|
|
}
|
|
if (body.containsKey("giftPlace") || body.containsKey("place")) {
|
|
Object v = body.containsKey("giftPlace") ? body.get("giftPlace") : body.get("place");
|
|
r.setGiftPlace(str(v));
|
|
}
|
|
if (body.containsKey("giftRequested") || body.containsKey("requested")) {
|
|
Object v = body.containsKey("giftRequested") ? body.get("giftRequested") : body.get("requested");
|
|
r.setGiftRequested(parseDate(str(v)));
|
|
}
|
|
if (body.containsKey("giftSended") || body.containsKey("sended")) {
|
|
Object v = body.containsKey("giftSended") ? body.get("giftSended") : body.get("sended");
|
|
r.setGiftSended(parseDate(str(v)));
|
|
}
|
|
if (Boolean.TRUE.equals(body.get("changeOrderDate")) && body.get("orderDate") != null) {
|
|
r.setOrderDate(parseDateTime(str(body.get("orderDate"))));
|
|
}
|
|
|
|
String newStatus = str(body.get("status"));
|
|
if (blank(newStatus)) newStatus = str(body.get("progressStatus"));
|
|
String progressMemo = str(body.get("memo"));
|
|
if (blank(progressMemo)) progressMemo = str(body.get("progressLog"));
|
|
boolean adminOnly = Boolean.TRUE.equals(body.get("adminOnly")) || "true".equalsIgnoreCase(String.valueOf(body.get("adminOnly")));
|
|
|
|
boolean statusChanged = false;
|
|
String prevProgress = ReceptionStatuses.normalizeProgress(r.getProgressStatus());
|
|
if (!blank(newStatus)) {
|
|
newStatus = ReceptionStatuses.normalizeProgress(newStatus);
|
|
if (!Objects.equals(newStatus, prevProgress)) {
|
|
Set<String> allowed = ReceptionStatuses.orderStatusTransitions(prevProgress);
|
|
if (("f23".equals(prevProgress) || "f24".equals(prevProgress) || "f25".equals(prevProgress))
|
|
&& !allowed.isEmpty() && !allowed.contains(newStatus)) {
|
|
return ApiResponse.fail("정산 관련 상태는 정산현황 메뉴에서 변경하세요. (현재: "
|
|
+ ReceptionStatuses.progressLabel(prevProgress) + ")");
|
|
}
|
|
r.setProgressStatus(newStatus);
|
|
statusChanged = true;
|
|
applyOpenSideEffects(r, newStatus, u);
|
|
}
|
|
}
|
|
|
|
String giftStatus = str(body.get("giftStatus"));
|
|
if (body.containsKey("giftStatus")) {
|
|
giftStatus = ReceptionStatuses.normalizeGift(giftStatus);
|
|
String prevGift = ReceptionStatuses.normalizeGift(r.getGiftStatus());
|
|
if (!Objects.equals(giftStatus, prevGift)) {
|
|
r.setGiftStatus(blank(giftStatus) ? null : giftStatus);
|
|
if ("g01".equals(giftStatus) && r.getGiftRequested() == null) {
|
|
r.setGiftRequested(LocalDate.now(ZoneId.of("Asia/Seoul")));
|
|
}
|
|
if ("g07".equals(giftStatus)) {
|
|
if (r.getGiftSended() == null) {
|
|
LocalDate today = LocalDate.now(ZoneId.of("Asia/Seoul"));
|
|
r.setGiftSended(today);
|
|
r.setGiftDate(today);
|
|
}
|
|
String cur = ReceptionStatuses.normalizeProgress(r.getProgressStatus());
|
|
if ("f14".equals(cur)) {
|
|
r.setProgressStatus("f23");
|
|
r.setSettleStatus("h01");
|
|
statusChanged = true;
|
|
appendLog(r, "f23", "사은품 지급완료 후 정산대기 자동변경", u, false);
|
|
}
|
|
}
|
|
appendGiftLog(r, blank(giftStatus) ? prevGift : giftStatus, str(body.get("giftProgressLog")), u);
|
|
} else if (!blank(str(body.get("giftProgressLog")))) {
|
|
appendGiftLog(r, r.getGiftStatus(), str(body.get("giftProgressLog")), u);
|
|
}
|
|
} else if (!blank(str(body.get("giftProgressLog")))) {
|
|
appendGiftLog(r, r.getGiftStatus(), str(body.get("giftProgressLog")), u);
|
|
}
|
|
|
|
String centerStatus = str(body.containsKey("centerStatus") ? body.get("centerStatus") : body.get("settleStatus"));
|
|
if (!blank(centerStatus)) {
|
|
centerStatus = ReceptionStatuses.normalizeCenter(centerStatus);
|
|
if (!Objects.equals(centerStatus, ReceptionStatuses.normalizeCenter(r.getSettleStatus()))) {
|
|
r.setSettleStatus(centerStatus);
|
|
}
|
|
}
|
|
|
|
if (statusChanged || !blank(progressMemo)) {
|
|
appendLog(r, blank(newStatus) ? r.getProgressStatus() : newStatus, progressMemo, u, adminOnly);
|
|
}
|
|
|
|
if (body.containsKey("processor") && !blank(str(body.get("processor")))) {
|
|
r.setProcessor(str(body.get("processor")));
|
|
} else if (statusChanged) {
|
|
r.setProcessor(resolveMemberName(u));
|
|
}
|
|
|
|
writeLog(u, "RECEPTION", "접수-진행", "접수 #" + r.getId() + " [" + nullToEmpty(r.getCustomerName()) + "] 진행내역 저장");
|
|
return ApiResponse.ok(toProgressDetail(r, u));
|
|
}
|
|
|
|
/** f14 개통완료 시 사은품 g01 + 입력처 h01 + 개통일 */
|
|
private void applyOpenSideEffects(HomesReception r, String newStatus, JwtUser u) {
|
|
if ("f22".equals(newStatus) && r.getCancelDate() == null) {
|
|
r.setCancelDate(LocalDate.now(ZoneId.of("Asia/Seoul")));
|
|
}
|
|
if (ReceptionStatuses.isPreCalc(newStatus)) {
|
|
r.setReceptionCostId(null);
|
|
}
|
|
if (!"f14".equals(newStatus)) return;
|
|
if (r.getOpenDate() == null) {
|
|
r.setOpenDate(LocalDate.now(ZoneId.of("Asia/Seoul")));
|
|
}
|
|
String gift = ReceptionStatuses.normalizeGift(r.getGiftStatus());
|
|
if (blank(gift)) {
|
|
r.setGiftStatus("g01");
|
|
if (r.getGiftRequested() == null) {
|
|
r.setGiftRequested(LocalDate.now(ZoneId.of("Asia/Seoul")));
|
|
}
|
|
appendGiftLog(r, "g01", "개통완료 후 자동변경", u);
|
|
}
|
|
String center = ReceptionStatuses.normalizeCenter(r.getSettleStatus());
|
|
r.setSettleStatus(blank(center) ? "h01" : center);
|
|
}
|
|
|
|
@DeleteMapping("/receptions/progress-log/{logId}")
|
|
@Transactional
|
|
ApiResponse deleteProgressLog(@PathVariable Long logId, @AuthenticationPrincipal JwtUser u) {
|
|
HomesReceptionProgressLog log = em.find(HomesReceptionProgressLog.class, logId);
|
|
if (log == null || !Objects.equals(log.getGroupId(), u.getGroupId())) return ApiResponse.fail("로그를 찾을 수 없습니다.");
|
|
em.remove(log);
|
|
return ApiResponse.ok(null);
|
|
}
|
|
|
|
@DeleteMapping("/receptions/gift-progress-log/{logId}")
|
|
@Transactional
|
|
ApiResponse deleteGiftProgressLog(@PathVariable Long logId, @AuthenticationPrincipal JwtUser u) {
|
|
HomesReceptionGiftProgressLog log = em.find(HomesReceptionGiftProgressLog.class, logId);
|
|
if (log == null || !Objects.equals(log.getGroupId(), u.getGroupId())) return ApiResponse.fail("로그를 찾을 수 없습니다.");
|
|
em.remove(log);
|
|
return ApiResponse.ok(null);
|
|
}
|
|
|
|
@PostMapping("/receptions")
|
|
@Transactional
|
|
ApiResponse create(@RequestBody Map<String, Object> body, @AuthenticationPrincipal JwtUser u) {
|
|
HomesReception r = new HomesReception();
|
|
r.setGroupId(u.getGroupId());
|
|
apply(r, body);
|
|
if (r.getOrderDate() == null) r.setOrderDate(LocalDateTime.now(ZoneId.of("Asia/Seoul")));
|
|
if (blank(r.getProgressStatus())) r.setProgressStatus("f01");
|
|
else r.setProgressStatus(ReceptionStatuses.normalizeProgress(r.getProgressStatus()));
|
|
if (blank(r.getSettleStatus())) r.setSettleStatus("h01");
|
|
else r.setSettleStatus(ReceptionStatuses.normalizeCenter(r.getSettleStatus()));
|
|
if (blank(r.getGiftStatus()) || "미지급".equals(r.getGiftStatus())) r.setGiftStatus(null);
|
|
else r.setGiftStatus(ReceptionStatuses.normalizeGift(r.getGiftStatus()));
|
|
if (blank(r.getOrderNumber())) r.setOrderNumber(genOrderNumber());
|
|
em.persist(r);
|
|
em.flush();
|
|
appendLog(r, r.getProgressStatus(), "접수 등록", u);
|
|
writeLog(u, "RECEPTION", "접수-등록", "접수 [" + nullToEmpty(r.getCustomerName()) + "] 등록하였습니다.");
|
|
return ApiResponse.ok(toMap(r));
|
|
}
|
|
|
|
@PutMapping("/receptions/{id}")
|
|
@Transactional
|
|
ApiResponse update(@PathVariable Long id, @RequestBody Map<String, Object> body, @AuthenticationPrincipal JwtUser u) {
|
|
HomesReception r = findOwned(id, u);
|
|
if (r == null) return ApiResponse.fail("접수를 찾을 수 없습니다.");
|
|
String prev = r.getProgressStatus();
|
|
apply(r, body);
|
|
if (!Objects.equals(prev, r.getProgressStatus())) {
|
|
appendLog(r, r.getProgressStatus(), str(body.get("progressMemo")), u);
|
|
}
|
|
writeLog(u, "RECEPTION", "접수-수정", "접수 [" + nullToEmpty(r.getCustomerName()) + "] 수정하였습니다.");
|
|
return ApiResponse.ok(toMap(r));
|
|
}
|
|
|
|
@DeleteMapping("/receptions/{id}")
|
|
@Transactional
|
|
ApiResponse delete(@PathVariable Long id, @AuthenticationPrincipal JwtUser u) {
|
|
HomesReception r = findOwned(id, u);
|
|
if (r == null) return ApiResponse.fail("접수를 찾을 수 없습니다.");
|
|
writeLog(u, "RECEPTION", "접수-삭제", "접수 [" + nullToEmpty(r.getCustomerName()) + "] 삭제하였습니다.");
|
|
em.remove(r);
|
|
return ApiResponse.ok(null);
|
|
}
|
|
|
|
@PostMapping("/receptions/delete")
|
|
@Transactional
|
|
ApiResponse bulkDelete(@RequestBody Map<String, Object> body, @AuthenticationPrincipal JwtUser u) {
|
|
List<Long> ids = toIds(body.get("ids"));
|
|
int n = 0;
|
|
for (Long id : ids) {
|
|
HomesReception r = findOwned(id, u);
|
|
if (r == null) continue;
|
|
writeLog(u, "RECEPTION", "접수-삭제", "접수 [" + nullToEmpty(r.getCustomerName()) + "] 삭제하였습니다.");
|
|
em.remove(r);
|
|
n++;
|
|
}
|
|
return ApiResponse.ok(Map.of("count", n));
|
|
}
|
|
|
|
@PostMapping("/receptions/bulk-progress")
|
|
@Transactional
|
|
ApiResponse bulkProgress(@RequestBody Map<String, Object> body, @AuthenticationPrincipal JwtUser u) {
|
|
List<Long> ids = toIds(body.get("ids"));
|
|
if (ids.isEmpty()) return ApiResponse.fail("리스트를 선택하세요.");
|
|
String status = str(body.get("status"));
|
|
if (blank(status)) return ApiResponse.fail("진행상황을 선택하세요.");
|
|
String memo = "[일괄처리] " + nullToEmpty(str(body.get("memo")));
|
|
boolean adminOnly = Boolean.TRUE.equals(body.get("adminOnly"));
|
|
String processor = firstNonBlank(str(body.get("centerId")), str(body.get("processor")), str(body.get("centerName")));
|
|
LocalDate opened = parseDate(str(body.containsKey("opended") ? body.get("opended")
|
|
: body.containsKey("opened") ? body.get("opened") : body.get("openDate")));
|
|
LocalDate canceled = parseDate(str(body.containsKey("canceled") ? body.get("canceled") : body.get("cancelDate")));
|
|
|
|
List<HomesReception> rows = new ArrayList<>();
|
|
String baseStatus = null;
|
|
for (Long id : ids) {
|
|
HomesReception r = findOwned(id, u);
|
|
if (r == null) return ApiResponse.fail("접수 리스트가 올바르지 않습니다.");
|
|
if (baseStatus != null && !Objects.equals(baseStatus, r.getProgressStatus())) {
|
|
return ApiResponse.fail("진행상황이 다른 접수가 포함되어 있습니다.");
|
|
}
|
|
baseStatus = r.getProgressStatus();
|
|
rows.add(r);
|
|
}
|
|
|
|
int n = 0;
|
|
for (HomesReception r : rows) {
|
|
String normalized = ReceptionStatuses.normalizeProgress(status);
|
|
r.setProgressStatus(normalized);
|
|
if (!blank(processor)) r.setProcessor(processor);
|
|
if (opened != null) r.setOpenDate(opened);
|
|
if (canceled != null) r.setCancelDate(canceled);
|
|
applyOpenSideEffects(r, normalized, u);
|
|
appendLog(r, normalized, memo, u, adminOnly);
|
|
n++;
|
|
}
|
|
writeLog(u, "RECEPTION", "접수-일괄진행", "접수 " + n + "건 진행상황을 [" + status + "]로 변경하였습니다.");
|
|
return ApiResponse.ok(Map.of("count", n));
|
|
}
|
|
|
|
@PostMapping("/receptions/bulk-gift")
|
|
@Transactional
|
|
ApiResponse bulkGift(@RequestBody Map<String, Object> body, @AuthenticationPrincipal JwtUser u) {
|
|
List<Long> ids = toIds(body.get("ids"));
|
|
if (ids.isEmpty()) return ApiResponse.fail("리스트를 선택하세요.");
|
|
String status = str(body.get("status"));
|
|
if (blank(status)) return ApiResponse.fail("사은품진행상황을 선택하세요.");
|
|
String place = str(body.get("place"));
|
|
String giftMemo = "[일괄처리] " + nullToEmpty(str(
|
|
body.containsKey("giftProgressLog") ? body.get("giftProgressLog") : body.get("memo")));
|
|
String deliveryCompany = str(body.get("deliveryCompany"));
|
|
String trackingNumber = str(body.get("trackingNumber"));
|
|
LocalDate requested = parseDate(str(body.containsKey("requested") ? body.get("requested") : body.get("giftRequested")));
|
|
LocalDate sended = parseDate(str(body.containsKey("sended") ? body.get("sended")
|
|
: body.containsKey("giftSended") ? body.get("giftSended") : body.get("giftDate")));
|
|
|
|
List<HomesReception> rows = new ArrayList<>();
|
|
String basePlace = null;
|
|
for (Long id : ids) {
|
|
HomesReception r = findOwned(id, u);
|
|
if (r == null) return ApiResponse.fail("선택한 접수가 올바르지 않습니다.");
|
|
String p = r.getGiftPlace();
|
|
if (basePlace == null) {
|
|
basePlace = p;
|
|
} else {
|
|
boolean baseSelf = "b02".equals(basePlace) || "영업점".equals(basePlace);
|
|
boolean curSelf = "b02".equals(p) || "영업점".equals(p);
|
|
if (baseSelf != curSelf) return ApiResponse.fail("사은품 지급처가 다른 접수가 포함되어 있습니다.");
|
|
}
|
|
rows.add(r);
|
|
}
|
|
|
|
int n = 0;
|
|
for (HomesReception r : rows) {
|
|
String normalized = ReceptionStatuses.normalizeGift(status);
|
|
r.setGiftStatus(blank(normalized) ? null : normalized);
|
|
if (!blank(place)) r.setGiftPlace(place);
|
|
if (!blank(deliveryCompany)) r.setDeliveryCompany(deliveryCompany);
|
|
if (!blank(trackingNumber)) r.setTrackingNumber(trackingNumber);
|
|
if (requested != null) r.setGiftRequested(requested);
|
|
if (sended != null) {
|
|
r.setGiftSended(sended);
|
|
r.setGiftDate(sended);
|
|
}
|
|
if ("g01".equals(normalized) && r.getGiftRequested() == null) {
|
|
r.setGiftRequested(LocalDate.now(ZoneId.of("Asia/Seoul")));
|
|
}
|
|
if ("g07".equals(normalized)) {
|
|
if (r.getGiftSended() == null) {
|
|
LocalDate today = LocalDate.now(ZoneId.of("Asia/Seoul"));
|
|
r.setGiftSended(today);
|
|
r.setGiftDate(today);
|
|
}
|
|
if ("f14".equals(ReceptionStatuses.normalizeProgress(r.getProgressStatus()))) {
|
|
r.setProgressStatus("f23");
|
|
r.setSettleStatus("h01");
|
|
appendLog(r, "f23", "사은품 일괄지급완료 후 정산대기", u, false);
|
|
}
|
|
}
|
|
appendGiftLog(r, blank(normalized) ? status : normalized, giftMemo, u);
|
|
n++;
|
|
}
|
|
writeLog(u, "RECEPTION", "사은품-일괄", "접수 " + n + "건 사은품진행을 [" + status + "]로 변경하였습니다.");
|
|
return ApiResponse.ok(Map.of("count", n));
|
|
}
|
|
|
|
@PostMapping("/receptions/bulk-center-progress")
|
|
@Transactional
|
|
ApiResponse bulkCenterProgress(@RequestBody Map<String, Object> body, @AuthenticationPrincipal JwtUser u) {
|
|
List<Long> ids = toIds(body.get("ids"));
|
|
if (ids.isEmpty()) return ApiResponse.fail("리스트를 선택하세요.");
|
|
|
|
List<HomesReception> rows = new ArrayList<>();
|
|
for (Long id : ids) {
|
|
HomesReception r = findOwned(id, u);
|
|
if (r == null) return ApiResponse.fail("접수 리스트가 올바르지 않습니다.");
|
|
// 입력처 정산이 비어있거나 정산대기(h01)인 건만 대상
|
|
String st = ReceptionStatuses.normalizeCenter(r.getSettleStatus());
|
|
if (!blank(st) && !"h01".equals(st)) {
|
|
return ApiResponse.fail("접수 리스트가 올바르지 않습니다.");
|
|
}
|
|
rows.add(r);
|
|
}
|
|
|
|
int n = 0;
|
|
for (HomesReception r : rows) {
|
|
r.setSettleStatus("h01");
|
|
appendLog(r, r.getProgressStatus(), "[일괄변경] 입력처 정산대기", u, false);
|
|
n++;
|
|
}
|
|
writeLog(u, "RECEPTION", "입력처-일괄", "접수 " + n + "건을 입력처 정산대기로 변경하였습니다.");
|
|
return ApiResponse.ok(Map.of("count", n));
|
|
}
|
|
|
|
/** 신규신청 통신사 목록 (billing_react GET /isp?onlyOn=true) */
|
|
@GetMapping("/reception-isps")
|
|
ApiResponse isps(@AuthenticationPrincipal JwtUser u) {
|
|
List<HomesReceptionIsp> list = em.createQuery(
|
|
"select e from HomesReceptionIsp e where e.groupId=:g and (e.active is null or e.active=true) order by e.seq asc, e.id asc",
|
|
HomesReceptionIsp.class)
|
|
.setParameter("g", u.getGroupId()).getResultList();
|
|
return ApiResponse.ok(list.stream().map(i -> {
|
|
Map<String, Object> m = new LinkedHashMap<>();
|
|
m.put("id", i.getId());
|
|
m.put("name", i.getName());
|
|
m.put("telecom", i.getTelecom());
|
|
m.put("seq", i.getSeq());
|
|
m.put("isSktb", Boolean.TRUE.equals(i.getIsSktb()));
|
|
return m;
|
|
}).toList());
|
|
}
|
|
|
|
@GetMapping("/reception-isps/{ispId}/products")
|
|
ApiResponse ispProducts(@PathVariable Long ispId, @AuthenticationPrincipal JwtUser u) {
|
|
HomesReceptionIsp isp = findIsp(ispId, u);
|
|
if (isp == null) return ApiResponse.fail("통신사를 찾을 수 없습니다.");
|
|
List<HomesReceptionIspProduct> list = em.createQuery(
|
|
"select e from HomesReceptionIspProduct e where e.groupId=:g and e.ispId=:isp and (e.active is null or e.active=true) order by e.id",
|
|
HomesReceptionIspProduct.class)
|
|
.setParameter("g", u.getGroupId()).setParameter("isp", ispId).getResultList();
|
|
return ApiResponse.ok(list.stream().map(p -> Map.of(
|
|
"id", p.getId(),
|
|
"type", nullToEmpty(p.getProductType()),
|
|
"name", nullToEmpty(p.getName())
|
|
)).toList());
|
|
}
|
|
|
|
@GetMapping("/reception-isps/{ispId}/agreements")
|
|
ApiResponse ispAgreements(@PathVariable Long ispId, @AuthenticationPrincipal JwtUser u) {
|
|
HomesReceptionIsp isp = findIsp(ispId, u);
|
|
if (isp == null) return ApiResponse.fail("통신사를 찾을 수 없습니다.");
|
|
List<HomesReceptionIspAgreement> list = em.createQuery(
|
|
"select e from HomesReceptionIspAgreement e where e.groupId=:g and e.ispId=:isp and (e.active is null or e.active=true) order by e.id",
|
|
HomesReceptionIspAgreement.class)
|
|
.setParameter("g", u.getGroupId()).setParameter("isp", ispId).getResultList();
|
|
return ApiResponse.ok(list.stream().map(a -> Map.of(
|
|
"id", a.getId(),
|
|
"name", nullToEmpty(a.getName())
|
|
)).toList());
|
|
}
|
|
|
|
/**
|
|
* 신규신청 등록 — billing_react POST /order 를 Care Homes reception 으로 매핑.
|
|
* body: { ispId, counselor, branch, customer:{type,name,phone,region,address,ssid,postIt}, payment:{method,name,...},
|
|
* product:{productType,productId,agreementId,price,installDate,discount}, gift:{type,place,cashAmount,goods,giftDate}, memo }
|
|
*/
|
|
@PostMapping("/receptions/apply")
|
|
@Transactional
|
|
ApiResponse apply(@RequestBody Map<String, Object> body, @AuthenticationPrincipal JwtUser u) {
|
|
Long ispId = toLong(body.get("ispId"));
|
|
HomesReceptionIsp isp = ispId == null ? null : findIsp(ispId, u);
|
|
if (isp == null) return ApiResponse.fail("통신사를 선택하세요.");
|
|
|
|
@SuppressWarnings("unchecked")
|
|
Map<String, Object> customer = body.get("customer") instanceof Map<?, ?> m ? (Map<String, Object>) m : Map.of();
|
|
@SuppressWarnings("unchecked")
|
|
Map<String, Object> payment = body.get("payment") instanceof Map<?, ?> m ? (Map<String, Object>) m : Map.of();
|
|
@SuppressWarnings("unchecked")
|
|
Map<String, Object> product = body.get("product") instanceof Map<?, ?> m ? (Map<String, Object>) m : Map.of();
|
|
@SuppressWarnings("unchecked")
|
|
Map<String, Object> gift = body.get("gift") instanceof Map<?, ?> m ? (Map<String, Object>) m : Map.of();
|
|
|
|
String customerName = str(customer.get("name"));
|
|
if (blank(customerName)) return ApiResponse.fail("고객명을 입력하세요.");
|
|
Long productId = toLong(product.get("productId"));
|
|
if (productId == null) return ApiResponse.fail("상품을 선택하세요.");
|
|
|
|
HomesReceptionIspProduct prod = em.find(HomesReceptionIspProduct.class, productId);
|
|
if (prod == null || !Objects.equals(prod.getGroupId(), u.getGroupId()) || !Objects.equals(prod.getIspId(), ispId)) {
|
|
return ApiResponse.fail("상품이 올바르지 않습니다.");
|
|
}
|
|
String agreementName = null;
|
|
Long agreementId = toLong(product.get("agreementId"));
|
|
if (agreementId != null) {
|
|
HomesReceptionIspAgreement ag = em.find(HomesReceptionIspAgreement.class, agreementId);
|
|
if (ag != null && Objects.equals(ag.getGroupId(), u.getGroupId())) agreementName = ag.getName();
|
|
}
|
|
|
|
String productTypeLabel = switch (nullToEmpty(prod.getProductType())) {
|
|
case "e02" -> "전화";
|
|
case "e03" -> "TV";
|
|
case "e04" -> "렌탈";
|
|
default -> "인터넷";
|
|
};
|
|
String giftType = str(gift.get("type"));
|
|
String giftCategory = switch (nullToEmpty(giftType)) {
|
|
case "a02" -> "현금";
|
|
case "a03" -> "상품";
|
|
case "a04" -> "현금+상품";
|
|
case "a01" -> "없음";
|
|
default -> blank(giftType) ? "상품권" : giftType;
|
|
};
|
|
String giftPlaceCode = str(gift.get("place"));
|
|
String payMethod = str(payment.get("method"));
|
|
String paymentType = switch (nullToEmpty(payMethod)) {
|
|
case "card" -> "카드";
|
|
case "paper" -> "지로";
|
|
case "telephone" -> "전화납부";
|
|
default -> "계좌";
|
|
};
|
|
|
|
HomesReception r = new HomesReception();
|
|
r.setGroupId(u.getGroupId());
|
|
r.setOrderDate(LocalDateTime.now(ZoneId.of("Asia/Seoul")));
|
|
r.setIspId(isp.getId());
|
|
r.setIspName(isp.getName());
|
|
r.setCarrier(isp.getTelecom());
|
|
r.setCounselor(blank(str(body.get("counselor"))) ? resolveMemberName(u) : str(body.get("counselor")));
|
|
r.setBranch(str(body.get("branch")));
|
|
r.setBranchGroup(str(body.get("branchGroup")));
|
|
r.setCustomerType(blank(str(customer.get("type"))) ? "public" : str(customer.get("type")));
|
|
r.setCustomerName(customerName);
|
|
r.setPhone(str(customer.get("phone")));
|
|
r.setTel(str(customer.get("tel")));
|
|
r.setEmail(str(customer.get("email")));
|
|
r.setZipcode(str(customer.get("zipcode")));
|
|
r.setAddress(str(customer.get("address")));
|
|
r.setAddressDetail(str(customer.get("addressDetail")));
|
|
r.setRegion(str(customer.get("region")));
|
|
r.setIdentifyNumber(str(customer.get("ssid")));
|
|
r.setPostIt(str(customer.get("postIt")));
|
|
r.setPostAdd(str(customer.get("postAdd")));
|
|
r.setProductType(prod.getProductType());
|
|
r.setProductCategory(productTypeLabel);
|
|
r.setProductName(prod.getName());
|
|
r.setAgreementName(agreementName);
|
|
r.setAmount(toDecimal(product.get("price")));
|
|
r.setOpenDate(parseDate(str(product.get("installDate"))));
|
|
r.setGiftCategory(giftCategory);
|
|
r.setGiftPlace(giftPlaceCode);
|
|
r.setGiftDate(parseDate(str(gift.get("giftDate"))));
|
|
r.setGiftStatus(blank(giftType) || "a01".equals(giftType) ? null : "g01");
|
|
if ("g01".equals(r.getGiftStatus())) {
|
|
r.setGiftRequested(LocalDate.now(ZoneId.of("Asia/Seoul")));
|
|
} r.setGiftCashAmount(toDecimal(gift.get("cashAmount")));
|
|
r.setGiftGoods(str(gift.get("goods")));
|
|
r.setGiftGoodsPrice(toDecimal(gift.get("goodsPrice")));
|
|
r.setGiftBank(str(gift.get("accountBank")));
|
|
r.setGiftAccountNumber(str(gift.get("accountNumber")));
|
|
r.setGiftAccountName(str(gift.get("accountName")));
|
|
r.setGiftSsid(str(gift.get("ssid")));
|
|
r.setPaymentMethod(blank(payMethod) ? "transfer" : payMethod);
|
|
r.setPaymentType(paymentType);
|
|
r.setPaymentName(str(payment.get("name")));
|
|
r.setPaymentSsid(str(payment.get("ssid")));
|
|
r.setPaymentTel(str(payment.get("tel")));
|
|
r.setPaymentBank(str(payment.get("bank")));
|
|
r.setPaymentAccountNumber(str(payment.get("accountNumber")));
|
|
r.setPaymentCardCompany(str(payment.get("cardCompany")));
|
|
r.setPaymentCardYear(str(payment.get("cardYear")));
|
|
r.setPaymentCardMonth(str(payment.get("cardMonth")));
|
|
r.setPaymentCardNumber(str(payment.get("cardNumber")));
|
|
r.setProgressStatus("f01");
|
|
r.setSettleStatus("h01");
|
|
r.setOrderNumber(genOrderNumber());
|
|
r.setProcessor(r.getCounselor());
|
|
r.setDetailProgress("신규신청");
|
|
r.setMemo(str(body.get("memo")));
|
|
em.persist(r);
|
|
em.flush();
|
|
appendLog(r, r.getProgressStatus(), "신규신청 [" + isp.getName() + "]", u, false);
|
|
writeLog(u, "RECEPTION", "신규신청", "신규신청 [" + isp.getName() + "] " + customerName + " 등록하였습니다.");
|
|
return ApiResponse.ok(toProgressDetail(r, u));
|
|
}
|
|
|
|
// ---- 첨부파일 (일반 file1~5) ----
|
|
@PostMapping("/receptions/{id}/file/{slot}")
|
|
@Transactional
|
|
ApiResponse uploadFile(@PathVariable Long id, @PathVariable int slot,
|
|
@RequestParam("file") MultipartFile file,
|
|
@AuthenticationPrincipal JwtUser u) {
|
|
return uploadAttachment(id, slot, false, file, u);
|
|
}
|
|
|
|
@GetMapping("/receptions/{id}/file/{slot}")
|
|
ResponseEntity<Resource> downloadFile(@PathVariable Long id, @PathVariable int slot,
|
|
@AuthenticationPrincipal JwtUser u) {
|
|
return downloadAttachment(id, slot, false, u);
|
|
}
|
|
|
|
@DeleteMapping("/receptions/{id}/file/{slot}")
|
|
@Transactional
|
|
ApiResponse deleteFile(@PathVariable Long id, @PathVariable int slot,
|
|
@AuthenticationPrincipal JwtUser u) {
|
|
return deleteAttachment(id, slot, false, u);
|
|
}
|
|
|
|
// ---- 관리자 첨부파일 (admin_file1~3) ----
|
|
@PostMapping("/receptions/{id}/admin-file/{slot}")
|
|
@Transactional
|
|
ApiResponse uploadAdminFile(@PathVariable Long id, @PathVariable int slot,
|
|
@RequestParam("file") MultipartFile file,
|
|
@AuthenticationPrincipal JwtUser u) {
|
|
return uploadAttachment(id, slot, true, file, u);
|
|
}
|
|
|
|
@GetMapping("/receptions/{id}/admin-file/{slot}")
|
|
ResponseEntity<Resource> downloadAdminFile(@PathVariable Long id, @PathVariable int slot,
|
|
@AuthenticationPrincipal JwtUser u) {
|
|
return downloadAttachment(id, slot, true, u);
|
|
}
|
|
|
|
@DeleteMapping("/receptions/{id}/admin-file/{slot}")
|
|
@Transactional
|
|
ApiResponse deleteAdminFile(@PathVariable Long id, @PathVariable int slot,
|
|
@AuthenticationPrincipal JwtUser u) {
|
|
return deleteAttachment(id, slot, true, u);
|
|
}
|
|
|
|
private ApiResponse uploadAttachment(Long id, int slot, boolean admin, MultipartFile file, JwtUser u) {
|
|
HomesReception r = findOwned(id, u);
|
|
int max = admin ? 3 : 5;
|
|
if (slot < 1 || slot > max) return ApiResponse.fail("첨부 슬롯이 올바르지 않습니다.");
|
|
if (file == null || file.isEmpty()) return ApiResponse.fail("업로드할 파일을 선택하세요.");
|
|
String old = getFile(r, slot, admin);
|
|
if (old != null && !old.isBlank()) fileStorage.delete(old);
|
|
String path = fileStorage.store("reception/" + id, file);
|
|
setFile(r, slot, admin, path);
|
|
writeLog(u, "RECEPTION", admin ? "관리자첨부" : "첨부",
|
|
"접수 #" + id + " " + (admin ? "관리자첨부" : "첨부") + slot + " 업로드");
|
|
Map<String, Object> data = new LinkedHashMap<>();
|
|
data.put("id", r.getId());
|
|
data.put("slot", slot);
|
|
data.put("admin", admin);
|
|
data.put("path", path);
|
|
data.put("name", FileStorageService.displayName(path));
|
|
return ApiResponse.ok(data);
|
|
}
|
|
|
|
private ResponseEntity<Resource> downloadAttachment(Long id, int slot, boolean admin, JwtUser u) {
|
|
HomesReception r = findOwned(id, u);
|
|
String rel = getFile(r, slot, admin);
|
|
if (rel == null || rel.isBlank()) {
|
|
return ResponseEntity.notFound().build();
|
|
}
|
|
Resource resource = fileStorage.loadAsResource(rel);
|
|
String filename = URLEncoder.encode(FileStorageService.displayName(rel), StandardCharsets.UTF_8)
|
|
.replace("+", "%20");
|
|
return ResponseEntity.ok()
|
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + filename)
|
|
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
|
.body(resource);
|
|
}
|
|
|
|
private ApiResponse deleteAttachment(Long id, int slot, boolean admin, JwtUser u) {
|
|
HomesReception r = findOwned(id, u);
|
|
int max = admin ? 3 : 5;
|
|
if (slot < 1 || slot > max) return ApiResponse.fail("첨부 슬롯이 올바르지 않습니다.");
|
|
String old = getFile(r, slot, admin);
|
|
if (old != null && !old.isBlank()) fileStorage.delete(old);
|
|
setFile(r, slot, admin, null);
|
|
writeLog(u, "RECEPTION", admin ? "관리자첨부삭제" : "첨부삭제",
|
|
"접수 #" + id + " " + (admin ? "관리자첨부" : "첨부") + slot + " 삭제");
|
|
return ApiResponse.ok(Map.of("id", id, "slot", slot, "admin", admin));
|
|
}
|
|
|
|
private static String getFile(HomesReception r, int slot, boolean admin) {
|
|
if (admin) {
|
|
return switch (slot) {
|
|
case 1 -> r.getAdminFile1();
|
|
case 2 -> r.getAdminFile2();
|
|
case 3 -> r.getAdminFile3();
|
|
default -> null;
|
|
};
|
|
}
|
|
return switch (slot) {
|
|
case 1 -> r.getFile1();
|
|
case 2 -> r.getFile2();
|
|
case 3 -> r.getFile3();
|
|
case 4 -> r.getFile4();
|
|
case 5 -> r.getFile5();
|
|
default -> null;
|
|
};
|
|
}
|
|
|
|
private static void setFile(HomesReception r, int slot, boolean admin, String path) {
|
|
if (admin) {
|
|
switch (slot) {
|
|
case 1 -> r.setAdminFile1(path);
|
|
case 2 -> r.setAdminFile2(path);
|
|
case 3 -> r.setAdminFile3(path);
|
|
default -> {
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
switch (slot) {
|
|
case 1 -> r.setFile1(path);
|
|
case 2 -> r.setFile2(path);
|
|
case 3 -> r.setFile3(path);
|
|
case 4 -> r.setFile4(path);
|
|
case 5 -> r.setFile5(path);
|
|
default -> {
|
|
}
|
|
}
|
|
}
|
|
|
|
private HomesReceptionIsp findIsp(Long id, JwtUser u) {
|
|
HomesReceptionIsp isp = em.find(HomesReceptionIsp.class, id);
|
|
if (isp == null || !Objects.equals(isp.getGroupId(), u.getGroupId())) return null;
|
|
return isp;
|
|
}
|
|
|
|
private static Long toLong(Object v) {
|
|
if (v == null || String.valueOf(v).isBlank()) return null;
|
|
try { return Long.valueOf(String.valueOf(v)); } catch (Exception e) { return null; }
|
|
}
|
|
|
|
private List<HomesReception> filterReceptions(JwtUser u, Map<String, String> f) {
|
|
List<HomesReception> all = em.createQuery(
|
|
"select e from HomesReception e where e.groupId=:g order by e.orderDate desc, e.id desc",
|
|
HomesReception.class)
|
|
.setParameter("g", u.getGroupId()).getResultList();
|
|
|
|
LocalDate from = parseDate(first(f, "dateFrom", "orderDateStart"));
|
|
LocalDate to = parseDate(first(f, "dateTo", "orderDateEnd"));
|
|
LocalDate openFrom = parseDate(f.get("openDateFrom"));
|
|
LocalDate openTo = parseDate(f.get("openDateTo"));
|
|
LocalDate opened = parseDate(first(f, "opended", "opened", "openDate"));
|
|
LocalDate giftSended = parseDate(first(f, "giftSended", "giftDateExact"));
|
|
String progress = blankToNull(first(f, "progressStatus", "tab"));
|
|
if ("ALL".equalsIgnoreCase(progress)) progress = null;
|
|
String settle = blankToNull(first(f, "settleStatus", "centerStatus"));
|
|
String giftStatus = blankToNull(f.get("giftStatus"));
|
|
String carrier = blankToNull(f.get("carrier"));
|
|
String branch = blankToNull(f.get("branch"));
|
|
String counselor = blankToNull(f.get("counselor"));
|
|
String processor = blankToNull(f.get("processor"));
|
|
String region = blankToNull(first(f, "region", "customerSido"));
|
|
String giftCategory = blankToNull(first(f, "giftCategory", "giftType"));
|
|
String productCategory = blankToNull(first(f, "productCategory", "productType"));
|
|
String customerName = blankToNull(f.get("customerName"));
|
|
String phone = blankToNull(f.get("customerPhone") != null ? f.get("customerPhone") : f.get("phone"));
|
|
String orderNumber = blankToNull(f.get("orderNumber"));
|
|
String q = blankToNull(first(f, "q", "keyword"));
|
|
String postIt = blankToNull(f.get("postIt"));
|
|
String agreementName = blankToNull(f.get("agreementName"));
|
|
String customerSsid = blankToNull(first(f, "customerSsid", "identifyNumber"));
|
|
String customerEmail = blankToNull(first(f, "customerEmail", "email"));
|
|
String productName = blankToNull(f.get("productName"));
|
|
String ispName = blankToNull(f.get("ispName"));
|
|
String contractNumber = blankToNull(f.get("contractNumber"));
|
|
String giftPlace = blankToNull(f.get("giftPlace"));
|
|
String branchEmployee = blankToNull(first(f, "branchEmployee"));
|
|
String branchName = blankToNull(f.get("branchName"));
|
|
String sorting = blankToNull(f.get("sorting"));
|
|
|
|
String progressF = progress;
|
|
List<HomesReception> result = all.stream().filter(r -> {
|
|
LocalDate od = r.getOrderDate() == null ? null : r.getOrderDate().toLocalDate();
|
|
if (from != null && (od == null || od.isBefore(from))) return false;
|
|
if (to != null && (od == null || od.isAfter(to))) return false;
|
|
if (openFrom != null && (r.getOpenDate() == null || r.getOpenDate().isBefore(openFrom))) return false;
|
|
if (openTo != null && (r.getOpenDate() == null || r.getOpenDate().isAfter(openTo))) return false;
|
|
if (opened != null && (r.getOpenDate() == null || !r.getOpenDate().equals(opened))) return false;
|
|
if (giftSended != null) {
|
|
LocalDate gd = r.getGiftSended() != null ? r.getGiftSended() : r.getGiftDate();
|
|
if (gd == null || !gd.equals(giftSended)) return false;
|
|
}
|
|
if (progressF != null) {
|
|
String rp = ReceptionStatuses.normalizeProgress(r.getProgressStatus());
|
|
String fp = ReceptionStatuses.normalizeProgress(progressF);
|
|
if (!fp.equals(rp) && !progressF.equals(r.getProgressStatus())) return false;
|
|
}
|
|
if (settle != null) {
|
|
String rs = ReceptionStatuses.normalizeCenter(r.getSettleStatus());
|
|
String fs = ReceptionStatuses.normalizeCenter(settle);
|
|
if (!fs.equals(rs) && !settle.equals(r.getSettleStatus())) return false;
|
|
}
|
|
if (giftStatus != null) {
|
|
String rg = ReceptionStatuses.normalizeGift(r.getGiftStatus());
|
|
String fg = ReceptionStatuses.normalizeGift(giftStatus);
|
|
if (!fg.equals(rg) && !giftStatus.equals(r.getGiftStatus())) return false;
|
|
}
|
|
if (carrier != null && !carrier.equals(r.getCarrier()) && !carrier.equals(r.getIspName())) return false;
|
|
if (ispName != null) {
|
|
String hay = (nullToEmpty(r.getIspName()) + " " + nullToEmpty(r.getCarrier())).toLowerCase();
|
|
if (!hay.contains(ispName.toLowerCase())) return false;
|
|
}
|
|
if (branch != null && !branch.equals(r.getBranch())) return false;
|
|
if (branchName != null && !nullToEmpty(r.getBranch()).contains(branchName)) return false;
|
|
if (counselor != null && !counselor.equals(r.getCounselor())) return false;
|
|
if (branchEmployee != null && !nullToEmpty(r.getCounselor()).contains(branchEmployee)) return false;
|
|
if (processor != null && !processor.equals(r.getProcessor())) return false;
|
|
if (region != null && !region.equals(r.getRegion())) return false;
|
|
if (giftCategory != null && !nullToEmpty(r.getGiftCategory()).contains(giftCategory)) return false;
|
|
if (productCategory != null
|
|
&& !productCategory.equals(r.getProductCategory())
|
|
&& !productCategory.equals(r.getProductType())) return false;
|
|
if (giftPlace != null && !giftPlace.equals(r.getGiftPlace())) return false;
|
|
if (customerName != null && !nullToEmpty(r.getCustomerName()).contains(customerName)) return false;
|
|
if (phone != null) {
|
|
String digits = nullToEmpty(r.getPhone()).replaceAll("\\D", "");
|
|
if (!digits.contains(phone.replaceAll("\\D", "")) && !nullToEmpty(r.getPhone()).contains(phone)) return false;
|
|
}
|
|
if (orderNumber != null && !nullToEmpty(r.getOrderNumber()).contains(orderNumber)) return false;
|
|
if (postIt != null && !nullToEmpty(r.getPostIt()).contains(postIt)
|
|
&& !nullToEmpty(r.getPostAdd()).contains(postIt)) return false;
|
|
if (agreementName != null && !nullToEmpty(r.getAgreementName()).contains(agreementName)) return false;
|
|
if (customerSsid != null && !nullToEmpty(r.getIdentifyNumber()).contains(customerSsid)) return false;
|
|
if (customerEmail != null && !nullToEmpty(r.getEmail()).contains(customerEmail)) return false;
|
|
if (productName != null && !nullToEmpty(r.getProductName()).contains(productName)) return false;
|
|
if (contractNumber != null && !nullToEmpty(r.getContractNumber()).contains(contractNumber)) return false;
|
|
if (q != null) {
|
|
String hay = (nullToEmpty(r.getCustomerName()) + " " + nullToEmpty(r.getPhone()) + " "
|
|
+ nullToEmpty(r.getProductName()) + " " + nullToEmpty(r.getOrderNumber()) + " "
|
|
+ nullToEmpty(r.getCounselor()) + " " + nullToEmpty(r.getBranch()) + " "
|
|
+ nullToEmpty(r.getMemo()) + " " + nullToEmpty(r.getPostIt()) + " "
|
|
+ nullToEmpty(r.getIdentifyNumber())).toLowerCase();
|
|
if (!hay.contains(q.toLowerCase())) return false;
|
|
}
|
|
return true;
|
|
}).collect(Collectors.toCollection(ArrayList::new));
|
|
|
|
if ("opended".equals(sorting) || "opened".equals(sorting)) {
|
|
result.sort(Comparator
|
|
.comparing(HomesReception::getOpenDate, Comparator.nullsLast(Comparator.naturalOrder()))
|
|
.reversed());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private void apply(HomesReception r, Map<String, Object> d) {
|
|
if (d.containsKey("orderDate")) r.setOrderDate(parseDateTime(str(d.get("orderDate"))));
|
|
if (d.containsKey("counselor")) r.setCounselor(str(d.get("counselor")));
|
|
if (d.containsKey("branch")) r.setBranch(str(d.get("branch")));
|
|
if (d.containsKey("branchGroup")) r.setBranchGroup(str(d.get("branchGroup")));
|
|
if (d.containsKey("carrier")) r.setCarrier(str(d.get("carrier")));
|
|
if (d.containsKey("giftCategory")) r.setGiftCategory(str(d.get("giftCategory")));
|
|
if (d.containsKey("productCategory")) r.setProductCategory(str(d.get("productCategory")));
|
|
if (d.containsKey("productName")) r.setProductName(str(d.get("productName")));
|
|
if (d.containsKey("customerName")) r.setCustomerName(str(d.get("customerName")));
|
|
if (d.containsKey("phone")) r.setPhone(str(d.get("phone")));
|
|
if (d.containsKey("region")) r.setRegion(str(d.get("region")));
|
|
if (d.containsKey("progressStatus")) r.setProgressStatus(ReceptionStatuses.normalizeProgress(str(d.get("progressStatus"))));
|
|
if (d.containsKey("orderNumber")) r.setOrderNumber(str(d.get("orderNumber")));
|
|
if (d.containsKey("ispId")) r.setIspId(toLong(d.get("ispId")));
|
|
if (d.containsKey("ispName")) r.setIspName(str(d.get("ispName")));
|
|
if (d.containsKey("inboundInfo")) r.setInboundInfo(str(d.get("inboundInfo")));
|
|
if (d.containsKey("processor")) r.setProcessor(str(d.get("processor")));
|
|
if (d.containsKey("detailProgress")) r.setDetailProgress(str(d.get("detailProgress")));
|
|
if (d.containsKey("paymentType")) r.setPaymentType(str(d.get("paymentType")));
|
|
if (d.containsKey("amount")) r.setAmount(toDecimal(d.get("amount")));
|
|
if (d.containsKey("settleStatus")) r.setSettleStatus(ReceptionStatuses.normalizeCenter(str(d.get("settleStatus"))));
|
|
if (d.containsKey("openDate")) r.setOpenDate(parseDate(str(d.get("openDate"))));
|
|
if (d.containsKey("giftDate")) r.setGiftDate(parseDate(str(d.get("giftDate"))));
|
|
if (d.containsKey("giftStatus")) {
|
|
String g = ReceptionStatuses.normalizeGift(str(d.get("giftStatus")));
|
|
r.setGiftStatus(blank(g) ? null : g);
|
|
} if (d.containsKey("giftPlace")) r.setGiftPlace(str(d.get("giftPlace")));
|
|
if (d.containsKey("agreementName")) r.setAgreementName(str(d.get("agreementName")));
|
|
if (d.containsKey("contractNumber")) r.setContractNumber(str(d.get("contractNumber")));
|
|
if (d.containsKey("identifyNumber")) r.setIdentifyNumber(str(d.get("identifyNumber")));
|
|
if (d.containsKey("postIt")) r.setPostIt(str(d.get("postIt")));
|
|
if (d.containsKey("postAdd")) r.setPostAdd(str(d.get("postAdd")));
|
|
if (d.containsKey("memo")) r.setMemo(str(d.get("memo")));
|
|
if (d.containsKey("adminMemo")) r.setAdminMemo(str(d.get("adminMemo")));
|
|
if (d.containsKey("customerType")) r.setCustomerType(str(d.get("customerType")));
|
|
if (d.containsKey("tel")) r.setTel(str(d.get("tel")));
|
|
if (d.containsKey("email")) r.setEmail(str(d.get("email")));
|
|
if (d.containsKey("zipcode")) r.setZipcode(str(d.get("zipcode")));
|
|
if (d.containsKey("address")) r.setAddress(str(d.get("address")));
|
|
if (d.containsKey("addressDetail")) r.setAddressDetail(str(d.get("addressDetail")));
|
|
if (d.containsKey("paymentMethod")) r.setPaymentMethod(str(d.get("paymentMethod")));
|
|
if (d.containsKey("productType")) r.setProductType(str(d.get("productType")));
|
|
if (d.containsKey("installSchedule")) r.setInstallSchedule(str(d.get("installSchedule")));
|
|
if (d.containsKey("customerLoginId")) r.setCustomerLoginId(str(d.get("customerLoginId")));
|
|
if (d.containsKey("newTel")) r.setNewTel(str(d.get("newTel")));
|
|
if (d.containsKey("cancelDate")) r.setCancelDate(parseDate(str(d.get("cancelDate"))));
|
|
if (d.containsKey("branchPhone")) r.setBranchPhone(str(d.get("branchPhone")));
|
|
}
|
|
|
|
private Map<String, Object> toProgressDetail(HomesReception r, JwtUser u) {
|
|
Map<String, Object> data = new LinkedHashMap<>();
|
|
Map<String, Object> reception = toMap(r);
|
|
data.put("reception", reception);
|
|
data.put("order", reception); // billing_react 호환 별칭
|
|
data.put("id", r.getId());
|
|
|
|
Map<String, Object> customer = new LinkedHashMap<>();
|
|
customer.put("type", blank(r.getCustomerType()) ? "public" : r.getCustomerType());
|
|
customer.put("name", r.getCustomerName());
|
|
customer.put("postIt", r.getPostIt());
|
|
customer.put("postAdd", r.getPostAdd());
|
|
customer.put("phone", r.getPhone());
|
|
customer.put("tel", r.getTel());
|
|
customer.put("email", r.getEmail());
|
|
customer.put("zipcode", r.getZipcode());
|
|
customer.put("address", r.getAddress());
|
|
customer.put("addressDetail", r.getAddressDetail());
|
|
customer.put("sido", r.getRegion());
|
|
customer.put("ssid", r.getIdentifyNumber());
|
|
data.put("customer", customer);
|
|
data.put("customerPublic", Map.of("ssid", nullToEmpty(r.getIdentifyNumber())));
|
|
|
|
Map<String, Object> payment = new LinkedHashMap<>();
|
|
payment.put("method", blank(r.getPaymentMethod()) ? paymentMethodFromType(r.getPaymentType()) : r.getPaymentMethod());
|
|
payment.put("name", r.getPaymentName());
|
|
payment.put("ssid", r.getPaymentSsid());
|
|
payment.put("tel", r.getPaymentTel());
|
|
payment.put("bank", r.getPaymentBank());
|
|
payment.put("accountNumber", r.getPaymentAccountNumber());
|
|
payment.put("cardCompany", r.getPaymentCardCompany());
|
|
payment.put("cardYear", r.getPaymentCardYear());
|
|
payment.put("cardMonth", r.getPaymentCardMonth());
|
|
payment.put("cardNumber", r.getPaymentCardNumber());
|
|
data.put("payment", payment);
|
|
if ("card".equals(payment.get("method"))) data.put("paymentCard", payment);
|
|
else if ("transfer".equals(payment.get("method"))) data.put("paymentTransfer", payment);
|
|
|
|
Map<String, Object> product = new LinkedHashMap<>();
|
|
product.put("productType", blank(r.getProductType()) ? productTypeFromCategory(r.getProductCategory()) : r.getProductType());
|
|
product.put("name", r.getProductName());
|
|
product.put("productName", r.getProductName());
|
|
product.put("price", r.getAmount() == null ? 0 : r.getAmount());
|
|
data.put("product", product);
|
|
data.put("productName", r.getProductName());
|
|
data.put("agreementName", r.getAgreementName());
|
|
data.put("ispName", blank(r.getIspName()) ? r.getCarrier() : r.getIspName());
|
|
data.put("eventNames", List.of());
|
|
|
|
Map<String, Object> gift = new LinkedHashMap<>();
|
|
gift.put("status", r.getGiftStatus());
|
|
gift.put("place", r.getGiftPlace());
|
|
gift.put("giftDate", r.getGiftDate() == null ? null : r.getGiftDate().toString());
|
|
gift.put("requested", r.getGiftRequested() == null ? null : r.getGiftRequested().toString());
|
|
gift.put("sended", r.getGiftSended() == null ? null : r.getGiftSended().toString());
|
|
gift.put("accountBank", r.getGiftBank());
|
|
gift.put("accountNumber", r.getGiftAccountNumber());
|
|
gift.put("accountName", r.getGiftAccountName());
|
|
gift.put("ssid", r.getGiftSsid());
|
|
gift.put("goods", r.getGiftGoods());
|
|
gift.put("cashAmount", r.getGiftCashAmount());
|
|
gift.put("goodsPrice", r.getGiftGoodsPrice());
|
|
gift.put("category", r.getGiftCategory());
|
|
data.put("gift", gift);
|
|
|
|
Map<String, Object> etc = new LinkedHashMap<>();
|
|
etc.put("memo", r.getMemo());
|
|
etc.put("adminMemo", r.getAdminMemo());
|
|
etc.put("file1", r.getFile1());
|
|
etc.put("file2", r.getFile2());
|
|
etc.put("file3", r.getFile3());
|
|
etc.put("file4", r.getFile4());
|
|
etc.put("file5", r.getFile5());
|
|
etc.put("adminFile1", r.getAdminFile1());
|
|
etc.put("adminFile2", r.getAdminFile2());
|
|
etc.put("adminFile3", r.getAdminFile3());
|
|
data.put("etc", etc);
|
|
|
|
data.put("employeeName", r.getCounselor());
|
|
data.put("branchOfficeName", blank(r.getBranch()) ? "본지점" : r.getBranch());
|
|
data.put("branchPhone", blank(r.getBranchPhone()) ? "" : r.getBranchPhone());
|
|
data.put("branchTel", "");
|
|
data.put("progressLogs", progressLogs(r.getId(), u.getGroupId()));
|
|
data.put("giftProgressLogs", giftProgressLogs(r.getId(), u.getGroupId()));
|
|
data.put("logs", data.get("progressLogs"));
|
|
data.put("progressStatuses", PROGRESS_STATUSES);
|
|
data.put("giftStatuses", GIFT_STATUSES);
|
|
data.put("settleStatuses", SETTLE_STATUSES);
|
|
data.put("progressStatusLabels", ReceptionStatuses.PROGRESS);
|
|
data.put("giftStatusLabels", ReceptionStatuses.GIFT);
|
|
data.put("settleStatusLabels", ReceptionStatuses.CENTER);
|
|
data.put("statusOptions", new LinkedHashMap<>(ReceptionStatuses.PROGRESS));
|
|
data.put("giftStatusOptions", new LinkedHashMap<>(ReceptionStatuses.GIFT));
|
|
data.put("centerStatusOptions", new LinkedHashMap<>(ReceptionStatuses.CENTER));
|
|
data.put("allowedProgressStatuses", new ArrayList<>(
|
|
ReceptionStatuses.orderStatusTransitions(ReceptionStatuses.normalizeProgress(r.getProgressStatus()))));
|
|
// flat alias for list edit form compatibility
|
|
data.putAll(reception);
|
|
return data;
|
|
}
|
|
|
|
private static String paymentMethodFromType(String paymentType) {
|
|
if ("카드".equals(paymentType)) return "card";
|
|
if ("지로".equals(paymentType)) return "paper";
|
|
if ("전화납부".equals(paymentType)) return "telephone";
|
|
return "transfer";
|
|
}
|
|
|
|
private static String productTypeFromCategory(String cat) {
|
|
if ("전화".equals(cat)) return "e02";
|
|
if ("TV".equals(cat)) return "e03";
|
|
if ("렌탈".equals(cat)) return "e04";
|
|
return "e01";
|
|
}
|
|
|
|
private Map<String, Object> toMap(HomesReception r) {
|
|
Map<String, Object> m = new LinkedHashMap<>();
|
|
m.put("id", r.getId());
|
|
m.put("orderDate", fmtDt(r.getOrderDate()));
|
|
m.put("today", r.getOrderDate() != null
|
|
&& r.getOrderDate().toLocalDate().equals(LocalDate.now(ZoneId.of("Asia/Seoul"))));
|
|
m.put("counselor", r.getCounselor());
|
|
m.put("branch", r.getBranch());
|
|
m.put("branchGroup", r.getBranchGroup());
|
|
m.put("branchPhone", r.getBranchPhone());
|
|
m.put("carrier", r.getCarrier());
|
|
m.put("giftCategory", r.getGiftCategory());
|
|
m.put("productCategory", r.getProductCategory());
|
|
m.put("productType", r.getProductType());
|
|
m.put("productName", r.getProductName());
|
|
m.put("customerType", r.getCustomerType());
|
|
m.put("customerName", r.getCustomerName());
|
|
m.put("phone", r.getPhone());
|
|
m.put("tel", r.getTel());
|
|
m.put("email", r.getEmail());
|
|
m.put("zipcode", r.getZipcode());
|
|
m.put("address", r.getAddress());
|
|
m.put("addressDetail", r.getAddressDetail());
|
|
m.put("region", r.getRegion());
|
|
m.put("progressStatus", r.getProgressStatus());
|
|
m.put("progressStatusLabel", ReceptionStatuses.progressLabel(ReceptionStatuses.normalizeProgress(r.getProgressStatus())));
|
|
m.put("status", ReceptionStatuses.progressLabel(ReceptionStatuses.normalizeProgress(r.getProgressStatus())));
|
|
m.put("orderNumber", r.getOrderNumber());
|
|
m.put("ispId", r.getIspId());
|
|
m.put("ispName", r.getIspName());
|
|
m.put("inboundInfo", r.getInboundInfo());
|
|
m.put("processor", r.getProcessor());
|
|
m.put("detailProgress", r.getDetailProgress());
|
|
m.put("paymentType", r.getPaymentType());
|
|
m.put("paymentMethod", r.getPaymentMethod());
|
|
m.put("amount", r.getAmount());
|
|
m.put("settleStatus", r.getSettleStatus());
|
|
m.put("openDate", r.getOpenDate() == null ? null : r.getOpenDate().toString());
|
|
m.put("cancelDate", r.getCancelDate() == null ? null : r.getCancelDate().toString());
|
|
m.put("giftDate", r.getGiftDate() == null ? null : r.getGiftDate().toString());
|
|
m.put("giftStatus", r.getGiftStatus());
|
|
m.put("giftPlace", r.getGiftPlace());
|
|
m.put("giftRequested", r.getGiftRequested() == null ? null : r.getGiftRequested().toString());
|
|
m.put("giftSended", r.getGiftSended() == null ? null : r.getGiftSended().toString());
|
|
m.put("agreementName", r.getAgreementName());
|
|
m.put("contractNumber", r.getContractNumber());
|
|
m.put("installSchedule", r.getInstallSchedule());
|
|
m.put("customerLoginId", r.getCustomerLoginId());
|
|
m.put("newTel", r.getNewTel());
|
|
m.put("multiLine", Boolean.TRUE.equals(r.getMultiLine()));
|
|
m.put("addPayer", Boolean.TRUE.equals(r.getAddPayer()));
|
|
m.put("record", Boolean.TRUE.equals(r.getRecordFlag()));
|
|
m.put("identifyNumber", r.getIdentifyNumber());
|
|
m.put("postIt", r.getPostIt());
|
|
m.put("postAdd", r.getPostAdd());
|
|
m.put("memo", r.getMemo());
|
|
m.put("adminMemo", r.getAdminMemo());
|
|
// billing_react OrderListRow 호환 별칭
|
|
m.put("employeeName", r.getCounselor());
|
|
m.put("sido", r.getRegion());
|
|
m.put("opened", r.getOpenDate() == null ? null : r.getOpenDate().toString());
|
|
m.put("canceled", r.getCancelDate() == null ? null : r.getCancelDate().toString());
|
|
m.put("giftType", r.getGiftCategory());
|
|
m.put("giftStatusLabel", ReceptionStatuses.giftLabel(ReceptionStatuses.normalizeGift(r.getGiftStatus())));
|
|
m.put("settleStatusLabel", ReceptionStatuses.centerLabel(ReceptionStatuses.normalizeCenter(r.getSettleStatus())));
|
|
m.put("centerStatus", r.getSettleStatus());
|
|
m.put("centerStatusLabel", ReceptionStatuses.centerLabel(ReceptionStatuses.normalizeCenter(r.getSettleStatus())));
|
|
m.put("giftSended", r.getGiftSended() == null
|
|
? (r.getGiftDate() == null ? null : r.getGiftDate().toString())
|
|
: r.getGiftSended().toString());
|
|
m.put("branchOfficeName", r.getBranch());
|
|
m.put("branchGroupName", r.getBranchGroup());
|
|
if (blank(r.getIspName())) m.put("ispName", r.getCarrier());
|
|
BigDecimal giftAmt = BigDecimal.ZERO;
|
|
if (r.getGiftCashAmount() != null) giftAmt = giftAmt.add(r.getGiftCashAmount());
|
|
if (r.getGiftGoodsPrice() != null) giftAmt = giftAmt.add(r.getGiftGoodsPrice());
|
|
if (giftAmt.signum() == 0 && r.getAmount() != null
|
|
&& r.getGiftStatus() != null && !r.getGiftStatus().isBlank()
|
|
&& !"미지급".equals(r.getGiftStatus()) && !"없음".equals(r.getGiftCategory())) {
|
|
giftAmt = r.getAmount();
|
|
}
|
|
m.put("giftAmount", giftAmt.signum() == 0 ? null : giftAmt);
|
|
m.put("centerName", blank(r.getProcessor()) ? "본사" : r.getProcessor());
|
|
m.put("centerStatus", r.getSettleStatus());
|
|
return m;
|
|
}
|
|
|
|
private List<Map<String, Object>> progressLogs(Long receptionId, String groupId) {
|
|
return em.createQuery(
|
|
"select l from HomesReceptionProgressLog l where l.groupId=:g and l.receptionId=:rid order by l.loggedAt desc, l.id desc",
|
|
HomesReceptionProgressLog.class)
|
|
.setParameter("g", groupId).setParameter("rid", receptionId)
|
|
.getResultList().stream().map(l -> {
|
|
Map<String, Object> m = new LinkedHashMap<>();
|
|
m.put("id", l.getId());
|
|
m.put("status", l.getStatus());
|
|
m.put("memo", l.getMemo());
|
|
m.put("authorName", l.getAuthorName());
|
|
m.put("writer", l.getAuthorName());
|
|
m.put("loggedAt", fmtDt(l.getLoggedAt()));
|
|
m.put("createdAt", fmtDt(l.getLoggedAt()));
|
|
m.put("adminOnly", Boolean.TRUE.equals(l.getAdminOnly()));
|
|
return m;
|
|
}).toList();
|
|
}
|
|
|
|
private List<Map<String, Object>> giftProgressLogs(Long receptionId, String groupId) {
|
|
return em.createQuery(
|
|
"select l from HomesReceptionGiftProgressLog l where l.groupId=:g and l.receptionId=:rid order by l.loggedAt desc, l.id desc",
|
|
HomesReceptionGiftProgressLog.class)
|
|
.setParameter("g", groupId).setParameter("rid", receptionId)
|
|
.getResultList().stream().map(l -> {
|
|
Map<String, Object> m = new LinkedHashMap<>();
|
|
m.put("id", l.getId());
|
|
m.put("status", l.getStatus());
|
|
m.put("memo", l.getMemo());
|
|
m.put("authorName", l.getAuthorName());
|
|
m.put("writer", l.getAuthorName());
|
|
m.put("loggedAt", fmtDt(l.getLoggedAt()));
|
|
m.put("createdAt", fmtDt(l.getLoggedAt()));
|
|
return m;
|
|
}).toList();
|
|
}
|
|
|
|
private void appendLog(HomesReception r, String status, String memo, JwtUser u) {
|
|
appendLog(r, status, memo, u, false);
|
|
}
|
|
|
|
private void appendLog(HomesReception r, String status, String memo, JwtUser u, boolean adminOnly) {
|
|
HomesReceptionProgressLog log = new HomesReceptionProgressLog();
|
|
log.setGroupId(u.getGroupId());
|
|
log.setReceptionId(r.getId());
|
|
log.setStatus(status);
|
|
log.setMemo(memo);
|
|
log.setAuthorName(resolveMemberName(u));
|
|
log.setLoggedAt(LocalDateTime.now(ZoneId.of("Asia/Seoul")));
|
|
log.setAdminOnly(adminOnly);
|
|
em.persist(log);
|
|
}
|
|
|
|
private void appendGiftLog(HomesReception r, String status, String memo, JwtUser u) {
|
|
HomesReceptionGiftProgressLog log = new HomesReceptionGiftProgressLog();
|
|
log.setGroupId(u.getGroupId());
|
|
log.setReceptionId(r.getId());
|
|
log.setStatus(status);
|
|
log.setMemo(memo);
|
|
log.setAuthorName(resolveMemberName(u));
|
|
log.setLoggedAt(LocalDateTime.now(ZoneId.of("Asia/Seoul")));
|
|
em.persist(log);
|
|
}
|
|
|
|
private HomesReception findOwned(Long id, JwtUser u) {
|
|
HomesReception r = em.find(HomesReception.class, id);
|
|
if (r == null || !Objects.equals(r.getGroupId(), u.getGroupId())) return null;
|
|
return r;
|
|
}
|
|
|
|
private void writeLog(JwtUser u, String domain, String action, String content) {
|
|
HomesLog log = new HomesLog();
|
|
log.setGroupId(u.getGroupId());
|
|
log.setDomain(domain);
|
|
log.setAction(action);
|
|
log.setContent(content);
|
|
String staff = resolveMemberName(u);
|
|
log.setStaff(staff == null || staff.isBlank() ? u.getUserid() : staff);
|
|
log.setProcessedAt(LocalDateTime.now());
|
|
em.persist(log);
|
|
}
|
|
|
|
private String resolveMemberName(JwtUser u) {
|
|
List<Member> rows = em.createQuery("select m from Member m where m.groupId=:g and m.userid=:uid", Member.class)
|
|
.setParameter("g", u.getGroupId()).setParameter("uid", u.getUserid()).setMaxResults(1).getResultList();
|
|
return rows.isEmpty() ? u.getUserid() : rows.getFirst().getName();
|
|
}
|
|
|
|
private static List<String> distinct(List<HomesReception> list,
|
|
java.util.function.Function<HomesReception, String> getter,
|
|
List<String> fallback) {
|
|
List<String> values = list.stream().map(getter).filter(s -> s != null && !s.isBlank())
|
|
.distinct().sorted().collect(Collectors.toCollection(ArrayList::new));
|
|
if (values.isEmpty() && fallback != null) return fallback;
|
|
return values;
|
|
}
|
|
|
|
private static String genOrderNumber() {
|
|
return "RCP-" + LocalDateTime.now(ZoneId.of("Asia/Seoul"))
|
|
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))
|
|
+ "-" + (1000 + new Random().nextInt(9000));
|
|
}
|
|
|
|
private static List<Long> toIds(Object raw) {
|
|
if (!(raw instanceof List<?> list)) return List.of();
|
|
List<Long> ids = new ArrayList<>();
|
|
for (Object o : list) {
|
|
if (o == null) continue;
|
|
try { ids.add(Long.valueOf(String.valueOf(o))); } catch (Exception ignored) { }
|
|
}
|
|
return ids;
|
|
}
|
|
|
|
private static BigDecimal toDecimal(Object v) {
|
|
if (v == null || String.valueOf(v).isBlank()) return null;
|
|
try { return new BigDecimal(String.valueOf(v).replace(",", "")); }
|
|
catch (Exception e) { return null; }
|
|
}
|
|
|
|
private static LocalDate parseDate(String s) {
|
|
if (s == null || s.isBlank()) return null;
|
|
try { return LocalDate.parse(s.substring(0, Math.min(10, s.length()))); }
|
|
catch (Exception e) { return null; }
|
|
}
|
|
|
|
private static LocalDateTime parseDateTime(String s) {
|
|
if (s == null || s.isBlank()) return null;
|
|
try {
|
|
if (s.length() <= 10) return LocalDate.parse(s).atStartOfDay();
|
|
return LocalDateTime.parse(s.replace(' ', 'T').substring(0, Math.min(19, s.length())));
|
|
} catch (Exception e) {
|
|
LocalDate d = parseDate(s);
|
|
return d == null ? null : d.atStartOfDay();
|
|
}
|
|
}
|
|
|
|
private static String fmtDt(LocalDateTime dt) {
|
|
if (dt == null) return null;
|
|
return dt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
|
}
|
|
|
|
private static String first(Map<String, String> f, String... keys) {
|
|
for (String k : keys) {
|
|
String v = f.get(k);
|
|
if (v != null && !v.isBlank()) return v;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static String blankToNull(String s) {
|
|
return s == null || s.isBlank() ? null : s.trim();
|
|
}
|
|
|
|
private static boolean blank(String s) {
|
|
return s == null || s.isBlank();
|
|
}
|
|
|
|
private static String nullToEmpty(String s) {
|
|
return s == null ? "" : s;
|
|
}
|
|
|
|
private static String str(Object v) {
|
|
return v == null ? null : String.valueOf(v).trim();
|
|
}
|
|
|
|
private static String firstNonBlank(String... values) {
|
|
if (values == null) return null;
|
|
for (String v : values) {
|
|
if (v != null && !v.isBlank()) return v.trim();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static String csvCell(Object value) {
|
|
if (value == null) return "";
|
|
String s = String.valueOf(value).replace("\"", "\"\"");
|
|
if (s.contains(",") || s.contains("\"") || s.contains("\n")) return "\"" + s + "\"";
|
|
return s;
|
|
}
|
|
}
|