18 package org.turro.dossier.entity;
20 import java.util.Collection;
21 import java.util.Date;
22 import java.util.HashSet;
23 import java.util.Iterator;
25 import javax.persistence.*;
26 import org.turro.string.Strings;
27 import org.turro.action.Contacts;
28 import org.turro.action.Interceptors;
29 import org.turro.dossier.db.DossierPU;
30 import org.turro.dossier.dossier.ParticipantSet;
31 import org.turro.jpa.Dao;
32 import org.turro.jpa.entity.IDaoEntity;
33 import org.turro.math.Round;
34 import org.turro.plugin.contacts.IContact;
35 import org.turro.reflection.MappingSet;
36 import org.turro.related.RelatedItem;
37 import org.turro.util.Chars;
47 @GeneratedValue(strategy=GenerationType.IDENTITY)
48 @Column(name=
"IDENTIFIER")
51 @Temporal(value = TemporalType.TIMESTAMP)
52 private java.util.Date startDate;
54 @Temporal(value = TemporalType.TIMESTAMP)
55 private java.util.Date controlDate;
57 @Temporal(value = TemporalType.TIMESTAMP)
58 private java.util.Date delivery;
60 @Temporal(value = TemporalType.TIMESTAMP)
61 private java.util.Date issueDate;
63 @Temporal(value = TemporalType.TIMESTAMP)
64 private java.util.Date modification;
66 @Temporal(value = TemporalType.TIMESTAMP)
67 private java.util.Date solvedDate;
71 private String description, grouping;
73 @Column(name=
"ISSUE_TYPE")
82 private double expenses, hours, price;
84 private boolean publishable, milestone;
87 private Issue duplicated;
90 @JoinColumn(name=
"DOSSIER_FK")
96 @OneToMany(mappedBy =
"issue", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval=
true)
97 @OrderBy(value=
"name")
98 private Set<IssueParticipant> participants =
new HashSet<IssueParticipant>();
100 @OneToMany(mappedBy =
"issue", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval=
true)
101 @OrderBy(value =
"modification ASC")
102 private Set<IssueComment> comments =
new HashSet<IssueComment>();
104 @OneToMany(mappedBy =
"target", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval=
true)
105 @OrderBy(value=
"type")
106 private Set<IssuePredecessor> sources =
new HashSet<IssuePredecessor>();
108 @OneToMany(mappedBy =
"source", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval=
true)
109 @OrderBy(value=
"type")
110 private Set<IssuePredecessor> targets =
new HashSet<IssuePredecessor>();
119 this.participants = participants;
124 if(
id !=
null &&
id > 0 && dao.
isNotLoaded(comments)) {
125 comments = dao.lazyLoader(
Issue.class,
this,
"comments").comments;
131 this.comments = comments;
139 this.controlDate = controlDate;
147 this.delivery = delivery;
155 this.description = description;
163 this.dossier = dossier;
171 this.duplicated = duplicated;
187 this.issueDate = issueDate;
195 this.milestone = milestone;
203 this.modification = modification;
211 this.priority = priority;
219 this.publishable = publishable;
231 this.resolution = resolution;
243 this.solvedDate = solvedDate;
252 solvedDate = endDate !=
null ? endDate :
new Date();
256 this.status = status;
264 this.grouping = grouping;
269 if(
id !=
null &&
id > 0 && dao.
isNotLoaded(sources)) {
270 sources = dao.lazyLoader(
Issue.class,
this,
"sources").sources;
276 this.sources = sources;
281 if(
id !=
null &&
id > 0 && dao.
isNotLoaded(targets)) {
282 targets = dao.lazyLoader(
Issue.class,
this,
"targets").targets;
288 this.targets = targets;
304 this.expenses = expenses;
328 this.startDate = startDate;
336 this.version = version;
348 return Strings.isBlank(description) || dossier ==
null;
360 (dossier !=
null ? Chars.forward().spaced() + dossier.getFullDescription(withSubject) :
"");
364 if(dossier !=
null) {
365 return dossier.isKnowledgeBase();
373 if(last ==
null || last.
getModification().before(comment.getModification())) {
382 private transient Collection<Issue> _duplicates;
385 if(_duplicates ==
null) {
387 _duplicates = dao.getResultList(
388 "select distinct i from Issue i " +
389 "where i.duplicated = ?",
390 new Object[] {
this });
428 if(
id ==
null)
return null;
433 if(contact ==
null)
return null;
444 if(contact ==
null)
return null;
446 while(it.hasNext()) {
462 if(_participants ==
null) {
464 if(dossier !=
null) _participants.
addAll(dossier.getFullParticipants());
466 return _participants;
476 return expenses != 0 || hours != 0 || price != 0;
482 r += c.getExpenses();
524 .replaceAll(
"\\#IID",
getId() +
"");
530 private transient Collection<Issue> _body, _next;
535 _body = dao.getResultList(
536 "select distinct ip.target from IssuePredecessor ip " +
537 "where ip.source = ? " +
546 if(!_body.isEmpty()) {
548 for(
Issue i : _body) {
549 if(i.getStatus().isFinished()) {
553 return new Round(d / ((
double) _body.size()) * 100.0).
decimals(2).value();
561 _next = dao.getResultList(
562 "select distinct ip.target from IssuePredecessor ip " +
563 "where ip.source = ? " +
564 "and ip.target.grouping = ip.source.grouping " +
574 MappingSet
set =
new MappingSet();
575 set.addMapping(
Dossier.class, 1,
576 new String[] {
"id" },
static Parameters parameters(String root)
boolean addAll(Collection<? extends P > collection)
Map< String, Object > getFieldMap()
void setIssue(Issue issue)
void setRole(IssueParticipantRole role)
void setIdContact(String idContact)
void setName(String name)
IssueParticipantRole getRole()
void setPublishable(boolean publishable)
void setTargets(Set< IssuePredecessor > targets)
ParticipantSet getFullParticipants()
void setMilestone(boolean milestone)
void setType(IssueType type)
IssueResolution getResolution()
Collection< Issue > getBodyIssues()
IssuePriority getPriority()
IssueParticipant removeParticipant(IContact contact, IssueParticipantRole role)
void setResolution(IssueResolution resolution)
void setParticipants(Set< IssueParticipant > participants)
boolean isKnowledgeBase()
void setDescription(String description)
static Issue getDefaultIssue()
void setModification(Date modification)
Collection< Issue > getDuplicates()
IssueParticipant addReporter(Object contact)
void setVersion(DossierVersion version)
Collection< Issue > getNextIssues()
IssueParticipant addQA(Object contact)
void setStatus(IssueStatus status)
ParticipantSet< IssueParticipant > getIssueParticipants()
void setDossier(Dossier dossier)
void setControlDate(Date controlDate)
void setStatus(IssueStatus status, Date endDate)
IssueParticipant addReporter(IContact contact)
void setComments(Set< IssueComment > comments)
IssueParticipant addResponsible(IContact contact)
IssueParticipant addParticipant(IContact contact, IssueParticipantRole role)
void setPriority(IssuePriority priority)
Set< IssueComment > getComments()
void setSolvedDate(Date solvedDate)
void setDuplicated(Issue duplicated)
void setStartDate(Date startDate)
void setSources(Set< IssuePredecessor > sources)
void setHours(double hours)
IssueParticipant addQA(IContact contact)
IssueParticipant addResponsible(Object contact)
DossierVersion getVersion()
void setGrouping(String grouping)
Set< IssueParticipant > getParticipants()
double getBodyPercentDone()
IssueParticipant addParticipant(String id, IssueParticipantRole role)
Set< IssuePredecessor > getSources()
void setIssueDate(Date issueDate)
String getFullDescription()
void setPrice(double price)
MappingSet getSerializerMappings()
String getFullDescription(boolean withSubject)
void setExpenses(double expenses)
IssueComment getLastComment()
Set< IssuePredecessor > getTargets()
void setDelivery(Date delivery)
boolean isNotLoaded(Object o, String attribute)
Round decimals(int digits)