content: package xyz.zhangyi.ddd.eas.projectcontext.domain.issue;
  
  import xyz.zhangyi.ddd.core.stereotype.Aggregate;
  import xyz.zhangyi.ddd.eas.projectcontext.domain.changehistory.ChangeHistory;
  import xyz.zhangyi.ddd.eas.projectcontext.domain.changehistory.Operation;
  import xyz.zhangyi.ddd.eas.projectcontext.domain.changehistory.Operator;
  import xyz.zhangyi.ddd.eas.projectcontext.domain.exception.AssignmentIssueException;
  import java.time.LocalDateTime;
  
  @Aggregate
  public class Issue {
      private IssueId issueId;
      private String name;
      private String description;
      private String ownerId;
      private IssueStatus status;
  
      private Issue(IssueId issueId, String name, String description) {
          this.issueId = issueId;
          this.name = name;
          this.description = description;
          this.status = IssueStatus.Open;
      }
  
      public static Issue of(IssueId issueId, String name, String description) {
          return new Issue(issueId, name, description);
      }
  
      public ChangeHistory assignTo(IssueOwner owner, Operator operator) {
          if (status.isResolved()) {
              throw new AssignmentIssueException("resolved issue can not be assigned.");
          }
          if (status.isClosed()) {
              throw new AssignmentIssueException("closed issue can not be assigned.");
          }
          if (this.ownerId != null && this.ownerId.equals(owner.id())) {
              throw new AssignmentIssueException("issue can not be assign to same owner again.");
          }
          this.ownerId = owner.id();
          return ChangeHistory
                  .operate(Operation.Assignment)
                  .to(issueId.id())
                  .by(operator)
                  .at(LocalDateTime.now());
      }
  
      public String ownerId() {
          return ownerId;
      }
  
      public IssueStatus status() {
          return status;
      }
  
      public void changeStatusTo(IssueStatus issueStatus) {
          this.status = issueStatus;
      }
  }