示例#1
0
文件: tasks.py 项目: eloyz/tendenci
    def run(self, memport, fields, **kwargs):
        """
        Require username or email address
        We use this to find the user record
        and membership record
        """
        from django.template.defaultfilters import slugify
        from tendenci.addons.memberships.utils import get_user

        payment_methods = {
            'cc': 1,
            'credit': 1,
            'credit card': 1,
            'check': 2,
            'cash': 3
        }

        app = memport.app
        file_path = os.path.join(settings.MEDIA_ROOT, memport.get_file().file.name)

        #get parsed membership dicts
        imported = []
        mems, stats = parse_mems_from_csv(
            file_path,
            fields,
            membership_import=memport
        )

        for m in mems:

            # membership type required
            if not m['membershiptype']:
                continue  # on to the next one

            # username or email required
            if not any([m['username'], m['email']]):
                continue  # on to the next one

            if m['status__action'] != 'skip':
                membership_type = MembershipType.objects.get(name=m['membershiptype'])

                # initialize dates
                expire_dt = m['expiredt']
                subscribe_dt = m['subscribedt']

                # get payment method id; assumes default payment methods
                payment_method = slugify(m.get('paymentmethod', '')).replace('-', '')
                payment_method_id = payment_methods.get(payment_method)

                # returns None if a user was not found
                # returns the first user made if multiple are returned
                user = None

                if m['username']:
                    user = get_user(username=m['username'])

                if not user:
                    try:  # we make you a username via your email
                        m['username'] = spawn_username(m['email'])
                        user = User.objects.create_user(m['username'], m['email'])
                    except:
                        # username already exists
                        continue  # on to the next one

                # get or create profile
                try:
                    profile = Profile.objects.get(user=user)
                except Profile.MultipleObjectsReturned:
                    profile = Profile.objects.filter(user=user)[0]
                except Profile.DoesNotExist:
                    profile = Profile.objects.create_profile(user)

                # update user and profile object with imported information
                if memport.override:
                    user.first_name = m.get('firstname', '') or user.first_name
                    user.last_name = m.get('lastname', '') or user.last_name
                    user.email = m['email'] or user.email
                    profile.company = m.get('company', '') or profile.company
                    profile.position_title = m.get('positiontitle', '') or profile.position_title
                    profile.address = m.get('mailingaddress', '') or profile.address
                    profile.address2 = m.get('address2', '') or profile.address2
                    profile.city = m.get('city', '') or profile.city
                    profile.state = m.get('state', '') or profile.state
                    profile.zipcode = m.get('zipcode', '') or profile.zipcode
                    profile.county = m.get('county', '') or profile.county
                    profile.address_type = m.get('addresstype', '') or profile.address_type
                    profile.work_phone = m.get('workphone', '') or profile.work_phone
                    profile.home_phone = m.get('homephone', '') or profile.home_phone
                    profile.mobile_phone = m.get('mobilephone', '') or profile.mobile_phone
                    profile.email2 = m.get('email2', '') or profile.email2
                    profile.url = m.get('website', '') or profile.url
                    profile.dob = dt_parse(m.get('dob', ''))
                else:
                    user.first_name = user.first_name or m['firstname']
                    user.last_name = user.last_name or m['lastname']
                    user.email = user.email or m['email']
                    profile.company = profile.company or m.get('company', '')
                    profile.position_title = profile.position_title or m.get('positiontitle', '')
                    profile.address = profile.address or m.get('mailingaddress', '')
                    profile.address2 = profile.address2 or m.get('address2', '')
                    profile.city = profile.city or m.get('city', '')
                    profile.state = profile.state or m.get('state', '')
                    profile.zipcode = profile.zipcode or m.get('zipcode', '')
                    profile.country = profile.county or m.get('county', '')
                    profile.address_type = profile.address_type or m.get('addresstype', '')
                    profile.work_phone = profile.work_phone or m.get('workphone', '')
                    profile.home_phone = profile.home_phone or m.get('homephone', '')
                    profile.mobile_phone = profile.mobile_phone or m.get('mobilephone', '')
                    profile.email2 = profile.email2 or m.get('email2', '')
                    profile.url = profile.url or m.get('website', '')
                    profile.dob = profile.dob or dt_parse(m.get('dob', ''))

                user.save()
                profile.save()

                if expire_dt > datetime.now():
                    # if expiration date after today
                    # then look for active memberships
                    memberships = Membership.objects.active(
                        user=user,
                        membership_type=membership_type,
                    ).order_by('-pk')  # newest on top
                else:
                    # if expiration date before today
                    # then look for inactive memberships
                    memberships = Membership.objects.expired(
                        user=user,
                        membership_type=membership_type,
                    ).order_by('-pk')  # newest on top

                if memberships:
                    membership = memberships[0]

                    if memport.override:
                        membership.member_number = m.get('membernumber') or membership.member_number
                        membership.subscribe_dt = subscribe_dt or membership.subscribe_dt
                        membership.expire_dt = expire_dt or membership.expire_dt

                else:
                    membership = Membership()
                    membership.ma = app
                    membership.user = user
                    membership.membership_type = membership_type
                    membership.member_number = m.get('membernumber') or 0
                    membership.owner = user
                    membership.creator = user
                    membership.subscribe_dt = subscribe_dt
                    membership.payment_method_id = payment_method_id
                    membership.renewal = m.get('renewal')
                    membership.status = m.get('status') or True
                    membership.status_detail = m.get('statusdetail') or 'Active'
                    membership.expire_dt = expire_dt

                membership.save()  # update_dt changes
                profile.refresh_member_number()

                # bind corporate membership with membership if it exists
                corp_memb_name = m.get('corpmembershipname')
                if corp_memb_name:
                    try:
                        corp_memb = CorporateMembership.objects.get(name=corp_memb_name)
                        membership.membership_type = corp_memb.corporate_membership_type.membership_type
                        membership.corporate_membership_id = corp_memb.pk
                        membership.save()
                    except CorporateMembership.DoesNotExist:
                        pass

                entry = membership.get_entry()

                if not entry:
                    entry = AppEntry.objects.create(
                        app=app,
                        user=membership.user,
                        entry_time=datetime.now(),
                        membership=membership,  # pk required here
                        is_renewal=membership.renewal,
                        is_approved=True,
                        decision_dt=membership.subscribe_dt,
                        judge=membership.creator,
                        creator=membership.creator,
                        creator_username=membership.creator_username,
                        owner=membership.owner,
                        owner_username=membership.owner_username,
                        allow_anonymous_view=False,
                    )

                entry_dict = {}  # entry pk and value
                field_dict = {}
                for field in entry.fields.all():
                    entry_dict[field.field.label] = {
                        'item': field,
                        'field': field.field,
                        'value': field.value.strip()
                        }
                    field_dict[field.field.label] = field.field

                # get a concise list of all app fields
                app_fields = AppField.objects.filter(app=app)
                for field in app_fields:

                    entry_field = entry_dict.get(field.label, {})

                    entry_dict[field.label] = {
                        'item': entry_field.get('item'),  # default: None
                        'field': entry_field.get('field'),  # default: None
                        'value': entry_field.get('value', u'').strip()
                    }
                    field_dict[field.label] = field

                # [finally] loop through all entry items
                # setting values from csv and saving entry items
                for k, d in entry_dict.items():

                    entry_item = d['item'] or AppFieldEntry()
                    field_name = slugify(k).replace('-', '')
                    field_name = clean_field_name(field_name).replace('_', '').strip()
                    imported_value = m.get(field_name, u'')

                    if isinstance(imported_value, basestring):
                        imported_value = imported_value.strip()

                    if not entry_item.pk:
                        entry_item.entry = entry
                        entry_item.field = field_dict[k]

                    if memport.override:
                        # update all fields (if csv has value)
                        entry_item.value = imported_value or d['value']
                    else:
                        # update blank fields
                        entry_item.value = d['value'] or imported_value

                    # save will either create or update
                    # depending if a pk is available
                    entry_item.save()

                # update membership number
                if not membership.member_number:
                    # all of this to get the largest membership number
                    newest_membership = Membership.objects.order_by('-pk')
                    if newest_membership:
                        membership.member_number = newest_membership[0].pk + 1000
                    else:
                        membership.member_number = 1000

                    membership.save()

                # add user to group
                membership.membership_type.group.add_user(membership.user)

                # append to imported list
                imported.append(membership)

        return imported, stats
示例#2
0
    def run(self, memport, fields, **kwargs):
        """
        Require username or email address
        We use this to find the user record
        and membership record
        """
        from django.template.defaultfilters import slugify
        from tendenci.addons.memberships.utils import get_user

        payment_methods = {
            'cc': 1,
            'credit': 1,
            'credit card': 1,
            'check': 2,
            'cash': 3
        }

        app = memport.app
        file_path = os.path.join(memport.get_file().file.name)

        #get parsed membership dicts
        imported = []
        mems, stats = parse_mems_from_csv(
            file_path,
            fields,
            membership_import=memport
        )

        for m in mems:

            # membership type required
            if not m['membershiptype']:
                continue  # on to the next one

            # username or email required
            if not any([m['username'], m['email']]):
                continue  # on to the next one

            if m['status__action'] != 'skip':
                membership_type = MembershipType.objects.get(name=m['membershiptype'])

                # initialize dates
                expire_dt = m['expiredt']
                subscribe_dt = m['subscribedt']

                # get payment method id; assumes default payment methods
                payment_method = slugify(m.get('paymentmethod', '')).replace('-', '')
                payment_method_id = payment_methods.get(payment_method)

                # returns None if a user was not found
                # returns the first user made if multiple are returned
                user = None

                if m['username']:
                    user = get_user(username=m['username'])

                if not user:
                    try:  # we make you a username via your email
                        m['username'] = spawn_username(m['email'])
                        user = User.objects.create_user(m['username'], m['email'])
                    except:
                        # username already exists
                        continue  # on to the next one

                # get or create profile
                try:
                    profile = Profile.objects.get(user=user)
                except Profile.MultipleObjectsReturned:
                    profile = Profile.objects.filter(user=user)[0]
                except Profile.DoesNotExist:
                    profile = Profile.objects.create_profile(user)

                # update user and profile object with imported information
                if memport.override:
                    user.first_name = m.get('firstname', '') or user.first_name
                    user.last_name = m.get('lastname', '') or user.last_name
                    user.email = m['email'] or user.email
                    profile.company = m.get('company', '') or profile.company
                    profile.position_title = m.get('positiontitle', '') or profile.position_title
                    profile.address = m.get('mailingaddress', '') or profile.address
                    profile.address2 = m.get('address2', '') or profile.address2
                    profile.city = m.get('city', '') or profile.city
                    profile.state = m.get('state', '') or profile.state
                    profile.zipcode = m.get('zipcode', '') or profile.zipcode
                    profile.county = m.get('county', '') or profile.county
                    profile.address_type = m.get('addresstype', '') or profile.address_type
                    profile.work_phone = m.get('workphone', '') or profile.work_phone
                    profile.home_phone = m.get('homephone', '') or profile.home_phone
                    profile.mobile_phone = m.get('mobilephone', '') or profile.mobile_phone
                    profile.email2 = m.get('email2', '') or profile.email2
                    profile.url = m.get('website', '') or profile.url
                    profile.dob = dt_parse(m.get('dob', ''))
                else:
                    user.first_name = user.first_name or m['firstname']
                    user.last_name = user.last_name or m['lastname']
                    user.email = user.email or m['email']
                    profile.company = profile.company or m.get('company', '')
                    profile.position_title = profile.position_title or m.get('positiontitle', '')
                    profile.address = profile.address or m.get('mailingaddress', '')
                    profile.address2 = profile.address2 or m.get('address2', '')
                    profile.city = profile.city or m.get('city', '')
                    profile.state = profile.state or m.get('state', '')
                    profile.zipcode = profile.zipcode or m.get('zipcode', '')
                    profile.country = profile.county or m.get('county', '')
                    profile.address_type = profile.address_type or m.get('addresstype', '')
                    profile.work_phone = profile.work_phone or m.get('workphone', '')
                    profile.home_phone = profile.home_phone or m.get('homephone', '')
                    profile.mobile_phone = profile.mobile_phone or m.get('mobilephone', '')
                    profile.email2 = profile.email2 or m.get('email2', '')
                    profile.url = profile.url or m.get('website', '')
                    profile.dob = profile.dob or dt_parse(m.get('dob', ''))

                user.save()
                profile.save()

                if expire_dt > datetime.now():
                    # if expiration date after today
                    # then look for active memberships
                    memberships = Membership.objects.active(
                        user=user,
                        membership_type=membership_type,
                    ).order_by('-pk')  # newest on top
                else:
                    # if expiration date before today
                    # then look for inactive memberships
                    memberships = Membership.objects.expired(
                        user=user,
                        membership_type=membership_type,
                    ).order_by('-pk')  # newest on top

                if memberships:
                    membership = memberships[0]

                    if memport.override:
                        membership.member_number = m.get('membernumber') or membership.member_number
                        membership.subscribe_dt = subscribe_dt or membership.subscribe_dt
                        membership.expire_dt = expire_dt or membership.expire_dt

                else:
                    membership = Membership()
                    membership.ma = app
                    membership.user = user
                    membership.membership_type = membership_type
                    membership.member_number = m.get('membernumber') or 0
                    membership.owner = user
                    membership.creator = user
                    membership.subscribe_dt = subscribe_dt
                    membership.payment_method_id = payment_method_id
                    membership.renewal = m.get('renewal')
                    membership.status = m.get('status') or True
                    membership.status_detail = m.get('statusdetail') or 'Active'
                    membership.expire_dt = expire_dt

                membership.save()  # update_dt changes
                profile.refresh_member_number()

                # bind corporate membership with membership if it exists
                corp_memb_name = m.get('corpmembershipname')
                if corp_memb_name:
                    try:
                        corp_memb = CorporateMembership.objects.get(name=corp_memb_name)
                        membership.membership_type = corp_memb.corporate_membership_type.membership_type
                        membership.corporate_membership_id = corp_memb.pk
                        membership.save()
                    except CorporateMembership.DoesNotExist:
                        pass

                entry = membership.get_entry()

                if not entry:
                    entry = AppEntry.objects.create(
                        app=app,
                        user=membership.user,
                        entry_time=datetime.now(),
                        membership=membership,  # pk required here
                        is_renewal=membership.renewal,
                        is_approved=True,
                        decision_dt=membership.subscribe_dt,
                        judge=membership.creator,
                        creator=membership.creator,
                        creator_username=membership.creator_username,
                        owner=membership.owner,
                        owner_username=membership.owner_username,
                        allow_anonymous_view=False,
                    )

                entry_dict = {}  # entry pk and value
                field_dict = {}
                for field in entry.fields.all():
                    entry_dict[field.field.label] = {
                        'item': field,
                        'field': field.field,
                        'value': field.value.strip()
                        }
                    field_dict[field.field.label] = field.field

                # get a concise list of all app fields
                app_fields = AppField.objects.filter(app=app)
                for field in app_fields:

                    entry_field = entry_dict.get(field.label, {})

                    entry_dict[field.label] = {
                        'item': entry_field.get('item'),  # default: None
                        'field': entry_field.get('field'),  # default: None
                        'value': entry_field.get('value', u'').strip()
                    }
                    field_dict[field.label] = field

                # [finally] loop through all entry items
                # setting values from csv and saving entry items
                for k, d in entry_dict.items():

                    entry_item = d['item'] or AppFieldEntry()
                    field_name = slugify(k).replace('-', '')
                    field_name = clean_field_name(field_name).replace('_', '').strip()
                    imported_value = m.get(field_name, u'')

                    if isinstance(imported_value, basestring):
                        imported_value = imported_value.strip()

                    if not entry_item.pk:
                        entry_item.entry = entry
                        entry_item.field = field_dict[k]

                    if memport.override:
                        # update all fields (if csv has value)
                        entry_item.value = imported_value or d['value']
                    else:
                        # update blank fields
                        entry_item.value = d['value'] or imported_value

                    # save will either create or update
                    # depending if a pk is available
                    entry_item.save()

                # update membership number
                if not membership.member_number:
                    # all of this to get the largest membership number
                    newest_membership = Membership.objects.order_by('-pk')
                    if newest_membership:
                        membership.member_number = newest_membership[0].pk + 1000
                    else:
                        membership.member_number = 1000

                    membership.save()

                # add user to group
                membership.membership_type.group.add_user(membership.user)

                # append to imported list
                imported.append(membership)

        return imported, stats
示例#3
0
文件: utils.py 项目: zenny/tendenci
def parse_mems_from_csv(file_path, mapping, **kwargs):
    """
    Returns membership dictionary and stats dictionary

    stats:
        all, added, skipped

    memberships:
        username, fn, ln, email,
        join dt, renew dt, expire dt,
        added, skipped, renewal
    """
    # initialize membership import settings
    membership_import = kwargs['membership_import']
    key = membership_import.key  # for determining duplicates
    override = membership_import.override  # override changed fields

    if override:
        update_override = 'override'
    else:
        update_override = 'update'

    csv_dicts = csv_to_dict(file_path, machine_name=True)

    # membership lists
    total = []
    added = []
    updated = []
    skipped = []

    for csv_dict in csv_dicts:  # field mapping

        # set up field mapping
        m = {}
        for app_field, csv_field in mapping.items():
            if csv_field:  # skip blank option
                # membership['username'] = '******'
                m[clean_field_name(app_field)] = csv_dict.get(csv_field, '')

        # remove empty keys
        m = dict([(k, v) for k, v in m.items() if len(v) > 0])

        if not m:  # empty row in imported file
            continue  # on to the next one

        user_keys = ['username', 'firstname', 'lastname', 'email']
        for user_key in user_keys:
            m[user_key] = m.get(user_key, '')
        null_date = datetime(1951, 1, 1)
        date_keys = ['joindate', 'renewdate', 'expiredate', 'joindt', 'renewdt', 'expiredt']
        for date_key in date_keys:
            m[date_key] = m.get(date_key)

        m['renewal'] = bool(m['renewdate'])
        m['status__action'] = 'add'

        # set up user kwargs from mapping
        keys = {}
        for i in key.split(','):
            keys[i] = m[i.replace('_', '')]

        if 'username' in kwargs:
            kwargs['username'] = kwargs['username'][:30]

        # remove empty keys
        keys = dict( [(k,v) for k,v in keys.items() if len(v)>0])

        user = None
        if 'member_number' in keys:
            membership = Membership.objects.first(**keys)
            user = membership.user
        elif keys:  # first name, last name, email
            user = get_user(**keys)

        if not user and m['username']:
            user = get_user(username=m['username'][:30])

        # if a user is found, determine if override or update
        if user:
            if override:
                m['status__action'] = update_override
                m['username'] = m['username'] or user.username
                m['firstname'] = m['firstname'] or user.first_name
                m['lastname'] = m['lastname'] or user.last_name
                m['email'] = m['email'] or user.email
            else:
                m['status__action'] = update_override
                m['username'] = user.username or m['username']
                m['firstname'] = user.first_name or m['firstname']
                m['lastname'] = user.last_name or m['lastname']
                m['email'] = user.email or m['email']

        # set up user's fullname
        m['fullname'] = "%s %s" % (m.get('firstname', ''), m.get('lastname', ''))
        m['fullname'] = m['fullname'].strip()

        # check if the membership type is valid
        try:
            membership_type = MembershipType.objects.get(name=m.get('membershiptype', ''))
        except MembershipType.DoesNotExist:
            # skip if it does not exist
            m['status__action'] = 'skip'
            m['status__reason'] = 'invalid membership type'
            membership_type = None

        # if it's not skipped yet
        if m['status__action'] != 'skip':
            # check if there is a corresponding user or an email
            if not user and not m['email']:  # email required to create user
                m['status__action'] = 'skip'

        # if it's still not skipped
        if m['status__action'] != 'skip':
            # check if membership already exists
            if membership_type and user:
                membership_exists = Membership.objects.active(
                    user=user, membership_type=membership_type).exists()
                # check if this is the first instance of the same key
                if is_duplicate(csv_dict, csv_dicts, key):
                    m['status__action'] = 'skip'
                    m['status__reason'] = 'duplicate'
                # consider as update if already exists and is not yet skipped
                if membership_exists and m['status__action'] != 'skip':
                    m['status__action'] = update_override

        if m['joindate']:
            dt = dt_parse(m['joindate'])
            if dt > null_date:
                m['joindt'] = dt

        if m['renewdate']:
            dt = dt_parse(m['renewdate'])
            if dt > null_date:
                m['renewdt'] = dt

        if m['expiredate']:
            m['expiredt'] = dt_parse(m['expiredate'])

        if not m['expiredt']:
            if membership_type:
                m['expiredt'] = membership_type.get_expiration_dt(
                    join_dt=m['joindt'],
                    renew_dt=m['renewdt'],
                    renewal=m['renewal']
                )

        m['subscribedt'] = m['joindt'] or datetime.now()

        # make lists of memberships
        total.append(m)
        if m['status__action'] == 'skip':
            skipped.append(m)
        elif m['status__action'] == 'add':
            added.append(m)
        elif m['status__action'] == update_override:
            updated.append(m)

    stats = {
        'all': len(total),
        'skipped': len(skipped),
        'added': len(added),
        'updated': len(updated),
    }

    # return "total" list of memberships & stats
    return total, stats