def delete_subcontribution(subcontrib):
    subcontrib.is_deleted = True
    db.session.flush()
    signals.event.subcontribution_deleted.send(subcontrib)
    logger.info('Subcontribution %s deleted by %s', subcontrib, session.user)
    subcontrib.event.log(
        EventLogRealm.management, EventLogKind.negative, 'Subcontributions',
        'Subcontribution "{}" has been deleted'.format(subcontrib.title),
        session.user)
def update_subcontribution(subcontrib, data):
    subcontrib.populate_from_dict(data)
    db.session.flush()
    signals.event.subcontribution_updated.send(subcontrib)
    logger.info('Subcontribution %s updated by %s', subcontrib, session.user)
    subcontrib.event.log(
        EventLogRealm.management, EventLogKind.change, 'Subcontributions',
        'Subcontribution "{}" has been updated'.format(subcontrib.title),
        session.user)
def delete_contribution(contrib):
    contrib.is_deleted = True
    if contrib.timetable_entry is not None:
        delete_timetable_entry(contrib.timetable_entry, log=False)
    db.session.flush()
    signals.event.contribution_deleted.send(contrib)
    logger.info('Contribution %s deleted by %s', contrib, session.user)
    contrib.event.log(
        EventLogRealm.management, EventLogKind.negative, 'Contributions',
        'Contribution "{}" has been deleted'.format(contrib.title),
        session.user)
def create_subcontribution(contrib, data):
    subcontrib = SubContribution()
    subcontrib.populate_from_dict(data)
    contrib.subcontributions.append(subcontrib)
    db.session.flush()
    signals.event.subcontribution_created.send(subcontrib)
    logger.info('Subcontribution %s created by %s', subcontrib, session.user)
    subcontrib.event.log(
        EventLogRealm.management, EventLogKind.positive, 'Subcontributions',
        'Subcontribution "{}" has been created'.format(subcontrib.title),
        session.user)
    return subcontrib
def update_contribution(contrib, contrib_data, custom_fields_data=None):
    """Update a contribution

    :param contrib: The `Contribution` to update
    :param contrib_data: A dict containing the data to update
    :param custom_fields_data: A dict containing the data for custom
                               fields.
    :return: A dictionary containing information related to the
             update.  `unscheduled` will be true if the modification
             resulted in the contribution being unscheduled.  In this
             case `undo_unschedule` contains the necessary data to
             re-schedule it (undoing the session change causing it to
             be unscheduled)
    """
    rv = {'unscheduled': False, 'undo_unschedule': None}
    current_session_block = contrib.session_block
    start_dt = contrib_data.pop('start_dt', None)
    if start_dt is not None:
        update_timetable_entry(contrib.timetable_entry, {'start_dt': start_dt})
    changes = contrib.populate_from_dict(contrib_data)
    if custom_fields_data:
        changes.update(set_custom_fields(contrib, custom_fields_data))
    if 'session' in contrib_data:
        timetable_entry = contrib.timetable_entry
        if timetable_entry is not None and _ensure_consistency(contrib):
            rv['unscheduled'] = True
            rv['undo_unschedule'] = {
                'start_dt':
                timetable_entry.start_dt.isoformat(),
                'contribution_id':
                contrib.id,
                'session_block_id':
                current_session_block.id if current_session_block else None,
                'force':
                True
            }
    db.session.flush()
    if changes:
        signals.event.contribution_updated.send(contrib, changes=changes)
        logger.info('Contribution %s updated by %s', contrib, session.user)
        contrib.event.log(
            EventLogRealm.management, EventLogKind.change, 'Contributions',
            'Contribution "{}" has been updated'.format(contrib.title),
            session.user)
    return rv
def create_contribution(event,
                        contrib_data,
                        custom_fields_data=None,
                        session_block=None,
                        extend_parent=False):
    start_dt = contrib_data.pop('start_dt', None)
    contrib = Contribution(event=event)
    contrib.populate_from_dict(contrib_data)
    if start_dt is not None:
        schedule_contribution(contrib,
                              start_dt=start_dt,
                              session_block=session_block,
                              extend_parent=extend_parent)
    if custom_fields_data:
        set_custom_fields(contrib, custom_fields_data)
    db.session.flush()
    signals.event.contribution_created.send(contrib)
    logger.info('Contribution %s created by %s', contrib, session.user)
    contrib.event.log(
        EventLogRealm.management, EventLogKind.positive, 'Contributions',
        'Contribution "{}" has been created'.format(contrib.title),
        session.user)
    return contrib