package crmdna.participant; import com.googlecode.objectify.Key; import crmdna.client.Client; import crmdna.common.ValidationResultProp; import crmdna.common.api.APIException; import crmdna.common.api.APIResponse.Status; import crmdna.common.contact.Contact; import crmdna.common.contact.ContactProp; import crmdna.member.Member; import crmdna.member.MemberEntity; import crmdna.member.MemberEntity.MemberFactory; import crmdna.member.MemberLoader; import crmdna.participant.ParticipantEntity.ParticipantFactory; import crmdna.program.Program; import crmdna.program.ProgramProp; import crmdna.user.User; import crmdna.user.User.GroupLevelPrivilege; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.logging.Logger; import static crmdna.common.AssertUtils.ensureEqual; import static crmdna.common.OfyService.ofy; import static crmdna.member.MemberBulkSaver.memberBulkSaver; public class Participant { public static List<ParticipantProp> getAll(String client, long programId, String login) { User.ensureValidUser(client, login); Program.safeGet(client, programId); List<Key<ParticipantEntity>> keys = ofy(client).load().type(ParticipantEntity.class).filter("programId", programId).keys() .list(); Map<Key<ParticipantEntity>, ParticipantEntity> map = ofy(client).load().keys(keys); List<ParticipantProp> participantProps = new ArrayList<>(); for (Key<ParticipantEntity> key : map.keySet()) { participantProps.add(map.get(key).toProp()); } Collections.sort(participantProps); return participantProps; } public static int deleteAll(String client, long programId, String login) { Client.ensureValid(client); ProgramProp programProp = Program.safeGet(client, programId).toProp(client); User.ensureGroupLevelPrivilege(client, programProp.groupProp.groupId, login, GroupLevelPrivilege.UPDATE_PARTICIPANT); List<Key<ParticipantEntity>> participantKeys = ofy(client).load().type(ParticipantEntity.class).filter("programId", programId).keys() .list(); if (0 == participantKeys.size()) { throw new APIException().status(Status.ERROR_RESOURCE_NOT_FOUND).message( "No participants data found for programId [" + programId + "]"); } Map<Key<ParticipantEntity>, ParticipantEntity> map = ofy(client).load().keys(participantKeys); // delete the program for all member records List<Long> memberIds = new ArrayList<>(); for (Key<ParticipantEntity> key : map.keySet()) { ParticipantEntity participantEntity = map.get(key); if (participantEntity != null) memberIds.add(participantEntity.memberId); } Map<Long, MemberEntity> memberEntities = MemberLoader.get(client, memberIds, login); memberBulkSaver(client, new ArrayList<>(memberEntities.values())).deleteProgramFromAll(programId) .populateDependantsAndSave(); ofy(client).delete().keys(participantKeys); Logger logger = Logger.getLogger(Participant.class.getName()); logger.info("Deleted [" + participantKeys.size() + "] participants. Removed program from [" + memberEntities.size() + "] members"); return participantKeys.size(); } // public static UploadReportProp uploadAll_old(String client, // List<ContactProp> contactProps, long programId, // boolean ignoreWarnings, String login) { // // // This function will save the entered details as is into participant // // entities. // // If the member is new it will create member entities. // // // if participant details are already saved, just // // throw an error message and exit // // Client.ensureValid(client); // int count = ofy(client).load().type(ParticipantEntity.class) // .filter("programId", programId).keys().list().size(); // // if (0 != count) { // throw new APIException(Status.ERROR_RESOURCE_ALREADY_EXISTS, "[" // + count + "] participants already found for program id [" // + programId // + "]. These participants should be deleted first before " // + " another upload. "); // } // // // logic is as follows - // // // for existing members // // 1. add program to memberentity // // 2. populate member id to participantentity // // for new members // // 1. save as members first and get the member id // // 2. populate member id to participant entity // // save all participant entities // // ProgramProp programProp = Program.safeGet(client, programId).toProp(); // User.ensureAccess(client, login, ResourceType.PROGRAM, // programProp.groupProp.groupId, Action.BULKWRITE); // // ValidationResultProp validationResultProp = Contact // .validate(contactProps); // // if (validationResultProp.hasErrors()) { // throw new APIException() // .status(Status.ERROR_RESOURCE_INCORRECT) // .object(validationResultProp) // .message( // "Found [" + validationResultProp.numErrors // + "] errors and [" // + validationResultProp.numWarnings // + "]. Please correct them before uploading"); // } // // if (validationResultProp.hasWarnings() && !ignoreWarnings) { // throw new APIException() // .status(Status.ERROR_RESOURCE_INCORRECT) // .object(validationResultProp) // .message( // "Found [" // + validationResultProp.numWarnings // + "] warnings. To ignore warnings set [ignoreWarnings] flag to true"); // } // // List<Long> existingMemberIds = Member.getMatchingMemberIds(client, // contactProps); // // List<ParticipantEntity> participantEntities = getParticipantEntities( // client, contactProps, programId); // // List<ContactProp> toAdd = new ArrayList<>(); // // int numExisting = 0; // for (int index = 0; index < contactProps.size(); index++) { // ContactProp c = contactProps.get(index); // ParticipantEntity pe = participantEntities.get(index); // Long memberId = existingMemberIds.get(index); // // if (memberId == null) { // toAdd.add(c); // } else { // toAdd.add(null); // pe.memberId = memberId; // numExisting++; // } // } // // List<Long> newMemberIds = Member.bulkCreateWithoutValidations(client, // toAdd, programId); // // ensureCorrectArraySizes(contactProps.size(), toAdd.size(), // existingMemberIds.size(), newMemberIds.size(), // participantEntities.size()); // // for (int index = 0; index < newMemberIds.size(); index++) { // Long memberId = newMemberIds.get(index); // if (memberId != null) { // ParticipantEntity pe = participantEntities.get(index); // pe.memberId = memberId; // } // } // // // add program to existing members // Member.addOrDeleteProgram(client, programId, existingMemberIds, true, // login); // // // save all participants entity // ofy(client).save().entities(participantEntities); // // UploadReportProp uploadReportProp = new UploadReportProp(); // uploadReportProp.numParticipants = contactProps.size(); // uploadReportProp.existingMemberEmails = numExisting; // uploadReportProp.newMemberEmails = uploadReportProp.numParticipants // - numExisting; // // return uploadReportProp; // } public static UploadReportProp uploadAll(String client, List<ContactProp> contacts, long programId, boolean ignoreWarnings, boolean updateProfile, String login) { // This function will save the entered details as is into participant // entities. // If the member is new it will create member entities. // if participant details are already saved, just // throw an error message and exit Client.ensureValid(client); int count = ofy(client).load().type(ParticipantEntity.class).filter("programId", programId).keys() .list().size(); if (0 != count) { throw new APIException().status(Status.ERROR_RESOURCE_ALREADY_EXISTS).message( "[" + count + "] participants already found for program id [" + programId + "]. These participants should be deleted first before " + " another upload. "); } // logic is as follows - // for existing members // 1. add program to memberentity // 2. populate member id to participantentity // for new members // 1. save as members first and get the member id // 2. populate member id to participant entity // save all participant entities ProgramProp programProp = Program.safeGet(client, programId).toProp(client); User.ensureGroupLevelPrivilege(client, programProp.groupProp.groupId, login, GroupLevelPrivilege.UPDATE_PARTICIPANT); ValidationResultProp validationResultProp = Contact.validate(contacts); if (validationResultProp.hasErrors()) { throw new APIException() .status(Status.ERROR_RESOURCE_INCORRECT) .object(validationResultProp) .message( "Found [" + validationResultProp.getNumErrors() + "] errors and [" + validationResultProp.getNumWarnings() + "] warnings. Please correct them before uploading"); } if (validationResultProp.hasWarnings() && !ignoreWarnings) { throw new APIException() .status(Status.ERROR_RESOURCE_INCORRECT) .object(validationResultProp) .message( "Found [" + validationResultProp.getNumWarnings() + "] warnings. To ignore warnings set [ignoreWarnings] flag to true"); } List<MemberEntity> memberEntities = Member.getMatchingMembersSameSizeList(client, contacts, login); List<ContactProp> toAddContactProps = new ArrayList<>(); List<ContactProp> toUpdateContactProps = new ArrayList<>(); List<MemberEntity> toUpdateMemberEntities = new ArrayList<>(); List<Boolean> match = new ArrayList<>(contacts.size()); for (int index = 0; index < contacts.size(); index++) { ContactProp c = contacts.get(index); c.asOfyyyymmdd = programProp.endYYYYMMDD; MemberEntity memberEntity = memberEntities.get(index); if (memberEntity == null) { toAddContactProps.add(c); match.add(false); } else { toUpdateContactProps.add(c); toUpdateMemberEntities.add(memberEntity); match.add(true); // never change the member profile email address c.email = null; } } ensureEqual(contacts.size(), match.size()); ensureEqual(toAddContactProps.size() + toUpdateContactProps.size(), contacts.size()); List<MemberEntity> toAddMemberEntities = MemberFactory.create(client, toAddContactProps.size()); // save new members memberBulkSaver(client, toAddMemberEntities).setContactsSameSizeList(toAddContactProps) .addGroupToAll(programProp.groupProp.groupId).addProgramToAll(programId) .populateDependantsAndSave(); // save existing members if (updateProfile) { // update contact details in member profile. Never change email. // email already set to null in one of the above for loops memberBulkSaver(client, toUpdateMemberEntities).setContactsSameSizeList(toUpdateContactProps) .addProgramToAll(programId).populateDependantsAndSave(); } else { memberBulkSaver(client, toUpdateMemberEntities).addProgramToAll(programId) .populateDependantsAndSave(); } // populate member id memberEntities = new ArrayList<>(contacts.size()); int addIndex = 0; int updateIndex = 0; for (int i = 0; i < contacts.size(); i++) { MemberEntity memberEntity; if (match.get(i)) { // already existing member memberEntity = toUpdateMemberEntities.get(updateIndex); updateIndex++; } else { // new member memberEntity = toAddMemberEntities.get(addIndex); addIndex++; } memberEntities.add(memberEntity); } List<ParticipantEntity> participantEntities = ParticipantFactory.create(client, contacts, memberEntities, programId); ensureEqual(participantEntities.size(), contacts.size()); // save ofy(client).save().entities(participantEntities); UploadReportProp uploadReportProp = new UploadReportProp(); uploadReportProp.numParticipants = contacts.size(); uploadReportProp.numExistingMembers = toUpdateMemberEntities.size(); uploadReportProp.numNewMembers = uploadReportProp.numParticipants - toUpdateMemberEntities.size(); return uploadReportProp; } }