11package com .assu .server .domain .user .service ;
22
3+ import java .time .LocalDate ;
34import java .time .LocalDateTime ;
45import java .time .format .DateTimeFormatter ;
56import java .util .List ;
67
8+ import com .assu .server .domain .admin .entity .Admin ;
9+ import com .assu .server .domain .admin .repository .AdminRepository ;
10+ import com .assu .server .domain .common .enums .ActivationStatus ;
11+ import com .assu .server .domain .partner .entity .Partner ;
12+ import com .assu .server .domain .partnership .entity .Goods ;
13+ import com .assu .server .domain .partnership .entity .Paper ;
714import com .assu .server .domain .partnership .entity .PaperContent ;
15+ import com .assu .server .domain .partnership .entity .enums .OptionType ;
16+ import com .assu .server .domain .partnership .repository .GoodsRepository ;
817import com .assu .server .domain .partnership .repository .PaperContentRepository ;
18+ import com .assu .server .domain .partnership .repository .PaperRepository ;
919import com .assu .server .domain .store .entity .Store ;
1020import com .assu .server .domain .user .converter .StudentConverter ;
1121import com .assu .server .domain .user .dto .StudentResponseDTO ;
1222import com .assu .server .domain .user .entity .PartnershipUsage ;
1323import com .assu .server .domain .user .entity .Student ;
24+ import com .assu .server .domain .user .entity .UserPaper ;
1425import com .assu .server .domain .user .repository .PartnershipUsageRepository ;
1526import com .assu .server .domain .user .repository .StudentRepository ;
27+ import com .assu .server .domain .user .repository .UserPaperRepository ;
1628import com .assu .server .global .apiPayload .code .status .ErrorStatus ;
1729import com .assu .server .global .exception .DatabaseException ;
1830import jakarta .transaction .Transactional ;
2739@ RequiredArgsConstructor
2840public class StudentServiceImpl implements StudentService {
2941 private final StudentRepository studentRepository ;
42+ private final UserPaperRepository userPaperRepository ;
43+ private final PaperContentRepository paperContentRepository ;
44+ private final PartnershipUsageRepository partnershipUsageRepository ;
45+ private final GoodsRepository goodsRepository ;
46+ private final AdminRepository adminRepository ;
47+ private final PaperRepository paperRepository ;
48+
3049 @ Override
3150 @ Transactional
3251 public StudentResponseDTO .CheckStampResponseDTO getStamp (Long memberId ) {
@@ -36,9 +55,6 @@ public StudentResponseDTO.CheckStampResponseDTO getStamp(Long memberId) {
3655 return StudentConverter .checkStampResponseDTO (student , "스탬프 조회 성공" );
3756 }
3857
39- private final PaperContentRepository paperContentRepository ;
40- private final PartnershipUsageRepository partnershipUsageRepository ;
41-
4258 @ Override
4359 @ Transactional
4460 public StudentResponseDTO .myPartnership getMyPartnership (Long studentId , int year , int month ) {
@@ -112,4 +128,105 @@ public Page<StudentResponseDTO.UsageDetailDTO> getUnreviewedUsage(Long memberId,
112128 });
113129 }
114130
131+ @ Override
132+ public List <StudentResponseDTO .UsablePartnershipDTO > getUsablePartnership (Long memberId , Boolean all ) {
133+ LocalDate today = LocalDate .now ();
134+
135+ List <UserPaper > userPapers = userPaperRepository .findActivePartnershipsByStudentId (memberId , today );
136+
137+ List <StudentResponseDTO .UsablePartnershipDTO > result = userPapers .stream ().map (up -> {
138+ Paper paper = up .getPaper ();
139+ PaperContent content = up .getPaperContent ();
140+ Store store = paper .getStore ();
141+
142+ String adminName = (paper .getAdmin () != null ) ? paper .getAdmin ().getName () : null ;
143+ String partnerName = (store != null ) ? store .getName () : null ;
144+
145+ // 카테고리 결정 로직 그대로
146+ String finalCategory = null ;
147+ if (content != null ) {
148+ if (content .getCategory () != null ) {
149+ finalCategory = content .getCategory ();
150+ } else if (content .getOptionType () == OptionType .SERVICE ) {
151+ List <Goods > goods = goodsRepository .findByContentId (content .getId ());
152+ if (!goods .isEmpty ()) {
153+ finalCategory = goods .get (0 ).getBelonging ();
154+ }
155+ }
156+ }
157+
158+ return StudentResponseDTO .UsablePartnershipDTO .builder ()
159+ .partnershipId (paper .getId ())
160+ .adminName (adminName )
161+ .partnerName (partnerName )
162+ .criterionType (content != null ? content .getCriterionType () : null )
163+ .optionType (content != null ? content .getOptionType () : null )
164+ .people (content != null ? content .getPeople () : null )
165+ .cost (content != null ? content .getCost () : null )
166+ .category (finalCategory )
167+ .discountRate (content != null ? content .getDiscount () : null )
168+ .build ();
169+ }).toList ();
170+
171+ return Boolean .FALSE .equals (all ) ? result .stream ().limit (2 ).toList () : result ;
172+ }
173+
174+ @ Transactional
175+ public void syncUserPapersForStudent (Long studentId ) {
176+ Student student = studentRepository .findById (studentId )
177+ .orElseThrow (() -> new DatabaseException (ErrorStatus .NO_SUCH_STUDENT ));
178+
179+ // 1. 학생 기준으로 admin 찾기
180+ List <Admin > admins = adminRepository .findMatchingAdmins (
181+ student .getUniversity (),
182+ student .getDepartment (),
183+ student .getMajor ()
184+ );
185+
186+ if (admins .isEmpty ()) {
187+ return ;
188+ }
189+
190+ List <Long > adminIds = admins .stream ().map (Admin ::getId ).toList ();
191+ LocalDate today = LocalDate .now ();
192+
193+ // 2. admin들이 만든 오늘 유효한 paper 조회
194+ List <Paper > papers = paperRepository .findActivePapersByAdminIds (
195+ adminIds ,
196+ today ,
197+ ActivationStatus .ACTIVE
198+ );
199+
200+ // 3. user_paper에 없으면 넣기
201+ for (Paper paper : papers ) {
202+ boolean exists = userPaperRepository .existsByStudentIdAndPaperId (studentId , paper .getId ());
203+ if (exists ) continue ;
204+
205+ PaperContent latestContent = paperContentRepository
206+ .findTopByPaperIdOrderByIdDesc (paper .getId ())
207+ .orElse (null );
208+
209+ UserPaper up = UserPaper .builder ()
210+ .paper (paper )
211+ .paperContent (latestContent )
212+ .student (student )
213+ .build ();
214+
215+ userPaperRepository .save (up );
216+ }
217+ }
218+
219+ /**
220+ * 전체 학생에 대해 일괄로 user_paper 채워 넣는 메서드
221+ * (스케줄러에서 이거만 호출하면 됨)
222+ */
223+ @ Transactional
224+ @ Override
225+ public void syncUserPapersForAllStudents () {
226+ List <Student > students = studentRepository .findAll ();
227+ for (Student s : students ) {
228+ syncUserPapersForStudent (s .getId ());
229+ }
230+ }
115231}
232+
0 commit comments