package jp.agentec.sinaburocast.service; import java.util.List; import java.util.Map; import jp.agentec.sinaburocast.common.SinaburoConstant; import jp.agentec.sinaburocast.common.util.SinaburoUtil; import jp.agentec.sinaburocast.dto.PointRecoveryDto; import jp.agentec.sinaburocast.entity.Gift; import jp.agentec.sinaburocast.entity.GiftExchange; import jp.agentec.sinaburocast.entity.Member; import jp.agentec.sinaburocast.entity.PointGet; import org.seasar.extension.jdbc.where.SimpleWhere; import org.seasar.framework.beans.util.BeanMap; import org.seasar.framework.container.annotation.tiger.Component; import org.seasar.framework.container.annotation.tiger.InstanceType; @Component(instance = InstanceType.SINGLETON) public class PointGetService extends AbstractService<PointGet> { private static final String ID_SEQ_NAME = "point_get_id_seq"; public MemberService memberService; public GiftExchangeService giftExchangeService; public PointPeriodService pointPeriodService; /** * IDを発行して、登録する。 */ public int insertPointGet(PointGet pointGet, String insId) { pointGet.pointGetId = getSeqNextVal(Integer.class, ID_SEQ_NAME); return super.insert(pointGet, insId); } public PointGet findById(Integer pointGetId) { return select().id(pointGetId).getSingleResult(); } public PointGet findBymemberId(Integer memberId) { return select().where(new SimpleWhere().eq("memberId", memberId)).getSingleResult(); } public List<PointGet> findBymemberIdList(Integer memberId) { return select().where(new SimpleWhere().eq("memberId", memberId)).getResultList(); } public List<PointGet> findAllOrderById() { return select().orderBy("pointGetId asc").getResultList(); } /** * ・ポイント取得履歴更新 ポイント交換申請による、消費ポイント数を増加する。 * 更新するレコードは複数、対象カラムは「pointUseNum,validFlg」 ・ポイント交換申請の登録 ・会員情報テーブルの有効ポイント数更新 * * @param gift * @param member * @return */ public void cutDownPointLogic(Gift gift, Member member) { // 有効なレコードを取得順に取得 List<PointGet> pointGetList = select().where(new SimpleWhere() .eq("memberId", member.memberId) .eq("validFlg",SinaburoConstant.ValidFlg.VALID)) .orderBy("pointGetDate") .getResultList(); int requiredPoint = gift.requiredPoint; // 各レコードごとに使えるポイント int validPoint = 0; // 消費ポイント int usePoint = 0; // 残ポイント int restPoint = 0; // ■ポイント取得履歴の更新 for (int i = 0; i < pointGetList.size(); i++) { PointGet pointGet = pointGetList.get(i); if (requiredPoint == 0) { // 会員情報テーブル残ポイントを取得する。ここから取得するレコードはpointUseNumが0であるはず。 restPoint += pointGet.pointGetNum - pointGet.pointUseNum; continue; } // 各レコードの使えるポイント // validPointは0以上pointGet.pointGetNum以下 validPoint = pointGet.pointGetNum - pointGet.pointUseNum; // 消費ポイントが0になるまで usePoint = Math.min(validPoint, requiredPoint); requiredPoint = requiredPoint - usePoint; pointGet.pointUseNum += usePoint; // レコードが消費完了していたら。INVALIDにする。 if (pointGet.pointGetNum - pointGet.pointUseNum == 0) { pointGet.validFlg = SinaburoConstant.ValidFlg.INVALID; } else { restPoint = pointGet.pointGetNum - pointGet.pointUseNum; } // 対象レコードを更新 update(pointGet, member.loginId); } // ■ポイント交換申請の登録 GiftExchange giftExchange = new GiftExchange(); giftExchange.memberId = member.memberId; giftExchange.giftId = gift.giftId; giftExchange.cnt = gift.requiredPoint / SinaburoConstant.ECHOBO_MAI_POINT.MAI1; giftExchange.applyDate = SinaburoUtil.getTimestamp(); giftExchangeService.insertGiftExchange(giftExchange, member.loginId); // ■メンバー情報を更新する。 member.pointNum = restPoint; memberService.update(member, member.loginId); } public Map<String, Integer> findPointByMemberId(Integer memberId, String startDay, String endDay) { String sql = "select sum( case WHEN substr(point_get_date, 1, 6) <= ? then point_get_num - point_use_num else 0 end ) as point1," + "sum( case WHEN substr(point_get_date, 1, 6) between ? and ? then point_get_num - point_use_num else 0 end ) as point2 " + "from t_point_get where member_id = ? and valid_flg = 1 "; @SuppressWarnings("unchecked") Map<String, Integer> cnt = jdbcManager.selectBySql(Map.class, sql, startDay,endDay, endDay, memberId).getSingleResult(); return cnt; } public String findPointByMemberIdAdmin(Integer memberId) { String sql = "select sum(point_get_num - point_use_num) as point " + "from t_point_get where member_id = ? and valid_flg = 1 "; @SuppressWarnings("unchecked") Map<String, Long> cnt = jdbcManager.selectBySql(Map.class, sql, memberId).getSingleResult(); if (cnt.get("point") == null) { return "0"; } else { return (String) cnt.get("point").toString(); } } public Integer findPointSumByMemberId(Integer memberId) { String sql = "select sum(point_get_num - point_use_num) as point " + "from t_point_get where member_id = ? and valid_flg = 1 "; Integer pointSum = jdbcManager.selectBySql(Integer.class, sql,memberId).getSingleResult(); if (pointSum == null) { return 0; } else { return pointSum; } } /** * ・ポイント取得履歴更新 ポイント交換申請による、消費ポイント数を増加する。 * 更新するレコードは複数、対象カラムは「pointUseNum,validFlg」 ・ポイント交換申請の登録 ・会員情報テーブルの有効ポイント数更新 * * @param gift * @param member * @return */ public void upDownPointLogic(Integer point, Integer memberId, String adminId) { // 有効なレコードを取得順に取得 List<PointGet> pointGetList = select().where(new SimpleWhere() .eq("memberId", memberId) .eq("validFlg",SinaburoConstant.ValidFlg.VALID)) .orderBy("pointGetDate") .getResultList(); int requiredPoint = point; // 各レコードごとに使えるポイント int validPoint = 0; // 消費ポイント int usePoint = 0; // ■ポイント取得履歴の更新 for (int i = 0; i < pointGetList.size(); i++) { PointGet pointGet = pointGetList.get(i); // 各レコードの使えるポイント // validPointは0以上pointGet.pointGetNum以下 validPoint = pointGet.pointGetNum - pointGet.pointUseNum; // 消費ポイントが0になるまで usePoint = Math.min(validPoint, requiredPoint); requiredPoint = requiredPoint - usePoint; pointGet.pointUseNum += usePoint; // レコードが消費完了していたら。INVALIDにする。 if (pointGet.pointGetNum - pointGet.pointUseNum == 0) { pointGet.validFlg = SinaburoConstant.ValidFlg.INVALID; } // 対象レコードを更新 update(pointGet, adminId); } } /** * ポイント有効期限変更時、ポイント取得日を変更処理した日とする * @param pointPeriod ポイント有効期 * @return ret 更新件数 */ public int updatePointGetDateByPointPeriod(String pointPeriod,String loginId) { String sql = "update t_point_get " + "set " + "point_get_date = to_char(current_timestamp,'yyyymmdd'), " + "update_date = now(), " + "update_id = '" + loginId + "' " + "where point_get_id in " + "( " + "select point_get_id " + "from " + "t_point_get " + "where " + "to_timestamp(point_get_date,'yyyymmdd') + '-1 days' + ' " + pointPeriod + " years' < date_trunc('day', current_timestamp) " + "and valid_flg = 1 " + ") "; int ret = jdbcManager.updateBySql(sql).execute(); return ret; } // /** // * ポイント有効期間切れ処理 // * 1.ポイント取得情報で有効期限が切れたレコードをvalid_flgを0に変更。 // * 2.会員情報のポイントを更新する。 // * @param strYearsAgoOneMonthAfter X年前の1ヶ月後 // */ // public void cutExpiredPoint(String strYearsAgoOneMonthAfter) { // //ポイント取得情報テーブル更新 // //有効期限が切れたレコードをvalid_flg=0に変更 // String sql = "UPDATE t_point_get SET valid_flg = '0' where point_get_date < ?"; // jdbcManager.updateBySql(sql,String.class).params(strYearsAgoOneMonthAfter+"01").execute(); // // //会員情報のポイントを更新する。既存ポイントが0以下は更新対象外(※パフォーマンスのため) // StringBuffer sqlSb = new StringBuffer(); // sqlSb.append("UPDATE m_member M SET point_num = COALESCE(P.validPoint,0) FROM "); // sqlSb.append(" (select MT.member_id,validPoint from m_member MT "); // sqlSb.append(" LEFT JOIN (select SUM(point_get_num - point_use_num) validPoint,member_id from t_point_get WHERE "); // sqlSb.append(" valid_flg = 1 "); // sqlSb.append(" GROUP BY member_id) PT "); // sqlSb.append(" ON MT.member_id = PT.member_id "); // sqlSb.append(" ) P "); // sqlSb.append("WHERE M.member_id = P.member_id "); // sqlSb.append(" AND M.point_Num > ? "); // jdbcManager.updateBySql(sqlSb.toString(),Integer.class).params(0).execute(); // } /** * ポイント有効期間切れ処理 * 1.ポイント取得情報で有効期限が切れたレコードをvalid_flgを0に変更。 * 2.会員情報のポイントを更新する。 * @param strYearsAgoOneMonthAfter X年前の1ヶ月後 */ public void cutExpiredPointBySql(String strYearsAgoOneMonthAfter) { //ポイント取得情報テーブル更新 //有効期限が切れたレコードをvalid_flg=0に変更 String sql = "UPDATE t_point_get SET valid_flg = '0' where point_get_date < ?"; jdbcManager.updateBySql(sql,String.class).params(strYearsAgoOneMonthAfter+"01").execute(); //会員情報のポイントを更新する。既存ポイントが0以下は更新対象外(※パフォーマンスのため) jdbcManager.updateBySqlFile("jp/agentec/sinaburocast/service/cm/cutExpiredPointBySql.sql",0).execute(); } /** * ・ポイント取得履歴更新 ポイント交換申請による、消費ポイント数を増加する。 * 更新するレコードは複数、対象カラムは「pointUseNum,validFlg」 ・ポイント交換申請の登録 ・会員情報テーブルの有効ポイント数更新 * マイレーション用 * * @param userPoint 減らすポイント * @param member * @return restPoint POINTテーブルに残っているポイント */ public int cutDownPointLogicForMaigration(int userPoint, Integer memberId,String loginId) { // 有効なレコードを取得順に取得 List<PointGet> pointGetList = select().where(new SimpleWhere() .eq("memberId", memberId) .eq("validFlg",SinaburoConstant.ValidFlg.VALID)) .orderBy("pointGetDate, pointGetid") .getResultList(); int requiredPoint = userPoint; // 各レコードごとに使えるポイント int validPoint = 0; // 消費ポイント int usePoint = 0; // 残ポイント int restPoint = 0; // ■ポイント取得履歴の更新 for (int i = 0; i < pointGetList.size(); i++) { PointGet pointGet = pointGetList.get(i); if (requiredPoint == 0) { // 会員情報テーブル残ポイントを取得する。ここから取得するレコードはpointUseNumが0であるはず。 restPoint += pointGet.pointGetNum - pointGet.pointUseNum; continue; } // 各レコードの使えるポイント // validPointは0以上pointGet.pointGetNum以下 validPoint = pointGet.pointGetNum - pointGet.pointUseNum; // 消費ポイントが0になるまで usePoint = Math.min(validPoint, requiredPoint); requiredPoint = requiredPoint - usePoint; pointGet.pointUseNum += usePoint; // レコードが消費完了していたら。INVALIDにする。 if (pointGet.pointGetNum - pointGet.pointUseNum == 0) { pointGet.validFlg = SinaburoConstant.ValidFlg.INVALID; } else { restPoint = pointGet.pointGetNum - pointGet.pointUseNum; } // 対象レコードを更新 update(pointGet, loginId); } return restPoint; } public void clearPointUseNumByMemberId(Integer memberId) { String sql = "UPDATE t_point_get SET point_use_num = 0, valid_flg = '1' where member_Id = ?"; jdbcManager.updateBySql(sql, Integer.class).params(memberId).execute(); } /** * マイレーション用 * MEMBERテーブルPOINT_GETテーブルとPOINTの差異があるレコードを取得 * MEMBER_Id,POINT_NUM,ppoint,mp(MならMEMBERが大きい、Pならポイントが大きい) * @return */ public BeanMap getDefaultPoint(Integer memberId) { StringBuilder sql = new StringBuilder(); sql.append("select *,(CASE WHEN MP ='P' THEN ppoint-POINT_NUM ELSE 0 END) herasuPoint from ( "); sql.append(" select m.MEMBER_ID ,M.POINT_NUM ,P.zan ppoint, (CASE WHEN M.POINT_NUM > P.ZAN THEN 'M' WHEN M.POINT_NUM < P.ZAN THEN 'P' END) MP from m_member M "); sql.append(" INNER JOIN "); sql.append(" (select member_id,sum(point_get_num-point_use_num) ZAN from T_POINT_GET where VALID_FLG=1 and member_id =? group by member_id) P "); sql.append(" ON M.MEMBER_ID = P.MEMBER_ID "); sql.append(" AND M.POINT_NUM != P.ZAN "); sql.append(" where m.member_Id = ?) R"); return jdbcManager.selectBySql(BeanMap.class,sql.toString(),memberId,memberId).getSingleResult(); } /** * * @return */ public List<BeanMap> memberPointLarge() { StringBuilder sql = new StringBuilder(); sql.append("select m.MEMBER_ID ,P.zan ppoint ,M.POINT_NUM,''''||M.POINT_NUM,P.ZAN ||'/'||M.POINT_NUM MP from m_member M "); sql.append(" INNER JOIN "); sql.append(" (select member_id,sum(point_get_num-point_use_num) ZAN from T_POINT_GET where VALID_FLG=1 and INSERT_ID='BATCH' group by member_id) P "); sql.append(" ON M.MEMBER_ID = P.MEMBER_ID "); sql.append(" AND M.POINT_NUM > P.ZAN "); sql.append(" "); sql.append(" order by m.member_id,mp "); return jdbcManager.selectBySql(BeanMap.class,sql.toString()).getResultList(); } public List<PointRecoveryDto> findPointRecoveryDto(){ StringBuilder sql = new StringBuilder(); sql.append("select member_id, sum(point_get_num) as amount_point_get_num, sum(point_use_num) as amount_point_use_num "); sql.append("from t_point_get "); sql.append("group by member_id "); sql.append("having sum(point_get_num) <> sum(point_use_num) "); sql.append("and sum(point_use_num) > 0 "); return jdbcManager.selectBySql(PointRecoveryDto.class, sql.toString()).getResultList(); } }