Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@
@Builder(access = AccessLevel.PRIVATE)
@Schema(description = "근무자 요약 정보")
public class WorkerSummaryDto {

@Schema(description = "근무자 ID", example = "1")
private Long workerId;

@Schema(description = "근무자명", example = "김알바")
private String workerName;

@Schema(description = "근무자 표시 색상 (hex)", example = "#9CA3AF")
private String colorCode;

public static WorkerSummaryDto of(WorkspaceWorker workspaceWorker) {
if (ObjectUtils.isEmpty(workspaceWorker)) {
return null;
}

return WorkerSummaryDto.builder()
.workerId(workspaceWorker.getId())
.workerName(workspaceWorker.getUser().getName())
.colorCode(workspaceWorker.getColorCode())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@
import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.ManagerWorkspaceWorkerListFilterDto;
import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.ManagerWorkspaceWorkerListResponseDto;
import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.UpdateFixedScheduleDateRequestDto;
import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.UpdateWorkspaceWorkerColorRequestDto;
import com.dreamteam.alter.application.aop.ManagerActionContext;
import com.dreamteam.alter.domain.user.context.ManagerActor;
import com.dreamteam.alter.domain.workspace.command.UpdateWorkspaceWorkerColorCommand;
import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceListUseCase;
import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceManagerListUseCase;
import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceUseCase;
import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceWorkerListUseCase;
import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateFixedScheduleDateUseCase;
import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateWorkspaceWorkerColorCodeUseCase;

import jakarta.annotation.Resource;
import jakarta.validation.Valid;
Expand Down Expand Up @@ -55,6 +58,9 @@ public class ManagerWorkspaceController implements ManagerWorkspaceControllerSpe
@Resource(name = "managerUpdateFixedScheduleDate")
private final ManagerUpdateFixedScheduleDateUseCase managerUpdateFixedScheduleDate;

@Resource(name = "managerUpdateWorkspaceWorkerColorCode")
private final ManagerUpdateWorkspaceWorkerColorCodeUseCase managerUpdateWorkspaceWorkerColor;

@Override
@GetMapping
public ResponseEntity<CommonApiResponse<List<ManagerWorkspaceListResponseDto>>> getWorkspaceList() {
Expand Down Expand Up @@ -106,4 +112,21 @@ public ResponseEntity<CommonApiResponse<Void>> updateFixedScheduleDate(
managerUpdateFixedScheduleDate.execute(actor, workspaceId, request);
return ResponseEntity.ok(CommonApiResponse.empty());
}

@Override
@PatchMapping("/{workspaceId}/workers/{workerId}/color")
public ResponseEntity<CommonApiResponse<Void>> updateWorkspaceWorkerColorCode(
@PathVariable Long workspaceId,
@PathVariable Long workerId,
@RequestBody @Valid UpdateWorkspaceWorkerColorRequestDto request
) {
ManagerActor actor = ManagerActionContext.getInstance().getActor();
managerUpdateWorkspaceWorkerColor.execute(
actor,
workspaceId,
workerId,
UpdateWorkspaceWorkerColorCommand.of(request.getColorCode())
);
return ResponseEntity.ok(CommonApiResponse.empty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,50 @@ ResponseEntity<CommonApiResponse<Void>> updateFixedScheduleDate(
@RequestBody @Valid UpdateFixedScheduleDateRequestDto request
);

@Operation(summary = "매니저 - 근무자 색상 변경", description = "근무자 캘린더에서 사용할 표시 색상을 변경합니다. 같은 업장의 ACTIVATED 근무자끼리 색상은 unique 합니다 (기본 색상 #9CA3AF 제외).")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "색상 변경 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 색상 형식",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class),
examples = {
@ExampleObject(
name = "잘못된 요청",
value = "{\"code\" : \"B001\"}"
),
})),
@ApiResponse(responseCode = "404", description = "존재하지 않는 업장 또는 근무자",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class),
examples = {
@ExampleObject(
name = "존재하지 않는 업장입니다.",
value = "{\"code\" : \"B008\"}"
),
@ExampleObject(
name = "근무자를 찾을 수 없습니다.",
value = "{\"code\" : \"B019\"}"
),
Comment thread
ysw789 marked this conversation as resolved.
})),
@ApiResponse(responseCode = "409", description = "이미 사용 중인 색상",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class),
examples = {
@ExampleObject(
name = "이미 사용 중인 근무자 색상입니다.",
value = "{\"code\" : \"B020\"}"
),
})),
})
ResponseEntity<CommonApiResponse<Void>> updateWorkspaceWorkerColorCode(
@PathVariable Long workspaceId,
@PathVariable Long workerId,
@RequestBody @Valid UpdateWorkspaceWorkerColorRequestDto request
);

// 업장 근무자 상세 정보 조회

// 업장 근무자 상태 변경
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public class ManagerWorkspaceWorkerListResponseDto {
@Schema(description = "직책")
private WorkerPositionResponseDto position;

@NotNull
@Schema(description = "근무자 표시 색상 (hex)", example = "#9CA3AF")
private String colorCode;

@NotNull
@Schema(description = "채용일자", example = "2023-10-01T12:00:00")
private LocalDate employedAt;
Expand All @@ -50,6 +54,7 @@ public static ManagerWorkspaceWorkerListResponseDto of(ManagerWorkspaceWorkerLis
.user(WorkspaceWorkerResponseDto.of(entity.getUser()))
.status(DescribedEnumDto.of(entity.getStatus(), WorkspaceWorkerStatus.describe()))
.position(WorkerPositionResponseDto.from(entity.getPosition()))
.colorCode(entity.getColorCode())
.employedAt(entity.getEmployedAt())
.resignedAt(entity.getResignedAt())
.nextShiftDateTime(entity.getNextShiftDateTime())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.dreamteam.alter.adapter.inbound.manager.workspace.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "매니저 - 근무자 색상 변경 요청 DTO")
public class UpdateWorkspaceWorkerColorRequestDto {

@NotBlank
@Pattern(regexp = "^#[0-9A-Fa-f]{6}$", message = "색상은 #로 시작하는 6자리 16진수여야 합니다.")
@Schema(description = "변경할 색상 (hex)", example = "#93B0A4")
private String colorCode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ public List<ManagerWorkspaceWorkerListResponse> getWorkspaceWorkerListWithCursor
),
qWorkspaceWorker.status,
Expressions.constant(WorkerPositionType.WORKER),
qWorkspaceWorker.colorCode,
qWorkspaceWorker.employedAt,
qWorkspaceWorker.resignedAt,
qWorkspaceWorker.createdAt,
Expand Down Expand Up @@ -205,6 +206,7 @@ public List<ManagerWorkspaceWorkerListResponse> getWorkspaceWorkerListWithCursor
qUser.contact,
qUser.gender,
qWorkspaceWorker.status,
qWorkspaceWorker.colorCode,
qWorkspaceWorker.employedAt,
qWorkspaceWorker.resignedAt,
qWorkspaceWorker.createdAt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,30 @@ public List<UserWorkspaceListResponse> getUserActiveWorkspaceListWithCursor(
}


@Override
public boolean existsActivatedByWorkspaceAndColorCode(Long workspaceId, String colorCode, Long excludeWorkerId) {
QWorkspaceWorker qWorkspaceWorker = QWorkspaceWorker.workspaceWorker;

BooleanExpression excludeCondition = ObjectUtils.isNotEmpty(excludeWorkerId)
? qWorkspaceWorker.id.ne(excludeWorkerId)
: null;

Integer result = queryFactory
.selectOne()
.from(qWorkspaceWorker)
.where(
qWorkspaceWorker.workspace.id.eq(workspaceId),
qWorkspaceWorker.colorCode.eq(colorCode),
qWorkspaceWorker.status.eq(WorkspaceWorkerStatus.ACTIVATED),
excludeCondition
)
.fetchFirst();

return result != null;
}

private BooleanExpression cursorConditions(
QWorkspaceWorker qWorkspaceWorker,
QWorkspaceWorker qWorkspaceWorker,
CursorDto cursor
) {
if (ObjectUtils.isEmpty(cursor)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class ManagerWorkspaceWorkerListResponse {
@Enumerated(EnumType.STRING)
private WorkerPositionType position;

private String colorCode;

private LocalDate employedAt;

private LocalDate resignedAt;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.dreamteam.alter.application.workspace.usecase;

import com.dreamteam.alter.common.exception.CustomException;
import com.dreamteam.alter.common.exception.ErrorCode;
import com.dreamteam.alter.domain.user.context.ManagerActor;
import com.dreamteam.alter.domain.workspace.command.UpdateWorkspaceWorkerColorCommand;
import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker;
import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateWorkspaceWorkerColorCodeUseCase;
import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceQueryRepository;
import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerQueryRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("managerUpdateWorkspaceWorkerColorCode")
@RequiredArgsConstructor
@Transactional
public class ManagerUpdateWorkspaceWorkerColorCode implements ManagerUpdateWorkspaceWorkerColorCodeUseCase {

private final WorkspaceQueryRepository workspaceQueryRepository;
private final WorkspaceWorkerQueryRepository workspaceWorkerQueryRepository;

@Override
public void execute(
ManagerActor actor,
Long workspaceId,
Long workerId,
UpdateWorkspaceWorkerColorCommand command
) {
if (!workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) {
throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND);
}

WorkspaceWorker worker = workspaceWorkerQueryRepository.findById(workerId)
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "근무자를 찾을 수 없습니다"));

if (!worker.getWorkspace().getId().equals(workspaceId)) {
throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND);
}

if (!WorkspaceWorker.DEFAULT_COLOR_CODE.equals(command.getColorCode())
&& workspaceWorkerQueryRepository.existsActivatedByWorkspaceAndColorCode(
workspaceId,
command.getColorCode(),
workerId
)) {
throw new CustomException(ErrorCode.CONFLICT, "이미 사용 중인 근무자 색상입니다.");
}

worker.updateColorCode(command.getColorCode());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.dreamteam.alter.domain.workspace.command;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class UpdateWorkspaceWorkerColorCommand {
Comment thread
ysw789 marked this conversation as resolved.

private String colorCode;

public static UpdateWorkspaceWorkerColorCommand of(String colorCode) {
return UpdateWorkspaceWorkerColorCommand.builder()
.colorCode(colorCode)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
@EntityListeners(AuditingEntityListener.class)
public class WorkspaceWorker {

public static final String DEFAULT_COLOR_CODE = "#9CA3AF";

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand All @@ -36,6 +38,10 @@ public class WorkspaceWorker {
@Column(name = "status", nullable = false)
private WorkspaceWorkerStatus status;

@Builder.Default
@Column(name = "color_code", nullable = false, length = 7)
private String colorCode = DEFAULT_COLOR_CODE;

@Column(name = "employed_at", nullable = false)
private LocalDate employedAt;

Expand Down Expand Up @@ -67,4 +73,8 @@ public void resign() {
this.resignedAt = LocalDate.now();
}

public void updateColorCode(String colorCode) {
this.colorCode = colorCode;
}
Comment thread
ysw789 marked this conversation as resolved.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.dreamteam.alter.domain.workspace.port.inbound;

import com.dreamteam.alter.domain.user.context.ManagerActor;
import com.dreamteam.alter.domain.workspace.command.UpdateWorkspaceWorkerColorCommand;

public interface ManagerUpdateWorkspaceWorkerColorCodeUseCase {
void execute(ManagerActor actor, Long workspaceId, Long workerId, UpdateWorkspaceWorkerColorCommand command);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ public interface WorkspaceWorkerQueryRepository {
Optional<WorkspaceWorker> findById(Long id);
List<WorkspaceWorker> findAllById(List<Long> ids);
List<WorkspaceWorker> findAllActiveByUserId(Long userId);

long getUserActiveWorkspaceCount(User user);

List<UserWorkspaceListResponse> getUserActiveWorkspaceListWithCursor(
CursorPageRequest<CursorDto> request,
CursorPageRequest<CursorDto> request,
User user
);

boolean existsActivatedByWorkspaceAndColorCode(Long workspaceId, String colorCode, Long excludeWorkerId);
}
Loading