package crmdna.member; import crmdna.client.Client; import crmdna.common.api.APIException; import crmdna.common.api.APIResponse.Status; import crmdna.common.contact.ContactProp; import crmdna.group.Group; import crmdna.program.Program; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import static crmdna.common.AssertUtils.*; import static crmdna.common.OfyService.ofy; // TODO: consider renaming this as bulk updater public class MemberBulkSaver { private String client; private List<MemberEntity> entities = new ArrayList<>(); private List<ContactProp> contacts = new ArrayList<>(); private Set<Long> programIdsToAdd = new HashSet<>(); private Set<Long> programIdsToDelete = new HashSet<>(); private Set<Long> groupIdsToAdd = new HashSet<>(); private Set<Long> groupIdsToDelete = new HashSet<>(); private MemberBulkSaver() { } public static MemberBulkSaver memberBulkSaver(String client, List<MemberEntity> entities) { Client.ensureValid(client); ensureNotNull(entities, "entities cannot be null"); MemberBulkSaver saver = new MemberBulkSaver(); saver.client = client; saver.entities = entities; return saver; } public MemberBulkSaver addProgramToAll(long programId) { Program.safeGet(client, programId); programIdsToAdd.add(programId); programIdsToDelete.remove(programId); return this; } public MemberBulkSaver deleteProgramFromAll(long programId) { programIdsToAdd.remove(programId); programIdsToDelete.add(programId); return this; } public MemberBulkSaver addGroupToAll(long groupId) { Group.safeGet(client, groupId); groupIdsToAdd.add(groupId); groupIdsToDelete.remove(groupId); return this; } public MemberBulkSaver deleteGroupToAll(long groupId) { groupIdsToAdd.remove(groupId); groupIdsToDelete.add(groupId); return this; } public MemberBulkSaver setContactsSameSizeList(List<ContactProp> contacts) { ensureNotNull(contacts, "contacts cannot be null"); ensureEqual(entities.size(), contacts.size(), "No of contacts [" + contacts.size() + "] does not match no of entities [" + entities.size() + "]"); // ensure contact is not null for (int i = 0; i < contacts.size(); i++) { ContactProp contact = contacts.get(i); ensureNotNull(contact, "contact(" + i + ") is null"); } this.contacts = contacts; return this; } public MemberBulkSaver populateDependantsAndSave() { if (!contacts.isEmpty()) { ensureEqual(entities.size(), contacts.size()); } Set<Integer> changedIndexes = new HashSet<>(); for (int i = 0; i < entities.size(); i++) { MemberEntity entity = entities.get(i); if (entity == null) continue; boolean change = entity.programIds.addAll(programIdsToAdd); if (change) changedIndexes.add(i); change = entity.programIds.removeAll(programIdsToDelete); if (change) changedIndexes.add(i); change = entity.groupIds.addAll(groupIdsToAdd); if (change) changedIndexes.add(i); change = entity.groupIds.removeAll(groupIdsToDelete); if (change) changedIndexes.add(i); if (entity.groupIds.size() == 0) { throw new APIException().status(Status.ERROR_RESOURCE_INCORRECT).message( "Member [" + entity.getId() + "] should have atleast one group"); } if (!contacts.isEmpty()) { ContactProp contact = contacts.get(i); ensureNotNull(contact, "contact(" + i + ") is null"); change = Member.populateContactDetails(entity, contact); if (change) changedIndexes.add(i); } } ensure(changedIndexes.size() <= entities.size()); List<MemberEntity> changedEntities = new ArrayList<>(); for (int i : changedIndexes) { MemberEntity entity = entities.get(i); changedEntities.add(entity); } Member.populateDependantFields(client, changedEntities); ofy(client).save().entities(changedEntities); return this; } }