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

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

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.springframework.format.annotation.DateTimeFormat;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonRootName;

import gov.va.oneconsult.seoc.api.util.ApiUtil;
import gov.va.oneconsult.seoc.api.util.Constants;
import gov.va.oneconsult.seoc.api.validation.ActivateCondition;
import gov.va.oneconsult.seoc.api.validation.ValidCategoryOfCare;
import gov.va.oneconsult.seoc.api.validation.ValidQasp;
import gov.va.oneconsult.seoc.api.validation.ValidServiceLine;

/**
* Description: Contains SEOC information with service line, category of care
* and services details.
*
* @author AbleVets
*/
@Entity
@Table(name = "Seoc")
@JsonRootName(value = "Seoc")
@JsonPropertyOrder({ "id", "seocKey", "name", "seocId", "versionNumber", "description",
"effectiveDate", "endDate", "duration", "REV", "proceduralOverview", "codeRequired",
"maxAllowableVisits", "disclaimer", "activatedTimestamp", "activatedBy",
"discontinuedTimestamp", "discontinuedBy", "status", "QASP", "categoryOfCare",
"serviceLine"})
@ActivateCondition(trigger = "status", triggerAttribute = "description", triggerValues = {
Constants.STATUS_DATEHOLD }, requiredAttributes = { "disclaimer", "duration", "description", "rev",
"proceduralOverview","categoryOfCare", "services", "qasp", "hptcs" },
requiredChild = "services", childKey = "id", requiredChildAttributes = {
"description", "visits", "codeRequired", "clinicalServices", "billingCodes" })
public final class Seoc
{

/**
* ID of SEOC. Auto generated value.Guaranteed to be non-null
*/
@Id
@Column(name = "id")
@NotNull
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonProperty("id")
private int id;

/**
* SEOC Key. Guaranteed to be non-null.
*/
@Column(name = "seockey")
@NotNull
@JsonProperty("seocKey")
private int seocKey;

/**
* SEOC name. Guaranteed to be non-null.
*/
@Column(name = "name")
@NotNull
@Size(max = 150, message = "Name should not exceed 150 characters")
@JsonProperty("name")
private String name;

/**
* Specifying the version number of SEOC. Possible null value.
*/
@Column(name = "versionnumber")
@Size(max = 25, message = "Version Number should not exceed 25 characters")
@JsonProperty("versionNumber")
private String versionNumber;

/**
* Specifying the start date of the SEOC version. Possible null value.
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM-dd-yyyy")
@Column(name = "effectivedate")
@DateTimeFormat(pattern = "MM-dd-yyyy hh-mi-ss a")
@JsonProperty("effectiveDate")
private Date effectiveDate;

/**
* Specifying the end date of the SEOC version.Possible null value.
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM-dd-yyyy")
@Column(name = "enddate")
@DateTimeFormat(pattern = "MM-dd-yyyy hh-mi-ss a")
@JsonProperty("endDate")
private Date endDate;

/**
* Disclaimer associated to the SEOC. Possible null value.
*/
@Column(name = "disclaimer")
@Size(max = 2000, message = "Disclaimer should not exceed 2000 characters")
@JsonProperty("disclaimer")
private String disclaimer;

/**
* Duration associated to the SEOC. Duration value in number of days. Possible
* null value.
*/
@Column(name = "duration")
@JsonProperty("duration")
private Integer duration;

/**
* Possibly null description associated to of the SEOC. Possible null value.
*/
@Column(name = "description")
@Size(max = 2000, message = "Description should not exceed 2000 characters")
@JsonProperty("description")
private String description;

/**
* Defines the rev value. Possible null value.Default false.
*/
@Column(name = "rev")
@JsonProperty("REV")
private Boolean rev;

/**
* Defines Procedural overview value. Possible null value.
*/
@Column(name = "proceduraloverview")
@Size(max = 5000, message = "Procedural overview should not exceed 5000 characters")
@JsonProperty("proceduralOverview")
private String proceduralOverview;

/**
* Defines maximum allowable visits. Possible null value.
*/
@Column(name = "maxallowablevisits")
@JsonProperty("maxAllowableVisits")
private Integer maxAllowableVisits;

/**
* Time stamp when the Seoc was activated. Possible null value.
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM-dd-yyyy")
@Column(name = "activatedtimestamp")
@JsonProperty("activatedTimestamp")
@DateTimeFormat(pattern = "MM-dd-yyyy hh-mi-ss a")
private Date activatedTimestamp;

/**
* Seoc activated by value. Possible null value.
*/
@Column(name = "activatedby")
@JsonProperty("activatedBy")
@Size(max = 80, message = "activatedBy field should not exceed 80 characters")
private String activatedBy;

/**
* Time stamp when the Seoc was discontinued. Possible null value.
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM-dd-yyyy")
@Column(name = "discontinuedtimestamp")
@JsonProperty("discontinuedTimestamp")
@DateTimeFormat(pattern = "MM-dd-yyyy hh-mi-ss a")
private Date discontinuedTimestamp;

/**
* Seoc discontinued by value. Possible null value.
*/
@Size(max = 80, message = "DiscontinuedBy field should not exceed 80 characters")
@Column(name = "discontinuedby")
@JsonProperty("discontinuedBy")
private String discontinuedBy;

/**
* Seoc comment by value. Possible null value.
*/
@Column(name = "comment")
@JsonIgnore
private String comment;


/**
* {@link Status} specifying the current status of the SEOC. Default value is
* DRAFT .Guaranteed to be non-null.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "statusid", nullable = false)
@JsonIgnore
@NotNull
private Status status;

/**
* {@link CategoryOfCare} specifying the categoryOfCare details. Guaranteed to
* be non-null.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "categoryofcareid", nullable = true)
@JsonManagedReference
@JsonIgnore
@ValidCategoryOfCare
private CategoryOfCare categoryOfCare;

/**
* {@link ServiceLine} specifying the service line details. Guaranteed to be
* non-null.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "servicelineid", nullable = true)
@JsonManagedReference
@JsonIgnore
@ValidServiceLine
private ServiceLine serviceLine;

/**
* {@link Qasp} specifies the QASP details related to the seoc.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "qaspid", nullable = true)
@JsonIgnore
@ValidQasp
private Qasp qasp;

/**
* List of Services associated with the Seoc.
*/
@OneToMany(mappedBy = "seoc", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST,
CascadeType.DETACH, CascadeType.REMOVE, CascadeType.MERGE }, orphanRemoval = true)
@JsonManagedReference
@Valid
private List<PayableService> services;

/**
* Set of {@link HPTC} values associated with the SEOC
*/
@JsonProperty("hptcs")
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.DETACH })
@JoinTable(name = "seochptc", joinColumns = @JoinColumn(name = "seocid", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "hptc", referencedColumnName = "hptc"))
@OrderBy("id ASC")
private Set<Hptc> hptcs;

/**
* Default constructor
*/
public Seoc()
{

}

/**
*
* @param seocKey
* @param name
* @param versionNumber
* @param effectiveDate
* @param endDate
* @param disclaimer
* @param duration
* @param description
* @param rev
* @param proceduralOverview
* @param maxAllowableVisits
* @param activatedTimestamp
* @param activatedBy
* @param discontinuedTimestamp
* @param discontinuedBy
* @param status
* @param categoryOfCare
* @param serviceLine
* @param qasp
* @param services
*/
private Seoc(int seocKey, String name, String versionNumber, Date effectiveDate, Date endDate,
String disclaimer, Integer duration, String description, Boolean rev,
String proceduralOverview, Integer maxAllowableVisits, Date activatedTimestamp,
String activatedBy, Date discontinuedTimestamp, String discontinuedBy, Status status,
CategoryOfCare categoryOfCare, ServiceLine serviceLine, Qasp qasp,
List<PayableService> services, Set<Hptc> hptcs)
{
this.seocKey = seocKey;
this.name = name;
this.versionNumber = versionNumber;
this.effectiveDate = effectiveDate;
this.endDate = endDate;
this.disclaimer = disclaimer;
this.duration = duration;
this.description = description;
this.rev = rev;
this.proceduralOverview = proceduralOverview;
this.maxAllowableVisits = maxAllowableVisits;
this.activatedTimestamp = activatedTimestamp;
this.activatedBy = activatedBy;
this.discontinuedTimestamp = discontinuedTimestamp;
this.discontinuedBy = discontinuedBy;
this.status = status;
this.categoryOfCare = categoryOfCare;
this.serviceLine = serviceLine;
this.qasp = qasp;
this.services = services;
this.services.forEach(s ->
{
s.setSeoc(this);
});
this.hptcs = hptcs;
}

/**
* Description: Determines if the ServiceLine has been discontinued
*
* @return boolean
*/
public boolean serviceLineDiscontinued()
{
Boolean discontinued = serviceLine.getDiscontinued();

return discontinued != null && discontinued;
}

/**
* Description: Determines if the CategoryOfCare has been discontinued
*
* @return boolean
*/
public boolean categoryOfCareDiscontinued()
{
Boolean discontinued = categoryOfCare.getDiscontinued();

return discontinued != null && discontinued;
}

/**
* Description: Determines if the Qasp has been discontinued
*
* @return boolean
*/
public boolean qaspDiscontinued()
{
Boolean discontinued = qasp.getDiscontinued();

return discontinued != null && discontinued;
}

/**
* Description: Deep clone of Seoc instance that which calls the method deepClone for PayableServices.
*
* @param noDeactivatedBillingCodes - when true, deactivated billingCodes will not be included in the cloned PayableServices
* @return Seoc
*/
public Seoc deepClone(Boolean noDeactivatedBillingCodes)
{
List<PayableService> thisServices = new ArrayList<PayableService>();
if (this.getServices() != null && !this.getServices().isEmpty())
{
this.getServices().forEach(service ->
{
thisServices.add(service.deepClone(noDeactivatedBillingCodes));
});
}

Set<Hptc> thisHptcs = new HashSet<Hptc>();
if(this.getHptcs()!=null && !this.getHptcs().isEmpty())
{
this.getHptcs().forEach(h -> {
thisHptcs.add(h);
});
}
Seoc thisSeoc = new Seoc(this.getSeocKey(), this.getName(), this.getVersionNumber(),
this.getEffectiveDate(), this.getEndDate(), this.getDisclaimer(),
this.getDuration(), this.getDescription(), this.getRev(),
this.getProceduralOverview(), this.getMaxAllowableVisits(),
this.getActivatedTimestamp(), this.getActivatedBy(),
this.getDiscontinuedTimestamp(), this.getDiscontinuedBy(), this.getStatus(),
this.getCategoryOfCare(), this.getServiceLine(), this.getQasp(), thisServices, thisHptcs);

if (thisSeoc.serviceLineDiscontinued())
{
thisSeoc.setServiceLine(null);
thisSeoc.setCategoryOfCare(null);
} else if (thisSeoc.categoryOfCareDiscontinued()) {
thisSeoc.setCategoryOfCare(null);
}

if (thisSeoc.qaspDiscontinued())
{
thisSeoc.setQasp(null);
}

return thisSeoc;
}

/**
* Description: Deep clone of Seoc instance that which calls the method deepClone for PayableServices.
*
* @return Seoc
*/
public Seoc deepClone()
{
return deepClone(false);
}

/**
* @return id
*/
public int getId()
{
return id;
}

/**
* @param id
*/
public void setId(int id)
{
this.id = id;
}

/**
* @return seocKey
*/
public int getSeocKey()
{
return seocKey;
}

/**
* @param seocKey
*/
public void setSeocKey(int seocKey)
{
this.seocKey = seocKey;
}

/**
* @return name
*/
public String getName()
{
return name;
}

/**
* @param name
*/
public void setName(String name)
{
this.name = name;
}

/**
* @return versionNumber
*/
public String getVersionNumber()
{
return versionNumber;
}

/**
* @param versionNumber
*/
public void setVersionNumber(String versionNumber)
{
this.versionNumber = versionNumber;
}

/**
* @return effectiveDate
*/
public Date getEffectiveDate()
{
return effectiveDate;
}

/**
* Description : Default Activation/Discontinuation Date to tomorrow defined as midnight = 0500 UTC
* @param effectiveDate
*/
public void setEffectiveDate(Date effectiveDate)
{
this.effectiveDate = ApiUtil.getUTCCalendarDate(effectiveDate);
}

/**
* @return endDate
*/
public Date getEndDate()
{
return endDate;
}

/**
* Description : Default Activation/Discontinuation Date to tomorrow defined as midnight = 0500 UTC
* @param endDate
*/
public void setEndDate(Date endDate)
{
this.endDate = ApiUtil.getUTCCalendarDate(endDate);
}

/**
* Description : Discontinuation Date will be set to immediate date
* @param endDate
*/
public void setEndDateToday()
{
this.endDate = ApiUtil.today_UTC();
}

/**
* @return disclaimer
*/
public String getDisclaimer()
{
return disclaimer;
}

/**
* @param disclaimer
*/
public void setDisclaimer(String disclaimer)
{
this.disclaimer = disclaimer;
}

/**
* @return duration
*/
public Integer getDuration()
{
return duration;
}

/**
* @param duration
*/
public void setDuration(Integer duration)
{
this.duration = duration;
}

/**
* @return description
*/
public String getDescription()
{
return description;
}

/**
* @param description
*/
public void setDescription(String description)
{
this.description = description;
}

/**
* @return rev
*/
public Boolean getRev()
{
return rev;
}

/**
* @param rev
*/
public void setRev(Boolean rev)
{
this.rev = rev;
}

/**
* @return proceduralOverview
*/
public String getProceduralOverview()
{
return proceduralOverview;
}

/**
* @param proceduralOverview
*/
public void setProceduralOverview(String proceduralOverview)
{
this.proceduralOverview = proceduralOverview;
}

/**
* @return maxAllowableVisits
*/
public Integer getMaxAllowableVisits()
{
return maxAllowableVisits;
}

/**
* @param maxAllowableVisits
*/
public void setMaxAllowableVisits(Integer maxAllowableVisits)
{
this.maxAllowableVisits = maxAllowableVisits;
}

/**
* @return activatedTimestamp
*/
public Date getActivatedTimestamp()
{
return activatedTimestamp;
}

/**
* @param activatedTimestamp
*/
public void setActivatedTimestamp(Date activatedTimestamp)
{
this.activatedTimestamp = ApiUtil.getUTCCalendarDate(activatedTimestamp);
}

/**
* @return activatedBy
*/
public String getActivatedBy()
{
return activatedBy;
}

/**
* @param activatedBy
*/
public void setActivatedBy(String activatedBy)
{
this.activatedBy = activatedBy;
}

/**
* @return discontinuedTimestamp
*/
public Date getDiscontinuedTimestamp()
{
return discontinuedTimestamp;
}

/**
* @param discontinuedTimestamp
*/
public void setDiscontinuedTimestamp(Date discontinuedTimestamp)
{
//discontinuedTimeStamp should have same date as setEndDateToday()
this.discontinuedTimestamp = ApiUtil.getUTCZoneDateTime(discontinuedTimestamp);
}

/**
* @return discontinuedBy
*/
public String getDiscontinuedBy()
{
return discontinuedBy;
}

/**
* @param discontinuedBy
*/
public void setDiscontinuedBy(String discontinuedBy)
{
this.discontinuedBy = discontinuedBy;
}

/**
* @param comment
*/
public void setComment(String comment)
{
this.comment = comment;
}

/**
* @return comment
*/
public String getComment()
{
if(comment==null || comment.isEmpty())
{
updateFormattedComment();
}
return comment;
}

/**
* @return status
*/
public Status getStatus()
{
return status;
}

/**
* @param status
*/
public void setStatus(Status status)
{
this.status = status;
}

/**
* @return categoryOfCare
*/
public CategoryOfCare getCategoryOfCare()
{
return categoryOfCare;
}

/**
* @param categoryOfCare
*/
public void setCategoryOfCare(CategoryOfCare categoryOfCare)
{
this.categoryOfCare = categoryOfCare;
}

/**
* @return serviceLine
*/
public ServiceLine getServiceLine()
{
return serviceLine;
}

/**
* @param serviceLine
*/
public void setServiceLine(ServiceLine serviceLine)
{
this.serviceLine = serviceLine;
}

/**
* @return qasp
*/
public Qasp getQasp()
{
return qasp;
}

/**
* @param qasp
*/
public void setQasp(Qasp qasp)
{
this.qasp = qasp;
}

/**
* @return payableServices
*/
public List<PayableService> getServices()
{
return services;
}

/**
* @param services
*/
public void setServices(List<PayableService> services)
{
this.services = services;
}

/**
* @return Status
*/
@Transient
@JsonProperty("status")
public String getStatusDescription()
{
String currentStatus = getCalculatedStatus();
return currentStatus;
}

/**
* @return serviceLine
*/
@Transient
@JsonProperty("serviceLine")
public String getServiceLineDescription()
{
if (this.getServiceLine() == null)
{
return null;
} else
{
return this.getServiceLine().getDescription();
}
}

/**
* @return categoryOfCare
*/
@Transient
@JsonProperty("categoryOfCare")
public String getCoCDescription()
{
if (this.getCategoryOfCare() == null)
{
return null;
} else
{
return this.getCategoryOfCare().getDescription();
}

}

/**
* @return QASP
*/
@Transient
@JsonProperty("QASP")
public String getQASPDescription()
{
if (this.getQasp() == null)
{
return null;
} else
{
return this.getQasp().getDescription();
}

}

/**
* Description: GetHptcs
* @return Set<Hptc>
*/
public Set<Hptc> getHptcs()
{
return hptcs;
}

/**
* Description: SetHptcs
* @param hptcs
*/
public void setHptcs(Set<Hptc> hptcs)
{
this.hptcs = hptcs;
}

/**
* Description: Concatenates Service Line abbreviation, Seoc name, version
* number, REV and PRE-CERT fields based on conditions. Ex:Service Line
* Abbreviation_SEOC Name_Version Number_REV (if a REV SEOC)_PRCT (if need
* pre-cert)
*
* @return returns the concatenated seocId
*/
@Transient
@JsonProperty("seocId")
public String getSeocId()
{
StringBuffer seocId = new StringBuffer();

if (serviceLine != null && serviceLine.getServiceAbbreviation() != null
&& !serviceLine.getServiceAbbreviation().isEmpty())
{
seocId.append(serviceLine.getServiceAbbreviation());
}

if (this.name != null && !this.name.isEmpty())
{
seocId.append(Constants.SEOCID_SEPARATOR);
seocId.append(this.name);
}

if (versionNumber != null)
{
seocId.append(Constants.SEOCID_SEPARATOR);
seocId.append(this.versionNumber);
}

if (rev != null && rev)
{
seocId.append(Constants.SEOCID_SEPARATOR + Constants.REV);
}

if (services != null)
{
if (getPrct())
{
seocId.append(Constants.SEOCID_SEPARATOR + Constants.PRCT);
}
}

return seocId.toString().toUpperCase();
}

public String getNameWithFlags()
{
StringBuffer seocName = new StringBuffer();

if (this.name != null && !this.name.isEmpty())
{
seocName.append(this.name);
}

if (rev != null && rev)
{
seocName.append(Constants.SEOCID_SEPARATOR + Constants.REV);
}

if (services != null)
{
if (getPrct())
{
seocName.append(Constants.SEOCID_SEPARATOR + Constants.PRCT);
}
}

return seocName.toString();
}

@JsonIgnore
@Transient
public boolean getPrct()
{
boolean precertReqd = false;
if(services!=null) {
Stream<PayableService> serviceStream = services.stream();

precertReqd = serviceStream.anyMatch(service -> (service.getBillingCodes() != null && service.getBillingCodes()
.stream().anyMatch(billingCode -> (billingCode.getPrecertRequired() != null
&& billingCode.getPrecertRequired()))) || service.getCodeRequired() != null &&
(service.codeRequiredEquals("NO") || service.codeRequiredEquals("ANY")));
}

return precertReqd;

}

@Transient
public boolean removePayableService(PayableService service)
{
service.setSeoc(null);
return this.services.remove(service);
}

@Transient
public boolean addPayableService(PayableService service)
{
service.setSeoc(this);
return this.services.add(service);
}

/**
* Description: SEOC Status becomes ACTIVE (DISCONTINUED) at 05:01 UTC (12:01am EST) on the Effective (End) Date
* a. INPROGRESS: Effective Date = NULL
* b. HOLD: Today < Effective Date
* c. ACTIVE: Effecting Date <= Today AND (Today < End Date OR End Date = NULL)
* d. DISCONTINUED: Today >= End Date
* Calculates status of the SEOC based on the effective and end dates
* @return String
*/
@JsonIgnore
@Transient
public String getCalculatedStatus() {
String status = getStatus().getDescription();

if (status.equalsIgnoreCase(Constants.STATUS_ACTIVE)
|| status.equalsIgnoreCase(Constants.STATUS_DISCONTINUED))
{
status = Constants.STATUS_DATEHOLD;
} else if (status.equalsIgnoreCase(Constants.STATUS_DRAFT))
{
status = Constants.STATUS_INPROGRESS;
}

if(this.effectiveDate==null) {
return status;
}

Date effectiveDateUTC = this.getEffectiveDate();
Date endDateUTC = this.getEndDate();

if(ApiUtil.today_UTC().before(effectiveDateUTC))
{
return status;
}else if(!ApiUtil.today_UTC().before(effectiveDateUTC)
&& (endDateUTC==null || ApiUtil.today_UTC().before(endDateUTC)))
{
status = Constants.STATUS_ACTIVE;
}else if(!ApiUtil.today_UTC().before(endDateUTC))
{
status = Constants.STATUS_DISCONTINUED;
}
return status;
}

/**
* Description: Remove Billing Code from all services in the Seoc
* @param bc
*/
@Transient
public void removeBillingCode(BillingCode bc)
{
List<PayableService> services = this.getServices();

if(services==null || services.isEmpty())
{
return;
}

services.forEach(s -> {
if(s!=null) {
s.removeBillingCode(bc);
}
});
}

/**
* Description: In a SEOC if a service contains old billing code, remove old billing code and add new billing code
* @param prevBC Previous Billing Code
* @param newBC New Billing Code
*/
@Transient
public void updateBillingCode(BillingCode prevBC, BillingCode newBC)
{
List<PayableService> services = this.getServices();

if(services==null || services.isEmpty())
{
return;
}

services.forEach(s -> {
if(s!=null) {
s.updateBillingCode(prevBC, newBC);
}
});
}

/**
* Description: Return all billingCodes associated with the SEOC
* @return Set<BillingCode>
*/
@JsonIgnore
@Transient
public Set<BillingCode> getBillingCodesForSeoc()
{
Set<BillingCode> billingCodesForSeoc = new HashSet<BillingCode>();

List<PayableService> services = this.getServices();

if (services == null || services.isEmpty()) {
return null;
}

services.forEach(service -> {
Set<BillingCode> billingCodes = null;

if (service != null) {
billingCodes = service.getBillingCodes();
}

if (!(billingCodes == null || billingCodes.isEmpty())) {
billingCodes.forEach(billingCode -> {
if (billingCode != null) {
billingCodesForSeoc.add(billingCode);
}
});
}
});

return billingCodesForSeoc.isEmpty() ? null : billingCodesForSeoc;
}

/**
* Description: Update comment with formatted SEOC data
* [name]
*
* SEOC ID:[seocID]
* Description:[description]
* Duration:[duration]days
*
* Procedural Overview:
* [proceduralOverview]
*
* [disclaimer]
*/
@Transient
public void updateFormattedComment()
{
StringBuffer strBuf = new StringBuffer();

strBuf.append("VHA Office of Community Care - Standardized Episode of Care\r\n");
strBuf.append(name + "\r\n\r\n");
strBuf.append("SEOC ID:" + this.getSeocId() + "\r\n");
strBuf.append("Description:" + this.getDescription() + "\r\n");
strBuf.append("Duration:" + this.getDuration() + " days\r\n\r\n");
strBuf.append("Procedural Overview:\r\n" + this.getProceduralOverview() + "\r\n\r\n");
strBuf.append(this.getDisclaimer());

this.setComment(ApiUtil.removeInvalidCharacters(strBuf.toString()));
}

/**
* {@inheritDoc}
*/
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((activatedBy == null) ? 0 : activatedBy.hashCode());
result = prime * result
+ ((activatedTimestamp == null) ? 0 : activatedTimestamp.hashCode());
result = prime * result + ((categoryOfCare == null) ? 0 : categoryOfCare.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((disclaimer == null) ? 0 : disclaimer.hashCode());
result = prime * result + ((discontinuedBy == null) ? 0 : discontinuedBy.hashCode());
result = prime * result
+ ((discontinuedTimestamp == null) ? 0 : discontinuedTimestamp.hashCode());
result = prime * result + ((duration == null) ? 0 : duration.hashCode());
result = prime * result + ((effectiveDate == null) ? 0 : effectiveDate.hashCode());
result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
result = prime * result + id;
result = prime * result
+ ((maxAllowableVisits == null) ? 0 : maxAllowableVisits.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((rev == null) ? 0 : rev.hashCode());
result = prime * result
+ ((proceduralOverview == null) ? 0 : proceduralOverview.hashCode());
result = prime * result + ((qasp == null) ? 0 : qasp.hashCode());
result = prime * result + seocKey;
result = prime * result + ((serviceLine == null) ? 0 : serviceLine.hashCode());
result = prime * result + ((services == null) ? 0 : services.hashCode());
result = prime * result + ((status == null) ? 0 : status.hashCode());
result = prime * result + ((versionNumber == null) ? 0 : versionNumber.hashCode());
return result;
}

/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
Seoc other = (Seoc) obj;
if (activatedBy == null)
{
if (other.activatedBy != null)
{
return false;
}
} else if (!activatedBy.equals(other.activatedBy))
{
return false;
}
if (activatedTimestamp == null)
{
if (other.activatedTimestamp != null)
{
return false;
}
} else if (!activatedTimestamp.equals(other.activatedTimestamp))
{
return false;
}
if (categoryOfCare == null)
{
if (other.categoryOfCare != null)
{
return false;
}
} else if (!categoryOfCare.equals(other.categoryOfCare))
{
return false;
}
if (description == null)
{
if (other.description != null)
{
return false;
}
} else if (!description.equals(other.description))
{
return false;
}
if (disclaimer == null)
{
if (other.disclaimer != null)
{
return false;
}
} else if (!disclaimer.equals(other.disclaimer))
{
return false;
}
if (discontinuedBy == null)
{
if (other.discontinuedBy != null)
{
return false;
}
} else if (!discontinuedBy.equals(other.discontinuedBy))
{
return false;
}
if (discontinuedTimestamp == null)
{
if (other.discontinuedTimestamp != null)
{
return false;
}
} else if (!discontinuedTimestamp.equals(other.discontinuedTimestamp))
{
return false;
}
if (duration == null)
{
if (other.duration != null)
{
return false;
}
} else if (!duration.equals(other.duration))
{
return false;
}
if (effectiveDate == null)
{
if (other.effectiveDate != null)
{
return false;
}
} else if (!effectiveDate.equals(other.effectiveDate))
{
return false;
}
if (endDate == null)
{
if (other.endDate != null)
{
return false;
}
} else if (!endDate.equals(other.endDate))
{
return false;
}
if (id != other.id)
{
return false;
}
if (maxAllowableVisits == null)
{
if (other.maxAllowableVisits != null)
{
return false;
}
} else if (!maxAllowableVisits.equals(other.maxAllowableVisits))
{
return false;
}
if (name == null)
{
if (other.name != null)
{
return false;
}
} else if (!name.equals(other.name))
{
return false;
}
if (rev == null)
{
if (other.rev != null)
{
return false;
}
} else if (!rev.equals(other.rev))
{
return false;
}
if (proceduralOverview == null)
{
if (other.proceduralOverview != null)
{
return false;
}
} else if (!proceduralOverview.equals(other.proceduralOverview))
{
return false;
}
if (qasp == null)
{
if (other.qasp != null)
{
return false;
}
} else if (!qasp.equals(other.qasp))
{
return false;
}
if (seocKey != other.seocKey)
{
return false;
}
if (serviceLine == null)
{
if (other.serviceLine != null)
{
return false;
}
} else if (!serviceLine.equals(other.serviceLine))
{
return false;
}
if (services == null)
{
if (other.services != null)
{
return false;
}
} else if (!services.equals(other.services))
{
return false;
}
if (status == null)
{
if (other.status != null)
{
return false;
}
} else if (!status.equals(other.status))
{
return false;
}
if (versionNumber == null)
{
if (other.versionNumber != null)
{
return false;
}
} else if (!versionNumber.equals(other.versionNumber))
{
return false;
}
return true;
}

/**
* {@inheritDoc}
*/
@Override
public String toString()
{
return "Seoc [id=" + id + ", seocKey=" + seocKey + ", name=" + name + ", versionNumber="
+ versionNumber + ", effectiveDate=" + effectiveDate + ", endDate=" + endDate
+ ", disclaimer=" + disclaimer + ", duration=" + duration + ", description="
+ description + ", rev=" + rev + ", proceduralOverview=" + proceduralOverview
+ ", maxAllowableVisits=" + maxAllowableVisits + ", activatedTimestamp="
+ activatedTimestamp + ", activatedBy=" + activatedBy + ", discontinuedTimestamp="
+ discontinuedTimestamp + ", discontinuedBy=" + discontinuedBy + ", status="
+ status + ", categoryOfCare=" + categoryOfCare + ", serviceLine=" + serviceLine
+ ", qasp=" + qasp + ", services=" + services + "]";
}

}