diff --git a/src/main/java/org/example/crm/controller/AttendanceController.java b/src/main/java/org/example/crm/controller/AttendanceController.java index 7bd44b1..1d57403 100644 --- a/src/main/java/org/example/crm/controller/AttendanceController.java +++ b/src/main/java/org/example/crm/controller/AttendanceController.java @@ -3,6 +3,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.Min; import org.example.crm.entity.dto.attendance.*; +import org.example.crm.filters.AttendanceFilterDto; import org.example.crm.service.AttendanceService; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -32,7 +33,7 @@ public ResponseEntity> getAll( @RequestParam(required = false) String search ) { Pageable pageable = PageRequest.of(page, size); - Page attendances = service.getAll(pageable, search); + Page attendances = service.getAll(pageable, new AttendanceFilterDto(search)); return ResponseEntity.ok(attendances); } diff --git a/src/main/java/org/example/crm/controller/BranchController.java b/src/main/java/org/example/crm/controller/BranchController.java index b2648f3..b131652 100644 --- a/src/main/java/org/example/crm/controller/BranchController.java +++ b/src/main/java/org/example/crm/controller/BranchController.java @@ -2,11 +2,10 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.example.crm.annotation.CurrentUser; import org.example.crm.entity.dto.branch.BranchCreateDto; import org.example.crm.entity.dto.branch.BranchDto; +import org.example.crm.filters.BranchFilterDto; import org.example.crm.entity.dto.branch.BranchUpdateDto; -import org.example.crm.entity.model.User; import org.example.crm.service.BranchService; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -31,7 +30,7 @@ public ResponseEntity> getAll( @RequestParam(required = false) String search ) { Pageable pageable = PageRequest.of(page, size); - Page lessons = branchService.getAll(pageable, search); + Page lessons = branchService.getAll(pageable, new BranchFilterDto(search)); return ResponseEntity.ok(lessons); } diff --git a/src/main/java/org/example/crm/controller/EnrollmentController.java b/src/main/java/org/example/crm/controller/EnrollmentController.java index 5d40413..7cf98dd 100644 --- a/src/main/java/org/example/crm/controller/EnrollmentController.java +++ b/src/main/java/org/example/crm/controller/EnrollmentController.java @@ -3,6 +3,7 @@ import jakarta.validation.Valid; import org.example.crm.entity.dto.enrollment.EnrollmentCreateDto; import org.example.crm.entity.dto.enrollment.EnrollmentDto; +import org.example.crm.filters.EnrollmentFilterDto; import org.example.crm.entity.dto.enrollment.EnrollmentUpdateDto; import org.example.crm.service.EnrollmentService; import org.springframework.data.domain.Page; @@ -17,10 +18,10 @@ @RequestMapping("api/v1/enrollments") public class EnrollmentController { - private final EnrollmentService enrollmentService; + private final EnrollmentService service; - public EnrollmentController(EnrollmentService enrollmentService) { - this.enrollmentService = enrollmentService; + public EnrollmentController(EnrollmentService service) { + this.service = service; } @GetMapping @@ -29,19 +30,19 @@ public ResponseEntity> getAll( @RequestParam(required = false) String search, @RequestParam(required = false) String groupId ) { - Page enrollments = groupId == null ? enrollmentService.getAll(pageable, search) : enrollmentService.getAll(pageable, search, groupId); + Page enrollments = service.getAll(pageable,new EnrollmentFilterDto(search,groupId)); return ResponseEntity.ok(enrollments); } @GetMapping("/{id}") public ResponseEntity getById(@PathVariable String id) { - EnrollmentDto enrollment = enrollmentService.get(id); + EnrollmentDto enrollment = service.get(id); return ResponseEntity.ok(enrollment); } @PostMapping public ResponseEntity create(@Valid @RequestBody EnrollmentCreateDto createDto) { - EnrollmentDto createdEnrollment = enrollmentService.create(createDto); + EnrollmentDto createdEnrollment = service.create(createDto); return ResponseEntity.status(HttpStatus.CREATED).body(createdEnrollment); } @@ -51,18 +52,18 @@ public ResponseEntity update( @PathVariable String id, @Valid @RequestBody EnrollmentUpdateDto updateDto ) { - EnrollmentDto updatedEnrollment = enrollmentService.update(updateDto, id); + EnrollmentDto updatedEnrollment = service.update(updateDto, id); return ResponseEntity.ok(updatedEnrollment); } @DeleteMapping("/{id}") public ResponseEntity delete(@PathVariable String id, @RequestParam String reason) { - enrollmentService.delete(id,reason); + service.delete(id,reason); return ResponseEntity.noContent().build(); } @GetMapping("/student/{studentId}") public ResponseEntity> getByStudentId(@PathVariable String studentId) { - return ResponseEntity.ok(enrollmentService.getByStudentId(studentId)); + return ResponseEntity.ok(service.getByStudentId(studentId)); } } \ No newline at end of file diff --git a/src/main/java/org/example/crm/controller/GroupController.java b/src/main/java/org/example/crm/controller/GroupController.java index 670d17c..294ae2e 100644 --- a/src/main/java/org/example/crm/controller/GroupController.java +++ b/src/main/java/org/example/crm/controller/GroupController.java @@ -2,11 +2,9 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.example.crm.entity.dto.group.FullGroupDto; -import org.example.crm.entity.dto.group.GroupCreateDto; -import org.example.crm.entity.dto.group.GroupDto; -import org.example.crm.entity.dto.group.GroupUpdateDto; +import org.example.crm.entity.dto.group.*; import org.example.crm.entity.enums.GroupStatus; +import org.example.crm.filters.GroupFilterDto; import org.example.crm.projection.GroupNameProjection; import org.example.crm.service.GroupService; import org.springframework.data.domain.Page; @@ -31,7 +29,7 @@ public ResponseEntity> getAllGroups(@RequestParam(required = fals @RequestParam(required = false) GroupStatus status, @RequestParam(required = false) String level) { Pageable pageable = PageRequest.of(page, size); - return ResponseEntity.ok(service.getAll(pageable, search, status, level)); + return ResponseEntity.ok(service.getAll(pageable, new GroupFilterDto(search,status,level))); } @GetMapping("/{id}") diff --git a/src/main/java/org/example/crm/controller/GroupLevelController.java b/src/main/java/org/example/crm/controller/GroupLevelController.java index 4b1a260..327ffc5 100644 --- a/src/main/java/org/example/crm/controller/GroupLevelController.java +++ b/src/main/java/org/example/crm/controller/GroupLevelController.java @@ -8,6 +8,7 @@ import org.example.crm.entity.dto.groupLevel.GroupLevelNameDto; import org.example.crm.entity.dto.groupLevel.GroupLevelUpdateDto; import org.example.crm.entity.request.GroupLevelList; +import org.example.crm.filters.SearchFilterDto; import org.example.crm.service.GroupLevelService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/org/example/crm/controller/ImageController.java b/src/main/java/org/example/crm/controller/ImageController.java index d44592f..a079be1 100644 --- a/src/main/java/org/example/crm/controller/ImageController.java +++ b/src/main/java/org/example/crm/controller/ImageController.java @@ -4,14 +4,13 @@ import lombok.RequiredArgsConstructor; import org.example.crm.entity.dto.image.ImageDto; import org.example.crm.service.ImageService; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; +import java.util.List; import java.util.Map; @RestController @@ -22,11 +21,8 @@ public class ImageController { private final ImageService imageService; @GetMapping - public ResponseEntity> getAll( - Pageable pageable, - @RequestParam(required = false) String search - ) { - Page images = imageService.getAll(pageable, search); + public ResponseEntity> getAll() { + List images = imageService.getAll(null, null); return ResponseEntity.ok(images); } @@ -38,7 +34,7 @@ public ResponseEntity getById(@PathVariable String id) { @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity upload(@Valid @RequestParam MultipartFile file) throws IOException { - return ResponseEntity.ok(Map.of("imageUrl",imageService.uploadImage(file))); + return ResponseEntity.ok(Map.of("imageUrl", imageService.uploadImage(file))); } @PutMapping("/main/{id}") diff --git a/src/main/java/org/example/crm/controller/InvoiceController.java b/src/main/java/org/example/crm/controller/InvoiceController.java index f2402eb..305fb76 100644 --- a/src/main/java/org/example/crm/controller/InvoiceController.java +++ b/src/main/java/org/example/crm/controller/InvoiceController.java @@ -4,6 +4,7 @@ import org.example.crm.entity.dto.InvoiceCreateDto; import org.example.crm.entity.dto.InvoiceDto; import org.example.crm.entity.enums.InvoiceStatus; +import org.example.crm.filters.InvoiceFilterDto; import org.example.crm.service.InvoiceService; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -30,7 +31,7 @@ public ResponseEntity> getAllInvoices(@RequestParam(required = @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size) { Pageable pageable = PageRequest.of(page, size); - return ResponseEntity.ok(service.getAllInvoices(search, from, to, status, pageable)); + return ResponseEntity.ok(service.getAll(pageable,new InvoiceFilterDto(from, to, status, search))); } @GetMapping("/{id}") diff --git a/src/main/java/org/example/crm/controller/LeadController.java b/src/main/java/org/example/crm/controller/LeadController.java index 3a9f053..4ab5909 100644 --- a/src/main/java/org/example/crm/controller/LeadController.java +++ b/src/main/java/org/example/crm/controller/LeadController.java @@ -8,6 +8,7 @@ import org.example.crm.entity.dto.lead.LeadRejectDto; import org.example.crm.entity.dto.lead.LeadUpdateDto; import org.example.crm.entity.enums.LeadStatus; +import org.example.crm.filters.LeadFilterDto; import org.example.crm.service.LeadService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -32,7 +33,7 @@ public ResponseEntity> getAll( @PageableDefault Pageable pageable, @RequestParam(required = false) String search, @RequestParam(required = false) LeadStatus status) { - return ResponseEntity.ok(service.getAll(pageable, search, status)); + return ResponseEntity.ok(service.getAll(pageable,new LeadFilterDto( search, status))); } @GetMapping("/{id}") diff --git a/src/main/java/org/example/crm/controller/LessonController.java b/src/main/java/org/example/crm/controller/LessonController.java index 0957095..53237ed 100644 --- a/src/main/java/org/example/crm/controller/LessonController.java +++ b/src/main/java/org/example/crm/controller/LessonController.java @@ -4,6 +4,7 @@ import org.example.crm.entity.dto.lesson.LessonCreateDto; import org.example.crm.entity.dto.lesson.LessonDto; import org.example.crm.entity.dto.lesson.LessonUpdateDto; +import org.example.crm.filters.LessonFilterDto; import org.example.crm.service.LessonService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -28,7 +29,7 @@ public ResponseEntity> getAll( Pageable pageable, @RequestParam(required = false) String search ) { - Page lessons = lessonService.getAll(pageable, search); + Page lessons = lessonService.getAll(pageable, new LessonFilterDto(search)); return ResponseEntity.ok(lessons); } diff --git a/src/main/java/org/example/crm/controller/OrganizationController.java b/src/main/java/org/example/crm/controller/OrganizationController.java index 1bae08a..9bbb5ce 100644 --- a/src/main/java/org/example/crm/controller/OrganizationController.java +++ b/src/main/java/org/example/crm/controller/OrganizationController.java @@ -5,6 +5,7 @@ import org.example.crm.entity.dto.organization.OrganizationCreateDto; import org.example.crm.entity.dto.organization.OrganizationDto; import org.example.crm.entity.dto.organization.OrganizationUpdateDto; +import org.example.crm.filters.OrganizationFilterDto; import org.example.crm.service.OrganizationService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -24,7 +25,7 @@ public class OrganizationController { public ResponseEntity> getAll( @PageableDefault(size = 10, sort = "createdAt") Pageable pageable, @RequestParam(required = false) String search) { - return ResponseEntity.ok(organizationService.getAll(pageable, search)); + return ResponseEntity.ok(organizationService.getAll(pageable, new OrganizationFilterDto(search))); } @GetMapping("/{id}") diff --git a/src/main/java/org/example/crm/controller/StudentController.java b/src/main/java/org/example/crm/controller/StudentController.java index 8049f3a..74060c5 100644 --- a/src/main/java/org/example/crm/controller/StudentController.java +++ b/src/main/java/org/example/crm/controller/StudentController.java @@ -4,6 +4,7 @@ import org.example.crm.entity.dto.student.StudentCreateDto; import org.example.crm.entity.dto.student.StudentDto; import org.example.crm.entity.dto.student.StudentUpdateDto; +import org.example.crm.filters.StudentFilterDto; import org.example.crm.service.StudentService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -31,7 +32,7 @@ public ResponseEntity> getAll( Pageable pageable, @RequestParam(required = false) String search ) { - Page students = studentService.getAll(pageable, search); + Page students = studentService.getAll(pageable, new StudentFilterDto(search)); return ResponseEntity.ok(students); } diff --git a/src/main/java/org/example/crm/controller/TeacherController.java b/src/main/java/org/example/crm/controller/TeacherController.java index 62e7c20..1f3a7da 100644 --- a/src/main/java/org/example/crm/controller/TeacherController.java +++ b/src/main/java/org/example/crm/controller/TeacherController.java @@ -4,6 +4,7 @@ import org.example.crm.entity.dto.teacher.TeacherCreateDto; import org.example.crm.entity.dto.teacher.TeacherDto; import org.example.crm.entity.dto.teacher.TeacherUpdateDto; +import org.example.crm.filters.TeacherFilterDto; import org.example.crm.service.TeacherService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -30,7 +31,7 @@ public ResponseEntity> getAll( Pageable pageable, @RequestParam(required = false) String search ) { - Page teachers = teacherService.getAll(pageable, search); + Page teachers = teacherService.getAll(pageable, new TeacherFilterDto(search)); return ResponseEntity.ok(teachers); } diff --git a/src/main/java/org/example/crm/controller/TimeTableController.java b/src/main/java/org/example/crm/controller/TimeTableController.java index f083d17..fd9c8f7 100644 --- a/src/main/java/org/example/crm/controller/TimeTableController.java +++ b/src/main/java/org/example/crm/controller/TimeTableController.java @@ -5,6 +5,7 @@ import org.example.crm.entity.dto.TimeTableUpdateDto; import org.example.crm.entity.dto.timeTable.TimeTableDto; import org.example.crm.entity.enums.DayType; +import org.example.crm.filters.TimeTableFilterDto; import org.example.crm.service.TimeTableService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -23,7 +24,7 @@ public class TimeTableController { public ResponseEntity> findAll(@RequestParam(required = false) DayType dayType, @RequestParam(required = false, defaultValue = "00:00") LocalTime start, @RequestParam(required = false, defaultValue = "23:59:59") LocalTime end) { - return ResponseEntity.ok(service.getAll(dayType,start,end)); + return ResponseEntity.ok(service.getAll(null,new TimeTableFilterDto(dayType,start,end))); } @GetMapping("/{id}") diff --git a/src/main/java/org/example/crm/controller/TransactionController.java b/src/main/java/org/example/crm/controller/TransactionController.java index 315f7ca..b99cb07 100644 --- a/src/main/java/org/example/crm/controller/TransactionController.java +++ b/src/main/java/org/example/crm/controller/TransactionController.java @@ -4,7 +4,9 @@ import lombok.RequiredArgsConstructor; import org.example.crm.entity.dto.transaction.TransactionCreateDto; import org.example.crm.entity.dto.transaction.TransactionDto; +import org.example.crm.filters.TransactionFilterDto; import org.example.crm.entity.dto.transaction.TransactionUpdateDto; +import org.example.crm.entity.enums.TransactionType; import org.example.crm.service.TransactionService; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -26,10 +28,11 @@ public class TransactionController { public ResponseEntity> getAll( @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size, + @RequestParam(defaultValue = "10") TransactionType type, @RequestParam(required = false) String search ) { Pageable pageable = PageRequest.of(page, size); - Page transactions = transactionService.getAll(pageable, search); + Page transactions = transactionService.getAll(pageable, new TransactionFilterDto(type,search)); return ResponseEntity.ok(transactions); } diff --git a/src/main/java/org/example/crm/controller/UserController.java b/src/main/java/org/example/crm/controller/UserController.java index 9e64e29..a669820 100644 --- a/src/main/java/org/example/crm/controller/UserController.java +++ b/src/main/java/org/example/crm/controller/UserController.java @@ -4,6 +4,7 @@ import org.example.crm.entity.dto.user.UserCreateDto; import org.example.crm.entity.dto.user.UserDto; import org.example.crm.entity.dto.user.UserUpdateDto; +import org.example.crm.filters.UserFilterDto; import org.example.crm.service.UserService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -28,7 +29,7 @@ public ResponseEntity> getAll( Pageable pageable, @RequestParam(required = false) String search ) { - Page users = userService.getAll(pageable, search); + Page users = userService.getAll(pageable, new UserFilterDto(search)); return ResponseEntity.ok(users); } diff --git a/src/main/java/org/example/crm/entity/dto/transaction/TransactionCreateDto.java b/src/main/java/org/example/crm/entity/dto/transaction/TransactionCreateDto.java index 08b8037..8305b5c 100644 --- a/src/main/java/org/example/crm/entity/dto/transaction/TransactionCreateDto.java +++ b/src/main/java/org/example/crm/entity/dto/transaction/TransactionCreateDto.java @@ -9,13 +9,18 @@ public record TransactionCreateDto( @NotNull - @Schema(allowableValues = {"PAID", "RETURNED","MONTHLY_FEE"}) + @Schema(allowableValues = {"PAID", "RETURNED","MONTHLY_FEE","CORRECTION"}) TransactionType type, @NotNull BigDecimal amount, + String note, + + @NotNull + String studentId, + @NotNull - String studentId + String invoiceId ) { } \ No newline at end of file diff --git a/src/main/java/org/example/crm/entity/dto/transaction/TransactionDto.java b/src/main/java/org/example/crm/entity/dto/transaction/TransactionDto.java index 5613a9c..ed6e2f4 100644 --- a/src/main/java/org/example/crm/entity/dto/transaction/TransactionDto.java +++ b/src/main/java/org/example/crm/entity/dto/transaction/TransactionDto.java @@ -11,6 +11,7 @@ public record TransactionDto( String id, TransactionType type, BigDecimal amount, + String note, InvoiceDto invoice, StudentDto user, LocalDateTime createdAt diff --git a/src/main/java/org/example/crm/entity/dto/transaction/TransactionUpdateDto.java b/src/main/java/org/example/crm/entity/dto/transaction/TransactionUpdateDto.java index 6f25386..d60055e 100644 --- a/src/main/java/org/example/crm/entity/dto/transaction/TransactionUpdateDto.java +++ b/src/main/java/org/example/crm/entity/dto/transaction/TransactionUpdateDto.java @@ -1,6 +1,5 @@ package org.example.crm.entity.dto.transaction; -import io.swagger.v3.oas.annotations.media.Schema; import org.example.crm.entity.enums.TransactionType; import java.math.BigDecimal; @@ -8,6 +7,7 @@ public record TransactionUpdateDto( TransactionType type, BigDecimal amount, + String note, String invoiceId, String studentId ) { diff --git a/src/main/java/org/example/crm/entity/enums/TransactionType.java b/src/main/java/org/example/crm/entity/enums/TransactionType.java index 3c22a5c..221e5a4 100644 --- a/src/main/java/org/example/crm/entity/enums/TransactionType.java +++ b/src/main/java/org/example/crm/entity/enums/TransactionType.java @@ -2,6 +2,7 @@ public enum TransactionType { PAID, - RETURNED, - MONTHLY_FEE + REFUND, + MONTHLY_FEE, + CORRECTION } diff --git a/src/main/java/org/example/crm/entity/model/Transaction.java b/src/main/java/org/example/crm/entity/model/Transaction.java index 7124138..71a0f55 100644 --- a/src/main/java/org/example/crm/entity/model/Transaction.java +++ b/src/main/java/org/example/crm/entity/model/Transaction.java @@ -1,8 +1,6 @@ package org.example.crm.entity.model; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.ManyToOne; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -20,14 +18,21 @@ @NoArgsConstructor public class Transaction extends BaseEntity { + @Enumerated(EnumType.STRING) + @Column(name = "type", nullable = false, length = 32) private TransactionType type; + @Column(name = "amount", nullable = false, precision = 19, scale = 2) private BigDecimal amount; - @ManyToOne(fetch = FetchType.LAZY, optional = false) + @Column(name = "note", length = 500) + private String note; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "invoice_id") private Invoice invoice; @ManyToOne(fetch = FetchType.LAZY, optional = false) - private Student user; - -} + @JoinColumn(name = "student_id", nullable = false) + private Student student; +} \ No newline at end of file diff --git a/src/main/java/org/example/crm/exceptions/ErrorType.java b/src/main/java/org/example/crm/exceptions/ErrorType.java index e384643..6f1e5ff 100644 --- a/src/main/java/org/example/crm/exceptions/ErrorType.java +++ b/src/main/java/org/example/crm/exceptions/ErrorType.java @@ -64,7 +64,9 @@ public enum ErrorType { COURSE_ALREADY_EXISTS("course.already.exists"), INVALID_INPUT("invalid.input"), TRANSACTION_NOT_FOUND("transaction.not.found"), - INVOICE_ALREADY_CREATED("invoice.already.created"); + INVOICE_ALREADY_CREATED("invoice.already.created"), + INVOICE_ALREADY_PAID("invoice.already.paid"), + INVOICE_REQUIRED("invoice.required"); private final String key; diff --git a/src/main/java/org/example/crm/filters/AttendanceFilterDto.java b/src/main/java/org/example/crm/filters/AttendanceFilterDto.java new file mode 100644 index 0000000..f897778 --- /dev/null +++ b/src/main/java/org/example/crm/filters/AttendanceFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record AttendanceFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/filters/BranchFilterDto.java b/src/main/java/org/example/crm/filters/BranchFilterDto.java new file mode 100644 index 0000000..827bfeb --- /dev/null +++ b/src/main/java/org/example/crm/filters/BranchFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record BranchFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/filters/CourseFilterDto.java b/src/main/java/org/example/crm/filters/CourseFilterDto.java new file mode 100644 index 0000000..e692820 --- /dev/null +++ b/src/main/java/org/example/crm/filters/CourseFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record CourseFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/filters/EnrollmentFilterDto.java b/src/main/java/org/example/crm/filters/EnrollmentFilterDto.java new file mode 100644 index 0000000..9ed61f0 --- /dev/null +++ b/src/main/java/org/example/crm/filters/EnrollmentFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record EnrollmentFilterDto(String search, String groupId) { +} diff --git a/src/main/java/org/example/crm/filters/GroupFilterDto.java b/src/main/java/org/example/crm/filters/GroupFilterDto.java new file mode 100644 index 0000000..4a11943 --- /dev/null +++ b/src/main/java/org/example/crm/filters/GroupFilterDto.java @@ -0,0 +1,6 @@ +package org.example.crm.filters; + +import org.example.crm.entity.enums.GroupStatus; + +public record GroupFilterDto(String search, GroupStatus status, String level) { +} diff --git a/src/main/java/org/example/crm/filters/GroupLevelFilterDto.java b/src/main/java/org/example/crm/filters/GroupLevelFilterDto.java new file mode 100644 index 0000000..5fe8fa7 --- /dev/null +++ b/src/main/java/org/example/crm/filters/GroupLevelFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record GroupLevelFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/filters/InvoiceFilterDto.java b/src/main/java/org/example/crm/filters/InvoiceFilterDto.java new file mode 100644 index 0000000..38235db --- /dev/null +++ b/src/main/java/org/example/crm/filters/InvoiceFilterDto.java @@ -0,0 +1,10 @@ +package org.example.crm.filters; + +import org.example.crm.entity.enums.InvoiceStatus; +import org.springframework.data.domain.Pageable; + +import java.time.LocalDateTime; + +public record InvoiceFilterDto(LocalDateTime from, LocalDateTime to, InvoiceStatus status, + String search) { +} diff --git a/src/main/java/org/example/crm/filters/LeadFilterDto.java b/src/main/java/org/example/crm/filters/LeadFilterDto.java new file mode 100644 index 0000000..10fb7f3 --- /dev/null +++ b/src/main/java/org/example/crm/filters/LeadFilterDto.java @@ -0,0 +1,6 @@ +package org.example.crm.filters; + +import org.example.crm.entity.enums.LeadStatus; + +public record LeadFilterDto(String search, LeadStatus status) { +} diff --git a/src/main/java/org/example/crm/filters/LessonFilterDto.java b/src/main/java/org/example/crm/filters/LessonFilterDto.java new file mode 100644 index 0000000..42ee2ca --- /dev/null +++ b/src/main/java/org/example/crm/filters/LessonFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record LessonFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/filters/OrganizationFilterDto.java b/src/main/java/org/example/crm/filters/OrganizationFilterDto.java new file mode 100644 index 0000000..98def80 --- /dev/null +++ b/src/main/java/org/example/crm/filters/OrganizationFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record OrganizationFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/filters/SearchFilterDto.java b/src/main/java/org/example/crm/filters/SearchFilterDto.java new file mode 100644 index 0000000..c37d9be --- /dev/null +++ b/src/main/java/org/example/crm/filters/SearchFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record SearchFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/filters/StudentFilterDto.java b/src/main/java/org/example/crm/filters/StudentFilterDto.java new file mode 100644 index 0000000..f4ed839 --- /dev/null +++ b/src/main/java/org/example/crm/filters/StudentFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record StudentFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/filters/TeacherFilterDto.java b/src/main/java/org/example/crm/filters/TeacherFilterDto.java new file mode 100644 index 0000000..6da0a5b --- /dev/null +++ b/src/main/java/org/example/crm/filters/TeacherFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record TeacherFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/filters/TimeTableFilterDto.java b/src/main/java/org/example/crm/filters/TimeTableFilterDto.java new file mode 100644 index 0000000..270cccc --- /dev/null +++ b/src/main/java/org/example/crm/filters/TimeTableFilterDto.java @@ -0,0 +1,5 @@ +package org.example.crm.filters; + +public record TimeTableFilterDto(org.example.crm.entity.enums.DayType dayType, java.time.LocalTime start, + java.time.LocalTime end) { +} diff --git a/src/main/java/org/example/crm/filters/TransactionFilterDto.java b/src/main/java/org/example/crm/filters/TransactionFilterDto.java new file mode 100644 index 0000000..678107f --- /dev/null +++ b/src/main/java/org/example/crm/filters/TransactionFilterDto.java @@ -0,0 +1,6 @@ +package org.example.crm.filters; + +import org.example.crm.entity.enums.TransactionType; + +public record TransactionFilterDto(TransactionType type,String search) { +} diff --git a/src/main/java/org/example/crm/filters/UserFilterDto.java b/src/main/java/org/example/crm/filters/UserFilterDto.java new file mode 100644 index 0000000..fe248f6 --- /dev/null +++ b/src/main/java/org/example/crm/filters/UserFilterDto.java @@ -0,0 +1,4 @@ +package org.example.crm.filters; + +public record UserFilterDto(String search) { +} diff --git a/src/main/java/org/example/crm/mapper/InvoiceMapper.java b/src/main/java/org/example/crm/mapper/InvoiceMapper.java index 6028e48..e9d6095 100644 --- a/src/main/java/org/example/crm/mapper/InvoiceMapper.java +++ b/src/main/java/org/example/crm/mapper/InvoiceMapper.java @@ -58,7 +58,7 @@ public InvoiceDto toDtoFromProjection(InvoiceProjection projection) { projection.getGroupId(), projection.getReason() ), - projection.getPaymentStatus() + projection.getInvoiceStatus() ); } diff --git a/src/main/java/org/example/crm/mapper/TransactionMapper.java b/src/main/java/org/example/crm/mapper/TransactionMapper.java index 6650fa7..e03fb2a 100644 --- a/src/main/java/org/example/crm/mapper/TransactionMapper.java +++ b/src/main/java/org/example/crm/mapper/TransactionMapper.java @@ -3,11 +3,9 @@ import lombok.RequiredArgsConstructor; import org.example.crm.entity.dto.transaction.TransactionCreateDto; import org.example.crm.entity.dto.transaction.TransactionDto; -import org.example.crm.entity.dto.transaction.TransactionUpdateDto; +import org.example.crm.entity.model.Invoice; +import org.example.crm.entity.model.Student; import org.example.crm.entity.model.Transaction; -import org.example.crm.service.StudentService; -import org.example.crm.validator.InvoiceValidator; -import org.example.crm.validator.StudentValidator; import org.springframework.stereotype.Component; @Component @@ -16,16 +14,14 @@ public class TransactionMapper { private final InvoiceMapper invoiceMapper; private final StudentMapper studentMapper; - private final InvoiceValidator invoiceValidator; - private final StudentValidator studentValidator; - final StudentService studentService; - public Transaction toEntity(TransactionCreateDto createDto) { + public Transaction toEntity(TransactionCreateDto createDto, Student student, Invoice invoice) { Transaction transaction = new Transaction(); transaction.setType(createDto.type()); transaction.setAmount(createDto.amount()); - transaction.setInvoice(studentService.getLatestInvoice(createDto.studentId())); - transaction.setUser(studentValidator.validateIdAndGet(createDto.studentId())); + transaction.setNote(createDto.note()); + transaction.setStudent(student); + transaction.setInvoice(invoice); return transaction; } @@ -34,24 +30,10 @@ public TransactionDto toDto(Transaction transaction) { transaction.getId(), transaction.getType(), transaction.getAmount(), + transaction.getNote(), transaction.getInvoice() != null ? invoiceMapper.toDto(transaction.getInvoice()) : null, - transaction.getUser() != null ? studentMapper.toDto(transaction.getUser()) : null, + transaction.getStudent() != null ? studentMapper.toDto(transaction.getStudent()) : null, transaction.getCreatedAt() ); } - - public void mapUpdate(Transaction transaction, TransactionUpdateDto updateDto) { - if (updateDto.type() != null) { - transaction.setType(updateDto.type()); - } - if (updateDto.amount() != null) { - transaction.setAmount(updateDto.amount()); - } - if (updateDto.invoiceId() != null) { - transaction.setInvoice(invoiceValidator.validateIdAndGet(updateDto.invoiceId())); - } - if (updateDto.studentId() != null) { - transaction.setUser(studentValidator.validateIdAndGet(updateDto.studentId())); - } - } } \ No newline at end of file diff --git a/src/main/java/org/example/crm/projection/InvoiceProjection.java b/src/main/java/org/example/crm/projection/InvoiceProjection.java index 2bffc84..d233fce 100644 --- a/src/main/java/org/example/crm/projection/InvoiceProjection.java +++ b/src/main/java/org/example/crm/projection/InvoiceProjection.java @@ -13,8 +13,7 @@ public interface InvoiceProjection { String getStudentFullName(); String getGroupId(); String getReason(); - BigDecimal getAmount(); LocalDateTime getCreatedAt(); - InvoiceStatus getPaymentStatus(); + InvoiceStatus getInvoiceStatus(); } diff --git a/src/main/java/org/example/crm/repository/EnrollmentRepository.java b/src/main/java/org/example/crm/repository/EnrollmentRepository.java index d0d984b..ae3171b 100644 --- a/src/main/java/org/example/crm/repository/EnrollmentRepository.java +++ b/src/main/java/org/example/crm/repository/EnrollmentRepository.java @@ -25,10 +25,7 @@ public interface EnrollmentRepository extends JpaRepository void softDelete(@Param("reason") String reason, @Param("id") String id); @Query("select e from Enrollment e where (:groupId is null or e.group.id =:groupId) and e.student.user.fullName ilike concat('%',:fullName,'%')") - Page findAllBySearch(@Param("groupId") String groupId, Pageable pageable,@Param("fullName") String search); - - @Query("select e from Enrollment e where e.student.user.fullName ilike concat('%',:fullName,'%')") - Page findAllBySearch(@Param("orgId") String organizationId, @Param("fullName") String search, Pageable pageable); + Page findAllBySearch(@Param("orgId") String organizationId, @Param("groupId") String groupId, @Param("fullName") String search, Pageable pageable); @Query(""" @@ -55,26 +52,26 @@ AnalyticEnrollmentProjection getAnalyticEnrollment( LocalDateTime startNextMonth); @Query(""" - select en - from Enrollment en - where en.student.id = :studentId and en.group.id = :groupId - and en.deleted = false and en.student.user.deleted = false and en.group.deleted = false -""") + select en + from Enrollment en + where en.student.id = :studentId and en.group.id = :groupId + and en.deleted = false and en.student.user.deleted = false and en.group.deleted = false + """) Optional findByStudentIdAndGroupId(String studentId, String groupId); @Query(""" - select en - from Enrollment en - where en.student.id = :studentId - and en.deleted = false and en.student.user.deleted = false -""") + select en + from Enrollment en + where en.student.id = :studentId + and en.deleted = false and en.student.user.deleted = false + """) List findByStudentId(String studentId); @Query(""" - select e as enrollment,l.monthlyFee as monthlyFee - from Enrollment e - join e.group.level l - where e.id=:id""") + select e as enrollment,l.monthlyFee as monthlyFee + from Enrollment e + join e.group.level l + where e.id=:id""") EnrollmentMonthlyFeeProjection getEnrollmentAndMonthlyFee(@Param("id") String enrollmentId); @Query("select e from Enrollment e join fetch e.student where e.deleted=false and e.group.id=:groupId") diff --git a/src/main/java/org/example/crm/repository/ImageRepository.java b/src/main/java/org/example/crm/repository/ImageRepository.java index 8f24c67..7efcc17 100644 --- a/src/main/java/org/example/crm/repository/ImageRepository.java +++ b/src/main/java/org/example/crm/repository/ImageRepository.java @@ -9,11 +9,13 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; + +import java.util.List; import java.util.Optional; public interface ImageRepository extends JpaRepository { @Query("SELECT i.id as id, i.imageUrl as imageUrl, i.originalFileName as originalFileName from Image i where i.createdBy =:userId and i.deleted = false") - Page findAllByUserId(@Param("userId") String userId, Pageable pageable); + List findAllByUserId(@Param("userId") String userId); @Query("SELECT EXISTS (SELECT i.id FROM Image i WHERE i.id=:id)") Optional checkId(@Param("id") String id); diff --git a/src/main/java/org/example/crm/repository/InvoiceRepository.java b/src/main/java/org/example/crm/repository/InvoiceRepository.java index f6e7e94..11058b4 100644 --- a/src/main/java/org/example/crm/repository/InvoiceRepository.java +++ b/src/main/java/org/example/crm/repository/InvoiceRepository.java @@ -30,7 +30,7 @@ public interface InvoiceRepository extends JpaRepository { e.leavingReason as reason, i.amount as amount, i.createdAt as createAt, - i.paymentStatus as paymentStatus + i.paymentStatus as invoiceStatus from Invoice i join i.enrollment e join e.student s diff --git a/src/main/java/org/example/crm/repository/TransactionRepository.java b/src/main/java/org/example/crm/repository/TransactionRepository.java index f9b085e..b6b0d10 100644 --- a/src/main/java/org/example/crm/repository/TransactionRepository.java +++ b/src/main/java/org/example/crm/repository/TransactionRepository.java @@ -1,10 +1,12 @@ package org.example.crm.repository; import jakarta.transaction.Transactional; +import org.example.crm.entity.enums.TransactionType; import org.example.crm.entity.model.Transaction; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -13,34 +15,7 @@ import java.util.Optional; @Repository -public interface TransactionRepository extends JpaRepository { - - @Query(""" - SELECT t FROM Transaction t - LEFT JOIN t.invoice i - LEFT JOIN t.user u - LEFT JOIN u.user uu - WHERE t.deleted = false - AND t.organizationId = :orgId - AND ( - CAST(:search AS string) IS NULL - OR LOWER(i.invoiceNumber) LIKE LOWER(CONCAT('%', CAST(:search AS string), '%')) - OR LOWER(uu.fullName) LIKE LOWER(CONCAT('%', CAST(:search AS string), '%')) - OR LOWER(uu.phone) LIKE LOWER(CONCAT('%', CAST(:search AS string), '%')) - OR CAST(t.amount AS string) LIKE CONCAT('%', CAST(:search AS string), '%') - ) -""") - Page findAll( - @Param("search") String search, - @Param("orgId") String orgId, - Pageable pageable - ); - - @Transactional - @Modifying - @Query("UPDATE Transaction t SET t.deleted = true WHERE t.id = :id and t.organizationId = :organizationId") - int deleteByIdFalse(@Param("id") String id, @Param("organizationId") String organizationId); - +public interface TransactionRepository extends JpaRepository, JpaSpecificationExecutor { @Query("select exists (select t.id from Transaction t where t.id=:id)") Optional checkId(@Param("id") String id); diff --git a/src/main/java/org/example/crm/service/AttendanceService.java b/src/main/java/org/example/crm/service/AttendanceService.java index 3ca7aaa..5ceb666 100644 --- a/src/main/java/org/example/crm/service/AttendanceService.java +++ b/src/main/java/org/example/crm/service/AttendanceService.java @@ -8,6 +8,7 @@ import org.example.crm.entity.model.AttendanceStudent; import org.example.crm.entity.model.Lesson; import org.example.crm.entity.model.Student; +import org.example.crm.filters.AttendanceFilterDto; import org.example.crm.mapper.AttendanceMapper; import org.example.crm.projection.AttendanceProjection; import org.example.crm.projection.AttendanceStudentProjection; @@ -26,7 +27,7 @@ public class AttendanceService extends AbstractService< AttendanceRepository, AttendanceMapper, - AttendanceValidator> implements CrudService { + AttendanceValidator> implements CrudService> { private final LessonValidator lessonValidator; private final StudentValidator studentValidator; @@ -42,16 +43,16 @@ protected AttendanceService(AttendanceRepository repository, AttendanceMapper ma } @Override - public Page getAll(Pageable pageable, String search) { + public Page getAll(Pageable pageable, AttendanceFilterDto filterDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - Page all = repository.findAll(search,organizationId,pageable); + Page all = repository.findAll(filterDto.search(), organizationId, pageable); return all.map(mapper::toDto); } @Override public AttendanceDto get(String id) { String organizationId = userValidator.authenticateAndGetId(); - Attendance attendance = validator.validateIdAndGet(id,organizationId); + Attendance attendance = validator.validateIdAndGet(id, organizationId); return mapper.toDto(attendance); } @@ -60,7 +61,7 @@ public AttendanceDto get(String id) { @Transactional public AttendanceDto create(AttendanceCreateDto createDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - Lesson lesson = lessonValidator.validateIdAndGet(createDto.lessonId(),organizationId); + Lesson lesson = lessonValidator.validateIdAndGet(createDto.lessonId(), organizationId); Attendance attendance = new Attendance(); attendance.setLesson(lesson); @@ -82,7 +83,7 @@ public AttendanceDto create(AttendanceCreateDto createDto) { @Override public AttendanceDto update(AttendanceUpdateDto updateDto, String id) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - Attendance attendance = validator.validateIdAndGet(id,organizationId); + Attendance attendance = validator.validateIdAndGet(id, organizationId); updateStudentAttendances(attendance, updateDto.attendanceStudents()); Attendance save = repository.save(attendance); return mapper.toDto(save); @@ -92,7 +93,7 @@ public AttendanceDto update(AttendanceUpdateDto updateDto, String id) { public void delete(String id) { validator.validateId(id); String organizationId = userValidator.authenticateAndGetOrganizationId(); - repository.softDelete(id,organizationId); + repository.softDelete(id, organizationId); } private void updateStudentAttendances(Attendance attendance, List attendanceStudentUpdateDtos) { diff --git a/src/main/java/org/example/crm/service/BranchService.java b/src/main/java/org/example/crm/service/BranchService.java index e8d6304..15b99f4 100644 --- a/src/main/java/org/example/crm/service/BranchService.java +++ b/src/main/java/org/example/crm/service/BranchService.java @@ -3,9 +3,9 @@ import jakarta.transaction.Transactional; import org.example.crm.entity.dto.branch.BranchCreateDto; import org.example.crm.entity.dto.branch.BranchDto; +import org.example.crm.filters.BranchFilterDto; import org.example.crm.entity.dto.branch.BranchUpdateDto; import org.example.crm.entity.model.Branch; -import org.example.crm.entity.model.User; import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; import org.example.crm.exceptions.RestException; @@ -22,7 +22,7 @@ public class BranchService extends AbstractService< BranchRepository, BranchMapper, - BranchValidator> implements CrudService { + BranchValidator> implements CrudService> { private final UserValidator userValidator; private final OrganizationValidator organizationValidator; @@ -34,9 +34,9 @@ protected BranchService(BranchRepository repository, BranchMapper mapper, Branch } @Override - public Page getAll(Pageable pageable, String search) { + public Page getAll(Pageable pageable, BranchFilterDto filterDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - Page branches = repository.findAll(search, organizationId, pageable); + Page branches = repository.findAll(filterDto.search(), organizationId, pageable); return branches.map(mapper::toDto); } diff --git a/src/main/java/org/example/crm/service/CourseService.java b/src/main/java/org/example/crm/service/CourseService.java index b5a7b94..f221e61 100644 --- a/src/main/java/org/example/crm/service/CourseService.java +++ b/src/main/java/org/example/crm/service/CourseService.java @@ -9,6 +9,7 @@ import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; import org.example.crm.exceptions.RestException; +import org.example.crm.filters.CourseFilterDto; import org.example.crm.mapper.CourseMapper; import org.example.crm.projection.CourseProjection; import org.example.crm.repository.CourseRepository; @@ -23,7 +24,7 @@ public class CourseService extends AbstractService< CourseRepository, CourseMapper, - CourseValidator> implements CrudService { + CourseValidator> implements CrudService> { private final UserValidator userValidator; private final UserRepository userRepository; @@ -39,11 +40,11 @@ protected CourseService(CourseRepository repository, } @Override - public Page getAll(Pageable pageable, String search) { + public Page getAll(Pageable pageable, CourseFilterDto filterDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - String searchPattern = (search != null && !search.isBlank()) - ? "%" + search.trim().toLowerCase() + "%" + String searchPattern = (filterDto.search() != null && !filterDto.search().isBlank()) + ? "%" + filterDto.search().trim().toLowerCase() + "%" : null; Page courses = repository.getAllByFilter(organizationId, searchPattern, pageable); diff --git a/src/main/java/org/example/crm/service/CrudService.java b/src/main/java/org/example/crm/service/CrudService.java index ef57c9c..e1448cc 100644 --- a/src/main/java/org/example/crm/service/CrudService.java +++ b/src/main/java/org/example/crm/service/CrudService.java @@ -1,14 +1,15 @@ package org.example.crm.service; import jakarta.validation.Valid; +import org.example.crm.filters.SearchFilterDto; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.validation.annotation.Validated; @Validated -public interface CrudService { +public interface CrudService { - Page getAll(Pageable pageable, String search); + R getAll(Pageable pageable, FD filterDto); D get(I id); diff --git a/src/main/java/org/example/crm/service/EnrollmentService.java b/src/main/java/org/example/crm/service/EnrollmentService.java index 15e670f..368527a 100644 --- a/src/main/java/org/example/crm/service/EnrollmentService.java +++ b/src/main/java/org/example/crm/service/EnrollmentService.java @@ -2,8 +2,8 @@ import org.example.crm.entity.dto.enrollment.EnrollmentCreateDto; import org.example.crm.entity.dto.enrollment.EnrollmentDto; +import org.example.crm.filters.EnrollmentFilterDto; import org.example.crm.entity.dto.enrollment.EnrollmentUpdateDto; -import org.example.crm.entity.enums.EnrollmentPaymentStatus; import org.example.crm.entity.model.Enrollment; import org.example.crm.entity.model.Group; import org.example.crm.entity.model.Student; @@ -21,14 +21,13 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; -import java.math.BigDecimal; import java.util.List; @Service public class EnrollmentService extends AbstractService< EnrollmentRepository, EnrollmentMapper, - EnrollmentValidator> implements CrudService { + EnrollmentValidator> implements CrudService> { private final StudentValidator studentValidator; private final GroupValidator groupValidator; @@ -44,14 +43,9 @@ protected EnrollmentService(EnrollmentRepository repository, EnrollmentMapper ma } @Override - public Page getAll(Pageable pageable, String search) { + public Page getAll(Pageable pageable, EnrollmentFilterDto filterDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - Page allBySearch = repository.findAllBySearch(organizationId, search, pageable); - return allBySearch.map(mapper::toDto); - } - - public Page getAll(Pageable pageable, String search, String groupId) { - Page allBySearch = repository.findAllBySearch(groupId, pageable, search); + Page allBySearch = repository.findAllBySearch(organizationId, filterDto.groupId(), filterDto.search(), pageable); return allBySearch.map(mapper::toDto); } diff --git a/src/main/java/org/example/crm/service/GroupLevelService.java b/src/main/java/org/example/crm/service/GroupLevelService.java index 3da86b6..4708304 100644 --- a/src/main/java/org/example/crm/service/GroupLevelService.java +++ b/src/main/java/org/example/crm/service/GroupLevelService.java @@ -7,6 +7,7 @@ import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; import org.example.crm.exceptions.RestException; +import org.example.crm.filters.GroupLevelFilterDto; import org.example.crm.mapper.GroupLevelMapper; import org.example.crm.projection.LevelNamesProjection; import org.example.crm.repository.GroupLevelRepository; @@ -23,7 +24,7 @@ public class GroupLevelService extends AbstractService< GroupLevelRepository, GroupLevelMapper, - GroupLevelValidator> implements CrudService { + GroupLevelValidator> implements CrudService> { private final UserValidator userValidator; @@ -40,14 +41,14 @@ public List getGroupLevels(String search) { } @Override - public Page getAll(Pageable pageable, String search) { + public Page getAll(Pageable pageable, GroupLevelFilterDto search) { return null; } @Override public GroupLevelDto get(String id) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - validator.validateAndGet(id,organizationId); + validator.validateAndGet(id, organizationId); Level level = repository.findLevelByIdAndOrganizationId(id, organizationId) .orElseThrow(() -> new RestException(ErrorType.GROUP_LEVEL_NOT_FOUND, ErrorCodes.NotFound)); return mapper.toDto(level); @@ -64,8 +65,8 @@ public GroupLevelDto create(GroupLevelCreateDto createDto) { @Override public GroupLevelDto update(GroupLevelUpdateDto updateDto, String id) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - Level level = validator.validateAndGet(id,organizationId); - mapper.mapUpdate(level,updateDto); + Level level = validator.validateAndGet(id, organizationId); + mapper.mapUpdate(level, updateDto); repository.save(level); return mapper.toDto(level); } @@ -74,7 +75,7 @@ public GroupLevelDto update(GroupLevelUpdateDto updateDto, String id) { @Transactional public void delete(String id) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - Level level = validator.validateAndGet(id,organizationId); + Level level = validator.validateAndGet(id, organizationId); repository.updateLevelDeleted(level.getId(), organizationId); } @@ -94,7 +95,7 @@ public List getGroupLevelsName() { String organizationId = userValidator.authenticateAndGetOrganizationId(); log.info("orgId->{}", organizationId); List levelNames = repository.getLevelNames(organizationId); - log.info("size of result is {}",levelNames.size()); + log.info("size of result is {}", levelNames.size()); return levelNames.stream() .map(l -> new GroupLevelNameDto(l.getId(), l.getName())) .toList(); diff --git a/src/main/java/org/example/crm/service/GroupService.java b/src/main/java/org/example/crm/service/GroupService.java index eb612b5..736234b 100644 --- a/src/main/java/org/example/crm/service/GroupService.java +++ b/src/main/java/org/example/crm/service/GroupService.java @@ -1,20 +1,17 @@ package org.example.crm.service; import jakarta.transaction.Transactional; -import org.example.crm.entity.dto.group.FullGroupDto; +import org.example.crm.entity.dto.group.*; import org.example.crm.entity.dto.student.StudentDto; import org.example.crm.entity.enums.DayType; import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; -import org.example.crm.entity.enums.GroupStatus; import org.example.crm.entity.model.TimeTable; import org.example.crm.entity.model.User; import org.example.crm.exceptions.RestException; +import org.example.crm.filters.GroupFilterDto; import org.example.crm.projection.GroupNameProjection; import org.example.crm.projection.GroupProjection; -import org.example.crm.entity.dto.group.GroupDto; -import org.example.crm.entity.dto.group.GroupCreateDto; -import org.example.crm.entity.dto.group.GroupUpdateDto; import org.example.crm.entity.model.Group; import org.example.crm.mapper.GroupMapper; import org.example.crm.repository.GroupRepository; @@ -38,7 +35,7 @@ public class GroupService extends AbstractService< GroupRepository, GroupMapper, - GroupValidator> implements CrudService { + GroupValidator> implements CrudService> { private final UserValidator userValidator; private final StudentService studentService; @@ -54,24 +51,17 @@ protected GroupService(GroupRepository repository, GroupMapper mapper, GroupVali } @Override - public Page getAll(Pageable pageable, String search) { -// Page projectionPage = repository.getAllByFilter(search, pageable); -// return projectionPage. -// map(mapper::toDtoFromProjection); - return null; - } - - public Page getAll(Pageable pageable, String search, GroupStatus status, String level) { + public Page getAll(Pageable pageable, GroupFilterDto filterDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - String searchPattern = (search != null && !search.isBlank()) - ? "%" + search.trim().toLowerCase() + "%" + String searchPattern = (filterDto.search() != null && !filterDto.search().isBlank()) + ? "%" + filterDto.search().trim().toLowerCase() + "%" : null; Page groups = repository.getAllByFilter( organizationId, - status, - level, + filterDto.status(), + filterDto.level(), searchPattern, pageable ); @@ -182,7 +172,7 @@ public List getMyGroups() { String userId = userValidator.authenticateAndGetId(); List myGroups = repository.getMyGroups(userId); return myGroups.stream() - .map(g->mapper.toDto(g,null)) + .map(g -> mapper.toDto(g, null)) .toList(); } } diff --git a/src/main/java/org/example/crm/service/ImageService.java b/src/main/java/org/example/crm/service/ImageService.java index 8f56aeb..94f6c5e 100644 --- a/src/main/java/org/example/crm/service/ImageService.java +++ b/src/main/java/org/example/crm/service/ImageService.java @@ -4,11 +4,11 @@ import org.example.crm.entity.dto.image.ImageCreateDto; import org.example.crm.entity.dto.image.ImageDto; import org.example.crm.entity.dto.image.ImageUpdateDto; -import org.example.crm.entity.model.User; import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; import org.example.crm.entity.model.Image; import org.example.crm.exceptions.RestException; +import org.example.crm.filters.SearchFilterDto; import org.example.crm.mapper.ImageMapper; import org.example.crm.projection.ImageProjection; import org.example.crm.repository.ImageRepository; @@ -21,13 +21,13 @@ import org.springframework.web.multipart.MultipartFile; import java.io.IOException; -import java.util.Objects; +import java.util.List; @Service public class ImageService extends AbstractService< ImageRepository, ImageMapper, - ImageValidator> implements CrudService{ + ImageValidator> implements CrudService> { private final S3Service s3Service; private final UserValidator userValidator; @@ -41,10 +41,12 @@ protected ImageService(ImageRepository repository, ImageMapper mapper, ImageVali } @Override - public Page getAll(Pageable pageable, String search) { + public List getAll(Pageable pageable, SearchFilterDto search) { String userId = userValidator.authenticateAndGetId(); - Page allByUserId = repository.findAllByUserId(userId,pageable); - return allByUserId.map(mapper::toDto); + List allByUserId = repository.findAllByUserId(userId); + return allByUserId.stream() + .map(mapper::toDto) + .toList(); } @Override @@ -66,7 +68,7 @@ public ImageDto update(ImageUpdateDto updateDto, String id) { public void delete(String id) { validator.validateId(id); String userId = userValidator.authenticateAndGetId(); - repository.softDelete(id,userId); + repository.softDelete(id, userId); } public ImageDto uploadImage(@Valid MultipartFile file) throws IOException { @@ -88,7 +90,7 @@ public ImageDto uploadImage(@Valid MultipartFile file) throws IOException { String presignedUrl = s3Service.getPublicUrl(key); image.setImageUrl(presignedUrl); String userId = userValidator.authenticateAndGetId(); - userRepository.updateUserImage(userId,presignedUrl); + userRepository.updateUserImage(userId, presignedUrl); Image save = repository.save(image); return mapper.toDto(save); } @@ -96,6 +98,6 @@ public ImageDto uploadImage(@Valid MultipartFile file) throws IOException { public void updateMainImg(String id) { validator.validateId(id); String userId = userValidator.authenticateAndGetId(); - repository.updateMainImg(id,userId); + repository.updateMainImg(id, userId); } } diff --git a/src/main/java/org/example/crm/service/InvoiceService.java b/src/main/java/org/example/crm/service/InvoiceService.java index 4ff6083..66c7566 100644 --- a/src/main/java/org/example/crm/service/InvoiceService.java +++ b/src/main/java/org/example/crm/service/InvoiceService.java @@ -10,9 +10,11 @@ import org.example.crm.entity.model.Enrollment; import org.example.crm.entity.model.Group; import org.example.crm.entity.model.Invoice; +import org.example.crm.entity.model.Transaction; import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; import org.example.crm.exceptions.RestException; +import org.example.crm.filters.InvoiceFilterDto; import org.example.crm.mapper.InvoiceMapper; import org.example.crm.projection.InvoiceProjection; import org.example.crm.repository.EnrollmentRepository; @@ -33,7 +35,7 @@ public class InvoiceService extends AbstractService< InvoiceRepository, InvoiceMapper, - InvoiceValidator> implements CrudService { + InvoiceValidator> implements CrudService> { final StudentRepository studentRepository; final EnrollmentService enrollmentService; @@ -56,13 +58,6 @@ private String wrapSearch(String search) { return search != null ? "%" + search.toLowerCase() + "%" : null; } - @Override - public Page getAll(Pageable pageable, String search) { - Page projectionPage = repository. - getAllInvoicesByFilter(wrapSearch(search), null, null, null, pageable); - return projectionPage.map(mapper::toDtoFromProjection); - } - @Override public InvoiceDto get(String id) { Invoice invoice = validator.validateIdAndGet(id); @@ -87,11 +82,11 @@ public void delete(String id) { repository.softDelete(id); } - public Page getAllInvoices(String search, LocalDateTime from, LocalDateTime to, - InvoiceStatus status, Pageable pageable) { - from = from == null ? LocalDateTime.now().minusYears(4) : from; - to = to == null ? LocalDateTime.now() : to; - Page projectionPage = repository.getAllInvoicesByFilter(wrapSearch(search), from, to, status, pageable); + @Override + public Page getAll(Pageable pageable, InvoiceFilterDto filterDto) { + LocalDateTime from = filterDto.from() == null ? LocalDateTime.now().minusYears(4) : filterDto.from(); + LocalDateTime to = filterDto.to() == null ? LocalDateTime.now() : filterDto.to(); + Page projectionPage = repository.getAllInvoicesByFilter(wrapSearch(filterDto.search()), from, to, filterDto.status(), pageable); return projectionPage.map(mapper::toDtoFromProjection); } @@ -109,26 +104,29 @@ public void createGroupInvoice(String groupId) { } String levelName = group.getLevel().getName(); boolean alreadyCreated = repository.checkIfAlreadyCreated(groupId, levelName, group.getCurrentMonth()); - if (alreadyCreated){ - throw new RestException(ErrorType.INVOICE_ALREADY_CREATED,ErrorCodes.AlreadyExists); + if (alreadyCreated) { + throw new RestException(ErrorType.INVOICE_ALREADY_CREATED, ErrorCodes.AlreadyExists); } List enrollments = enrollmentRepository.getAllByGroupId(groupId); if (enrollments.isEmpty()) { throw new RestException(ErrorType.ENROLLMENT_NOT_FOUND, ErrorCodes.NotFound); } - List invoices = enrollments.stream() - .map(e -> mapper.toEntity(new InvoiceCreateDto(e.getId(), monthlyFee, levelName, group.getCurrentMonth()))) - .toList(); - repository.saveAll(invoices); + List invoices = repository.saveAll( + enrollments.stream() + .map(e -> mapper.toEntity(new InvoiceCreateDto(e.getId(), monthlyFee, levelName, group.getCurrentMonth()))) + .toList() + ); BigDecimal feeDebit = monthlyFee.negate(); - for (Enrollment enrollment : enrollments) { - transactionService.create(new TransactionCreateDto( - TransactionType.MONTHLY_FEE, - feeDebit, - enrollment.getStudent().getId() - )); + for (int i = 0; i < enrollments.size(); i++) { +// transactionService.create(new TransactionCreateDto( +// TransactionType.MONTHLY_FEE, +// feeDebit, +// enrollments.get(i).getStudent().getId(), +// invoices.get(i).getId() +// )); + transactionService.internalCreate(new Transaction(TransactionType.MONTHLY_FEE, feeDebit, null, invoices.get(i), enrollments.get(i).getStudent())); } } } diff --git a/src/main/java/org/example/crm/service/LeadService.java b/src/main/java/org/example/crm/service/LeadService.java index ed04673..459d024 100644 --- a/src/main/java/org/example/crm/service/LeadService.java +++ b/src/main/java/org/example/crm/service/LeadService.java @@ -19,6 +19,7 @@ import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; import org.example.crm.exceptions.RestException; +import org.example.crm.filters.LeadFilterDto; import org.example.crm.mapper.LeadMapper; import org.example.crm.projection.LeadProjection; import org.example.crm.repository.LeadRepository; @@ -36,7 +37,7 @@ public class LeadService extends AbstractService< LeadRepository, LeadMapper, - LeadValidator> implements CrudService { + LeadValidator> implements CrudService> { private final UserValidator userValidator; private final EnrollmentService enrollmentService; @@ -54,16 +55,12 @@ protected LeadService(LeadRepository repository, LeadMapper mapper, LeadValidato } @Override - public Page getAll(Pageable pageable, String search) { - return null; - } - - public Page getAll(Pageable pageable, String search, LeadStatus status) { + public Page getAll(Pageable pageable, LeadFilterDto filterDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - String searchPattern = (search != null && !search.isBlank()) - ? "%" + search.trim().toLowerCase() + "%" + String searchPattern = (filterDto.search() != null && !filterDto.search().isBlank()) + ? "%" + filterDto.search().trim().toLowerCase() + "%" : null; - Page all = repository.findAll(organizationId, searchPattern, status, pageable); + Page all = repository.findAll(organizationId, searchPattern, filterDto.status(), pageable); Page map = all.map(mapper::toDto); map.getContent().forEach(l -> System.out.println("lead->" + l)); return map; @@ -80,7 +77,7 @@ public LeadDto create(LeadCreateDto createDto) { validator.validate(createDto); Lead entity = mapper.toEntity(createDto); String organizationId = userValidator.authenticateAndGetOrganizationId(); - Level level = groupLevelValidator.validateAndGet(createDto.preferredCourseId(),organizationId); + Level level = groupLevelValidator.validateAndGet(createDto.preferredCourseId(), organizationId); entity.setPreferredCourse(level); return mapper.toDto(repository.save(entity)); } @@ -101,7 +98,7 @@ public LeadDto update(LeadUpdateDto updateDto, String id) { public void delete(String id) { validator.validateId(id); String organizationId = userValidator.authenticateAndGetOrganizationId(); - Integer integer = repository.softDelete(id,organizationId); + Integer integer = repository.softDelete(id, organizationId); if (integer == 0) { throw new RestException(ErrorType.LEAD_NOT_FOUND, ErrorCodes.NotFound); } diff --git a/src/main/java/org/example/crm/service/LessonService.java b/src/main/java/org/example/crm/service/LessonService.java index 717f9ce..82cdced 100644 --- a/src/main/java/org/example/crm/service/LessonService.java +++ b/src/main/java/org/example/crm/service/LessonService.java @@ -7,6 +7,7 @@ import org.example.crm.entity.enums.GroupStatus; import org.example.crm.entity.model.*; import org.example.crm.eventListeners.GroupCycleCompletedEvent; +import org.example.crm.filters.LessonFilterDto; import org.example.crm.mapper.LessonMapper; import org.example.crm.repository.*; import org.example.crm.validator.GroupValidator; @@ -21,7 +22,7 @@ public class LessonService extends AbstractService< LessonRepository, LessonMapper, - LessonValidator> implements CrudService { + LessonValidator> implements CrudService> { final TeacherRepository teacherRepository; private final GroupRepository groupRepository; private final UserValidator userValidator; @@ -41,9 +42,9 @@ protected LessonService(LessonRepository repository, LessonMapper mapper, Lesson } @Override - public Page getAll(Pageable pageable, String search) { + public Page getAll(Pageable pageable, LessonFilterDto filterDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - Page all = repository.findAll(pageable, organizationId, search); + Page all = repository.findAll(pageable, organizationId, filterDto.search()); return all.map(mapper::toDto); } diff --git a/src/main/java/org/example/crm/service/OrganizationService.java b/src/main/java/org/example/crm/service/OrganizationService.java index 37e5745..383ed66 100644 --- a/src/main/java/org/example/crm/service/OrganizationService.java +++ b/src/main/java/org/example/crm/service/OrganizationService.java @@ -5,6 +5,7 @@ import org.example.crm.entity.dto.organization.OrganizationDto; import org.example.crm.entity.dto.organization.OrganizationUpdateDto; import org.example.crm.entity.model.Organization; +import org.example.crm.filters.OrganizationFilterDto; import org.example.crm.mapper.OrganizationMapper; import org.example.crm.repository.OrganizationRepository; import org.example.crm.validator.OrganizationValidator; @@ -17,7 +18,7 @@ public class OrganizationService extends AbstractService< OrganizationRepository, OrganizationMapper, - OrganizationValidator> implements CrudService { + OrganizationValidator> implements CrudService> { private final UserValidator userValidator; protected OrganizationService(OrganizationRepository repository, OrganizationMapper mapper, OrganizationValidator validator, UserValidator userValidator) { @@ -26,8 +27,8 @@ protected OrganizationService(OrganizationRepository repository, OrganizationMap } @Override - public Page getAll(Pageable pageable, String search) { - Page all = repository.findAll(search, pageable); + public Page getAll(Pageable pageable, OrganizationFilterDto filterDto) { + Page all = repository.findAll(filterDto.search(), pageable); return all.map(mapper::toDto); } @@ -50,7 +51,7 @@ public OrganizationDto create(OrganizationCreateDto createDto) { public OrganizationDto update(OrganizationUpdateDto updateDto, String id) { validator.validate(updateDto); String organizationId = userValidator.authenticateAndGetOrganizationId(); - validator.validateOrganizationMatch(id,organizationId); + validator.validateOrganizationMatch(id, organizationId); Organization organization = validator.validateAndGetId(id); mapper.mapUpdate(organization, updateDto); return mapper.toDto(repository.save(organization)); diff --git a/src/main/java/org/example/crm/service/StudentService.java b/src/main/java/org/example/crm/service/StudentService.java index 6d851c7..37f685b 100644 --- a/src/main/java/org/example/crm/service/StudentService.java +++ b/src/main/java/org/example/crm/service/StudentService.java @@ -11,6 +11,7 @@ import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; import org.example.crm.exceptions.RestException; +import org.example.crm.filters.StudentFilterDto; import org.example.crm.mapper.StudentMapper; import org.example.crm.mapper.UserMapper; import org.example.crm.projection.StudentProjection; @@ -30,7 +31,7 @@ public class StudentService extends AbstractService< StudentRepository, StudentMapper, - StudentValidator> implements CrudService { + StudentValidator> implements CrudService> { final UserService userService; private final UserValidator userValidator; @@ -46,11 +47,10 @@ protected StudentService(StudentRepository repository, StudentMapper mapper, Stu } @Override - public Page getAll(Pageable pageable, String search) { - + public Page getAll(Pageable pageable, StudentFilterDto filterDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); log.info("org id of current user {}", organizationId); - Page all = repository.searchStudentsByOrganization(search, organizationId, pageable); + Page all = repository.searchStudentsByOrganization(filterDto.search(), organizationId, pageable); System.out.println(all); return all.map(mapper::toDtoProj); } diff --git a/src/main/java/org/example/crm/service/TeacherService.java b/src/main/java/org/example/crm/service/TeacherService.java index a194b79..3cda1f4 100644 --- a/src/main/java/org/example/crm/service/TeacherService.java +++ b/src/main/java/org/example/crm/service/TeacherService.java @@ -11,6 +11,7 @@ import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; import org.example.crm.exceptions.RestException; +import org.example.crm.filters.TeacherFilterDto; import org.example.crm.mapper.TeacherMapper; import org.example.crm.repository.TeacherRepository; import org.example.crm.repository.UserRepository; @@ -27,7 +28,7 @@ public class TeacherService extends AbstractService< TeacherRepository, TeacherMapper, - TeacherValidator> implements CrudService { + TeacherValidator> implements CrudService> { final UserValidator userValidator; final UserRepository userRepository; @@ -41,11 +42,11 @@ protected TeacherService(TeacherRepository repository, TeacherMapper mapper, Tea } @Override - public Page getAll(Pageable pageable, String search) { + public Page getAll(Pageable pageable, TeacherFilterDto filterDto) { String organizationId = userValidator.authenticateAndGetOrganizationId(); log.info("orgId of current user {}", organizationId); - Page all = repository.findAllBySearch(organizationId, search, pageable); + Page all = repository.findAllBySearch(organizationId, filterDto.search(), pageable); System.out.println(all); return all.map(mapper::toDto); } @@ -55,7 +56,7 @@ public TeacherDto get(String id) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - Teacher teacher = validator.validateIdAndGetOrg(id,organizationId); + Teacher teacher = validator.validateIdAndGetOrg(id, organizationId); return mapper.toDto(teacher); } @@ -82,7 +83,7 @@ public TeacherDto update(TeacherUpdateDto updateDto, String id) { public void delete(String id) { String organizationId = userValidator.authenticateAndGetOrganizationId(); - validator.validateId(id,organizationId); + validator.validateId(id, organizationId); repository.softDelete(id); } @@ -115,7 +116,6 @@ public TeacherDto create(@Valid TeacherCreateDto createDto, String organizationI public TeacherDto update(@Valid TeacherUpdateDto updateDto, String id, String organizationId) { - Teacher teacher = validator.validateIdAndGetOrg(id, organizationId); mapper.mapUpdate(teacher, updateDto); return mapper.toDto(repository.save(teacher)); @@ -132,7 +132,7 @@ public void delete(String id, String organizationId) { public List getMyGroup(String groupId) { String userId = userValidator.authenticateAndGetId(); - validator.validateGroupAndTeacher(userId,groupId); + validator.validateGroupAndTeacher(userId, groupId); return studentService.getStudentsByGroupId(groupId); } } diff --git a/src/main/java/org/example/crm/service/TimeTableService.java b/src/main/java/org/example/crm/service/TimeTableService.java index e17bb98..c5c9c60 100644 --- a/src/main/java/org/example/crm/service/TimeTableService.java +++ b/src/main/java/org/example/crm/service/TimeTableService.java @@ -6,6 +6,7 @@ import org.example.crm.entity.dto.timeTable.TimeTableDto; import org.example.crm.entity.enums.DayType; import org.example.crm.entity.model.TimeTable; +import org.example.crm.filters.TimeTableFilterDto; import org.example.crm.mapper.TimeTableMapper; import org.example.crm.projection.TimeTableProjection; import org.example.crm.repository.TimeTableRepository; @@ -21,15 +22,18 @@ public class TimeTableService extends AbstractService< TimeTableRepository, TimeTableMapper, - TimeTableValidator> implements CrudService { + TimeTableValidator> implements CrudService> { protected TimeTableService(TimeTableRepository repository, TimeTableMapper mapper, TimeTableValidator validator) { super(repository, mapper, validator); } @Override - public Page getAll(Pageable pageable, String search) { - return null; + public List getAll(Pageable pageable, TimeTableFilterDto filterDto) { + List projection = repository.getAllTimeTableByFilter(filterDto.dayType(), filterDto.start(), filterDto.end()); + return projection.stream() + .map(mapper::toDtoFromProjection) + .toList(); } @Override @@ -60,11 +64,4 @@ public void delete(String id) { TimeTable timeTable = validator.validateAndGet(id); repository.updateDeleted(timeTable.getId()); } - - public List getAll(DayType dayType, LocalTime start, LocalTime end) { - List projection = repository.getAllTimeTableByFilter(dayType,start,end); - return projection.stream() - .map(mapper::toDtoFromProjection) - .toList(); - } } diff --git a/src/main/java/org/example/crm/service/TransactionService.java b/src/main/java/org/example/crm/service/TransactionService.java index ec78f78..50f1ab3 100644 --- a/src/main/java/org/example/crm/service/TransactionService.java +++ b/src/main/java/org/example/crm/service/TransactionService.java @@ -3,7 +3,11 @@ import jakarta.transaction.Transactional; import org.example.crm.entity.dto.transaction.TransactionCreateDto; import org.example.crm.entity.dto.transaction.TransactionDto; +import org.example.crm.filters.TransactionFilterDto; import org.example.crm.entity.dto.transaction.TransactionUpdateDto; +import org.example.crm.entity.enums.TransactionType; +import org.example.crm.entity.model.Invoice; +import org.example.crm.entity.model.Student; import org.example.crm.entity.model.Transaction; import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; @@ -11,35 +15,45 @@ import org.example.crm.mapper.TransactionMapper; import org.example.crm.repository.StudentRepository; import org.example.crm.repository.TransactionRepository; +import org.example.crm.specs.TransactionSpec; +import org.example.crm.validator.InvoiceValidator; import org.example.crm.validator.OrganizationValidator; import org.example.crm.validator.TransactionValidator; import org.example.crm.validator.UserValidator; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; @Service public class TransactionService extends AbstractService< TransactionRepository, TransactionMapper, - TransactionValidator> implements CrudService { + TransactionValidator> implements CrudService> { private final UserValidator userValidator; private final OrganizationValidator organizationValidator; private final StudentRepository studentRepository; + private final InvoiceValidator invoiceValidator; - protected TransactionService(TransactionRepository repository, TransactionMapper mapper, TransactionValidator validator, UserValidator userValidator, OrganizationValidator organizationValidator, StudentRepository studentRepository) { + protected TransactionService(TransactionRepository repository, TransactionMapper mapper, TransactionValidator validator, UserValidator userValidator, OrganizationValidator organizationValidator, StudentRepository studentRepository, InvoiceValidator invoiceValidator) { super(repository, mapper, validator); this.userValidator = userValidator; this.organizationValidator = organizationValidator; this.studentRepository = studentRepository; + this.invoiceValidator = invoiceValidator; } @Override - public Page getAll(Pageable pageable, String search) { - String organizationId = userValidator.authenticateAndGetOrganizationId(); - Page transactions = repository.findAll(search, organizationId, pageable); - return transactions.map(mapper::toDto); + public Page getAll(Pageable pageable, TransactionFilterDto filterDto) { + String orgId = userValidator.authenticateAndGetOrganizationId(); + Specification spec = Specification + .where(TransactionSpec.isNotDeleted()) + .and(TransactionSpec.belongsToOrg(orgId)) + .and(TransactionSpec.hasType(filterDto.type())) + .and(TransactionSpec.searchKeyword(filterDto.search())); + + return repository.findAll(spec, pageable).map(mapper::toDto); } @Override @@ -51,34 +65,50 @@ public TransactionDto get(String id) { } @Override + @Transactional public TransactionDto create(TransactionCreateDto createDto) { - Transaction transaction = mapper.toEntity(createDto); - String organizationId = userValidator.authenticateAndGetOrganizationId(); - organizationValidator.validateOrganizationMatch(transaction.getInvoice().getOrganizationId(), organizationId); + String currentOrgId = userValidator.authenticateAndGetOrganizationId(); + Student student = studentRepository.findById(createDto.studentId()) + .orElseThrow(() -> new RestException(ErrorType.STUDENT_NOT_FOUND, ErrorCodes.NotFound)); + organizationValidator.validateOrganizationMatch(student.getUser().getOrganizationId(), currentOrgId); + + Invoice invoice = resolveInvoiceIfRequired(createDto, currentOrgId); + + Transaction transaction = mapper.toEntity(createDto, student, invoice); + validator.validate(transaction); + + Transaction saved = repository.save(transaction); + studentRepository.setNewBalance(saved.getAmount(), student.getId()); + + return mapper.toDto(saved); + } + + private Invoice resolveInvoiceIfRequired(TransactionCreateDto dto, String currentOrgId) { + if (dto.type() != TransactionType.MONTHLY_FEE) { + return null; + } + if (dto.invoiceId() == null || dto.invoiceId().isBlank()) { + throw new RestException(ErrorType.INVOICE_REQUIRED, ErrorCodes.BadRequest); + } + Invoice invoice = invoiceValidator.validateIdAndGet(dto.invoiceId()); + organizationValidator.validateOrganizationMatch(invoice.getOrganizationId(), currentOrgId); + return invoice; + } + + + public void internalCreate(Transaction transaction) { Transaction save = repository.save(transaction); - studentRepository.setNewBalance(save.getAmount(),createDto.studentId()); - return mapper.toDto(save); + studentRepository.setNewBalance(save.getAmount(), transaction.getStudent().getId()); } @Override - @Transactional public TransactionDto update(TransactionUpdateDto updateDto, String id) { - Transaction transaction = validator.validateIdAndGet(id); - String organizationId = userValidator.authenticateAndGetOrganizationId(); - organizationValidator.validateOrganizationMatch(transaction.getOrganizationId(), organizationId); - mapper.mapUpdate(transaction, updateDto); - Transaction save = repository.save(transaction); - return mapper.toDto(save); + return null; } @Override public void delete(String id) { - validator.validateId(id); - String organizationId = userValidator.authenticateAndGetOrganizationId(); - int rowsUpdated = repository.deleteByIdFalse(id, organizationId); - if (rowsUpdated == 0) { - throw new RestException(ErrorType.FORBIDDEN, ErrorCodes.Unauthorized); - } + } public Long getAllCount() { diff --git a/src/main/java/org/example/crm/service/UserService.java b/src/main/java/org/example/crm/service/UserService.java index b7a2e8c..77d0f45 100644 --- a/src/main/java/org/example/crm/service/UserService.java +++ b/src/main/java/org/example/crm/service/UserService.java @@ -9,6 +9,7 @@ import org.example.crm.entity.model.Branch; import org.example.crm.entity.model.User; import org.example.crm.exceptions.RestException; +import org.example.crm.filters.UserFilterDto; import org.example.crm.mapper.UserMapper; import org.example.crm.repository.BranchRepository; import org.example.crm.repository.UserRepository; @@ -24,7 +25,7 @@ public class UserService extends AbstractService< UserRepository, UserMapper, - UserValidator> implements CrudService { + UserValidator> implements CrudService> { final BranchRepository branchRepository; final BranchValidator branchValidator; @@ -38,8 +39,8 @@ protected UserService(UserRepository repository, UserMapper mapper, UserValidato } @Override - public Page getAll(Pageable pageable, String search) { - Page all = repository.findAll(pageable, search); + public Page getAll(Pageable pageable, UserFilterDto filterDto) { + Page all = repository.findAll(pageable, filterDto.search()); return all.map(mapper::toDto); } diff --git a/src/main/java/org/example/crm/specs/TransactionSpec.java b/src/main/java/org/example/crm/specs/TransactionSpec.java new file mode 100644 index 0000000..f0b62cb --- /dev/null +++ b/src/main/java/org/example/crm/specs/TransactionSpec.java @@ -0,0 +1,52 @@ +package org.example.crm.specs; + +import jakarta.persistence.criteria.Join; +import jakarta.persistence.criteria.JoinType; +import jakarta.persistence.criteria.Predicate; +import org.example.crm.entity.enums.TransactionType; +import org.example.crm.entity.model.Invoice; +import org.example.crm.entity.model.Student; +import org.example.crm.entity.model.Transaction; +import org.example.crm.entity.model.User; +import org.springframework.data.jpa.domain.Specification; + +import java.util.ArrayList; +import java.util.List; + +public class TransactionSpec { + + public static Specification isNotDeleted() { + return (root, query, cb) -> cb.isFalse(root.get("deleted")); + } + + public static Specification belongsToOrg(String orgId) { + return (root, query, cb) -> cb.equal(root.get("organizationId"), orgId); + } + + public static Specification hasType(TransactionType type) { + return (root, query, cb) -> type == null ? null : cb.equal(root.get("type"), type); + } + + public static Specification searchKeyword(String search) { + return (root, query, cb) -> { + if (search == null || search.trim().isEmpty()) { + return null; + } + + String pattern = "%" + search.trim().toLowerCase() + "%"; + + // Joins + Join invoiceJoin = root.join("invoice", JoinType.LEFT); + Join studentJoin = root.join("student", JoinType.INNER); + Join userJoin = studentJoin.join("user", JoinType.INNER); + + List predicates = new ArrayList<>(); + predicates.add(cb.like(cb.lower(invoiceJoin.get("invoiceNumber")), pattern)); + predicates.add(cb.like(cb.lower(userJoin.get("fullName")), pattern)); + predicates.add(cb.like(cb.lower(userJoin.get("phone")), pattern)); + predicates.add(cb.like(cb.lower(root.get("amount").as(String.class)), pattern)); + + return cb.or(predicates.toArray(new Predicate[0])); + }; + } +} \ No newline at end of file diff --git a/src/main/java/org/example/crm/validator/TransactionValidator.java b/src/main/java/org/example/crm/validator/TransactionValidator.java index 9d65bf5..fa5604b 100644 --- a/src/main/java/org/example/crm/validator/TransactionValidator.java +++ b/src/main/java/org/example/crm/validator/TransactionValidator.java @@ -1,6 +1,7 @@ package org.example.crm.validator; import lombok.RequiredArgsConstructor; +import org.example.crm.entity.enums.InvoiceStatus; import org.example.crm.entity.model.Transaction; import org.example.crm.exceptions.ErrorCodes; import org.example.crm.exceptions.ErrorType; @@ -25,4 +26,10 @@ public void validateId(String id) { throw new RestException(ErrorType.TRANSACTION_NOT_FOUND, ErrorCodes.NotFound); } } + + public void validate(Transaction transaction) { + if (transaction.getInvoice().getPaymentStatus().equals(InvoiceStatus.PAID)){ + throw new RestException(ErrorType.INVOICE_ALREADY_PAID,ErrorCodes.BadRequest); + } + } } \ No newline at end of file