package com.withiter.models.account; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; import org.bson.types.ObjectId; import org.joda.time.DateTime; import play.Logger; import play.Play; import play.modules.morphia.Model.NoAutoTimestamp; import cn.bran.japid.util.StringUtils; import com.google.code.morphia.annotations.Entity; import com.withiter.common.Constants; import com.withiter.common.Constants.CreditStatus; import com.withiter.common.Constants.ReservationStatus; import com.withiter.models.merchant.Haoma; import com.withiter.models.merchant.Merchant; import com.withiter.utils.RemindDateUtils; @Entity @NoAutoTimestamp public class Reservation extends ReservationEntityDef { private static int DEFAULT_PAGE_ITEMS_NUMBER = 10; /** * Find valid reservation list by account id * * @param accountId * user account id * @return the list of valid reservation */ public static List<Reservation> findValidReservations(String accountId) { MorphiaQuery q = Reservation.q(); q.filter("accountId", accountId).filter("valid", true).filter("status !=", ReservationStatus.canceled).filter("available", true); return q.asList(); } /** * 获取到第index个reservation * @param merchantId 商家id * @param seatNumber 座位类型 * @param index 第index个reservation * @return Reservation */ public static Reservation findReservationForSMSRemind(String merchantId, int seatNumber, int index, long version){ MorphiaQuery q = Reservation.q(); q.filter("version", version); q.filter("merchantId", merchantId).filter("seatNumber", seatNumber); q.filter("valid", true); // 得到第index个Reservation q.order("created"); q.offset(index); return q.first(); } /** * get next page current reservations by account ID * * @param accountId * account ID * @param page * the page number * @param sortBy * 排序方式 * @return reservations list */ public static List<Reservation> findValidReservations(String accountId, int page, String sortBy) { MorphiaQuery q = Reservation.q(); q.filter("accountId", accountId).filter("valid", true).filter("available", true); if (!StringUtils.isEmpty(sortBy)) { q = sortBy(q, sortBy); } else { q = sortBy(q, "-created"); } return paginate(q, page); } /** * get all reservations by account ID * * @param accountId * account ID * @param sortBy * 排序方式 * @return reservations list */ public static List<Reservation> findValidReservations(String accountId, String sortBy) { MorphiaQuery q = Reservation.q(); q.filter("accountId", accountId).filter("valid", true).filter("available", true); if (!StringUtils.isEmpty(sortBy)) { q = sortBy(q, sortBy); } else { q = sortBy(q, "-created"); } return q.asList(); } /** * Check whether does the reservation exist by account id, merchant id and * seat number * * @param accountId * user account id * @param mid * merchant id * @param seatNumber * the number of seat * @return Reservation object */ public static Reservation reservationExist(String accountId, String mid, int seatNumber) { MorphiaQuery q = Reservation.q(); q.filter("accountId", accountId).filter("merchantId", mid).filter("valid", true).filter("seatNumber", seatNumber); return q.first(); } /** * Find the history reservations by account id * * @param accountId * user account id * @return the list of history reservations (valid == false) */ public static List<Reservation> findHistroyReservations(String accountId) { MorphiaQuery q = Reservation.q(); q.filter("accountId", accountId).filter("valid", false).filter("available", true); return q.asList(); } /** * get next page reservations by account ID * * @param accountId * account ID * @param page * the page number * @param sortBy * 排序方式 * @return reservations list */ public static List<Reservation> findHistroyReservations(String accountId, int page, String sortBy) { MorphiaQuery q = Reservation.q(); q.filter("accountId", accountId).filter("valid", false).filter("available", true); if (!StringUtils.isEmpty(sortBy)) { q = sortBy(q, sortBy); } else { q = sortBy(q, "-created"); } return paginate(q, page); } /** * get next page reservations by account ID * * @param accountId * account ID * @param page * the page number * @param sortBy * 排序方式 * @return reservations list */ public static List<Reservation> findHistroyReservationsNew(String accountId, String sortBy) { MorphiaQuery q = Reservation.q(); q.filter("accountId", accountId).filter("valid", false).filter("available", true).filter("status !=", ReservationStatus.invalidByMerchantUpdate); if (!StringUtils.isEmpty(sortBy)) { q = sortBy(q, sortBy); } else { q = sortBy(q, "-created"); } return q.asList(); } /** * 通用排序 * * @param q * @param sortBy * @return */ private static MorphiaQuery sortBy(MorphiaQuery q, String sortBy) { q.order(sortBy); return q; } /** * 通用分页 * * @param q * @param page * @return */ private static List<Reservation> paginate(MorphiaQuery q, int page) { q.offset((page - 1) * DEFAULT_PAGE_ITEMS_NUMBER).limit(DEFAULT_PAGE_ITEMS_NUMBER); return q.asList(); } /** * 当排队情况有变化时,需要推送到所有关联的用户 * when current object updated, this function will automatically invoked. */ @OnUpdate private void updateHaoma() { // String mid = this.merchantId; // int myNumber = this.myNumber; // int seatNumber = this.seatNumber; // Haoma haoma = Haoma.findByMerchantId(mid); // Haoma.updateByXmethod(haoma, mid, myNumber, seatNumber, this.status); pushToClient(); } private void pushToClient() { } /** * Cancel one reservation by reservation id * * @param reservationId * the id of reservation */ public static boolean cancel(String reservationId) { Reservation r = Reservation.findById(reservationId); if (r != null) { r.status = ReservationStatus.canceled; r.valid = false; r.modified = new Date(); r.save(); // 返还积分 String aid = r.accountId; Account account = Account.findById(new ObjectId(aid)); int jifen = Integer.parseInt(Play.configuration.getProperty("credit.cancel.jifen")); account.jifen += jifen; account.save(); // 增加积分消费情况 Credit credit = new Credit(); credit.accountId = r.accountId; credit.merchantId = r.merchantId; credit.reservationId = r.id(); credit.cost = true; credit.jifen = jifen; credit.status = CreditStatus.canceled; credit.created = new Date(); credit.modified = new Date(); credit.create(); return true; } return false; } /** * Finish one reservation by reservation id * * @param reservationId * the id of reservation */ public static boolean finish(String reservationId) { Reservation r = Reservation.findById(reservationId); if (r != null) { r.status = ReservationStatus.finished; r.valid = false; r.modified = new Date(); r.save(); String accountId = r.accountId; // 手机号产生的reservation if(accountId == null){ return true; } int finishedJifen = Integer.parseInt(Play.configuration.getProperty("credit.finished.jifen")); Account account = Account.findById(accountId); account.jifen = account.jifen + finishedJifen; account.modified = new Date(); account.save(); // 增加积分消费情况 Credit credit = new Credit(); credit.accountId = r.accountId; credit.merchantId = r.merchantId; credit.reservationId = r.id(); credit.cost = true; credit.jifen = finishedJifen; credit.status = CreditStatus.finished; credit.created = new Date(); credit.modified = new Date(); credit.create(); return true; } return false; } /** * Expire one reservation by reservation id * * @param reservationId * the id of reservation */ public static boolean expire(String reservationId) { Reservation r = Reservation.findById(reservationId); if (r != null) { r.status = ReservationStatus.expired; r.valid = false; r.modified = new Date(); r.save(); // 增加积分消费情况 Credit credit = new Credit(); credit.accountId = r.accountId; credit.merchantId = r.merchantId; credit.reservationId = r.id(); credit.cost = true; credit.jifen = Integer.parseInt(Play.configuration.getProperty("credit.getnumber.jifen")); credit.status = CreditStatus.expired; credit.created = new Date(); credit.modified = new Date(); credit.create(); return true; } return false; } /** * * query reservations by merchant id and account id * * @param accountId * account id * @param mid * merchant id * @return the reservations */ public static List<Reservation> getReservationsByMerchantIdAndAccountId(String accountId, String mid,long version) { MorphiaQuery q = Reservation.q(); q.filter("accountId", accountId).filter("merchantId", mid).filter("valid", true).filter("version", version); return q.asList(); } /** * * query previous number * * @param accountId * @param mid * @return */ public static long findCountBetweenCurrentNoAndMyNumber(String mid, int currentNo, int myNumber, int seatNumber, long version) { MorphiaQuery q = Reservation.q(); q.filter("version", version); q.filter("seatNumber", seatNumber).filter("merchantId", mid).filter("status", "canceled").filter("myNumber <" , myNumber).filter("myNumber >" , currentNo); return q.count(); } /** * Get the reservations which finished by merchant author * * @param seatNumber * @param currentNumber * @param mid * @return */ public static Reservation findReservationForHandle(int seatNumber, int currentNumber, String mid, long version) { MorphiaQuery q = Reservation.q(); q.filter("version", version); q.filter("merchantId", mid).filter("status", "active"); q.filter("seatNumber", seatNumber).filter("myNumber", currentNumber); return q.first(); } public static List<Reservation> findReservationsByMerchantIdandDate(String mid, Date beforeDate) { MorphiaQuery q = Reservation.q(); q.filter("created >", new DateTime(beforeDate.getTime()).toDate()).filter("merchantId", mid); return q.asList(); } /** * 统计一年当中此商家的Reservation * @param mid 商家ID * @return */ public static List<Reservation> findReservationsByMerchantIdandDate(String mid) { long duration = System.currentTimeMillis() - 1000l * 60 * 60 * 24 * 365; Date d = new Date(duration); return findReservationsByMerchantIdandDate(mid, d); } /** * * @param rid * id of reservation * @return reservation */ public static Reservation findByRid(String rid) { MorphiaQuery q = Reservation.q(); q.filter("_id", new ObjectId(rid)); if (q.asKeyList().size() == 0) { return null; } return (Reservation) q.asList().get(0); } public static Reservation queryForCancel(String merchantId, int seatNumber, int currentNumber, long version){ MorphiaQuery q = Reservation.q(); q.filter("version", version); q.filter("merchantId", merchantId); q.filter("seatNumber", seatNumber); q.filter("myNumber =", currentNumber); return q.first(); } /** * 商家更新资料导致当前所有的Reservation都变成invalid状态 * @param seatNumber * @param merchantId */ public static void invalidByMerchantUpdate(int seatNumber, String merchantId){ MorphiaQuery q = Reservation.q(); q.filter("merchantId", merchantId).filter("seatNumber", seatNumber); q.filter("valid", true); Iterator it = q.iterator(); Reservation r = null; while(it.hasNext()){ r = (Reservation)it.next(); r.valid = false; r.status = ReservationStatus.invalidByMerchantUpdate; r.save(); } } /** * 当天截止到当前时间所有Reservation * @param mid * @return */ private static MorphiaQuery todayCount(String mid) { MorphiaQuery q = Reservation.q(); RemindDateUtils utils = new RemindDateUtils(); Date todayStart = utils.getTodayStartTime(); q.filter("created >", todayStart).filter("merchantId", mid); return q; } /** * 前一天所有Reservation * @param mid * @return */ private static MorphiaQuery lastDayCount(String mid){ MorphiaQuery q = Reservation.q(); RemindDateUtils utils = new RemindDateUtils(); Date lastDayStart = utils.getLastDayStartTime(); Date lastDayEnd = utils.getLastDayEndTime(); q.filter("created >", lastDayStart).filter("created <", lastDayEnd).filter("merchantId", mid); return q; } /** * 上一个月所有Reservation * @param mid * @return */ private static MorphiaQuery lastMonthCount(String mid){ MorphiaQuery q = Reservation.q(); RemindDateUtils utils = new RemindDateUtils(); Date lastMonthStart = utils.getLastMonthStartTime(); Date lastMonthEnd = utils.getLastMonthEndTime(); Logger.debug("lastMonthStart : start date -> %s", lastMonthStart); Logger.debug("lastMonthEnd : end date -> %s", lastMonthEnd); q.filter("created >", lastMonthStart).filter("created <", lastMonthEnd).filter("merchantId", mid); Logger.debug("merchantId -> %s", mid); Logger.debug("last month reservation count -> %s", q.count()); return q; } /** * 上一个月所有Reservation * @param mid * @return */ private static MorphiaQuery lastThreeMonthsCount(String mid){ MorphiaQuery q = Reservation.q(); RemindDateUtils utils = new RemindDateUtils(); Date lastThreeMonthsStart = utils.getLastThreeMonthsStartTime(); Date lastThreeMonthsEnd = utils.getLastMonthEndTime(); q.filter("created >", lastThreeMonthsStart).filter("created <", lastThreeMonthsEnd).filter("merchantId", mid); return q; } public static long lastMonthFinishCount(String mid) { MorphiaQuery q = lastMonthCount(mid); q.filter("status", Constants.ReservationStatus.finished); return q.count(); } public static long lastMonthCancelCount(String mid) { MorphiaQuery q = lastMonthCount(mid); q.filter("status", Constants.ReservationStatus.canceled); return q.count(); } public static long lastQuarterFinishCount(String mid) { return 0; } public static long lastQuarterCancelCount(String mid) { return 0; } public static long lastThreeMonthsFinishCount(String mid) { MorphiaQuery q = lastThreeMonthsCount(mid); q.filter("status", Constants.ReservationStatus.finished); return q.count(); } public static long lastThreeMonthsCancelCount(String mid) { MorphiaQuery q = lastThreeMonthsCount(mid); q.filter("status", Constants.ReservationStatus.canceled); return q.count(); } public static long lastDayFinishCount(String mid) { MorphiaQuery q = lastDayCount(mid); q.filter("status", Constants.ReservationStatus.finished); return q.count(); } public static long lastDayCancelCount(String mid) { MorphiaQuery q = lastDayCount(mid); q.filter("status", Constants.ReservationStatus.canceled); return q.count(); } public static long todayFinishCount(String mid) { MorphiaQuery q = todayCount(mid); q.filter("status", Constants.ReservationStatus.finished); return q.count(); } public static long todayCancelCount(String mid) { MorphiaQuery q = todayCount(mid); q.filter("status", Constants.ReservationStatus.canceled); return q.count(); } }