Esempio n. 1
0
 def _clone_registrations(self, old_form, new_form, field_data_map):
     registration_attrs = get_simple_column_attrs(Registration) - {
         'uuid', 'ticket_uuid'
     }
     for old_registration in old_form.registrations:
         if old_registration.is_deleted:
             continue
         new_registration = Registration(user=old_registration.user,
                                         registration_form=new_form,
                                         **{
                                             attr: getattr(
                                                 old_registration, attr)
                                             for attr in registration_attrs
                                         })
         reg_data_attrs = get_simple_column_attrs(RegistrationData) - {
             'storage_file_id', 'storage_backend', 'size'
         }
         for old_registration_data in old_registration.data:
             new_registration_data = RegistrationData(
                 registration=new_registration,
                 **{
                     attr: getattr(old_registration_data, attr)
                     for attr in reg_data_attrs
                 })
             new_registration_data.field_data = field_data_map[
                 old_registration_data.field_data]
             if old_registration_data.storage_file_id is not None:
                 with old_registration_data.open() as fd:
                     new_registration_data.save(fd)
         db.session.flush()
         signals.event.registration_state_updated.send(new_registration)
Esempio n. 2
0
def test_multi_choice_field_process_form_data_price_change_deselected(
        multi_choice_field):
    # reg linked to old version, a currently selected item had its price changed and another changed
    # item was deselected.
    # field data should be upgraded to a new version containing both the new items and the old-priced one
    multi_choice_field.versioned_data = _update_data(
        multi_choice_field.versioned_data, {
            _id(2): {
                'is_billable': True,
                'price': 100
            },
            _id(3): {
                'price': 500
            }
        })
    old_version = multi_choice_field.current_data
    old_data = RegistrationData(field_data=old_version,
                                data={
                                    _id(2): 1,
                                    _id(3): 1
                                })
    assert old_data.price == 600
    multi_choice_field.versioned_data = _update_data(
        multi_choice_field.versioned_data, {
            _id(2): {
                'price': 10
            },
            _id(3): {
                'price': 50
            }
        })
    form_data = {_id(3): 1}
    rv = multi_choice_field.field_impl.process_form_data(
        None, form_data, old_data)
    assert rv['field_data'] not in {
        multi_choice_field.current_data, old_version
    }
    assert rv['data'] == form_data
    new_data = RegistrationData(**rv)
    assert new_data.price == 500
    old_choices = old_version.versioned_data['choices']
    new_choices = multi_choice_field.versioned_data['choices']
    combined = [old_choices[-1]] + new_choices[:-1]
    _assert_same_choices(rv['field_data'].versioned_data['choices'], combined)
    # now we re-check the previously deselected option and should get the NEW price
    form_data = {_id(2): 1, _id(3): 1}
    rv = multi_choice_field.field_impl.process_form_data(
        None, form_data, new_data)
    assert RegistrationData(**rv).price == 510
Esempio n. 3
0
def create_registration(regform, data, invitation=None, management=False, notify_user=True):
    registration = Registration(registration_form=regform, user=get_user_by_email(data['email']),
                                base_price=regform.base_price, currency=regform.currency)
    for form_item in regform.active_fields:
        if form_item.parent.is_manager_only:
            with db.session.no_autoflush:
                value = form_item.field_impl.default_value
        else:
            value = data.get(form_item.html_field_name)
        with db.session.no_autoflush:
            data_entry = RegistrationData()
            registration.data.append(data_entry)
            for attr, value in form_item.field_impl.process_form_data(registration, value).iteritems():
                setattr(data_entry, attr, value)
        if form_item.type == RegistrationFormItemType.field_pd and form_item.personal_data_type.column:
            setattr(registration, form_item.personal_data_type.column, value)
    if invitation is None:
        # Associate invitation based on email in case the user did not use the link
        with db.session.no_autoflush:
            invitation = (RegistrationInvitation
                          .find(email=data['email'], registration_id=None)
                          .with_parent(regform)
                          .first())
    if invitation:
        invitation.state = InvitationState.accepted
        invitation.registration = registration
    registration.sync_state(_skip_moderation=management)
    db.session.flush()
    notify_registration_creation(registration, notify_user)
    logger.info('New registration %s by %s', registration, session.user)
    regform.event.log(EventLogRealm.management if management else EventLogRealm.participants,
                      EventLogKind.positive, 'Registration',
                      'New registration: {}'.format(registration.full_name),
                      session.user, data={'Email': registration.email})
    return registration
Esempio n. 4
0
 def _get_registration_data(self, field):
     registration_ids = [
         r.id for r in field.registration_form.active_registrations
     ]
     field_data_ids = [data.id for data in field.data_versions]
     return RegistrationData.find_all(
         RegistrationData.registration_id.in_(registration_ids),
         RegistrationData.field_data_id.in_(field_data_ids),
         RegistrationData.data != {})
Esempio n. 5
0
def test_multi_choice_field_process_form_data_current_version(
        multi_choice_field):
    # nothing changed
    old_data = RegistrationData(field_data=multi_choice_field.current_data,
                                data={
                                    _id(1): 1,
                                    _id(2): 1
                                })
    form_data = {_id(1): 1, _id(2): 1}
    assert multi_choice_field.field_impl.process_form_data(
        None, form_data, old_data) == {}
Esempio n. 6
0
def test_multi_choice_field_process_form_data_item_removed(multi_choice_field):
    # reg linked to old version, one selected item removed from there
    # in this case everything should remain linked to the old version
    old_version = multi_choice_field.current_data
    old_data = RegistrationData(field_data=old_version,
                                data={
                                    _id(1): 1,
                                    _id(2): 1
                                })
    multi_choice_field.versioned_data = _update_data(
        multi_choice_field.versioned_data, {_id(1): None})
    form_data = {_id(1): 1, _id(2): 1}
    assert multi_choice_field.field_impl.process_form_data(
        None, form_data, old_data) == {}
Esempio n. 7
0
def modify_registration(registration, data, management=False, notify_user=True):
    old_price = registration.price
    personal_data_changes = {}
    with db.session.no_autoflush:
        regform = registration.registration_form
        data_by_field = registration.data_by_field
        if management or not registration.user:
            registration.user = get_user_by_email(data['email'])

        billable_items_locked = not management and registration.is_paid
        for form_item in regform.active_fields:
            field_impl = form_item.field_impl
            if management or not form_item.parent.is_manager_only:
                value = data.get(form_item.html_field_name)
            elif form_item.id not in data_by_field:
                # set default value for manager-only field if it didn't have one before
                value = field_impl.default_value
            else:
                # manager-only field that has data which should be preserved
                continue

            if form_item.id not in data_by_field:
                data_by_field[form_item.id] = RegistrationData(registration=registration,
                                                               field_data=form_item.current_data)

            attrs = field_impl.process_form_data(registration, value, data_by_field[form_item.id],
                                                 billable_items_locked=billable_items_locked)
            for key, val in attrs.iteritems():
                setattr(data_by_field[form_item.id], key, val)
            if form_item.type == RegistrationFormItemType.field_pd and form_item.personal_data_type.column:
                key = form_item.personal_data_type.column
                if getattr(registration, key) != value:
                    personal_data_changes[key] = value
                setattr(registration, key, value)
        registration.sync_state()
    db.session.flush()
    # sanity check
    if billable_items_locked and old_price != registration.price:
        raise Exception("There was an error while modifying your registration (price mismatch: %s / %s)",
                        old_price, registration.price)
    if personal_data_changes:
        signals.event.registration_personal_data_modified.send(registration, change=personal_data_changes)
    notify_registration_modification(registration, notify_user)
    logger.info('Registration %s modified by %s', registration, session.user)
    regform.event.log(EventLogRealm.management if management else EventLogRealm.participants,
                      EventLogKind.change, 'Registration',
                      'Registration modified: {}'.format(registration.full_name),
                      session.user, data={'Email': registration.email})
Esempio n. 8
0
def test_multi_choice_field_process_form_data_old_version(multi_choice_field):
    # reg linked to old version, price changed in new version, nothing changed
    # in this case everything should remain linked to the old version
    old_version = multi_choice_field.current_data
    old_data = RegistrationData(field_data=old_version,
                                data={
                                    _id(2): 1,
                                    _id(3): 1
                                })
    multi_choice_field.versioned_data = _update_data(
        multi_choice_field.versioned_data, {_id(3): {
                                                'price': 1000
                                            }})
    form_data = {_id(2): 1, _id(3): 1}
    assert multi_choice_field.field_impl.process_form_data(
        None, form_data, old_data) == {}
Esempio n. 9
0
def test_multi_choice_field_process_form_data_item_removed_deselected(
        multi_choice_field):
    # reg linked to old version, one selected item removed from there and deselected
    # since all other items are available in the latest version we upgrade to it
    old_version = multi_choice_field.current_data
    old_data = RegistrationData(field_data=old_version,
                                data={
                                    _id(1): 1,
                                    _id(2): 1
                                })
    multi_choice_field.versioned_data = _update_data(
        multi_choice_field.versioned_data, {_id(1): None})
    form_data = {_id(2): 1}
    rv = multi_choice_field.field_impl.process_form_data(
        None, form_data, old_data)
    assert rv['field_data'] == multi_choice_field.current_data
    assert rv['data'] == form_data
Esempio n. 10
0
def test_multi_choice_field_process_form_data_only_new(multi_choice_field):
    # reg linked to old version, but all old items deselected
    # field data should be upgraded to the current version
    old_version = multi_choice_field.current_data
    old_data = RegistrationData(field_data=old_version,
                                data={
                                    _id(1): 1,
                                    _id(2): 1
                                })
    multi_choice_field.versioned_data = _update_data(
        multi_choice_field.versioned_data, {
            _id(1): None,
            _id(4): {}
        })
    form_data = {_id(4): 1}
    rv = multi_choice_field.field_impl.process_form_data(
        None, form_data, old_data)
    assert rv['field_data'] == multi_choice_field.current_data
    assert rv['data'] == form_data
Esempio n. 11
0
def test_multi_choice_field_process_form_data_mixed(multi_choice_field):
    # reg linked to old version, a currently selected item was deleted and a new item is selected
    # field data should be upgraded to a new version containing both the new items and the deleted one
    old_version = multi_choice_field.current_data
    old_data = RegistrationData(field_data=old_version, data={_id(1): 1})
    multi_choice_field.versioned_data = _update_data(
        multi_choice_field.versioned_data, {
            _id(1): None,
            _id(4): {}
        })
    form_data = {_id(1): 1, _id(4): 1}
    rv = multi_choice_field.field_impl.process_form_data(
        None, form_data, old_data)
    assert rv['field_data'] not in {
        multi_choice_field.current_data, old_version
    }
    assert rv['data'] == form_data
    combined = multi_choice_field.versioned_data['choices'] + [
        old_version.versioned_data['choices'][0]
    ]
    _assert_same_choices(rv['field_data'].versioned_data['choices'], combined)
Esempio n. 12
0
def test_multi_choice_field_process_form_data_mixed_price_change(
        multi_choice_field):
    # reg linked to old version, a currently selected item had its price changed and a new item is selected
    # field data should be upgraded to a new version containing both the new items and the old-priced one
    old_version = multi_choice_field.current_data
    old_data = RegistrationData(field_data=old_version, data={_id(3): 1})
    multi_choice_field.versioned_data = _update_data(
        multi_choice_field.versioned_data, {
            _id(3): {
                'price': 1000
            },
            _id(4): {}
        })
    form_data = {_id(3): 1, _id(4): 1}
    rv = multi_choice_field.field_impl.process_form_data(
        None, form_data, old_data)
    assert rv['field_data'] not in {
        multi_choice_field.current_data, old_version
    }
    assert rv['data'] == form_data
    old_choices = old_version.versioned_data['choices']
    new_choices = multi_choice_field.versioned_data['choices']
    combined = new_choices[:2] + [old_choices[2]] + [new_choices[-1]]
    _assert_same_choices(rv['field_data'].versioned_data['choices'], combined)