Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to specify type and number of officers in a company #112

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;

import java.util.List;

/**
* Requirements a new company must meet.
*/
Expand Down Expand Up @@ -34,6 +36,13 @@ public class CompanySpec {
@JsonProperty("has_super_secure_pscs")
private Boolean hasSuperSecurePscs;

@JsonProperty("number_of_appointments")
private int numberOfAppointments = 1;

@JsonProperty("officer_roles")
private List<@Pattern(regexp = "director|secretary",
message = "Invalid officer role") String> officerRoles;

public CompanySpec() {
jurisdiction = Jurisdiction.ENGLAND_WALES;
}
Expand Down Expand Up @@ -85,4 +94,20 @@ public Boolean getHasSuperSecurePscs() {
public void setHasSuperSecurePscs(Boolean hasSuperSecurePscs) {
this.hasSuperSecurePscs = hasSuperSecurePscs;
}

public int getNumberOfAppointments() {
return numberOfAppointments;
}

public void setNumberOfAppointments(int numberOfAppointments) {
this.numberOfAppointments = numberOfAppointments;
}

public List<String> getOfficerRoles() {
return officerRoles;
}

public void setOfficerRoles(List<String> officerRoles) {
this.officerRoles = officerRoles;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.gov.companieshouse.api.testdata.repository;

import java.util.List;
import java.util.Optional;

import org.springframework.data.mongodb.repository.MongoRepository;
Expand All @@ -9,5 +10,5 @@

@NoRepositoryBean
public interface AppointmentsRepository extends MongoRepository<Appointment, String> {
Optional<Appointment> findByCompanyNumber(String companyNumber);
List<Appointment> findAllByCompanyNumber(String companyNumber);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package uk.gov.companieshouse.api.testdata.service;

import uk.gov.companieshouse.api.testdata.model.entity.Appointment;
import uk.gov.companieshouse.api.testdata.model.rest.CompanySpec;

import java.util.List;

public interface AppointmentService {

/**
* Creates one or more Appointment entities for the given CompanySpec,
* and returns them all in a list.
*/
List<Appointment> create(CompanySpec spec);

/**
* Deletes an appointment by its company number.
*
* @return true if found and deleted, false otherwise
*/
boolean delete(String companyNumber);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import uk.gov.companieshouse.api.testdata.model.entity.*;
import uk.gov.companieshouse.api.testdata.model.entity.Appointment;
import uk.gov.companieshouse.api.testdata.model.entity.Links;
import uk.gov.companieshouse.api.testdata.model.entity.OfficerAppointment;
import uk.gov.companieshouse.api.testdata.model.entity.OfficerAppointmentItem;
import uk.gov.companieshouse.api.testdata.model.rest.CompanySpec;
import uk.gov.companieshouse.api.testdata.model.rest.Jurisdiction;
import uk.gov.companieshouse.api.testdata.repository.AppointmentsRepository;
import uk.gov.companieshouse.api.testdata.repository.OfficerRepository;
import uk.gov.companieshouse.api.testdata.service.AddressService;
import uk.gov.companieshouse.api.testdata.service.DataService;
import uk.gov.companieshouse.api.testdata.service.AppointmentService;
import uk.gov.companieshouse.api.testdata.service.RandomService;

@Service
public class AppointmentsServiceImpl implements DataService<Appointment,CompanySpec> {
public class AppointmentsServiceImpl implements AppointmentService {

private static final int SALT_LENGTH = 8;
private static final int ID_LENGTH = 10;
Expand All @@ -40,77 +42,102 @@ public class AppointmentsServiceImpl implements DataService<Appointment,CompanyS
private OfficerRepository officerRepository;

@Override
public Appointment create(CompanySpec spec) {
public List<Appointment> create(CompanySpec spec) {
final String companyNumber = spec.getCompanyNumber();

final String countryOfResidence = addressService.getCountryOfResidence(spec.getJurisdiction());
int numberOfAppointments = spec.getNumberOfAppointments();
if (numberOfAppointments <= 0) {
numberOfAppointments = 1;
}

Appointment appointment = new Appointment();

String appointmentId = randomService.getEncodedIdWithSalt(ID_LENGTH, SALT_LENGTH);

LocalDate officerDob = LocalDate.of(1990, 3, 6);

Instant dateTimeNow = Instant.now();
Instant dateNow = LocalDate.now().atStartOfDay(ZoneId.of("UTC")).toInstant();
Instant dob = officerDob.atStartOfDay(ZoneId.of("UTC")).toInstant();

appointment.setId(appointmentId);
appointment.setCreated(dateTimeNow);

String internalId = INTERNAL_ID_PREFIX + this.randomService.getNumber(INTERNAL_ID_LENGTH);
String officerId = randomService.addSaltAndEncode(internalId, SALT_LENGTH);
appointment.setInternalId(internalId);
appointment.setAppointmentId(appointmentId);

appointment.setNationality("British");
appointment.setOccupation(OCCUPATION);
appointment.setServiceAddressIsSameAsRegisteredOfficeAddress(true);
appointment.setCountryOfResidence(countryOfResidence);
appointment.setUpdatedAt(dateTimeNow);
appointment.setForename("Test");
appointment.setAppointedOn(dateNow);
appointment.setOfficerRole("director");
appointment.setEtag(randomService.getEtag());

appointment.setServiceAddress(addressService.getAddress(spec.getJurisdiction()));
appointment.setDataCompanyNumber(companyNumber);

Links links = new Links();
links.setSelf(COMPANY_LINK + companyNumber + "/appointments/" + officerId);
links.setOfficerSelf(OFFICERS_LINK + officerId);
links.setOfficerAppointments(OFFICERS_LINK + officerId + "/appointments");
appointment.setLinks(links);
List<String> officerRoles = spec.getOfficerRoles();
if (officerRoles == null) {
officerRoles = new ArrayList<>();
}

appointment.setSurname("DIRECTOR");
appointment.setDateOfBirth(dob);
for (String role : officerRoles) {
if (!role.equalsIgnoreCase("director") && !role.equalsIgnoreCase("secretary")) {
throw new IllegalArgumentException("Invalid officer role: " + role);
}
}

appointment.setCompanyName("Company " + companyNumber);
appointment.setCompanyStatus("active");
appointment.setOfficerId(officerId);
appointment.setCompanyNumber(companyNumber);
appointment.setUpdated(dateTimeNow);
while (officerRoles.size() < numberOfAppointments) {
officerRoles.add("director");
}

this.createOfficerAppointment(spec, officerId, appointmentId);
List<Appointment> createdAppointments = new ArrayList<>();

for (int i = 0; i < numberOfAppointments; i++) {
String currentRole = officerRoles.get(i);

Appointment appointment = new Appointment();

String appointmentId = randomService.getEncodedIdWithSalt(ID_LENGTH, SALT_LENGTH);
String internalId = INTERNAL_ID_PREFIX + this.randomService.getNumber(INTERNAL_ID_LENGTH);
String officerId = randomService.addSaltAndEncode(internalId, SALT_LENGTH);

LocalDate officerDob = LocalDate.of(1990, 3, 6);
Instant dateTimeNow = Instant.now();
Instant dateNow = LocalDate.now().atStartOfDay(ZoneId.of("UTC")).toInstant();
Instant dob = officerDob.atStartOfDay(ZoneId.of("UTC")).toInstant();

appointment.setId(appointmentId);
appointment.setCreated(dateTimeNow);
appointment.setInternalId(internalId);
appointment.setAppointmentId(appointmentId);
appointment.setNationality("British");
appointment.setOccupation(OCCUPATION);
appointment.setServiceAddressIsSameAsRegisteredOfficeAddress(true);
appointment.setCountryOfResidence(countryOfResidence);
appointment.setUpdatedAt(dateTimeNow);
appointment.setForename("Test " + (i + 1));
appointment.setAppointedOn(dateNow);
appointment.setOfficerRole(currentRole);
appointment.setEtag(randomService.getEtag());
appointment.setServiceAddress(addressService.getAddress(spec.getJurisdiction()));
appointment.setDataCompanyNumber(companyNumber);

Links links = new Links();
links.setSelf(COMPANY_LINK + companyNumber + "/appointments/" + officerId);
links.setOfficerSelf(OFFICERS_LINK + officerId);
links.setOfficerAppointments(OFFICERS_LINK + officerId + "/appointments");
appointment.setLinks(links);

appointment.setSurname("DIRECTOR");
appointment.setDateOfBirth(dob);
appointment.setCompanyName("Company " + companyNumber);
appointment.setCompanyStatus("active");
appointment.setOfficerId(officerId);
appointment.setCompanyNumber(companyNumber);
appointment.setUpdated(dateTimeNow);

this.createOfficerAppointment(spec, officerId, appointmentId, currentRole);

Appointment savedAppointment = appointmentsRepository.save(appointment);
createdAppointments.add(savedAppointment);
}

return appointmentsRepository.save(appointment);
return createdAppointments;
}

@Override
public boolean delete(String companyNumber) {
Optional<Appointment> existingAppointment = appointmentsRepository.findByCompanyNumber(companyNumber);

if (existingAppointment.isPresent()) {
String officerId = existingAppointment.get().getOfficerId();
officerRepository.findById(officerId).ifPresent(officerRepository::delete);
appointmentsRepository.delete(existingAppointment.get());
List<Appointment> foundAppointments =
appointmentsRepository.findAllByCompanyNumber(companyNumber);

if (!foundAppointments.isEmpty()) {
for (Appointment ap : foundAppointments) {
String officerId = ap.getOfficerId();
officerRepository.findById(officerId).ifPresent(officerRepository::delete);
}
appointmentsRepository.deleteAll(foundAppointments);
return true;
}
return false;
}

private void createOfficerAppointment(CompanySpec spec, String officerId, String appointmentId) {

private void createOfficerAppointment(CompanySpec spec,
String officerId, String appointmentId, String role) {
OfficerAppointment officerAppointment = new OfficerAppointment();

Instant dayTimeNow = Instant.now();
Expand All @@ -119,7 +146,6 @@ private void createOfficerAppointment(CompanySpec spec, String officerId, String
officerAppointment.setId(officerId);
officerAppointment.setCreatedAt(dayTimeNow);
officerAppointment.setUpdatedAt(dayTimeNow);

officerAppointment.setTotalResults(1);
officerAppointment.setActiveCount(1);
officerAppointment.setInactiveCount(0);
Expand All @@ -131,39 +157,47 @@ private void createOfficerAppointment(CompanySpec spec, String officerId, String
links.setSelf(OFFICERS_LINK + officerId + "/appointments");
officerAppointment.setLinks(links);

officerAppointment.setEtag(this.randomService.getEtag());
officerAppointment.setEtag(randomService.getEtag());
officerAppointment.setDateOfBirthYear(1990);
officerAppointment.setDateOfBirthMonth(3);

officerAppointment.setOfficerAppointmentItems(
createOfficerAppointmentItems(spec, appointmentId, dayNow, dayTimeNow));
createOfficerAppointmentItems(spec, appointmentId, dayNow, dayTimeNow, role)
);

officerRepository.save(officerAppointment);
}

private List<OfficerAppointmentItem> createOfficerAppointmentItems(CompanySpec companySpec, String appointmentId,
Instant dayNow, Instant dayTimeNow) {

private List<OfficerAppointmentItem> createOfficerAppointmentItems(
CompanySpec companySpec,
String appointmentId,
Instant dayNow,
Instant dayTimeNow,
String role
) {
List<OfficerAppointmentItem> officerAppointmentItemList = new ArrayList<>();

String companyNumber = companySpec.getCompanyNumber();
Jurisdiction jurisdiction = companySpec.getJurisdiction();

OfficerAppointmentItem officerAppointmentItem = new OfficerAppointmentItem();
officerAppointmentItem.setOccupation(OCCUPATION);
officerAppointmentItem.setAddress(addressService.getAddress(jurisdiction));
officerAppointmentItem.setForename("Test");
officerAppointmentItem.setSurname(OCCUPATION);
officerAppointmentItem.setOfficerRole("director");
officerAppointmentItem.setLinks(createOfficerAppointmentItemLinks(companyNumber, appointmentId));
officerAppointmentItem.setCountryOfResidence(addressService.getCountryOfResidence(jurisdiction));
officerAppointmentItem.setAppointedOn(dayNow);
officerAppointmentItem.setNationality("British");
officerAppointmentItem.setUpdatedAt(dayTimeNow);
officerAppointmentItem.setName("Test DIRECTOR");
officerAppointmentItem.setCompanyName("Company " + companyNumber);
officerAppointmentItem.setCompanyNumber(companyNumber);
officerAppointmentItem.setCompanyStatus("active");

officerAppointmentItemList.add(officerAppointmentItem);
OfficerAppointmentItem item = new OfficerAppointmentItem();
item.setOccupation(OCCUPATION);
item.setAddress(addressService.getAddress(jurisdiction));
item.setForename("Test");
item.setSurname(OCCUPATION);
item.setOfficerRole(role);
item.setLinks(createOfficerAppointmentItemLinks(companyNumber, appointmentId));
item.setCountryOfResidence(addressService.getCountryOfResidence(jurisdiction));
item.setAppointedOn(dayNow);
item.setNationality("British");
item.setUpdatedAt(dayTimeNow);
item.setName("Test DIRECTOR");
item.setCompanyName("Company " + companyNumber);
item.setCompanyNumber(companyNumber);
item.setCompanyStatus("active");

officerAppointmentItemList.add(item);

return officerAppointmentItemList;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import uk.gov.companieshouse.api.testdata.model.rest.UserSpec;

import uk.gov.companieshouse.api.testdata.repository.AcspMembersRepository;
import uk.gov.companieshouse.api.testdata.service.AppointmentService;
import uk.gov.companieshouse.api.testdata.service.CompanyAuthAllowListService;
import uk.gov.companieshouse.api.testdata.service.CompanyAuthCodeService;
import uk.gov.companieshouse.api.testdata.service.CompanyProfileService;
Expand All @@ -56,7 +57,7 @@ public class TestDataServiceImpl implements TestDataService {
@Autowired
private CompanyAuthCodeService companyAuthCodeService;
@Autowired
private DataService<Appointment, CompanySpec> appointmentService;
private AppointmentService appointmentService;
@Autowired
private DataService<CompanyMetrics, CompanySpec> companyMetricsService;
@Autowired
Expand Down
Loading