Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.gradle
build/
.idea
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
Expand Down
19 changes: 16 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
plugins {
id("java")
id("io.freefair.lombok") version "9.1.0"
}

group = "org.lab"
version = "1.0-SNAPSHOT"
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(25))
}
}

group = "org.itmo"
version = "1.0"

repositories {
mavenCentral()
gradlePluginPortal()
}

dependencies {
Expand All @@ -15,6 +23,11 @@ dependencies {
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

tasks.compileJava {
options.release = 25
options.encoding = "UTF-8"
}

tasks.test {
useJUnitPlatform()
}
}
17 changes: 17 additions & 0 deletions src/main/java/org/itmo/CurrentUserHolder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.itmo;

import org.itmo.entity.UserEntity;

import lombok.Setter;

public class CurrentUserHolder {
@Setter
private static UserEntity user;

public static UserEntity getUser() {
if (user == null) {
throw new IllegalStateException("No current user");
}
return user;
}
}
6 changes: 6 additions & 0 deletions src/main/java/org/itmo/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.itmo;

public class Main {
static void main(String[] args) {
}
}
6 changes: 6 additions & 0 deletions src/main/java/org/itmo/dto/BugDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.itmo.dto;

import org.itmo.type.BugStatusEnum;

public record BugDto(long id, String title, BugStatusEnum status) {
}
6 changes: 6 additions & 0 deletions src/main/java/org/itmo/dto/ProjectBugsDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.itmo.dto;

import java.util.Set;

public record ProjectBugsDto(ProjectDto projectDto, Set<BugDto> bugs) {
}
4 changes: 4 additions & 0 deletions src/main/java/org/itmo/dto/ProjectDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package org.itmo.dto;

public record ProjectDto(long id, String name) {
}
8 changes: 8 additions & 0 deletions src/main/java/org/itmo/dto/ProjectTicketsDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.itmo.dto;

import java.util.Set;

import org.itmo.entity.TicketEntity;

public record ProjectTicketsDto(ProjectDto projectDto, Set<TicketEntity> tickets) {
}
18 changes: 18 additions & 0 deletions src/main/java/org/itmo/entity/AbstractEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.itmo.entity;

import java.util.concurrent.atomic.AtomicLong;

import lombok.EqualsAndHashCode;
import lombok.Getter;

@EqualsAndHashCode
public sealed abstract class AbstractEntity permits BugEntity, MilestoneEntity, ProjectEntity, TicketEntity, UserEntity {
private static final AtomicLong idSequence = new AtomicLong(0);

@Getter
private final Long id;

public AbstractEntity() {
this.id = idSequence.incrementAndGet();
}
}
24 changes: 24 additions & 0 deletions src/main/java/org/itmo/entity/BugEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.itmo.entity;

import org.itmo.dto.BugDto;
import org.itmo.type.BugStatusEnum;

import lombok.Getter;
import lombok.Setter;

public final class BugEntity extends AbstractEntity {
private final String title;
@Getter
@Setter
private BugStatusEnum status;

public BugEntity(String title) {
super();
this.title = title;
this.status = BugStatusEnum.NEW;
}

public BugDto toDto() {
return new BugDto(getId(), title, status);
}
}
74 changes: 74 additions & 0 deletions src/main/java/org/itmo/entity/MilestoneEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.itmo.entity;

import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.itmo.type.MilestoneStatusEnum;
import org.itmo.type.TicketStatusEnum;

import lombok.Getter;
import lombok.Setter;

public final class MilestoneEntity extends AbstractEntity {
@Getter
private final String name;
@Getter
private final LocalDate startDate;
@Getter
private final LocalDate endDate;

@Getter
@Setter
private MilestoneStatusEnum status;

private final Map<Long, TicketEntity> tickets = new HashMap<>();
private final Map<UserEntity, Set<TicketEntity>> assigneesTickets = new HashMap<>();

public MilestoneEntity(String name, LocalDate startDate, LocalDate endDate) {
if (endDate.isBefore(startDate)) {
throw new IllegalArgumentException("Start date must not be after end date");
}
this.name = name;
this.startDate = startDate;
this.endDate = endDate;
this.status = MilestoneStatusEnum.OPEN;
}

public boolean hasActiveTickets() {
return tickets.values().stream().anyMatch(t -> t.getStatus() != TicketStatusEnum.COMPLETED);
}

public Set<TicketEntity> getAssignedTickets(UserEntity user) {
var tickets = assigneesTickets.get(user);
if (tickets == null) {
return new HashSet<>();
}
return tickets;
}

public TicketEntity createTicket(String title) {
TicketEntity ticket = new TicketEntity(title);
tickets.put(ticket.getId(), ticket);
return ticket;
}

public void assignTicket(UserEntity assignee, TicketEntity ticket) {
if (tickets.get(ticket.getId()) == null) {
throw new IllegalArgumentException("Unknown ticket");
}
assigneesTickets.compute(assignee, (_, v) -> {
// ^^^ feature!
if (v == null) {
Set<TicketEntity> set = new HashSet<>();
set.add(ticket);
return set;
}
v.add(ticket);
return v;
});
}
}
Loading