コード例 #1
0
def test_acquisition_order(client, rero_json_header, org_martigny,
                           lib_martigny, budget_2020_martigny, vendor_martigny,
                           librarian_martigny, document):
    """Scenario to test orders creation."""

    login_user_via_session(client, librarian_martigny.user)

    # STEP 0 :: Create the account tree
    basic_data = {
        'allocated_amount': 1000,
        'budget': {
            '$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)
        },
        'library': {
            '$ref': get_ref_for_pid('lib', lib_martigny.pid)
        }
    }
    account_a = dict(name='A', allocated_amount=2000)
    account_a = {**basic_data, **account_a}
    account_a = _make_resource(client, 'acac', account_a)
    account_a_ref = {'$ref': get_ref_for_pid('acac', account_a.pid)}

    account_b = dict(name='B', allocated_amount=500, parent=account_a_ref)
    account_b = {**basic_data, **account_b}
    account_b = _make_resource(client, 'acac', account_b)
    account_b_ref = {'$ref': get_ref_for_pid('acac', account_b.pid)}

    # TEST 1 :: Create an order and add some order lines on it.
    #   * The creation of the order will be successful
    #   * We create first order line linked to account B. After this creation,
    #     we can check the encumbrance of this account and its parent account.
    order_data = {
        'vendor': {
            '$ref': get_ref_for_pid('vndr', vendor_martigny.pid)
        },
        'library': {
            '$ref': get_ref_for_pid('lib', lib_martigny.pid)
        },
        'type': 'monograph',
    }
    order = _make_resource(client, 'acor', order_data)
    assert order['reference'] == f'ORDER-{order.pid}'
    assert order.get_order_provisional_total_amount() == 0
    assert order.status == AcqOrderStatus.PENDING
    assert order.can_delete

    basic_data = {
        'acq_account': account_b_ref,
        'acq_order': {
            '$ref': get_ref_for_pid('acor', order.pid)
        },
        'document': {
            '$ref': get_ref_for_pid('doc', document.pid)
        },
        'quantity': 4,
        'amount': 25
    }
    order_line_1 = _make_resource(client, 'acol', basic_data)
    assert order_line_1.get('total_amount') == 100

    assert account_b.encumbrance_amount[0] == 100
    assert account_b.remaining_balance[0] == 400  # 500 - 100
    assert account_a.encumbrance_amount == (0, 100)
    assert account_a.remaining_balance[0] == 1500
    assert account_a.expenditure_amount == (0, 0)

    # TEST 2 :: update the number of received item from the order line.
    #   * The encumbrance amount account should be decrease by quantity
    #     received * amount.
    # field received_quantity is now dynamically calculated at the receive of
    # receipt_lines
    assert order_line_1.received_quantity == 0

    # TEST 3 :: add a new cancelled order line.
    #   * As this new order line has CANCELLED status, its amount is not
    #     calculated into the encumbrance_amount
    basic_data = {
        'acq_account': account_b_ref,
        'acq_order': {
            '$ref': get_ref_for_pid('acor', order.pid)
        },
        'document': {
            '$ref': get_ref_for_pid('doc', document.pid)
        },
        'quantity': 2,
        'amount': 10,
        'is_cancelled': True
    }
    order_line_1_1 = _make_resource(client, 'acol', basic_data)
    assert order_line_1_1.get('total_amount') == 20

    assert account_b.encumbrance_amount[0] == 100
    assert account_b.remaining_balance[0] == 400  # 500 - 100
    assert account_a.encumbrance_amount == (0, 100)
    assert account_a.remaining_balance[0] == 1500
    assert account_a.expenditure_amount == (0, 0)

    # TEST 4 :: new order line raises the limit of account available money.
    #   * Create a new order line on the same account ; but the total amount
    #     of the line must be larger than account available money --> should
    #     be raise an ValidationError
    #   * Update the first order line to raise the limit and check than the
    #     same validation error occurs.
    #   * Update the first order line to reach the limit without exceeding it
    order_line_2 = dict(quantity=50)
    order_line_2 = {**basic_data, **order_line_2}
    with pytest.raises(Exception) as excinfo:
        _make_resource(client, 'acol', order_line_2)
    assert 'Parent account available amount too low' in str(excinfo.value)

    order_line_1['quantity'] = 50
    with pytest.raises(Exception) as excinfo:
        order_line_1.update(order_line_1, dbcommit=True, reindex=True)
    assert 'Parent account available amount too low' in str(excinfo.value)

    order_line_1['quantity'] = 20
    order_line_1 = order_line_1.update(order_line_1,
                                       dbcommit=True,
                                       reindex=True)
    assert account_b.encumbrance_amount[0] == 500
    assert account_b.remaining_balance[0] == 0
    assert account_a.encumbrance_amount == (0, 500)
    assert account_a.remaining_balance[0] == 1500

    # TEST 5 :: Update the account encumbrance exceedance and test it.
    #   * At this time, the account B doesn't have any available money to
    #     place any nex order line. Try to add an other item to existing order
    #     line will raise a ValidationError
    #   * Update the account 'encumbrance_exceedance' setting to allow more
    #     encumbrance and try to add an item to order_line. It will be OK
    order_line_1['quantity'] += 1
    with pytest.raises(Exception) as excinfo:
        order_line_1.update(order_line_1, dbcommit=True, reindex=True)
    assert 'Parent account available amount too low' in str(excinfo.value)

    account_b['encumbrance_exceedance'] = 5  # 5% of 500 = 25
    account_b = account_b.update(account_b, dbcommit=True, reindex=True)
    order_line_1 = order_line_1.update(order_line_1,
                                       dbcommit=True,
                                       reindex=True)
    assert account_b.encumbrance_amount[0] == 525
    assert account_b.remaining_balance[0] == -25
    assert account_a.encumbrance_amount == (0, 525)
    assert account_a.remaining_balance[0] == 1500

    # Test cascade deleting of order lines when attempting to delete a
    # PENDING order.
    order_line_1 = AcqOrderLine.get_record_by_pid(order_line_1.pid)
    order_line_1['is_cancelled'] = True
    order_line_1.update(order_line_1, dbcommit=True, reindex=True)

    order = AcqOrder.get_record_by_pid(order.pid)
    assert order.status == AcqOrderStatus.CANCELLED

    # Delete CANCELLED order is not permitted
    with pytest.raises(IlsRecordError.NotDeleted):
        _del_resource(client, 'acor', order.pid)

    order_line_1['is_cancelled'] = False
    order_line_1.update(order_line_1, dbcommit=True, reindex=True)

    order = AcqOrder.get_record_by_pid(order.pid)
    assert order.status == AcqOrderStatus.PENDING

    # DELETE created resources
    _del_resource(client, 'acor', order.pid)
    # Deleting the parent PENDING order does delete all of its order lines
    order_line_1 = AcqOrderLine.get_record_by_pid(order_line_1.pid)
    order_line_1_1 = AcqOrderLine.get_record_by_pid(order_line_1_1.pid)
    assert not order_line_1
    assert not order_line_1_1

    _del_resource(client, 'acac', account_b.pid)
    _del_resource(client, 'acac', account_a.pid)
コード例 #2
0
def test_create_accounts(client, rero_json_header, org_martigny, lib_martigny,
                         budget_2020_martigny):
    """Basic scenario to test account creation."""
    # STEP 1 :: Create a root account
    root_account_data = {
        'name': 'Root account',
        'number': '000.0000.00',
        'allocated_amount': 1000,
        'budget': {
            '$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)
        },
        'library': {
            '$ref': get_ref_for_pid('lib', lib_martigny.pid)
        }
    }
    root_account = _make_resource(client, 'acac', root_account_data)

    # STEP 2 :: Create a child account
    #   * Try to create a child account with too much amount regarding root
    #     account. It should be failed with a ValidationError due to
    #     `pre_create` extension.
    #   * Create a child account with 70% of the available amount of root
    #     account
    child_account_data = {
        'name': 'Chid account',
        'number': '000.0001.00',
        'allocated_amount': root_account['allocated_amount'] + 1,
        'budget': {
            '$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)
        },
        'library': {
            '$ref': get_ref_for_pid('lib', lib_martigny.pid)
        },
        'parent': {
            '$ref': get_ref_for_pid('acac', root_account.pid)
        },
    }
    with pytest.raises(Exception) as excinfo:
        _make_resource(client, 'acac', child_account_data)
    assert 'Parent account available amount too low.' in str(excinfo.value)

    amount_70 = round(root_account['allocated_amount'] * 0.7)
    amount_30 = root_account['allocated_amount'] - amount_70
    child_account_data['allocated_amount'] = amount_70
    child_account = _make_resource(client, 'acac', child_account_data)

    # STEP 3 :: Check accounts distribution
    #   * Parent account should have 30% as available amount
    #   * Parent account distribution should be 70%
    assert root_account.remaining_balance[0] == amount_30
    assert root_account.distribution == amount_70

    # STEP 4 :: Decrease the allocated amount of parent account too much
    root_account_data['allocated_amount'] = amount_30 + 1
    with pytest.raises(Exception) as excinfo:
        root_account.update(root_account_data, dbcommit=True)
    assert 'Remaining balance too low' in str(excinfo.value)

    # RESET DATA
    _del_resource(client, 'acac', child_account.pid)
    _del_resource(client, 'acac', root_account.pid)
コード例 #3
0
def test_acquisition_orders_serializers(client, librarian_martigny,
                                        budget_2020_martigny, lib_martigny,
                                        vendor_martigny, document,
                                        rero_json_header):
    """Test orders serializer."""
    login_user_via_session(client, librarian_martigny.user)
    # STEP 0 :: Create the account with multiple order lines
    account_data = {
        'name': 'Account A',
        'allocated_amount': 1000,
        'budget': {
            '$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)
        },
        'library': {
            '$ref': get_ref_for_pid('lib', lib_martigny.pid)
        }
    }
    account_a = _make_resource(client, 'acac', account_data)
    account_a_ref = {'$ref': get_ref_for_pid('acac', account_a.pid)}
    order_data = {
        'vendor': {
            '$ref': get_ref_for_pid('vndr', vendor_martigny.pid)
        },
        'library': {
            '$ref': get_ref_for_pid('lib', lib_martigny.pid)
        },
        'reference': 'ORDER#1',
        'type': 'monograph',
    }
    order = _make_resource(client, 'acor', order_data)
    order.reindex()
    line_data = {
        'acq_account': account_a_ref,
        'acq_order': {
            '$ref': get_ref_for_pid('acor', order.pid)
        },
        'document': {
            '$ref': get_ref_for_pid('doc', document.pid)
        },
        'quantity': 4,
        'amount': 25
    }
    order_line_1 = _make_resource(client, 'acol', line_data)

    # TEST ORDER SERIALIZER
    list_url = url_for('invenio_records_rest.acor_list')
    response = client.get(list_url, headers=rero_json_header)
    assert response.status_code == 200
    data = get_json(response)
    record = data.get('hits', {}).get('hits', [])[0]
    assert record.get('metadata', {})\
        .get('order_lines', [])[0] \
        .get('account', {})\
        .get('name') == account_a['name']
    assert record.get('metadata', {}) \
        .get('order_lines', [])[0] \
        .get('document', {}) \
        .get('pid') == document.pid

    # RESET RESOURCES
    _del_resource(client, 'acol', order_line_1.pid)
    _del_resource(client, 'acor', order.pid)
    _del_resource(client, 'acac', account_a.pid)
コード例 #4
0
def test_transfer_funds_api(client, rero_json_header, org_martigny,
                            lib_martigny, budget_2020_martigny,
                            librarian_martigny):
    """Scenario to test fund transfer between both accounts."""
    def _check_account(account):
        """Check amount available about an account."""
        return account['allocated_amount'], account.remaining_balance[0]

    login_user_via_session(client, librarian_martigny.user)

    # STEP 0 :: Create account tree
    #   Test structure account is described below. Each account are noted like
    #   A{x, y} where :
    #     * 'A' is the account name
    #     * 'x' is the account allocated amount
    #     * 'y' is the account remaining_balance
    #
    #   A{2000, 500}                E{200, 100}
    #   |-- B{500, 150}             +-- F{200, 100}
    #   |   |-- B1{300, 300}            +-- G{100, 100}
    #   |   +-- B2{50, 50}
    #   +-- C{1000, 700}
    #       |-- C1{100, 100}
    #       |-- C2{100, 30}
    #       |   |-- C21{50, 50}
    #       |   +-- C22{20, 20}
    #       +-- C3{100, 100}
    basic_data = {
        'allocated_amount': 1000,
        'budget': {
            '$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)
        },
        'library': {
            '$ref': get_ref_for_pid('lib', lib_martigny.pid)
        }
    }
    account_a = dict(name='A', allocated_amount=2000)
    account_a = {**basic_data, **account_a}
    account_a = _make_resource(client, 'acac', account_a)
    a_ref = {'$ref': get_ref_for_pid('acac', account_a.pid)}

    account_b = dict(name='B', allocated_amount=500, parent=a_ref)
    account_b = {**basic_data, **account_b}
    account_b = _make_resource(client, 'acac', account_b)
    b_ref = {'$ref': get_ref_for_pid('acac', account_b.pid)}

    account_c = dict(name='C', allocated_amount=1000, parent=a_ref)
    account_c = {**basic_data, **account_c}
    account_c = _make_resource(client, 'acac', account_c)
    c_ref = {'$ref': get_ref_for_pid('acac', account_c.pid)}

    account_b1 = dict(name='B1', allocated_amount=300, parent=b_ref)
    account_b1 = {**basic_data, **account_b1}
    account_b1 = _make_resource(client, 'acac', account_b1)
    account_b2 = dict(name='B2', allocated_amount=50, parent=b_ref)
    account_b2 = {**basic_data, **account_b2}
    account_b2 = _make_resource(client, 'acac', account_b2)

    account_c1 = dict(name='C1', allocated_amount=100, parent=c_ref)
    account_c1 = {**basic_data, **account_c1}
    account_c1 = _make_resource(client, 'acac', account_c1)
    account_c2 = dict(name='C2', allocated_amount=100, parent=c_ref)
    account_c2 = {**basic_data, **account_c2}
    account_c2 = _make_resource(client, 'acac', account_c2)
    account_c3 = dict(name='C3', allocated_amount=100, parent=c_ref)
    account_c3 = {**basic_data, **account_c3}
    account_c3 = _make_resource(client, 'acac', account_c3)
    c2_ref = {'$ref': get_ref_for_pid('acac', account_c2.pid)}

    account_c21 = dict(name='C21', allocated_amount=50, parent=c2_ref)
    account_c21 = {**basic_data, **account_c21}
    account_c21 = _make_resource(client, 'acac', account_c21)
    account_c22 = dict(name='C22', allocated_amount=20, parent=c2_ref)
    account_c22 = {**basic_data, **account_c22}
    account_c22 = _make_resource(client, 'acac', account_c22)

    account_e = dict(name='E', allocated_amount=300)
    account_e = {**basic_data, **account_e}
    account_e = _make_resource(client, 'acac', account_e)
    e_ref = {'$ref': get_ref_for_pid('acac', account_e.pid)}

    account_f = dict(name='F', allocated_amount=200, parent=e_ref)
    account_f = {**basic_data, **account_f}
    account_f = _make_resource(client, 'acac', account_f)
    f_ref = {'$ref': get_ref_for_pid('acac', account_f.pid)}

    account_g = dict(name='G', allocated_amount=100, parent=f_ref)
    account_g = {**basic_data, **account_g}
    account_g = _make_resource(client, 'acac', account_g)

    # TEST 0 :: Try the API with invalid arguments.
    res = client.get(url_for('api_acq_account.transfer_funds'))
    assert res.status_code == 400
    assert 'argument is required' in res.get_data(as_text=True)
    cases_to_test = [{
        'source': 'dummy',
        'target': 'dummy',
        'amount': 'dummy',
        'error': 'Unable to load source account'
    }, {
        'source': account_a.pid,
        'target': 'dummy',
        'amount': 'dummy',
        'error': 'Unable to load target account'
    }, {
        'source': account_a.pid,
        'target': account_b.pid,
        'amount': 'dummy',
        'error': "could not convert"
    }, {
        'source': account_a.pid,
        'target': account_b.pid,
        'amount': -1.52,
        'error': "'amount' should be a positive number"
    }, {
        'source': account_a.pid,
        'target': account_a.pid,
        'amount': 1,
        'error': "Cannot transfer fund to myself"
    }, {
        'source': account_a.pid,
        'target': account_e.pid,
        'amount': 100000,
        'error': "Not enough available money from source account"
    }]
    for case in cases_to_test:
        res = client.get(
            url_for('api_acq_account.transfer_funds',
                    source=case['source'],
                    target=case['target'],
                    amount=case['amount']))
        assert res.status_code == 400
        data = get_json(res)
        assert case['error'] in data['message']

    # STATUS BEFORE NEXT TEST
    #   A{2000, 500}                E{300, 100}
    #   |-- B{500, 150}             +-- F{200, 100}
    #   |   |-- B1{300, 300}            +-- G{100, 100}
    #   |   +-- B2{50, 50}
    #   +-- C{1000, 700}
    #       |-- C1{100, 100}
    #       |-- C2{100, 30}
    #       |   |-- C21{50, 50}
    #       |   +-- C22{20, 20}
    #       +-- C3{100, 100}

    # TEST 1 :: Transfer to an ancestor account
    #   Transfer 25 from C21 account to C account. After this transfer, the
    #   C20 remaining balance should be equal to 25 ; the remaining balance for
    #   C account should be 725
    res = client.get(
        url_for('api_acq_account.transfer_funds',
                source=account_c21.pid,
                target=account_c.pid,
                amount=25))
    assert res.status_code == 200
    account_c21 = AcqAccount.get_record_by_pid(account_c21.pid)
    account_c2 = AcqAccount.get_record_by_pid(account_c2.pid)
    account_c = AcqAccount.get_record_by_pid(account_c.pid)
    assert _check_account(account_c) == (1000, 725)
    assert _check_account(account_c2) == (75, 30)
    assert _check_account(account_c21) == (25, 25)

    # STATUS BEFORE NEXT TEST
    #   A{2000, 500}                E{300, 100}
    #   |-- B{500, 150}             +-- F{200, 100}
    #   |   |-- B1{300, 300}            +-- G{100, 100}
    #   |   +-- B2{50, 50}
    #   +-- C{1000, 725}
    #       |-- C1{100, 100}
    #       |-- C2{75, 30}
    #       |   |-- C21{25, 25}
    #       |   +-- C22{20, 20}
    #       +-- C3{100, 100}

    # TEST 2 :: Transfer between accounts in the same tree
    #   Transfer 100 from A account to C22 account. After this transfer, the
    #   C22 remaining balance should be equal to 120 ; the remaining balance
    #   for A account should be 400. The remaining balance for intermediate
    #   accounts (C, C2) should be the same, but allocated amount should be
    #   increased by 100 (1100, 175)
    res = client.get(
        url_for('api_acq_account.transfer_funds',
                source=account_a.pid,
                target=account_c22.pid,
                amount=100))
    assert res.status_code == 200
    account_a = AcqAccount.get_record_by_pid(account_a.pid)
    account_c = AcqAccount.get_record_by_pid(account_c.pid)
    account_c2 = AcqAccount.get_record_by_pid(account_c2.pid)
    account_c22 = AcqAccount.get_record_by_pid(account_c22.pid)
    assert _check_account(account_a) == (2000, 400)
    assert _check_account(account_c) == (1100, 725)
    assert _check_account(account_c2) == (175, 30)
    assert _check_account(account_c22) == (120, 120)

    # STATUS BEFORE NEXT TEST
    #   A{2000, 400}                E{300, 100}
    #   |-- B{500, 150}             +-- F{200, 100}
    #   |   |-- B1{300, 300}            +-- G{100, 100}
    #   |   +-- B2{50, 50}
    #   +-- C{1100, 725}
    #       |-- C1{100, 100}
    #       |-- C2{175, 30}
    #       |   |-- C21{25, 25}
    #       |   +-- C22{120, 120}
    #       +-- C3{100, 100}

    # TEST 3 :: Transfer 300 from B1 account to C21 account.
    #   Same behavior than previous test, but source account isn't the common
    #   ancestor.
    res = client.get(
        url_for('api_acq_account.transfer_funds',
                source=account_b1.pid,
                target=account_c21.pid,
                amount=300))
    assert res.status_code == 200
    account_b1 = AcqAccount.get_record_by_pid(account_b1.pid)
    account_b = AcqAccount.get_record_by_pid(account_b.pid)
    account_a = AcqAccount.get_record_by_pid(account_a.pid)
    account_c = AcqAccount.get_record_by_pid(account_c.pid)
    account_c2 = AcqAccount.get_record_by_pid(account_c2.pid)
    account_c21 = AcqAccount.get_record_by_pid(account_c21.pid)
    assert _check_account(account_b1) == (0, 0)
    assert _check_account(account_b) == (200, 150)
    assert _check_account(account_a) == (2000, 400)
    assert _check_account(account_c) == (1400, 725)
    assert _check_account(account_c2) == (475, 30)
    assert _check_account(account_c21) == (325, 325)

    # STATUS BEFORE NEXT TEST
    #   A{2000, 400}                E{300, 100}
    #   |-- B{200, 150}             +-- F{200, 100}
    #   |   |-- B1{0, 0}                +-- G{100, 100}
    #   |   +-- B2{50, 50}
    #   +-- C{1400, 725}
    #       |-- C1{100, 100}
    #       |-- C2{475, 30}
    #       |   |-- C21{325, 325}
    #       |   +-- C22{120, 120}
    #       +-- C3{100, 100}

    # TEST 4 :: Transfer between two account from separate tree.
    #   We transfer 100 from F account to C3 account. As both accounts aren't
    #   in the same tree, they not exists a common ancestor. Each root tag
    #   should be update (E will decrease, A will increase)
    res = client.get(
        url_for('api_acq_account.transfer_funds',
                source=account_f.pid,
                target=account_c3.pid,
                amount=100))
    assert res.status_code == 200
    account_f = AcqAccount.get_record_by_pid(account_f.pid)
    account_e = AcqAccount.get_record_by_pid(account_e.pid)
    account_a = AcqAccount.get_record_by_pid(account_a.pid)
    account_c = AcqAccount.get_record_by_pid(account_c.pid)
    account_c3 = AcqAccount.get_record_by_pid(account_c3.pid)
    assert _check_account(account_f) == (100, 0)
    assert _check_account(account_e) == (200, 100)
    assert _check_account(account_a) == (2100, 400)
    assert _check_account(account_c) == (1500, 725)
    assert _check_account(account_c3) == (200, 200)

    # STATUS BEFORE NEXT TEST
    #   A{2100, 400}                E{200, 100}
    #   |-- B{200, 150}             +-- F{100, 0}
    #   |   |-- B1{0, 0}                +-- G{100, 100}
    #   |   +-- B2{50, 50}
    #   +-- C{1500, 725}
    #       |-- C1{100, 100}
    #       |-- C2{475, 30}
    #       |   |-- C21{325, 325}
    #       |   +-- C22{120, 120}
    #       +-- C3{200, 200}

    # delete accounts
    _del_resource(client, 'acac', account_g.pid)
    _del_resource(client, 'acac', account_f.pid)
    _del_resource(client, 'acac', account_e.pid)

    _del_resource(client, 'acac', account_c22.pid)
    _del_resource(client, 'acac', account_c21.pid)
    _del_resource(client, 'acac', account_c3.pid)
    _del_resource(client, 'acac', account_c2.pid)
    _del_resource(client, 'acac', account_c1.pid)
    _del_resource(client, 'acac', account_c.pid)
    _del_resource(client, 'acac', account_b2.pid)
    _del_resource(client, 'acac', account_b1.pid)
    _del_resource(client, 'acac', account_b.pid)
    _del_resource(client, 'acac', account_a.pid)
コード例 #5
0
def test_acquisition_reception_workflow(
    client, rero_json_header, org_martigny,
    lib_martigny, lib_saxon, budget_2020_martigny,
    vendor_martigny, librarian_martigny, document
):
    """Test complete acquisition workflow."""

    def assert_account_data(accounts):
        """assert account informations."""
        for acc, (balance, expenditure, encumbrance) in accounts.items():
            assert acc.expenditure_amount == expenditure
            assert acc.encumbrance_amount == encumbrance
            assert acc.remaining_balance == balance

    # STEP 1 :: Create account structures
    #   * Create accounts for Martigny library.
    #     - MTY.0000.00' (root)
    #       --> MTY.000b.00
    #       --> MTY.000s.00
    #   * Create accounts for Saxon library.
    #     - SXN.0000.00 (root)
    #       --> SXN.000b.00
    #       --> SXN.000s.00
    data = {
        'name': 'Martigny root account',
        'number': 'MTY.0000.00',
        'allocated_amount': 10000,
        'budget': {'$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)},
        'library': {'$ref': get_ref_for_pid('lib', lib_martigny.pid)}
    }
    m_root_acc = _make_resource(client, 'acac', data)
    data = {
        'name': 'Martigny Books child account',
        'number': 'MTY.000b.00',
        'allocated_amount': 2000,
        'budget': {'$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)},
        'library': {'$ref': get_ref_for_pid('lib', lib_martigny.pid)},
        'parent': {'$ref': get_ref_for_pid('acac', m_root_acc.pid)},
    }
    m_books_acc = _make_resource(client, 'acac', data)
    data = {
        'name': 'Martigny Serials child account',
        'number': 'MTY.000s.00',
        'allocated_amount': 3000,
        'budget': {'$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)},
        'library': {'$ref': get_ref_for_pid('lib', lib_martigny.pid)},
        'parent': {'$ref': get_ref_for_pid('acac', m_root_acc.pid)},
    }
    m_serials_acc = _make_resource(client, 'acac', data)
    data = {
        'name': 'Saxon root account',
        'number': 'SXN.0000.00',
        'allocated_amount': 20000,
        'budget': {'$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)},
        'library': {'$ref': get_ref_for_pid('lib', lib_saxon.pid)}
    }
    s_root_acc = _make_resource(client, 'acac', data)
    data = {
        'name': 'Saxon Books chid account',
        'number': 'SXN.000b.00',
        'allocated_amount': 2500,
        'budget': {'$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)},
        'library': {'$ref': get_ref_for_pid('lib', lib_saxon.pid)},
        'parent': {'$ref': get_ref_for_pid('acac', s_root_acc.pid)},
    }
    s_books_acc = _make_resource(client, 'acac', data)
    data = {
        'name': 'Saxon Serials chid account',
        'number': 'SXN.000s.00',
        'allocated_amount': 4000,
        'budget': {'$ref': get_ref_for_pid('budg', budget_2020_martigny.pid)},
        'library': {'$ref': get_ref_for_pid('lib', lib_saxon.pid)},
        'parent': {'$ref': get_ref_for_pid('acac', s_root_acc.pid)},
    }
    s_serials_acc = _make_resource(client, 'acac', data)

    # For each account check data. the dict values are tuples. Each tuple
    # define `balance`, `expenditure`, `encumbrance`
    manual_controls = {
        m_root_acc: ((5000, 10000), (0, 0), (0, 0)),
        m_books_acc: ((2000, 2000), (0, 0), (0, 0)),
        m_serials_acc: ((3000, 3000), (0, 0), (0, 0)),
        s_root_acc: ((13500, 20000), (0, 0), (0, 0)),
        s_books_acc: ((2500, 2500), (0, 0), (0, 0)),
        s_serials_acc: ((4000, 4000), (0, 0), (0, 0))
    }
    assert_account_data(manual_controls)

    # STEP 2 :: CREATE REAL ORDER
    #   * Create an order for Martigny library
    #   * Adds 6 order lines for this order
    #       martigny_books_account:
    #           line_1: quantity: 5 of amount 10   = 50
    #           line_2: quantity: 2 of amount 50   = 100
    #           line_3: quantity: 3 of amount 100  = 300
    #                                        Total = 450
    #       martigny_serials_account:
    #           line_1: quantity: 3 of amount 15   = 45
    #           line_2: quantity: 1 of amount 150  = 150
    #           line_3: quantity: 10 of amount 7   = 70
    #                                        Total = 265
    #       Items quantity = 24: order total amount = 715
    login_user_via_session(client, librarian_martigny.user)
    data = {
        'vendor': {'$ref': get_ref_for_pid('vndr', vendor_martigny.pid)},
        'library': {'$ref': get_ref_for_pid('lib', lib_martigny.pid)},
        'type': 'monograph',
    }
    order = _make_resource(client, 'acor', data)
    assert order['reference'] == f'ORDER-{order.pid}'
    assert order.get_order_provisional_total_amount() == 0
    assert order.status == AcqOrderStatus.PENDING
    assert order.can_delete

    data = {
        'acq_account': {'$ref': get_ref_for_pid('acac', m_books_acc.pid)},
        'acq_order': {'$ref': get_ref_for_pid('acor', order.pid)},
        'document': {'$ref': get_ref_for_pid('doc', document.pid)},
        'quantity': 5,
        'amount': 10
    }
    order_line_1 = _make_resource(client, 'acol', data)
    order_line_1_ref = get_ref_for_pid('acol', order_line_1.pid)
    assert order_line_1.get('total_amount') == 50
    assert order_line_1.quantity == 5
    assert order_line_1.received_quantity == 0
    assert order_line_1.unreceived_quantity == 5
    assert not order_line_1.is_cancelled
    assert order_line_1.status == AcqOrderLineStatus.APPROVED

    data = {
        'acq_account': {'$ref': get_ref_for_pid('acac', m_books_acc.pid)},
        'acq_order': {'$ref': get_ref_for_pid('acor', order.pid)},
        'document': {'$ref': get_ref_for_pid('doc', document.pid)},
        'quantity': 2,
        'amount': 50
    }
    order_line_2 = _make_resource(client, 'acol', data)
    order_line_2_ref = get_ref_for_pid('acol', order_line_2.pid)
    assert order_line_2.get('total_amount') == 100
    assert order_line_2.quantity == 2
    assert order_line_2.received_quantity == 0
    assert order_line_2.unreceived_quantity == 2
    assert not order_line_2.is_cancelled
    assert order_line_2.status == AcqOrderLineStatus.APPROVED

    data = {
        'acq_account': {'$ref': get_ref_for_pid('acac', m_books_acc.pid)},
        'acq_order': {'$ref': get_ref_for_pid('acor', order.pid)},
        'document': {'$ref': get_ref_for_pid('doc', document.pid)},
        'quantity': 3,
        'amount': 100
    }
    order_line_3 = _make_resource(client, 'acol', data)
    order_line_3_ref = get_ref_for_pid('acol', order_line_3.pid)
    assert order_line_3.get('total_amount') == 300
    assert order_line_3.quantity == 3
    assert order_line_3.received_quantity == 0
    assert order_line_3.unreceived_quantity == 3
    assert not order_line_3.is_cancelled
    assert order_line_3.status == AcqOrderLineStatus.APPROVED

    data = {
        'acq_account': {'$ref': get_ref_for_pid('acac', m_serials_acc.pid)},
        'acq_order': {'$ref': get_ref_for_pid('acor', order.pid)},
        'document': {'$ref': get_ref_for_pid('doc', document.pid)},
        'quantity': 3,
        'amount': 15
    }
    order_line_4 = _make_resource(client, 'acol', data)
    order_line_4_ref = get_ref_for_pid('acol', order_line_4.pid)
    assert order_line_4.get('total_amount') == 45
    assert order_line_4.quantity == 3
    assert order_line_4.received_quantity == 0
    assert order_line_4.unreceived_quantity == 3
    assert not order_line_4.is_cancelled
    assert order_line_4.status == AcqOrderLineStatus.APPROVED

    data = {
        'acq_account': {'$ref': get_ref_for_pid('acac', m_serials_acc.pid)},
        'acq_order': {'$ref': get_ref_for_pid('acor', order.pid)},
        'document': {'$ref': get_ref_for_pid('doc', document.pid)},
        'quantity': 1,
        'amount': 150
    }
    order_line_5 = _make_resource(client, 'acol', data)
    order_line_5_ref = get_ref_for_pid('acol', order_line_5.pid)
    assert order_line_5.get('total_amount') == 150
    assert order_line_5.quantity == 1
    assert order_line_5.received_quantity == 0
    assert order_line_5.unreceived_quantity == 1
    assert not order_line_5.is_cancelled
    assert order_line_5.status == AcqOrderLineStatus.APPROVED

    data = {
        'acq_account': {'$ref': get_ref_for_pid('acac', m_serials_acc.pid)},
        'acq_order': {'$ref': get_ref_for_pid('acor', order.pid)},
        'document': {'$ref': get_ref_for_pid('doc', document.pid)},
        'quantity': 10,
        'amount': 7
    }
    order_line_6 = _make_resource(client, 'acol', data)
    order_line_6_ref = get_ref_for_pid('acol', order_line_6.pid)
    assert order_line_6.get('total_amount') == 70
    assert order_line_6.quantity == 10
    assert order_line_6.received_quantity == 0
    assert order_line_6.unreceived_quantity == 10
    assert not order_line_6.is_cancelled
    assert order_line_6.status == AcqOrderLineStatus.APPROVED

    # test order after adding lines
    assert order.get_order_provisional_total_amount() == 715
    assert order.status == AcqOrderStatus.PENDING
    # TODO: fix links to me for the order resource, this should fail
    assert order.can_delete
    assert not order.order_date
    assert order.item_quantity == 24
    assert order.item_received_quantity == 0

    manual_controls = {
        m_root_acc: ((5000, 9285), (0, 0), (0, 715)),
        m_books_acc: ((1550, 1550), (0, 0), (450, 0)),
        m_serials_acc: ((2735, 2735), (0, 0), (265, 0)),
        s_root_acc: ((13500, 20000), (0, 0), (0, 0)),
        s_books_acc: ((2500, 2500), (0, 0), (0, 0)),
        s_serials_acc: ((4000, 4000), (0, 0), (0, 0))
    }
    assert_account_data(manual_controls)

    # STEP 3 :: UPDATE ORDER LINES
    #   * Cancel some order lines and change some quantities --> make sure
    #     calculations still good
    #       martigny_books_account:
    #           line_1: quantity: 5 of amount 10   = 50
    #           line_2: quantity: 6 of amount 50   = 300  (quantity: 2 --> 6)
    #           line_3: quantity: 3 of amount 100  = 300 but cancelled !
    #                                        Total = 350
    #       martigny_serials_account:
    #           line_1: quantity: 3 of amount 15   = 45
    #           line_2: quantity: 2 of amount 150  = 300  (quantity: 1 --> 2)
    #           line_3: quantity: 10 of amount 7   = 70  but cancelled
    #                                        Total = 345
    #       Items quantity = 16: order total amount = 695

    order_line_2['quantity'] = 6
    order_line_2.update(order_line_2, dbcommit=True, reindex=True)
    order_line_3['is_cancelled'] = True
    order_line_3.update(order_line_3, dbcommit=True, reindex=True)
    order_line_5['quantity'] = 2
    order_line_5.update(order_line_5, dbcommit=True, reindex=True)
    order_line_6['is_cancelled'] = True
    order_line_6.update(order_line_6, dbcommit=True, reindex=True)

    # ensure correct calculations and status again
    manual_controls = {
        m_root_acc: ((5000, 9305), (0, 0), (0, 695)),
        m_books_acc: ((1650, 1650), (0, 0), (350, 0)),
        m_serials_acc: ((2655, 2655), (0, 0), (345, 0)),
        s_root_acc: ((13500, 20000), (0, 0), (0, 0)),
        s_books_acc: ((2500, 2500), (0, 0), (0, 0)),
        s_serials_acc: ((4000, 4000), (0, 0), (0, 0))
    }
    assert_account_data(manual_controls)

    assert order_line_6.get('total_amount') == 70
    assert order_line_6.is_cancelled
    assert order_line_6.quantity == 10
    assert order_line_6.received_quantity == 0
    assert order_line_6.unreceived_quantity == 10
    assert order_line_6.status == AcqOrderLineStatus.CANCELLED

    assert order_line_5.get('total_amount') == 300
    assert not order_line_5.is_cancelled
    assert order_line_5.quantity == 2
    assert order_line_5.received_quantity == 0
    assert order_line_5.unreceived_quantity == 2
    assert order_line_5.status == AcqOrderLineStatus.APPROVED

    assert order_line_4.get('total_amount') == 45
    assert not order_line_4.is_cancelled
    assert order_line_4.quantity == 3
    assert order_line_4.received_quantity == 0
    assert order_line_4.unreceived_quantity == 3
    assert order_line_4.status == AcqOrderLineStatus.APPROVED

    assert order_line_3.get('total_amount') == 300
    assert order_line_3.is_cancelled
    assert order_line_3.quantity == 3
    assert order_line_3.received_quantity == 0
    assert order_line_3.unreceived_quantity == 3
    assert order_line_3.status == AcqOrderLineStatus.CANCELLED

    assert order_line_2.get('total_amount') == 300
    assert not order_line_2.is_cancelled
    assert order_line_2.quantity == 6
    assert order_line_2.received_quantity == 0
    assert order_line_2.unreceived_quantity == 6
    assert order_line_2.status == AcqOrderLineStatus.APPROVED

    assert order_line_1.get('total_amount') == 50
    assert not order_line_1.is_cancelled
    assert order_line_1.quantity == 5
    assert order_line_1.received_quantity == 0
    assert order_line_1.unreceived_quantity == 5
    assert order_line_1.status == AcqOrderLineStatus.APPROVED

    # STEP 4 :: SEND THE ORDER
    #    * Test send order and make sure statuses are up to date.
    #      - check order lines (status, order-date)
    #      - check order (status)
    #      - check notification
    address = vendor_martigny.get('default_contact').get('email')
    emails = [
        {'type': 'to', 'address': address},
        {'type': 'reply_to', 'address': lib_martigny.get('email')}
    ]
    res, data = postdata(
        client,
        'api_order.send_order',
        data=dict(emails=emails),
        url_data=dict(order_pid=order.pid)
    )
    assert res.status_code == 200

    for order_line in [
        {'line': order_line_1, 'status': AcqOrderLineStatus.ORDERED},
        {'line': order_line_2, 'status': AcqOrderLineStatus.ORDERED},
        {'line': order_line_3, 'status': AcqOrderLineStatus.CANCELLED},
        {'line': order_line_4, 'status': AcqOrderLineStatus.ORDERED},
        {'line': order_line_5, 'status': AcqOrderLineStatus.ORDERED},
        {'line': order_line_6, 'status': AcqOrderLineStatus.CANCELLED},
    ]:
        line = AcqOrderLine.get_record_by_pid(order_line.get('line').pid)
        assert line.status == order_line.get('status')
        if line.status == AcqOrderLineStatus.CANCELLED:
            assert not line.order_date
        else:
            assert line.order_date
    # check order
    order = AcqOrder.get_record_by_pid(order.pid)
    assert order.status == AcqOrderStatus.ORDERED
    # notification testing
    notification_pid = data.get('data').get('pid')
    notif = Notification.get_record_by_pid(notification_pid)
    assert notif.organisation_pid == order.organisation_pid
    assert notif.aggregation_key == str(notif.id)
    assert notif.type == NotificationType.ACQUISITION_ORDER
    assert notif.status == NotificationStatus.DONE
    assert notif.acq_order_pid == order.pid
    assert notif.library_pid == order.library_pid
    assert notif.can_be_cancelled() == (False, None)
    assert notif.get_communication_channel() == NotificationChannel.EMAIL
    assert notif.get_language_to_use() == \
        vendor_martigny.get('communication_language')
    assert address in notif.get_recipients(RecipientType.TO)

    # STEP 5 :: CREATE A RECEIPT
    #   * create a receipt without any order lines yet
    #   * but with some adjustments
    ref_acc_book = get_ref_for_pid('acac', m_books_acc.pid)
    ref_acc_serial = get_ref_for_pid('acac', m_serials_acc.pid)
    data = {
        'acq_order': {'$ref': get_ref_for_pid('acor', order.pid)},
        'exchange_rate': 1,
        'amount_adjustments': [
            {
                'label': 'handling fees',
                'amount': 2.0,
                'acq_account': {'$ref': ref_acc_book}
            },
            {
                'label': 'discount',
                'amount': -1.0,
                'acq_account': {'$ref': ref_acc_book}
            },
            {
                'label': 'handling fees',
                'amount': 10,
                'acq_account': {'$ref': ref_acc_serial}
            }
        ],
        'library': {'$ref': get_ref_for_pid('lib', lib_martigny.pid)},
        'organisation': {'$ref': get_ref_for_pid('org', org_martigny.pid)}
    }
    receipt_1 = _make_resource(client, 'acre', data)
    assert receipt_1.total_amount == 11  # 2 - 1 + 10
    assert receipt_1.can_delete

    manual_controls = {
        m_root_acc: ((5000, 9294), (0, 11), (0, 695)),
        m_books_acc: ((1649, 1649), (1, 0), (350, 0)),
        m_serials_acc: ((2645, 2645), (10, 0), (345, 0)),
        s_root_acc: ((13500, 20000), (0, 0), (0, 0)),
        s_books_acc: ((2500, 2500), (0, 0), (0, 0)),
        s_serials_acc: ((4000, 4000), (0, 0), (0, 0))
    }
    assert_account_data(manual_controls)

    # STEP 6 :: RECEIVE SOME ORDER LINES
    #    Received 2 items from the order_line_1. We need to ensure :
    #    * the order_line status is PARTIALLY_RECEIVED
    #    * the order status is PARTIALLY_RECEIVED too
    #    * the related account amounts are correctly assigned

    # CHECK :: Not possible to receive quantity more than what you ordered
    res, data = postdata(
        client,
        'api_receipt.lines',
        data=[{
            'acq_order_line': {'$ref': order_line_1_ref},
            'amount': 10,
            'quantity': 12,
            'receipt_date': '2021-11-01'
        }],
        url_data=dict(receipt_pid=receipt_1.pid)
    )
    assert res.status_code == 200
    response = data.get('response')
    assert response[0]['status'] == AcqReceiptLineCreationStatus.FAILURE

    # partially receive one order with few quantities in receipt_1
    res, data = postdata(
        client,
        'api_receipt.lines',
        data=[{
            'acq_order_line': {'$ref': order_line_1_ref},
            'amount': 10,
            'quantity': 2,
            'vat_rate': 6,
            'receipt_date': '2021-11-01'
        }],
        url_data=dict(receipt_pid=receipt_1.pid)
    )
    assert res.status_code == 200
    response = data.get('response')
    assert response[0]['status'] == AcqReceiptLineCreationStatus.SUCCESS

    # Test order and order lines
    for order_line in [{
        'line': order_line_1,
        'status': AcqOrderLineStatus.PARTIALLY_RECEIVED,
        'received': 2
    }, {
        'line': order_line_2,
        'status': AcqOrderLineStatus.ORDERED,
        'received': 0
    }, {
        'line': order_line_3,
        'status': AcqOrderLineStatus.CANCELLED,
        'received': 0
    }, {
        'line': order_line_4,
        'status': AcqOrderLineStatus.ORDERED,
        'received': 0
    }, {
        'line': order_line_5,
        'status': AcqOrderLineStatus.ORDERED,
        'received': 0
    }, {
        'line': order_line_6,
        'status': AcqOrderLineStatus.CANCELLED,
        'received': 0
    }]:
        line = AcqOrderLine.get_record_by_pid(order_line.get('line').pid)
        assert line.status == order_line.get('status')
        assert line.received_quantity == order_line.get('received')
    order = AcqOrder.get_record_by_pid(order.pid)
    assert order.status == AcqOrderStatus.PARTIALLY_RECEIVED

    manual_controls = {
        m_root_acc: ((5000, 9292.8), (0, 32.2), (0, 675)),
        m_books_acc: ((1647.8, 1647.8), (22.2, 0), (330, 0)),
        m_serials_acc: ((2645, 2645), (10, 0), (345, 0)),
        s_root_acc: ((13500, 20000), (0, 0), (0, 0)),
        s_books_acc: ((2500, 2500), (0, 0), (0, 0)),
        s_serials_acc: ((4000, 4000), (0, 0), (0, 0))
    }
    assert_account_data(manual_controls)

    # STEP 7 :: CREATE NEW RECEIVE AND RECEIVE ALL PENDING ORDER LINES
    #   * Create a second receipt for the same order with no adjustments.
    #   * To to receive all pending order lines BUT with a mistake for
    #     `order_line_5` (try to receive more than ordered items) ==> all lines
    #     except `order_line_5` should have the RECEIVED STATUS
    #   * complete the order reception to receive the `order_line_5`
    data = {
        'exchange_rate': 1,
        'acq_order': {'$ref': get_ref_for_pid('acor', order.pid)},
        'library': {'$ref': get_ref_for_pid('lib', lib_martigny.pid)},
        'organisation': {'$ref': get_ref_for_pid('org', org_martigny.pid)}
    }
    receipt_2 = _make_resource(client, 'acre', data)

    data = [{
        'acq_order_line': {'$ref': order_line_1_ref},
        'amount': 10,
        'quantity': 3,
        'receipt_date': '2021-11-01'
    }, {
        'acq_order_line': {'$ref': order_line_2_ref},
        'amount': 50,
        'quantity': 6,
        'receipt_date': '2021-11-01'
    }, {
        'acq_order_line': {'$ref': order_line_4_ref},
        'amount': 15,
        'quantity': 3,
        'receipt_date': '2021-11-01'
    }, {
        'acq_order_line': {'$ref': order_line_5_ref},
        'amount': 150,
        'quantity': 12,  # too many items ! Max quantity should be 2
        'receipt_date': '2021-11-01'
    }]
    res, data = postdata(
        client,
        'api_receipt.lines',
        data=data,
        url_data=dict(receipt_pid=receipt_2.pid)
    )

    assert res.status_code == 200
    response = data.get('response')
    assert response[0]['status'] == AcqReceiptLineCreationStatus.SUCCESS
    assert response[1]['status'] == AcqReceiptLineCreationStatus.SUCCESS
    assert response[2]['status'] == AcqReceiptLineCreationStatus.SUCCESS
    assert response[3]['status'] == AcqReceiptLineCreationStatus.FAILURE

    # Test order and order lines
    for order_line in [
        {'line': order_line_1, 'status': AcqOrderLineStatus.RECEIVED},
        {'line': order_line_2, 'status': AcqOrderLineStatus.RECEIVED},
        {'line': order_line_3, 'status': AcqOrderLineStatus.CANCELLED},
        {'line': order_line_4, 'status': AcqOrderLineStatus.RECEIVED},
        {'line': order_line_5, 'status': AcqOrderLineStatus.ORDERED},
        {'line': order_line_6, 'status': AcqOrderLineStatus.CANCELLED}
    ]:
        line = AcqOrderLine.get_record_by_pid(order_line.get('line').pid)
        assert line.status == order_line.get('status')

    # Receive the last pending order_line
    data = [{
        'acq_order_line': {'$ref': order_line_5_ref},
        'amount': 150,
        'quantity': 2,
        'receipt_date': '2021-11-01'
    }]
    res, data = postdata(
        client,
        'api_receipt.lines',
        data=data,
        url_data=dict(receipt_pid=receipt_2.pid)
    )
    assert res.status_code == 200
    response = data.get('response')
    assert response[0]['status'] == AcqReceiptLineCreationStatus.SUCCESS
    order_line = AcqOrderLine.get_record_by_pid(order_line_5.pid)
    assert order_line.status == AcqOrderLineStatus.RECEIVED

    # check than order is now fully received
    order = AcqOrder.get_record_by_pid(order.pid)
    assert order.status == AcqOrderStatus.RECEIVED
    # check account amounts
    manual_controls = {
        m_root_acc: ((5000, 9292.8), (0, 707.2), (0, 0)),
        m_books_acc: ((1647.8, 1647.8), (352.2, 0), (0, 0)),
        m_serials_acc: ((2645, 2645), (355, 0), (0, 0)),
        s_root_acc: ((13500, 20000), (0, 0), (0, 0)),
        s_books_acc: ((2500, 2500), (0, 0), (0, 0)),
        s_serials_acc: ((4000, 4000), (0, 0), (0, 0))
    }
    assert_account_data(manual_controls)

    # TEST 8: DELETE RECEIPTS
    #   * Delete the second receipt. This will also delete the related receipt
    #     lines. The order status must remain to PARTIALLY_RECEIVED.
    #   * Delete the first receipt. The order status should remain to ORDERED
    #     and account amount should be the same than STEP#3.

    # Check links between object
    #   * check some order lines (cancelled or not); not need to test all lines
    #   * check receipt links
    links = order.get_links_to_me(get_pids=True)
    for pid in [order_line_3.pid, order_line_4.pid, order_line_5.pid]:
        assert pid in links['order_lines']
    for pid in [receipt_1.pid, receipt_2.pid]:
        assert pid in links['receipts']

    # DELETE `RECEIPT_2` ----------
    receipt_line_pids = receipt_2.get_receipt_lines(output='pids')
    url = url_for('invenio_records_rest.acre_item', pid_value=receipt_2.pid)
    client.delete(url)
    # Check all resources related to `receipt_2` is deleted
    for pid in receipt_line_pids:
        line = AcqReceiptLine.get_record_by_pid(pid)
        assert line is None
    assert AcqReceipt.get_record_by_pid(receipt_2.pid) is None
    # Check ES is up-to-date
    response = AcqReceiptLinesSearch()\
        .filter('terms', pid=receipt_line_pids).execute()
    assert response.hits.total.value == 0
    response = AcqReceiptsSearch() \
        .filter('term', pid=receipt_2.pid).execute()
    assert response.hits.total.value == 0
    # Check order status
    order = AcqOrder.get_record_by_pid(order.pid)
    assert order.status == AcqOrderStatus.PARTIALLY_RECEIVED

    # DELETE `RECEIPT_1` ----------
    receipt_line_pids = receipt_1.get_receipt_lines(output='pids')
    url = url_for('invenio_records_rest.acre_item', pid_value=receipt_1.pid)
    client.delete(url)
    # Check all resources related to `receipt_1` is deleted
    for pid in receipt_line_pids:
        line = AcqReceiptLine.get_record_by_pid(pid)
        assert line is None
    assert AcqReceipt.get_record_by_pid(receipt_1.pid) is None
    # Check ES is up-to-date
    response = AcqReceiptLinesSearch() \
        .filter('terms', pid=receipt_line_pids).execute()
    assert response.hits.total.value == 0
    response = AcqReceiptsSearch() \
        .filter('term', pid=receipt_1.pid).execute()
    assert response.hits.total.value == 0
    # Check order status
    order = AcqOrder.get_record_by_pid(order.pid)
    assert order.status == AcqOrderStatus.ORDERED

    # ensure correct calculations and status again
    manual_controls = {
        m_root_acc: ((5000, 9305), (0, 0), (0, 695)),
        m_books_acc: ((1650, 1650), (0, 0), (350, 0)),
        m_serials_acc: ((2655, 2655), (0, 0), (345, 0)),
        s_root_acc: ((13500, 20000), (0, 0), (0, 0)),
        s_books_acc: ((2500, 2500), (0, 0), (0, 0)),
        s_serials_acc: ((4000, 4000), (0, 0), (0, 0))
    }
    assert_account_data(manual_controls)