diff --git a/.gitignore b/.gitignore index 0a8a77f..3c0caa3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Log file *.log +*.iml # BlueJ files *.ctxt @@ -76,4 +77,6 @@ baseline.json .history # Husky -.husky/_ \ No newline at end of file +.husky/_ + +.angular \ No newline at end of file diff --git a/README.md b/README.md index 2f7a896..bc6f490 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,32 @@ -# SocialServiceFinder -My first commit - -#CORS Filter (Change the port number accordingly) -@Bean -public CorsFilter corsFilter() { -CorsConfiguration corsConfiguration = new CorsConfiguration(); -corsConfiguration.setAllowCredentials(true); -corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:4202")); -corsConfiguration.setAllowedHeaders(Arrays.asList("Origin", "Access-Control-Allow-Origin", "Content-Type", -"Accept", "Authorization", "Origin, Accept", "X-Requested-With", -"Access-Control-Request-Method", "Access-Control-Request-Headers")); -corsConfiguration.setExposedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "Authorization", -"Access-Control-Allow-Origin", "Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")); -corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); -UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); -urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); -return new CorsFilter(urlBasedCorsConfigurationSource); -} \ No newline at end of file +## SocialServiceFinder + +### [Video Link](https://www.youtube.com/watch?v=DoI5_Ww7daA) + +### Abstract + +There are many people who would like to do community services, but don’t know the places that offer the opportunity for +the same. Our project aims to provide a platform not only to people who seek non-profit organizations for any +opportunities where they can contribute, but also to encourage more people by rewarding them for doing good deeds. We +also plan on helping the organizations that are looking for volunteers to help them. + +We are planning to create a web platform that creates and manages volunteering opportunities (posted by social service +organizations). Users can search for an opportunity based on various criterias like location, type of service required, +type of organizations listing the opportunities, etc. For motivating the users, rewards from various partner companies +will be offered to those who volunteer in these events. We are planning to implement a microservice based architecture +using SOLID principles, and create a complete system with a reactive frontend, scalable backend software and a NOSQL +database. For internal communication within the services, we will be using Messaging channels between them. We are +focusing on microservice based architecture because we want to create a robust, maintainable and a highly scalable +system in a way that makes it easy to add more features in the future, supporting Agile methodology. We are also +planning to cover the features using functional tests. + +### Setup + +TO DO Add instructions to set up Elasticsearch + +#### Pre-reqs: + +1. Java +2. Angular Cli +3. MongoDb +4. Git + diff --git a/eventservice/pom.xml b/eventservice/pom.xml new file mode 100644 index 0000000..758e7d6 --- /dev/null +++ b/eventservice/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.2 + + + com.socialservicefinder + eventservice + 0.0.1-SNAPSHOT + eventservice + Event Service Folder for Social Service Finder Project + + 11 + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.data + spring-data-mongodb + + + + org.springframework.data + spring-data-elasticsearch + 4.3.4 + + + junit + junit + test + + + com.socialservicefinder + userservice + 0.0.1-SNAPSHOT + compile + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/EventServiceApplication.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/EventServiceApplication.java new file mode 100644 index 0000000..424e4f4 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/EventServiceApplication.java @@ -0,0 +1,36 @@ +package com.socialservicefinder.eventservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +import java.util.Arrays; + +@SpringBootApplication +@ComponentScan(basePackages = {"com.socialservicefinder.eventservice", "com.socialservicefinder.userservice"}) +public class EventServiceApplication { + public static void main(String[] args) { + SpringApplication.run(EventServiceApplication.class, args); + } + + //CORS is some mechanism added by mordern browswers. just copy pasting. More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS + @Bean + public CorsFilter corsFilter1() { + CorsConfiguration corsConfiguration = new CorsConfiguration(); + corsConfiguration.setAllowCredentials(true); + corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:4200")); + corsConfiguration.setAllowedHeaders(Arrays.asList("Origin", "Access-Control-Allow-Origin", "Content-Type", + "Accept", "Authorization", "Origin, Accept", "X-Requested-With", + "Access-Control-Request-Method", "Access-Control-Request-Headers")); + corsConfiguration.setExposedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "Authorization", + "Access-Control-Allow-Origin", "Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")); + corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); + UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); + urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); + return new CorsFilter(urlBasedCorsConfigurationSource); + } +} diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/controller/EventController.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/controller/EventController.java new file mode 100644 index 0000000..8eef4d5 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/controller/EventController.java @@ -0,0 +1,119 @@ +package com.socialservicefinder.eventservice.controller; + +import com.socialservicefinder.eventservice.dto.*; +import com.socialservicefinder.eventservice.exceptions.InvalidEventException; +import com.socialservicefinder.eventservice.service.EventLookUpService; +import com.socialservicefinder.eventservice.service.EventService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@RestController +@RequestMapping(path = "api/v1/event") +public class EventController { + private final EventService eventService; + private final EventLookUpService eventLookUpService; + + @Autowired + public EventController(EventService eventService, EventLookUpService eventLookUpService) { + this.eventService = eventService; + this.eventLookUpService = eventLookUpService; + } + + @GetMapping + public List getEvents() { + return eventService.getEvents(); + } + + @PostMapping + public ResponseEntity addEvent(@RequestBody Event event) { + try { + eventService.addEvent(event); + return ResponseEntity.status(HttpStatus.OK).body(null); + } catch (InvalidEventException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + } + + @PostMapping + @RequestMapping("/update/") + public ResponseEntity updateEvent(@RequestBody Event event) { + try { + eventService.updateEvent(event); + return ResponseEntity.status(HttpStatus.OK).body(null); + } catch (InvalidEventException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + } + + @PostMapping + @RequestMapping("/delete/") + public ResponseEntity deleteEvent(@RequestBody Event event) { + try { + eventService.deleteEvent(event); + return ResponseEntity.status(HttpStatus.OK).body(null); + } catch (InvalidEventException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + } + + @GetMapping + @RequestMapping("/search/") + public List getMatchingEvents(@RequestBody SearchQuery q) { + try { + if (q.getQuery().isEmpty()) { + return Collections.emptyList(); + } + Page eventLookUps = eventLookUpService.findEventLookUpByEventInfoContaining(q.getQuery(), PageRequest.of(0, 10)); + List eventIds = new ArrayList<>(); + eventLookUps.forEach(x -> eventIds.add(x.getEventId())); + List events = eventService.findEventsByIds(eventIds); + for (Event e : events) { + //Logging events coming from search + System.out.println(e.toString()); + } + System.out.println("Query String:" + q.getQuery()); + return events; + } catch (Exception e) { + return Collections.emptyList(); + } + } + + @GetMapping + @RequestMapping("/fetchMyEvents/") + public List fetchMyEvents(@RequestBody FetchMyEvents f) { + try { + if (f.getId().length() == 0) { + return Collections.emptyList(); + } + return eventService.fetchMyEvents(f.getId(), f.getIsOrganizer(), false); + } catch (Exception e) { + return Collections.emptyList(); + } + } + + @PutMapping + @RequestMapping("/registerForEvent") + public ResponseEntity registerUserForEvent(@RequestBody RegisterEvent eventToRegister){ + try { + eventService.registerUserForEvent(eventToRegister); + return ResponseEntity.status(HttpStatus.OK).body(null); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + } + +} diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/Event.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/Event.java new file mode 100644 index 0000000..d92c383 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/Event.java @@ -0,0 +1,182 @@ +package com.socialservicefinder.eventservice.dto; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.Date; +import java.util.Set; +import java.util.UUID; + +@Document("events") +public class Event { + @Id + private String id; + private String name; + private String description; + private String phoneNo; + private String address; + private String city; + private long rewards; + private long pinCode; + private String email; + private String pocName; + private Date startDate; + private Date endDate; + private String organizationId; + private Set registeredUsers; + private boolean deleted; + + @Override + public String toString() { + return "Event [name=" + name + ", description=" + description + ", phoneNo=" + phoneNo + ", email=" + email + ", POCName=" + pocName + + ", address=" + address + ", city=" + city + ", rewards=" + rewards + ", pinCode=" + + pinCode + ", startDate=" + startDate.toString() + ", endDate=" + endDate.toString() + ", isDeleted=" + deleted + "]"; + } + + public Event() { + super(); + } + + public Event(String name, String description, String phoneNo, String address, String city, long rewards, long pinCode, String email, String pocName, Date startDate, Date endDate, boolean deleted) { + this.name = name; + this.description = description; + this.phoneNo = phoneNo; + this.address = address; + this.city = city; + this.rewards = rewards; + this.pinCode = pinCode; + this.email = email; + this.pocName = pocName; + this.startDate = startDate; + this.endDate = endDate; + this.deleted = deleted; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPocName() { + return pocName; + } + + public void setPocName(String pocName) { + this.pocName = pocName; + } + + public void assign_id() { + this.id = UUID.randomUUID().toString(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPhoneNo() { + return phoneNo; + } + + public void setPhoneNo(String phoneNo) { + this.phoneNo = phoneNo; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public long getRewards() { + return rewards; + } + + public void setRewards(long rewards) { + this.rewards = rewards; + } + + public long getPinCode() { + return pinCode; + } + + public void setPinCode(long pinCode) { + this.pinCode = pinCode; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + public String getOrganizationId() { + return organizationId; + } + + public void setOrganizationId(String organizationId) { + this.organizationId = organizationId; + } + + public Set getRegisteredUsers() { + return registeredUsers; + } + + public void setRegisteredUsers(Set registeredUsers) { + this.registeredUsers = registeredUsers; + } + + public void addRegisteredUser(String id) { + registeredUsers.add(id); + } +} diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/EventLookUp.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/EventLookUp.java new file mode 100644 index 0000000..939cac0 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/EventLookUp.java @@ -0,0 +1,42 @@ +package com.socialservicefinder.eventservice.dto; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; + +@Document(indexName = "eventlookup") +public class EventLookUp { + @Id + private String id; + private String eventId; + private String eventInfo; + + public EventLookUp(String id, String eventId, String eventInfo) { + this.id = id; + this.eventId = eventId; + this.eventInfo = eventInfo; + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public String getEventInfo() { + return eventInfo; + } + + public void setEventInfo(String eventInfo) { + this.eventInfo = eventInfo; + } + + @Override + public String toString() { + return "EventLookUp{" + + "id=" + id + ", " + + "eventId=" + eventId + ", " + + "eventInfo=" + eventInfo + "}"; + } +} diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/FetchMyEvents.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/FetchMyEvents.java new file mode 100644 index 0000000..3a5af88 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/FetchMyEvents.java @@ -0,0 +1,27 @@ +package com.socialservicefinder.eventservice.dto; + +public class FetchMyEvents { + private String id; + private boolean isOrganizer; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public boolean getIsOrganizer() { + return isOrganizer; + } + + public void setOrganizer(boolean organizer) { + isOrganizer = organizer; + } + + @Override + public String toString() { + return "Fetching events for [id=" + id + ", " + "isOrganizer=" + isOrganizer + "]"; + } +} diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/RegisterEvent.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/RegisterEvent.java new file mode 100644 index 0000000..2734f53 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/RegisterEvent.java @@ -0,0 +1,23 @@ +package com.socialservicefinder.eventservice.dto; + +public class RegisterEvent { + + String userId; + String eventId; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } +} diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/SearchQuery.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/SearchQuery.java new file mode 100644 index 0000000..a651e2f --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/dto/SearchQuery.java @@ -0,0 +1,18 @@ +package com.socialservicefinder.eventservice.dto; + +public class SearchQuery { + private String query; + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + @Override + public String toString() { + return "Search Query [query=" + query + "]"; + } +} diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/exceptions/InvalidEventException.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/exceptions/InvalidEventException.java new file mode 100644 index 0000000..fdf4390 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/exceptions/InvalidEventException.java @@ -0,0 +1,15 @@ +package com.socialservicefinder.eventservice.exceptions; + +public class InvalidEventException extends RuntimeException { + public InvalidEventException() { + super(); + } + + public InvalidEventException(String errorMessage) { + super(errorMessage); + } + + public InvalidEventException(String errorMessage, Throwable throwable) { + super(errorMessage, throwable); + } +} diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/repository/EventLookUpRepository.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/repository/EventLookUpRepository.java new file mode 100644 index 0000000..fecdbf8 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/repository/EventLookUpRepository.java @@ -0,0 +1,10 @@ +package com.socialservicefinder.eventservice.repository; + +import com.socialservicefinder.eventservice.dto.EventLookUp; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; + +public interface EventLookUpRepository extends ElasticsearchRepository { + Page findEventLookUpByEventInfoContaining(String query, Pageable pageable); +} \ No newline at end of file diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/repository/EventRepository.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/repository/EventRepository.java new file mode 100644 index 0000000..fac769f --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/repository/EventRepository.java @@ -0,0 +1,14 @@ +package com.socialservicefinder.eventservice.repository; + +import com.socialservicefinder.eventservice.dto.Event; +import org.springframework.data.mongodb.repository.MongoRepository; + +import java.util.List; + +public interface EventRepository extends MongoRepository { + List findEventByNameContains(String name); + + List findEventByOrganizationIdAndDeletedIs(String id, boolean isDeleted); + + List findEventByOrganizationIdAndDeleted(String id, boolean isDeleted); +} diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/service/EventLookUpService.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/service/EventLookUpService.java new file mode 100644 index 0000000..319b006 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/service/EventLookUpService.java @@ -0,0 +1,15 @@ +package com.socialservicefinder.eventservice.service; + +import com.socialservicefinder.eventservice.dto.EventLookUp; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface EventLookUpService { + EventLookUp save(EventLookUp eventLookUp); + + void delete(EventLookUp eventLookUp); + + Iterable findAll(); + + Page findEventLookUpByEventInfoContaining(String query, Pageable pageable); +} \ No newline at end of file diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/service/EventLookUpServiceImpl.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/service/EventLookUpServiceImpl.java new file mode 100644 index 0000000..f5a83c8 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/service/EventLookUpServiceImpl.java @@ -0,0 +1,40 @@ +package com.socialservicefinder.eventservice.service; + +import com.socialservicefinder.eventservice.dto.EventLookUp; +import com.socialservicefinder.eventservice.repository.EventLookUpRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +@Service +@Component +public class EventLookUpServiceImpl implements EventLookUpService { + private final EventLookUpRepository eventLookUpRepository; + + @Autowired + public EventLookUpServiceImpl(EventLookUpRepository eventLookUpRepository) { + this.eventLookUpRepository = eventLookUpRepository; + } + + @Override + public EventLookUp save(EventLookUp eventLookUp) { + return eventLookUpRepository.save(eventLookUp); + } + + @Override + public void delete(EventLookUp eventLookUp) { + eventLookUpRepository.delete(eventLookUp); + } + + @Override + public Iterable findAll() { + return eventLookUpRepository.findAll(); + } + + @Override + public Page findEventLookUpByEventInfoContaining(String query, Pageable pageable) { + return eventLookUpRepository.findEventLookUpByEventInfoContaining(query, pageable); + } +} \ No newline at end of file diff --git a/eventservice/src/main/java/com/socialservicefinder/eventservice/service/EventService.java b/eventservice/src/main/java/com/socialservicefinder/eventservice/service/EventService.java new file mode 100644 index 0000000..d03b272 --- /dev/null +++ b/eventservice/src/main/java/com/socialservicefinder/eventservice/service/EventService.java @@ -0,0 +1,157 @@ +package com.socialservicefinder.eventservice.service; + +import com.mongodb.MongoWriteException; +import com.socialservicefinder.eventservice.dto.Event; +import com.socialservicefinder.eventservice.dto.EventLookUp; +import com.socialservicefinder.eventservice.dto.RegisterEvent; +import com.socialservicefinder.eventservice.exceptions.InvalidEventException; +import com.socialservicefinder.eventservice.repository.EventRepository; +import com.socialservicefinder.userservice.dto.User; +import com.socialservicefinder.userservice.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.HashSet; + +@Service +@Component +public class EventService { + private final EventRepository eventRepository; + private final EventLookUpService eventLookUpService; + private final UserService userService; + private final int NO_OF_TRIES; + + @Autowired + public EventService(EventRepository eventRepository, EventLookUpService eventLookUpService, UserService userService) { + this.eventRepository = eventRepository; + this.eventLookUpService = eventLookUpService; + this.userService = userService; + this.NO_OF_TRIES = 5; + } + + public List getEvents() { + return eventRepository.findAll(); + } + + public List getMatchingEvents(String name) { + return eventRepository.findEventByNameContains(name); + } + + public List findEventsByIds(List eventIds) { + Iterable itr = eventRepository.findAllById(eventIds); + List events = new ArrayList<>(); + while (itr.iterator().hasNext()) { + Event e = itr.iterator().next(); + if (!e.isDeleted()) { + events.add(e); + } + } + return events; + } + + public List fetchMyEvents(String id, boolean isOrganization, boolean isDeleted) { + List eventIds; + if (isOrganization) { + return eventRepository.findEventByOrganizationIdAndDeleted(id, isDeleted); + } else { + eventIds = userService.getEventIds(id); + List events = new ArrayList<>(); + for (String eventId : eventIds) { + Optional event = eventRepository.findById(eventId); + if (event.isPresent() && !event.get().isDeleted()) { + events.add(event.get()); + } + } + return events; + } + } + + public void addEvent(Event e) { + if (e == null || e.getName() == null || e.getAddress() == null || e.getDescription() == null) { + throw new InvalidEventException("name, address or description cannot be null or empty"); + } + e.setRegisteredUsers(new HashSet<>()); + insertEvent(e); + } + + public void updateEvent(Event e) { + if (e == null || e.getName() == null || e.getAddress() == null || e.getDescription() == null) { + throw new InvalidEventException("name, address or description cannot be null or empty"); + } + updateEvents(e); + } + + public void deleteEvent(Event e) { + if (e == null || e.getName() == null || e.getAddress() == null || e.getDescription() == null) { + throw new InvalidEventException("Cannot delete event: name, address or description cannot be null or empty"); + } + boolean id_assigned = false; + for (int tries = 0; tries < NO_OF_TRIES; tries++) { + try { + e.setDeleted(true); + eventRepository.save(e); + eventLookUpService.delete(new EventLookUp(e.getId(), e.getId(), e.toString())); + id_assigned = true; + break; + } catch (MongoWriteException ignored) { + } + } + if (!id_assigned) + throw new InvalidEventException("Please try after sometime."); + } + + private void updateEvents(Event e) { + boolean id_assigned = false; + for (int tries = 0; tries < NO_OF_TRIES; tries++) { + try { + eventRepository.save(e); + eventLookUpService.save(new EventLookUp(e.getId(), e.getId(), e.toString())); + id_assigned = true; + break; + } catch (MongoWriteException ignored) { + } + } + if (!id_assigned) + throw new InvalidEventException("Please try after sometime."); + } + + private void insertEvent(Event e) { + boolean id_assigned = false; + for (int tries = 0; tries < NO_OF_TRIES; tries++) { + try { + e.assign_id(); + eventRepository.insert(e); + eventLookUpService.save(new EventLookUp(e.getId(), e.getId(), e.toString())); + id_assigned = true; + break; + } catch (MongoWriteException ignored) { + } + } + if (!id_assigned) + throw new InvalidEventException("Please try after sometime."); + } + + public void registerUserForEvent(RegisterEvent eventToRegister) { + try { + String eventId = eventToRegister.getEventId(); + String userId = eventToRegister.getUserId(); + List events = findEventsByIds(Arrays.asList(eventId)); + User user = userService.getUserById(userId); + + for (Event event : events) { + event.getRegisteredUsers().add(userId); + //eventRepository.save(event); + updateEvent(event); + user.getEventIds().add(eventId); + userService.setNewRewardsForUser(user, event.getRewards()); + userService.updateUser(user); + } + } catch (Exception exception) { + } + } +} diff --git a/eventservice/src/main/resources/application.properties b/eventservice/src/main/resources/application.properties new file mode 100644 index 0000000..2091b08 --- /dev/null +++ b/eventservice/src/main/resources/application.properties @@ -0,0 +1,5 @@ +server.port=8091 +spring.data.mongodb.url=mongodb://localhost:27017/socialservicefinder +spring.data.mongodb.database=socialservicefinder +spring.data.mongodb.port=27017 +spring.data.mongodb.host=localhost \ No newline at end of file diff --git a/eventservice/src/test/java/com/socialservicefinder/eventservice/EventServiceApplicationIntegrationTests.java b/eventservice/src/test/java/com/socialservicefinder/eventservice/EventServiceApplicationIntegrationTests.java new file mode 100644 index 0000000..f881964 --- /dev/null +++ b/eventservice/src/test/java/com/socialservicefinder/eventservice/EventServiceApplicationIntegrationTests.java @@ -0,0 +1,76 @@ +package com.socialservicefinder.eventservice; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.socialservicefinder.eventservice.dto.Event; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.Date; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; + +@SpringBootTest +@AutoConfigureMockMvc +public class EventServiceApplicationIntegrationTests { + @Autowired + private MockMvc mockMvc; + + @Test + public void shouldReturnDefaultMessage() throws Exception { + this.mockMvc.perform(get("/api/v1/event")).andExpect(status().isOk()); + } + + @Test + public void post_endpoint_should_return_ok() throws Exception { + Date startDate = new Date(System.currentTimeMillis() - 10000); + Date endDate = new Date(System.currentTimeMillis()); + Event event = new Event("Covid Campaign", "Campaign to raise covid awareness", "9499926608", "3901 Parkview Ln, Apt 8A", "Irvine", 10000, 92612, "abc@gmail.com", "Covid", startDate, endDate, false); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(event); + this.mockMvc.perform( + post("/api/v1/event").contentType(MediaType.APPLICATION_JSON).content(json).characterEncoding("utf-8")) + .andExpect(status().isOk()); + } + + @Test + public void post_endpoint_null_name_should_return_badRequest() throws Exception { + Date startDate = new Date(System.currentTimeMillis() - 10000); + Date endDate = new Date(System.currentTimeMillis()); + Event event = new Event(null, "Campaign to raise covid awareness", "9499926608", "3901 Parkview Ln, Apt 8A", "Irvine", 10000, 92612, "abc@gmail.com", "Covid", startDate, endDate, false); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(event); + this.mockMvc.perform( + post("/api/v1/event").contentType(MediaType.APPLICATION_JSON).content(json).characterEncoding("utf-8")) + .andExpect(status().isBadRequest()); + } + + @Test + public void post_endpoint_null_description_should_return_badRequest() throws Exception { + Date startDate = new Date(System.currentTimeMillis() - 10000); + Date endDate = new Date(System.currentTimeMillis()); + Event event = new Event("Covid Campaign", null, "9499926608", "3901 Parkview Ln, Apt 8A", "Irvine", 10000, 92612, "abc@gmail.com", "Covid", startDate, endDate, false); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(event); + this.mockMvc.perform( + post("/api/v1/event").contentType(MediaType.APPLICATION_JSON).content(json).characterEncoding("utf-8")) + .andExpect(status().isBadRequest()); + } + + @Test + public void post_endpoint_null_address_should_return_badRequest() throws Exception { + Date startDate = new Date(System.currentTimeMillis() - 10000); + Date endDate = new Date(System.currentTimeMillis()); + Event event = new Event("Covid Campaign", "Campaign to raise covid awareness", "9499926608", null, "Irvine", 10000, 92612, "abc@gmail.com", "Covid", startDate, endDate, false); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(event); + this.mockMvc.perform( + post("/api/v1/event").contentType(MediaType.APPLICATION_JSON).content(json).characterEncoding("utf-8")) + .andExpect(status().isBadRequest()); + } +} \ No newline at end of file diff --git a/eventservice/src/test/java/com/socialservicefinder/eventservice/EventServiceApplicationTestConfiguration.java b/eventservice/src/test/java/com/socialservicefinder/eventservice/EventServiceApplicationTestConfiguration.java new file mode 100644 index 0000000..ba17b3b --- /dev/null +++ b/eventservice/src/test/java/com/socialservicefinder/eventservice/EventServiceApplicationTestConfiguration.java @@ -0,0 +1,18 @@ +package com.socialservicefinder.eventservice; + +import com.socialservicefinder.eventservice.service.EventService; +import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; + +@Profile("test") +@Configuration +public class EventServiceApplicationTestConfiguration { + @Bean + @Primary + public EventService nameService() { + return Mockito.mock(EventService.class); + } +} diff --git a/eventservice/src/test/java/com/socialservicefinder/eventservice/EventServiceApplicationTests.java b/eventservice/src/test/java/com/socialservicefinder/eventservice/EventServiceApplicationTests.java new file mode 100644 index 0000000..7867554 --- /dev/null +++ b/eventservice/src/test/java/com/socialservicefinder/eventservice/EventServiceApplicationTests.java @@ -0,0 +1,50 @@ +package com.socialservicefinder.eventservice; + +import com.socialservicefinder.eventservice.dto.Event; +import com.socialservicefinder.eventservice.service.EventService; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Date; +import java.util.List; + +@ActiveProfiles("test") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {EventServiceApplication.class}) +class EventServiceApplicationTests { + private static List _events; + @Autowired + private EventService eventService; + + @BeforeEach + public void init() { + Date startDate = new Date(System.currentTimeMillis() - 10000); + Date endDate = new Date(System.currentTimeMillis()); + _events = List.of( + new Event("Covid Campaign", "Campaign to raise covid awareness", "9499926608", "3901 Parkview Ln, Apt 8A", "Irvine", 10000, 92612, "abc@gmail.com", "Covid", startDate, endDate, false), + new Event("Covid Campaign - I", "Campaign I to raise covid awareness", "9499926608", "3901 Parkview Ln, Apt 8A", "Irvine", 50000, 92612, "abc@gmail.com", "Covid", startDate, endDate, false), + new Event("Covid Campaign - II", "Campaign II to raise covid awareness", "9499926609", "3901 Parkview Ln, Apt 8A", "Irvine", 5000, 92613, "abc@gmail.com", "Covid", startDate, endDate, false), + new Event("Covid Campaign - III", "Campaign III to raise covid awareness", "9499926610", "3901 Parkview Ln, Apt 8A", "Irvine", 45000, 92614, "abc@gmail.com", "Covid", startDate, endDate, false)); + } + + @Test + public void getEvents() { + Mockito.when(eventService.getEvents()).thenReturn(_events); + List events = eventService.getEvents(); + Assertions.assertEquals(events, _events); + } + + @Test + public void getMatchingEvents() { + Mockito.when(eventService.getMatchingEvents(Mockito.anyString())).thenReturn(_events); + List events = eventService.getMatchingEvents("Covid"); + Assertions.assertEquals(events, _events); + } +} \ No newline at end of file diff --git a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/OrganizationserviceApplication.java b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/OrganizationserviceApplication.java index f14d327..e882d59 100644 --- a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/OrganizationserviceApplication.java +++ b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/OrganizationserviceApplication.java @@ -14,13 +14,12 @@ public class OrganizationserviceApplication { public static void main(String[] args) { SpringApplication.run(OrganizationserviceApplication.class, args); } - - //CORS is some mechanism added by mordern browswers. just copy pasting. More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS + //CORS is some mechanism added by modern browsers. just copy pasting. More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS @Bean public CorsFilter corsFilter() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowCredentials(true); - corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:4202")); + corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:4200")); corsConfiguration.setAllowedHeaders(Arrays.asList("Origin", "Access-Control-Allow-Origin", "Content-Type", "Accept", "Authorization", "Origin, Accept", "X-Requested-With", "Access-Control-Request-Method", "Access-Control-Request-Headers")); diff --git a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/controller/OrganizationController.java b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/controller/OrganizationController.java index a468598..de27f1f 100644 --- a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/controller/OrganizationController.java +++ b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/controller/OrganizationController.java @@ -29,15 +29,13 @@ public OrganizationController(OrganizationService organizationService) { } @PostMapping("/login") - public ResponseEntity authOrganization(@RequestBody Login login){ - try{ + public ResponseEntity authOrganization(@RequestBody Login login) { + try { var organization = organizationService.getAuthOrganization(login); return ResponseEntity.status(HttpStatus.OK).body(organization); - } - catch (InvalidLoginException e){ - return ResponseEntity.status(HttpStatus .BAD_REQUEST).body(null); - } - catch (Exception e){ + } catch (InvalidLoginException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); + } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } } @@ -54,14 +52,38 @@ public ResponseEntity addOrganization(@RequestBody Organization organiza organizationService.addOrganization(organization); ObjectMapper mapper = new ObjectMapper(); return ResponseEntity.status(HttpStatus.OK).body(mapper.writeValueAsString(organization)); - } - catch (InvalidOrganizationException e) { + } catch (InvalidOrganizationException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); - } - catch (Exception e) { + } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } } + @PostMapping + @RequestMapping("/update/") + public ResponseEntity updateOrganization(@RequestBody Organization organization) { + try { + organizationService.updateOrganization(organization); + ObjectMapper mapper = new ObjectMapper(); + return ResponseEntity.status(HttpStatus.OK).body(mapper.writeValueAsString(organization)); + } catch (InvalidOrganizationException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + } + @PostMapping + @RequestMapping("/delete/") + public ResponseEntity deleteOrganization(@RequestBody Organization organization) { + try { + organizationService.deleteOrganization(organization); + ObjectMapper mapper = new ObjectMapper(); + return ResponseEntity.status(HttpStatus.OK).body(mapper.writeValueAsString(organization)); + } catch (InvalidOrganizationException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + } } diff --git a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/dto/Organization.java b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/dto/Organization.java index 2d63942..e677f92 100644 --- a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/dto/Organization.java +++ b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/dto/Organization.java @@ -7,116 +7,124 @@ @Document("organizations") public class Organization { - @Id - private String id; - private String name; - private String email; - private String phoneNo; - private String address; - private String city; - private String password; - private long pinCode; - private OrganizationTypes organization_type; - - @Override - public String toString() { - return "Organization [name=" + name + ", email=" + email + ", phoneNo=" + phoneNo - + ", address=" + address + ", city=" + city + ", pinCode=" + pinCode + ", organization_type=" - + organization_type + "]"; - } - - public Organization() { - super(); - } - - public Organization(String name, String email, String phoneNo, String address, String city, String password, - long pinCode, OrganizationTypes organization_type) { - //TODO: Add check for unique uuid. - this.name = name; - this.email = email; - this.phoneNo = phoneNo; - this.address = address; - this.city = city; - this.password = password; - this.pinCode = pinCode; - this.organization_type = organization_type; - - System.out.println("ID of this organization: " + id); - } - - public void assign_id(){ - this.id = UUID.randomUUID().toString(); - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getPhoneNo() { - return phoneNo; - } - - public void setPhoneNo(String phoneNo) { - this.phoneNo = phoneNo; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - - public long getPinCode() { - return pinCode; - } - - public void setPinCode(long pinCode) { - this.pinCode = pinCode; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public OrganizationTypes getOrganizationType() { - return organization_type; - } - - public void setOrganizationType(OrganizationTypes organization_type) { - this.organization_type = organization_type; - } + @Id + private String id; + private String name; + private String email; + private String phoneNo; + private String address; + private String city; + private String password; + private long pinCode; + private boolean deleted; + private OrganizationTypes organization_type; + + @Override + public String toString() { + return "Organization [name=" + name + ", email=" + email + ", phoneNo=" + phoneNo + + ", address=" + address + ", city=" + city + ", pinCode=" + pinCode + ", organization_type=" + + organization_type + ", isDeleted=" + deleted + "]"; + } + + public Organization() { + super(); + } + + public Organization(String name, String email, String phoneNo, String address, String city, String password, + long pinCode, boolean deleted, OrganizationTypes organization_type) { + //TODO: Add check for unique uuid. + this.name = name; + this.email = email; + this.phoneNo = phoneNo; + this.address = address; + this.city = city; + this.password = password; + this.pinCode = pinCode; + this.deleted = deleted; + this.organization_type = organization_type; + } + + public void assign_id() { + this.id = UUID.randomUUID().toString(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhoneNo() { + return phoneNo; + } + + public void setPhoneNo(String phoneNo) { + this.phoneNo = phoneNo; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public long getPinCode() { + return pinCode; + } + + public void setPinCode(long pinCode) { + this.pinCode = pinCode; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + public OrganizationTypes getOrganizationType() { + return organization_type; + } + + public void setOrganizationType(OrganizationTypes organization_type) { + this.organization_type = organization_type; + } } diff --git a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/repository/OrganizationRepository.java b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/repository/OrganizationRepository.java index 9c084a2..dd682ca 100644 --- a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/repository/OrganizationRepository.java +++ b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/repository/OrganizationRepository.java @@ -4,6 +4,10 @@ import com.socialservicefinder.organizationservice.dto.Organization; -public interface OrganizationRepository extends MongoRepository{ - public Organization findOrganizationByEmail(String email); +public interface OrganizationRepository extends MongoRepository { + //Organization findOrganizationByEmailAndDeleted(String email, boolean isDeleted); + + Organization findByEmailAndDeletedFalse(String email); + + Organization findOrganizationByEmailAndDeletedIs(String email, boolean isDeleted); } diff --git a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/service/OrganizationService.java b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/service/OrganizationService.java index 5554773..8d54a14 100644 --- a/organizationservice/src/main/java/com/socialservicefinder/organizationservice/service/OrganizationService.java +++ b/organizationservice/src/main/java/com/socialservicefinder/organizationservice/service/OrganizationService.java @@ -27,12 +27,12 @@ public OrganizationService(OrganizationRepository organizationRepository) throws this.ASSIGN_ID_TRIES = 3; } - public List getOrganizations(){ + public List getOrganizations() { return organizationRepository.findAll(); } public void addOrganization(Organization organization) { - if(organization == null || organization.getEmail() == null || organization.getName() == null + if (organization == null || organization.getEmail() == null || organization.getName() == null || organization.getPassword() == null) throw new IllegalArgumentException("organization, email, name or password cannot be null or empty"); @@ -40,35 +40,73 @@ public void addOrganization(Organization organization) { insertOrganization(organization); } - public void insertOrganization(Organization organization) { + public void updateOrganization(Organization organization) { + if (organization == null || organization.getEmail() == null || organization.getName() == null) + throw new IllegalArgumentException("organization, email, name cannot be null or empty"); + Organization oldOrganization = organizationRepository.findById(organization.getId()).get(); + if (organization.getPassword().length() == 0) { + organization.setPassword(oldOrganization.getPassword()); + } else { + organization.setPassword(codec.encrypt(organization.getPassword())); + } + updateOrganizations(organization); + } + + public void deleteOrganization(Organization organization) { + boolean id_assigned = false; + for (int tries = 0; tries < ASSIGN_ID_TRIES; tries++) { + try { + organization.setDeleted(true); + organizationRepository.save(organization); + id_assigned = true; + break; + } catch (MongoWriteException ignored) { + } + } + if (!id_assigned) + throw new InvalidOrganizationException("Unable to delete Organization, please try after sometime."); + } + + private void updateOrganizations(Organization organization) { + boolean id_assigned = false; + for (int tries = 0; tries < ASSIGN_ID_TRIES; tries++) { + try { + organizationRepository.save(organization); + id_assigned = true; + break; + } catch (MongoWriteException ignored) { + } + } + if (!id_assigned) + throw new InvalidOrganizationException("Please try after sometime."); + } + + private void insertOrganization(Organization organization) { // Try assigning ID to organization for TRIES number of times. boolean id_assigned = false; - for(int tries = 0; tries < ASSIGN_ID_TRIES; tries++){ - try{ + for (int tries = 0; tries < ASSIGN_ID_TRIES; tries++) { + try { organization.assign_id(); organizationRepository.insert(organization); id_assigned = true; break; - } - catch (MongoWriteException ignored){ + } catch (MongoWriteException ignored) { } } - if(!id_assigned) + if (!id_assigned) throw new InvalidOrganizationException("Please try after sometime."); } - public Organization getAuthOrganization(Login login){ - if(login == null || login.getEmail()==null || login.getPassword() == null) + public Organization getAuthOrganization(Login login) { + if (login == null || login.getEmail() == null || login.getPassword() == null) throw new IllegalArgumentException("Login object or email or password cannot be null"); login.setPassword(codec.encrypt(login.getPassword())); - Organization organization =organizationRepository.findOrganizationByEmail(login.getEmail()); - - if(organization!=null && organization.getPassword().equals(login.getPassword())) { + Organization organization = organizationRepository.findByEmailAndDeletedFalse(login.getEmail()); + if (organization != null && organization.getPassword().equals(login.getPassword())) { System.out.println(organization); return organization; - } - else + } else throw new InvalidLoginException("Authentication Failed"); } } diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..d473f5a --- /dev/null +++ b/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + pom + + + org.springframework + spring-context + 5.3.14 + compile + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + com.socialservicefinder + socialservicefinder + 0.0.1-SNAPSHOT + socialservicefinder + Social Service Finder Project using Spring Boot + + 11 + 1.8 + 1.8 + + + organizationservice + userservice + eventservice + + + diff --git a/socialseriveapp/src/app/app-routing.module.ts b/socialseriveapp/src/app/app-routing.module.ts index 6bfaa7e..7e88a81 100644 --- a/socialseriveapp/src/app/app-routing.module.ts +++ b/socialseriveapp/src/app/app-routing.module.ts @@ -5,6 +5,8 @@ import { HomepageComponent } from "./homepage/homepage.component"; import { RegistrationFormComponent } from './registration-form/registration-form.component'; import { LoginComponent } from './login/login.component'; import { DashboardComponent } from "./dashboard/dashboard.component"; +import {EventPageComponent} from "./event-page/event-page.component"; +import { UpdateProfileComponent } from "./update-profile/update-profile.component"; const routes: Routes = [ { path: '', component: HomepageComponent }, @@ -12,6 +14,8 @@ const routes: Routes = [ { path: 'contact', component: ContactusComponent }, { path: 'login', component: LoginComponent }, { path: 'dashboard', component: DashboardComponent }, + { path: 'eventPage', component: EventPageComponent }, + {path: 'updateProfile', component: UpdateProfileComponent} ]; @NgModule({ diff --git a/socialseriveapp/src/app/app.module.ts b/socialseriveapp/src/app/app.module.ts index 590f1ac..8356162 100644 --- a/socialseriveapp/src/app/app.module.ts +++ b/socialseriveapp/src/app/app.module.ts @@ -28,6 +28,8 @@ import { DashboardComponent } from './dashboard/dashboard.component'; import {MatSnackBarModule} from '@angular/material/snack-bar'; import {MatDividerModule} from '@angular/material/divider'; import {MatExpansionModule} from '@angular/material/expansion'; +import { EventPageComponent } from './event-page/event-page.component'; +import { UpdateProfileComponent } from './update-profile/update-profile.component'; @@ -43,7 +45,9 @@ import {MatExpansionModule} from '@angular/material/expansion'; ContactusComponent, NavbarComponent, LoginComponent, - DashboardComponent + DashboardComponent, + EventPageComponent, + UpdateProfileComponent ], imports: [ CommonModule, diff --git a/socialseriveapp/src/app/dashboard/dashboard.component.css b/socialseriveapp/src/app/dashboard/dashboard.component.css index 605a1bb..a32fe75 100644 --- a/socialseriveapp/src/app/dashboard/dashboard.component.css +++ b/socialseriveapp/src/app/dashboard/dashboard.component.css @@ -10,4 +10,64 @@ mat-expansion-panel{ width: 50%; margin: auto; margin-top: 1rem; +} + +.search-Results{ + position: relative; + margin: auto; + width: 85%; + border-radius: 1em; + margin-top: 1%; +} + +.createEventForm{ + width: 40% !important; +} + +.searchForm { + color: #555; + display: flex; + padding: 2px; + border: 1px solid currentColor; + border-radius: 5px; + } + + .searchBar { + border: none; + background: transparent; + margin: 0; + width: 95%; + padding: 7px 8px; + font-size: 14px; + color: inherit; + border: 1px solid transparent; + border-radius: inherit; + } + + .searchBar::placeholder { + color: #bbb; + } + + .searchButton { + text-indent: -999px; + overflow: hidden; + width: 5%; + padding: 0; + margin: 0; + border: 1px solid transparent; + border-radius: inherit; + background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' class='bi bi-search' viewBox='0 0 16 16'%3E%3Cpath d='M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z'%3E%3C/path%3E%3C/svg%3E") no-repeat center; + cursor: pointer; + opacity: 0.7; + } + + .searchButton:hover { + opacity: 1; + } + +.searchButton:focus, +.searchBar:focus { + box-shadow: 0 0 3px 0 #1183d6; + border-color: #1183d6; + outline: none; } \ No newline at end of file diff --git a/socialseriveapp/src/app/dashboard/dashboard.component.html b/socialseriveapp/src/app/dashboard/dashboard.component.html index 224e758..dc1775c 100644 --- a/socialseriveapp/src/app/dashboard/dashboard.component.html +++ b/socialseriveapp/src/app/dashboard/dashboard.component.html @@ -1,24 +1,9 @@ - - User + {{isUser?"User":"Organization"}} {{isUser?user.name:organisation.name}} @@ -26,9 +11,146 @@

Email: {{isUser?user.email :organisation.email}}

Phone No: {{isUser?user.phoneNo :organisation.phoneNo}}

-

Date of Birth: {{isUser?user.dob :organisation.dob}}

+

Date of Birth: {{isUser?user.dob :organisation.dob}}

Address: {{isUser?user.address :organisation.address}}

Preference: {{user.preferences}}

+

My Rewards: {{user.rewards}}

Organisation Type: {{organisation.organizationType}}

-
\ No newline at end of file + + + + + + + + + + Click on the button to create an event + + + + Create Event +
+ + Event Name + + + + + Event Description + +
+ + + Rewards + + + + + Address + + + + City + + + + Zip Code + + + + Start Date + + + + + + + End Date + + + + Invalid Date + + +
+ Point of Contact (POC) Details: + + Name + + + + Contact + + Should be 10 digits + + + + + Email: + + + + + + +
+
+
+
+ +
+ +
+
+

MY EVENTS

+
+
+ +
+
+ +
+ + +

{{event.name}}

+
+ +

Start Date: {{event.startDate}} +
Contact: {{event.phoneNo}} +
Email: {{event.email}} +
Address: {{event.address}}, {{event.city}} , {{event.pinCode}}

+

About: {{event.description}}

+
+
+
+ +
+
+
+

SEARCH FOR EVENTS

+
+
+ + +
+
+ + +
+ + +

{{event.name}}

+
+ +

Start Date: {{event.startDate}} +
Contact: {{event.phoneNo}} +
Email: {{event.email}} +
Address: {{event.address}}, {{event.city}} , {{event.pinCode}}

+

About: {{event.description}}

+
+
+
+ diff --git a/socialseriveapp/src/app/dashboard/dashboard.component.ts b/socialseriveapp/src/app/dashboard/dashboard.component.ts index 90e1d45..1e5ffe8 100644 --- a/socialseriveapp/src/app/dashboard/dashboard.component.ts +++ b/socialseriveapp/src/app/dashboard/dashboard.component.ts @@ -1,5 +1,14 @@ import { Component, OnInit } from '@angular/core'; +import { + MatSnackBar, + MatSnackBarHorizontalPosition, + MatSnackBarVerticalPosition, +} from '@angular/material/snack-bar'; +import { Event } from '../users/models/Event'; +import {FetchMyEvents} from '../users/models/FetchMyEvents' +import { FetchMyRewards } from '../users/models/FetchMyRewards'; import { Organiser } from '../users/models/Organiser'; +import { SearchQuery } from '../users/models/SearchQuery'; import { User } from '../users/models/User'; import { DashboardService } from '../users/services/dashboardservice/dashboard.service'; @@ -8,19 +17,169 @@ import { DashboardService } from '../users/services/dashboardservice/dashboard.s templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.css'] }) + export class DashboardComponent implements OnInit { user!: User; isUser!: boolean; organisation!: Organiser; panelOpenState = false; - constructor(private dashboardService: DashboardService) { } + createEventObject!: Event; + createEventFormPanelOpenState = false; + eventName: string=""; + eventDescription: string=""; + eventRewards: string=""; + eventLocation: string=""; + eventPOCName: string=""; + eventPOCContact: string=""; + eventPOCEmail: string=""; + eventCity: string=""; + eventZip: string=""; + searchEventsQuery: string=""; + eventResult! : any[]; + searchQueryObject!:SearchQuery; + startDate!: Date; + endDate!: Date; + eventReturn: string=""; + horizontalPosition: MatSnackBarHorizontalPosition = 'center'; + verticalPosition: MatSnackBarVerticalPosition = 'top'; + events!: Event; + id: string=""; + fetchMyEventsObject!:FetchMyEvents; + myEvents!: any[]; + fetchMyRewardsObject!:FetchMyRewards; + constructor(private dashboardService: DashboardService, private _snackBar: MatSnackBar) { } ngOnInit(): void { - this.isUser = this.dashboardService.isUser; - if(this.isUser) - this.user = this.dashboardService.getUser(); - else - this.organisation = this.dashboardService.getOrganiser(); + this.isUser = JSON.parse(localStorage.getItem('status') || '{}'); + if(this.isUser){ + this.user = JSON.parse(localStorage.getItem('userDetails') || '{}'); + console.log(this.user); + this.id=JSON.parse(localStorage.getItem('userDetails') || '{}').id; + console.log(this.user); + this.fetchMyRewards(this.id); + }else{ + this.organisation = JSON.parse(localStorage.getItem('orgDetails') || '{}'); + this.id=JSON.parse(localStorage.getItem('orgDetails') || '{}').id; + } + } + + createEvent(): void{ + this.createEventObject ={ + name: this.eventName, + description: this.eventDescription, + rewards: Number(this.eventRewards), + address: this.eventLocation, + pocName: this.eventPOCName, + phoneNo: Number(this.eventPOCContact), + email: this.eventPOCEmail, + city: this.eventCity, + pinCode: Number(this.eventZip), + startDate: this.startDate, + endDate: this.endDate, + organizationId: this.id, + deleted: false + } + + console.log(this.createEventObject); + + this.dashboardService.createEvent(this.createEventObject).subscribe((res)=>{ + this._snackBar.open('Event Created!!', "",{ + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + duration: 2000, + }); + this.clearForm(); + }, + (err)=>{ + this._snackBar.open('Failure: In Event Creation!!', "",{ + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + duration: 2000, + }); + } + ) + } + + getEventData(event: any): void{ + localStorage.setItem("currEvent", JSON.stringify(event)); + localStorage.setItem("myEvent",JSON.stringify(false)); + } + + getEventDataMyEvent(event: any): void{ + localStorage.setItem("currEvent", JSON.stringify(event)); + localStorage.setItem("myEvent",JSON.stringify(true)); + } + + searchEvents(): void{ + this.searchQueryObject={ + query: this.searchEventsQuery + } + + console.log(this.searchQueryObject); + this.dashboardService.searchEvents(this.searchQueryObject).subscribe((res)=>{ + this.eventReturn = JSON.stringify(res); + this.eventResult=JSON.parse(this.eventReturn); + this.searchEventsQuery=""; + },(err)=>{ + this.searchEventsQuery=""; + this._snackBar.open('Search Fetch Failed!!', "",{ + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + duration: 2000, + }); + }); + } + + clearForm(): void{ + this.eventName=""; + this.eventDescription=""; + this.eventRewards=""; + this.eventLocation=""; + this.eventPOCName=""; + this.eventPOCContact=""; + this.eventPOCEmail=""; + this.eventCity=""; + this.eventZip=""; + } + + fetchMyEvents(): void{ + this.fetchMyEventsObject={ + id: this.id, + isOrganizer: !this.isUser + } + this.dashboardService.fetchMyEvents(this.fetchMyEventsObject).subscribe((res)=>{ + console.log(res); + this.myEvents=JSON.parse(JSON.stringify(res)); + }, (err)=>{ + this._snackBar.open('My Events Fetch Failed!!', "",{ + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + duration: 2000, + }); + }); } -} + clearEventsResult(): void{ + this.myEvents=[]; + } + + fetchMyRewards(id: string): void{ + + this.fetchMyRewardsObject={ + id: this.id + }; + this.dashboardService.fetchMyRewards(this.fetchMyRewardsObject).subscribe((res)=>{ + this.user.rewards=(JSON.parse(JSON.stringify(res)).rewards); + }, (err)=>{ + this._snackBar.open('Fetch Failed for my Rewards!!', "",{ + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + duration: 2000, + }); + }); + } + + isNumber(contact: any): boolean { + return !isNaN(contact); + } +} \ No newline at end of file diff --git a/socialseriveapp/src/app/event-page/event-page.component.css b/socialseriveapp/src/app/event-page/event-page.component.css new file mode 100644 index 0000000..3826f87 --- /dev/null +++ b/socialseriveapp/src/app/event-page/event-page.component.css @@ -0,0 +1,46 @@ +.title{ + position: relative; + padding: 0; + margin: 0; + font-family: "Raleway", sans-serif; + font-weight: 300; + font-size: 40px; + color: green; + text-align: left; + text-transform: uppercase; + padding-bottom: 5px; + padding-top: 15px; + text-decoration: underline +} + +.search-Results{ + position: relative; + margin: auto; + width: 75%; + border-radius: 1em; + margin-top: 1%; +} + +.details{ + font-family: "Raleway", sans-serif; + font-weight: 30; + font-size: 18px; + color: grey; + text-align: left; + padding-bottom: 50px; + padding-top: 50px; +} + +.description{ + font-family: "Raleway", sans-serif; + font-weight: 30; + font-size: 15px; + color: #080808; + text-align: left; +} + +.btn{ + padding-bottom: 50px; + padding-top: 50px; +} + diff --git a/socialseriveapp/src/app/event-page/event-page.component.html b/socialseriveapp/src/app/event-page/event-page.component.html new file mode 100644 index 0000000..ef4c423 --- /dev/null +++ b/socialseriveapp/src/app/event-page/event-page.component.html @@ -0,0 +1,17 @@ +
+ + +

{{event.name}}

+
+

Start Date: {{event.startDate}} +
Contact: {{event.phoneNo}} +
Email: {{event.email}} +
Address: {{event.address}}, {{event.city}} , {{event.pinCode}}

+

Description:

+

{{event.description}}

+ + + +
+
+ diff --git a/socialseriveapp/src/app/event-page/event-page.component.spec.ts b/socialseriveapp/src/app/event-page/event-page.component.spec.ts new file mode 100644 index 0000000..63608ae --- /dev/null +++ b/socialseriveapp/src/app/event-page/event-page.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EventPageComponent } from './event-page.component'; + +describe('EventPageComponent', () => { + let component: EventPageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ EventPageComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EventPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/socialseriveapp/src/app/event-page/event-page.component.ts b/socialseriveapp/src/app/event-page/event-page.component.ts new file mode 100644 index 0000000..f0c2aa3 --- /dev/null +++ b/socialseriveapp/src/app/event-page/event-page.component.ts @@ -0,0 +1,85 @@ +import { Component, OnInit } from '@angular/core'; +import { + MatSnackBar, + MatSnackBarHorizontalPosition, + MatSnackBarVerticalPosition, +} from '@angular/material/snack-bar'; +import { EventRegistration } from '../users/models/EventRegistration'; +import { EventregistrationserviceService } from '../users/services/eventregistationservice/event-registration-service.service'; +import { Router } from '@angular/router'; +import {EventDeleteServiceService} from '../users/services/eventdeletionservice/event-delete-service.service'; + +@Component({ + selector: 'app-event-page', + templateUrl: './event-page.component.html', + styleUrls: ['./event-page.component.css'] +}) +export class EventPageComponent implements OnInit { + event!: any; + eventId: string=""; + userId: string=""; + isUser!: boolean; + myEvent!: boolean; + eventRegistrationObject!: EventRegistration; + horizontalPosition: MatSnackBarHorizontalPosition = 'center'; + verticalPosition: MatSnackBarVerticalPosition = 'top'; + + constructor(private eventRegisterService:EventregistrationserviceService,private _snackBar: MatSnackBar, private router: Router, + private eventDeletionService: EventDeleteServiceService) { } + + ngOnInit(): void { + this.event = JSON.parse(localStorage.getItem('currEvent') || '{}'); + this.eventId = JSON.parse(localStorage.getItem('currEvent') || '{}').id; + this.userId = JSON.parse(localStorage.getItem('userDetails') || '{}').id; + this.isUser = JSON.parse(localStorage.getItem('status') || '{}'); + this.myEvent = JSON.parse(localStorage.getItem('myEvent') || '{}'); + console.log(this.event); + } + + registerEvent(): void{ + //console.log(this.event); + this.eventRegistrationObject = { + userId: this.userId, + eventId: this.eventId + } + console.log(this.eventRegistrationObject); + this.eventRegisterService.registerForEvent(this.eventRegistrationObject).subscribe((res)=>{ + this._snackBar.open('Registration Successful!!', "",{ + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + duration: 2000, + }) + console.log(res); + this.router.navigateByUrl("/dashboard") + }, + (err)=>{ + this._snackBar.open('Registartion Failed!!', "",{ + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + duration: 2000, + }); + }); + } + + deleteEvent(): void{ + this.event.deleted = true; + console.log(this.event); + this.eventDeletionService.deleteEvent(this.event).subscribe((res)=>{ + this._snackBar.open('Deletion Successful!!', "",{ + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + duration: 2000, + }) + console.log(res); + this.router.navigateByUrl("/dashboard") + }, + (err)=>{ + this._snackBar.open('Deletion Failed!!', "",{ + horizontalPosition: this.horizontalPosition, + verticalPosition: this.verticalPosition, + duration: 2000, + }); + }); + + } +} diff --git a/socialseriveapp/src/app/homepage/contactus/contactus.component.css b/socialseriveapp/src/app/homepage/contactus/contactus.component.css index e69de29..aa0caf3 100644 --- a/socialseriveapp/src/app/homepage/contactus/contactus.component.css +++ b/socialseriveapp/src/app/homepage/contactus/contactus.component.css @@ -0,0 +1,21 @@ +.form-input-field{ + position: relative; + width: 100%; +} + +#bannerimage { + width: 100%; + background-image: url(../../../assets/contact_us.jpg); + height: 50%; + background-position: center; + } + + +.section-heading{ + text-align: center; + +} + +.margin-top-sm{ + margin-top: 2%; +} \ No newline at end of file diff --git a/socialseriveapp/src/app/homepage/contactus/contactus.component.html b/socialseriveapp/src/app/homepage/contactus/contactus.component.html index bbafbec..702784a 100644 --- a/socialseriveapp/src/app/homepage/contactus/contactus.component.html +++ b/socialseriveapp/src/app/homepage/contactus/contactus.component.html @@ -1 +1,63 @@ -

Contact Us

+ +
+ + + + + About us + +
+ + There are many people who would like to do community services, but don't know the places that + offer the + opportunity for the same. We aim to provide a platform not only to people who seek non-profit + organizations for any opportunities where they can contribute, but also to encourage more people + by + rewarding them for doing good deeds. We plan on helping the organizations that are looking for + volunteers to help them. + +
+ +
+ + + Locate Us Near You + +
+ + Central Offices + + + IRVINE REGISTERED OFFICE #1
+
+ Donald Bren School of Computer and Information Sciences, + Irvine, CA-92697
+ Contact: +1 949-824-7427
+ Email: info@uci.edi + +
+
+ IRVINE REGISTERED OFFICE #2
+
+ 3901 Parkview Ln + Irvine, CA-92612
+ Contact: +1 949-994-2615
+ Email: info@uci.edi +
+
+ + + International Affiliation + +
+ +
    +
  • We have affiliations with 1000+ NGO accross United States and India.
  • +
  • We are focusing on different community issues like environment change, water health and hygiene, quality education and poverty elevation issues.
  • +
  • We are collaborating local youth clubs, women groups for better society across the above mentioned countries.
  • +
  • Please feel free to reach out to us at info@uci.edi and we will get back to you shortly.
  • +
+
+
+
+ \ No newline at end of file diff --git a/socialseriveapp/src/app/homepage/contactus/contactus.component.ts b/socialseriveapp/src/app/homepage/contactus/contactus.component.ts index 9d2b309..b7c1d4f 100644 --- a/socialseriveapp/src/app/homepage/contactus/contactus.component.ts +++ b/socialseriveapp/src/app/homepage/contactus/contactus.component.ts @@ -6,9 +6,8 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./contactus.component.css'] }) export class ContactusComponent implements OnInit { - + constructor() { } - ngOnInit(): void { } } diff --git a/socialseriveapp/src/app/layout/navbar/navbar.component.html b/socialseriveapp/src/app/layout/navbar/navbar.component.html index dffdf40..9b1f944 100644 --- a/socialseriveapp/src/app/layout/navbar/navbar.component.html +++ b/socialseriveapp/src/app/layout/navbar/navbar.component.html @@ -3,12 +3,15 @@ Social Service Finder - -