Customer.java
package com.deveagles.be15_deveagles_be.features.customers.command.domain.aggregate;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
@Entity
@Table(name = "customer")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "customer_id")
private Long id;
@Column(name = "customer_grade_id", nullable = false)
private Long customerGradeId;
@Column(name = "shop_id", nullable = false)
private Long shopId;
@Column(name = "staff_id", nullable = false)
private Long staffId;
@Column(name = "customer_name", nullable = false, length = 100)
private String customerName;
@Column(name = "phone_number", nullable = false, length = 11)
private String phoneNumber;
@Column(name = "memo", length = 255)
private String memo;
@Builder.Default
@ColumnDefault("0")
@Column(name = "visit_count", nullable = false)
private Integer visitCount = 0;
@Builder.Default
@ColumnDefault("0")
@Column(name = "total_revenue", nullable = false)
private Integer totalRevenue = 0;
@Builder.Default
@ColumnDefault("CURRENT_TIMESTAMP")
@Column(name = "recent_visit_date", nullable = false)
private LocalDate recentVisitDate = LocalDate.now();
@Column(name = "birthdate", nullable = false)
private LocalDate birthdate;
@Builder.Default
@ColumnDefault("0")
@Column(name = "noshow_count", nullable = false)
private Integer noshowCount = 0;
@Enumerated(EnumType.STRING)
@Column(name = "gender", length = 1)
private Gender gender;
@Builder.Default
@Column(name = "marketing_consent", nullable = false)
private Boolean marketingConsent = false;
@Column(name = "marketing_consented_at")
private LocalDateTime marketingConsentedAt;
@Builder.Default
@Column(name = "notification_consent", nullable = false)
private Boolean notificationConsent = false;
@Column(name = "last_message_sent_at")
private LocalDateTime lastMessageSentAt;
@Column(name = "channel_id")
private Long channelId;
@Column(name = "created_at", nullable = false, updatable = false)
@CreationTimestamp
private LocalDateTime createdAt;
@Column(name = "modified_at", nullable = false)
@UpdateTimestamp
private LocalDateTime modifiedAt;
@Column(name = "deleted_at")
private LocalDateTime deletedAt;
// Business methods
public void updateCustomerInfo(
String customerName, String phoneNumber, String memo, Gender gender, Long channelId) {
this.customerName = customerName;
this.phoneNumber = phoneNumber;
this.memo = memo;
this.gender = gender;
this.channelId = channelId;
}
public void updateStaff(Long staffId) {
this.staffId = staffId;
}
public void updateGrade(Long customerGradeId) {
this.customerGradeId = customerGradeId;
}
public void updateBirthdate(LocalDate birthdate) {
this.birthdate = birthdate;
}
public void updateMarketingConsent(Boolean consent) {
this.marketingConsent = consent;
if (consent) {
this.marketingConsentedAt = LocalDateTime.now();
}
}
public void updateNotificationConsent(Boolean consent) {
this.notificationConsent = consent;
}
public void addVisit(Integer revenue) {
this.visitCount++;
this.totalRevenue += revenue;
this.recentVisitDate = LocalDate.now();
}
public void addNoshow() {
this.noshowCount++;
}
public void updateLastMessageSentAt() {
this.lastMessageSentAt = LocalDateTime.now();
}
public void softDelete() {
this.deletedAt = LocalDateTime.now();
}
public boolean isDeleted() {
return this.deletedAt != null;
}
public enum Gender {
M,
F
}
public void incrementVisitCount() {
this.visitCount += 1;
}
public void addRevenue(int amount) {
this.totalRevenue += amount;
}
public void updateRecentVisitDate(LocalDate visitDate) {
this.recentVisitDate = visitDate;
this.modifiedAt = LocalDateTime.now();
}
public void subtractRevenue(int amount) {
this.totalRevenue -= amount;
}
}