package com.dora.mapper;

import com.dora.entity.Order;
import org.apache.ibatis.annotations.*;


import java.time.LocalDateTime;
import java.util.List;

/**
 * 订单Mapper接口
 */
@Mapper
public interface OrderMapper {

    /**
     * 插入订单（支持会员订单和积分订单）
     * @param order 订单实体
     * @return 影响行数
     */
    int insertOrder(Order order);
    
    /**
     * 插入订单（旧方法，保持兼容性）
     * @param order 订单实体
     * @return 影响行数
     */
    @Insert("INSERT INTO `order` (order_no, user_id, plan_id, original_price, amount, actual_duration_days, " +
            "discount_type, discount_amount, discount_description, status, payment_method, " +
            "create_time, update_time, is_deleted) VALUES " +
            "(#{orderNo}, #{userId}, #{planId}, #{originalPrice}, #{amount}, #{actualDurationDays}, " +
            "#{discountType}, #{discountAmount}, #{discountDescription}, #{status}, #{paymentMethod}, " +
            "#{createTime}, #{updateTime}, #{isDeleted})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(Order order);

    /**
     * 根据订单号查询订单
     * @param orderNo 订单号
     * @return 订单实体
     */
    @Select("SELECT * FROM `order` WHERE order_no = #{orderNo} AND is_deleted = 0")
    Order selectByOrderNo(@Param("orderNo") String orderNo);

    /**
     * 根据订单ID查询订单
     * @param orderId 订单ID
     * @return 订单实体
     */
    @Select("SELECT * FROM `order` WHERE id = #{orderId} AND is_deleted = 0")
    Order selectById(@Param("orderId") Long orderId);

    /**
     * 更新订单状态和支付信息
     * @param orderNo 订单号
     * @param status 订单状态
     * @param paymentMethod 支付方式
     * @param paidAt 支付时间
     * @return 影响行数
     */
    @Update("UPDATE `order` SET status = #{status}, payment_method = #{paymentMethod}, " +
            "paid_at = #{paidAt}, update_time = NOW() " +
            "WHERE order_no = #{orderNo} AND is_deleted = 0")
    int updateOrderStatus(@Param("orderNo") String orderNo, 
                         @Param("status") Integer status,
                         @Param("paymentMethod") Integer paymentMethod,
                         @Param("paidAt") LocalDateTime paidAt);

    /**
     * 根据用户ID获取订单列表（包含套餐信息）
     * @param userId 用户ID
     * @param offset 偏移量
     * @param size 每页大小
     * @return 订单列表（包含套餐信息）
     */
    @Select("SELECT o.id, o.order_no, o.user_id, o.plan_id, o.original_price, o.amount, o.actual_duration_days, " +
            "o.discount_type, o.discount_amount, o.discount_description, o.status, " +
            "o.payment_method, o.paid_at, o.create_time, o.update_time, " +
            "mp.name as plan_name, mp.description as plan_description, mp.price as plan_price, " +
            "mp.duration_days, mp.target_role " +
            "FROM `order` o " +
            "LEFT JOIN membership_plan mp ON o.plan_id = mp.id " +
            "WHERE o.user_id = #{userId} AND o.is_deleted = 0 " +
            "ORDER BY o.create_time DESC LIMIT #{offset}, #{size}")
    List<OrderWithPlanInfo> selectByUserIdWithPlanInfo(@Param("userId") Long userId, @Param("offset") int offset, @Param("size") int size);

    /**
     * 根据用户ID统计订单数量
     * @param userId 用户ID
     * @return 订单数量
     */
    @Select("SELECT COUNT(*) FROM `order` WHERE user_id = #{userId} AND is_deleted = 0")
    int countByUserId(@Param("userId") Long userId);

    /**
     * 统计用户成功支付的订单数量
     * @param userId 用户ID
     * @return 成功支付的订单数量
     */
    @Select("SELECT COUNT(*) FROM `order` WHERE user_id = #{userId} AND status = 1 AND is_deleted = 0")
    int countSuccessOrdersByUserId(@Param("userId") Long userId);

    /**
     * 根据订单ID获取订单详情（包含套餐信息）
     * @param orderId 订单ID
     * @param userId 用户ID（用于权限验证）
     * @return 订单详情（包含套餐信息）
     */
    @Select("SELECT o.id, o.order_no, o.user_id, o.plan_id, o.original_price, o.amount, o.actual_duration_days, " +
            "o.discount_type, o.discount_amount, o.discount_description, o.status, " +
            "o.payment_method, o.paid_at, o.create_time, o.update_time, " +
            "mp.name as plan_name, mp.description as plan_description, mp.price as plan_price, " +
            "mp.duration_days, mp.target_role " +
            "FROM `order` o " +
            "LEFT JOIN membership_plan mp ON o.plan_id = mp.id " +
            "WHERE o.id = #{orderId} AND o.user_id = #{userId} AND o.is_deleted = 0")
    OrderWithPlanInfo selectByIdWithPlanInfo(@Param("orderId") Long orderId, @Param("userId") Long userId);

    /**
     * 查询所有订单（管理员用）
     * @return 订单列表
     */
    @Select("SELECT * FROM `order` WHERE is_deleted = 0 ORDER BY create_time DESC")
    List<Order> selectAllOrders();

    /**
     * 管理员分页查询订单列表（支持条件筛选）
     * @param status 订单状态
     * @param orderType 订单类型
     * @param keyword 搜索关键词
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param sortField 排序字段
     * @param sortOrder 排序方向
     * @param offset 偏移量
     * @param size 每页大小
     * @return 订单列表（包含用户和套餐信息）
     */
    @Select("<script>" +
            "SELECT o.id, o.order_no, o.user_id, o.plan_id, o.original_price, o.amount, " +
            "o.actual_duration_days, o.discount_type, o.discount_amount, o.discount_description, " +
            "o.status, o.payment_method, o.paid_at, o.create_time, o.update_time, " +
            "u.username, u.phone, u.role, " +
            "mp.name as plan_name, mp.description as plan_description, mp.price as plan_price, " +
            "mp.duration_days, mp.target_role " +
            "FROM `order` o " +
            "LEFT JOIN user u ON o.user_id = u.id " +
            "LEFT JOIN membership_plan mp ON o.plan_id = mp.id " +
            "WHERE o.is_deleted = 0 " +
            "<if test='status != null'> AND o.status = #{status} </if>" +
            "<if test='orderType != null and orderType != \"\"'> AND mp.name LIKE CONCAT('%', #{orderType}, '%') </if>" +
            "<if test='keyword != null and keyword != \"\"'> " +
            "AND (o.order_no LIKE CONCAT('%', #{keyword}, '%') " +
            "OR u.username LIKE CONCAT('%', #{keyword}, '%') " +
            "OR u.phone LIKE CONCAT('%', #{keyword}, '%')) " +
            "</if>" +
            "<if test='startDate != null and startDate != \"\"'> AND DATE(o.create_time) &gt;= #{startDate} </if>" +
            "<if test='endDate != null and endDate != \"\"'> AND DATE(o.create_time) &lt;= #{endDate} </if>" +
            "ORDER BY " +
            "<choose>" +
            "<when test='sortField != null and sortField == \"amount\"'>o.amount</when>" +
            "<when test='sortField != null and sortField == \"status\"'>o.status</when>" +
            "<when test='sortField != null and sortField == \"paid_at\"'>o.paid_at</when>" +
            "<when test='sortField != null and sortField == \"username\"'>u.username</when>" +
            "<otherwise>o.create_time</otherwise>" +
            "</choose> " +
            "<if test='sortOrder != null and sortOrder == \"asc\"'>ASC</if>" +
            "<if test='sortOrder == null or sortOrder != \"asc\"'>DESC</if> " +
            "LIMIT #{offset}, #{size}" +
            "</script>")
    List<AdminOrderInfo> selectAdminOrderList(@Param("status") Integer status,
                                             @Param("orderType") String orderType,
                                             @Param("keyword") String keyword,
                                             @Param("startDate") String startDate,
                                             @Param("endDate") String endDate,
                                             @Param("sortField") String sortField,
                                             @Param("sortOrder") String sortOrder,
                                             @Param("offset") int offset,
                                             @Param("size") int size);

    /**
     * 管理员查询订单总数（支持条件筛选）
     * @param status 订单状态
     * @param orderType 订单类型
     * @param keyword 搜索关键词
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 总数量
     */
    @Select("<script>" +
            "SELECT COUNT(*) FROM `order` o " +
            "LEFT JOIN user u ON o.user_id = u.id " +
            "LEFT JOIN membership_plan mp ON o.plan_id = mp.id " +
            "WHERE o.is_deleted = 0 " +
            "<if test='status != null'> AND o.status = #{status} </if>" +
            "<if test='orderType != null and orderType != \"\"'> AND mp.name LIKE CONCAT('%', #{orderType}, '%') </if>" +
            "<if test='keyword != null and keyword != \"\"'> " +
            "AND (o.order_no LIKE CONCAT('%', #{keyword}, '%') " +
            "OR u.username LIKE CONCAT('%', #{keyword}, '%') " +
            "OR u.phone LIKE CONCAT('%', #{keyword}, '%')) " +
            "</if>" +
            "<if test='startDate != null and startDate != \"\"'> AND DATE(o.create_time) &gt;= #{startDate} </if>" +
            "<if test='endDate != null and endDate != \"\"'> AND DATE(o.create_time) &lt;= #{endDate} </if>" +
            "</script>")
    Long countAdminOrderList(@Param("status") Integer status,
                            @Param("orderType") String orderType,
                            @Param("keyword") String keyword,
                            @Param("startDate") String startDate,
                            @Param("endDate") String endDate);

    /**
     * 根据ID更新订单
     * @param order 订单实体
     * @return 影响行数
     */
    @Update("UPDATE `order` SET status = #{status}, payment_method = #{paymentMethod}, " +
            "paid_at = #{paidAt}, update_time = #{updateTime} " +
            "WHERE id = #{id} AND is_deleted = 0")
    int updateById(Order order);

    /**
     * 统计总收入（已支付订单）
     * @return 总收入
     */
    @Select("SELECT COALESCE(SUM(amount), 0) FROM `order` WHERE status = 1 AND is_deleted = 0")
    java.math.BigDecimal getTotalRevenue();

    /**
     * 统计总订单数
     * @return 总订单数
     */
    @Select("SELECT COUNT(*) FROM `order` WHERE is_deleted = 0")
    Long getTotalOrders();

    /**
     * 统计指定时间范围内的收入
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 收入金额
     */
    @Select("SELECT COALESCE(SUM(amount), 0) FROM `order` " +
            "WHERE status = 1 AND is_deleted = 0 " +
            "AND paid_at >= #{startTime} AND paid_at < #{endTime}")
    java.math.BigDecimal getRevenueByDateRange(@Param("startTime") LocalDateTime startTime, 
                                               @Param("endTime") LocalDateTime endTime);

    /**
     * 统计指定时间范围内的订单数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 订单数量
     */
    @Select("SELECT COUNT(*) FROM `order` " +
            "WHERE status = 1 AND is_deleted = 0 " +
            "AND paid_at >= #{startTime} AND paid_at < #{endTime}")
    Long getOrderCountByDateRange(@Param("startTime") LocalDateTime startTime, 
                                  @Param("endTime") LocalDateTime endTime);

    /**
     * 统计指定时间范围内新增VIP用户数（角色2）
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return VIP用户数
     */
    @Select("SELECT COUNT(DISTINCT o.user_id) FROM `order` o " +
            "LEFT JOIN membership_plan mp ON o.plan_id = mp.id " +
            "WHERE o.status = 1 AND o.is_deleted = 0 " +
            "AND mp.target_role = 2 " +
            "AND o.paid_at >= #{startTime} AND o.paid_at < #{endTime}")
    Long getNewVipUsersByDateRange(@Param("startTime") LocalDateTime startTime, 
                                   @Param("endTime") LocalDateTime endTime);

    /**
     * 统计指定时间范围内新增SVIP用户数（角色3）
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return SVIP用户数
     */
    @Select("SELECT COUNT(DISTINCT o.user_id) FROM `order` o " +
            "LEFT JOIN membership_plan mp ON o.plan_id = mp.id " +
            "WHERE o.status = 1 AND o.is_deleted = 0 " +
            "AND mp.target_role = 3 " +
            "AND o.paid_at >= #{startTime} AND o.paid_at < #{endTime}")
    Long getNewSvipUsersByDateRange(@Param("startTime") LocalDateTime startTime, 
                                    @Param("endTime") LocalDateTime endTime);

    /**
     * 统计失败订单数量
     * @return 失败订单数
     */
    @Select("SELECT COUNT(*) FROM `order` WHERE status IN (2, 3) AND is_deleted = 0")
    Long getFailedOrderCount();

    /**
     * 统计退款订单数量和金额
     * @return 退款订单数
     */
    @Select("SELECT COUNT(*) FROM `order` WHERE status = 2 AND is_deleted = 0")
    Long getRefundOrderCount();

    @Select("SELECT COALESCE(SUM(amount), 0) FROM `order` WHERE status = 2 AND is_deleted = 0")
    java.math.BigDecimal getRefundAmount();

    /**
     * 按日期范围统计每日交易数据
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 每日统计列表
     */
    @Select("SELECT DATE(paid_at) as date, " +
            "COUNT(*) as count, " +
            "COALESCE(SUM(amount), 0) as amount, " +
            "COUNT(DISTINCT user_id) as new_users " +
            "FROM `order` " +
            "WHERE status = 1 AND is_deleted = 0 " +
            "AND DATE(paid_at) >= #{startDate} AND DATE(paid_at) <= #{endDate} " +
            "GROUP BY DATE(paid_at) " +
            "ORDER BY DATE(paid_at)")
    List<java.util.Map<String, Object>> getDailyTransactionStats(@Param("startDate") String startDate, 
                                                                  @Param("endDate") String endDate);

    /**
     * 统计指定套餐的购买次数
     * @param planId 套餐ID
     * @return 购买次数
     */
    @Select("SELECT COUNT(*) FROM `order` WHERE plan_id = #{planId} AND status = 1 AND is_deleted = 0")
    Long getPlanPurchaseCount(@Param("planId") Long planId);

    /**
     * 统计指定套餐的总收入
     * @param planId 套餐ID
     * @return 总收入
     */
    @Select("SELECT COALESCE(SUM(amount), 0) FROM `order` WHERE plan_id = #{planId} AND status = 1 AND is_deleted = 0")
    java.math.BigDecimal getPlanTotalRevenue(@Param("planId") Long planId);

    /**
     * 统计指定套餐指定时间范围内的购买次数
     * @param planId 套餐ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 购买次数
     */
    @Select("SELECT COUNT(*) FROM `order` " +
            "WHERE plan_id = #{planId} AND status = 1 AND is_deleted = 0 " +
            "AND paid_at >= #{startTime} AND paid_at < #{endTime}")
    Long getPlanPurchaseCountByDateRange(@Param("planId") Long planId,
                                        @Param("startTime") LocalDateTime startTime,
                                        @Param("endTime") LocalDateTime endTime);

    /**
     * 统计指定套餐指定时间范围内的收入
     * @param planId 套餐ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 收入金额
     */
    @Select("SELECT COALESCE(SUM(amount), 0) FROM `order` " +
            "WHERE plan_id = #{planId} AND status = 1 AND is_deleted = 0 " +
            "AND paid_at >= #{startTime} AND paid_at < #{endTime}")
    java.math.BigDecimal getPlanRevenueByDateRange(@Param("planId") Long planId,
                                                  @Param("startTime") LocalDateTime startTime,
                                                  @Param("endTime") LocalDateTime endTime);

    // ==================== 积分订单查询方法 ====================

    /**
     * 查询用户的积分订单列表
     * @param userId 用户ID
     * @param offset 偏移量
     * @param size 每页大小
     * @return 订单列表
     */
    List<Order> selectPointsOrdersByUserId(@Param("userId") Long userId, 
                                          @Param("offset") int offset, 
                                          @Param("size") int size);

    /**
     * 统计用户积分订单数量
     * @param userId 用户ID
     * @param status 订单状态（可选）
     * @return 订单数量
     */
    Long countPointsOrdersByUserId(@Param("userId") Long userId, @Param("status") Integer status);

    /**
     * 统计用户积分订单总金额
     * @param userId 用户ID
     * @param status 订单状态（可选）
     * @return 总金额
     */
    java.math.BigDecimal sumPointsOrdersAmountByUserId(@Param("userId") Long userId, @Param("status") Integer status);

    /**
     * 统计用户积分订单总积分
     * @param userId 用户ID
     * @param status 订单状态（可选）
     * @return 总积分
     */
    Long sumPointsOrdersPointsByUserId(@Param("userId") Long userId, @Param("status") Integer status);

    /**
     * 查询用户最后一笔积分订单
     * @param userId 用户ID
     * @param status 订单状态（可选）
     * @return 订单
     */
    Order selectLastPointsOrderByUserId(@Param("userId") Long userId, @Param("status") Integer status);

    /**
     * 订单记录（包含套餐信息）
     */
    class OrderWithPlanInfo {
        private Long id;
        private String orderNo;
        private Long userId;
        private Long planId;
        private java.math.BigDecimal originalPrice;
        private java.math.BigDecimal amount;
        private Integer actualDurationDays;
        private String discountType;
        private java.math.BigDecimal discountAmount;
        private String discountDescription;
        private Integer status;
        private Integer paymentMethod;
        private java.time.LocalDateTime paidAt;
        private java.time.LocalDateTime createTime;
        private java.time.LocalDateTime updateTime;
        private String planName;
        private String planDescription;
        private java.math.BigDecimal planPrice;
        private Integer durationDays;
        private Integer targetRole;

        // Getters and Setters
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        
        public String getOrderNo() { return orderNo; }
        public void setOrderNo(String orderNo) { this.orderNo = orderNo; }
        
        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        
        public Long getPlanId() { return planId; }
        public void setPlanId(Long planId) { this.planId = planId; }
        
        public java.math.BigDecimal getOriginalPrice() { return originalPrice; }
        public void setOriginalPrice(java.math.BigDecimal originalPrice) { this.originalPrice = originalPrice; }
        
        public java.math.BigDecimal getAmount() { return amount; }
        public void setAmount(java.math.BigDecimal amount) { this.amount = amount; }
        
        public Integer getActualDurationDays() { return actualDurationDays; }
        public void setActualDurationDays(Integer actualDurationDays) { this.actualDurationDays = actualDurationDays; }
        
        public String getDiscountType() { return discountType; }
        public void setDiscountType(String discountType) { this.discountType = discountType; }
        
        public java.math.BigDecimal getDiscountAmount() { return discountAmount; }
        public void setDiscountAmount(java.math.BigDecimal discountAmount) { this.discountAmount = discountAmount; }
        
        public String getDiscountDescription() { return discountDescription; }
        public void setDiscountDescription(String discountDescription) { this.discountDescription = discountDescription; }
        
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
        
        public Integer getPaymentMethod() { return paymentMethod; }
        public void setPaymentMethod(Integer paymentMethod) { this.paymentMethod = paymentMethod; }
        
        public java.time.LocalDateTime getPaidAt() { return paidAt; }
        public void setPaidAt(java.time.LocalDateTime paidAt) { this.paidAt = paidAt; }
        
        public java.time.LocalDateTime getCreateTime() { return createTime; }
        public void setCreateTime(java.time.LocalDateTime createTime) { this.createTime = createTime; }
        
        public java.time.LocalDateTime getUpdateTime() { return updateTime; }
        public void setUpdateTime(java.time.LocalDateTime updateTime) { this.updateTime = updateTime; }
        
        public String getPlanName() { return planName; }
        public void setPlanName(String planName) { this.planName = planName; }
        
        public String getPlanDescription() { return planDescription; }
        public void setPlanDescription(String planDescription) { this.planDescription = planDescription; }
        
        public java.math.BigDecimal getPlanPrice() { return planPrice; }
        public void setPlanPrice(java.math.BigDecimal planPrice) { this.planPrice = planPrice; }
        
        public Integer getDurationDays() { return durationDays; }
        public void setDurationDays(Integer durationDays) { this.durationDays = durationDays; }
        
        public Integer getTargetRole() { return targetRole; }
        public void setTargetRole(Integer targetRole) { this.targetRole = targetRole; }
    }

    /**
     * 管理员订单信息（包含用户和套餐信息）
     */
    class AdminOrderInfo {
        private Long id;
        private String orderNo;
        private Long userId;
        private Long planId;
        private java.math.BigDecimal originalPrice;
        private java.math.BigDecimal amount;
        private Integer actualDurationDays;
        private String discountType;
        private java.math.BigDecimal discountAmount;
        private String discountDescription;
        private Integer status;
        private Integer paymentMethod;
        private java.time.LocalDateTime paidAt;
        private java.time.LocalDateTime createTime;
        private java.time.LocalDateTime updateTime;
        
        // 用户信息
        private String username;
        private String phone;
        private Integer role;
        
        // 套餐信息
        private String planName;
        private String planDescription;
        private java.math.BigDecimal planPrice;
        private Integer durationDays;
        private Integer targetRole;

        // Getters and Setters
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        
        public String getOrderNo() { return orderNo; }
        public void setOrderNo(String orderNo) { this.orderNo = orderNo; }
        
        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        
        public Long getPlanId() { return planId; }
        public void setPlanId(Long planId) { this.planId = planId; }
        
        public java.math.BigDecimal getOriginalPrice() { return originalPrice; }
        public void setOriginalPrice(java.math.BigDecimal originalPrice) { this.originalPrice = originalPrice; }
        
        public java.math.BigDecimal getAmount() { return amount; }
        public void setAmount(java.math.BigDecimal amount) { this.amount = amount; }
        
        public Integer getActualDurationDays() { return actualDurationDays; }
        public void setActualDurationDays(Integer actualDurationDays) { this.actualDurationDays = actualDurationDays; }
        
        public String getDiscountType() { return discountType; }
        public void setDiscountType(String discountType) { this.discountType = discountType; }
        
        public java.math.BigDecimal getDiscountAmount() { return discountAmount; }
        public void setDiscountAmount(java.math.BigDecimal discountAmount) { this.discountAmount = discountAmount; }
        
        public String getDiscountDescription() { return discountDescription; }
        public void setDiscountDescription(String discountDescription) { this.discountDescription = discountDescription; }
        
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
        
        public Integer getPaymentMethod() { return paymentMethod; }
        public void setPaymentMethod(Integer paymentMethod) { this.paymentMethod = paymentMethod; }
        
        public java.time.LocalDateTime getPaidAt() { return paidAt; }
        public void setPaidAt(java.time.LocalDateTime paidAt) { this.paidAt = paidAt; }
        
        public java.time.LocalDateTime getCreateTime() { return createTime; }
        public void setCreateTime(java.time.LocalDateTime createTime) { this.createTime = createTime; }
        
        public java.time.LocalDateTime getUpdateTime() { return updateTime; }
        public void setUpdateTime(java.time.LocalDateTime updateTime) { this.updateTime = updateTime; }
        
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        
        public Integer getRole() { return role; }
        public void setRole(Integer role) { this.role = role; }
        
        public String getPlanName() { return planName; }
        public void setPlanName(String planName) { this.planName = planName; }
        
        public String getPlanDescription() { return planDescription; }
        public void setPlanDescription(String planDescription) { this.planDescription = planDescription; }
        
        public java.math.BigDecimal getPlanPrice() { return planPrice; }
        public void setPlanPrice(java.math.BigDecimal planPrice) { this.planPrice = planPrice; }
        
        public Integer getDurationDays() { return durationDays; }
        public void setDurationDays(Integer durationDays) { this.durationDays = durationDays; }
        
        public Integer getTargetRole() { return targetRole; }
        public void setTargetRole(Integer targetRole) { this.targetRole = targetRole; }
    }
} 