def confirm_ill_extension(ill_loan_cycle):
    """Confirm the requested extension for the given inter library loan.

    The end_date and desired_end_date attributes will be adjusted.
    'extension_requested' will be removed from additional_statuses.
    :raise: ValidationExceptions
    """
    try:
        try_confirm_ill_extension(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ser = IllLoanCycle.STATUS_EXTENSION_REQUESTED
    ill_loan_cycle.end_date = ill_loan_cycle.desired_end_date
    ill_loan_cycle.desired_end_date = None
    ill_loan_cycle.additional_statuses.remove(ser)
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_EXTENSION_CONFIRMED)

    email_notification('ill_extension_request_confirmed',
                       '*****@*****.**',
                       ill_loan_cycle.user.email,
                       loan_cycle=ill_loan_cycle)
def decline_ill_extension(ill_loan_cycle, reason=''):
    """Decline the requested extension for the given inter library loan.

    'extension_requested' will be removed from additional_statuses.
    The desired_end_date will be set to None.
    :raise: ValidationExceptions
    """
    try:
        try_decline_ill_extension(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ser = IllLoanCycle.STATUS_EXTENSION_REQUESTED
    ill_loan_cycle.desired_end_date = None
    ill_loan_cycle.additional_statuses.remove(ser)
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_EXTENSION_DECLINED,
                 description=reason)

    email_notification('ill_extension_request_declined',
                       '*****@*****.**',
                       ill_loan_cycle.user.email,
                       loan_cycle=ill_loan_cycle)
def deliver_ill(ill_loan_cycle):
    """Deliver the given inter library loan.

    The items current_status will be set to 'on_loan'.
    The ill_loan_cycles current_status will be set to 'on_loan'.
    :raise: ValidationExceptions
    """
    try:
        try_deliver_ill(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    import invenio_circulation.models as models

    ill_loan_cycle.current_status = IllLoanCycle.STATUS_ON_LOAN
    ill_loan_cycle.save()

    ill_loan_cycle.item.current_status = models.CirculationItem.STATUS_ON_LOAN
    ill_loan_cycle.item.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_DELIVERED)

    email_notification('ill_delivery',
                       '*****@*****.**',
                       ill_loan_cycle.user.email,
                       ill_loan_cycle=ill_loan_cycle)
def deliver_ill(ill_loan_cycle):
    """Deliver the given inter library loan.

    The items current_status will be set to 'on_loan'.
    The ill_loan_cycles current_status will be set to 'on_loan'.
    :raise: ValidationExceptions
    """
    try:
        try_deliver_ill(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    import invenio_circulation.models as models

    ill_loan_cycle.current_status = IllLoanCycle.STATUS_ON_LOAN
    ill_loan_cycle.save()

    ill_loan_cycle.item.current_status = models.CirculationItem.STATUS_ON_LOAN
    ill_loan_cycle.item.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_DELIVERED)

    email_notification('ill_delivery', '*****@*****.**',
                       ill_loan_cycle.user.email,
                       ill_loan_cycle=ill_loan_cycle)
def confirm_ill_request(ill_loan_cycle, supplier_id, comments=''):
    """Confirm the given inter library loan request.

    The ill_loan_cycles current_status will be set to 'ordered'.

    :param supplier_id: Id of the chosen IllSupplier.

    :raise: ValidationExceptions
    """
    try:
        try_confirm_ill_request(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ill_loan_cycle.current_status = IllLoanCycle.STATUS_ORDERED
    ill_loan_cycle.supplier_id = supplier_id
    ill_loan_cycle.comments = comments
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_ORDERED)

    email_notification('ill_ordered',
                       '*****@*****.**',
                       ill_loan_cycle.user.email,
                       ill_loan_cycle=ill_loan_cycle)
def request_acquisition(user, record, acquisition_type, copies,
                        payment_method, budget_code='', price='',
                        delivery=None, comments=''):
    if not delivery:
        delivery = AcquisitionLoanCycle.DELIVERY_DEFAULT

    item = _create_acquisition_temporary_item(record)

    acquisition_clc = AcquisitionLoanCycle.new(
            current_status=AcquisitionLoanCycle.STATUS_REQUESTED,
            item=item, user=user,
            acquisition_type=acquisition_type,
            copies=copies,
            payment_method=payment_method,
            budget_code=budget_code,
            price=price,
            delivery=delivery,
            comments=comments,
            issued_date=datetime.datetime.now())

    if acquisition_type == 'acquisition':
        event = AcquisitionLoanCycle.EVENT_ACQUISITION_REQUEST
    elif acquisition_type == 'purchase':
        event = AcquisitionLoanCycle.EVENT_PURCHASE_REQUEST

    create_event(user_id=user.id, item_id=item.id,
                 acquisition_loan_cycle_id=acquisition_clc.id,
                 event=event)

    email_notification('acquisition_request', '*****@*****.**', user.email,
                       name=user.name, action='requested', items=item)

    return acquisition_clc
def request_ill(user, record, start_date, end_date,
                delivery=None, comments='', type=None):
    """Request inter library loan for the given record to the given user.

    :param record: Invenio Record.
    :param user: CirculationUser.
    :param start_date: Start date of the loan (without time).
    :param end_date: End date of the loan (without time).
    :param delivery: 'pick_up' or 'internal_mail'
    :param comments: Comments regarding the inter library loan.

    :return: Created IllLoanCycle
    """
    delivery = IllLoanCycle.DELIVERY_DEFAULT if delivery is None else delivery
    type = IllLoanCycle.TYPE_BOOK if type is None else type

    item = _create_ill_temporary_item(record)

    ill_clc = IllLoanCycle.new(current_status=IllLoanCycle.STATUS_REQUESTED,
                               item=item, user=user,
                               start_date=start_date, end_date=end_date,
                               delivery=delivery, comments=comments,
                               type=type)

    create_event(user_id=user.id, item_id=item.id,
                 ill_loan_cycle_id=ill_clc.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_REQUEST)

    email_notification('ill_request', '*****@*****.**', user.email,
                       name=user.name, action='requested', items=item)

    return ill_clc
def confirm_ill_request(ill_loan_cycle, supplier_id, comments=''):
    """Confirm the given inter library loan request.

    The ill_loan_cycles current_status will be set to 'ordered'.

    :param supplier_id: Id of the chosen IllSupplier.

    :raise: ValidationExceptions
    """
    try:
        try_confirm_ill_request(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ill_loan_cycle.current_status = IllLoanCycle.STATUS_ORDERED
    ill_loan_cycle.supplier_id = supplier_id
    ill_loan_cycle.comments = comments
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_ORDERED)

    email_notification('ill_ordered', '*****@*****.**',
                       ill_loan_cycle.user.email,
                       ill_loan_cycle=ill_loan_cycle)
def deliver_acquisition(acquisition_loan_cycle):
    try:
        try_deliver_acquisition(acquisition_loan_cycle)
    except ValidationExceptions as e:
        raise e

    status = AcquisitionLoanCycle.STATUS_DELIVERED
    acquisition_loan_cycle.current_status = status
    acquisition_loan_cycle.save()

    create_event(acquisition_loan_cycle_id=acquisition_loan_cycle.id,
                 event=AcquisitionLoanCycle.EVENT_ACQUISITION_DELIVERED)

    email_notification('acquisition_delivery', '*****@*****.**',
                       acquisition_loan_cycle.user.email,
                       acquisition_loan_cycle=acquisition_loan_cycle)
def deliver_acquisition(acquisition_loan_cycle):
    try:
        try_deliver_acquisition(acquisition_loan_cycle)
    except ValidationExceptions as e:
        raise e

    status = AcquisitionLoanCycle.STATUS_DELIVERED
    acquisition_loan_cycle.current_status = status
    acquisition_loan_cycle.save()

    create_event(acquisition_loan_cycle_id=acquisition_loan_cycle.id,
                 event=AcquisitionLoanCycle.EVENT_ACQUISITION_DELIVERED)

    email_notification('acquisition_delivery',
                       '*****@*****.**',
                       acquisition_loan_cycle.user.email,
                       acquisition_loan_cycle=acquisition_loan_cycle)
def request_ill(user,
                record,
                start_date,
                end_date,
                delivery=None,
                comments='',
                type=None):
    """Request inter library loan for the given record to the given user.

    :param record: Invenio Record.
    :param user: CirculationUser.
    :param start_date: Start date of the loan (without time).
    :param end_date: End date of the loan (without time).
    :param delivery: 'pick_up' or 'internal_mail'
    :param comments: Comments regarding the inter library loan.

    :return: Created IllLoanCycle
    """
    delivery = IllLoanCycle.DELIVERY_DEFAULT if delivery is None else delivery
    type = IllLoanCycle.TYPE_BOOK if type is None else type

    item = _create_ill_temporary_item(record)

    ill_clc = IllLoanCycle.new(current_status=IllLoanCycle.STATUS_REQUESTED,
                               item=item,
                               user=user,
                               start_date=start_date,
                               end_date=end_date,
                               delivery=delivery,
                               comments=comments,
                               type=type)

    create_event(user_id=user.id,
                 item_id=item.id,
                 ill_loan_cycle_id=ill_clc.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_REQUEST)

    email_notification('ill_request',
                       '*****@*****.**',
                       user.email,
                       name=user.name,
                       action='requested',
                       items=item)

    return ill_clc
def request_acquisition(user,
                        record,
                        acquisition_type,
                        copies,
                        payment_method,
                        budget_code='',
                        price='',
                        delivery=None,
                        comments=''):
    if not delivery:
        delivery = AcquisitionLoanCycle.DELIVERY_DEFAULT

    item = _create_acquisition_temporary_item(record)

    acquisition_clc = AcquisitionLoanCycle.new(
        current_status=AcquisitionLoanCycle.STATUS_REQUESTED,
        item=item,
        user=user,
        acquisition_type=acquisition_type,
        copies=copies,
        payment_method=payment_method,
        budget_code=budget_code,
        price=price,
        delivery=delivery,
        comments=comments,
        issued_date=datetime.datetime.now())

    if acquisition_type == 'acquisition':
        event = AcquisitionLoanCycle.EVENT_ACQUISITION_REQUEST
    elif acquisition_type == 'purchase':
        event = AcquisitionLoanCycle.EVENT_PURCHASE_REQUEST

    create_event(user_id=user.id,
                 item_id=item.id,
                 acquisition_loan_cycle_id=acquisition_clc.id,
                 event=event)

    email_notification('acquisition_request',
                       '*****@*****.**',
                       user.email,
                       name=user.name,
                       action='requested',
                       items=item)

    return acquisition_clc
def confirm_acquisition_request(acquisition_loan_cycle,
                                vendor_id, price, currency, comments):
    try:
        try_confirm_acquisition_request(acquisition_loan_cycle)
    except ValidationExceptions as e:
        raise e

    acquisition_loan_cycle.current_status = AcquisitionLoanCycle.STATUS_ORDERED
    acquisition_loan_cycle.vendor_id = vendor_id
    acquisition_loan_cycle.price = price
    acquisition_loan_cycle.currency = currency
    acquisition_loan_cycle.comments = comments
    acquisition_loan_cycle.save()

    create_event(acquisition_loan_cycle_id=acquisition_loan_cycle.id,
                 event=AcquisitionLoanCycle.EVENT_ACQUISITION_ORDERED)

    email_notification('acquisition_ordered', '*****@*****.**',
                       acquisition_loan_cycle.user.email,
                       acquisition_loan_cycle=acquisition_loan_cycle)
def confirm_acquisition_request(acquisition_loan_cycle, vendor_id, price,
                                currency, comments):
    try:
        try_confirm_acquisition_request(acquisition_loan_cycle)
    except ValidationExceptions as e:
        raise e

    acquisition_loan_cycle.current_status = AcquisitionLoanCycle.STATUS_ORDERED
    acquisition_loan_cycle.vendor_id = vendor_id
    acquisition_loan_cycle.price = price
    acquisition_loan_cycle.currency = currency
    acquisition_loan_cycle.comments = comments
    acquisition_loan_cycle.save()

    create_event(acquisition_loan_cycle_id=acquisition_loan_cycle.id,
                 event=AcquisitionLoanCycle.EVENT_ACQUISITION_ORDERED)

    email_notification('acquisition_ordered',
                       '*****@*****.**',
                       acquisition_loan_cycle.user.email,
                       acquisition_loan_cycle=acquisition_loan_cycle)
def decline_ill_request(ill_loan_cycle, reason=''):
    """Decline the given inter library loan request.

    The ill_loan_cycles current_status will be set to 'declined'.
    :raise: ValidationExceptions
    """
    try:
        try_decline_ill_request(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ill_loan_cycle.current_status = IllLoanCycle.STATUS_DECLINED
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_DECLINED,
                 description=reason)

    email_notification('ill_declined', '*****@*****.**',
                       ill_loan_cycle.user.email,
                       ill_loan_cycle=ill_loan_cycle)
def decline_ill_request(ill_loan_cycle, reason=''):
    """Decline the given inter library loan request.

    The ill_loan_cycles current_status will be set to 'declined'.
    :raise: ValidationExceptions
    """
    try:
        try_decline_ill_request(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ill_loan_cycle.current_status = IllLoanCycle.STATUS_DECLINED
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_DECLINED,
                 description=reason)

    email_notification('ill_declined',
                       '*****@*****.**',
                       ill_loan_cycle.user.email,
                       ill_loan_cycle=ill_loan_cycle)
def request_ill_extension(ill_loan_cycle, requested_end_date):
    """Request an extension for the given inter library loan.

    'extension_requested' will be added to the attribute additional_statuses.
    The desired_end_date will be set to requested_end_date.
    :raise: ValidationExceptions
    """
    try:
        try_request_ill_extension(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ser = IllLoanCycle.STATUS_EXTENSION_REQUESTED
    ill_loan_cycle.desired_end_date = requested_end_date
    ill_loan_cycle.additional_statuses.append(ser)
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_EXTENSION_REQUESTED)

    email_notification('ill_extension_request', '*****@*****.**',
                       ill_loan_cycle.user.email,
                       loan_cycle=ill_loan_cycle)
def request_ill_extension(ill_loan_cycle, requested_end_date):
    """Request an extension for the given inter library loan.

    'extension_requested' will be added to the attribute additional_statuses.
    The desired_end_date will be set to requested_end_date.
    :raise: ValidationExceptions
    """
    try:
        try_request_ill_extension(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ser = IllLoanCycle.STATUS_EXTENSION_REQUESTED
    ill_loan_cycle.desired_end_date = requested_end_date
    ill_loan_cycle.additional_statuses.append(ser)
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_EXTENSION_REQUESTED)

    email_notification('ill_extension_request',
                       '*****@*****.**',
                       ill_loan_cycle.user.email,
                       loan_cycle=ill_loan_cycle)
def confirm_ill_extension(ill_loan_cycle):
    """Confirm the requested extension for the given inter library loan.

    The end_date and desired_end_date attributes will be adjusted.
    'extension_requested' will be removed from additional_statuses.
    :raise: ValidationExceptions
    """
    try:
        try_confirm_ill_extension(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ser = IllLoanCycle.STATUS_EXTENSION_REQUESTED
    ill_loan_cycle.end_date = ill_loan_cycle.desired_end_date
    ill_loan_cycle.desired_end_date = None
    ill_loan_cycle.additional_statuses.remove(ser)
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_EXTENSION_CONFIRMED)

    email_notification('ill_extension_request_confirmed', '*****@*****.**',
                       ill_loan_cycle.user.email,
                       loan_cycle=ill_loan_cycle)
def decline_ill_extension(ill_loan_cycle, reason=''):
    """Decline the requested extension for the given inter library loan.

    'extension_requested' will be removed from additional_statuses.
    The desired_end_date will be set to None.
    :raise: ValidationExceptions
    """
    try:
        try_decline_ill_extension(ill_loan_cycle)
    except ValidationExceptions as e:
        raise e

    ser = IllLoanCycle.STATUS_EXTENSION_REQUESTED
    ill_loan_cycle.desired_end_date = None
    ill_loan_cycle.additional_statuses.remove(ser)
    ill_loan_cycle.save()

    create_event(ill_loan_cycle_id=ill_loan_cycle.id,
                 event=IllLoanCycle.EVENT_ILL_CLC_EXTENSION_DECLINED,
                 description=reason)

    email_notification('ill_extension_request_declined', '*****@*****.**',
                       ill_loan_cycle.user.email,
                       loan_cycle=ill_loan_cycle)