Summary Table

Categories Total Count
PII 0
URL 0
DNS 0
EKL 0
IP 0
PORT 0
VsID 0
CF 0
AI 0
VPD 0
PL 0
Other 0

File Content

/*
* SeocController.java
* Copyright (c) 2017 Veterans Affairs.
*/
package gov.va.oneconsult.seoc.api.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.validation.Valid;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;

import gov.va.oneconsult.seoc.api.exceptions.BusinessException;
import gov.va.oneconsult.seoc.api.json.CheckNameRequest;
import gov.va.oneconsult.seoc.api.json.CreateBillingCodeRequest;
import gov.va.oneconsult.seoc.api.json.SeocActivateRequest;
import gov.va.oneconsult.seoc.api.json.SeocCreateRequest;
import gov.va.oneconsult.seoc.api.json.SeocCreateResponse;
import gov.va.oneconsult.seoc.api.json.SeocGenericRequest;
import gov.va.oneconsult.seoc.api.json.SeocGenericResponse;
import gov.va.oneconsult.seoc.api.model.Seoc;
import gov.va.oneconsult.seoc.api.serializer.SeocBillingCodeSerializer;
import gov.va.oneconsult.seoc.api.serializer.SeocExternalSerializer;
import gov.va.oneconsult.seoc.api.serializer.SeocListSerializer;
import gov.va.oneconsult.seoc.api.serializer.SeocMinDetailsSerializer;
import gov.va.oneconsult.seoc.api.serializer.SeocSetSerializer;
import gov.va.oneconsult.seoc.api.serializer.StringSerializer;
import gov.va.oneconsult.seoc.api.service.SeocService;
import gov.va.oneconsult.seoc.api.service.impl.SeocServiceHelper;
import gov.va.oneconsult.seoc.api.threadlocal.Context;
import gov.va.oneconsult.seoc.api.threadlocal.SeocThreadLocal;
import gov.va.oneconsult.seoc.api.util.Constants;
import gov.va.oneconsult.seoc.api.util.EncodeLoggerFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

/**
* RestController for Seoc
* <p>
* Exposes Create, Update, Read and Delete operations on SEOC
* </p>
*
* @author AbleVets
* @version 1.0
*/
@RestController
@CrossOrigin
@RequestMapping(value = Constants.ROOT_SEOC_V1)
@Api(value = "SeocController", description = "Allows to create and manage seoc")
public class SeocController {

/**
* {@link SeocService}
*/
@Autowired
private SeocService seocService;

public static final Logger logger = EncodeLoggerFactory.getLogger(SeocController.class);

private static ObjectMapper seocSetMapper = new ObjectMapper();
private static SimpleModule seocSetModule = new SimpleModule("SeocSetSerializer",
new Version(1, 0, 0, null, null, null));

private static ObjectMapper seocListMapper = new ObjectMapper();
private static SimpleModule seocListModule = new SimpleModule("SeocListSerializer",
new Version(1, 0, 0, null, null, null));

private static ObjectMapper seocToolBoxMapper = new ObjectMapper();
private static SimpleModule seocToolBoxModule = new SimpleModule("SeocExternalSerializer",
new Version(1, 0, 0, null, null, null));

private static ObjectMapper seocExternalMapper = new ObjectMapper();
private static SimpleModule seocExternalModule = new SimpleModule("SeocExternalSerializer",
new Version(1, 0, 0, null, null, null));

private static ObjectMapper seocMapper = new ObjectMapper();
private static SimpleModule seocModule = new SimpleModule("SeocSerializer", new Version(1, 0, 0, null, null, null));

private static ObjectMapper seocMinDetailsMapper = new ObjectMapper();
private static SimpleModule seocMinDetailsModule = new SimpleModule("SeocMinDetailsSerializer", new Version(1, 0, 0, null, null, null));

private static ObjectMapper objectMapper = new ObjectMapper();
private static SimpleModule objectModule = new SimpleModule("ObjectSerializer",
new Version(1, 0, 0, null, null, null));

private static SeocExternalSerializer toolBoxSerializer = new SeocExternalSerializer();
private static SeocExternalSerializer externalSerializer = new SeocExternalSerializer();

private static ObjectMapper seocBillingCodeMapper = new ObjectMapper();
private static SimpleModule seocBillingCodeModule = new SimpleModule("SeocBillingCodeSerializer",
new Version(1, 0, 0, null, null, null));


static {
Set<Seoc> seocsSet = new HashSet<Seoc>();
List<Seoc> seocsList = new ArrayList<Seoc>();

seocSetModule.addSerializer((Class<Set<Seoc>>) seocsSet.getClass(), new SeocSetSerializer());
seocSetModule.addSerializer((Class<String>) String.class, new StringSerializer());
seocSetMapper.registerModule(seocSetModule);

seocListModule.addSerializer((Class<Set<Seoc>>) seocsSet.getClass(), new SeocListSerializer());
seocListModule.addSerializer((Class<String>) String.class, new StringSerializer());
seocListMapper.registerModule(seocListModule);

externalSerializer.setExternalSystem(Constants.HSRM);
seocExternalModule.addSerializer((Class<List<Seoc>>) seocsList.getClass(), externalSerializer);
seocExternalModule.addSerializer((Class<String>) String.class, new StringSerializer());
seocExternalMapper.registerModule(seocExternalModule);

toolBoxSerializer.setExternalSystem(Constants.TOOLBOX);
seocToolBoxModule.addSerializer((Class<List<Seoc>>) seocsList.getClass(), toolBoxSerializer);
seocToolBoxModule.addSerializer((Class<String>) String.class, new StringSerializer());
seocToolBoxMapper.registerModule(seocToolBoxModule);

seocModule.addSerializer((Class<String>) String.class, new StringSerializer());
seocMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
seocMapper.registerModule(seocModule);

seocMinDetailsModule.addSerializer((Class<Set<Seoc>>) seocsSet.getClass(), new SeocMinDetailsSerializer());
seocMinDetailsMapper.registerModule(seocMinDetailsModule);

objectModule.addSerializer((Class<String>) String.class, new StringSerializer());
objectMapper.registerModule(objectModule);


seocBillingCodeModule.addSerializer((Class<List<Seoc>>) seocsList.getClass(), new SeocBillingCodeSerializer());
seocBillingCodeModule.addSerializer((Class<String>) String.class, new StringSerializer());
seocBillingCodeMapper.registerModule(seocBillingCodeModule);
}

@InitBinder
public void initBinder(WebDataBinder binder, WebRequest request) {
binder.setDisallowedFields();
}

/**
* Description: Read all Seocs
*
* @return Returns {@link ResponseEntity} with the list of {@link Seoc} objects
* and status of the response
*/
@ApiOperation(value = "readAll", notes = "Get all Seocs", nickname = "getall")
@ApiResponses(value = { @ApiResponse(code = 204, message = "No Content Found"),
@ApiResponse(code = 200, message = "Successful retrieval", response = SeocController.class, responseContainer = "List") })
@RequestMapping(value = "/all", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> readAll() {

logger.info("Obtaining all seocs");

Set<Seoc> seocs = seocService.getAllSeocs();
String result = null;
try {
if (seocs != null) {
result = seocListMapper.writeValueAsString(seocs);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} else {// "204 No Content"

logger.error("No seocs available.");
return new ResponseEntity<String>("No seoc available", HttpStatus.NO_CONTENT);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in retreiving all SEOC data." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Read all Active Seocs
*
* @return Returns {@link ResponseEntity} with the list of {@link Seoc} objects
* and status of the response
*/
@ApiOperation(value = "readAllActiveSeocs", notes = "Get all active Seocs", nickname = "getActiveSeocs")
@ApiResponses(value = { @ApiResponse(code = 204, message = "No Content Found"),
@ApiResponse(code = 200, message = "Successful retrieval", response = SeocController.class, responseContainer = "List") })
@RequestMapping(value = "/active", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> readAllActiveSeocs() {

logger.info("Obtaining all active seocs");

List<Seoc> seocSet = seocService.getActiveSeocs();

try {
if (!seocSet.isEmpty()) {
String result = seocToolBoxMapper.writeValueAsString(seocSet);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} else {// "204 No Content"

logger.error("No seoc available");
return new ResponseEntity<String>("No seoc available", HttpStatus.NO_CONTENT);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in retreiving active SEOC data." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Read all Active Seocs With Billing Codes
*
* @return Returns {@link ResponseEntity} with the list of {@link Seoc} objects
* and status of the response
*/
@ApiOperation(value = "getAllActiveSeocsWithBillingCodes", notes = "Get all active Seocs with Billing Codes", nickname = "getActiveSeocsWithBillingCodes")
@ApiResponses(value = { @ApiResponse(code = 204, message = "No Content Found"),
@ApiResponse(code = 200, message = "Successful retrieval", response = SeocController.class, responseContainer = "List") })
@RequestMapping(value = "/active/billingcodes", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> getAllActiveSeocsWithBillingCodes() {

logger.info("Obtaining all active seocs with billing codes");

List<Seoc> seocSet = seocService.getActiveSeocs();

try {
if (!seocSet.isEmpty()) {
String result = seocBillingCodeMapper.writeValueAsString(seocSet);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} else {// "204 No Content"

logger.error("No active seoc with billing codes available");
return new ResponseEntity<String>("No active seoc with billing codesavailable", HttpStatus.NO_CONTENT);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in retreiving active SEOC data." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
} catch (IOException e) {
logger.error("IO Exception occured in retreiving active SEOC data." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Read all Active/Discontinued Seocs
*
* @return Returns {@link ResponseEntity} with the list of {@link Seoc} objects
* and status of the response
*/
@ApiOperation(value = "readPublishedSeocs", notes = "Get all date hold, active, or discontinued Seocs", nickname = "getPublishedSeocs")
@ApiResponses(value = { @ApiResponse(code = 204, message = "No Content Found"),
@ApiResponse(code = 200, message = "Successful retrieval", response = SeocController.class, responseContainer = "List") })
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> readAllConditionSeocs() {

logger.info("Obtaining all Date Hold, Active, or Discontinued seocs");

List<Seoc> seocList = seocService.getPublishedSeocs();
try {
if (!seocList.isEmpty()) {
String result = seocExternalMapper.writeValueAsString(seocList);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} else {// "204 No Content"

logger.error("No seoc available");
return new ResponseEntity<String>("No seoc available", HttpStatus.NO_CONTENT);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in retreiving published SEOC data." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Read all Active/Discontinued Seocs
*
* @return Returns {@link ResponseEntity} with the list of {@link Seoc} objects
* and status of the response
*/
@ApiOperation(value = "getSeocsByKey", notes = "Get all Seocs with the same Seoc key", nickname = "getSeocsByKey")
@ApiResponses(value = { @ApiResponse(code = 204, message = "No Content Found"),
@ApiResponse(code = 200, message = "Successful retrieval", response = SeocController.class, responseContainer = "List") })
@RequestMapping(value = "/seocKey/{seocKey:.+}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> getSeocsByKey(@PathVariable("seocKey") Integer seocKey) {
logger.info("Obtaining Seocs by seocKey");

Set<Seoc> seocSet = seocService.getBySeocKey(seocKey);
try {
if (!seocSet.isEmpty()) {
String result = seocSetMapper.writeValueAsString(seocSet);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} else {// "204 No Content"

logger.error("Unable to find Seocs by seocKey");
return new ResponseEntity<String>("Unable to find Seocs by seocKey", HttpStatus.NO_CONTENT);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in retreiving SEOC data." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Retrieve Seoc by Id
*
* @param id - Id of the seoc object to be retrieved
* @return Returns {@link ResponseEntity} with the {@link Seoc} object found and
* status of the response
*/
@ApiOperation(value = "getSeocById", notes = "Get Seoc from database by id", nickname = "GetSeoc")
@ApiResponses(value = { @ApiResponse(code = 204, message = "No Content Found"),
@ApiResponse(code = 200, message = "Successful retrieval", response = SeocController.class, responseContainer = "String") })
@RequestMapping(value = "/{id:.+}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> getSeocById(@PathVariable("id") Integer id) {

logger.info("Obtaining Seoc by id");

Seoc seoc = seocService.getSeocById(id);

try {
if (seoc != null) {
String result = seocMapper.writeValueAsString(seoc);

HttpHeaders headers = new HttpHeaders();
headers.set("Access-Control-Expose-Headers", "ETag");
headers.set(HttpHeaders.ETAG, SeocServiceHelper.getHashCodeOfSeoc(seoc));
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
ResponseEntity<String> response = new ResponseEntity<String>(result, headers, HttpStatus.OK);
return response;
} else {// "204 No Content"

logger.error("Unable to find Seoc by Id.");
return new ResponseEntity<String>("Unable to find seoc", HttpStatus.NO_CONTENT);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in retreiving SEOC by Id." + e.getMessage());
return new ResponseEntity<String>("Unable to find seoc", HttpStatus.NO_CONTENT);
} catch (BusinessException e) {
logger.error("Exception occured in generating ETag value.");
return new ResponseEntity<String>("Exception occured in generating ETag value.", HttpStatus.NO_CONTENT);
}

}

/**
* Description: Retrieve Seoc by Name
*
* @param name - Name of the seoc object to be retrieved
* @return Returns {@link ResponseEntity} with the {@link Seoc} object found and
* status of the response
*/
@ApiOperation(value = "getSeocByName", notes = "Get Seoc from database by name", nickname = "GetSeoc")
@ApiResponses(value = { @ApiResponse(code = 204, message = "No Content Found"),
@ApiResponse(code = 200, message = "Successful retrieval", response = SeocController.class, responseContainer = "String") })
@RequestMapping(value = "/name/{name:.+}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> getSeocByName(@PathVariable("name") String name) {

logger.info("Obtaining Seoc by name");

Set<Seoc> seocSet = new HashSet<Seoc>();

if (name != null && !name.isEmpty()) {

seocSet = seocService.getByNameMatch(name);
}
try {
if (seocSet != null && !seocSet.isEmpty()) {
String result = seocSetMapper.writeValueAsString(seocSet);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} else {// "204 No Content"

logger.error("No seoc available by name");
return new ResponseEntity<String>("No seoc available", HttpStatus.NO_CONTENT);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in retreiving SEOC by name." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}

}

/**
* Description: Save Seoc. Allows to create and update the SEOC after validating
* the input request
*
* @param seocRequest - Object of type {@link SeocCreateRequest}
* @return - Returns {@link SeocCreateResponse}
*/
@ApiOperation(value = "saveSeoc", notes = "Save or Update SEOC", nickname = "SaveSeoc")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 201, message = "Successfully Save", response = SeocController.class, responseContainer = "SeocCreateResponse"),
@ApiResponse(code = 200, message = "Completed with Errors"), @ApiResponse(code = 204, message = "No Content"),
@ApiResponse(code = 412, message = "Pre-Condition failed") })
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<String> saveSeoc(@RequestBody @Valid SeocCreateRequest seocRequest,
@RequestHeader HttpHeaders headers) {
if (seocRequest == null) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
logger.info("Save seoc requested");

String ifMatchFromRequest = headers != null ? headers.getFirst(HttpHeaders.IF_MATCH) : null;
String userIdFromRequest = headers != null ? headers.getFirst(Constants.USERID) : null;

if (userIdFromRequest == null || userIdFromRequest.isEmpty()) {
logger.error("UserId is missing in the request.");
return new ResponseEntity<String>("UserId is missing in the request.", HttpStatus.BAD_REQUEST);
}

Context context = new Context();
context.setEtag(ifMatchFromRequest);
context.setUserId(userIdFromRequest);
SeocThreadLocal.setContext(context);

if (seocRequest.getSeocId() > 0) {
if (seocService.getSeocById(seocRequest.getSeocId()) == null) {
return new ResponseEntity<String>("Seoc not found.", HttpStatus.NO_CONTENT);
}
if (ifMatchFromRequest == null || ifMatchFromRequest.isEmpty()) {
logger.error("Bad request - ifMatch condition is missing in the request header");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}

SeocCreateResponse seocResponse = seocService.saveSeoc(seocRequest);
try {
String result = objectMapper.writeValueAsString(seocResponse);

context = SeocThreadLocal.getContext();

if (seocResponse.getStatus() != null && ((Constants.CREATED).equals(seocResponse.getStatus())
|| (Constants.UPDATED).equals(seocResponse.getStatus()))) {
logger.info("**CREATED/UPDATED**");
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("Access-Control-Expose-Headers", "ETag");
responseHeaders.set(HttpHeaders.ETAG, context.getEtag());
responseHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
return new ResponseEntity<String>(result, responseHeaders, HttpStatus.CREATED);
} else if ((Constants.FAILURE).equalsIgnoreCase(seocResponse.getStatus())) {
logger.error("**FAILED**");
return new ResponseEntity<String>(result, HttpStatus.BAD_REQUEST);
} else {
logger.error("**PRECONDITION FAILED**");
return new ResponseEntity<String>(result, HttpStatus.PRECONDITION_FAILED);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in response of SaveSeoc." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}

}

/**
* Description: Determines if the seoc data is valid for create/update
*
* @param checkRequest - Object of type {@link CheckNameRequest}
* @return - Returns the status of the evaluation
*/
@ApiOperation(value = "getSeocAvailability", notes = "Check if a seoc exists by this name", nickname = "GetSeocAvailability")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request"),
@ApiResponse(code = 204, message = "No Content"),
@ApiResponse(code = 200, message = "Successful retrieval", response = SeocController.class) })
@RequestMapping(value = "/checkseocexists", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<String> getSeocAvailability(@RequestBody @Valid CheckNameRequest checkRequest) {

if (checkRequest == null) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

Boolean seocAvailable = seocService.isSeocAvailable(checkRequest.getSeocKey(), checkRequest.getName());
SeocGenericResponse response = new SeocGenericResponse(Constants.SUCCESS, null);
if (!seocAvailable) {
response = new SeocGenericResponse(Constants.FAILURE, null);
}

try {
String result = objectMapper.writeValueAsString(response);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in response of seoc availability." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}

}

/**
* Description: Create pending revision of the requested seoc
*
* @param seocRequest - Object of type {@link SeocGenericRequest}
* @return - Returns {@link SeocGenericResponse}
*/
@ApiOperation(value = "createPendingRequest", notes = "Create a pending draft SEOC", nickname = "pendingRevision")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 201, message = "Successfully Create", response = SeocController.class, responseContainer = "SeocGenericResponse"),
@ApiResponse(code = 204, message = "No Content"), @ApiResponse(code = 200, message = "Completed with Errors") })
@RequestMapping(value = "/createPendingRevision", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<String> createPendingRevision(@RequestBody @Valid SeocGenericRequest seocRequest) {
logger.info("Create pending revision request.");
if (seocRequest == null) {
logger.info("SeocRequest is null");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

if (seocRequest.getSeocId() <= 0) {
logger.info("SeocId is not available");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

SeocCreateResponse seocResponse = seocService.createPendingRevision(seocRequest.getSeocId());

try {
String result = objectMapper.writeValueAsString(seocResponse);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

if ((Constants.CREATED).equals(seocResponse.getStatus())) {
logger.info("**CREATED**");
return new ResponseEntity<String>(result, headers, HttpStatus.CREATED);
} else {
logger.info("**OK**");
return new ResponseEntity<String>(result, headers, HttpStatus.OK);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in response of create pending revision." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}

}

/**
* Description: Check if the seoc is valid for creation of pending revision
*
* @param id - Id of the seoc that is being checked for pending revision
* @return - Returns {@link SeocGenericResponse}
*/
@ApiOperation(value = "validPendingRevision", notes = "Check if it is a valid pending draft SEOC", nickname = "pendingRevision")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 204, message = "No Content"), @ApiResponse(code = 200, message = "Completed") })
@RequestMapping(value = "/validPendingRevision/{id:.+}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> validPendingRevision(@PathVariable("id") Integer id) {
logger.info("Valid Pending Revision request..");

if (id != null && id <= 0) {
logger.info("Id is not valid");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

SeocGenericResponse seocResponse = seocService.validPendingRevision(id);

try {
String result = objectMapper.writeValueAsString(seocResponse);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in response of validPendingRevision." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Check the validity of seoc for activation
*
* @param id seocId
* @return Returns {@link SeocGenericResponse}
*/
@ApiOperation(value = "ValidActivate", notes = "Check if the seoc can be Activated", nickname = "validActive")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 204, message = "No Content"), @ApiResponse(code = 200, message = "Completed") })
@RequestMapping(value = "/validActivate/{id:.+}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> validSeocActivate(@PathVariable("id") Integer id) {
logger.info("*** Request to check validity for activation of seoc " + id + " ***");

if (id != null && id <= 0) {
logger.info("Id is not valid");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

SeocGenericResponse seocResponse = seocService.validSeocActivate(id);

try {
String result = objectMapper.writeValueAsString(seocResponse);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in response of validSeocActivate." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Activate Seoc
*
* @param id seocId
* @return Returns {@link SeocGenericResponse}
*/
@ApiOperation(value = "ActivateSeoc", notes = "Activate draft SEOC", nickname = "activate")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 204, message = "No Content"),
@ApiResponse(code = 412, message = "PreCondition Failed"),
@ApiResponse(code = 200, message = "Completed", response = SeocController.class, responseContainer = "SeocGenericResponse") })
@RequestMapping(value = "/activate", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<String> activateSeoc(@RequestBody @Valid SeocActivateRequest seocActivateRequest, @RequestHeader HttpHeaders reqHeaders) {
if (seocActivateRequest == null) {
logger.info("Seoc activate request is empty.");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

logger.info("*** Seoc activate request *** " + seocActivateRequest);

if (seocActivateRequest.getSeocId() <= 0) {
logger.info("SeocId is not available");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

String ifMatchFromRequest = reqHeaders != null ? reqHeaders.getFirst(HttpHeaders.IF_MATCH) : null;

// IfMatch missing in the request headers
if (ifMatchFromRequest == null || ifMatchFromRequest.isEmpty()) {
logger.error("Activate is not initiated. IfMatch tag missing in the request headers");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

String userIdFromRequest = reqHeaders != null ? reqHeaders.getFirst(Constants.USERID) : null;

if (userIdFromRequest == null || userIdFromRequest.isEmpty()) {
logger.error("UserId is missing in the request.");
return new ResponseEntity<String>("UserId is missing in the request.", HttpStatus.BAD_REQUEST);
}

Context context = new Context();
context.setEtag(ifMatchFromRequest);
context.setUserId(userIdFromRequest);
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

try {
String result = objectMapper.writeValueAsString(seocResponse);

context = SeocThreadLocal.getContext();

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.set("Access-Control-Expose-Headers", "ETag");
headers.set(HttpHeaders.ETAG, context.getEtag());

if ((Constants.PRECONDITION_FAILED).equals(seocResponse.getStatus())) {
logger.error("**PRECONDITION FAILED**");
return new ResponseEntity<String>(result, HttpStatus.PRECONDITION_FAILED);
}
if ((Constants.FAILURE).equals(seocResponse.getStatus())) {
logger.error("**FAILURE**");
return new ResponseEntity<String>(result, HttpStatus.NO_CONTENT);
}

return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in response of activateSeoc." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Discontinue Active Seoc
*
* @param id seocId
* @return Returns {@link SeocGenericResponse}
*/
@ApiOperation(value = "DiscontinueSeoc", notes = "Discontinue active SEOC", nickname = "discontinue")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 204, message = "No Content"), @ApiResponse(code = 200, message = "Completed") })
@RequestMapping(value = "/discontinue/{id:.+}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> discontinueSeoc(@PathVariable("id") Integer id, @RequestHeader HttpHeaders reqHeaders) {
logger.info("*** Seoc requested to be discontinued *** " + id);

if (id != null && id <= 0) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

String userIdFromRequest = reqHeaders != null ? reqHeaders.getFirst(Constants.USERID) : null;

if (userIdFromRequest == null || userIdFromRequest.isEmpty()) {
logger.error("UserId is missing in the request.");
return new ResponseEntity<String>("UserId is missing in the request.", HttpStatus.BAD_REQUEST);
}

Context context = new Context();
context.setUserId(userIdFromRequest);
SeocThreadLocal.setContext(context);

try {
SeocGenericResponse seocResponse = seocService.discontinueSeoc(id);

String result = objectMapper.writeValueAsString(seocResponse);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in response of discontinueSeoc." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Delete Seoc
*
* @param id seocId
* @return Returns {@link SeocGenericResponse}
*/
@ApiOperation(value = "DeleteSeoc", notes = "Delete SEOC", nickname = "delete")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 204, message = "No Content"), @ApiResponse(code = 412, message = "PreCondition Failed"),
@ApiResponse(code = 200, message = "Completed") })
@RequestMapping(value = "/delete/{id:.+}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> deleteSeoc(@PathVariable("id") Integer id, @RequestHeader HttpHeaders reqHeaders) {
logger.info("*** Seoc requested to be deleted *** " + id);

String ifMatchFromRequest = reqHeaders != null ? reqHeaders.getFirst(HttpHeaders.IF_MATCH) : null;

// IfMatch missing in the request headers
if (ifMatchFromRequest == null || ifMatchFromRequest.isEmpty()) {
logger.error("Delete is not initiated. IfMatch tag missing in the request headers");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

String userIdFromRequest = reqHeaders != null ? reqHeaders.getFirst(Constants.USERID) : null;

if (userIdFromRequest == null || userIdFromRequest.isEmpty()) {
logger.error("UserId is missing in the request.");
return new ResponseEntity<String>("UserId is missing in the request.", HttpStatus.BAD_REQUEST);
}

if (id != null && id <= 0) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

Context context = new Context();
context.setEtag(ifMatchFromRequest);
context.setUserId(userIdFromRequest);
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.deleteSeoc(id);

try {
String result = objectMapper.writeValueAsString(seocResponse);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

if ((Constants.PRECONDITION_FAILED).equalsIgnoreCase(seocResponse.getStatus())) {
logger.error("**PRECONDITION FAILED**");
return new ResponseEntity<String>(result, HttpStatus.PRECONDITION_FAILED);
}

if ((Constants.FAILURE).equalsIgnoreCase(seocResponse.getStatus())) {
logger.error("**FAILURE**");
return new ResponseEntity<String>(result, HttpStatus.NO_CONTENT);
}

return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in response of deleteSeoc." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Reverse Date Hold SEOC
*
* @param id seocId
* @return Returns {@link SeocGenericResponse}
*/
@ApiOperation(value = "ReverseSeoc", notes = "Reverse Date Hold SEOC", nickname = "reverse")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 204, message = "No Content"), @ApiResponse(code = 200, message = "Completed") })
@RequestMapping(value = "/reverse/{id:.+}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> reverseSeoc(@PathVariable("id") Integer id, @RequestHeader HttpHeaders reqHeaders) {
logger.info("*** Seoc requested to be reversed *** " + id);

String ifMatchFromRequest = reqHeaders != null ? reqHeaders.getFirst(HttpHeaders.IF_MATCH) : null;

// IfMatch missing in the request headers
if (ifMatchFromRequest == null || ifMatchFromRequest.isEmpty()) {
logger.error("Reverse is not initiated. IfMatch tag missing in the request headers");
return new ResponseEntity<String>("Reverse is not initiated. IfMatch tag missing in the request headers", HttpStatus.BAD_REQUEST);
}

String userIdFromRequest = reqHeaders != null ? reqHeaders.getFirst(Constants.USERID) : null;

if (userIdFromRequest == null || userIdFromRequest.isEmpty()) {
logger.error("UserId is missing in the request.");
return new ResponseEntity<String>("Reverse is not initiated. UserId is missing in the request headers", HttpStatus.BAD_REQUEST);
}

Context context = new Context();
context.setEtag(ifMatchFromRequest);
context.setUserId(userIdFromRequest);
SeocThreadLocal.setContext(context);

if (id != null && id <= 0) {
return new ResponseEntity<>("Reverse is not initiated. SEOC Id is missing in the request", HttpStatus.BAD_REQUEST);
}

try {
SeocGenericResponse seocResponse = seocService.reverseSeoc(id);

String result = objectMapper.writeValueAsString(seocResponse);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.set("Access-Control-Expose-Headers", "ETag");
headers.set(HttpHeaders.ETAG, context.getEtag());

if ((Constants.PRECONDITION_FAILED).equalsIgnoreCase(seocResponse.getStatus())) {
logger.error("**PRECONDITION FAILED**");
return new ResponseEntity<String>(result, HttpStatus.PRECONDITION_FAILED);
}

if ((Constants.FAILURE).equalsIgnoreCase(seocResponse.getStatus())) {
logger.error("**FAILURE**");
return new ResponseEntity<String>(result, HttpStatus.BAD_REQUEST);
}

return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in response of reverseSeoc." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}
}

/**
* Description: Create new Billing Code
*
* @param billingCodeRequest
* @return - ResponseEntity<String>
*/
@ApiOperation(value = "createBillingCode", notes = "Create Billing Code", nickname = "New Billing Code")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 201, message = "Successfully Created new billing code", response = SeocController.class, responseContainer = "SeocGenericResponse"),
@ApiResponse(code = 409, message = "Conflict") })
@RequestMapping(value = "/createBillingCode", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<String> createBillingCode(@RequestBody @Valid CreateBillingCodeRequest billingCodeRequest) {
if (billingCodeRequest == null) {
logger.info("Billing code request is empty.");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

logger.info("*** Billing Code Request ***" + billingCodeRequest);

SeocGenericResponse seocResponse = seocService.createBillingCode(billingCodeRequest);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

if ((seocResponse.getAction()).equalsIgnoreCase(Constants.FAILURE)) {
logger.info("Failed to create billing code.");
return new ResponseEntity<String>(seocResponse.getComments(), headers, HttpStatus.CONFLICT);
}
logger.info("Successfully created new billing code.");
return new ResponseEntity<String>("Billing code created.", headers, HttpStatus.CREATED);

}


/**
* Description: Retrieve Seocs which contain the billing code
*
* @param billingCode - Billing code
* @return Returns {@link ResponseEntity} with the {@link Seoc} object found and
* status of the response
*/
@ApiOperation(value = "getSeocsByBillingCode", notes = "Get Seocs from database that contain the billing code", nickname = "GetSeocsByBillingCode")
@ApiResponses(value = { @ApiResponse(code = 204, message = "No Content Found"),
@ApiResponse(code = 200, message = "Successful retrieval", response = SeocController.class, responseContainer = "String") })
@RequestMapping(value = "/seocsByBillingCode/{billingCode:.+}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> getSeocsByBillingCode(@PathVariable("billingCode") String billingCode) {

logger.info("Obtaining Seoc by billing code");

Set<Seoc> seocSet = new HashSet<Seoc>();

if (billingCode != null && !billingCode.isEmpty()) {

seocSet = seocService.retrieveSeocsByBillingCode(billingCode);
}
try {
if (seocSet != null && !seocSet.isEmpty()) {
String result = seocMinDetailsMapper.writeValueAsString(seocSet);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return new ResponseEntity<String>(result, headers, HttpStatus.OK);
} else {// "204 No Content"

logger.error("No seoc available for billing code");
return new ResponseEntity<String>("No seoc available for billing code", HttpStatus.NO_CONTENT);
}
} catch (JsonProcessingException e) {
logger.error("Json Exception occured in retreiving SEOC by billing code." + e.getMessage());
return new ResponseEntity<String>("Exception occured generating JSON", HttpStatus.NO_CONTENT);
}

}

/**
* Description: Manage Billing Code. Edit or Delete a Billing Code.
*
* @param billingCodeRequest - Contains data for editing or deleting billing code.
* @return ResponseEntity<String>
*/
@ApiOperation(value = "manageBillingCode", notes = "Discontinue Billing Code", nickname = "Retire Billing Code")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request Found"),
@ApiResponse(code = 200, message = "Successfully retired a billing code", response = SeocController.class, responseContainer = "String") })
@RequestMapping(value = "/manageBillingCode", method = RequestMethod.PUT)
@ResponseBody
public ResponseEntity<String> manageBillingCode(@RequestBody @Valid CreateBillingCodeRequest billingCodeRequest)
{
logger.info("Request to Manage Billing Code");

//Validations for billing code request
if (billingCodeRequest == null) {
logger.info("Not a valid billing code request.");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
//It should be either a valid discontinue request or edit request. If none - Bad Request
if(!(billingCodeRequest.isDiscontinueRequest() || billingCodeRequest.isEditRequest())) {
logger.info("Not a valid billing code request.");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
//If a valid edit request check if all billing code parameters are available
if(billingCodeRequest.isEditRequest() && !billingCodeRequest.isValidEditRequest()) {
logger.info("Not a valid edit billing code request.");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

SeocGenericResponse seocResponse = seocService.manageBillingCode(billingCodeRequest);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

if (seocResponse!=null && seocResponse.getAction().equalsIgnoreCase(Constants.FAILURE))
{
logger.info("Failed to manage billing code.");
return new ResponseEntity<String>(seocResponse.getComments(), headers,
HttpStatus.BAD_REQUEST);
}
logger.info("Successfully completed the manage billing code.");
return new ResponseEntity<String>("Manage billing code request completed.", headers, HttpStatus.OK);

}


}