bill
Version: 2.1.5
Contains functionalities to receive the receipts from the POS.
Having problems? Contact us at <dev@anybill.de>
Release History
2.1.5
Add new model
RKSV
and enumTSEType
.BREAKING:
Change type of
NoScanBill.security.tse
to an abstract classTSEBase
.TSEBase
can be one of its subclassesTSE
orRKSV
determined by it's parametertype
.2.1.4
Add
AnybillURLUtils
which can be used to check URLs/Strings for existing bill id. (E.g. after scanning a POS QR Code)Change Return of
addBillByID
/addBillByURl
toBillAddedResponse
which 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
UpsertBillDTO
editable.Bills should now be updated by filling the
UpsertBillDTO
with the bill's previous values. New changes should then be applied on theUpsertBillDTO
afterwards.2.1.2
Remove deprecated parameter
id
from allPaymentDetails
-types2.1.1
Extend Bill Model with values:
Misc.isHospitalityBill
,Misc.hospitalityBillInformation
,Misk.customSections
,Misk.contentAreaId
Head.creditorId
Data.fullAmountInclVatBeforeDiscounts
,Data.tip
See 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
name
inLineItem
nullable1.1.2
Replaced deprecated LocalBroadcastManager
1.1.1
Extend
Warranty
model 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
:auth
The bill module is part of the SDK's core functions which consists of the following SDK modules:
:core
:bill
:auth
:category
:log
Please 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.