diff --git a/src/main/java/com/codeplanks/home360/controller/ListingController.java b/src/main/java/com/codeplanks/home360/controller/ListingController.java index 8f4d8bc..e7836bf 100644 --- a/src/main/java/com/codeplanks/home360/controller/ListingController.java +++ b/src/main/java/com/codeplanks/home360/controller/ListingController.java @@ -15,6 +15,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; import lombok.RequiredArgsConstructor; +import org.bson.Document; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; @@ -308,4 +309,13 @@ public ResponseEntity> updateTakenListing( updatedListing.setStatus(HttpStatus.OK); return new ResponseEntity<>(updatedListing, HttpStatus.OK); } + + @GetMapping("/listing-statistics") + public ResponseEntity> getListingStatistics() { + SuccessDataResponse response = new SuccessDataResponse<>(); + response.setData(listingService.getAggregateListingStats()); + response.setMessage("Statistics data retrieved successfully"); + response.setStatus(HttpStatus.OK); + return new ResponseEntity<>(response, HttpStatus.OK); + } } diff --git a/src/main/java/com/codeplanks/home360/domain/listing/AggregateListingStatistics.java b/src/main/java/com/codeplanks/home360/domain/listing/AggregateListingStatistics.java new file mode 100644 index 0000000..54bac4b --- /dev/null +++ b/src/main/java/com/codeplanks/home360/domain/listing/AggregateListingStatistics.java @@ -0,0 +1,14 @@ +package com.codeplanks.home360.domain.listing; + +import lombok.Data; + +import java.util.List; + +@Data +public class AggregateListingStatistics { + private Integer total_listings; + private Integer rented_listings; + private Integer total_income; + private List income; + private List listings; +} diff --git a/src/main/java/com/codeplanks/home360/domain/listing/MonthlyIncome.java b/src/main/java/com/codeplanks/home360/domain/listing/MonthlyIncome.java new file mode 100644 index 0000000..48ecaaa --- /dev/null +++ b/src/main/java/com/codeplanks/home360/domain/listing/MonthlyIncome.java @@ -0,0 +1,17 @@ +package com.codeplanks.home360.domain.listing; + +import java.util.Map; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MonthlyIncome { + private int year; + private Map months; + + @Override + public String toString() { + return "MonthlyIncome{" + "year=" + year + ", months=" + months + '}'; + } +} diff --git a/src/main/java/com/codeplanks/home360/domain/listing/MonthlyListings.java b/src/main/java/com/codeplanks/home360/domain/listing/MonthlyListings.java new file mode 100644 index 0000000..1eb399c --- /dev/null +++ b/src/main/java/com/codeplanks/home360/domain/listing/MonthlyListings.java @@ -0,0 +1,21 @@ +package com.codeplanks.home360.domain.listing; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Map; + +@Getter +@Setter +public class MonthlyListings { + private int year; + private Map months; + + @Override + public String toString() { + return "MonthlyListings{" + + "year=" + year + + ", months=" + months + + '}'; + } +} diff --git a/src/main/java/com/codeplanks/home360/service/EmailServiceImpl.java b/src/main/java/com/codeplanks/home360/service/EmailServiceImpl.java index 340308c..5bec074 100644 --- a/src/main/java/com/codeplanks/home360/service/EmailServiceImpl.java +++ b/src/main/java/com/codeplanks/home360/service/EmailServiceImpl.java @@ -1,9 +1,9 @@ package com.codeplanks.home360.service; -import com.codeplanks.home360.service.EmailService; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; +import java.io.UnsupportedEncodingException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.javamail.JavaMailSender; @@ -13,8 +13,6 @@ import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; -import java.io.UnsupportedEncodingException; - @Service public class EmailServiceImpl implements EmailService { private final JavaMailSender mailSender; diff --git a/src/main/java/com/codeplanks/home360/service/ListingEnquiryServiceImpl.java b/src/main/java/com/codeplanks/home360/service/ListingEnquiryServiceImpl.java index 0c018e3..d7d2bce 100644 --- a/src/main/java/com/codeplanks/home360/service/ListingEnquiryServiceImpl.java +++ b/src/main/java/com/codeplanks/home360/service/ListingEnquiryServiceImpl.java @@ -34,7 +34,7 @@ public class ListingEnquiryServiceImpl implements ListingEnquiryService { private final AuthenticationUtils authenticationUtils; @Override - public ListingEnquiry makeEnquiry(@Valid ListingEnquiryDTO enquiryRequest) { + public ListingEnquiry makeEnquiry(ListingEnquiryDTO enquiryRequest) { if (authenticationUtils.isAuthenticated()) { Integer userId = userService.extractUserId(); enquiryRequest.setUserId(userId); diff --git a/src/main/java/com/codeplanks/home360/service/ListingServiceImpl.java b/src/main/java/com/codeplanks/home360/service/ListingServiceImpl.java index 657ac9c..89727bc 100644 --- a/src/main/java/com/codeplanks/home360/service/ListingServiceImpl.java +++ b/src/main/java/com/codeplanks/home360/service/ListingServiceImpl.java @@ -7,15 +7,20 @@ import com.codeplanks.home360.exception.UnAuthorizedException; import com.codeplanks.home360.repository.ListingRepository; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; +import org.bson.BsonNull; +import org.bson.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; @@ -27,6 +32,7 @@ public class ListingServiceImpl implements ListingService { private final ListingRepository listingRepository; private final UserServiceImpl userService; + @Autowired MongoTemplate mongoTemplate; Logger logger = LoggerFactory.getLogger(ListingServiceImpl.class); @@ -37,7 +43,6 @@ public Listing createListing(ListingDTO request) { throw new UnAuthorizedException( "You are not authorized to create a listing." + " Please confirm your email to proceed."); } - ; Listing listing = Listing.builder() @@ -153,4 +158,133 @@ public Listing updateRentedListing(RentUpdate rentUpdate) { return savedListing; } + + public Document getAggregateListingStats() { + Integer userId = userService.extractUserId(); + List pipeline = Arrays.asList(new Document("$match", + new Document("agent_id", userId)), + new Document("$facet", + new Document("totalListings", Arrays.asList(new Document("$count", "total_count"))) + .append("rentedListings", Arrays.asList(new Document("$match", + new Document("rented", true)), + new Document("$count", "total_rented"))) + .append("totalIncome", Arrays.asList(new Document("$match", + new Document("rented", true)), + new Document("$group", + new Document("_id", + new BsonNull()) + .append("total_income", + new Document("$sum", + new Document("$add", Arrays.asList("$cost.annual_rent", "$cost.agent_fee", "$cost.caution_fee", "$cost.agreement_fee"))))))) + .append("income", Arrays.asList(new Document("$match", + new Document("rented", true)), + new Document("$addFields", + new Document("total_income", + new Document("$add", Arrays.asList("$cost.annual_rent", "$cost.agent_fee", "$cost.caution_fee", "$cost.agreement_fee")))), + new Document("$group", + new Document("_id", + new Document("year", + new Document("$year", "$created_at")) + .append("month", + new Document("$month", "$created_at"))) + .append("total_income", + new Document("$sum", "$total_income"))), + new Document("$group", + new Document("_id", "$_id.year") + .append("months", + new Document("$push", + new Document("k", + new Document("$arrayElemAt", Arrays.asList(Arrays.asList("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), + new Document("$subtract", Arrays.asList("$_id.month", 1L))))) + .append("v", "$total_income")))), + new Document("$addFields", + new Document("months", + new Document("$mergeObjects", Arrays.asList(new Document("$arrayToObject", + new Document("$map", + new Document("input", + new Document("$range", Arrays.asList(0L, + new Document("$cond", Arrays.asList(new Document("$eq", Arrays.asList("$_id", + new Document("$year", + new java.util.Date()))), + new Document("$month", + new java.util.Date()), 12L))))) + .append("as", "i") + .append("in", + new Document("k", + new Document("$arrayElemAt", Arrays.asList(Arrays.asList("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), "$$i"))) + .append("v", 0L)))), + new Document("$arrayToObject", "$months"))))), + new Document("$addFields", + new Document("months", + new Document("$map", + new Document("input", + new Document("$objectToArray", "$months")) + .append("as", "m") + .append("in", + new Document("name", "$$m.k") + .append( + "amount", "$$m.v"))))), + new Document("$project", + new Document("_id", 0L) + .append("year", "$_id") + .append("months", 1L)))) + .append("listings", Arrays.asList(new Document("$group", + new Document("_id", + new Document("year", + new Document("$year", "$created_at")) + .append("month", + new Document("$month", "$created_at"))) + .append("count", + new Document("$sum", 1L))), + new Document("$group", + new Document("_id", "$_id.year") + .append("months", + new Document("$push", + new Document("k", + new Document("$arrayElemAt", Arrays.asList(Arrays.asList("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), + new Document("$subtract", Arrays.asList("$_id.month", 1L))))) + .append("v", "$count")))), + new Document("$addFields", + new Document("months", + new Document("$mergeObjects", Arrays.asList(new Document("$arrayToObject", + new Document("$map", + new Document("input", + new Document("$range", Arrays.asList(0L, + new Document("$cond", Arrays.asList(new Document("$eq", Arrays.asList("$_id", + new Document("$year", + new java.util.Date()))), + new Document("$month", + new java.util.Date()), 12L))))) + .append("as", "i") + .append("in", + new Document("k", + new Document("$arrayElemAt", Arrays.asList(Arrays.asList("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), "$$i"))) + .append("v", 0L)))), + new Document("$arrayToObject", "$months"))))), + new Document("$addFields", + new Document("months", + new Document("$map", + new Document("input", + new Document("$objectToArray", "$months")) + .append("as", "m") + .append("in", + new Document("name", "$$m.k") + .append( + "amount", "$$m.v"))))), + new Document("$project", + new Document("_id", 0L) + .append("year", "$_id") + .append("months", 1L))))), + new Document("$project", + new Document("total_listings", + new Document("$arrayElemAt", Arrays.asList("$totalListings.total_count", 0L))) + .append("rented_listings", + new Document("$arrayElemAt", Arrays.asList("$rentedListings.total_rented", 0L))) + .append("total_income", + new Document("$arrayElemAt", Arrays.asList("$totalIncome.total_income", 0L))) + .append("income", "$income") + .append("listings", "$listings"))); + + return mongoTemplate.getDb().getCollection("listings").aggregate(pipeline).first(); + } }