app/models/imports/memberships_import.rb in artfully_ose-1.2.0 vs app/models/imports/memberships_import.rb in artfully_ose-1.3.0.pre1

- old
+ new

@@ -6,38 +6,236 @@ "memberships" end def row_valid?(parsed_row) raise Import::RowError, "No Amount included in this row: #{parsed_row.row}" if parsed_row.unparsed_amount.blank? - raise Import::RowError, "Please include a first name, last name, email, or company name in this row: #{parsed_row.row}" unless attach_person(parsed_row).naming_details_available? + raise Import::RowError, "No Email included in this row: #{parsed_row.row}" unless attach_person(parsed_row).email.present? raise Import::RowError, "Please include a payment method in this row: #{parsed_row.row}" if parsed_row.payment_method.blank? - valid_amount? parsed_row.unparsed_amount unless parsed_row.unparsed_amount.blank? - valid_date? parsed_row.order_date unless parsed_row.order_date.blank? + valid_amount? parsed_row.unparsed_amount unless parsed_row.unparsed_amount.blank? + valid_date? parsed_row.order_date unless parsed_row.order_date.blank? + + case detect_membership_type(parsed_row.membership_type).to_s + when RollingMembershipType.to_s + valid_date? parsed_row.start_date + raise Import::RowError, "Please include a 'Period' for Rolling membership: #{parsed_row.row}" if parsed_row.period.blank? + raise Import::RowError, "Please include a 'Duration' for Rolling membership: #{parsed_row.row}" if parsed_row.duration.blank? + when SeasonalMembershipType.to_s + valid_date? parsed_row.start_date + valid_date? parsed_row.end_date + end + true end - + + def new_membership_types + self.import_rows.select('membership_name, membership_type, count(id) as member_count').where(membership_type_exists: false).group('membership_name') + end + + def existing_membership_types + self.import_rows.select('membership_name, membership_type, count(id) as member_count').where(membership_type_exists: true).group('membership_name') + end + + def index_parsed_row(parsed_row) + import_row = super + import_row.membership_type = parsed_row.membership_type + import_row.membership_name = parsed_row.membership_name + import_row.membership_type_exists = find_membership_type(parsed_row).present? + import_row + end + def process(parsed_row) row_valid?(parsed_row) - membership_type = create_membership_type(parsed_row) - person = create_person(parsed_row) - order = create_order(parsed_row, person, membership_type) - actions = create_actions(parsed_row, person, memberships_type) + person = create_person(parsed_row) + member = create_member(person) + membership_type = create_membership_type(parsed_row) + order = create_order(parsed_row, person, member, membership_type) end + def create_person(parsed_row) + new_person = attach_person(parsed_row) + + existing_person = Person.first_or_initialize( {:email => new_person.email, :organization => self.organization} ) do |p| + p.type = new_person.type + p.subtype = new_person.subtype + end + + if existing_person.new_record? + existing_person.import = self + else + message(nil, parsed_row, existing_person, "#{existing_person.email} exists. Will merge records.") + end + + existing_person.update_from_import(new_person) + existing_person.skip_commit = true + + unless existing_person.save + message = [] + message << "#{parsed_row.email}: " unless parsed_row.email.blank? + message << person.errors.full_messages.join(', ') + raise Import::RowError, message.join('') + end + + existing_person + end + + def create_member(person) + member = self.members.where(:person_id => person.id, :organization_id => self.organization_id).first + + unless member + member = self.members.build + member.email = person.email + member.password = Devise.friendly_token.first(15) + member.person = person + member.organization = self.organization + member.save! + end + + member + end + def create_membership_type(parsed_row) - membership_type = self.organization.membership_types.build({ - :name => parsed_row.membership_name - }) - membership_type.plan = parsed_row.membership_plan + membership_type = find_membership_type(parsed_row) + + unless membership_type + klass = detect_membership_type(parsed_row.membership_type) + membership_type = klass.new + membership_type.import_id = self.id + membership_type.name = parsed_row.membership_name + membership_type.description = parsed_row.membership_name + membership_type.organization = self.organization + membership_type.price = parsed_row.amount + + case klass.to_s + when SeasonalMembershipType.to_s + membership_type.starts_at = DateTime.parse(parsed_row.start_date) + membership_type.ends_at = DateTime.parse(parsed_row.end_date) + when RollingMembershipType.to_s + membership_type.starts_at = DateTime.parse(parsed_row.start_date) + membership_type.duration = parsed_row.duration + membership_type.period = parsed_row.period + else + raise Import::RowError, "Unknown membership type #{klass}" + end + + membership_type.save(:validate => false) + end + membership_type end - def create_order(parsed_row, person, membership_type) - #get order from hash - # for 0 to parsed_row.number_of_memberships - # create an item for this membership_type - #add the item to the order - #save the order - #update get_action - #hash order by order key (person, membership_type, payment_method) + def find_membership_type(parsed_row) + membership_type = MembershipType.where( + :name => parsed_row.membership_name, + :organization_id => self.organization.id + ).first + end + + def create_membership(parsed_row, member, membership_type) + membership = self.memberships.build + membership.organization = self.organization + membership.membership_type = membership_type + membership.member = member + membership.price = parsed_row.amount + membership.sold_price = parsed_row.amount + membership.cart_price = parsed_row.amount + membership.total_paid = parsed_row.amount + + membership.starts_at = DateTime.parse(parsed_row.start_date) + + case membership_type.type + when SeasonalMembershipType.to_s + membership.ends_at = DateTime.parse(parsed_row.end_date) + when RollingMembershipType.to_s + membership.ends_at = membership.starts_at + membership_type.duration_in_seconds + else + raise Import::RowError, "Failed to create a membership of type: #{membership_type}" + end + + membership.save! + membership + end + + def existing_order(person, membership_type, payment_method) + # lookup order ids: + # for membership(s): + # + of the same membership type + # + with the same payment method + # + and the same buyer + existing_orders = ImportedOrder.joins(:items).where orders: { + import_id: self.id, + person_id: person.id, + payment_method: payment_method + }, + + items: { + product_type: 'Membership', + product_id: membership_type.id + } + order = existing_orders.last + ImportedOrder.find(order.id) if order + end + + def create_order(parsed_row, person, member, membership_type) + order = existing_order(person, membership_type, parsed_row.payment_method) || ImportedOrder.new + + order.organization = self.organization + order.payment_method = parsed_row.payment_method + order.person = person + order.details = "Imported by #{user.email} on #{I18n.l self.created_at_local_to_organization, :format => :date}" + order.import = self + + product = create_membership(parsed_row, member, membership_type) + + item = Item.for(product, order) + item.state = "settled" + order.items << item + + order.skip_actions = true + order.save + unless parsed_row.order_date.blank? + date_in_zone = DateTime.parse(parsed_row.order_date) + order_date = date_in_zone - time_zone_parser.utc_offset.seconds + + order.update_attribute(:created_at, order_date) + end + + order.create_generic_action(:memberships, self.id) + order.actions.where(:type => 'GetAction').first.update_attribute(:occurred_at, order.created_at) + + order + end + + def detect_membership_type(type) + case type.to_s.downcase + when /seasonal/ + SeasonalMembershipType + when /rolling/ + RollingMembershipType + else + raise Import::RowError, "Unknown Membership Type: #{type}" + end + end + + def rollback + rollback_orders + rollback_actions + rollback_memberships + rollback_membership_types + rollback_people + end + + def rollback_members + Member.where(:import_id => self.id).destroy_all + end + + def rollback_memberships + Membership.where(:import_id => self.id).destroy_all + end + + def rollback_membership_types + MembershipType.where(:import_id => self.id).destroy_all + end + + def rollback_actions + Action.where(:import_id => self.id).destroy_all end end \ No newline at end of file