package com.bizcare.agent; import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor; import org.springframework.boot.CommandLineRunner; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.YearMonth; import java.time.ZoneId; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; @Component @RequiredArgsConstructor class DataInitializer implements CommandLineRunner { private final EntityManager em; private final PasswordEncoder encoder; @Override @Transactional public void run(String... args) { if (em.createQuery("select m from Member m where m.userid='demo'", Member.class).getResultList().isEmpty()) { seedAll(); } seedUsimLedgersIfEmpty(); seedStockHistoryIfEmpty(); seedIndocsEnrich(); seedReturnsEnrich(); seedBalancesIfEmpty(); seedOpenAdjustFields(); seedUnitCostsIfEmpty(); seedHomeSalesIfEmpty(); seedCareHomesIfEmpty(); seedHomeIndocsIfEmpty(); seedOpenExchangesIfEmpty(); seedOpenNameChangesIfEmpty(); seedOpenWithdrawalsIfEmpty(); seedOpenSettleHistoriesIfEmpty(); seedOpenDeleteHistoriesIfEmpty(); seedBbsNoticeBoardIfEmpty(); seedBbsPolicyBoardIfEmpty(); seedBbsPdsBoardIfEmpty(); seedBoardGroupsIfEmpty(); seedScansEnrich(); seedSettlementDocsIfEmpty(); seedOutcompanyAccountsIfEmpty(); seedAgentShopSettingIfEmpty(); seedOpenStatsDemo(); seedFareboxSamplesIfEmpty(); seedFareboxPaymentsIfEmpty(); seedSmsHistoryIfEmpty(); seedSmsAddressIfEmpty(); seedStaffMembersIfEmpty(); seedHomesMembersEnrich(); seedIncompaniesIfEmpty(); seedOutcompaniesEnrich(); seedDeliveriesIfEmpty(); seedPreferenceIfEmpty(); seedCsNoticesIfEmpty(); seedCsInquiriesIfEmpty(); seedInternalBoardIfEmpty(); seedScheduleSampleIfEmpty(); seedPostitsIfEmpty(); seedStockInfoSampleIfEmpty(); } private void seedStockInfoSampleIfEmpty() { Long exists = em.createQuery("select count(s) from Stock s where s.groupId='demo' and s.serial='0018987'", Long.class).getSingleResult(); if (exists != null && exists > 0) return; Company in = em.createQuery("select c from Company c where c.groupId='demo' and c.name like '%CJ헬로%'", Company.class) .setMaxResults(1).getResultList().stream().findFirst().orElse(null); if (in == null) { in = new Company(); in.setGroupId("demo"); in.setType("IN"); in.setName("CJ헬로(SKT)"); in.setManagerName("CJ담당"); in.setPhone("02-0000-0000"); in.setTelecom("SKT"); in.setActive(true); em.persist(in); em.flush(); } Company out = em.createQuery("select c from Company c where c.groupId='demo' and c.name='늘푸른통신'", Company.class) .setMaxResults(1).getResultList().stream().findFirst().orElse(null); if (out == null) { out = new Company(); out.setGroupId("demo"); out.setType("OUT"); out.setName("늘푸른통신"); out.setManagerName("박총괄"); out.setPhone("010-1111-1003"); out.setCategory("직영"); out.setActive(true); em.persist(out); em.flush(); } else if (out.getCategory() == null || out.getCategory().isBlank()) { out.setCategory("직영"); } LocalDate day = LocalDate.of(2026, 7, 9); Stock s = new Stock(); s.setGroupId("demo"); s.setGubun("태블릿"); s.setTelecom("SKT"); s.setTelcompany("LG헬로비전"); s.setSerial("0018987"); s.setBarcode("0018987"); s.setModel("SM-A175N"); s.setColor("블랙"); s.setCond("정상"); s.setPay("여신"); s.setState("OUT"); s.setInprice(new BigDecimal("319000")); s.setIncompanyId(in.getId()); s.setOutcompanyId(out.getId()); s.setOutCategory("직영"); s.setIndate(day); s.setOutdate(day); s.setProcessDate(day); s.setProcessor("김대표"); s.setUserid("demo"); s.setProcid("demo"); s.setUid("stk-0018987"); em.persist(s); em.flush(); StockHistory inHist = new StockHistory(); inHist.setGroupId("demo"); inHist.setStockId(s.getId()); inHist.setIncompanyId(in.getId()); inHist.setProcessDate(day); inHist.setGubun(s.getGubun()); inHist.setState("IN"); inHist.setStatusLabel("입고"); inHist.setSerial(s.getSerial()); inHist.setModel(s.getModel()); inHist.setColor(s.getColor()); inHist.setCond(s.getCond()); inHist.setProcessor("김대표"); inHist.setCompanyLabel(""); em.persist(inHist); StockHistory outHist = new StockHistory(); outHist.setGroupId("demo"); outHist.setStockId(s.getId()); outHist.setIncompanyId(in.getId()); outHist.setOutcompanyId(out.getId()); outHist.setProcessDate(day); outHist.setGubun(s.getGubun()); outHist.setState("OUT"); outHist.setStatusLabel("출고"); outHist.setSerial(s.getSerial()); outHist.setModel(s.getModel()); outHist.setColor(s.getColor()); outHist.setCond(s.getCond()); outHist.setProcessor("김대표"); outHist.setCompanyLabel("늘푸른통신 (직영)"); em.persist(outHist); } private void seedAll() { Company in = company("IN", "입고처A", "김입고", "02-1234-5678"); Company shop = company("SHOP", "늘붉은통신", "홍길동", "010-1234-5678"); shop.setBusinessName("늘붉은통신"); shop.setBankAccount("국민은행 000-000-0000000 홍길동"); company("DEALER", "데모 딜러", "박딜러", "010-2222-3333"); Company out = company("OUT", "출고처 샘플", "이출고", "010-4444-5555"); Company in2 = company("IN", "비즈케어 물류센터", "최물류", "02-5555-1004"); company("OUT", "D1", "김대리", "010-1111-1001"); company("OUT", "D2", "이대리", "010-1111-1002"); company("OUT", "늘푸른통신", "박총괄", "010-1111-1003"); company("OUT", "스마트모바일", "최영업", "010-1111-1004"); company("OUT", "블루폰", "정매니저", "010-1111-1005"); Member agent = new Member(); agent.setGroupId("demo"); agent.setUserid("demo"); agent.setPassword(encoder.encode("demo123")); agent.setName("데모 관리자"); agent.setPhone("010-9999-0000"); agent.setRole("AGENT"); agent.setActive(true); em.persist(agent); Member shopUser = new Member(); shopUser.setGroupId("demo"); shopUser.setUserid("demoshop"); shopUser.setPassword(encoder.encode("demoshop")); shopUser.setName("늘붉은통신"); shopUser.setPhone("010-1234-5678"); shopUser.setRole("SHOP"); shopUser.setCompanyId(shop.getId()); shopUser.setActive(true); shopUser.setLoginCount(0); shopUser.setPlainPassword("demoshop"); shopUser.setMenuFlags("{\"policy\":true,\"pds\":true,\"return\":true,\"indoc\":true,\"scan\":true,\"stock\":true,\"open\":true,\"settle\":true,\"farebox\":true}"); em.persist(shopUser); Stock phone = stock("휴대폰", "SKT", "SM-S931N_256G", "아이스블루", "5477154", "OUT", in.getId(), shop.getId(), "1155000"); Stock tablet = stock("태블릿", "KT", "SM-X910", "그레이", "TAB9001", "IN", in.getId(), null, "900000"); Stock usim = stock("유심", "SKT", "20044", "공통색상", "10867345", "OUT", in.getId(), shop.getId(), "7700"); String[] states = {"IN", "OUT", "RETURN", "LOSS", "OPEN", "SELL", "RECOVERY", "RECOVERY", "IN", "OUT", "RECOVERY", "RETURN", "IN", "SELL", "LOSS", "OUT", "RECOVERY"}; String[] models = {"갤럭시 S25", "아이폰 16 Pro", "갤럭시 A36", "아이폰 16", "갤럭시 Z Flip7", "20044", "갤럭시 S25+", "아이폰 15", "갤럭시 A56"}; String[] colors = {"티타늄 블루", "블랙", "화이트", "실버", "민트", "공통색상"}; String[] telecoms = {"SKT", "KT", "LGU+"}; for (int i = 0; i < states.length; i++) { String state = states[i]; Stock sample = stock(i % 6 == 5 ? "유심" : "휴대폰", telecoms[i % telecoms.length], models[i % models.length], colors[i % colors.length], String.format("SN%010d", 240001 + i), state, i % 2 == 0 ? in.getId() : in2.getId(), state.equals("IN") ? null : (i % 2 == 0 ? shop.getId() : out.getId()), String.valueOf(7700 + i * 85000)); sample.setPetname(new String[]{"S25특가", "아이폰프로", "보급형", "유심재고"}[i % 4]); sample.setOutCategory(i % 2 == 0 ? "판매점" : "도매"); sample.setSalesperson(new String[]{"김영업", "이영업", "박영업"}[i % 3]); sample.setSource(i % 2 == 0 ? "본사" : "온라인"); sample.setProcessDate(LocalDate.now().minusDays(i % 12)); sample.setProcessor(new String[]{"데모 관리자", "김대리", "이과장"}[i % 3]); sample.setCond(state.equals("RECOVERY") ? "고품" : "정상"); sample.setMemo(i % 4 == 0 ? "검수 완료" : (state.equals("RECOVERY") ? "회수대기" : null)); sample.setIndate(LocalDate.now().minusDays(i + 1)); if (state.equals("RECOVERY")) { sample.setOutcompanyId(shop.getId()); sample.setOutdate(LocalDate.now().minusDays(i + 3)); sample.setRecalldate(null); } } OpenRecord firstOpen = null; String[][] openSamples = { {"할부", "SKT", "보상", "김*철", "010-****-5678", "319000", "20000", "5000"}, {"현금", "KT", "신규", "이*수", "010-****-1234", "450000", "35000", "0"}, {"유심", "LGU+", "번호이동", "박*영", "010-****-9876", "0", "15000", "0"}, {"할부", "SKT", "기변", "최*민", "010-****-4321", "890000", "40000", "10000"}, {"현금", "KT", "메이징", "정*아", "010-****-2468", "120000", "8000", "0"}, {"할부", "SKT", "가개통", "한*진", "010-****-1357", "550000", "25000", "3000"}, {"유심", "LGU+", "선불개통", "오*희", "010-****-8642", "0", "5000", "0"}, {"현금", "SKT", "신규", "윤*호", "010-****-7531", "280000", "18000", "0"}, }; for (int i = 0; i < openSamples.length; i++) { String[] s = openSamples[i]; OpenRecord open = new OpenRecord(); open.setGroupId("demo"); open.setOutcompanyId(shop.getId()); open.setIncompanyId(in.getId()); open.setGubun(s[0]); open.setTelecom(s[1]); open.setOpenhow(s[2]); open.setName(s[3]); open.setOpenphone(s[4]); open.setOpendate(LocalDate.now().minusDays(i)); open.setOpenHour(10 + (i % 8)); open.setOpenMinute(i % 2 == 0 ? 0 : 30); open.setOpenStatus("정상"); open.setOutCategory("판매점"); open.setSalesperson(i % 2 == 0 ? "김영업" : "이영업"); open.setEmployee("demo"); open.setPlan(i % 2 == 0 ? "5GX 프라임" : "LTE 슬림"); open.setSalemon("할부".equals(s[0]) ? 24 : 0); open.setAgreemon(24); open.setSalehow(s[0]); open.setJoinhow("일반"); open.setSupportType(i % 3 == 0 ? "선택약정" : "일반"); open.setPmodel(i % 2 == 0 ? "SM-S928N" : "A2860"); open.setPserial("할부".equals(s[0]) || "현금".equals(s[0]) ? "IMEI" + (100000 + i) : null); open.setPcolor("블랙"); open.setUserial("유심".equals(s[0]) || i % 2 == 0 ? "USIM" + (200000 + i) : null); open.setInprice(new BigDecimal(s[5])); open.setNetprice(new BigDecimal(s[5])); open.setSellprice(new BigDecimal(s[5])); open.setDealermargin1(new BigDecimal(s[6])); open.setDeclprice1(new BigDecimal(s[7])); open.setCommonSupport(new BigDecimal(i % 2 == 0 ? "300000" : "150000")); open.setBasicprice1(new BigDecimal("100000")); open.setBasicprice2(new BigDecimal("50000")); open.setBasicprice3(new BigDecimal("30000")); open.setDecltype(i % 2 == 0 ? "단말할인" : "요금할인"); open.setState("OPEN"); open.setUserid("demo"); open.setUid("open-" + UUID.randomUUID()); if (i == 0) { open.setPhoneStockId(phone.getId()); open.setPserial(phone.getSerial()); open.setPmodel(phone.getModel()); open.setPcolor(phone.getColor()); } em.persist(open); if (i == 0) { firstOpen = open; phone.setOpenId(open.getId()); phone.setState("OPEN"); } } OpenRecord open = firstOpen; // shop/policy/pds boards are seeded in dedicated seedBbs* methods ScanDoc scan = new ScanDoc(); scan.setGroupId("demo"); scan.setOutcompanyId(shop.getId()); scan.setIncompanyId(in.getId()); scan.setOutcompanyName(shop.getName()); scan.setTelcompany("SKT"); scan.setGubun("보상기변"); scan.setName("홍길동/010-1234-5678"); scan.setFilesCount(1); scan.setMemo("123456"); scan.setSendmsg("미비"); scan.setState("완료"); scan.setSrc("2"); scan.setRegisteredAt(java.time.LocalDateTime.now().withHour(13).withMinute(32).withSecond(0).withNano(0)); em.persist(scan); IncompleteDoc indoc = new IncompleteDoc(); indoc.setGroupId("demo"); indoc.setOutcompanyId(shop.getId()); indoc.setIncompanyId(in.getId()); indoc.setOpenId(open.getId()); indoc.setOpendate(LocalDate.now()); indoc.setTelecom("SKT"); indoc.setCustomerName("김*철"); indoc.setOpenphone("010-****-5678"); indoc.setMissingDocs("신분증사본"); indoc.setDeductAmount(new BigDecimal("30000")); indoc.setDeductReason("서류미비"); indoc.setDeadline(LocalDate.now().plusDays(7)); indoc.setStatus("미비"); em.persist(indoc); IncompleteDoc indoc2 = new IncompleteDoc(); indoc2.setGroupId("demo"); indoc2.setOutcompanyId(shop.getId()); indoc2.setIncompanyId(in.getId()); indoc2.setOpendate(LocalDate.now().minusDays(3)); indoc2.setTelecom("KT"); indoc2.setCustomerName("이*수"); indoc2.setOpenphone("010-****-1234"); indoc2.setMissingDocs("인감증명서, 가족관계증명서"); indoc2.setDeductAmount(new BigDecimal("50000")); indoc2.setDeductReason("추가서류 미제출"); indoc2.setDeadline(LocalDate.now().plusDays(3)); indoc2.setStatus("미비"); em.persist(indoc2); IncompleteDoc indoc3 = new IncompleteDoc(); indoc3.setGroupId("demo"); indoc3.setOutcompanyId(out.getId()); indoc3.setIncompanyId(in2.getId()); indoc3.setOpendate(LocalDate.now().minusDays(10)); indoc3.setTelecom("LGU+"); indoc3.setCustomerName("박*영"); indoc3.setOpenphone("010-****-9876"); indoc3.setMissingDocs("위임장"); indoc3.setDeductAmount(new BigDecimal("20000")); indoc3.setDeductReason("대리개통 서류"); indoc3.setDeadline(LocalDate.now().minusDays(1)); indoc3.setStatus("마감임박"); em.persist(indoc3); UnreturnedPhone ret = new UnreturnedPhone(); ret.setGroupId("demo"); ret.setOutcompanyId(shop.getId()); ret.setIncompanyId(in.getId()); ret.setOpenId(open.getId()); ret.setOpendate(LocalDate.now().minusDays(10)); ret.setTelecom("SKT"); ret.setCustomerName("이*영"); ret.setOpenphone("010-****-1111"); ret.setModel("SM-A175N"); ret.setSerial("0018987"); ret.setDeductAmount(new BigDecimal("50000")); ret.setReturnStatus("미반납"); em.persist(ret); String[][] returnSamples = { {"KT", "박*지", "010-****-6595", "미반납", "A125", "50000", "0"}, {"SKT", "홍*동", "010-****-2222", "반납", "sm-g220", "1234", "10000"}, {"LGU+", "김*수", "010-****-3344", "미반납", "SM-S928N", "IMEI9001", "30000"}, {"SKT", "최*아", "010-****-7788", "반납", "A2860", "SN7788", ""}, {"KT", "정*호", "010-****-9900", "미반납", "SM-A546", "A5469900", "15000"}, }; for (int i = 0; i < returnSamples.length; i++) { String[] s = returnSamples[i]; UnreturnedPhone row = new UnreturnedPhone(); row.setGroupId("demo"); row.setOutcompanyId(i % 2 == 0 ? shop.getId() : out.getId()); row.setIncompanyId(i % 2 == 0 ? in.getId() : in2.getId()); row.setOpendate(LocalDate.now().minusDays(5 + i * 3)); row.setTelecom(s[0]); row.setCustomerName(s[1]); row.setOpenphone(s[2]); row.setReturnStatus(s[3]); row.setModel(s[4]); row.setSerial(s[5]); if (!s[6].isBlank()) row.setDeductAmount(new BigDecimal(s[6])); if ("반납".equals(s[3])) row.setReturndate(LocalDate.now().minusDays(i)); em.persist(row); } SettlementMonth settle = new SettlementMonth(); settle.setGroupId("demo"); settle.setOutcompanyId(shop.getId()); settle.setOutcompanyName(shop.getName()); settle.setYearMonth(LocalDate.now().toString().substring(0, 7)); settle.setOpenCount(0); settle.setOpenAmount(BigDecimal.ZERO); settle.setAfterSettleCount(1); settle.setAfterSettleAmount(new BigDecimal("-100000")); settle.setHomeProductCount(0); settle.setHomeProductAmount(BigDecimal.ZERO); settle.setRealSettleAmount(new BigDecimal("-100000")); settle.setOutCategory("판매점"); settle.setStatus("READY"); settle.setIssued(false); settle.setMemo(""); em.persist(settle); Farebox fare = new Farebox(); fare.setGroupId("demo"); fare.setOutcompanyId(shop.getId()); fare.setOutcompanyName(shop.getName()); fare.setOutCategory("판매점"); fare.setFaredate(LocalDate.now()); fare.setTelcompany("SKT"); fare.setName("홍*동"); fare.setPhone("010-****-5678"); fare.setHow("수납"); fare.setPaystate("완결"); fare.setCashprice(new BigDecimal("50000")); fare.setCardprice(BigDecimal.ZERO); fare.setDetail("요금수납"); fare.setRegistrant("김대표"); fare.setReceiptNo("R-001"); em.persist(fare); AccountEntry acc = new AccountEntry(); acc.setGroupId("demo"); acc.setOutcompanyId(shop.getId()); acc.setEntryDate(LocalDate.now()); acc.setType("IN"); acc.setCategory("정산입금"); acc.setAmount(new BigDecimal("110000")); acc.setMemo("월정산"); acc.setYearMonth(LocalDate.now().toString().substring(0, 7)); em.persist(acc); for (String telecom : new String[]{"SKT", "KT", "LGU+"}) { PlanMaster p = new PlanMaster(); p.setGroupId("demo"); p.setTelecom(telecom); p.setName(telecom + " 5G 베이직"); p.setPrice(new BigDecimal("55000")); p.setActive(true); em.persist(p); } PhoneModel model = new PhoneModel(); model.setGroupId("demo"); model.setTelecom("SKT"); model.setModelCode("SM-S931N"); model.setModelName("갤럭시 S25"); model.setColorOptions("블랙,실버,아이스블루"); model.setActive(true); em.persist(model); ScheduleItem schedule = new ScheduleItem(); schedule.setGroupId("demo"); schedule.setUserid("demo"); schedule.setSdate(LocalDate.now()); schedule.setStime("10:00"); schedule.setContents("월 정산 확인"); em.persist(schedule); Alim alim = new Alim(); alim.setGroupId("demo"); alim.setUserid("demo"); alim.setTitle("개통 서류 확인"); alim.setContent("미비 서류를 확인해 주세요."); alim.setConfirmed(false); em.persist(alim); SmsTemplate tpl = new SmsTemplate(); tpl.setGroupId("demo"); tpl.setTitle("개통안내"); tpl.setBody("안녕하세요. 개통이 완료되었습니다."); em.persist(tpl); CsInquiry cs = new CsInquiry(); cs.setGroupId("demo"); cs.setUserid("demo"); cs.setAuthorName("김대표"); cs.setTitle("정산 문의"); cs.setContent("이번달 실정산금 확인 부탁드립니다."); cs.setStatus("답변대기"); cs.setReplyCount(0); em.persist(cs); Setting setting = new Setting(); setting.setGroupId("demo"); setting.setSettingKey("company"); setting.setValue("{\"name\":\"에이전트 데모\",\"phone\":\"010-0000-0000\",\"managerName\":\"김대표\",\"businessName\":\"에이전트 데모\",\"businessNumber\":\"123-45-67890\",\"ceo\":\"김유신\",\"bizType\":\"도소매\",\"bizItem\":\"휴대폰판매\",\"address\":\"대구시 수성구 수성4가 먼길\"}"); em.persist(setting); tablet.getId(); usim.getId(); } private void seedUsimLedgersIfEmpty() { Map outs = new LinkedHashMap<>(); for (Company c : em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('OUT','SHOP')", Company.class).getResultList()) { outs.put(c.getName(), c.getId()); } for (String name : List.of("D1", "D2", "늘푸른통신", "스마트모바일", "블루폰")) { if (outs.containsKey(name)) continue; Company c = company("OUT", name, "담당자", "010-0000-0000"); em.flush(); outs.put(c.getName(), c.getId()); } if (outs.isEmpty()) return; Object[][] samples = { {LocalDate.of(2025, 7, 20), "D1", "SKT", 100, "770000", "YENZI", "김대표"}, {LocalDate.of(2025, 7, 18), "D2", "KT", 50, "385000", "", "정총괄"}, {LocalDate.of(2025, 7, 15), "늘푸른통신", "LGT", 20, "154000", "333", "김대표"}, {LocalDate.of(2025, 7, 10), "스마트모바일", "SKT", 5, "38500", "", "이과장"}, {LocalDate.of(2025, 6, 28), "블루폰", "KT", 8, "61600", "유심일괄", "정총괄"}, {LocalDate.of(2025, 6, 20), "늘붉은통신", "SK텔링크", 12, "92400", "", "김대표"}, {LocalDate.of(2025, 6, 12), "출고처 샘플", "SKT", 15, "115500", "프로모션", "데모 관리자"}, {LocalDate.of(2025, 5, 30), "늘푸른통신", "KT", 10, "77000", "", "정총괄"}, {LocalDate.of(2025, 5, 22), "D1", "LGT", 7, "53900", "YENZI", "이과장"}, {LocalDate.of(2025, 5, 10), "D2", "SKT", 25, "192500", "", "김대표"}, {LocalDate.of(2025, 4, 18), "스마트모바일", "KT", 3, "23100", "333", "정총괄"}, {LocalDate.of(2025, 4, 5), "블루폰", "LGT", 32, "246400", "", "김대표"}, }; for (Object[] s : samples) { LocalDate date = (LocalDate) s[0]; String outName = String.valueOf(s[1]); Long outId = outs.get(outName); if (outId == null) continue; Long exists = em.createQuery( "select count(e) from UsimLedger e where e.groupId='demo' and e.tradeDate=:d and e.outcompanyId=:o and e.qty=:q", Long.class) .setParameter("d", date).setParameter("o", outId).setParameter("q", (Integer) s[3]).getSingleResult(); if (exists != null && exists > 0) continue; UsimLedger row = new UsimLedger(); row.setGroupId("demo"); row.setOutcompanyId(outId); row.setTradeDate(date); row.setTelecom(String.valueOf(s[2])); row.setQty((Integer) s[3]); row.setAmount(new BigDecimal(String.valueOf(s[4]))); String detail = String.valueOf(s[5]); row.setDetail(detail.isBlank() ? null : detail); row.setRegistrant(String.valueOf(s[6])); row.setStatus("정상거래"); em.persist(row); } } private void seedStockHistoryIfEmpty() { Long count = em.createQuery("select count(e) from StockHistory e", Long.class).getSingleResult(); if (count != null && count > 0) return; List stocks = em.createQuery("select s from Stock s where s.groupId='demo'", Stock.class).getResultList(); for (Stock s : stocks) { StockHistory h = new StockHistory(); h.setGroupId("demo"); h.setStockId(s.getId()); h.setIncompanyId(s.getIncompanyId()); h.setOutcompanyId(s.getOutcompanyId()); h.setProcessDate(s.getProcessDate() != null ? s.getProcessDate() : (s.getIndate() != null ? s.getIndate() : LocalDate.now())); h.setGubun(s.getGubun()); h.setState(s.getState()); h.setStatusLabel(switch (s.getState() == null ? "" : s.getState()) { case "IN" -> "입고"; case "OUT" -> "출고"; case "RETURN" -> "반품"; case "LOSS" -> "분실"; case "OPEN" -> "개통"; case "SELL" -> "판매"; case "RECOVERY" -> "회수대기"; default -> s.getState(); }); h.setSerial(s.getSerial()); h.setModel(s.getModel()); h.setColor(s.getColor()); h.setCond(s.getCond()); h.setMemo(s.getMemo()); h.setProcessor(s.getProcessor() != null ? s.getProcessor() : "데모 관리자"); h.setSalesperson(s.getSalesperson()); em.persist(h); if (s.getIndate() != null && s.getProcessDate() != null && !s.getIndate().equals(s.getProcessDate())) { StockHistory in = new StockHistory(); in.setGroupId("demo"); in.setStockId(s.getId()); in.setIncompanyId(s.getIncompanyId()); in.setProcessDate(s.getIndate()); in.setGubun(s.getGubun()); in.setState("IN"); in.setStatusLabel("입고"); in.setSerial(s.getSerial()); in.setModel(s.getModel()); in.setColor(s.getColor()); in.setCond(s.getCond()); in.setProcessor("데모 관리자"); in.setSalesperson(s.getSalesperson()); em.persist(in); } } } private void seedOpenExchangesIfEmpty() { Long count = em.createQuery("select count(e) from OpenExchange e where e.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); if (shops.isEmpty()) return; Object[][] samples = { {"단말기", "홍*동", "010-****-5678", "SM-A235N", "블랙", "77777", "SM-A235N", "블랙", "88888", "김처리", "교품완료"}, {"단말기", "김*수", "010-****-1234", "SM-S911N", "크림", "11111", "SM-S908N", "그린", "22222", "이처리", null}, {"유심", "박*지", "010-****-9988", "USIM-KT", "-", "U9001", "USIM-KT", "-", "U8001", "demo", "유심교체"}, {"단말기", "이*호", "010-****-3344", "LM-G820N", "티탄", "33333", "LM-V500N", "화이트", "44444", "최처리", null}, {"단말기", "최*아", "010-****-5566", "SM-A546S", "라벤더", "55555", "SM-A536S", "어썸블랙", "66666", "김처리", "색상변경"}, {"유심", "정*민", "010-****-7788", "USIM-SKT", "-", "U7002", "USIM-SKT", "-", "U6002", "demo", null}, {"단말기", "윤*희", "010-****-1122", "IPHONE15", "블루", "A1001", "IPHONE14", "미드나잇", "A0901", "박처리", null}, {"단말기", "강*우", "010-****-4455", "SM-F946N", "그레이", "F1001", "SM-F936N", "그린", "F0901", "이처리", "폴드교품"}, {"단말기", "조*연", "010-****-6677", "SM-A256N", "라이트블루", "A2561", "SM-A245N", "블랙", "A2451", "demo", null}, {"유심", "한*석", "010-****-8899", "USIM-LGU", "-", "U5003", "USIM-LGU", "-", "U4003", "최처리", null}, {"단말기", "오*진", "010-****-2211", "SM-S921N", "그레이", "S9211", "SM-S918N", "크림", "S9181", "김처리", null}, {"단말기", "서*영", "010-****-3434", "LM-Q920N", "오로라", "Q9201", "LM-Q730N", "모로칸블루", "Q7301", "demo", "메모있음"}, {"단말기", "문*태", "010-****-5656", "SM-A156N", "라이트그레이", "A1561", "SM-A145N", "블랙", "A1451", "박처리", null}, {"유심", "배*리", "010-****-7878", "USIM-KT", "-", "U3004", "USIM-KT", "-", "U2004", "이처리", null}, {"단말기", "신*호", "010-****-9090", "SM-G991N", "팬텀그레이", "G9911", "SM-G990N", "화이트", "G9901", "demo", null}, {"단말기", "유*나", "010-****-1313", "IPHONE13", "핑크", "I1301", "IPHONE12", "퍼플", "I1201", "최처리", "고객요청"}, }; for (int i = 0; i < samples.length; i++) { Object[] s = samples[i]; Company shop = shops.get(i % shops.size()); OpenExchange e = new OpenExchange(); e.setGroupId("demo"); e.setOutcompanyId(shop.getId()); e.setOutcompanyName(shop.getName()); e.setKind(String.valueOf(s[0])); e.setCustomerName(String.valueOf(s[1])); e.setOpenphone(String.valueOf(s[2])); e.setNewModel(String.valueOf(s[3])); e.setNewColor(String.valueOf(s[4])); e.setNewSerial(String.valueOf(s[5])); e.setOldModel(String.valueOf(s[6])); e.setOldColor(String.valueOf(s[7])); e.setOldSerial(String.valueOf(s[8])); e.setProcessor(String.valueOf(s[9])); e.setMemo(s[10] == null ? null : String.valueOf(s[10])); e.setExchangeDate(LocalDate.now().minusDays(i)); e.setOpenDate(LocalDate.now().minusDays(i + 10)); e.setProcessedAt(java.time.LocalDateTime.now().minusDays(i).withHour(10 + (i % 8)).withMinute((i * 7) % 60).withSecond(0).withNano(0)); em.persist(e); } } private void seedOpenNameChangesIfEmpty() { Long count = em.createQuery("select count(e) from OpenNameChange e where e.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); if (shops.isEmpty()) return; Object[][] samples = { {"지*이", "010-****-1234", "김*수", "010-****-9999", "usim (0012345)", "김처리", "명의변경"}, {"박*지", "010-****-5678", "이*호", "010-****-1111", "-", "이처리", null}, {"최*아", "010-****-3344", "정*민", "010-****-2222", "usim (0098765)", "demo", null}, {"윤*희", "010-****-7788", "한*석", "010-****-3333", "-", "최처리", "가족명의"}, {"강*우", "010-****-5566", "오*진", "010-****-4444", "usim (0054321)", "박처리", null}, {"조*연", "010-****-9900", "서*영", "010-****-5555", "-", "demo", null}, {"문*태", "010-****-1122", "배*리", "010-****-6666", "usim (0077001)", "김처리", "법인전환"}, {"신*호", "010-****-4455", "유*나", "010-****-7777", "-", "이처리", null}, }; for (int i = 0; i < samples.length; i++) { Object[] s = samples[i]; Company shop = shops.get(i % shops.size()); OpenNameChange e = new OpenNameChange(); e.setGroupId("demo"); e.setOutcompanyId(shop.getId()); e.setOutcompanyName(shop.getName()); e.setCustomerName(String.valueOf(s[0])); e.setOpenphone(String.valueOf(s[1])); e.setOldOwner(String.valueOf(s[2])); e.setOldPhone(String.valueOf(s[3])); e.setOldUsim(String.valueOf(s[4])); e.setProcessor(String.valueOf(s[5])); e.setMemo(s[6] == null ? null : String.valueOf(s[6])); e.setChangeDate(LocalDate.now().minusDays(i * 3)); e.setOpenDate(LocalDate.now().minusDays(i * 3 + 20)); e.setProcessedAt(java.time.LocalDateTime.now().minusDays(i * 3).withHour(9 + (i % 8)).withMinute((i * 11) % 60).withSecond(0).withNano(0)); em.persist(e); } } private void seedOpenWithdrawalsIfEmpty() { Long count = em.createQuery("select count(e) from OpenWithdrawal e where e.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); if (shops.isEmpty()) return; String[] names = {"김*수", "이*호", "박*지", "최*아", "정*민", "윤*희", "강*우", "조*연", "한*석", "오*진"}; String[] reasons = {"고객요청", "개통오류", "서류미비", "요금미납", "중복개통", "본인취소", "정책철회", "-"}; String[] processors = {"김처리", "이처리", "demo", "최처리", "박처리"}; for (int i = 0; i < 30; i++) { Company shop = shops.get(i % shops.size()); OpenWithdrawal e = new OpenWithdrawal(); e.setGroupId("demo"); e.setOutcompanyId(shop.getId()); e.setOutcompanyName(shop.getName()); e.setCustomerName(names[i % names.length]); e.setOpenphone(String.format("010-****-%04d", 1000 + i * 17)); e.setProcessor(processors[i % processors.length]); e.setReason(reasons[i % reasons.length]); e.setWithdrawDate(LocalDate.now().minusDays(i)); e.setOpenDate(LocalDate.now().minusDays(i + 15)); e.setProcessedAt(java.time.LocalDateTime.now().minusDays(i).withHour(10 + (i % 8)).withMinute((i * 13) % 60).withSecond(0).withNano(0)); em.persist(e); } } private void seedOpenSettleHistoriesIfEmpty() { Long count = em.createQuery("select count(e) from OpenSettleHistory e where e.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); if (shops.isEmpty()) return; String[] names = {"박*수", "김*한", "이*호", "최*아", "정*민", "윤*희", "강*우", "조*연"}; String[] processors = {"김대표", "이개통", "demo", "최처리", "박처리"}; String[] memos = {"정책변경", "단가조정", "추가정산", "차감반영", "재계산", "오류수정"}; for (int i = 0; i < 40; i++) { Company shop = shops.get(i % shops.size()); long oldAmt = (i % 3 == 0 ? -1 : 1) * (50000L + (i * 17311L) % 300000); long newAmt = oldAmt + ((i % 2 == 0 ? 1 : -1) * (10000L + (i * 7919L) % 80000)); OpenSettleHistory e = new OpenSettleHistory(); e.setGroupId("demo"); e.setOutcompanyId(shop.getId()); e.setOutcompanyName(shop.getName()); e.setCustomerName(names[i % names.length]); e.setOpenphone(String.format("010-****-%04d", 2000 + i * 19)); e.setOldAmount(BigDecimal.valueOf(oldAmt)); e.setNewAmount(BigDecimal.valueOf(newAmt)); e.setProcessor(processors[i % processors.length]); e.setMemo(memos[i % memos.length]); e.setChangeDate(LocalDate.now().minusDays(i)); e.setOpenDate(LocalDate.now().minusDays(i + 12)); e.setProcessedAt(java.time.LocalDateTime.now().minusDays(i).withHour(9 + (i % 9)).withMinute((i * 17) % 60).withSecond(0).withNano(0)); em.persist(e); } } private void seedOpenDeleteHistoriesIfEmpty() { Long count = em.createQuery("select count(e) from OpenDeleteHistory e where e.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); if (shops.isEmpty()) return; Object[][] samples = { {"홍***님", "010-****-9870", "정총괄", "개통삭제(변심)"}, {"a****s", "010-****-1234", "김대표", "개통삭제(출고처수정)"}, {"홍*동", "010-****-5678", "이개통", "첨부파일삭제(파일명.gif)"}, {"김*수", "010-****-3344", "demo", "개통삭제(오류)"}, {"박*지", "010-****-7788", "최처리", "개통삭제(변심)"}, {"이*호", "010-****-5566", "정총괄", "첨부파일삭제(계약서.pdf)"}, {"최*아", "010-****-9900", "김대표", "개통삭제(출고처수정)"}, {"정*민", "010-****-1122", "이개통", "개통삭제(중복)"}, {"윤*희", "010-****-4455", "demo", "개통삭제(변심)"}, {"강*우", "010-****-6677", "박처리", "첨부파일삭제(신분증.jpg)"}, {"조*연", "010-****-8899", "정총괄", "개통삭제(요금미납)"}, {"한*석", "010-****-2211", "김대표", "개통삭제(변심)"}, {"오*진", "010-****-3434", "이개통", "개통삭제(출고처수정)"}, {"서*영", "010-****-5656", "demo", "첨부파일삭제(동의서.png)"}, {"문*태", "010-****-7878", "최처리", "개통삭제(오류)"}, {"배*리", "010-****-9090", "정총괄", "개통삭제(변심)"}, }; for (int i = 0; i < samples.length; i++) { Object[] s = samples[i]; Company shop = shops.get(i % shops.size()); OpenDeleteHistory e = new OpenDeleteHistory(); e.setGroupId("demo"); e.setOutcompanyId(shop.getId()); e.setOutcompanyName(shop.getName()); e.setCustomerName(String.valueOf(s[0])); e.setOpenphone(String.valueOf(s[1])); e.setProcessor(String.valueOf(s[2])); e.setMemo(String.valueOf(s[3])); e.setDeleteDate(LocalDate.now().minusDays(i)); e.setOpenDate(LocalDate.now().minusDays(i + 5)); e.setProcessedAt(java.time.LocalDateTime.now().minusDays(i).withHour(10 + (i % 8)).withMinute((i * 19) % 60).withSecond(0).withNano(0)); em.persist(e); } } private void seedBbsNoticeBoardIfEmpty() { List posts = em.createQuery("select b from BbsPost b where b.groupId='demo' and b.code='shop'", BbsPost.class).getResultList(); Object[][] samples = { {"124124", "2020-10-05"}, {"※ 동행보고 ※ 124123n124 5", "2020-02-17"}, {"테스트", "2019-04-09"}, }; for (Object[] s : samples) { String title = String.valueOf(s[0]); boolean exists = posts.stream().anyMatch(b -> title.equals(b.getTitle())); if (exists) continue; BbsPost b = new BbsPost(); b.setGroupId("demo"); b.setCode("shop"); b.setTitle(title); b.setContents("

" + title + "

"); b.setAuthorName("김대표"); b.setUserid("demo"); b.setTargetGroup("전체"); b.setConfirmCount(2); b.setNotice(false); b.setViews(0); b.setState("1"); em.persist(b); } for (BbsPost b : em.createQuery("select b from BbsPost b where b.groupId='demo' and b.code='shop'", BbsPost.class).getResultList()) { if (b.getTargetGroup() == null || b.getTargetGroup().isBlank()) b.setTargetGroup("전체"); if (b.getConfirmCount() == null) b.setConfirmCount(2); if (b.getAuthorName() == null || b.getAuthorName().isBlank()) b.setAuthorName("김대표"); } } private void seedBbsPolicyBoardIfEmpty() { List posts = em.createQuery("select b from BbsPost b where b.groupId='demo' and b.code='policy'", BbsPost.class).getResultList(); Object[][] samples = { {"31일 1차 단가표", "전체", "김대표", 1}, {"24124", "전체", "김대표", 3}, {"124124", "KT", "정총괄", 1}, }; for (Object[] s : samples) { String title = String.valueOf(s[0]); boolean exists = posts.stream().anyMatch(b -> title.equals(b.getTitle())); if (exists) continue; BbsPost b = new BbsPost(); b.setGroupId("demo"); b.setCode("policy"); b.setTitle(title); b.setContents("

" + title + "

"); b.setAuthorName(String.valueOf(s[2])); b.setUserid("demo"); b.setTargetGroup(String.valueOf(s[1])); b.setConfirmCount(((Number) s[3]).intValue()); b.setNotice(false); b.setViews(0); b.setState("1"); em.persist(b); } for (BbsPost b : em.createQuery("select b from BbsPost b where b.groupId='demo' and b.code='policy'", BbsPost.class).getResultList()) { if (b.getTargetGroup() == null || b.getTargetGroup().isBlank()) b.setTargetGroup("전체"); if (b.getConfirmCount() == null) b.setConfirmCount(1); if (b.getAuthorName() == null || b.getAuthorName().isBlank()) b.setAuthorName("김대표"); } } private void seedBbsPdsBoardIfEmpty() { List posts = em.createQuery("select b from BbsPost b where b.groupId='demo' and b.code='pds'", BbsPost.class).getResultList(); Object[][] samples = { {"24124124", "전체", "김대표", 2}, {"123", "전체", "김대표", 2}, }; for (Object[] s : samples) { String title = String.valueOf(s[0]); boolean exists = posts.stream().anyMatch(b -> title.equals(b.getTitle())); if (exists) continue; BbsPost b = new BbsPost(); b.setGroupId("demo"); b.setCode("pds"); b.setTitle(title); b.setContents("

" + title + "

"); b.setAuthorName(String.valueOf(s[2])); b.setUserid("demo"); b.setTargetGroup(String.valueOf(s[1])); b.setConfirmCount(((Number) s[3]).intValue()); b.setNotice(false); b.setViews(0); b.setState("1"); em.persist(b); } for (BbsPost b : em.createQuery("select b from BbsPost b where b.groupId='demo' and b.code='pds'", BbsPost.class).getResultList()) { if (b.getTargetGroup() == null || b.getTargetGroup().isBlank()) b.setTargetGroup("전체"); if (b.getConfirmCount() == null) b.setConfirmCount(2); if (b.getAuthorName() == null || b.getAuthorName().isBlank()) b.setAuthorName("김대표"); } } private void seedBoardGroupsIfEmpty() { Long count = em.createQuery("select count(g) from BoardGroup g where g.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); String shopIds = shops.stream().map(c -> String.valueOf(c.getId())).collect(java.util.stream.Collectors.joining(",")); Object[][] samples = { {"기본통신사", "LG헬로비전", shopIds}, {"기본통신사", "KT", shopIds}, {"기본통신사", "SKT", shopIds}, {"기본통신사", "LGU+", shopIds.isEmpty() ? "" : shops.getFirst().getId().toString()}, {"기본통신사", "SK브로드밴드", ""}, {"사용자그룹", "A그룹", shops.size() < 2 ? shopIds : shops.stream().limit(2).map(c -> String.valueOf(c.getId())).collect(java.util.stream.Collectors.joining(","))}, {"사용자그룹", "테스트", ""}, {"사용자그룹", "LG유모비", ""}, {"사용자그룹", "B그룹", shops.size() > 1 ? shops.get(1).getId().toString() : ""}, {"사용자그룹", "VIP", ""}, {"사용자그룹", "도매전용", shops.isEmpty() ? "" : shops.getFirst().getId().toString()}, }; for (Object[] s : samples) { BoardGroup g = new BoardGroup(); g.setGroupId("demo"); g.setCategory(String.valueOf(s[0])); g.setName(String.valueOf(s[1])); g.setCompanyIds(String.valueOf(s[2])); em.persist(g); } } private void seedScansEnrich() { List scans = em.createQuery("select s from ScanDoc s where s.groupId='demo'", ScanDoc.class).getResultList(); for (ScanDoc s : scans) { if ("DONE".equals(s.getState()) || "DONE".equalsIgnoreCase(String.valueOf(s.getState()))) s.setState("완료"); if ("PENDING".equals(s.getState())) s.setState("대기"); if (s.getRegisteredAt() == null) s.setRegisteredAt(s.getCreatedAt() == null ? java.time.LocalDateTime.now() : java.time.LocalDateTime.ofInstant(s.getCreatedAt(), java.time.ZoneId.of("Asia/Seoul"))); if (s.getOutcompanyName() == null || s.getOutcompanyName().isBlank()) { if (s.getOutcompanyId() != null) { Company c = em.find(Company.class, s.getOutcompanyId()); if (c != null) s.setOutcompanyName(c.getName()); } } } if (scans.size() >= 3) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); if (shops.isEmpty()) return; Company shop = shops.getFirst(); Object[][] samples = { {"완료", "SKT", "보상기변", "비즈케어/010-1234-5678", null, null, 1}, {"접수", "SKT2", "MNP", "비즈케어", null, null, 1}, }; for (int i = 0; i < samples.length; i++) { if (scans.size() + i >= 3) break; Object[] s = samples[i]; ScanDoc d = new ScanDoc(); d.setGroupId("demo"); d.setOutcompanyId(shop.getId()); d.setOutcompanyName(shop.getName()); d.setState(String.valueOf(s[0])); d.setTelcompany(String.valueOf(s[1])); d.setGubun(String.valueOf(s[2])); d.setName(String.valueOf(s[3])); d.setSendmsg(s[4] == null ? null : String.valueOf(s[4])); d.setMemo(s[5] == null ? null : String.valueOf(s[5])); d.setFilesCount(((Number) s[6]).intValue()); d.setSrc("2"); d.setRegisteredAt(java.time.LocalDateTime.now().minusDays(i + 1).withHour(12 + i).withMinute(1 + i * 20).withSecond(0).withNano(0)); em.persist(d); } } private void seedSettlementDocsIfEmpty() { String ym = LocalDate.now().minusMonths(1).toString().substring(0, 7); Company d2 = em.createQuery("select c from Company c where c.groupId='demo' and c.name='D2'", Company.class) .getResultList().stream().findFirst().orElse(null); if (d2 == null) { d2 = company("OUT", "D2", "이대리", "010-1111-1002"); } List prev = em.createQuery( "select s from SettlementMonth s where s.groupId='demo' and s.yearMonth=:y", SettlementMonth.class) .setParameter("y", ym).getResultList(); if (prev.isEmpty()) { SettlementMonth s = new SettlementMonth(); s.setGroupId("demo"); s.setOutcompanyId(d2.getId()); s.setOutcompanyName("D2"); s.setYearMonth(ym); s.setOutCategory("판매점"); s.setOpenCount(0); s.setOpenAmount(BigDecimal.ZERO); s.setAfterSettleCount(1); s.setAfterSettleAmount(new BigDecimal("-100000")); s.setHomeProductCount(0); s.setHomeProductAmount(BigDecimal.ZERO); s.setRealSettleAmount(new BigDecimal("-100000")); s.setIssued(false); s.setStatus("READY"); s.setInquiry("-"); s.setAgreement("-"); s.setInvoiceStatus("-"); s.setRemittanceStatus("-"); em.persist(s); } else { // Align demo sample with original screenshot (출고처 D2 / 후정산 1 / -100,000) SettlementMonth s = prev.getFirst(); s.setOutcompanyId(d2.getId()); s.setOutcompanyName("D2"); s.setOutCategory(s.getOutCategory() == null ? "판매점" : s.getOutCategory()); if (s.getAfterSettleCount() == null || s.getAfterSettleCount() == 0) s.setAfterSettleCount(1); if (s.getAfterSettleAmount() == null || s.getAfterSettleAmount().compareTo(BigDecimal.ZERO) == 0) { s.setAfterSettleAmount(new BigDecimal("-100000")); } if (s.getRealSettleAmount() == null || s.getRealSettleAmount().compareTo(BigDecimal.ZERO) == 0) { s.setRealSettleAmount(s.getAfterSettleAmount()); } } for (SettlementMonth row : em.createQuery("select s from SettlementMonth s where s.groupId='demo'", SettlementMonth.class).getResultList()) { if (row.getOutcompanyName() == null || row.getOutcompanyName().isBlank()) { Company c = row.getOutcompanyId() == null ? null : em.find(Company.class, row.getOutcompanyId()); if (c != null) row.setOutcompanyName(c.getName()); } if (row.getAfterSettleCount() == null) row.setAfterSettleCount(row.getAfterSettleAmount() == null || row.getAfterSettleAmount().compareTo(BigDecimal.ZERO) == 0 ? 0 : 1); if (row.getOpenCount() == null) row.setOpenCount(0); if (row.getOpenAmount() == null) row.setOpenAmount(BigDecimal.ZERO); if (row.getHomeProductCount() == null) row.setHomeProductCount(0); if (row.getHomeProductAmount() == null) row.setHomeProductAmount(BigDecimal.ZERO); if (row.getInquiry() == null) row.setInquiry("-"); if (row.getAgreement() == null) row.setAgreement("-"); if (row.getInvoiceStatus() == null) row.setInvoiceStatus("-"); if (row.getRemittanceStatus() == null) row.setRemittanceStatus("-"); } } private void seedOutcompanyAccountsIfEmpty() { String menuAll = "{\"policy\":true,\"pds\":true,\"return\":true,\"indoc\":true,\"scan\":true,\"stock\":true,\"open\":true,\"settle\":true,\"farebox\":true}"; Object[][] specs = { {"대구 D1", "도매", "P0000", "늘명훈", "010-1111-1111", "demoshop", "demoshop", true, 0, null}, {"대구 늘푸른통신", "도매", "P1234", "김담당", "010-2222-2222", "as001", "as001", true, 89, "2026-07-10T22:10:00"}, {"경산 D2", "도매", "P2001", "이대리", "010-1111-1002", "d2shop", "d2shop", true, 53, "2026-07-09T18:20:00"}, {"스마트모바일", "소매", "P3001", "최영업", "010-1111-1004", "smart01", "smart01", false, 12, "2026-06-01T10:00:00"}, {"블루폰", "C채널", "P4001", "정매니저", "010-1111-1005", null, null, true, 0, null}, {"출고처 샘플", "특판", "P5001", "이출고", "010-4444-5555", "sample1", "sample1", true, 100, "2026-07-08T09:15:00"}, {"늘붉은통신", "소매", "P0001", "홍길동", "010-1234-5678", null, null, true, 0, null}, }; for (Object[] s : specs) { String name = String.valueOf(s[0]); Company c = em.createQuery("select c from Company c where c.groupId='demo' and c.name=:n", Company.class) .setParameter("n", name).getResultList().stream().findFirst().orElse(null); if (c == null && name.endsWith(" D1")) { c = em.createQuery("select c from Company c where c.groupId='demo' and c.name='D1'", Company.class) .getResultList().stream().findFirst().orElse(null); } if (c == null && name.endsWith(" D2")) { c = em.createQuery("select c from Company c where c.groupId='demo' and c.name='D2'", Company.class) .getResultList().stream().findFirst().orElse(null); } if (c == null && name.contains("늘푸른")) { c = em.createQuery("select c from Company c where c.groupId='demo' and c.name='늘푸른통신'", Company.class) .getResultList().stream().findFirst().orElse(null); } if (c == null) { String type = "늘붉은통신".equals(name) ? "SHOP" : "OUT"; c = company(type, name, String.valueOf(s[3]), String.valueOf(s[4])); } else { c.setName(name); } c.setChannel(String.valueOf(s[1])); c.setPcode(String.valueOf(s[2])); c.setManagerName(String.valueOf(s[3])); c.setPhone(String.valueOf(s[4])); if (s[5] == null) continue; String userid = String.valueOf(s[5]); String password = String.valueOf(s[6]); boolean active = Boolean.TRUE.equals(s[7]); int loginCount = ((Number) s[8]).intValue(); Member m = em.createQuery("select m from Member m where m.groupId='demo' and m.role='SHOP' and m.companyId=:c", Member.class) .setParameter("c", c.getId()).getResultList().stream().findFirst().orElse(null); if (m == null) { List byUser = em.createQuery("select m from Member m where m.userid=:id", Member.class) .setParameter("id", userid).getResultList(); if (!byUser.isEmpty()) { m = byUser.getFirst(); m.setCompanyId(c.getId()); m.setRole("SHOP"); } else { m = new Member(); m.setGroupId("demo"); m.setRole("SHOP"); m.setCompanyId(c.getId()); m.setUserid(userid); m.setPassword(encoder.encode(password)); em.persist(m); } } m.setUserid(userid); m.setPassword(encoder.encode(password)); m.setPlainPassword(password); m.setName(c.getName()); m.setPhone(c.getPhone()); m.setActive(active); m.setLoginCount(loginCount); m.setMenuFlags(menuAll); if (s[9] != null) m.setLastLoginAt(java.time.LocalDateTime.parse(String.valueOf(s[9]))); } for (Company c : em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('OUT','SHOP')", Company.class).getResultList()) { if (c.getChannel() == null || c.getChannel().isBlank()) c.setChannel("기타"); if (c.getPcode() == null || c.getPcode().isBlank()) c.setPcode("P" + String.format("%04d", c.getId() == null ? 0 : c.getId())); } for (Member m : em.createQuery("select m from Member m where m.groupId='demo' and m.role='SHOP'", Member.class).getResultList()) { if ((m.getPlainPassword() == null || m.getPlainPassword().isBlank()) && "demoshop".equals(m.getUserid())) { m.setPlainPassword("demoshop"); } if (m.getMenuFlags() == null || m.getMenuFlags().isBlank()) m.setMenuFlags(menuAll); if (m.getLoginCount() == null) m.setLoginCount(0); } } private void seedAgentShopSettingIfEmpty() { Long count = em.createQuery("select count(s) from Setting s where s.groupId='demo' and s.settingKey='agentshop'", Long.class).getSingleResult(); if (count != null && count > 0) return; Setting s = new Setting(); s.setGroupId("demo"); s.setSettingKey("agentshop"); s.setValue("{\"access\":true,\"policy\":true,\"pds\":true,\"returnPhone\":true,\"indoc\":true,\"scan\":true,\"scanReceiveSms\":false,\"scanReceivePhones\":\"\",\"scanSendSms\":false,\"scanSenderPhone\":\"1600-3903\",\"scanCompleteMsg\":\"스캔신청서가 완료 처리되었습니다.\",\"scanHoldMsg\":\"스캔신청서가 보류 처리되었습니다.\",\"stock\":true,\"stockPeriod\":\"always\",\"open\":true,\"settle\":true,\"farebox\":true,\"shopUrl\":\"https://shop.bizcare.co.kr\"}"); em.persist(s); } private void seedFareboxSamplesIfEmpty() { Long count = em.createQuery("select count(e) from Farebox e where e.groupId='demo'", Long.class).getSingleResult(); if (count != null && count >= 6) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT') order by c.id", Company.class).getResultList(); if (shops.isEmpty()) return; Object[][] samples = { {LocalDate.of(2025, 11, 16), "SKT", "대박통신", "김*현", "010-****-5555", "수납", "0", "12200", "완결", "", "김대표"}, {LocalDate.of(2025, 5, 22), "SKT", "늘푸른통신", "1*3", "***-****-****", "수납", "653000", "0", "미결", "", "김대표"}, {LocalDate.of(2025, 4, 10), "KT엠모바일", "늘푸른통신", "최***신", "010-****-1111", "수납", "20000", "0", "완결", "선불충전", "김대표"}, {LocalDate.of(2025, 3, 8), "LGT", "테스트", "홍*동", "010-****-2222", "대납", "-20000", "0", "미결", "환불금", "김대표"}, {LocalDate.of(2025, 2, 1), "SK텔링크", shops.getFirst().getName(), "박*수", "010-****-3333", "수납", "0", "50000", "완결", "요금수납", "김대표"}, }; for (int i = 0; i < samples.length; i++) { Object[] s = samples[i]; LocalDate date = (LocalDate) s[0]; String name = String.valueOf(s[3]); Long exists = em.createQuery("select count(e) from Farebox e where e.groupId='demo' and e.faredate=:d and e.name=:n", Long.class) .setParameter("d", date).setParameter("n", name).getSingleResult(); if (exists != null && exists > 0) continue; Company shop = shops.get(i % shops.size()); Farebox row = new Farebox(); row.setGroupId("demo"); row.setOutcompanyId(shop.getId()); row.setOutcompanyName(String.valueOf(s[2])); row.setOutCategory("판매점"); row.setFaredate(date); row.setTelcompany(String.valueOf(s[1])); row.setName(name); row.setPhone(String.valueOf(s[4])); row.setHow(String.valueOf(s[5])); row.setCashprice(new BigDecimal(String.valueOf(s[6]))); row.setCardprice(new BigDecimal(String.valueOf(s[7]))); row.setPaystate(String.valueOf(s[8])); row.setDetail(String.valueOf(s[9])); row.setRegistrant(String.valueOf(s[10])); row.setReceiptNo("R-S" + (i + 1)); em.persist(row); } } private void seedFareboxPaymentsIfEmpty() { Long count = em.createQuery("select count(p) from FareboxPayment p where p.groupId='demo'", Long.class).getSingleResult(); if (count != null && count >= 8) return; List boxes = em.createQuery("select e from Farebox e where e.groupId='demo' order by e.id", Farebox.class).getResultList(); Object[][] samples = { {LocalDate.of(2025, 7, 12), "늘푸른통신", "일반", "653000", "이계통", "정상", "판매점"}, {LocalDate.of(2025, 7, 10), "D1", "건별", "2500", "재고전용", "정상", "판매점"}, {LocalDate.of(2025, 6, 20), "대박통신", "일반", "12200", "김대표", "취소됨", "판매점"}, {LocalDate.of(2025, 5, 15), "늘푸른통신", "건별", "20000", "이계통", "정상", "판매점"}, {LocalDate.of(2025, 4, 8), "테스트", "일반", "50000", "김대표", "정상", "판매점"}, {LocalDate.of(2025, 3, 22), "늘붉은통신", "일반", "30000", "재고전용", "정상", "판매점"}, {LocalDate.of(2025, 2, 14), "대박통신", "건별", "15000", "이계통", "취소됨", "판매점"}, {LocalDate.of(2025, 1, 5), "D1", "일반", "8800", "김대표", "정상", "판매점"}, }; for (int i = 0; i < samples.length; i++) { Object[] s = samples[i]; LocalDate paydate = (LocalDate) s[0]; String outName = String.valueOf(s[1]); Long exists = em.createQuery( "select count(p) from FareboxPayment p where p.groupId='demo' and p.paydate=:d and p.outcompanyName=:n and p.amount=:a", Long.class) .setParameter("d", paydate).setParameter("n", outName).setParameter("a", new BigDecimal(String.valueOf(s[3]))) .getSingleResult(); if (exists != null && exists > 0) continue; FareboxPayment p = new FareboxPayment(); p.setGroupId("demo"); p.setPaydate(paydate); p.setOutcompanyName(outName); p.setMode(String.valueOf(s[2])); p.setAmount(new BigDecimal(String.valueOf(s[3]))); p.setRegistrant(String.valueOf(s[4])); p.setStatus(String.valueOf(s[5])); p.setOutCategory(String.valueOf(s[6])); p.setPayCount(1); p.setMemo(null); if (!boxes.isEmpty()) { Farebox box = boxes.get(i % boxes.size()); p.setOutcompanyId(box.getOutcompanyId()); p.setFareboxIds(String.valueOf(box.getId())); } em.persist(p); } } private void seedSmsHistoryIfEmpty() { Long balCount = em.createQuery("select count(s) from Setting s where s.groupId='demo' and s.settingKey='sms_balance'", Long.class).getSingleResult(); if (balCount == null || balCount == 0) { Setting bal = new Setting(); bal.setGroupId("demo"); bal.setSettingKey("sms_balance"); bal.setValue("996"); em.persist(bal); } Long count = em.createQuery("select count(e) from SmsMessage e where e.groupId='demo'", Long.class).getSingleResult(); if (count != null && count >= 4) return; Object[][] samples = { {LocalDateTime.of(2026, 7, 10, 13, 40), "01011111111", "단문", "안녕하세요. 비즈케어 안내 문자입니다.", "김대표"}, {LocalDateTime.of(2026, 7, 9, 10, 15), "01022222222", "단문", "개통 서류 안내드립니다.", "이계통"}, {LocalDateTime.of(2026, 7, 8, 16, 5), "01033334444,01055556666", "단문", "유심 수령 안내입니다.", "김대표"}, {LocalDateTime.of(2026, 7, 7, 9, 30), "01077778888", "단문", "요금수납 확인 부탁드립니다.", "이계통"}, }; for (Object[] s : samples) { LocalDateTime ldt = (LocalDateTime) s[0]; String phone = String.valueOf(s[1]); Long exists = em.createQuery( "select count(e) from SmsMessage e where e.groupId='demo' and e.phone=:p and e.message=:m", Long.class) .setParameter("p", phone).setParameter("m", String.valueOf(s[3])).getSingleResult(); if (exists != null && exists > 0) continue; int sendCount = phone.split(",").length; SmsMessage row = new SmsMessage(); row.setGroupId("demo"); row.setUserid("demo"); row.setPhone(phone); row.setMessage(String.valueOf(s[3])); row.setStatus("발송"); row.setMsgType(String.valueOf(s[2])); row.setSenderNumber("1600-3903"); row.setSenderName(String.valueOf(s[4])); row.setSendCount(sendCount); row.setDeductCount(sendCount); row.setSentAt(ldt.atZone(ZoneId.systemDefault()).toInstant()); em.persist(row); } } private void seedSmsAddressIfEmpty() { Long gCount = em.createQuery("select count(g) from SmsAddressGroup g where g.groupId='demo'", Long.class).getSingleResult(); if (gCount != null && gCount > 0) return; SmsAddressGroup g1 = new SmsAddressGroup(); g1.setGroupId("demo"); g1.setName("동해물과"); em.persist(g1); em.flush(); SmsAddressGroup g2 = new SmsAddressGroup(); g2.setGroupId("demo"); g2.setName("백두산이"); em.persist(g2); Object[][] contacts = { {g1.getId(), "1", "01000000000"}, {g1.getId(), "홍길동", "01015231244"}, }; for (Object[] s : contacts) { SmsAddressContact c = new SmsAddressContact(); c.setGroupId("demo"); c.setAddressGroupId((Long) s[0]); c.setName(String.valueOf(s[1])); c.setPhone(String.valueOf(s[2])); em.persist(c); } } private void seedStaffMembersIfEmpty() { // enrich demo owner List demos = em.createQuery("select m from Member m where m.userid='demo'", Member.class).getResultList(); if (!demos.isEmpty()) { Member demo = demos.getFirst(); if (demo.getStaffPermission() == null || demo.getStaffPermission().isBlank()) { demo.setStaffPermission("대표"); demo.setName("김대표"); demo.setPhone("010-1111-2222"); if (demo.getLoginCount() == null || demo.getLoginCount() == 0) demo.setLoginCount(5032); if (demo.getLastLoginAt() == null) demo.setLastLoginAt(LocalDateTime.now().minusMinutes(10)); if (demo.getAssignedOutNames() == null) demo.setAssignedOutNames("늘푸른통신,대박통신"); } } Long count = em.createQuery("select count(m) from Member m where m.groupId='demo' and m.role='AGENT'", Long.class).getSingleResult(); if (count != null && count >= 8) return; Object[][] samples = { {"demo02", "이총괄", "총괄", "010-2222-3333", "D1,D2", 1204}, {"demo03", "박재고", "재고", "010-3333-4444", "늘푸른통신", 856}, {"demo04", "최개통", "개통", "010-4444-5555", "스마트모바일,블루폰", 642}, {"demo05", "정영업", "영업", "010-5555-6666", "대박통신", 311}, {"demo06", "한딜러", "딜러", "010-6666-7777", "출고처 샘플", 98}, {"demo07", "오재고", "재고", "010-7777-8888", "", 45}, {"demo08", "윤영업", "영업", "010-8888-9999", "늘붉은통신", 22}, {"demo09", "강총괄", "총괄", "010-9999-1111", "D1", 15}, {"demo10", "조개통", "개통", "010-1212-3434", "", 8}, {"demo11", "임영업", "영업", "010-5656-7878", "블루폰", 3}, {"demo12", "배수납", "영업", "010-9090-1212", "스마트모바일", 1}, }; for (int i = 0; i < samples.length; i++) { Object[] s = samples[i]; String userid = String.valueOf(s[0]); Long exists = em.createQuery("select count(m) from Member m where m.userid=:id", Long.class) .setParameter("id", userid).getSingleResult(); if (exists != null && exists > 0) continue; Member m = new Member(); m.setGroupId("demo"); m.setUserid(userid); m.setPassword(encoder.encode("demo123")); m.setPlainPassword("demo123"); m.setName(String.valueOf(s[1])); m.setStaffPermission(String.valueOf(s[2])); m.setPhone(String.valueOf(s[3])); String outs = String.valueOf(s[4]); m.setAssignedOutNames(outs.isBlank() ? null : outs); m.setRole("AGENT"); m.setActive(true); m.setLoginCount((Integer) s[5]); m.setLastLoginAt(LocalDateTime.now().minusDays(i).minusHours(i % 5)); em.persist(m); } } private void seedHomesMembersEnrich() { // 홈즈 직원관리 원본 샘플 (대표 + demo1~5) Object[][] samples = { {"demo", "홍길동", "대표", "010-1234-1234", "대구광역시 동구 동대구로455", "", 205, LocalDateTime.of(2026, 7, 11, 17, 53), LocalDate.of(2022, 4, 12), "데모 대표계정"}, {"demo1", "홍총괄", "총괄", "010-1111-1111", "1", "", 6, LocalDateTime.of(2022, 4, 13, 12, 33), LocalDate.of(2022, 4, 13), null}, {"demo2", "홍팀장", "팀장", "010-2222-2222", "", "", 3, LocalDateTime.of(2022, 4, 14, 10, 12), LocalDate.of(2022, 4, 13), null}, {"demo3", "홍사원", "사원", "010-3333-3333", "", "", 2, LocalDateTime.of(2022, 4, 13, 16, 36), LocalDate.of(2022, 4, 13), null}, {"demo4", "홍영업", "영업", "010-4444-4444", "", "", 3, LocalDateTime.of(2022, 4, 13, 16, 42), LocalDate.of(2022, 4, 13), null}, {"demo5", "홍딜러", "딜러", "010-5555-5555", "", "", 1, LocalDateTime.of(2022, 4, 13, 16, 49), LocalDate.of(2022, 4, 13), null}, }; java.util.Set keep = new java.util.HashSet<>(); for (Object[] s : samples) keep.add(String.valueOf(s[0])); for (Member old : em.createQuery("select m from Member m where m.groupId='demo' and m.role='AGENT'", Member.class).getResultList()) { if (!keep.contains(old.getUserid())) em.remove(old); } em.flush(); for (Object[] s : samples) { String userid = String.valueOf(s[0]); List found = em.createQuery("select m from Member m where m.userid=:id", Member.class) .setParameter("id", userid).getResultList(); Member m = found.isEmpty() ? new Member() : found.getFirst(); m.setGroupId("demo"); m.setUserid(userid); m.setName(String.valueOf(s[1])); m.setStaffPermission(String.valueOf(s[2])); m.setPhone(String.valueOf(s[3])); String addr = String.valueOf(s[4]); m.setAddress(addr.isBlank() ? null : addr); String limit = String.valueOf(s[5]); m.setAccessLimit(limit.isBlank() ? null : limit); m.setLoginCount((Integer) s[6]); m.setLastLoginAt((LocalDateTime) s[7]); m.setRole("AGENT"); m.setActive(true); if (s[9] != null) m.setMemo(String.valueOf(s[9])); if (found.isEmpty()) { m.setPassword(encoder.encode("demo123")); m.setPlainPassword("demo123"); em.persist(m); em.flush(); } LocalDate reg = (LocalDate) s[8]; if (reg != null) { Instant at = reg.atStartOfDay(ZoneId.of("Asia/Seoul")).toInstant(); m.setCreatedAt(at); m.setUpdatedAt(at); } } } private void seedIncompaniesIfEmpty() { Long count = em.createQuery("select count(c) from Company c where c.groupId='demo' and c.type='IN'", Long.class).getSingleResult(); Object[][] samples = { {"디엘로(KT)", "LG헬로비전 (KT)", "02-0000-0000", "02-0000-0001", "우담당", "010-0000-0000", "디헬로우", "000-00-00000"}, {"KT", "KT", "02-1111-1111", "02-1111-1112", "김담당", "010-1111-1111", "케이티", "111-11-11111"}, {"SKT", "SKT", "02-2222-2222", "02-2222-2223", "이담당", "010-2222-2222", "에스케이티", "222-22-22222"}, {"LGU+", "LGU+", "02-3333-3333", "", "박담당", "010-3333-3333", "엘지유플러스", "333-33-33333"}, {"SK텔링크", "SK텔링크", "02-4444-4444", "", "최담당", "010-4444-4444", "텔링크", "444-44-44444"}, {"KT엠모바일", "KT엠모바일", "02-5555-5555", "", "정담당", "010-5555-5555", "엠모바일", "555-55-55555"}, {"비즈케어 물류센터", "SKT", "02-5555-1004", "02-5555-1005", "최물류", "010-5555-1004", "비즈케어물류", "666-66-66666"}, {"입고처A", "KT", "02-1234-5678", "", "김입고", "010-1234-5678", "입고에이", "777-77-77777"}, }; if (count != null && count >= 8) { // enrich existing IN companies missing telecom List existing = em.createQuery("select c from Company c where c.groupId='demo' and c.type='IN'", Company.class).getResultList(); for (Company c : existing) { if (c.getTelecom() == null || c.getTelecom().isBlank()) { for (Object[] s : samples) { if (String.valueOf(s[0]).equals(c.getName())) { c.setTelecom(String.valueOf(s[1])); c.setFax(blankStr(String.valueOf(s[3]))); c.setMobile(String.valueOf(s[5])); c.setBusinessName(String.valueOf(s[6])); c.setBusinessNumber(String.valueOf(s[7])); break; } } if (c.getTelecom() == null || c.getTelecom().isBlank()) c.setTelecom("SKT"); } } return; } for (Object[] s : samples) { String name = String.valueOf(s[0]); Long exists = em.createQuery("select count(c) from Company c where c.groupId='demo' and c.type='IN' and c.name=:n", Long.class) .setParameter("n", name).getSingleResult(); if (exists != null && exists > 0) continue; Company c = new Company(); c.setGroupId("demo"); c.setType("IN"); c.setName(name); c.setTelecom(String.valueOf(s[1])); c.setPhone(String.valueOf(s[2])); c.setFax(blankStr(String.valueOf(s[3]))); c.setManagerName(String.valueOf(s[4])); c.setMobile(String.valueOf(s[5])); c.setBusinessName(String.valueOf(s[6])); c.setBusinessNumber(String.valueOf(s[7])); c.setActive(true); em.persist(c); } } private String blankStr(String v) { return v == null || v.isBlank() ? null : v; } private void seedOutcompaniesEnrich() { List outs = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('OUT','SHOP')", Company.class).getResultList(); Object[][] extras = { {"대구 D1", "도매", "판매점", "P0001", "김영업", "010-1111-1001", "대구디원", "101-01-10001", "국민 111-111-111111"}, {"경산 D2", "도매", "판매점", "P0002", "이영업", "010-1111-1002", "경산디투", "102-02-10002", "신한 222-222-222222"}, {"대구 늘푸른통신", "도매", "판매점", "P0003", "박영업", "010-1111-1003", "늘푸른", "103-03-10003", "우리 333-333-333333"}, {"스마트모바일", "소매", "판매점", "P0004", "최영업", "010-1111-1004", "스마트", "104-04-10004", "하나 444-444-444444"}, {"블루폰", "특판", "판매점", "P0005", "정영업", "010-1111-1005", "블루폰", "105-05-10005", "농협 555-555-555555"}, {"늘붉은통신", "도매", "판매점", "P1000", "홍길동", "010-1234-5678", "늘붉은통신", "106-06-10006", "국민은행 000-000-0000000 홍길동"}, {"출고처 샘플", "기타", "출고처", "P2000", "이출고", "010-4444-5555", "출고샘플", "107-07-10007", null}, }; Map byName = new LinkedHashMap<>(); for (Object[] s : extras) byName.put(String.valueOf(s[0]), s); for (Company c : outs) { Object[] s = byName.get(c.getName()); if (s != null) { if (blankStr(c.getChannel()) == null) c.setChannel(String.valueOf(s[1])); if (blankStr(c.getCategory()) == null) c.setCategory(String.valueOf(s[2])); if (blankStr(c.getPcode()) == null) c.setPcode(String.valueOf(s[3])); if (blankStr(c.getSalesperson()) == null) c.setSalesperson(String.valueOf(s[4])); if (blankStr(c.getMobile()) == null) c.setMobile(String.valueOf(s[5])); if (blankStr(c.getBusinessName()) == null) c.setBusinessName(String.valueOf(s[6])); if (blankStr(c.getBusinessNumber()) == null) c.setBusinessNumber(String.valueOf(s[7])); if (blankStr(c.getBankAccount()) == null && s[8] != null) c.setBankAccount(String.valueOf(s[8])); } else { if (blankStr(c.getChannel()) == null) c.setChannel("도매"); if (blankStr(c.getCategory()) == null) c.setCategory("SHOP".equals(c.getType()) ? "판매점" : "출고처"); if (blankStr(c.getSalesperson()) == null) c.setSalesperson(c.getManagerName()); } } // ensure sample names exist for (Object[] s : extras) { String name = String.valueOf(s[0]); boolean exists = outs.stream().anyMatch(c -> name.equals(c.getName())); if (exists) continue; Company c = new Company(); c.setGroupId("demo"); c.setType("OUT"); c.setName(name); c.setChannel(String.valueOf(s[1])); c.setCategory(String.valueOf(s[2])); c.setPcode(String.valueOf(s[3])); c.setSalesperson(String.valueOf(s[4])); c.setManagerName(String.valueOf(s[4])); c.setPhone(String.valueOf(s[5])); c.setMobile(String.valueOf(s[5])); c.setBusinessName(String.valueOf(s[6])); c.setBusinessNumber(String.valueOf(s[7])); if (s[8] != null) c.setBankAccount(String.valueOf(s[8])); c.setActive(true); em.persist(c); } } private void seedDeliveriesIfEmpty() { Long count = em.createQuery("select count(c) from Company c where c.groupId='demo' and c.type='DELIVERY'", Long.class).getSingleResult(); if (count != null && count >= 3) return; Object[][] samples = { {"대한통운", "1588-1255", null}, {"오성퀵", "000-0000-0000", null}, {"해운퀵", "000-0000-0000", null}, }; for (Object[] s : samples) { String name = String.valueOf(s[0]); Long exists = em.createQuery("select count(c) from Company c where c.groupId='demo' and c.type='DELIVERY' and c.name=:n", Long.class) .setParameter("n", name).getSingleResult(); if (exists != null && exists > 0) continue; Company c = new Company(); c.setGroupId("demo"); c.setType("DELIVERY"); c.setName(name); c.setPhone(String.valueOf(s[1])); c.setMemo(s[2] == null ? null : String.valueOf(s[2])); c.setActive(true); em.persist(c); } } private void seedPreferenceIfEmpty() { Long count = em.createQuery("select count(s) from Setting s where s.groupId='demo' and s.settingKey='preference'", Long.class).getSingleResult(); if (count != null && count > 0) return; String json = "{" + "\"company\":{" + "\"name\":\"에이전트 데모\"," + "\"managerName\":\"김대표\"," + "\"mobile\":\"010-0000-0000\"," + "\"businessName\":\"에이전트 데모\"," + "\"businessNumber\":\"123-45-67890\"," + "\"ceo\":\"김유신\"," + "\"bizType\":\"도소매\"," + "\"bizItem\":\"휴대폰판매\"," + "\"address\":\"대구시 수성구 수성4가 먼길\"" + "}," + "\"accessIps\":{\"enabled\":false,\"ips\":[]}," + "\"masking\":{\"enabled\":true,\"name\":true,\"phone\":true,\"rrn\":true,\"address\":false}," + "\"outCategories\":[\"판매점\",\"도매\"]," + "\"stock\":{\"duplicateSerialCheck\":true,\"allowNegative\":false,\"autoRecallDays\":0}," + "\"open\":{\"requireUsim\":true,\"requirePhone\":true,\"defaultOpenHow\":\"\",\"autoSettle\":false}" + "}"; Setting s = new Setting(); s.setGroupId("demo"); s.setSettingKey("preference"); s.setValue(json); em.persist(s); } private void seedCsNoticesIfEmpty() { Long count = em.createQuery("select count(b) from BbsPost b where b.groupId='demo' and b.code='cs'", Long.class).getSingleResult(); if (count != null && count >= 20) return; Object[][] samples = { {"고객센터 5월 4일(월) 임시휴무안내", 6, LocalDate.of(2026, 4, 29)}, {"지원금표기 관련 설정업데이트", 7, LocalDate.of(2025, 7, 30)}, {"지원금표기 관련 설정업데이트 안내", 8, LocalDate.of(2025, 7, 30)}, {"개통등록 화면 개선 안내", 12, LocalDate.of(2025, 7, 15)}, {"문자발송 시스템 점검 안내", 18, LocalDate.of(2025, 6, 20)}, {"요금수납 기능 업데이트 안내", 22, LocalDate.of(2025, 5, 28)}, {"개인정보 마스킹 기능 추가 안내", 31, LocalDate.of(2025, 4, 10)}, {"출고처 분류 설정 방법 안내", 15, LocalDate.of(2025, 3, 22)}, {"재고관리 바코드 스캔 개선", 27, LocalDate.of(2025, 2, 14)}, {"정산자료 엑셀다운로드 오류 수정", 19, LocalDate.of(2025, 1, 20)}, {"연말연시 고객센터 운영안내", 45, LocalDate.of(2024, 12, 24)}, {"에이전트샵 접속 장애 복구 안내", 38, LocalDate.of(2024, 11, 8)}, {"보안 업데이트 적용 안내", 52, LocalDate.of(2024, 10, 15)}, {"신규 통신사 요금제 등록 안내", 24, LocalDate.of(2024, 9, 3)}, {"모바일 앱 버전 업데이트 안내", 41, LocalDate.of(2024, 8, 12)}, {"스캔신청서 접수 문자 설정 안내", 16, LocalDate.of(2024, 7, 25)}, {"서버 정기점검 안내 (7/20)", 33, LocalDate.of(2024, 7, 18)}, {"개통내역 일괄삭제 기능 추가", 29, LocalDate.of(2024, 6, 5)}, {"유심거래장부 메뉴 오픈 안내", 21, LocalDate.of(2024, 5, 17)}, {"비밀번호 변경 권고 안내", 67, LocalDate.of(2024, 4, 2)}, {"고객센터 설 연휴 휴무안내", 55, LocalDate.of(2024, 2, 8)}, {"프로그램 이용약관 개정 안내", 48, LocalDate.of(2024, 1, 15)}, {"엑셀 업로드 양식 변경 안내", 36, LocalDate.of(2023, 12, 1)}, {"출고처 일괄등록 기능 추가", 28, LocalDate.of(2023, 10, 20)}, {"알림톡 발송 서비스 오픈", 44, LocalDate.of(2023, 9, 8)}, {"재고실사 기능 사용방법 안내", 39, LocalDate.of(2023, 8, 14)}, {"로그인 2단계 인증 안내", 61, LocalDate.of(2023, 7, 3)}, {"고객센터 추석 연휴 휴무안내", 50, LocalDate.of(2023, 9, 25)}, {"개통수수료 정산 로직 변경", 34, LocalDate.of(2023, 6, 12)}, {"브라우저 권장사양 안내", 72, LocalDate.of(2023, 5, 1)}, }; for (Object[] s : samples) { String title = String.valueOf(s[0]); Long exists = em.createQuery("select count(b) from BbsPost b where b.groupId='demo' and b.code='cs' and b.title=:t", Long.class) .setParameter("t", title).getSingleResult(); if (exists != null && exists > 0) continue; BbsPost b = new BbsPost(); b.setGroupId("demo"); b.setCode("cs"); b.setTitle(title); b.setContents("

" + title + "

자세한 내용은 고객센터(1600-3903)로 문의해 주세요.

"); b.setAuthorName("비즈케어"); b.setUserid("system"); b.setTargetGroup("전체"); b.setNotice(false); b.setViews((Integer) s[1]); b.setConfirmCount(0); b.setState("1"); em.persist(b); em.flush(); LocalDate d = (LocalDate) s[2]; b.setCreatedAt(d.atStartOfDay(ZoneId.of("Asia/Seoul")).toInstant()); b.setUpdatedAt(b.getCreatedAt()); } } private void seedCsInquiriesIfEmpty() { Long count = em.createQuery("select count(c) from CsInquiry c where c.groupId='demo'", Long.class).getSingleResult(); // ensure sample matching original screenshot exists Long test3 = em.createQuery("select count(c) from CsInquiry c where c.groupId='demo' and c.title='test3'", Long.class).getSingleResult(); if (test3 == null || test3 == 0) { CsInquiry c = new CsInquiry(); c.setGroupId("demo"); c.setUserid("demo"); c.setAuthorName("김대표"); c.setTitle("test3"); c.setContent("테스트 문의입니다."); c.setReply("확인되었습니다. 추가 문의사항이 있으시면 남겨주세요."); c.setStatus("답변완료"); c.setReplyCount(1); em.persist(c); em.flush(); c.setCreatedAt(LocalDate.of(2019, 11, 5).atStartOfDay(ZoneId.of("Asia/Seoul")).toInstant()); c.setUpdatedAt(c.getCreatedAt()); } if (count != null && count >= 1) { for (CsInquiry c : em.createQuery("select c from CsInquiry c where c.groupId='demo'", CsInquiry.class).getResultList()) { if (c.getAuthorName() == null || c.getAuthorName().isBlank()) c.setAuthorName("김대표"); if (c.getStatus() == null || "OPEN".equalsIgnoreCase(c.getStatus())) c.setStatus("답변대기"); if ("DONE".equalsIgnoreCase(c.getStatus())) c.setStatus("답변완료"); if (c.getReplyCount() == null) c.setReplyCount(c.getReply() != null && !c.getReply().isBlank() ? 1 : 0); } } } private void seedInternalBoardIfEmpty() { Long count = em.createQuery("select count(b) from BbsPost b where b.groupId='demo' and b.code='company'", Long.class).getSingleResult(); if (count != null && count >= 5) return; Object[][] samples = { {"7", "김대표", 0, LocalDate.of(2023, 6, 23), 0}, {"업무공지", "김대표", 20, LocalDate.of(2021, 2, 15), 0}, {"zcxvzxcv", "김대표", 6, LocalDate.of(2020, 11, 13), 0}, {"124", "오영업", 14, LocalDate.of(2019, 8, 8), 1}, {"124", "김대표", 8, LocalDate.of(2019, 8, 2), 0}, }; for (Object[] s : samples) { String title = String.valueOf(s[0]); String author = String.valueOf(s[1]); LocalDate date = (LocalDate) s[3]; Long exists = em.createQuery( "select count(b) from BbsPost b where b.groupId='demo' and b.code='company' and b.title=:t and b.authorName=:a", Long.class) .setParameter("t", title).setParameter("a", author).getSingleResult(); if (exists != null && exists > 0) { // still update date/views for matching sample continue; } BbsPost b = new BbsPost(); b.setGroupId("demo"); b.setCode("company"); b.setTitle(title); b.setContents("

" + title + "

"); b.setAuthorName(author); b.setUserid("demo"); b.setTargetGroup("전체"); b.setNotice(false); b.setViews((Integer) s[2]); b.setCommentCount((Integer) s[4]); b.setConfirmCount(0); b.setState("1"); em.persist(b); em.flush(); b.setCreatedAt(date.atStartOfDay(ZoneId.of("Asia/Seoul")).toInstant()); b.setUpdatedAt(b.getCreatedAt()); } } private void seedScheduleSampleIfEmpty() { LocalDate d = LocalDate.of(2026, 7, 11); Long exists = em.createQuery( "select count(s) from ScheduleItem s where s.groupId='demo' and s.sdate=:d and s.contents=:c", Long.class) .setParameter("d", d).setParameter("c", "ㅇㄴㅁㄹㅇㄴㅁ").getSingleResult(); if (exists != null && exists > 0) return; ScheduleItem s = new ScheduleItem(); s.setGroupId("demo"); s.setUserid("demo"); s.setSdate(d); s.setStime("01:30"); s.setContents("ㅇㄴㅁㄹㅇㄴㅁ"); em.persist(s); } private void seedPostitsIfEmpty() { String json = "[" + "{\"slot\":1,\"title\":\"포스트잇 #1\",\"contents\":\"신규 예약 개통 오예\",\"authorName\":\"김대표\",\"noteDate\":\"26-06-08\"}," + "{\"slot\":2,\"title\":\"포스트잇 #2\",\"contents\":\"demo\",\"authorName\":\"김대표\",\"noteDate\":\"26-06-08\"}," + "{\"slot\":3,\"title\":\"포스트잇 #3\",\"contents\":\"유심 발주 요청\",\"authorName\":\"이과장\",\"noteDate\":\"26-06-05\"}," + "{\"slot\":4,\"title\":\"포스트잇 #4\",\"contents\":\"정산서 마감 체크\",\"authorName\":\"김대표\",\"noteDate\":\"26-05-28\"}," + "{\"slot\":5,\"title\":\"포스트잇 #5\",\"contents\":\"스캔자료 검토\",\"authorName\":\"오영업\",\"noteDate\":\"26-05-20\"}," + "{\"slot\":6,\"title\":\"포스트잇 #6\",\"contents\":\"정책단가 업데이트\",\"authorName\":\"정총괄\",\"noteDate\":\"26-05-12\"}," + "{\"slot\":7,\"title\":\"포스트잇 #7\",\"contents\":\"고객센터 휴무 안내\",\"authorName\":\"김대표\",\"noteDate\":\"26-04-29\"}," + "{\"slot\":8,\"title\":\"포스트잇 #8\",\"contents\":\"월간 리포트 작성\",\"authorName\":\"이과장\",\"noteDate\":\"26-04-15\"}" + "]"; List rows = em.createQuery("select s from Setting s where s.groupId='demo' and s.settingKey='postits'", Setting.class).getResultList(); if (rows.isEmpty()) { Setting s = new Setting(); s.setGroupId("demo"); s.setSettingKey("postits"); s.setValue(json); em.persist(s); return; } Setting existing = rows.get(0); if (existing.getValue() != null && existing.getValue().contains("재고실사")) { existing.setValue(json); } } private void seedOpenStatsDemo() { LocalDate today = LocalDate.now(); LocalDate day8 = today.withDayOfMonth(Math.min(8, today.lengthOfMonth())); LocalDate day9 = today.withDayOfMonth(Math.min(9, today.lengthOfMonth())); List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT') order by c.id", Company.class).getResultList(); List ins = em.createQuery("select c from Company c where c.groupId='demo' and c.type='IN' order by c.id", Company.class).getResultList(); if (shops.isEmpty()) return; Long inId = ins.isEmpty() ? null : ins.getFirst().getId(); ensureOpenStatSample(day8, "기변", "20000", shops.getFirst().getId(), inId, "SM-S928N"); ensureOpenStatSample(day9, "보상", "25000", shops.get(Math.min(1, shops.size() - 1)).getId(), inId, "SM-A175N"); LocalDate apr = LocalDate.of(today.getYear(), 4, 12); LocalDate jul = LocalDate.of(today.getYear(), 7, Math.min(10, today.lengthOfMonth())); if (shops.size() > 2) ensureOpenStatSample(apr, "신규", "18000", shops.get(2).getId(), inId, "SM-F766NK"); if (shops.size() > 3) ensureOpenStatSample(apr, "MNP", "22000", shops.get(3).getId(), ins.size() > 1 ? ins.get(1).getId() : inId, "SM-S942NK"); ensureOpenStatSample(jul, "신규", "21000", shops.getFirst().getId(), inId, "SM-S942N_256G"); if (shops.size() > 1) ensureOpenStatSample(jul, "기변", "19000", shops.get(1).getId(), inId, "SM-A175N"); } private void ensureOpenStatSample(LocalDate date, String openhow, String margin, Long shopId, Long inId) { ensureOpenStatSample(date, openhow, margin, shopId, inId, "SM-S928N"); } private void ensureOpenStatSample(LocalDate date, String openhow, String margin, Long shopId, Long inId, String model) { Long count = em.createQuery( "select count(o) from OpenRecord o where o.groupId='demo' and o.opendate=:d and o.openhow=:h and o.pmodel=:m", Long.class) .setParameter("d", date).setParameter("h", openhow).setParameter("m", model).getSingleResult(); if (count != null && count > 0) return; OpenRecord open = new OpenRecord(); open.setGroupId("demo"); open.setOutcompanyId(shopId); open.setIncompanyId(inId); open.setGubun("할부"); open.setTelecom("SKT"); open.setOpenhow(openhow); open.setName("통계*샘플"); open.setOpenphone("010-****-0000"); open.setOpendate(date); open.setOpenHour(11); open.setOpenMinute(0); open.setOpenStatus("정상"); open.setOutCategory("판매점"); open.setSalesperson("김영업"); open.setEmployee("demo"); open.setPlan("5GX 프라임"); open.setPmodel(model); open.setPserial("STAT" + date.getMonthValue() + date.getDayOfMonth() + model.hashCode()); open.setSellprice(BigDecimal.ZERO); open.setDealermargin1(new BigDecimal(margin)); open.setDealermargin2(BigDecimal.ZERO); open.setState("OPEN"); open.setUserid("demo"); open.setUid("open-stat-" + openhow + "-" + date + "-" + model); em.persist(open); } private void seedHomeIndocsIfEmpty() { Long count = em.createQuery("select count(d) from HomeIncompleteDoc d where d.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); List ins = em.createQuery("select c from Company c where c.groupId='demo' and c.type='IN'", Company.class).getResultList(); if (shops.isEmpty()) return; Long inId = ins.isEmpty() ? null : ins.getFirst().getId(); Object[][] samples = { {"SKT", "김*근", "010-****-3566", "인터넷,TV", "신분증사본", "30000", "서류미비"}, {"KT", "박*지", "010-****-1122", "인터넷", "통장사본", "20000", "추가서류"}, {"LGU+", "이*수", "010-****-5678", "TV,집전화", "인감증명서", "50000", "대리신청"}, }; for (int i = 0; i < samples.length; i++) { Object[] s = samples[i]; HomeIncompleteDoc d = new HomeIncompleteDoc(); d.setGroupId("demo"); d.setOutcompanyId(shops.get(i % shops.size()).getId()); d.setIncompanyId(inId); d.setOutcompanyName(shops.get(i % shops.size()).getName()); d.setTelecom(String.valueOf(s[0])); d.setCustomerName(String.valueOf(s[1])); d.setPhone(String.valueOf(s[2])); d.setProducts(String.valueOf(s[3])); d.setMissingDocs(String.valueOf(s[4])); d.setDeductAmount(new BigDecimal(String.valueOf(s[5]))); d.setDeductReason(String.valueOf(s[6])); d.setInstallDate(LocalDate.now().minusDays(i * 2)); d.setDeadline(LocalDate.now().plusDays(7 - i)); d.setStatus("미비"); em.persist(d); } } private void seedHomeSalesIfEmpty() { Long count = em.createQuery("select count(h) from HomeSale h where h.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); List ins = em.createQuery("select c from Company c where c.groupId='demo' and c.type='IN'", Company.class).getResultList(); if (shops.isEmpty()) return; Long inId = ins.isEmpty() ? null : ins.getFirst().getId(); Object[][] samples = { {"완료", "SKT", "인터넷,TV", "김*근", "010-****-3566", "-700000", "50000", "D2"}, {"대기", "KT", "인터넷", "박*지", "010-****-1122", "0", "30000", "늘푸른통신"}, {"완료", "LGU+", "TV,집전화", "이*수", "010-****-5678", "-1000000", "80000", "스마트모바일"}, {"완료", "SKT", "홈IOT,기타", "최*아", "010-****-7788", "-200000", "20000", "블루폰"}, {"대기", "KT", "소호,원스톱", "정*호", "010-****-9900", "0", "15000", "메인텔레콤"}, {"완료", "SKT", "인터넷전화,신용카드", "홍*동", "010-****-2222", "-350000", "40000", "늘붉은통신"}, {"완료", "LGU+", "후결합,재약정", "윤*희", "010-****-3344", "-150000", "25000", "D1"}, {"대기", "KT", "렌탈", "한*진", "010-****-4455", "0", "10000", "늘푸른통신"}, }; for (int i = 0; i < samples.length; i++) { Object[] s = samples[i]; HomeSale h = new HomeSale(); h.setGroupId("demo"); h.setOutcompanyId(shops.get(i % shops.size()).getId()); h.setIncompanyId(inId); h.setStatus(String.valueOf(s[0])); h.setTelecom(String.valueOf(s[1])); h.setProducts(String.valueOf(s[2])); h.setCustomerName(String.valueOf(s[3])); h.setPhone(String.valueOf(s[4])); h.setSettleAmount(new BigDecimal(String.valueOf(s[5]))); h.setMargin(new BigDecimal(String.valueOf(s[6]))); h.setOutcompanyName(String.valueOf(s[7])); h.setOutCategory("판매점"); h.setEmployee("demo"); h.setInstallDate(LocalDate.now().minusDays(i)); h.setReceiptDate(LocalDate.now().minusDays(i + 1)); h.setMissingDocs("관계없음"); h.setExtraPolicy(BigDecimal.ZERO); h.setAddress("서울시 강남구"); em.persist(h); } } private void seedCareHomesIfEmpty() { if (em.createQuery("select count(p) from HomesProduct p where p.groupId='demo'", Long.class).getSingleResult() == 0) { Object[][] products = { {"INTERNET", "인터넷", "KT", "안심 인터넷 베이직 와이드", null, 36, "80000", 3}, {"INTERNET", "인터넷", "KT", "인터넷 슬림", null, 36, "50000", 1}, {"INTERNET", "인터넷", "KT", "기가인터넷 500M", null, 36, "80000", 0}, {"INTERNET", "인터넷", "KT", "기가인터넷 1G", null, 36, "90000", 2}, {"INTERNET", "인터넷", "KT", "인터넷 베이직 와이파이", null, 36, "60000", 1}, {"INTERNET", "인터넷", "KT", "인터넷 에센스", null, 36, "70000", 0}, {"INTERNET", "인터넷", "KT", "인터넷 베이직", null, 36, "55000", 0}, {"INTERNET", "인터넷", "KT", "인터넷 프리미엄", null, 36, "100000", 3}, {"INTERNET", "인터넷", "SKB", "B tv 인터넷", null, 36, "75000", 1}, {"INTERNET", "인터넷", "LGU+", "U+ 인터넷", null, 36, "70000", 0}, {"INTERNET", "TV", "KT", "올레tv 베이직", null, 36, "30000", 1}, {"INTERNET", "TV", "KT", "올레tv 슬림", null, 36, "25000", 0}, {"INTERNET", "TV", "KT", "지니 TV 프리미엄", null, 36, "40000", 2}, {"INTERNET", "전화", "KT", "집전화 기본", null, 24, "10000", 0}, {"INTERNET", "전화", "KT", "집전화 스마트", null, 24, "15000", 1}, {"INTERNET", "와이파이", "KT", "와이파이 공유기", null, 24, "15000", 0}, {"INTERNET", "와이파이", "SKB", "와이파이 메시", null, 24, "20000", 1}, {"INTERNET", "스마트홈", "LGU+", "스마트홈 패키지", null, 36, "20000", 0}, {"INTERNET", "스마트홈", "KT", "GiGA IoT 홈캠", null, 36, "25000", 1}, {"INTERNET", "기타", "KT", "기타 부가상품", null, 12, "5000", 0}, {"HOME", "정수기", "청호나이스", "450 (냉온정)", "WP-40C9500M", 60, "120000", 1}, {"HOME", "정수기", "청호나이스", "550 (얼음냉온정)", "WI-55S9500M", 60, "150000", 0}, {"HOME", "정수기", "청호나이스", "Compact (정)", "WP-CP1000", 60, "90000", 0}, {"HOME", "정수기", "청호나이스", "700 (얼음냉온정)", "WI-70S9500M", 60, "180000", 1}, {"HOME", "정수기", "코웨이", "아이콘 정수기", "CHP-7210N", 60, "130000", 0}, {"HOME", "정수기", "코웨이", "냉온정수기", "CHP-5610L", 36, "110000", 1}, {"HOME", "정수기", "SK매직", "스스로살균 정수기", "WPU-A110C", 60, "100000", 0}, {"HOME", "정수기", "LG전자", "퓨리케어 오브제", "WD503AS", 60, "140000", 0}, {"HOME", "공기청정기", "LG전자", "퓨리케어 360", "AS180DWFA", 36, "90000", 0}, {"HOME", "공기청정기", "코웨이", "에어메가", "AP-2021A", 36, "85000", 1}, {"HOME", "공기청정기", "삼성", "비스포크 큐브", "AX60A", 36, "95000", 0}, {"HOME", "비데", "SK매직", "비데 기본형", "BIDET-01", 36, "50000", 0}, {"HOME", "비데", "코웨이", "스스로케어 비데", "BAU-20", 36, "60000", 1}, {"HOME", "비데", "청호나이스", "방수비데", "BA-17", 0, "45000", 0}, {"HOME", "매트리스", "코웨이", "매트리스 퀸", "MT-Q", 60, "150000", 0}, {"HOME", "매트리스", "코웨이", "매트리스 킹", "MT-K", 60, "180000", 1}, {"HOME", "매트리스", "시몬스", "뷰티레스트", "BR-Q", 0, "200000", 0}, {"HOME", "가전", "삼성", "김치냉장고", "RQ33A74", 36, "80000", 0}, {"HOME", "가전", "LG전자", "디오스 냉장고", "M872GBB", 36, "100000", 0}, {"HOME", "가전", "위닉스", "제습기", "DXAE100-KEK", 24, "40000", 1}, {"HOME", "기타", "기타", "렌탈 기타상품", "ETC-01", 12, "30000", 0}, }; for (Object[] s : products) { HomesProduct p = new HomesProduct(); p.setGroupId("demo"); p.setKind(String.valueOf(s[0])); p.setCategory(String.valueOf(s[1])); p.setCompany(String.valueOf(s[2])); p.setName(String.valueOf(s[3])); p.setModel(s[4] == null ? null : String.valueOf(s[4])); p.setMonths((Integer) s[5]); p.setPolicyAmount(new BigDecimal(String.valueOf(s[6]))); p.setPolicyCount((Integer) s[7]); em.persist(p); } } if (em.createQuery("select count(c) from HomesCustomer c where c.groupId='demo'", Long.class).getSingleResult() == 0) { Object[][] customers = { {"단골", "개인", "임*무", "010-1111-3203", "010-2222-8715", "서울시 강남구", "김사원", LocalDate.of(2024, 4, 26)}, {"단골", "개인", "홍*동", "010-3333-2222", "", "서울시 서초구", "홍길동", LocalDate.of(2024, 4, 26)}, {"단골1", "개인", "박*지", "010-2222-1122", "010-9999-1122", "서울시 마포구", "홍길동", LocalDate.of(2024, 5, 10)}, {"단골2", "사업자", "최*아", "010-4444-7788", "", "인천시 연수구", "김대표", LocalDate.of(2024, 6, 1)}, {"단골3", "개인", "정*민", "010-5555-9900", "010-5555-1111", "부산시 해운대", "홍총괄", LocalDate.of(2024, 7, 15)}, {"분류없음", "개인", "이*수", "010-3333-5678", "", "경기도 성남시", "김대표", LocalDate.of(2024, 8, 20)}, {"단골4", "개인", "김*근", "010-1111-3566", "", "서울시 송파구", "김사원", LocalDate.of(2024, 9, 5)}, }; for (Object[] s : customers) { HomesCustomer c = new HomesCustomer(); c.setGroupId("demo"); c.setGrade(String.valueOf(s[0])); c.setCustomerType(String.valueOf(s[1])); c.setName(String.valueOf(s[2])); c.setPhone(String.valueOf(s[3])); c.setPhoneAlt(String.valueOf(s[4])); c.setAddress(String.valueOf(s[5])); c.setEmployee(String.valueOf(s[6])); c.setRegisteredDate((LocalDate) s[7]); em.persist(c); } } else { for (HomesCustomer c : em.createQuery("select c from HomesCustomer c where c.groupId='demo'", HomesCustomer.class).getResultList()) { if (c.getCustomerType() == null || c.getCustomerType().isBlank()) c.setCustomerType("개인"); if ("일반".equals(c.getGrade())) c.setGrade("분류없음"); if (c.getRegisteredDate() == null && c.getCreatedAt() != null) { c.setRegisteredDate(c.getCreatedAt().atZone(ZoneId.systemDefault()).toLocalDate()); } if (c.getRegisteredDate() == null) c.setRegisteredDate(LocalDate.now().minusDays(30)); } } if (em.createQuery("select count(c) from HomesContract c where c.groupId='demo'", Long.class).getSingleResult() == 0) { Object[][] contracts = { {"INTERNET", "완료", "홍*동", "010-1111-1019", "광랜인터넷 와이파이, B tv All", "30150000", "28000000", "-940000", "SK브로드밴드", "홍길동"}, {"INTERNET", "완료", "김*수", "010-2222-3344", "기가인터넷 500M", "80000", "70000", "10000", "늘푸른통신", "홍길동"}, {"INTERNET", "완료", "이*아", "010-3333-5566", "올레tv 베이직, 집전화 기본", "40000", "35000", "5000", "(주)코웨이", "홍총괄"}, {"INTERNET", "접수", "박*지", "010-2222-1122", "올레tv 베이직", "30000", "25000", "5000", "대박통신", "김대표"}, {"INTERNET", "신청", "이*수", "010-3333-5678", "와이파이 공유기", "15000", "12000", "3000", "스마트홈", "홍길동"}, {"INTERNET", "철회", "최*민", "010-7777-8899", "인터넷 슬림", "50000", "0", "0", "대박통신", "홍총괄"}, {"INTERNET", "완료", "정*희", "010-8888-9900", "기가인터넷 1G", "90000", "80000", "10000", "늘푸른통신", "김대표"}, {"HOME", "완료", "최*아", "010-4444-7788", "냉온정수기", "120000", "100000", "20000", "늘푸른통신", "김대표"}, {"HOME", "접수", "정*민", "010-5555-9900", "공기청정기", "90000", "75000", "15000", "블루홈", "홍길동"}, {"HOME", "철회", "윤*희", "010-6666-1122", "비데 기본형", "50000", "0", "0", "대박통신", "홍총괄"}, }; for (int i = 0; i < contracts.length; i++) { Object[] s = contracts[i]; HomesContract c = new HomesContract(); c.setGroupId("demo"); c.setKind(String.valueOf(s[0])); c.setStatus(String.valueOf(s[1])); c.setCustomerType("개인"); c.setCustomerName(String.valueOf(s[2])); c.setPhone(String.valueOf(s[3])); c.setProducts(String.valueOf(s[4])); c.setPolicySum(new BigDecimal(String.valueOf(s[5]))); c.setSettleAmount(new BigDecimal(String.valueOf(s[6]))); c.setMargin(new BigDecimal(String.valueOf(s[7]))); c.setAgency(String.valueOf(s[8])); c.setEmployee(String.valueOf(s[9])); c.setPayMethod("자동이체"); c.setContractDate(LocalDate.now().minusDays(i * 2L)); c.setInstallDate("완료".equals(s[1]) ? LocalDate.now().minusDays(i) : null); c.setMonths(36); c.setAddress("서울시"); c.setCustomerGrade("분류없음"); c.setNationality("내국인"); em.persist(c); } } if (em.createQuery("select count(b) from HomesBalance b where b.groupId='demo'", Long.class).getSingleResult() == 0) { Object[][] balances = { {"정산차감", "하부점", "늘푸른통신", "서류미비", "-21124", "서류 보완 요청"}, {"정산추가", "직원", "김대표", "추가정책", "30000", null}, {"정산차감", "직원", "김대표", "철회차감", "-10000", "철회 건"}, {"정산추가", "하부점", "대박통신", "프로모션", "15000", null}, {"정산차감", "하부점", "대박통신", "오등록", "-5000", null}, {"정산추가", "직원", "홍길동", "인센티브", "20000", "월 인센티브"}, {"정산차감", "직원", "홍길동", "과지급", "-8000", null}, }; for (int i = 0; i < balances.length; i++) { Object[] s = balances[i]; HomesBalance b = new HomesBalance(); b.setGroupId("demo"); b.setBalanceType(String.valueOf(s[0])); b.setTargetType(String.valueOf(s[1])); b.setTargetName(String.valueOf(s[2])); b.setReason(String.valueOf(s[3])); b.setAmount(new BigDecimal(String.valueOf(s[4]))); b.setMemo(s[5] == null ? null : String.valueOf(s[5])); b.setBaseDate(LocalDate.now().minusDays(i)); if ("하부점".equals(b.getTargetType())) b.setAgency(b.getTargetName()); else b.setCustomerName(b.getTargetName()); em.persist(b); } } else { // 구 데이터(차감/추가) → 원본 라벨로 정규화 + 대상 필드 보강 for (HomesBalance b : em.createQuery("select b from HomesBalance b where b.groupId='demo'", HomesBalance.class).getResultList()) { if ("차감".equals(b.getBalanceType())) b.setBalanceType("정산차감"); if ("추가".equals(b.getBalanceType())) b.setBalanceType("정산추가"); if (b.getTargetType() == null || b.getTargetType().isBlank()) { if (b.getAgency() != null && !b.getAgency().isBlank() && (b.getCustomerName() == null || b.getCustomerName().isBlank() || b.getCustomerName().contains("*"))) { b.setTargetType("하부점"); b.setTargetName(b.getAgency()); } else { b.setTargetType("직원"); b.setTargetName(b.getCustomerName() != null && !b.getCustomerName().isBlank() ? b.getCustomerName() : "김대표"); } } if ("정산차감".equals(b.getBalanceType()) && b.getAmount() != null && b.getAmount().signum() > 0) { b.setAmount(b.getAmount().negate()); } } long balCount = em.createQuery("select count(b) from HomesBalance b where b.groupId='demo'", Long.class).getSingleResult(); if (balCount < 5) { Object[][] extra = { {"정산차감", "하부점", "대박통신", "오등록", "-5000", null}, {"정산추가", "직원", "홍길동", "인센티브", "20000", "월 인센티브"}, {"정산차감", "직원", "홍길동", "과지급", "-8000", null}, {"정산추가", "하부점", "늘푸른통신", "프로모션", "15000", null}, {"정산차감", "직원", "김대표", "철회차감", "-10000", "철회 건"}, }; for (int i = 0; i < extra.length && balCount + i < 7; i++) { Object[] s = extra[i]; HomesBalance b = new HomesBalance(); b.setGroupId("demo"); b.setBalanceType(String.valueOf(s[0])); b.setTargetType(String.valueOf(s[1])); b.setTargetName(String.valueOf(s[2])); b.setReason(String.valueOf(s[3])); b.setAmount(new BigDecimal(String.valueOf(s[4]))); b.setMemo(s[5] == null ? null : String.valueOf(s[5])); b.setBaseDate(LocalDate.now().minusDays(i + 1)); if ("하부점".equals(b.getTargetType())) b.setAgency(b.getTargetName()); else b.setCustomerName(b.getTargetName()); em.persist(b); } } } if (em.createQuery("select count(i) from HomesInvoice i where i.groupId='demo'", Long.class).getSingleResult() == 0) { for (int i = 0; i < 6; i++) { YearMonth ym = YearMonth.now().minusMonths(i); HomesInvoice inv = new HomesInvoice(); inv.setGroupId("demo"); inv.setScope(i % 2 == 0 ? "PUBLISH" : "MY"); inv.setYearMonth(ym.toString()); inv.setEmployee("김대표"); inv.setAgency("늘푸른통신"); inv.setInternetCount(2 + i % 3); inv.setInternetAmount(new BigDecimal(50000 + i * 10000L)); inv.setHomeCount(1 + i % 2); inv.setHomeAmount(new BigDecimal(80000 + i * 5000L)); inv.setBalanceCount(i % 3); inv.setBalanceAmount(new BigDecimal(i % 2 == 0 ? -5000 : 10000)); inv.setContractCount(inv.getInternetCount() + inv.getHomeCount()); inv.setSettleAmount(inv.getInternetAmount().add(inv.getHomeAmount()).add(inv.getBalanceAmount())); inv.setAmount(inv.getSettleAmount()); inv.setIssued(i != 0); inv.setStatus(i == 0 ? "대기" : "발행"); inv.setConsent(i == 0 ? "-" : "대기"); inv.setTaxInvoice(i == 0 ? "-" : "미발행"); inv.setWithdrawStatus(i == 0 ? "-" : "대기"); em.persist(inv); } } else { for (HomesInvoice inv : em.createQuery("select i from HomesInvoice i where i.groupId='demo'", HomesInvoice.class).getResultList()) { if (("발행".equals(inv.getStatus()) || "확정".equals(inv.getStatus())) && !Boolean.TRUE.equals(inv.getIssued())) { inv.setIssued(true); } if (inv.getSettleAmount() == null && inv.getAmount() != null) inv.setSettleAmount(inv.getAmount()); if (inv.getInternetCount() == null && inv.getAmount() != null) { inv.setInternetCount(2); inv.setInternetAmount(inv.getAmount().multiply(new BigDecimal("0.4")).setScale(0, java.math.RoundingMode.HALF_UP)); inv.setHomeCount(1); inv.setHomeAmount(inv.getAmount().multiply(new BigDecimal("0.5")).setScale(0, java.math.RoundingMode.HALF_UP)); inv.setBalanceCount(1); inv.setBalanceAmount(inv.getAmount().subtract(inv.getInternetAmount()).subtract(inv.getHomeAmount())); inv.setContractCount(inv.getInternetCount() + inv.getHomeCount()); } } } if (em.createQuery("select count(p) from HomesPending p where p.groupId='demo'", Long.class).getSingleResult() == 0) { Object[][] pendings = { {"접수", "일반", "설치 상담", "김*근", "010-1111-3566", "김대표", null, null, "14:00", 0, "방문 전 연락 요망"}, {"접수", "약속1", "방문 약속", "박*지", "010-2222-1122", "홍길동", null, null, "10:30", 1, null}, {"해결", "약속2", "계약 설명", "이*수", "010-3333-5678", "홍길동", "김대표", 2, "16:00", 2, "완료 확인"}, {"접수", "일반", "회선 제한 상담", "제한설", "010-7777-8899", "김대표", null, null, "11:00", 6, null}, {"해결", "약속1", "설치 일정 조율", "최*아", "010-4444-7788", "홍총괄", "홍총괄", 3, "15:30", 4, null}, {"접수", "일반", "요금 안내", "정*민", "010-5555-9900", "홍길동", null, null, "09:00", 5, "오전 통화"}, {"접수", "약속2", "해지 상담", "윤*희", "010-6666-1122", "김대표", null, null, "13:20", 7, null}, {"해결", "일반", "AS 접수", "한*솔", "010-8888-3344", "홍길동", "홍길동", 1, "17:00", 8, null}, {"접수", "약속1", "이전설치", "오*진", "010-9999-5566", "김대표", null, null, "12:00", 9, null}, {"접수", "일반", "결합상품 문의", "배*수", "010-1212-3434", "홍총괄", null, null, "14:40", 10, null}, {"해결", "약속2", "약정 연장", "임*영", "010-5656-7878", "홍길동", "김대표", 5, "10:00", 11, null}, {"접수", "일반", "개통 일정", "조*현", "010-9090-1212", "김대표", null, null, "16:30", 12, null}, }; for (Object[] s : pendings) { HomesPending p = new HomesPending(); p.setGroupId("demo"); p.setStatus(String.valueOf(s[0])); p.setPendingType(String.valueOf(s[1])); p.setContents(String.valueOf(s[2])); p.setCustomerName(String.valueOf(s[3])); p.setPhone(String.valueOf(s[4])); p.setReceiveEmployee(String.valueOf(s[5])); p.setEmployee(String.valueOf(s[5])); p.setProcessEmployee(s[6] == null ? null : String.valueOf(s[6])); if (s[7] != null) p.setProcessDate(LocalDate.now().minusDays(((Number) s[7]).longValue())); p.setPendingTime(String.valueOf(s[8])); p.setPendingDate(LocalDate.now().plusDays(((Number) s[9]).longValue())); p.setMemo(s[10] == null ? null : String.valueOf(s[10])); em.persist(p); } } else { for (HomesPending p : em.createQuery("select p from HomesPending p where p.groupId='demo'", HomesPending.class).getResultList()) { if ("예정".equals(p.getStatus())) p.setStatus("접수"); if ("완료".equals(p.getStatus())) p.setStatus("해결"); if ((p.getReceiveEmployee() == null || p.getReceiveEmployee().isBlank()) && p.getEmployee() != null) { p.setReceiveEmployee(p.getEmployee()); } } long cnt = em.createQuery("select count(p) from HomesPending p where p.groupId='demo'", Long.class).getSingleResult(); if (cnt < 8) { Object[][] extra = { {"접수", "일반", "요금 안내", "정*민", "010-5555-9900", "홍길동", 5}, {"해결", "약속1", "설치 일정 조율", "최*아", "010-4444-7788", "홍총괄", 4}, {"접수", "약속2", "해지 상담", "윤*희", "010-6666-1122", "김대표", 7}, {"해결", "일반", "AS 접수", "한*솔", "010-8888-3344", "홍길동", 8}, {"접수", "약속1", "이전설치", "오*진", "010-9999-5566", "김대표", 9}, {"접수", "일반", "결합상품 문의", "배*수", "010-1212-3434", "홍총괄", 10}, {"해결", "약속2", "약정 연장", "임*영", "010-5656-7878", "홍길동", 11}, {"접수", "일반", "개통 일정", "조*현", "010-9090-1212", "김대표", 12}, }; for (int i = 0; i < extra.length && cnt + i < 12; i++) { Object[] s = extra[i]; HomesPending p = new HomesPending(); p.setGroupId("demo"); p.setStatus(String.valueOf(s[0])); p.setPendingType(String.valueOf(s[1])); p.setContents(String.valueOf(s[2])); p.setCustomerName(String.valueOf(s[3])); p.setPhone(String.valueOf(s[4])); p.setReceiveEmployee(String.valueOf(s[5])); p.setEmployee(String.valueOf(s[5])); if ("해결".equals(p.getStatus())) { p.setProcessEmployee(String.valueOf(s[5])); p.setProcessDate(LocalDate.now().minusDays(1)); } p.setPendingTime("10:00"); p.setPendingDate(LocalDate.now().plusDays(((Number) s[6]).longValue())); em.persist(p); } } } if (em.createQuery("select count(b) from HomesBooking b where b.groupId='demo'", Long.class).getSingleResult() == 0) { Object[][] bookings = { {"완료", "이*신", "0000-0000-0000", "인터넷, TV, 전화", "매트리스, 가전", LocalDate.of(2022, 7, 14)}, {"접수", "홍*동", "010-1111-2222", "인터넷, 전화, 스마트홈", "공기청정기, 매트리스, 기타", LocalDate.of(2022, 7, 14)}, {"보류", "김*근", "010-1000-2000", "인터넷, 와이파이", "정수기", LocalDate.now().plusDays(1)}, }; for (Object[] s : bookings) { HomesBooking b = new HomesBooking(); b.setGroupId("demo"); b.setStatus(String.valueOf(s[0])); b.setCustomerName(String.valueOf(s[1])); b.setPhone(String.valueOf(s[2])); b.setInternetProducts(String.valueOf(s[3])); b.setRentalProducts(String.valueOf(s[4])); b.setProducts(s[3] + ", " + s[4]); b.setBookingDate((LocalDate) s[5]); b.setAddress("서울시"); b.setEmployee("홍길동"); em.persist(b); } } else { // 기존 시드에 인터넷/홈렌탈 분리 필드 보강 List existing = em.createQuery( "select b from HomesBooking b where b.groupId='demo'", HomesBooking.class).getResultList(); for (HomesBooking b : existing) { if (b.getInternetProducts() == null || b.getInternetProducts().isBlank()) { String p = b.getProducts() == null ? "" : b.getProducts(); if (p.contains("인터넷") || p.contains("기가") || p.contains("TV") || p.contains("전화") || p.contains("와이파이") || p.contains("스마트")) { List inet = new ArrayList<>(); if (p.contains("인터넷") || p.contains("기가")) inet.add("인터넷"); if (p.contains("TV")) inet.add("TV"); if (p.contains("전화")) inet.add("전화"); if (p.contains("와이파이")) inet.add("와이파이"); if (p.contains("스마트")) inet.add("스마트홈"); if (inet.isEmpty()) inet.add("인터넷"); b.setInternetProducts(String.join(", ", inet)); } if (p.contains("정수기") || p.contains("공기") || p.contains("비데") || p.contains("매트") || p.contains("가전")) { List rent = new ArrayList<>(); if (p.contains("정수기")) rent.add("정수기"); if (p.contains("공기")) rent.add("공기청정기"); if (p.contains("비데")) rent.add("비데"); if (p.contains("매트")) rent.add("매트리스"); if (p.contains("가전")) rent.add("가전"); b.setRentalProducts(String.join(", ", rent)); } if ((b.getInternetProducts() == null || b.getInternetProducts().isBlank()) && (b.getRentalProducts() == null || b.getRentalProducts().isBlank())) { b.setInternetProducts("인터넷"); b.setRentalProducts("기타"); } } if (b.getEmployee() == null || b.getEmployee().isBlank()) b.setEmployee("홍길동"); } } if (em.createQuery("select count(a) from HomesAbook a where a.groupId='demo'", Long.class).getSingleResult() == 0) { Object[][] abooks = { {"입금", "일반", "계약정산", "150000", "홍길동"}, {"출금", "일반", "사무용품", "35000", "홍길동"}, {"입금", "123", "후정산추가", "10000", "홍길동"}, {"카드입금", "일반", "카드매출", "55000", "김대표"}, {"카드출금", "123", "카드수수료", "2200", "홍길동"}, {"출금", "일반", "테스트2", "5000", "홍길동"}, }; for (int i = 0; i < abooks.length; i++) { Object[] s = abooks[i]; HomesAbook a = new HomesAbook(); a.setGroupId("demo"); a.setEntryType(String.valueOf(s[0])); a.setCategory(String.valueOf(s[1])); a.setItem(String.valueOf(s[2])); a.setAmount(new BigDecimal(String.valueOf(s[3]))); a.setEmployee(String.valueOf(s[4])); a.setEntryDate(LocalDate.now().minusDays(i)); a.setMemo(i == 0 ? "데모 시드" : null); em.persist(a); } } else { for (HomesAbook a : em.createQuery("select a from HomesAbook a where a.groupId='demo'", HomesAbook.class).getResultList()) { if ("수입".equals(a.getEntryType())) a.setEntryType("입금"); else if ("지출".equals(a.getEntryType())) a.setEntryType("출금"); String cat = a.getCategory(); boolean knownCat = cat != null && (cat.equals("일반") || cat.equals("123") || cat.startsWith("단골")); if (!knownCat && cat != null && !cat.isBlank()) { if (a.getItem() == null || a.getItem().isBlank()) a.setItem(cat); a.setCategory("일반"); } if ((a.getItem() == null || a.getItem().isBlank()) && a.getAgency() != null && !a.getAgency().isBlank()) { a.setItem(a.getAgency()); } if (a.getCategory() == null || a.getCategory().isBlank()) a.setCategory("일반"); if (a.getEmployee() == null || a.getEmployee().isBlank()) a.setEmployee("홍길동"); } } { Object[][] agencies = { {"(주)코웨이", "", "", "", "", LocalDate.of(2022, 5, 27), true, null}, {"SK브로드밴드", "", "", "", "", LocalDate.of(2022, 5, 27), true, null}, {"테스트", "02-1234-5678", "02-9876-5432", "홍길동", "010-1234-5678", LocalDate.of(2022, 4, 13), true, "데모 거래처"}, }; java.util.Set keep = new java.util.HashSet<>(); for (Object[] s : agencies) keep.add(String.valueOf(s[0])); for (HomesAgency old : em.createQuery("select a from HomesAgency a where a.groupId='demo'", HomesAgency.class).getResultList()) { if (!keep.contains(old.getName())) em.remove(old); } em.flush(); for (Object[] s : agencies) { String name = String.valueOf(s[0]); List found = em.createQuery( "select a from HomesAgency a where a.groupId='demo' and a.name=:name", HomesAgency.class) .setParameter("name", name).getResultList(); HomesAgency a = found.isEmpty() ? new HomesAgency() : found.getFirst(); a.setGroupId("demo"); a.setName(name); a.setPhone(String.valueOf(s[1])); a.setFax(String.valueOf(s[2])); a.setManagerName(String.valueOf(s[3])); a.setMobile(String.valueOf(s[4])); a.setRegisteredDate((LocalDate) s[5]); a.setActive((Boolean) s[6]); a.setAgencyType("대리점"); a.setAddress(null); a.setMemo(s[7] == null ? null : String.valueOf(s[7])); if (found.isEmpty()) em.persist(a); } } // 상부점/하부점관리 원본은 빈 목록 for (HomesPartner p : em.createQuery("select p from HomesPartner p where p.groupId='demo'", HomesPartner.class).getResultList()) { em.remove(p); } em.flush(); { // 공지사항 원본 샘플 1건 String title = "비즈케어 홈즈를 베타오픈 하였습니다."; List all = em.createQuery("select n from HomesNotice n where n.groupId='demo'", HomesNotice.class).getResultList(); HomesNotice target = all.stream().filter(n -> title.equals(n.getTitle())).findFirst().orElse(null); if (target == null) { for (HomesNotice old : all) em.remove(old); em.flush(); target = new HomesNotice(); target.setGroupId("demo"); target.setTitle(title); target.setAuthorName("비즈케어"); target.setContents("비즈케어 홈즈를 베타오픈 하였습니다.\n\n이용에 참고 부탁드립니다."); target.setViews(10); em.persist(target); em.flush(); } else { target.setViews(target.getViews() == null || target.getViews() < 10 ? 10 : target.getViews()); if (target.getContents() == null || target.getContents().isBlank()) { target.setContents("비즈케어 홈즈를 베타오픈 하였습니다.\n\n이용에 참고 부탁드립니다."); } } Instant at = LocalDate.of(2022, 11, 22).atStartOfDay(ZoneId.of("Asia/Seoul")).toInstant(); target.setCreatedAt(at); target.setUpdatedAt(at); // 원본과 다른 데모 공지 제거 for (HomesNotice n : em.createQuery("select n from HomesNotice n where n.groupId='demo'", HomesNotice.class).getResultList()) { if (!title.equals(n.getTitle())) em.remove(n); } } // 사용문의 원본은 빈 목록 for (HomesQuestion q : em.createQuery("select q from HomesQuestion q where q.groupId='demo'", HomesQuestion.class).getResultList()) { em.remove(q); } em.flush(); // 사내게시판 원본은 빈 목록 for (HomesBbs b : em.createQuery("select b from HomesBbs b where b.groupId='demo'", HomesBbs.class).getResultList()) { em.remove(b); } em.flush(); if (em.createQuery("select count(r) from HomesReception r where r.groupId='demo'", Long.class).getSingleResult() == 0) { Object[][] rows = { {LocalDateTime.of(2026, 7, 10, 9, 12), "김상담", "강남점", "KT", "상품권", "인터넷", "기가인터넷 1G", "홍*동", "010-1111-2222", "서울", "1.접수완료", "SAMPLE-00001", "서울입고", "박처리", "접수", "현금", "100000", "정산대기", null, null, "미지급", "본사", "36개월", "02-1234-5678"}, {LocalDateTime.of(2026, 7, 10, 10, 30), "이상담", "서초점", "SKB", "가전", "TV", "B tv 프리미엄", "김*수", "010-2222-3333", "경기", "2.고객통화", "SAMPLE-00002", "", "최처리", "통화완료", "계좌", "80000", "정산대기", null, null, "지급대기", "영업점", "24개월", ""}, {LocalDateTime.of(2026, 7, 9, 14, 5), "김상담", "강남점", "LGU+", "상품권", "인터넷", "U+ 인터넷", "박*지", "010-3333-4444", "인천", "4.개통완료", "SAMPLE-00003", "서울입고", "박처리", "개통", "현금", "120000", "정산대기", LocalDate.of(2026, 7, 9), null, "미지급", "본사", "36개월", "032-555-1212"}, {LocalDateTime.of(2026, 7, 8, 11, 20), "정상담", "송파점", "KT", "캐시백", "정수기", "청호 450", "최*아", "010-4444-5555", "서울", "4.개통완료", "SAMPLE-00004", "물류완료", "이처리", "설치완료", "카드", "150000", "정산완료", LocalDate.of(2026, 7, 8), LocalDate.of(2026, 7, 10), "지급완료", "본사", "60개월", ""}, {LocalDateTime.of(2026, 7, 8, 16, 40), "이상담", "서초점", "SKT", "상품권", "전화", "집전화 스마트", "정*민", "010-5555-6666", "부산", "3.서류검토", "SAMPLE-00005", "", "최처리", "서류요청", "현금", "15000", "정산대기", null, null, "미지급", "본사", "24개월", ""}, {LocalDateTime.of(2026, 7, 7, 9, 50), "김상담", "강남점", "KT", "가전", "공기청정기", "퓨리케어 360", "이*수", "010-6666-7777", "서울", "5.사은품지급", "SAMPLE-00006", "서울입고", "박처리", "사은품발송", "계좌", "90000", "정산대기", LocalDate.of(2026, 7, 6), LocalDate.of(2026, 7, 7), "지급완료", "본사", "36개월", ""}, {LocalDateTime.of(2026, 7, 6, 13, 15), "정상담", "송파점", "SKB", "상품권", "인터넷", "B tv 인터넷", "윤*희", "010-7777-8888", "경기", "6.정산완료", "SAMPLE-00007", "완료", "이처리", "정산", "현금", "75000", "정산완료", LocalDate.of(2026, 7, 5), LocalDate.of(2026, 7, 6), "지급완료", "영업점", "36개월", ""}, {LocalDateTime.of(2026, 7, 5, 15, 0), "이상담", "서초점", "LGU+", "캐시백", "와이파이", "와이파이 메시", "한*진", "010-8888-9999", "대전", "9.취소", "SAMPLE-00008", "", "최처리", "고객취소", "", "0", "회수대기", null, null, "반송", "", "12개월", ""}, {LocalDateTime.of(2026, 7, 11, 8, 45), "김상담", "강남점", "KT", "상품권", "인터넷", "안심 인터넷 베이직", "오*라", "010-1212-3434", "서울", "1.접수완료", "SAMPLE-00009", "", "박처리", "접수", "현금", "60000", "정산대기", null, null, "미지급", "본사", "36개월", ""}, {LocalDateTime.of(2026, 7, 11, 11, 10), "정상담", "송파점", "SKB", "가전", "비데", "스스로케어 비데", "서*호", "010-5656-7878", "경남", "2.고객통화", "SAMPLE-00010", "물류대기", "이처리", "통화예약", "계좌", "60000", "정산대기", null, null, "지급대기", "본사", "36개월", ""}, }; for (Object[] s : rows) { HomesReception r = new HomesReception(); r.setGroupId("demo"); r.setOrderDate((LocalDateTime) s[0]); r.setCounselor(String.valueOf(s[1])); r.setBranch(String.valueOf(s[2])); r.setCarrier(String.valueOf(s[3])); r.setGiftCategory(String.valueOf(s[4])); r.setProductCategory(String.valueOf(s[5])); r.setProductName(String.valueOf(s[6])); r.setCustomerName(String.valueOf(s[7])); r.setPhone(String.valueOf(s[8])); r.setRegion(String.valueOf(s[9])); r.setProgressStatus(String.valueOf(s[10])); r.setOrderNumber(String.valueOf(s[11])); r.setInboundInfo(String.valueOf(s[12])); r.setProcessor(String.valueOf(s[13])); r.setDetailProgress(String.valueOf(s[14])); r.setPaymentType(String.valueOf(s[15])); r.setAmount(new BigDecimal(String.valueOf(s[16]))); r.setSettleStatus(String.valueOf(s[17])); r.setOpenDate(s[18] == null ? null : (LocalDate) s[18]); r.setGiftDate(s[19] == null ? null : (LocalDate) s[19]); r.setGiftStatus(String.valueOf(s[20])); r.setGiftPlace(String.valueOf(s[21])); r.setAgreementName(String.valueOf(s[22])); r.setContractNumber(String.valueOf(s[23])); r.setBranchGroup("본사그룹"); r.setPostIt(""); r.setMemo("데모 접수 데이터"); em.persist(r); } em.flush(); for (HomesReception r : em.createQuery("select r from HomesReception r where r.groupId='demo'", HomesReception.class).getResultList()) { HomesReceptionProgressLog log = new HomesReceptionProgressLog(); log.setGroupId("demo"); log.setReceptionId(r.getId()); log.setStatus(r.getProgressStatus()); log.setMemo("초기 등록"); log.setAuthorName(r.getCounselor()); log.setLoggedAt(r.getOrderDate() == null ? LocalDateTime.now() : r.getOrderDate()); em.persist(log); } } seedReceptionIspsIfEmpty(); enrichReceptionProgressFields(); if (em.createQuery("select count(l) from HomesLog l where l.groupId='demo'", Long.class).getSingleResult() == 0) { Object[][] logs = { {"PRODUCT", "인터넷상품-등록", "인터넷상품 [센트릭스] 등록하였습니다.", "홍길동", 2}, {"PRODUCT", "인터넷상품-정책-등록", "인터넷상품 정책 [36개월] 등록하였습니다.", "홍길동", 3}, {"PRODUCT", "인터넷상품-수정", "인터넷상품 [기가인터넷 500M] 수정하였습니다.", "홍총괄", 5}, {"PRODUCT", "홈렌탈상품-등록", "홈렌탈상품 [450 (냉온정)] 등록하였습니다.", "홍길동", 8}, {"PRODUCT", "홈렌탈상품-정책-등록", "홈렌탈상품 정책 [60개월] 등록하였습니다.", "홍총괄", 10}, {"PRODUCT", "인터넷상품-삭제", "인터넷상품 [인터넷 슬림] 삭제하였습니다.", "김대표", 12}, {"PRODUCT", "기본상품-동기화", "인터넷상품 기본상품 16건을 동기화하였습니다.", "김대표", 20}, {"CONTRACT", "인터넷접수-등록", "인터넷접수 [홍*동] 등록하였습니다.", "홍길동", 1}, {"CONTRACT", "인터넷접수-상태", "인터넷접수 [홍*동] 완료(으)로 변경하였습니다.", "홍길동", 2}, {"CONTRACT", "인터넷접수-수정", "인터넷접수 [김*수] 수정하였습니다.", "홍총괄", 4}, {"CONTRACT", "홈렌탈접수-등록", "홈렌탈접수 [최*아] 등록하였습니다.", "김대표", 6}, {"CONTRACT", "홈렌탈접수-상태", "홈렌탈접수 [윤*희] 철회(으)로 변경하였습니다.", "홍총괄", 9}, {"CUSTOMER", "고객-등록", "고객 [위*우] 등록하였습니다.", "홍길동", 1}, {"CUSTOMER", "고객-수정", "고객 [홍*동] 수정하였습니다.", "홍길동", 2}, {"CUSTOMER", "고객-분류", "고객 [홍*동] 분류수정하였습니다.", "홍길동", 3}, {"CUSTOMER", "고객-등록", "계약고객 [홍*동] 하부점(인터넷)에서 등록하였습니다.", "홍길동", 4}, {"CUSTOMER", "고객-등록", "고객 [김*근] 등록하였습니다.", "김대표", 5}, {"CUSTOMER", "고객-삭제", "고객 [이*수] 삭제하였습니다.", "홍길동", 8}, {"BOOKING", "예약-상태", "예약 [이*신] 완료(으)로 상태변경하였습니다.", "홍길동", 1}, {"BOOKING", "예약-수정", "예약 [홍*동] 수정하였습니다.", "홍길동", 2}, {"BOOKING", "예약-등록", "예약 [이*신] 등록하였습니다.", "홍길동", 3}, {"BOOKING", "예약-등록", "예약 [홍*동] 등록하였습니다.", "홍길동", 4}, {"BOOKING", "예약-상태", "예약 [김*근] 보류(으)로 상태변경하였습니다.", "홍길동", 7}, {"ABOOKS", "간편장부-등록", "간편장부 [입금/일반] 등록하였습니다.", "홍길동", 1}, {"ABOOKS", "간편장부-수정", "간편장부 [출금/일반] 수정하였습니다.", "홍길동", 2}, {"ABOOKS", "간편장부-삭제", "간편장부 [카드출금/123] 삭제하였습니다.", "홍길동", 3}, {"ABOOKS", "간편장부-등록", "간편장부 [카드입금/일반] 등록하였습니다.", "김대표", 5}, {"ABOOKS", "간편장부-등록", "간편장부 [출금/123] 등록하였습니다.", "홍길동", 8}, {"INVOICE", "정산서-발행", "정산서 [김사원] 발행하였습니다.", "홍길동", 1}, {"INVOICE", "정산서-발행", "정산서 [김대표] 발행하였습니다.", "김대표", 3}, {"INVOICE", "정산서-재발행", "정산서 [홍길동] 재발행하였습니다.", "홍총괄", 5}, {"INVOICE", "정산서-삭제", "정산서 [이총괄] 삭제하였습니다.", "김대표", 8}, {"INVOICE", "정산서-발행", "정산서 [박재고] 발행하였습니다.", "홍길동", 12}, {"INVOICE", "정산서-수정", "정산서 [김대표] 수정하였습니다.", "김대표", 15}, {"INVOICE", "정산서-삭제", "정산서 [윤영업] 삭제하였습니다.", "홍길동", 20}, }; for (Object[] s : logs) { HomesLog l = new HomesLog(); l.setGroupId("demo"); l.setDomain(String.valueOf(s[0])); l.setAction(String.valueOf(s[1])); l.setContent(String.valueOf(s[2])); l.setStaff(String.valueOf(s[3])); l.setProcessedAt(LocalDateTime.now().minusHours(((Number) s[4]).longValue())); em.persist(l); } } else { // 정산서이력 데모 보강 long invoiceLogs = em.createQuery("select count(l) from HomesLog l where l.groupId='demo' and l.domain='INVOICE'", Long.class).getSingleResult(); if (invoiceLogs < 5) { Object[][] extra = { {"정산서-발행", "정산서 [김사원] 발행하였습니다.", "홍길동", 2}, {"정산서-발행", "정산서 [김대표] 발행하였습니다.", "김대표", 6}, {"정산서-재발행", "정산서 [홍길동] 재발행하였습니다.", "홍총괄", 10}, {"정산서-삭제", "정산서 [이총괄] 삭제하였습니다.", "김대표", 14}, {"정산서-발행", "정산서 [박재고] 발행하였습니다.", "홍길동", 18}, {"정산서-수정", "정산서 [김대표] 수정하였습니다.", "김대표", 22}, {"정산서-삭제", "정산서 [윤영업] 삭제하였습니다.", "홍길동", 28}, }; for (Object[] s : extra) { HomesLog l = new HomesLog(); l.setGroupId("demo"); l.setDomain("INVOICE"); l.setAction(String.valueOf(s[0])); l.setContent(String.valueOf(s[1])); l.setStaff(String.valueOf(s[2])); l.setProcessedAt(LocalDateTime.now().minusHours(((Number) s[3]).longValue())); em.persist(l); } } // 구 라벨 정규화 for (HomesLog l : em.createQuery("select l from HomesLog l where l.groupId='demo' and l.domain='INVOICE'", HomesLog.class).getResultList()) { if ("발행".equals(l.getAction())) { l.setAction("정산서-발행"); if (l.getContent() != null && !l.getContent().contains("정산서 [")) { l.setContent("정산서 [" + l.getContent().replace(" 정산서를 발행하였습니다.", "").trim() + "] 발행하였습니다."); } } else if ("등록".equals(l.getAction())) { l.setAction("정산서-등록"); if (l.getContent() != null && !l.getContent().startsWith("정산서 [")) { String[] parts = l.getContent().split(" ", 2); String emp = parts.length > 1 ? parts[1] : parts[0]; l.setContent("정산서 [" + emp + "] 등록하였습니다."); } } else if ("삭제".equals(l.getAction())) { l.setAction("정산서-삭제"); } } // 예약이력 데모 보강 long bookingLogs = em.createQuery("select count(l) from HomesLog l where l.groupId='demo' and l.domain='BOOKING'", Long.class).getSingleResult(); if (bookingLogs < 5) { Object[][] extra = { {"예약-상태", "예약 [이*신] 완료(으)로 상태변경하였습니다.", "홍길동", 1}, {"예약-수정", "예약 [홍*동] 수정하였습니다.", "홍길동", 2}, {"예약-등록", "예약 [이*신] 등록하였습니다.", "홍길동", 3}, {"예약-등록", "예약 [홍*동] 등록하였습니다.", "홍길동", 4}, {"예약-상태", "예약 [김*근] 보류(으)로 상태변경하였습니다.", "홍길동", 7}, }; for (Object[] s : extra) { HomesLog l = new HomesLog(); l.setGroupId("demo"); l.setDomain("BOOKING"); l.setAction(String.valueOf(s[0])); l.setContent(String.valueOf(s[1])); l.setStaff(String.valueOf(s[2])); l.setProcessedAt(LocalDateTime.now().minusHours(((Number) s[3]).longValue())); em.persist(l); } } for (HomesLog l : em.createQuery("select l from HomesLog l where l.groupId='demo' and l.domain='BOOKING'", HomesLog.class).getResultList()) { if ("등록".equals(l.getAction())) { l.setAction("예약-등록"); if (l.getContent() != null && !l.getContent().startsWith("예약 [")) { l.setContent("예약 [" + l.getContent().trim() + "] 등록하였습니다."); } } else if ("수정".equals(l.getAction())) { l.setAction("예약-수정"); } else if ("삭제".equals(l.getAction())) { l.setAction("예약-삭제"); } else if ("상태".equals(l.getAction())) { l.setAction("예약-상태"); } } // 고객이력 데모 보강 long customerLogs = em.createQuery("select count(l) from HomesLog l where l.groupId='demo' and l.domain='CUSTOMER'", Long.class).getSingleResult(); if (customerLogs < 5) { Object[][] extra = { {"고객-등록", "고객 [위*우] 등록하였습니다.", "홍길동", 1}, {"고객-수정", "고객 [홍*동] 수정하였습니다.", "홍길동", 2}, {"고객-분류", "고객 [홍*동] 분류수정하였습니다.", "홍길동", 3}, {"고객-등록", "계약고객 [홍*동] 하부점(인터넷)에서 등록하였습니다.", "홍길동", 4}, {"고객-등록", "고객 [김*근] 등록하였습니다.", "김대표", 5}, {"고객-삭제", "고객 [이*수] 삭제하였습니다.", "홍길동", 8}, }; for (Object[] s : extra) { HomesLog l = new HomesLog(); l.setGroupId("demo"); l.setDomain("CUSTOMER"); l.setAction(String.valueOf(s[0])); l.setContent(String.valueOf(s[1])); l.setStaff(String.valueOf(s[2])); l.setProcessedAt(LocalDateTime.now().minusHours(((Number) s[3]).longValue())); em.persist(l); } } for (HomesLog l : em.createQuery("select l from HomesLog l where l.groupId='demo' and l.domain='CUSTOMER'", HomesLog.class).getResultList()) { if ("등록".equals(l.getAction())) { l.setAction("고객-등록"); if (l.getContent() != null && !l.getContent().startsWith("고객 [") && !l.getContent().startsWith("계약고객 [")) { l.setContent("고객 [" + l.getContent().trim() + "] 등록하였습니다."); } } else if ("수정".equals(l.getAction())) { l.setAction("고객-수정"); if (l.getContent() != null && !l.getContent().startsWith("고객 [")) { l.setContent("고객 [" + l.getContent().trim() + "] 수정하였습니다."); } } else if ("삭제".equals(l.getAction())) { l.setAction("고객-삭제"); } else if ("분류".equals(l.getAction()) || "고객-분류변경".equals(l.getAction())) { l.setAction("고객-분류"); } } // 장부이력 데모 보강 long abookLogs = em.createQuery("select count(l) from HomesLog l where l.groupId='demo' and l.domain='ABOOKS'", Long.class).getSingleResult(); if (abookLogs < 5) { Object[][] extra = { {"간편장부-등록", "간편장부 [입금/일반] 등록하였습니다.", "홍길동", 1}, {"간편장부-수정", "간편장부 [출금/일반] 수정하였습니다.", "홍길동", 2}, {"간편장부-삭제", "간편장부 [카드출금/123] 삭제하였습니다.", "홍길동", 3}, {"간편장부-등록", "간편장부 [카드입금/일반] 등록하였습니다.", "김대표", 5}, {"간편장부-등록", "간편장부 [출금/123] 등록하였습니다.", "홍길동", 8}, {"간편장부-수정", "간편장부 [입금/일반] 수정하였습니다.", "홍길동", 12}, }; for (Object[] s : extra) { HomesLog l = new HomesLog(); l.setGroupId("demo"); l.setDomain("ABOOKS"); l.setAction(String.valueOf(s[0])); l.setContent(String.valueOf(s[1])); l.setStaff(String.valueOf(s[2])); l.setProcessedAt(LocalDateTime.now().minusHours(((Number) s[3]).longValue())); em.persist(l); } } for (HomesLog l : em.createQuery("select l from HomesLog l where l.groupId='demo' and l.domain='ABOOKS'", HomesLog.class).getResultList()) { if ("등록".equals(l.getAction()) || "장부-등록".equals(l.getAction())) { l.setAction("간편장부-등록"); if (l.getContent() != null && !l.getContent().startsWith("간편장부 [")) { l.setContent("간편장부 [입금/일반] 등록하였습니다."); } } else if ("수정".equals(l.getAction()) || "장부-수정".equals(l.getAction())) { l.setAction("간편장부-수정"); if (l.getContent() != null && !l.getContent().startsWith("간편장부 [")) { l.setContent("간편장부 [입금/일반] 수정하였습니다."); } } else if ("삭제".equals(l.getAction()) || "장부-삭제".equals(l.getAction())) { l.setAction("간편장부-삭제"); if (l.getContent() != null && !l.getContent().startsWith("간편장부 [")) { l.setContent("간편장부 [출금/일반] 삭제하였습니다."); } } } } ensurePendingDemoLogs(); } /** 일정이력 원본 샘플(목록 48건) */ private void ensurePendingDemoLogs() { for (HomesLog l : em.createQuery("select l from HomesLog l where l.groupId='demo' and l.domain='PENDING'", HomesLog.class).getResultList()) { if ("등록".equals(l.getAction())) { l.setAction("약속-등록"); if (l.getContent() == null || !l.getContent().startsWith("약속 [")) { String name = l.getContent() == null || l.getContent().isBlank() ? "일반" : l.getContent().trim(); l.setContent("약속 [" + name + "] 등록하였습니다."); } } else if ("수정".equals(l.getAction())) { l.setAction("약속-수정"); } else if ("삭제".equals(l.getAction())) { l.setAction("약속-삭제"); } else if ("처리".equals(l.getAction()) || "약속-처리".equals(l.getAction())) { l.setAction("약속-해결"); if (l.getContent() != null && l.getContent().contains("해결 처리")) { l.setContent(l.getContent().replace("해결 처리하였습니다.", "해결완료하였습니다.")); } else if (l.getContent() == null || !l.getContent().startsWith("약속 [")) { l.setContent("약속 [일반] 해결완료하였습니다."); } } } em.flush(); long pendingLogs = em.createQuery("select count(l) from HomesLog l where l.groupId='demo' and l.domain='PENDING'", Long.class).getSingleResult(); if (pendingLogs >= 40) return; for (HomesLog old : em.createQuery("select l from HomesLog l where l.groupId='demo' and l.domain='PENDING'", HomesLog.class).getResultList()) { em.remove(old); } em.flush(); String[] types = {"일반", "약속1", "약속2"}; LocalDateTime base = LocalDateTime.of(2024, 4, 1, 19, 49); for (int i = 0; i < 48; i++) { String type = types[i % types.length]; HomesLog l = new HomesLog(); l.setGroupId("demo"); l.setDomain("PENDING"); if (i % 3 == 1) { l.setAction("약속-해결"); l.setContent("약속 [" + type + "] 해결완료하였습니다."); } else if (i % 9 == 0) { l.setAction("약속-수정"); l.setContent("약속 [" + type + "] 수정하였습니다."); } else if (i % 13 == 0) { l.setAction("약속-삭제"); l.setContent("약속 [" + type + "] 삭제하였습니다."); } else { l.setAction("약속-등록"); l.setContent("약속 [" + type + "] 등록하였습니다."); } l.setStaff("홍길동"); l.setProcessedAt(base.minusMinutes(i * 7L)); em.persist(l); } } private void seedUnitCostsIfEmpty() { Long count = em.createQuery("select count(t) from UnitCostTable t where t.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List ins = em.createQuery("select c from Company c where c.groupId='demo' and c.type='IN'", Company.class).getResultList(); Object[][] samples = { {"SKT", "SKT", "정책202103_테스트", 4, 11, 14, 2, null, null, null, 1, "표준"}, {"KT", "KT", "KT기본정책", 2, 5, 7, 1, null, null, null, 1, "공시/선택구분"}, {"LGU+", "LGT", "LG물류정책", 1, 3, null, null, null, null, null, 0, "표준"}, {"SKT", "SKT2", "SKT2테스트", 3, 2, 1, null, null, null, null, 1, "표준"}, {"LGU+", "LG물류", "LG물류", 2, null, null, null, null, null, null, 0, "표준"}, {"KT", "KT", "선택약정표", 5, 4, 3, 2, 1, null, null, 1, "공시/선택구분"}, }; for (Object[] s : samples) { UnitCostTable t = new UnitCostTable(); t.setGroupId("demo"); t.setTelecom(String.valueOf(s[0])); t.setIncompanyName(String.valueOf(s[1])); if (!ins.isEmpty()) t.setIncompanyId(ins.getFirst().getId()); t.setMemo(String.valueOf(s[2])); t.setPlanGroupA((Integer) s[3]); t.setPlanGroupB((Integer) s[4]); t.setPlanGroupC((Integer) s[5]); t.setPlanGroupD((Integer) s[6]); t.setPlanGroupE((Integer) s[7]); t.setPlanGroupF((Integer) s[8]); t.setPlanGroupG((Integer) s[9]); t.setPolicyCount((Integer) s[10]); t.setCategory(String.valueOf(s[11])); em.persist(t); em.flush(); if ((Integer) s[10] > 0) { UnitCostPolicy p = new UnitCostPolicy(); p.setGroupId("demo"); p.setUnitCostId(t.getId()); p.setPlanGroup("A"); p.setModel("SM-"); p.setPlanName("5GX 프라임"); p.setAmount(new BigDecimal("100000")); em.persist(p); } } } private void seedOpenAdjustFields() { List opens = em.createQuery("select o from OpenRecord o where o.groupId='demo'", OpenRecord.class).getResultList(); int i = 0; for (OpenRecord o : opens) { if (o.getDecltype() == null) o.setDecltype(i % 2 == 0 ? "단말할인" : "요금할인"); if (o.getBasicprice1() == null) o.setBasicprice1(new BigDecimal("100000")); if (o.getBasicprice2() == null) o.setBasicprice2(new BigDecimal("50000")); if (o.getBasicprice3() == null) o.setBasicprice3(new BigDecimal("30000")); i++; } } private void seedBalancesIfEmpty() { Long count = em.createQuery("select count(b) from AfterBalance b where b.groupId='demo'", Long.class).getSingleResult(); if (count > 0) return; List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); List ins = em.createQuery("select c from Company c where c.groupId='demo' and c.type='IN'", Company.class).getResultList(); if (shops.isEmpty()) return; Long inId = ins.isEmpty() ? null : ins.getFirst().getId(); Object[][] samples = { {"정산차감", "그레이드 누락", "20000", "주*라", "010-****-3566", "D2"}, {"정산추가", "택배비", "-100000", "남*섭", "010-****-1122", "늘푸른통신"}, {"홈상품차감", "부가서비스 해지", "30000", "김*철", "010-****-5678", "늘붉은통신"}, {"유심차감", "유심비 미수", "7700", "이*수", "010-****-1234", "스마트모바일"}, {"정산추가", "테스트", "-3000", "박*영", "010-****-9876", "블루폰"}, {"정산차감", "악세사리", "15000", "홍*동", "010-****-2222", "메인텔레콤"}, {"정산차감", "서류미비 차감", "50000", "최*아", "010-****-7788", "늘푸른통신"}, {"정산추가", "정책 보정", "-20000", "정*호", "010-****-9900", "D1"}, }; for (int i = 0; i < samples.length; i++) { Object[] s = samples[i]; AfterBalance b = new AfterBalance(); b.setGroupId("demo"); b.setOutcompanyId(shops.get(i % shops.size()).getId()); b.setIncompanyId(inId); b.setOutcompanyName(String.valueOf(s[5])); b.setGubun(String.valueOf(s[0])); b.setReason(String.valueOf(s[1])); b.setAmount(new BigDecimal(String.valueOf(s[2]))); b.setCustomerName(String.valueOf(s[3])); b.setOpenphone(String.valueOf(s[4])); b.setTelecom(i % 3 == 0 ? "SKT" : (i % 3 == 1 ? "KT" : "LGU+")); b.setOutCategory("판매점"); b.setOpendate(LocalDate.now().minusDays(20 + i * 5)); b.setBasedate(LocalDate.now().minusDays(i * 2)); b.setMemo(i % 3 == 0 ? "확인필요" : null); em.persist(b); } } private void seedReturnsEnrich() { List rows = em.createQuery("select r from UnreturnedPhone r where r.groupId='demo'", UnreturnedPhone.class).getResultList(); List ins = em.createQuery("select c from Company c where c.groupId='demo' and c.type='IN'", Company.class).getResultList(); List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type in ('SHOP','OUT')", Company.class).getResultList(); Long inId = ins.isEmpty() ? null : ins.getFirst().getId(); Long shopId = shops.isEmpty() ? null : shops.getFirst().getId(); for (UnreturnedPhone r : rows) { if (r.getTelecom() == null) r.setTelecom("SKT"); if (r.getReturnStatus() == null) r.setReturnStatus("미반납"); if (r.getIncompanyId() == null) r.setIncompanyId(inId); } if (rows.size() >= 5 || shopId == null) return; String[][] samples = { {"KT", "박*지", "010-****-6595", "미반납", "A125", "50000", "0"}, {"SKT", "홍*동", "010-****-2222", "반납", "sm-g220", "1234", "10000"}, {"LGU+", "김*수", "010-****-3344", "미반납", "SM-S928N", "IMEI9001", "30000"}, {"SKT", "최*아", "010-****-7788", "반납", "A2860", "SN7788", ""}, {"KT", "정*호", "010-****-9900", "미반납", "SM-A546", "A5469900", "15000"}, }; for (int i = 0; i < samples.length; i++) { String[] s = samples[i]; UnreturnedPhone row = new UnreturnedPhone(); row.setGroupId("demo"); row.setOutcompanyId(shopId); row.setIncompanyId(inId); row.setOpendate(LocalDate.now().minusDays(5 + i * 3)); row.setTelecom(s[0]); row.setCustomerName(s[1]); row.setOpenphone(s[2]); row.setReturnStatus(s[3]); row.setModel(s[4]); row.setSerial(s[5]); if (!s[6].isBlank()) row.setDeductAmount(new BigDecimal(s[6])); if ("반납".equals(s[3])) row.setReturndate(LocalDate.now().minusDays(i)); em.persist(row); } } private void seedIndocsEnrich() { List docs = em.createQuery("select d from IncompleteDoc d where d.groupId='demo'", IncompleteDoc.class).getResultList(); List ins = em.createQuery("select c from Company c where c.groupId='demo' and c.type='IN'", Company.class).getResultList(); List shops = em.createQuery("select c from Company c where c.groupId='demo' and c.type='SHOP'", Company.class).getResultList(); Long inId = ins.isEmpty() ? null : ins.getFirst().getId(); Long shopId = shops.isEmpty() ? null : shops.getFirst().getId(); for (IncompleteDoc d : docs) { if (d.getTelecom() == null) d.setTelecom("SKT"); if (d.getStatus() == null) d.setStatus("미비"); if (d.getIncompanyId() == null) d.setIncompanyId(inId); } if (docs.size() >= 3 || shopId == null) return; String[][] samples = { {"KT", "이*수", "010-****-1234", "인감증명서, 가족관계증명서", "50000", "추가서류 미제출"}, {"LGU+", "박*영", "010-****-9876", "위임장", "20000", "대리개통 서류"}, }; for (int i = 0; i < samples.length; i++) { String[] s = samples[i]; IncompleteDoc d = new IncompleteDoc(); d.setGroupId("demo"); d.setOutcompanyId(shopId); d.setIncompanyId(inId); d.setOpendate(LocalDate.now().minusDays(3L + i * 7)); d.setTelecom(s[0]); d.setCustomerName(s[1]); d.setOpenphone(s[2]); d.setMissingDocs(s[3]); d.setDeductAmount(new BigDecimal(s[4])); d.setDeductReason(s[5]); d.setDeadline(LocalDate.now().plusDays(5L - i * 3)); d.setStatus(i == 1 ? "마감임박" : "미비"); em.persist(d); } } private void enrichReceptionProgressFields() { List rows = em.createQuery( "select r from HomesReception r where r.groupId='demo'", HomesReception.class).getResultList(); int i = 0; for (HomesReception r : rows) { if (r.getCustomerType() == null || r.getCustomerType().isBlank()) r.setCustomerType("public"); if (r.getPaymentMethod() == null || r.getPaymentMethod().isBlank()) { String pt = r.getPaymentType(); r.setPaymentMethod("카드".equals(pt) ? "card" : "지로".equals(pt) ? "paper" : "전화납부".equals(pt) ? "telephone" : "transfer"); } if (r.getProductType() == null || r.getProductType().isBlank()) { String cat = r.getProductCategory(); r.setProductType("전화".equals(cat) ? "e02" : "TV".equals(cat) ? "e03" : "렌탈".equals(cat) || (cat != null && (cat.contains("정수") || cat.contains("비데") || cat.contains("공기"))) ? "e04" : "e01"); } if (r.getEmail() == null || r.getEmail().isBlank()) { r.setEmail("sample" + (++i) + "@example.com"); } if (r.getAddress() == null || r.getAddress().isBlank()) { r.setZipcode("06236"); r.setAddress("서울특별시 강남구 테헤란로 " + (10 + i)); r.setAddressDetail((100 + i) + "호"); } if (r.getIdentifyNumber() == null || r.getIdentifyNumber().isBlank()) { r.setIdentifyNumber("900101-1******"); } if (r.getPostIt() == null || r.getPostIt().isBlank()) r.setPostIt("샘플메모" + (i % 50 + 1)); if (r.getBranchPhone() == null || r.getBranchPhone().isBlank()) r.setBranchPhone("1599-2889"); if (r.getTel() == null || r.getTel().isBlank()) r.setTel("02-100" + i); if (r.getGiftSended() == null && r.getGiftDate() != null) r.setGiftSended(r.getGiftDate()); if (r.getGiftCashAmount() == null && r.getAmount() != null && r.getGiftStatus() != null && !"미지급".equals(r.getGiftStatus()) && !"없음".equals(r.getGiftCategory())) { r.setGiftCashAmount(r.getAmount()); } if (r.getIspName() == null || r.getIspName().isBlank()) r.setIspName(r.getCarrier()); if (r.getProcessor() == null || r.getProcessor().isBlank()) r.setProcessor("본사"); } } private void seedReceptionIspsIfEmpty() { if (em.createQuery("select count(i) from HomesReceptionIsp i where i.groupId='demo'", Long.class).getSingleResult() > 0) { return; } Object[][] isps = { {"LG USIM", "LGU+", 1, false}, {"LGU+ 온라인", "LGU+", 2, false}, {"LGU+ (T일반)", "LGU+", 3, false}, {"KT USIM", "KT", 4, false}, {"KT일반 (강북)", "KT", 5, false}, {"KT일반 (강남)", "KT", 6, false}, {"KT일반 (강서)", "KT", 7, false}, {"KT일반 (경남)", "KT", 8, false}, {"KT일반 (경북)", "KT", 9, false}, {"KT일반 (충청)", "KT", 10, false}, {"KT일반 (전라)", "KT", 11, false}, {"SKB USIM", "SKB", 12, false}, {"SKB다이렉트(서울/경기)", "SKB", 13, false}, {"SKB다이렉트(부산/경남)", "SKB", 14, false}, {"SKB다이렉트(대구/경북)", "SKB", 15, false}, {"SKB다이렉트(충청/강원)", "SKB", 16, false}, {"SKB다이렉트(전라/제주)", "SKB", 17, false}, {"SKB POP", "SKB", 18, false}, {"SKT온/한가족(서울/경기)", "SKT", 19, true}, {"SKT온/한가족(부산/경남)", "SKT", 20, true}, {"SKT온/한가족(대구/경북)", "SKT", 21, true}, {"SKT온/한가족(대전/충청/강원)", "SKT", 22, true}, {"SKT온/한가족(전라/제주)", "SKT", 23, true}, {"SK매직", "SK매직", 24, false}, {"LG렌탈", "LG렌탈", 25, false}, {"Skylife(전국)", "Skylife", 26, false}, }; for (Object[] row : isps) { HomesReceptionIsp isp = new HomesReceptionIsp(); isp.setGroupId("demo"); isp.setName(String.valueOf(row[0])); isp.setTelecom(String.valueOf(row[1])); isp.setSeq((Integer) row[2]); isp.setActive(true); isp.setIsSktb((Boolean) row[3]); em.persist(isp); em.flush(); boolean rental = "SK매직".equals(isp.getTelecom()) || "LG렌탈".equals(isp.getTelecom()); String[][] products = rental ? new String[][]{{"e04", isp.getName() + " 기본렌탈"}, {"e04", isp.getName() + " 프리미엄"}} : new String[][]{ {"e01", isp.getTelecom() + " 인터넷 기본"}, {"e01", isp.getTelecom() + " 인터넷 프리미엄"}, {"e03", isp.getTelecom() + " TV"}, {"e02", isp.getTelecom() + " 집전화"}, }; for (String[] p : products) { HomesReceptionIspProduct prod = new HomesReceptionIspProduct(); prod.setGroupId("demo"); prod.setIspId(isp.getId()); prod.setProductType(p[0]); prod.setName(p[1]); prod.setActive(true); em.persist(prod); } for (String agName : List.of("24개월", "36개월", "48개월", "60개월")) { HomesReceptionIspAgreement ag = new HomesReceptionIspAgreement(); ag.setGroupId("demo"); ag.setIspId(isp.getId()); ag.setName(agName); ag.setActive(true); em.persist(ag); } } } private Company company(String type, String name, String manager, String phone) { Company c = new Company(); c.setGroupId("demo"); c.setType(type); c.setName(name); c.setManagerName(manager); c.setPhone(phone); c.setActive(true); em.persist(c); em.flush(); return c; } private Stock stock(String gubun, String telecom, String model, String color, String serial, String state, Long inId, Long outId, String price) { Stock s = new Stock(); s.setGroupId("demo"); s.setGubun(gubun); s.setTelecom(telecom); s.setTelcompany(telecom); s.setModel(model); s.setColor(color); s.setSerial(serial); s.setBarcode(serial); s.setCond("정상"); s.setPay("할부"); s.setState(state); s.setOutcode(state.equals("OUT") || state.equals("OPEN") ? "21" : "10"); s.setIncompanyId(inId); s.setOutcompanyId(outId); s.setIndate(LocalDate.now().minusDays(5)); if (outId != null) s.setOutdate(LocalDate.now().minusDays(1)); s.setProcessDate(LocalDate.now().minusDays(1)); s.setProcessor("데모 관리자"); s.setInprice(new BigDecimal(price)); s.setUserid("demo"); s.setProcid("demo"); s.setUid("stk-" + UUID.randomUUID()); em.persist(s); return s; } }