Skip to content

Commit 72b4fce

Browse files
committed
✨ add support for receipts_items_classifier v1.0
1 parent 6e39122 commit 72b4fce

File tree

6 files changed

+330
-0
lines changed

6 files changed

+330
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import com.mindee.MindeeClient;
2+
import com.mindee.input.LocalInputSource;
3+
import com.mindee.parsing.common.AsyncPredictResponse;
4+
import com.mindee.product.receiptsitemsclassifier.ReceiptsItemsClassifierV1;
5+
import java.io.File;
6+
import java.io.IOException;
7+
8+
public class SimpleMindeeClient {
9+
10+
public static void main(String[] args) throws IOException, InterruptedException {
11+
String apiKey = "my-api-key";
12+
String filePath = "/path/to/the/file.ext";
13+
14+
// Init a new client
15+
MindeeClient mindeeClient = new MindeeClient(apiKey);
16+
17+
// Load a file from disk
18+
LocalInputSource inputSource = new LocalInputSource(new File(filePath));
19+
20+
// Parse the file asynchronously
21+
AsyncPredictResponse<ReceiptsItemsClassifierV1> response = mindeeClient.enqueueAndParse(
22+
ReceiptsItemsClassifierV1.class,
23+
inputSource
24+
);
25+
26+
// Print a summary of the response
27+
System.out.println(response.toString());
28+
29+
// Print a summary of the predictions
30+
// System.out.println(response.getDocumentObj().toString());
31+
32+
// Print the document-level predictions
33+
// System.out.println(response.getDocumentObj().getInference().getPrediction().toString());
34+
35+
// Print the page-level predictions
36+
// response.getDocumentObj().getInference().getPages().forEach(
37+
// page -> System.out.println(page.toString())
38+
// );
39+
}
40+
41+
}

src/main/java/com/mindee/CommandLineInterface.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.mindee.product.multireceiptsdetector.MultiReceiptsDetectorV1;
1616
import com.mindee.product.passport.PassportV1;
1717
import com.mindee.product.receipt.ReceiptV4;
18+
import com.mindee.product.receiptsitemsclassifier.ReceiptsItemsClassifierV1;
1819
import java.io.File;
1920
import java.io.IOException;
2021
import java.util.ArrayList;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.mindee.product.receiptsitemsclassifier;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.mindee.http.EndpointInfo;
5+
import com.mindee.parsing.common.Inference;
6+
import lombok.Getter;
7+
8+
/**
9+
* The definition for Receipts Items Classifier, API version 1.
10+
*/
11+
@Getter
12+
@JsonIgnoreProperties(ignoreUnknown = true)
13+
@EndpointInfo(endpointName = "receipts_items_classifier", version = "1")
14+
public class ReceiptsItemsClassifierV1
15+
extends Inference<ReceiptsItemsClassifierV1Document, ReceiptsItemsClassifierV1Document> {
16+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package com.mindee.product.receiptsitemsclassifier;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.mindee.parsing.SummaryHelper;
6+
import com.mindee.parsing.common.Prediction;
7+
import com.mindee.parsing.standard.AmountField;
8+
import com.mindee.parsing.standard.ClassificationField;
9+
import com.mindee.parsing.standard.StringField;
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
import lombok.EqualsAndHashCode;
13+
import lombok.Getter;
14+
15+
/**
16+
* Document data for Receipts Items Classifier, API version 1.
17+
*/
18+
@Getter
19+
@EqualsAndHashCode(callSuper = false)
20+
@JsonIgnoreProperties(ignoreUnknown = true)
21+
public class ReceiptsItemsClassifierV1Document extends Prediction {
22+
23+
/**
24+
* The currency of the receipt in ISO 4217 three-letter code.
25+
*/
26+
@JsonProperty("currency_code")
27+
private StringField currencyCode;
28+
/**
29+
* The category or type of the expense.
30+
*/
31+
@JsonProperty("expense_category")
32+
private ClassificationField expenseCategory;
33+
/**
34+
* The ISO formatted date on which the receipt was issued.
35+
*/
36+
@JsonProperty("issue_date")
37+
private StringField issueDate;
38+
/**
39+
* A list of fields about individual items or services being billed.
40+
*/
41+
@JsonProperty("line_items")
42+
private List<ReceiptsItemsClassifierV1LineItem> lineItems = new ArrayList<>();
43+
/**
44+
* The address of the merchant.
45+
*/
46+
@JsonProperty("merchant_address")
47+
private StringField merchantAddress;
48+
/**
49+
* The name of the merchant.
50+
*/
51+
@JsonProperty("merchant_name")
52+
private StringField merchantName;
53+
/**
54+
* Whether there are several receipts on the document.
55+
*/
56+
@JsonProperty("multiple_receipts")
57+
private StringField multipleReceipts;
58+
/**
59+
* The tip added on the receipt.
60+
*/
61+
@JsonProperty("tip")
62+
private AmountField tip;
63+
/**
64+
* The sum of all the individual line item amounts, including taxes and discounts.
65+
*/
66+
@JsonProperty("total_amount")
67+
private AmountField totalAmount;
68+
/**
69+
* The total tax of the bought items.
70+
*/
71+
@JsonProperty("total_tax")
72+
private AmountField totalTax;
73+
74+
@Override
75+
public boolean isEmpty() {
76+
return (
77+
this.multipleReceipts == null
78+
&& this.issueDate == null
79+
&& this.expenseCategory == null
80+
&& this.merchantName == null
81+
&& this.merchantAddress == null
82+
&& this.totalAmount == null
83+
&& this.tip == null
84+
&& this.totalTax == null
85+
&& this.currencyCode == null
86+
&& (this.lineItems == null || this.lineItems.isEmpty())
87+
);
88+
}
89+
90+
@Override
91+
public String toString() {
92+
StringBuilder outStr = new StringBuilder();
93+
outStr.append(
94+
String.format(":Multiple Receipts: %s%n", this.getMultipleReceipts())
95+
);
96+
outStr.append(
97+
String.format(":Date of Issue: %s%n", this.getIssueDate())
98+
);
99+
outStr.append(
100+
String.format(":Expense Type: %s%n", this.getExpenseCategory())
101+
);
102+
outStr.append(
103+
String.format(":Merchant: %s%n", this.getMerchantName())
104+
);
105+
outStr.append(
106+
String.format(":Merchant address: %s%n", this.getMerchantAddress())
107+
);
108+
outStr.append(
109+
String.format(":Total Amount: %s%n", this.getTotalAmount())
110+
);
111+
outStr.append(
112+
String.format(":Tip: %s%n", this.getTip())
113+
);
114+
outStr.append(
115+
String.format(":Total tax: %s%n", this.getTotalTax())
116+
);
117+
outStr.append(
118+
String.format(":Currency: %s%n", this.getCurrencyCode())
119+
);
120+
String lineItemsSummary = "";
121+
if (!this.getLineItems().isEmpty()) {
122+
int[] lineItemsColSizes = new int[]{21, 11, 10, 7};
123+
lineItemsSummary =
124+
String.format("%n%s%n ", SummaryHelper.lineSeparator(lineItemsColSizes, "-"))
125+
+ "| Item Classification "
126+
+ "| Item Name "
127+
+ "| Quantity "
128+
+ "| Price "
129+
+ String.format("|%n%s%n ", SummaryHelper.lineSeparator(lineItemsColSizes, "="));
130+
lineItemsSummary += SummaryHelper.arrayToString(this.getLineItems(), lineItemsColSizes);
131+
lineItemsSummary += String.format("%n%s", SummaryHelper.lineSeparator(lineItemsColSizes, "-"));
132+
}
133+
outStr.append(
134+
String.format(":Line Items: %s%n", lineItemsSummary)
135+
);
136+
return SummaryHelper.cleanSummary(outStr.toString());
137+
}
138+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.mindee.product.receiptsitemsclassifier;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.mindee.parsing.SummaryHelper;
6+
import com.mindee.parsing.standard.BaseField;
7+
import com.mindee.parsing.standard.LineItemField;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
import lombok.Getter;
11+
12+
/**
13+
* A list of fields about individual items or services being billed.
14+
*/
15+
@Getter
16+
@JsonIgnoreProperties(ignoreUnknown = true)
17+
public class ReceiptsItemsClassifierV1LineItem extends BaseField implements LineItemField {
18+
19+
/**
20+
* The class or type of item.
21+
*/
22+
@JsonProperty("item_classification")
23+
String itemClassification;
24+
/**
25+
* The name or description of a specific item or product being invoiced.
26+
*/
27+
@JsonProperty("item_name")
28+
String itemName;
29+
/**
30+
* The number of units of a specific item that were purchased or sold.
31+
*/
32+
@JsonProperty("quantity")
33+
Double quantity;
34+
/**
35+
* The total cost of a specific item or service, including any applicable taxes or discounts.
36+
*/
37+
@JsonProperty("total_price")
38+
Double totalPrice;
39+
40+
/**
41+
* Output the line in a format suitable for inclusion in an rST table.
42+
*/
43+
public String toTableLine() {
44+
Map<String, String> printable = this.printableValues();
45+
return String.format("| %-19s ", printable.get("itemClassification"))
46+
+ String.format("| %-9s ", printable.get("itemName"))
47+
+ String.format("| %-8s ", printable.get("quantity"))
48+
+ String.format("| %-5s |", printable.get("totalPrice"));
49+
}
50+
51+
@Override
52+
public String toString() {
53+
Map<String, String> printable = this.printableValues();
54+
return String.format("Item Classification: %s", printable.get("itemClassification"))
55+
+ String.format(", Item Name: %s", printable.get("itemName"))
56+
+ String.format(", Quantity: %s", printable.get("quantity"))
57+
+ String.format(", Price: %s", printable.get("totalPrice"));
58+
}
59+
60+
private Map<String, String> printableValues() {
61+
Map<String, String> printable = new HashMap<>();
62+
63+
printable.put("itemClassification", SummaryHelper.formatString(this.itemClassification));
64+
printable.put("itemName", SummaryHelper.formatString(this.itemName));
65+
printable.put(
66+
"quantity",
67+
SummaryHelper.formatAmount(this.quantity)
68+
);
69+
printable.put(
70+
"totalPrice",
71+
SummaryHelper.formatAmount(this.totalPrice)
72+
);
73+
return printable;
74+
}
75+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.mindee.product.receiptsitemsclassifier;
2+
3+
import com.fasterxml.jackson.databind.JavaType;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.mindee.parsing.common.Document;
6+
import com.mindee.parsing.common.PredictResponse;
7+
import com.mindee.parsing.standard.ClassificationField;
8+
import com.mindee.product.ProductTestHelper;
9+
import org.junit.jupiter.api.Assertions;
10+
import org.junit.jupiter.api.Test;
11+
import java.io.File;
12+
import java.io.IOException;
13+
14+
/**
15+
* Unit tests for ReceiptsItemsClassifierV1.
16+
*/
17+
public class ReceiptsItemsClassifierV1Test {
18+
19+
protected PredictResponse<ReceiptsItemsClassifierV1> getPrediction(String name) throws IOException {
20+
ObjectMapper objectMapper = new ObjectMapper();
21+
objectMapper.findAndRegisterModules();
22+
23+
JavaType type = objectMapper.getTypeFactory().constructParametricType(
24+
PredictResponse.class,
25+
ReceiptsItemsClassifierV1.class
26+
);
27+
return objectMapper.readValue(
28+
new File("src/test/resources/products/receipts_items_classifier/response_v1/" + name + ".json"),
29+
type
30+
);
31+
}
32+
33+
@Test
34+
void whenEmptyDeserialized_mustHaveValidProperties() throws IOException {
35+
PredictResponse<ReceiptsItemsClassifierV1> response = getPrediction("empty");
36+
ReceiptsItemsClassifierV1Document docPrediction = response.getDocument().getInference().getPrediction();
37+
Assertions.assertNull(docPrediction.getMultipleReceipts().getValue());
38+
Assertions.assertNull(docPrediction.getIssueDate().getValue());
39+
Assertions.assertInstanceOf(ClassificationField.class, docPrediction.getExpenseCategory());
40+
Assertions.assertNull(docPrediction.getMerchantName().getValue());
41+
Assertions.assertNull(docPrediction.getMerchantAddress().getValue());
42+
Assertions.assertNull(docPrediction.getTotalAmount().getValue());
43+
Assertions.assertNull(docPrediction.getTip().getValue());
44+
Assertions.assertNull(docPrediction.getTotalTax().getValue());
45+
Assertions.assertNull(docPrediction.getCurrencyCode().getValue());
46+
Assertions.assertTrue(docPrediction.getLineItems().isEmpty());
47+
}
48+
49+
@Test
50+
void whenCompleteDeserialized_mustHaveValidDocumentSummary() throws IOException {
51+
PredictResponse<ReceiptsItemsClassifierV1> response = getPrediction("complete");
52+
Document<ReceiptsItemsClassifierV1> doc = response.getDocument();
53+
ProductTestHelper.assertStringEqualsFile(
54+
doc.toString(),
55+
"src/test/resources/products/receipts_items_classifier/response_v1/summary_full.rst"
56+
);
57+
}
58+
59+
}

0 commit comments

Comments
 (0)