Search in sources :

Example 6 with Adjustment

use of org.folio.rest.jaxrs.model.Adjustment in project mod-invoice by folio-org.

the class InvoicesApiTest method testCreateInvoiceWithTwoProratedAdjustmentsNoLines.

@Test
void testCreateInvoiceWithTwoProratedAdjustmentsNoLines() throws IOException {
    logger.info("=== Test create invoice with 1 prorated and 1 not prorated adjustments with no lines - adjustmentTotal should always be calculated irrespective if there are any invoiceLines or not===");
    // === Preparing invoice for test ===
    Invoice invoice = new JsonObject(getMockData(REVIEWED_INVOICE_SAMPLE_PATH)).mapTo(Invoice.class);
    Adjustment adjustment1 = createAdjustment(Prorate.NOT_PRORATED, Type.AMOUNT, 10d).withId(randomUUID().toString());
    Adjustment adjustment2 = createAdjustment(Prorate.BY_LINE, Type.AMOUNT, 10d).withId(randomUUID().toString());
    invoice.setAdjustments((Arrays.asList(adjustment1, adjustment2)));
    // === Run test ===
    final Invoice resp = verifyPostResponse(INVOICE_PATH, JsonObject.mapFrom(invoice), prepareHeaders(X_OKAPI_TENANT), APPLICATION_JSON, 201).as(Invoice.class);
    /* The invoice has 2 adjustments with no lines, one not prorated and one prorated by line adjustments */
    assertThat(resp.getAdjustmentsTotal(), equalTo(20.d));
    assertThat(resp.getSubTotal(), equalTo(0d));
    assertThat(resp.getTotal(), equalTo(20d));
    // Verify that expected number of external calls made
    assertThat(serverRqRs.cellSet(), hasSize(2));
    assertThat(getRqRsEntries(HttpMethod.GET, FOLIO_INVOICE_NUMBER), hasSize(1));
    compareRecordWithSentToStorage(resp);
}
Also used : Invoice(org.folio.rest.jaxrs.model.Invoice) Adjustment(org.folio.rest.jaxrs.model.Adjustment) JsonObject(io.vertx.core.json.JsonObject) Test(org.junit.jupiter.api.Test)

Example 7 with Adjustment

use of org.folio.rest.jaxrs.model.Adjustment in project mod-invoice by folio-org.

the class InvoicesApiTest method testTransitionFromOpenToApproved.

@Test
void testTransitionFromOpenToApproved() {
    logger.info("=== Test transition invoice to Approved ===");
    Adjustment adjustment1 = new Adjustment().withProrate(Prorate.NOT_PRORATED).withDescription("Description").withType(Type.AMOUNT).withValue(50d).withRelationToTotal(Adjustment.RelationToTotal.IN_ADDITION_TO);
    FundDistribution fundDistribution1 = new FundDistribution().withDistributionType(FundDistribution.DistributionType.PERCENTAGE).withValue(100d).withFundId(EXISTING_FUND_ID);
    Adjustment adjustment2 = new Adjustment().withProrate(Prorate.NOT_PRORATED).withDescription("Description").withType(Type.AMOUNT).withValue(50d).withRelationToTotal(Adjustment.RelationToTotal.IN_ADDITION_TO);
    FundDistribution fundDistribution2 = new FundDistribution().withDistributionType(AMOUNT).withValue(50d).withFundId(EXISTING_FUND_ID);
    adjustment1.getFundDistributions().add(fundDistribution1);
    adjustment2.getFundDistributions().add(fundDistribution2);
    List<InvoiceLine> invoiceLines = getMockAsJson(INVOICE_LINES_LIST_PATH).mapTo(InvoiceLineCollection.class).getInvoiceLines();
    Invoice reqData = getMockAsJson(OPEN_INVOICE_SAMPLE_PATH).mapTo(Invoice.class);
    reqData.getAdjustments().add(adjustment1);
    reqData.getAdjustments().add(adjustment2);
    String id = reqData.getId();
    invoiceLines.forEach(invoiceLine -> {
        invoiceLine.setId(UUID.randomUUID().toString());
        invoiceLine.setInvoiceId(id);
        invoiceLine.getFundDistributions().forEach(fundDistribution -> fundDistribution.setCode(null));
        addMockEntry(INVOICE_LINES, JsonObject.mapFrom(invoiceLine));
    });
    reqData.setStatus(Invoice.Status.APPROVED);
    String jsonBody = JsonObject.mapFrom(reqData).encode();
    Headers headers = prepareHeaders(X_OKAPI_URL, X_OKAPI_TENANT, X_OKAPI_TOKEN, X_OKAPI_USER_ID);
    verifyPut(String.format(INVOICE_ID_PATH, id), jsonBody, headers, "", 204);
    // Verify that expected number of external calls made
    assertThat(getInvoiceRetrievals(), hasSize(1));
    assertThat(getInvoiceLineSearches(), hasSize(1));
    Invoice updatedInvoice = serverRqRs.get(INVOICES, HttpMethod.PUT).get(0).mapTo(Invoice.class);
    List<JsonObject> vouchersCreated = serverRqRs.get(VOUCHERS_STORAGE, HttpMethod.POST);
    assertThat(vouchersCreated, notNullValue());
    assertThat(vouchersCreated, hasSize(1));
    Voucher voucherCreated = vouchersCreated.get(0).mapTo(Voucher.class);
    assertThat(voucherCreated.getVoucherNumber(), equalTo(TEST_PREFIX + VOUCHER_NUMBER_VALUE));
    assertThat(voucherCreated.getSystemCurrency(), equalTo(DEFAULT_SYSTEM_CURRENCY));
    verifyTransitionToApproved(voucherCreated, invoiceLines, updatedInvoice, 5);
    verifyVoucherLineWithExpenseClasses(2L);
    checkVoucherAcqUnitIdsList(voucherCreated, reqData);
}
Also used : FundDistribution(org.folio.rest.jaxrs.model.FundDistribution) Invoice(org.folio.rest.jaxrs.model.Invoice) Adjustment(org.folio.rest.jaxrs.model.Adjustment) InvoiceLine(org.folio.rest.jaxrs.model.InvoiceLine) Headers(io.restassured.http.Headers) JsonObject(io.vertx.core.json.JsonObject) InvoiceLineCollection(org.folio.rest.jaxrs.model.InvoiceLineCollection) Matchers.containsString(org.hamcrest.Matchers.containsString) Voucher(org.folio.rest.jaxrs.model.Voucher) Test(org.junit.jupiter.api.Test)

Example 8 with Adjustment

use of org.folio.rest.jaxrs.model.Adjustment in project mod-invoice by folio-org.

the class InvoicesProratedAdjustmentsTest method testUpdateInvoiceWithOneLineAndOneAdjustmentAddingSecondAdj.

@ParameterizedTest
@CsvSource({ "BY_AMOUNT, AMOUNT", "BY_AMOUNT, PERCENTAGE", "BY_LINE, AMOUNT", "BY_LINE, PERCENTAGE", "BY_QUANTITY, AMOUNT", "BY_QUANTITY, PERCENTAGE" })
public void testUpdateInvoiceWithOneLineAndOneAdjustmentAddingSecondAdj(Adjustment.Prorate prorate, Adjustment.Type type) {
    logger.info("=== Updating invoice with one line and one prorated adjustment - adding second adjustment ===");
    // Prepare data "from storage"
    Invoice invoice = getMockAsJson(OPEN_INVOICE_SAMPLE_PATH).mapTo(Invoice.class).withId(randomUUID().toString());
    Adjustment adjustment1 = createAdjustment(prorate, type, 15d).withId(randomUUID().toString());
    invoice.setAdjustments(Collections.singletonList(adjustment1));
    addMockEntry(INVOICES, invoice);
    InvoiceLine invoiceLine = getMockInvoiceLine(invoice.getId()).withSubTotal(25d).withQuantity(10).withAdjustments(Collections.singletonList(copyObject(adjustment1).withAdjustmentId(adjustment1.getId()).withId(null)));
    addMockEntry(INVOICE_LINES, invoiceLine);
    // Send update request adding one more adjustment
    Adjustment adjustment2 = createAdjustment(prorate, type, 10d);
    Invoice body = copyObject(invoice);
    body.getAdjustments().add(adjustment2);
    verifyPut(String.format(INVOICE_ID_PATH, invoice.getId()), body, "", 204);
    // Verification
    assertThat(getInvoiceUpdates(), hasSize(1));
    assertThat(getInvoiceLineUpdates(), hasSize(1));
    /*
     * Calculated adjustment value depends of type:
     * "Amount" - this is the same as adjustment value i.e. 10 + 15 = 25
     * "Percentage" - this is the percentage of subTotal i.e. 25% of 25$ = 6.25$
     */
    double expectedAdjTotal = (type == AMOUNT) ? 25d : 6.25d;
    Invoice invoiceToStorage = getInvoiceUpdates().get(0).mapTo(Invoice.class);
    assertThat(invoiceToStorage.getAdjustments(), hasSize(2));
    assertThat(invoiceToStorage.getAdjustmentsTotal(), is(expectedAdjTotal));
    Adjustment invoiceAdjToStorage1 = null;
    Adjustment invoiceAdjToStorage2 = null;
    for (Adjustment adjustment : invoiceToStorage.getAdjustments()) {
        assertThat(adjustment.getId(), not(isEmptyOrNullString()));
        if (adjustment1.getId().equals(adjustment.getId())) {
            invoiceAdjToStorage1 = adjustment;
            assertThat(invoiceAdjToStorage1.getValue(), is(15d));
        } else {
            invoiceAdjToStorage2 = adjustment;
            assertThat(invoiceAdjToStorage2.getValue(), is(10d));
        }
    }
    // Make sure that both adjustments are found
    assertThat(invoiceAdjToStorage1, notNullValue());
    assertThat(invoiceAdjToStorage2, notNullValue());
    InvoiceLine lineToStorage = getInvoiceLineUpdates().get(0).mapTo(InvoiceLine.class);
    assertThat(lineToStorage.getAdjustments(), hasSize(2));
    assertThat(lineToStorage.getAdjustmentsTotal(), is(expectedAdjTotal));
    double adjustment1ExpectedAmount = (type == AMOUNT) ? 15d : 3.75d;
    double adjustment2ExpectedAmount = (type == AMOUNT) ? 10d : 2.5d;
    for (Adjustment adj : lineToStorage.getAdjustments()) {
        if (adjustment1.getId().equals(adj.getAdjustmentId())) {
            verifyInvoiceLineAdjustmentCommon(invoiceAdjToStorage1, adj);
            assertThat(adj.getValue(), is(adjustment1ExpectedAmount));
        } else {
            verifyInvoiceLineAdjustmentCommon(invoiceAdjToStorage2, adj);
            assertThat(adj.getValue(), is(adjustment2ExpectedAmount));
        }
    }
}
Also used : Invoice(org.folio.rest.jaxrs.model.Invoice) Adjustment(org.folio.rest.jaxrs.model.Adjustment) InvoiceLine(org.folio.rest.jaxrs.model.InvoiceLine) CsvSource(org.junit.jupiter.params.provider.CsvSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 9 with Adjustment

use of org.folio.rest.jaxrs.model.Adjustment in project mod-invoice by folio-org.

the class InvoicesProratedAdjustmentsTest method testUpdateInvoiceWithThreeLinesAddingNegativeAmountAdjustmentByAmountWithMissed2Pennies.

@Test
public void testUpdateInvoiceWithThreeLinesAddingNegativeAmountAdjustmentByAmountWithMissed2Pennies() {
    logger.info("=== Updating invoice with zero subTotal and three lines  adding adjustment by amount, missing two \"pennies\" ===");
    // Prepare data "from storage"
    Invoice invoice = getMockAsJson(OPEN_INVOICE_SAMPLE_PATH).mapTo(Invoice.class).withId(randomUUID().toString());
    invoice.getAdjustments().clear();
    addMockEntry(INVOICES, invoice);
    InvoiceLine invoiceLine1 = getMockInvoiceLine(invoice.getId()).withSubTotal(25d).withInvoiceLineNumber("n-3");
    InvoiceLine invoiceLine2 = getMockInvoiceLine(invoice.getId()).withSubTotal(25d).withInvoiceLineNumber("n-4");
    addMockEntry(INVOICE_LINES, invoiceLine2);
    InvoiceLine invoiceLine3 = getMockInvoiceLine(invoice.getId()).withSubTotal(25d).withInvoiceLineNumber("n-13");
    addMockEntry(INVOICE_LINES, invoiceLine3);
    addMockEntry(INVOICE_LINES, invoiceLine1);
    // Prepare request body
    Invoice invoiceBody = copyObject(invoice);
    invoiceBody.getAdjustments().add(createAdjustment(BY_AMOUNT, AMOUNT, -0.02d));
    // Send update request
    verifyPut(String.format(INVOICE_ID_PATH, invoice.getId()), invoiceBody, "", 204);
    // Verification
    assertThat(getInvoiceUpdates(), hasSize(1));
    assertThat(getInvoiceLineUpdates(), hasSize(3));
    Invoice invoiceToStorage = getInvoiceUpdates().get(0).mapTo(Invoice.class);
    assertThat(invoiceToStorage.getAdjustments(), hasSize(1));
    // Prorated adj value + non prorated adj of first line
    assertThat(invoiceToStorage.getAdjustmentsTotal(), is(-0.02d));
    Adjustment invoiceAdjustment = invoiceToStorage.getAdjustments().get(0);
    assertThat(invoiceAdjustment.getId(), not(isEmptyOrNullString()));
    // -0.02 * 25 / 75 = -0,00(6666666666666)
    verifyAdjustmentValue(invoiceLine1.getId(), 0d);
    // -0.02 * 25 / 75 = -0,00(6666666666666) - 0.01
    verifyAdjustmentValue(invoiceLine2.getId(), -0.01d);
    // -0.02 * 25 / 75 = -0,00(6666666666666) - 0.01
    verifyAdjustmentValue(invoiceLine3.getId(), -0.01d);
}
Also used : Invoice(org.folio.rest.jaxrs.model.Invoice) Adjustment(org.folio.rest.jaxrs.model.Adjustment) InvoiceLine(org.folio.rest.jaxrs.model.InvoiceLine) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 10 with Adjustment

use of org.folio.rest.jaxrs.model.Adjustment in project mod-invoice by folio-org.

the class InvoicesProratedAdjustmentsTest method testUpdateInvoiceWithThreeLinesAddingNegativePercentageAdjustmentByAmount.

@Test
public void testUpdateInvoiceWithThreeLinesAddingNegativePercentageAdjustmentByAmount() {
    logger.info("=== Updating invoice with zero subTotal and three lines (mixed subTotals) adding -20% adjustment by amount ===");
    // Prepare data "from storage"
    Invoice invoice = getMockAsJson(OPEN_INVOICE_SAMPLE_PATH).mapTo(Invoice.class).withId(randomUUID().toString());
    invoice.getAdjustments().clear();
    addMockEntry(INVOICES, invoice);
    InvoiceLine invoiceLine1 = getMockInvoiceLine(invoice.getId()).withSubTotal(5d).withInvoiceLineNumber("n-1").withAdjustments(Collections.singletonList(createAdjustment(NOT_PRORATED, AMOUNT, 10d)));
    addMockEntry(INVOICE_LINES, invoiceLine1);
    InvoiceLine invoiceLine2 = getMockInvoiceLine(invoice.getId()).withSubTotal(20d).withInvoiceLineNumber("n-2");
    addMockEntry(INVOICE_LINES, invoiceLine2);
    InvoiceLine invoiceLine3 = getMockInvoiceLine(invoice.getId()).withSubTotal(-25d).withInvoiceLineNumber("n-3");
    addMockEntry(INVOICE_LINES, invoiceLine3);
    // Prepare request body
    Invoice invoiceBody = copyObject(invoice);
    invoiceBody.getAdjustments().add(createAdjustment(BY_AMOUNT, PERCENTAGE, -20d));
    // Send update request
    verifyPut(String.format(INVOICE_ID_PATH, invoice.getId()), invoiceBody, "", 204);
    // Verification
    assertThat(getInvoiceUpdates(), hasSize(1));
    assertThat(getInvoiceLineUpdates(), hasSize(3));
    Invoice invoiceToStorage = getInvoiceUpdates().get(0).mapTo(Invoice.class);
    assertThat(invoiceToStorage.getAdjustments(), hasSize(1));
    assertThat(invoiceToStorage.getAdjustmentsTotal(), is(10d));
    Adjustment invoiceAdjustment = invoiceToStorage.getAdjustments().get(0);
    assertThat(invoiceAdjustment.getId(), not(isEmptyOrNullString()));
    InvoiceLine lineToStorage1 = getLineToStorageById(invoiceLine1.getId());
    assertThat(lineToStorage1.getAdjustments(), hasSize(2));
    assertThat(lineToStorage1.getAdjustmentsTotal(), is(10d));
    // First adjustment is not prorated
    assertThat(lineToStorage1.getAdjustments().get(0).getValue(), is(10d));
    // Second adjustment is prorated
    Adjustment line1Adjustment2 = lineToStorage1.getAdjustments().get(1);
    verifyInvoiceLineAdjustmentCommon(invoiceAdjustment, line1Adjustment2);
    assertThat(line1Adjustment2.getValue(), is(0d));
    InvoiceLine lineToStorage2 = getLineToStorageById(invoiceLine2.getId());
    assertThat(lineToStorage2.getAdjustments(), hasSize(1));
    assertThat(lineToStorage2.getAdjustmentsTotal(), is(0d));
    Adjustment line2Adjustment1 = lineToStorage2.getAdjustments().get(0);
    verifyInvoiceLineAdjustmentCommon(invoiceAdjustment, line2Adjustment1);
    assertThat(line2Adjustment1.getValue(), is(0d));
    InvoiceLine lineToStorage3 = getLineToStorageById(invoiceLine3.getId());
    assertThat(lineToStorage3.getAdjustments(), hasSize(1));
    assertThat(lineToStorage3.getAdjustmentsTotal(), is(0d));
    Adjustment line3Adjustment1 = lineToStorage3.getAdjustments().get(0);
    verifyInvoiceLineAdjustmentCommon(invoiceAdjustment, line3Adjustment1);
    assertThat(line3Adjustment1.getValue(), is(0d));
}
Also used : Invoice(org.folio.rest.jaxrs.model.Invoice) Adjustment(org.folio.rest.jaxrs.model.Adjustment) InvoiceLine(org.folio.rest.jaxrs.model.InvoiceLine) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

Adjustment (org.folio.rest.jaxrs.model.Adjustment)40 Invoice (org.folio.rest.jaxrs.model.Invoice)33 InvoiceLine (org.folio.rest.jaxrs.model.InvoiceLine)33 Test (org.junit.jupiter.api.Test)24 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)21 ArrayList (java.util.ArrayList)12 CsvSource (org.junit.jupiter.params.provider.CsvSource)10 FundDistribution (org.folio.rest.jaxrs.model.FundDistribution)7 JsonObject (io.vertx.core.json.JsonObject)6 Errors (org.folio.rest.jaxrs.model.Errors)6 List (java.util.List)5 Matchers.containsString (org.hamcrest.Matchers.containsString)5 Headers (io.restassured.http.Headers)4 Collections (java.util.Collections)4 Date (java.util.Date)4 MonetaryAmount (javax.money.MonetaryAmount)4 HttpException (org.folio.invoices.rest.exceptions.HttpException)4 RequestContext (org.folio.rest.core.models.RequestContext)4 Error (org.folio.rest.jaxrs.model.Error)4 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)4