public static GroupMember Translate(IDictionary <string, object> record) { if (record == null || !record.Keys.Any()) { return(null); } // Map the properties of Person Note class to known CSV headers // Maybe this could be configurable to the user in the UI if the need arises var propertyToCsvFieldNameMap = new Dictionary <string, string> { { "PersonId", "Person ID" } }; // Create a person note object. Using the map, read values from the CSV record and // set the associated properties of the person with those values var groupMember = new GroupMember(); var groupMemberType = groupMember.GetType(); foreach (var kvp in propertyToCsvFieldNameMap) { var propertyName = kvp.Key; var csvFieldName = kvp.Value; var property = groupMemberType.GetProperty(propertyName); var value = CsvFieldTranslators.GetValue(property.PropertyType, csvFieldName, record); property.SetValue(groupMember, value); } // TODO store unused values, like username, as attributes when slingshot supports it return(groupMember); }
/// <summary> /// Add a phone number to the person if the CSV record has a value for that field and /// phone type. /// </summary> /// <param name="person"></param> /// <param name="csvRecord"></param> /// <param name="fieldName"></param> /// <param name="phoneType"></param> private static void AddPhone(Person person, IDictionary <string, object> csvRecord, string fieldName, string phoneType) { var number = CsvFieldTranslators.GetString(fieldName, csvRecord); if (string.IsNullOrWhiteSpace(number)) { return; } person.PhoneNumbers.Add(new PersonPhone { PersonId = person.Id, PhoneNumber = number, PhoneType = phoneType }); }
/// <summary> /// Takes a dictionary representing a CSV record/row and returns a new Person /// Note object with the properties set to the values indicated in the CSV record. /// </summary> /// <param name="csvRecord"></param> /// <returns></returns> public static PersonNote Translate(IDictionary <string, object> csvRecord) { if (csvRecord == null || !csvRecord.Keys.Any()) { return(null); } // Map the properties of Person Note class to known CSV headers // Maybe this could be configurable to the user in the UI if the need arises var propertyToCsvFieldNameMap = new Dictionary <string, string> { { "PersonId", "Breeze ID" }, // Id { "NoteType", "Username" }, // Caption // IsAlert { "IsPrivateNote", "Is Private" }, { "Text", "Note" }, { "DateTime", "Created On" } // CreatedByPersonId }; // Create a person note object. Using the map, read values from the CSV record and // set the associated properties of the person with those values var personNote = new PersonNote(); var personNoteType = personNote.GetType(); foreach (var kvp in propertyToCsvFieldNameMap) { var propertyName = kvp.Key; var csvFieldName = kvp.Value; var property = personNoteType.GetProperty(propertyName); var value = CsvFieldTranslators.GetValue(property.PropertyType, csvFieldName, csvRecord); property.SetValue(personNote, value); } // Notetype is mapped to username since there is no great way to match a username to an author person if (string.IsNullOrWhiteSpace(personNote.NoteType)) { personNote.NoteType = "Anonymous"; } // TODO store unused values, like username, as attributes when slingshot supports it return(personNote); }
public static FinancialTransaction Translate(IDictionary <string, object> record, List <FinancialAccount> accounts, List <FinancialBatch> batches) { if (record == null || !record.Keys.Any()) { return(null); } var accountName = CsvFieldTranslators.GetString("Fund(s)", record); var account = accounts.FirstOrDefault(a => a.Name == accountName); if (account == null) { account = new FinancialAccount { // CampusId Id = accounts.Count + 1, Name = accountName }; accounts.Add(account); } // Map the properties of Person Note class to known CSV headers // Maybe this could be configurable to the user in the UI if the need arises var transactionPropertyToCsvFieldNameMap = new Dictionary <string, string> { { "Id", "Payment ID" }, { "BatchId", "Batch" }, { "AuthorizedPersonId", "Person ID" }, { "TransactionDate", "Date" }, //{ "TransactionType", "" } { "TransactionSource", "Method ID" }, { "CurrencyType", "Method ID" }, { "Summary", "Note" }, { "TransactionCode", "Payment ID" }, { "CreatedDateTime", "Date" } // ModifiedByPersonId // ModifiedDateTime }; var detailPropertyToCsvFieldNameMap = new Dictionary <string, string> { { "Id", "Payment ID" }, { "TransactionId", "Payment ID" }, // AccountId { "Amount", "Amount" }, { "Summary", "Note" }, // CreatedByPersonId { "CreatedDateTime", "Date" } // ModifiedByPersonId // ModifiedDateTime }; // Create a person note object. Using the map, read values from the CSV record and // set the associated properties of the person with those values var transaction = new FinancialTransaction(); var transactionType = transaction.GetType(); foreach (var kvp in transactionPropertyToCsvFieldNameMap) { var propertyName = kvp.Key; var csvFieldName = kvp.Value; var property = transactionType.GetProperty(propertyName); var value = CsvFieldTranslators.GetValue(property.PropertyType, csvFieldName, record); property.SetValue(transaction, value); } var detail = new FinancialTransactionDetail { AccountId = account.Id }; var detailType = detail.GetType(); transaction.FinancialTransactionDetails.Add(detail); foreach (var kvp in detailPropertyToCsvFieldNameMap) { var propertyName = kvp.Key; var csvFieldName = kvp.Value; var property = detailType.GetProperty(propertyName); var value = CsvFieldTranslators.GetValue(property.PropertyType, csvFieldName, record); property.SetValue(detail, value); } var existingBatch = batches.FirstOrDefault(b => b.Id == transaction.BatchId); if (existingBatch == null) { existingBatch = new FinancialBatch { Id = transaction.BatchId, Name = "Breeze Transactions", Status = BatchStatus.Closed }; batches.Add(existingBatch); } existingBatch.FinancialTransactions.Add(transaction); // Batch doesn't have a start date or this transaction is before the start date if (!existingBatch.StartDate.HasValue || (transaction.TransactionDate.HasValue && transaction.TransactionDate.Value < existingBatch.StartDate.Value)) { existingBatch.StartDate = transaction.TransactionDate; } // TODO store unused values, like checknumber, as attributes when slingshot supports it return(transaction); }
/// <summary> /// Takes a dictionary representing a CSV record/row and returns a new Person /// object with the properties set to the values indicated in the CSV record. /// </summary> /// <param name="csvRecord"></param> /// <returns></returns> public static Person Translate(IDictionary <string, object> csvRecord, List <PersonAttribute> attributes) { if (csvRecord == null || !csvRecord.Keys.Any()) { return(null); } // Map the properties of Person class to known CSV headers // Maybe this could be configurable to the user in the UI if the need arises var propertyToCsvFieldNameMap = new Dictionary <string, string> { { "Id", "Breeze ID" }, { "FamilyId", "Family" }, // FamilyName // FamilyImageUrl { "FamilyRole", "Family Role" }, { "FirstName", "First Name" }, { "NickName", "Nickname" }, { "LastName", "Last Name" }, { "MiddleName", "Middle Name" }, // Salutation // Suffix { "Email", "Email" }, { "Gender", "Gender" }, { "MaritalStatus", "Marital Status" }, { "Birthdate", "Birthdate" }, // AnniversaryDate // RecordStatus // InactiveReason // ConnectionStatus // This seems specific to a single church, so make it a person attribute instead of email preference to work for more than one church //{ "EmailPreference", "Opt-out Graceland Emails" }, { "CreatedDateTime", "Added Date" }, { "ModifiedDateTime", "Record Last Updated" }, // PersonPhotoUrl // Campus // Note // GiveIndividually // IsDeceased // GiveIndividually }; // Keep track of which fields are used so that the remaining fields can be // stored as attributes var unusedCsvFieldNames = csvRecord.Keys.ToList(); // Discard fields that are calculated from other fields or simply not needed var ignoreFieldNames = new List <string> { "Birthdate Month/Day", // Calculated from birthdate "Age", // Calculated from birthdate "Record Last Updated Month/Day", // Calculated from RecordLastUpdated "Years Since Record Last Updated", // Calculated from RecordLastUpdated "Grade" // Calculated from graduation year }; foreach (var ignoreFieldName in ignoreFieldNames) { unusedCsvFieldNames.Remove(ignoreFieldName); } // Create a person object. Using the map, read values from the CSV record and // set the associated properties of the person with those values var person = new Person(); var personType = person.GetType(); foreach (var kvp in propertyToCsvFieldNameMap) { var propertyName = kvp.Key; var csvFieldName = kvp.Value; var property = personType.GetProperty(propertyName); var value = CsvFieldTranslators.GetValue(property.PropertyType, csvFieldName, csvRecord); property.SetValue(person, value); unusedCsvFieldNames.Remove(csvFieldName); } // Add phones if the CSV fields are set. The phone types match the breeze // field names. foreach (var phoneType in new[] { "Home", "Mobile", "Work" }) { AddPhone(person, csvRecord, phoneType, phoneType); unusedCsvFieldNames.Remove(phoneType); } // Add an address if at least one of the properties has a value var address = CsvFieldTranslators.GetString("Street Address", csvRecord); unusedCsvFieldNames.Remove("Street Address"); var city = CsvFieldTranslators.GetString("City", csvRecord); unusedCsvFieldNames.Remove("City"); var state = CsvFieldTranslators.GetString("State", csvRecord); unusedCsvFieldNames.Remove("State"); var zip = CsvFieldTranslators.GetString("Zip", csvRecord); unusedCsvFieldNames.Remove("Zip"); if (!string.IsNullOrWhiteSpace(address) || !string.IsNullOrWhiteSpace(city) || !string.IsNullOrWhiteSpace(state) || !string.IsNullOrWhiteSpace(zip)) { person.Addresses.Add(new PersonAddress { AddressType = AddressType.Home, City = city, PersonId = person.Id, PostalCode = zip, State = state, Street1 = address }); } // For all remaining fields of the CSV, create an attribute value var whitespaceRegex = new Regex(@"\s+"); foreach (var csvFieldName in unusedCsvFieldNames) { var key = whitespaceRegex.Replace(csvFieldName, string.Empty); var value = CsvFieldTranslators.GetString(csvFieldName, csvRecord); if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(value)) { continue; } // Don't want the attribute values being added to the core system attribute, so avoid key collisions key = "Breeze" + key; var existingAttribute = attributes.FirstOrDefault(a => a.Key.Equals(key, StringComparison.OrdinalIgnoreCase)); if (existingAttribute == null) { existingAttribute = new PersonAttribute { Key = key, FieldType = "Rock.Field.Types.TextFieldType", Name = csvFieldName, Category = "Breeze Import" }; attributes.Add(existingAttribute); } person.Attributes.Add(new PersonAttributeValue { AttributeKey = existingAttribute.Key, AttributeValue = value, PersonId = person.Id }); } const int maxLength = 50; if (person.FirstName != null && person.FirstName.Length > maxLength) { person.FirstName = person.FirstName.Substring(0, maxLength); } if (person.NickName != null && person.NickName.Length > maxLength) { person.NickName = person.NickName.Substring(0, maxLength); } return(person); }