Hi,
I have been using the Lori Timesheets that you guys created.
I am trying to create a new TimeEntry Entity via the REST API using Postman.
Whenever I try to create a new entity I get the following response:
“error”: “Server error”,
“details”: “”
I have added the REST API role to have full access permissions to the TimeEntry Entity.
I can get access tokens, search for Entities by ID etc but can’t seem to create any, so I know the REST API is working.
Here is the TimeEntry class:
import com.haulmont.chile.core.annotations.MetaProperty;
import com.haulmont.chile.core.annotations.NamePattern;
import com.haulmont.cuba.core.entity.StandardEntity;
import com.haulmont.cuba.core.entity.annotation.Listeners;
import com.haulmont.cuba.core.entity.annotation.OnDeleteInverse;
import com.haulmont.cuba.core.entity.annotation.PublishEntityChangedEvents;
import com.haulmont.cuba.core.global.DeletePolicy;
import com.haulmont.cuba.core.global.PersistenceHelper;
import com.haulmont.timesheets.global.HoursAndMinutes;
import org.slf4j.Logger;
import javax.persistence.*;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.Date;
import java.util.Set;
/**
* @author gorelov
*/
@PublishEntityChangedEvents
@Listeners("ts_TimeEntryListener")
@NamePattern("#getCaption|timeInMinutes")
@Table(name = "TS_TIME_ENTRY")
@Entity(name = "ts$TimeEntry")
public class TimeEntry extends StandardEntity implements TimeEntryBase {
private static final long serialVersionUID = -5042871389501734493L;
private static final Logger log = org.slf4j.LoggerFactory.getLogger(TimeEntry.class);
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "TASK_ID")
protected Task task;
@Column(name = "TASK_NAME", length = 100)
protected String taskName;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "USER_ID")
protected ExtUser user;
@JoinTable(name = "TS_TIME_ENTRY_TAG_LINK",
joinColumns = @JoinColumn(name = "TIME_ENTRY_ID"),
inverseJoinColumns = @JoinColumn(name = "TAG_ID"))
@ManyToMany
protected Set<Tag> tags;
@Temporal(TemporalType.DATE)
@Column(name = "DATE_", nullable = false)
protected Date date;
@Column(name = "COST_CODE")
protected String costCode;
@Column(name = "COST_TYPE")
protected Integer costType = 1;
@Column(name = "CATEGORY")
protected String category = "L";
@Column(name = "TIME_IN_MINUTES", nullable = false)
protected Integer timeInMinutes = 0;
@Column(name = "STATUS", nullable = false)
protected String status = TimeEntryStatus.NEW.getId();
@Column(name = "DESCRIPTION")
protected String description;
@Column(name = "REJECTION_REASON")
protected String rejectionReason;
@OnDeleteInverse(DeletePolicy.DENY)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ACTIVITY_TYPE_ID")
protected ActivityType activityType;
@Column(name = "TIME_IN_HOURS", nullable = false, precision = 10, scale = 2)
protected BigDecimal timeInHours;
@Column(name = "CLOCK_IN_TIME")
protected LocalTime clockInTime;
@MetaProperty
@Transient
protected BigDecimal overtimeInHours;
public LocalTime getClockInTime() {
return clockInTime;
}
public void setClockInTime(LocalTime clockInTime) {
this.clockInTime = clockInTime;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public Integer getCostType() {
return costType;
}
public void setCostType(Integer costType) {
this.costType = costType;
}
public String getCostCode() {
return costCode;
}
public void setCostCode(String costCode) {
this.costCode = costCode;
}
public void setUser(ExtUser user) {
this.user = user;
}
public ExtUser getUser() {
return user;
}
public void setTimeInHours(BigDecimal timeInHours) {
this.timeInHours = timeInHours;
}
public BigDecimal getTimeInHours() {
return timeInHours;
}
public void setTimeInMinutes(Integer timeInMinutes) {
this.timeInMinutes = timeInMinutes;
}
public Integer getTimeInMinutes() {
return timeInMinutes;
}
public void setActivityType(ActivityType activityType) {
this.activityType = activityType;
}
public ActivityType getActivityType() {
return activityType;
}
public TimeEntryStatus getStatus() {
return status == null ? null : TimeEntryStatus.fromId(status);
}
public void setStatus(TimeEntryStatus status) {
this.status = status == null ? null : status.getId();
}
public Set<Tag> getTags() {
return tags;
}
public void setTags(Set<Tag> tags) {
this.tags = tags;
}
public void setDescription(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public String getTaskName() {
return taskName;
}
public void setDate(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
public void setTask(Task task) {
this.task = task;
}
public Task getTask() {
return task;
}
public void setRejectionReason(String rejectionReason) {
this.rejectionReason = rejectionReason;
}
public String getRejectionReason() {
return rejectionReason;
}
public String getCaption() {
return HoursAndMinutes.fromTimeEntry(this).getFormattedCaption();
}
public HoursAndMinutes getSpentTime(){
return HoursAndMinutes.fromTimeEntry(this);
}
public BigDecimal getOvertimeInHours() {
return overtimeInHours;
}
public void setOvertimeInHours(BigDecimal overtimeInHours) {
this.overtimeInHours = overtimeInHours;
}
@MetaProperty(related = {"user", "date"})
public Overtime getOvertime() {
if (!PersistenceHelper.isLoaded(this, "user")
|| !PersistenceHelper.isLoaded(this, "date")) {
return null;
}
return new Overtime(getUser(), getDate(), overtimeInHours);
}
public void setOvertime(Overtime overtimeInHours) {
this.overtimeInHours = overtimeInHours != null ? overtimeInHours.overtimeInHours : null;
}
public void setCostCode(TimeEntry timeEntry){
ExtUser extUser = timeEntry.getUser();
String costHead = extUser.getCostHead().getId();//extUserDl.getContainer().getItem().getCostHead().toString();
Boolean isSmallWorksFm = null;
Task taskField = timeEntry.getTask();
Project project = null;
String projectCode="";
project = taskField.getProject();
isSmallWorksFm = project.getIsSmallWorksFm();
log.info(String.valueOf(isSmallWorksFm));//projectsService.getIsSmallWorksFm(project).get(0).getIsSmallWorksFm();
projectCode = project.getCode();
//costHead = extUser.getCostHead().toString();
if(costHead.equals("2002")){
//costHead = extUser.getCostHead().getId();
timeEntry.setCostCode(costHead);
}
else if(isSmallWorksFm){
timeEntry.setCostCode(projectCode + costHead);
}
else{
timeEntry.setCostCode(projectCode);
}
}
}
Below is my postman request body for to create a new instance of a TimeEntry:
{
"_entityName": "ts$TimeEntry",
"_instanceName": " 5h 00m",
"id": "4d8ef1d4-90b6-c075-8bfd-79181ff889ef",
"date": "2021-04-10",
"description": null,
"costType": 1,
"timeInHours": 5.00,
"timeInMinutes": 300,
"tags": [],
"costCode": "2002",
"task": {
"_entityName": "ts$Task",
"_instanceName": "[Bloomberg] Standard Hours",
"id": "52eae3b8-8ba6-e98e-72f9-b2b98f15f344",
"code": "2541_STANDARD_HOURS",
"description": null,
"project": {
"_entityName": "ts$Project",
"_instanceName": "Bloomberg",
"id": "58b61257-4b78-869a-b4e7-104ae63d60fd",
"parent": null,
"code": "2541",
"timeEntryNamePattern": null,
"isSmallWorksFm": false,
"name": "Bloomberg"
},
"type": {
"_entityName": "ts$TaskType",
"_instanceName": "Standard Hours",
"id": "b8a60df1-a585-a4cc-18fa-0434dbe7cf6e",
"name": "Standard Hours"
},
"defaultTags": [],
"requiredTagTypes": [],
"name": "Standard Hours",
"exclusiveParticipants": [],
"status": "ACTIVE"
},
"taskName": "Standard Hours",
"category": "L",
"rejectionReason": null,
"activityType": null,
"user": {
"_entityName": "ts$ExtUser",
"_instanceName": "admin admin",
"id": "60885987-1b61-4247-94c7-dff348347f93",
"lastName": "admin",
"login": "admin",
"costHead": "L2002",
"firstName": "admin",
"name": "Administrator"
},
"status": "NEW"
}
My idea was to ‘Get an Entity by ID’ via the REST API so I could see the structure of a TimeEntry Entity and then copy the body of it and change the ID so it would be a new Entity. I have tried so many different variations of the above JSON body to no success.
Any help would be much appreciated.