package crmdna.registration; import com.googlecode.objectify.cmd.Query; import crmdna.client.Client; import crmdna.common.DateUtils; import crmdna.common.Utils; import crmdna.common.api.APIException; import crmdna.common.api.APIResponse; import crmdna.program.Program; import crmdna.program.ProgramProp; import crmdna.sequence.Sequence; import crmdna.user.User; import java.util.*; import static crmdna.common.OfyService.ofy; public class Discount { public static DiscountEntity get(String client, String discountCode) { return get(client, discountCode, null); } public static DiscountEntity get(String client, String discountCode, Long programTypeId) { Client.ensureValid(client); Query<DiscountEntity> q = ofy(client).load().type(DiscountEntity.class).filter("discountCode", discountCode); List<Long> programTypeIds = new ArrayList<>(); programTypeIds.add(programTypeId); if (programTypeId != null) { q = q.filter("programTypeIds in", programTypeIds); } List<DiscountEntity> entities = q.list(); return (entities.size() > 0) ? entities.get(0) : null; } public static DiscountProp createDiscountCode(String client, String discountCode, Set<Long> programTypeIds, int validTillYYYYMMDD, Double percentage, Double amount, String login) { User.ensureClientLevelPrivilege(client, login, User.ClientLevelPrivilege.UPDATE_PROGRAM_TYPE); DateUtils.ensureFormatYYYYMMDD(validTillYYYYMMDD); if (validTillYYYYMMDD < DateUtils.toYYYYMMDD(new Date())) { Utils.throwIncorrectSpecException("Validity should not be in the past"); } DiscountEntity entity = get(client, discountCode); if (entity != null) { Utils.throwAlreadyExistsException("Discount Code [" + discountCode + "] already exists"); } if ((percentage == null) && (amount == null)) { Utils.throwIncorrectSpecException("Either percentage or amount must be specified"); } if ((percentage != null) && (amount != null)) { Utils.throwIncorrectSpecException("Both percentage and amount must not be specified"); } entity = new DiscountEntity(); entity.discountId = Sequence.getNext(client, Sequence.SequenceType.DISCOUNT); entity.discountCode = discountCode; entity.programTypeIds = programTypeIds; entity.validTillYYYYMMDD = validTillYYYYMMDD; entity.percentage = (percentage != null) ? percentage : -1; entity.amount = (amount != null) ? amount : -1; ofy(client).save().entity(entity).now(); return entity.toProp(); } public static DiscountProp updateDiscountCode(String client, String discountCode, Set<Long> newProgramTypeIds, Integer newValidTillYYYYMMDD, Double newPercentage, Double newAmount, String login) { User.ensureClientLevelPrivilege(client, login, User.ClientLevelPrivilege.UPDATE_PROGRAM_TYPE); if (newValidTillYYYYMMDD != null) { DateUtils.ensureFormatYYYYMMDD(newValidTillYYYYMMDD); if (newValidTillYYYYMMDD < DateUtils.toYYYYMMDD(new Date())) { Utils.throwIncorrectSpecException("Validity should not be in the past"); } } boolean changed = false; DiscountEntity entity = get(client, discountCode); if (entity == null) { Utils.throwNotFoundException("Discount Code [" + discountCode + "] does not exist"); } if ((newPercentage != null) && (newAmount != null)) { Utils.throwIncorrectSpecException("Both percentage and amount must not be specified"); } if (newProgramTypeIds != null) { entity.programTypeIds = newProgramTypeIds; changed = true; } if (newValidTillYYYYMMDD != null) { entity.validTillYYYYMMDD = newValidTillYYYYMMDD; changed = true; } if (newPercentage != null) { entity.percentage = newPercentage; changed = true; } if (newAmount != null) { entity.amount = newAmount; changed = true; } if (changed) { ofy(client).save().entity(entity).now(); } return entity.toProp(); } public static DiscountProp applyDiscount(String client, String discountCode, long programId) { ProgramProp programProp = Program.safeGet(client, programId).toProp(client); DiscountEntity entity = get(client, discountCode, programProp.programTypeProp.programTypeId); if (entity == null) { Utils.throwNotFoundException("Invalid Discount Code"); } DiscountProp prop = entity.toProp(); if (prop.validTillYYYYMMDD < DateUtils.toYYYYMMDD(new Date())) { Utils.throwIncorrectSpecException("Expired Discount Code"); } if (prop.amount > 0) { prop.discountedAmount = programProp.fee - prop.amount; } else if (prop.percentage > 0) { prop.discountedAmount = programProp.fee - (programProp.fee * prop.percentage / 100); } else { prop.discountedAmount = programProp.fee; } return prop; } }