bill
Contains functionalities to receive the receipts from the POS.
Having problems? Contact us at
Release History
2.3.0
Upgrade to Gradle 8 and Java Version 17
2.2.3
New Model
LinkedBillInformationwith information about linked bills (e.g. return receipts) included aslinkedBillsinBillMisc2.2.2
New attributes:
Bill.security.tse: New TseTypeBoiTvafor FranceBill.head.additionalHeaderInformation: Additional information which is displayed in the headerEquivalent value can be used to display custom points or payment methods.
Bill.data.equivalentValueNameBill.data.fullEquivalentValue2.2.1
New object
BillErrorsholding consts for custom errors returned from the bill moduleImplemented methods to integrate addition of bills from AnybillAppLink links. With AnybillAppLink linking from the anybill bill website into mobile apps can be enabled.
BillProvider.addBillFromAppLink()BillProvider.addBillFromAppLinkQueue()BillProvider.clearAppLinkQueue()Moved
AnybillURLUtilsto core module breaking2.2.0
Upgrade to Android API 33 and Gradle 7.4
Remove AndroidThreeTen dependency and replace with coreLibraryDesugaring
2.1.15
Optimize logging.
Adding safe enum parsing, that can deal with invalid enum types in JSON responses.
Improved error handling on bills, now a erroneous bill JSON is ignored and does not cause the getBill calls to fail.
Deprecated some
PaymentTypes as they are not meant to be displayed.2.1.14
Add new enum QuantityMeasure:
KilowattHourImprove internal error logging
2.1.13
Add support for
Pregeneratedbills.Added method
updateHospitalityInformationto update a bills' hospitality data.Add new type of receipt security information
DynamicTSESecurityfor arbitrary security key value pairs.Add support for all currency symbols to
CurrencyUtils.2.1.12
Add new AfterSalesCouponType
Ean128.2.1.11
New Method: deleteBills(billIds: List
) You can now delete mutliple bills of the user's bill list at once
LiveData object BillProvider.bills now uses lazy initialized Flow of Room Database
2.1.10
Fix bug where discounts of bills weren't parsed correctly
Add extension function
getDetailDiscount(detailDiscounts: List<Discount>)to Defaultline to get detailed Discounts for a specific line.2.1.8
Add new method
BillProvider.updateIsFavourite(billId: String, isFavourite: Boolean)to mark a bill as favourite.The anybill sdk automatically updates the bill list, if a new bill is added to the users account
Implement
AnybillMessagingService.handleAnybillNotificationfrom auth module to forward the notification to the anybill sdkAdd new
ReturnBarCodeType:Barcode2.1.7
Adjust to latest
RuntimeTypeAdapterFactory.javaversion2.1.6
Bugfix:
Fix Serialization bug during parsing of nullable abstract classes
2.1.5
Add new model
RKSVand enumTSEType.BREAKING:
Change type of
NoScanBill.security.tseto an abstract classTSEBase.TSEBasecan be one of its subclassesTSEorRKSVdetermined by it's parametertype.2.1.4
Add
AnybillURLUtilswhich can be used to check URLs/Strings for existing bill id. (E.g. after scanning a POS QR Code)Change Return of
addBillByID/addBillByURltoBillAddedResponsewhich contains the added id and a flag which determines if the bill is a "Pregenerated" Bill. Further information to Pregenerated Bills can be found here.2.1.3
Made values of
UpsertBillDTOeditable.Bills should now be updated by filling the
UpsertBillDTOwith the bill's previous values. New changes should then be applied on theUpsertBillDTOafterwards.2.1.2
Remove deprecated parameter
idfrom allPaymentDetails-types2.1.1
Extend Bill Model with values:
Misc.isHospitalityBill,Misc.hospitalityBillInformation,Misk.customSections,Misk.contentAreaIdHead.creditorIdData.fullAmountInclVatBeforeDiscounts,Data.tipSee documentation for detailed description of usage
Add method to update
NoScanBills. UseBillprovider.updateBill()with anUpsertBillDTO.2.1.0
Upgrade to Gradle 7 and Java 11
Improve caching algorithm by changing Room queries
Add CurrencyUtils object including helper functions for currency Strings
2.0.2
Improve internal logging
2.0.1
Upgrade dependencies
2.0.0
Refactor bill model to new anybill API Version
More detailed model for Bills based on the DFKA (v1.0.0)
Improve serialization of bill models by extending null safety
1.1.3
Made parameter
nameinLineItemnullable1.1.2
Replaced deprecated LocalBroadcastManager
1.1.1
Extend
Warrantymodel with notification flag1.1.0
Reset version number on Artifactory Move
Resolving the artifact using gradle:
Add this to your project's build.gradle with:
allprojects {
repositories {
maven {
url "https://anybill.jfrog.io/artifactory/anybill_android_sdk"
credentials {
username = {username}
password = {password}
}
}
}
}Add this to your module's build.gradle:
dependencies {
implementation 'de.anybill.anybill_android_sdk:bill:{latest version}'
}Resolving the artifact using maven:
Add this to your settings.xml:
<?xml version="1.0" encoding="UTF-8"?>
<settings
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"
xmlns="http://maven.apache.org/SETTINGS/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<servers>
<server>
<username>${security.getCurrentUsername()}</username>
<password>${security.getEscapedEncryptedPassword()!"*** Insert encrypted password here ***"}</password>
<id>central</id>
</server>
<server>
<username>${security.getCurrentUsername()}</username>
<password>${security.getEscapedEncryptedPassword()!"*** Insert encrypted password here ***"}</password>
<id>snapshots</id>
</server>
</servers>
<profiles>
<profile>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>maven-release</name>
<url>https://anybill.jfrog.io/artifactory/maven-release</url>
</repository>
<repository>
<snapshots />
<id>snapshots</id>
<name>maven-release</name>
<url>https://anybill.jfrog.io/artifactory/maven-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>maven-release</name>
<url>https://anybill.jfrog.io/artifactory/maven-release</url>
</pluginRepository>
<pluginRepository>
<snapshots />
<id>snapshots</id>
<name>maven-release</name>
<url>https://anybill.jfrog.io/artifactory/maven-release</url>
</pluginRepository>
</pluginRepositories>
<id>artifactory</id>
</profile>
</profiles>
<activeProfiles>
<activeProfile>artifactory</activeProfile>
</activeProfiles>
</settings>Add this dependency:
<dependency>
<groupId>de.anybill.anybill_android_sdk</groupId>
<artifactId>bill</artifactId>
<version>{latest version}</version>
<type>pom</type>
</dependency>Required modules
The bill module depends on the following anybill SDK modules and can't be used without them:
:core
:authThe bill module is part of the SDK's core functions which consists of the following SDK modules:
:core
:bill
:auth
:category
:logPlease add the corresponding dependencies to your module's build.gradle.
Coming soon: Single dependency for the SDK's core functions.
Usage
Error Handling
The anybill sdk uses a custom error handling model. All methods return a type of the sealed class ApiResult, including the return object on success and/or information about the error which occurred. Detailed description of the possible error codes can be found in the corresponding documentation of the methods
sealed class ApiResult<out T> {
/**
* Success\
* Used when Api Call and serialization was successful\
*
* @param T Type [T] of the object which should be returned if Api call and JSON Serialization was successful
* @property value Object of type [T] holding the serialized result of the api call
*/
data class Success<out T>(val value: T) : ApiResult<T>()
/**
* Generic error\
* Used if a generic error occurs during execution of the api call or serialization of the received data\
* Possible GenericError's of each operation are listed in the method documentation
*
* @property code Nullable [Int] with the Error Code of the exception
* @property error Nullable [ErrorResponse] object with further exception information
*/
data class GenericError(val code: Int? = null, val error: ErrorResponse? = null) : ApiResult<Nothing>()
/**
* Empty success\
* Used if the execution of the api call and the serialization of the result was successful without a need of a result object (e.g. token operations)\
*
*/
object EmptySuccess : ApiResult<Nothing>()
/**
* Network error\
* Used if a network error occurs during execution of the api call (e.g. timeout, no network)
*/
object NetworkError : ApiResult<Nothing>()
}Example usage of the error model based on the loginCall of the AuthProvider.
fun loginUser(email: String, password: String) {
viewModelScope.launch {
when (val loginTask = AuthProvider.loginUser(email = email, password = password)) {
is NetworkError -> //Error Handling
is GenericError -> {
when(loginTask.code){
INVALID_DATA -> //Error Handling
SERVER_ERROR -> //Error Handling
REFRESH_ERROR -> //Error Handling
}
}
is EmptySuccess -> //Success
}
}
}Example usage of the public provider and models:
Providers
BillProvider
Singleton provider granting access to the anybill bill functions. Most functions of the BillProvider are suspend functions and have to be called in a coroutine scope.
Retrieving user's bills
With its caching technique the anybill sdk stores the user's bills in a local database and updates them using the anybill backend when needed. The anybill sdk provides a LiveData object bills representing a list of bills which can be observed in your app. By calling BillProvider's updateBills() method the LiveData object gets filled with the locally cached bills first and updated with the newly modified/added bills as soon as the API operation completed.
Sample-Code for your ViewModel:
//This LiveData can be observed in your View
val billList : LiveData<List<Bill>> = BillProvider.bills
//Call this to initialize/fill/update the LiveData object
fun updateBills(){
viewModelScope.launch{
BillProvider.updateBills()
}
}To receive all of the user's bills without the caching process the anybill sdk provides the getBills() (includes parameters for pagination) method.
val billList: MutableLiveData<Bill> = MutableLiveData<Bill>()
fun getAllBills(){
viewModelScope.launch {
when (val billCall = BillProvider.getBills()) {
is NetworkError -> //Error Handling
is GenericError -> //Error Handling
is Success -> {
billList.postValue(billCall.value)
}
}
}
}To get all Bills by Category (see Category module) use 'getBillsFromCategory(categoryId: String)'.
Adding bills
The anybill SDK provides several ways to add a Bill to the users account.
QR-Code on POS-Terminal
To add a bill from the QR-Code on the POS-Terminal use a common QR-Code Reader and extract the information of the shown QR Code. The data includes an URL with the ID of the Bill which should be added to the users account. Add the bill by calling on of the listed Methods with your preferred parameter type.
//Depending on the QR Code Scanner you are going to receive a String or URL object.
//
//Format:
// https://getmy.anybill.de/#/bill/b45f4b77-9c3c-454a-8b87-08d8bbd02f7e
//
//You can choose to parse and validate the URL before using the sdk or call one of the following methods:
BillProvider.addBillByID(billID: String)
BillProvider.addBillByURL(url: URL)
BillProvider.addBillByString(url: String)QR-Code on Mobile-Screen
To add a bill with a QR-Code on the user's phone screen use AuthProviders QR-Code Data method. (See auth module documentation)
Exporting bills
To share or save a bill as PDF exportBillAsPDF(bill: Bill) returns an URI of a PDF file in the cached directory of the app. The Uri can then be shared using an intent or saved on the user's device. (Generation of the PDF file takes up to 30 sec)
Share PDF in other apps:
fun exportBillToPDF(bill: Bill) {
viewModelScope.launch {
when (val exportCall = billProvider.exportBillAsPDF(bill)) {
is ApiResult.Success -> startIntent(exportCall.value)
is ApiResult.GenericError -> //Error Handling
is ApiResult.NetworkError -> //Error Handling
}
}
}
private fun startIntent(uri: Uri) {
val intent = Intent()
intent.action = Intent.ACTION_SEND
intent.type = "application/pdf"
intent.putExtra(Intent.EXTRA_STREAM, uri)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(share)
}ZIP
If the user wants to get hold of all his bills as PDF files, the anybill SDK provides an endpoint to generate a .zip file containing the user's bills and send it to his email address.
fun exportAllBills() {
viewModelScope.launch {
when(val exportCall = billProvider.exportBills()){
is ApiResult.EmptySuccess -> //Success
is ApiResult.GenericError -> //Error Handling
is ApiResult.NetworkError -> //Error Handling
}
}
}Deleting bills
Deleting a bill is irreversible. After deleting a bill with BillProvider.deleteBill(bill: Bill) the LiveData object should be updated using updateBills().
Models
Bill
Bill
Bill is an abstract class and represents both ScanBill and NoScanBill which are distinguish through the type parameter.
ScanBill
Bills of type ScanBill represent all bills created or added by the user. Either manually or with the OCR scan (OCR module). It's not mandatory for ScanBills to have a OCR scan or images.
NoScanBill
Bills of type NoScanBill are solely created by the anybill API (e.g. the POS-Terminal).
Detailed description of the structure and function of models/variables can be found in the code or provided KDoc.