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