Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change entities to be TenantAware #722

Merged
merged 3 commits into from
Jun 21, 2024
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 @@ -10,23 +10,23 @@

interface AbsenceRepository extends CrudRepository<AbsenceWriteEntity, Long> {

Optional<AbsenceWriteEntity> findByTenantIdAndSourceIdAndType_Category(String tenantId, Long sourceId, AbsenceTypeCategory absenceTypeCategory);
Optional<AbsenceWriteEntity> findBySourceIdAndType_Category(Long sourceId, AbsenceTypeCategory absenceTypeCategory);

/**
* Finds all absences of tenantId, userId of set and intersection with interval from and toExclusive-1
* Finds all absences of userId of set and intersection with interval from and toExclusive-1
*/
List<AbsenceWriteEntity> findAllByTenantIdAndUserIdInAndStartDateLessThanAndEndDateGreaterThanEqual(
String tenantId, List<String> userIds, Instant toExclusive, Instant from
List<AbsenceWriteEntity> findAllByUserIdInAndStartDateLessThanAndEndDateGreaterThanEqual(
List<String> userIds, Instant toExclusive, Instant from
);

/**
* Finds all absences of tenantId and intersection with interval from and toExclusive-1
* Finds all absences of intersection with interval from and toExclusive-1
*/
List<AbsenceWriteEntity> findAllByTenantIdAndStartDateLessThanAndEndDateGreaterThanEqual(
String tenantId, Instant toExclusive, Instant from
List<AbsenceWriteEntity> findAllByStartDateLessThanAndEndDateGreaterThanEqual(
Instant toExclusive, Instant from
);

@Modifying
@Transactional
int deleteByTenantIdAndSourceIdAndType_Category(String tenantId, Long sourceId, AbsenceTypeCategory absenceTypeCategory);
int deleteBySourceIdAndType_Category(Long sourceId, AbsenceTypeCategory absenceTypeCategory);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package de.focusshift.zeiterfassung.absence;

import de.focusshift.zeiterfassung.CachedFunction;
import de.focusshift.zeiterfassung.tenancy.tenant.TenantContextHolder;
import de.focusshift.zeiterfassung.tenancy.tenant.TenantId;
import de.focusshift.zeiterfassung.user.UserId;
import de.focusshift.zeiterfassung.user.UserIdComposite;
import de.focusshift.zeiterfassung.user.UserSettingsProvider;
Expand Down Expand Up @@ -46,21 +44,18 @@ class AbsenceServiceImpl implements AbsenceService {
private final AbsenceRepository absenceRepository;
private final AbsenceTypeService absenceTypeService;
private final UserSettingsProvider userSettingsProvider;
private final TenantContextHolder tenantContextHolder;
private final UserManagementService userManagementService;
private final MessageSource messageSource;

AbsenceServiceImpl(AbsenceRepository absenceRepository,
AbsenceTypeService absenceTypeService,
UserSettingsProvider userSettingsProvider,
TenantContextHolder tenantContextHolder,
UserManagementService userManagementService,
MessageSource messageSource) {

this.absenceRepository = absenceRepository;
this.absenceTypeService = absenceTypeService;
this.userSettingsProvider = userSettingsProvider;
this.tenantContextHolder = tenantContextHolder;
this.userManagementService = userManagementService;
this.messageSource = messageSource;
}
Expand All @@ -69,10 +64,9 @@ class AbsenceServiceImpl implements AbsenceService {
public Map<LocalDate, List<Absence>> findAllAbsences(UserId userId, Instant from, Instant toExclusive) {

final ZoneId zoneId = userSettingsProvider.zoneId();
final String tenantId = tenantContextHolder.getCurrentTenantId().orElse(new TenantId("")).tenantId();

final List<AbsenceWriteEntity> absenceEntities =
absenceRepository.findAllByTenantIdAndUserIdInAndStartDateLessThanAndEndDateGreaterThanEqual(tenantId, List.of(userId.value()), toExclusive, from);
absenceRepository.findAllByUserIdInAndStartDateLessThanAndEndDateGreaterThanEqual(List.of(userId.value()), toExclusive, from);

final List<Absence> absences = toAbsences(absenceEntities).toList();

Expand All @@ -96,7 +90,6 @@ public Map<LocalDate, List<Absence>> findAllAbsences(UserId userId, Instant from
public Map<UserIdComposite, List<Absence>> getAbsencesByUserIds(List<UserLocalId> userLocalIds, LocalDate from, LocalDate toExclusive) {

final InstantPeriod period = getInstantPeriod(from, toExclusive);
final String tenantId = tenantContextHolder.getCurrentTenantId().orElse(new TenantId("")).tenantId();

final List<User> users = userManagementService.findAllUsersByLocalIds(userLocalIds);

Expand All @@ -109,7 +102,7 @@ public Map<UserIdComposite, List<Absence>> getAbsencesByUserIds(List<UserLocalId
final Map<UserId, UserIdComposite> idCompositeByUserId = users.stream().collect(toMap(User::userId, User::userIdComposite));

final List<AbsenceWriteEntity> absenceEntities =
absenceRepository.findAllByTenantIdAndUserIdInAndStartDateLessThanAndEndDateGreaterThanEqual(tenantId, userIdValues, period.toExclusive, period.from);
absenceRepository.findAllByUserIdInAndStartDateLessThanAndEndDateGreaterThanEqual(userIdValues, period.toExclusive, period.from);

final Map<UserIdComposite, List<Absence>> result = toAbsences(absenceEntities)
.collect(groupingBy(absence -> idCompositeByUserId.get(absence.userId())));
Expand All @@ -124,10 +117,9 @@ public Map<UserIdComposite, List<Absence>> getAbsencesByUserIds(List<UserLocalId
public Map<UserIdComposite, List<Absence>> getAbsencesForAllUsers(LocalDate from, LocalDate toExclusive) {

final InstantPeriod period = getInstantPeriod(from, toExclusive);
final String tenantId = tenantContextHolder.getCurrentTenantId().orElse(new TenantId("")).tenantId();

final List<AbsenceWriteEntity> absenceEntities =
absenceRepository.findAllByTenantIdAndStartDateLessThanAndEndDateGreaterThanEqual(tenantId, period.toExclusive, period.from);
absenceRepository.findAllByStartDateLessThanAndEndDateGreaterThanEqual(period.toExclusive, period.from);

final Map<UserId, List<Absence>> absenceByUserId = toAbsences(absenceEntities)
.collect(groupingBy(Absence::userId));
Expand All @@ -149,10 +141,8 @@ public Map<UserIdComposite, List<Absence>> getAbsencesForAllUsers(LocalDate from
public List<Absence> getAbsencesByUserId(UserId userId, LocalDate from, LocalDate toExclusive) {

final InstantPeriod period = getInstantPeriod(from, toExclusive);
final String tenantId = tenantContextHolder.getCurrentTenantId().orElse(new TenantId("")).tenantId();

final List<AbsenceWriteEntity> absenceEntities =
absenceRepository.findAllByTenantIdAndUserIdInAndStartDateLessThanAndEndDateGreaterThanEqual(tenantId, List.of(userId.value()), period.toExclusive, period.from);
final List<AbsenceWriteEntity> absenceEntities = absenceRepository.findAllByUserIdInAndStartDateLessThanAndEndDateGreaterThanEqual(List.of(userId.value()), period.toExclusive, period.from);

return toAbsences(absenceEntities).toList();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package de.focusshift.zeiterfassung.absence;

import de.focusshift.zeiterfassung.tenancy.configuration.multi.AdminAware;
import de.focusshift.zeiterfassung.tenancy.tenant.AbstractTenantAwareEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
Expand All @@ -9,7 +9,6 @@
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import jakarta.validation.constraints.Size;

import java.util.Locale;
import java.util.Map;
Expand All @@ -18,11 +17,7 @@
import static jakarta.persistence.EnumType.STRING;

@Entity(name = "absence_type")
public class AbsenceTypeEntity implements AdminAware<Long> {

@Size(max = 255)
@Column(name = "tenant_id")
private String tenantId;
public class AbsenceTypeEntity extends AbstractTenantAwareEntity {

@Id
@Column(name = "id", unique = true, nullable = false, updatable = false)
Expand All @@ -45,15 +40,10 @@ public class AbsenceTypeEntity implements AdminAware<Long> {
@Convert(converter = LabelByLocaleConverter.class)
private Map<Locale, String> labelByLocale;

public String getTenantId() {
return tenantId;
}

public void setTenantId(String tenantId) {
this.tenantId = tenantId;
public AbsenceTypeEntity() {
super(null);
}

@Override
public Long getId() {
return id;
}
Expand Down Expand Up @@ -110,7 +100,6 @@ public int hashCode() {
@Override
public String toString() {
return "AbsenceTypeEntity{" +
"tenantId='" + tenantId + '\'' +
", id=" + id +
", category=" + category +
", sourceId=" + sourceId +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
import jakarta.persistence.Embeddable;
import jakarta.persistence.Enumerated;

import java.io.Serial;
import java.io.Serializable;
import java.util.Objects;

import static jakarta.persistence.EnumType.STRING;

@Embeddable
public class AbsenceTypeEntityEmbeddable {
public class AbsenceTypeEntityEmbeddable implements Serializable {

@Serial
private static final long serialVersionUID = -393457998708034020L;

@Column(name = "type_category", nullable = false)
@Enumerated(STRING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

interface AbsenceTypeRepository extends CrudRepository<AbsenceTypeEntity, Long> {

Optional<AbsenceTypeEntity> findByTenantIdAndSourceId(String tenantId, Long sourceId);
Optional<AbsenceTypeEntity> findBySourceId(Long sourceId);

List<AbsenceTypeEntity> findByTenantIdAndSourceIdIsIn(String tenantId, Collection<Long> sourceIds);
List<AbsenceTypeEntity> findBySourceIdIsIn(Collection<Long> sourceIds);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package de.focusshift.zeiterfassung.absence;

import de.focusshift.zeiterfassung.tenancy.tenant.TenantContextHolder;
import org.springframework.stereotype.Service;

import java.util.Collection;
Expand All @@ -11,23 +10,19 @@
class AbsenceTypeServiceImpl implements AbsenceTypeService {

private final AbsenceTypeRepository repository;
private final TenantContextHolder tenantContextHolder;

AbsenceTypeServiceImpl(AbsenceTypeRepository repository, TenantContextHolder tenantContextHolder) {
AbsenceTypeServiceImpl(AbsenceTypeRepository repository) {
this.repository = repository;
this.tenantContextHolder = tenantContextHolder;
}

@Override
public void updateAbsenceType(AbsenceTypeUpdate absenceTypeUpdate) {

final String tenantId = absenceTypeUpdate.tenantId().tenantId();
final Long sourceId = absenceTypeUpdate.sourceId();

final AbsenceTypeEntity entity = repository.findByTenantIdAndSourceId(tenantId, sourceId)
final AbsenceTypeEntity entity = repository.findBySourceId(sourceId)
.orElseGet(AbsenceTypeEntity::new);

entity.setTenantId(tenantId);
entity.setSourceId(sourceId);
entity.setCategory(absenceTypeUpdate.category());
entity.setColor(absenceTypeUpdate.color());
Expand All @@ -38,17 +33,11 @@ public void updateAbsenceType(AbsenceTypeUpdate absenceTypeUpdate) {

@Override
public List<AbsenceType> findAllByAbsenceTypeSourceIds(Collection<Long> absenceTypeSourceIds) {
return repository.findByTenantIdAndSourceIdIsIn(tenantId(), absenceTypeSourceIds).stream()
return repository.findBySourceIdIsIn(absenceTypeSourceIds).stream()
.map(AbsenceTypeServiceImpl::toAbsenceType)
.toList();
}

private String tenantId() {
return tenantContextHolder.getCurrentTenantId()
.orElseThrow(() -> new IllegalStateException("expected tenantId to exist."))
.tenantId();
}

private static AbsenceType toAbsenceType(AbsenceTypeEntity entity) {
return new AbsenceType(
entity.getCategory(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package de.focusshift.zeiterfassung.absence;

import de.focusshift.zeiterfassung.tenancy.tenant.TenantId;

import java.util.Locale;
import java.util.Map;

/**
* Update {@linkplain AbsenceType} to the given values.
*
* @param tenantId {@linkplain TenantId} this {@linkplain AbsenceType} is linked to
* @param sourceId external system source identifier of the absence type
* @param category next {@linkplain AbsenceTypeCategory}
* @param color next {@linkplain AbsenceColor}
* @param labelByLocale next labels
*/
public record AbsenceTypeUpdate(
TenantId tenantId,
Long sourceId,
AbsenceTypeCategory category,
AbsenceColor color,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package de.focusshift.zeiterfassung.absence;

import de.focusshift.zeiterfassung.tenancy.tenant.TenantId;
import de.focusshift.zeiterfassung.user.UserId;
import jakarta.annotation.Nullable;

Expand All @@ -9,7 +8,6 @@
/**
* Describes the write model of an absence like holiday or sick.
*
* @param tenantId
* @param sourceId
* @param userId
* @param startDate
Expand All @@ -19,7 +17,6 @@
* @param absenceTypeSourceId absence type source id or {@code null} for {@linkplain AbsenceTypeCategory#SICK}
*/
public record AbsenceWrite(
TenantId tenantId,
Long sourceId,
UserId userId,
Instant startDate,
Expand All @@ -32,15 +29,14 @@ public record AbsenceWrite(
/**
* constructor for absences without a absenceType sourceId (e.g. {@linkplain AbsenceTypeCategory#SICK}).
*
* @param tenantId
* @param sourceId
* @param userId
* @param startDate
* @param endDate
* @param dayLength
* @param absenceTypeCategory
*/
public AbsenceWrite(TenantId tenantId, Long sourceId, UserId userId, Instant startDate, Instant endDate, DayLength dayLength, AbsenceTypeCategory absenceTypeCategory) {
this(tenantId, sourceId, userId, startDate, endDate, dayLength, absenceTypeCategory, null);
public AbsenceWrite(Long sourceId, UserId userId, Instant startDate, Instant endDate, DayLength dayLength, AbsenceTypeCategory absenceTypeCategory) {
this(sourceId, userId, startDate, endDate, dayLength, absenceTypeCategory, null);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package de.focusshift.zeiterfassung.absence;

import de.focusshift.zeiterfassung.tenancy.configuration.multi.AdminAware;
import de.focusshift.zeiterfassung.tenancy.tenant.AbstractTenantAwareEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
Expand All @@ -10,7 +10,6 @@
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Size;

import java.time.Instant;
import java.util.Objects;
Expand All @@ -19,11 +18,7 @@

@Entity
@Table(name = "absence")
public class AbsenceWriteEntity implements AdminAware<Long> {

@Size(max = 255)
@Column(name = "tenant_id")
private String tenantId;
public class AbsenceWriteEntity extends AbstractTenantAwareEntity {

@Id
@Column(name = "id", unique = true, nullable = false, updatable = false)
Expand All @@ -50,12 +45,8 @@ public class AbsenceWriteEntity implements AdminAware<Long> {
@Embedded
private AbsenceTypeEntityEmbeddable type;

public String getTenantId() {
return tenantId;
}

public void setTenantId(String tenantId) {
this.tenantId = tenantId;
public AbsenceWriteEntity() {
super(null);
}

public Long getId() {
Expand Down Expand Up @@ -130,7 +121,6 @@ public int hashCode() {
@Override
public String toString() {
return "AbsenceEntity{" +
"tenantId=" + tenantId +
", id=" + id +
'}';
}
Expand Down
Loading