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 LinkedBillInformation with information about linked bills (e.g. return receipts) included as linkedBills in BillMisc

  • 2.2.2

    • New attributes:

      • Bill.security.tse: New TseType BoiTva for France

      • Bill.head.additionalHeaderInformation: Additional information which is displayed in the header

      • Equivalent value can be used to display custom points or payment methods.

        • Bill.data.equivalentValueName

        • Bill.data.fullEquivalentValue

  • 2.2.1

    • New object BillErrors holding consts for custom errors returned from the bill module

    • Implemented 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 AnybillURLUtils to core module breaking

  • 2.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: KilowattHour

    • Improve internal error logging

  • 2.1.13

    • Add support for Pregenerated bills.

    • Added method updateHospitalityInformation to update a bills' hospitality data.

    • Add new type of receipt security information DynamicTSESecurity for 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.handleAnybillNotification from auth module to forward the notification to the anybill sdk

    • Add new ReturnBarCodeType: Barcode

  • 2.1.7

    • Adjust to latest RuntimeTypeAdapterFactory.java version

  • 2.1.6

    • Bugfix:

      • Fix Serialization bug during parsing of nullable abstract classes

  • 2.1.5

    • Add new model RKSV and enum TSEType.

    • BREAKING:

      • Change type of NoScanBill.security.tse to an abstract class TSEBase. TSEBase can be one of its subclasses TSE or RKSV determined by it's parameter type.

  • 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 to BillAddedResponse 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 the UpsertBillDTO afterwards.

  • 2.1.2

    • Remove deprecated parameter id from all PaymentDetails-types

  • 2.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. Use Billprovider.updateBill() with an UpsertBillDTO.

  • 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 in LineItem nullable

  • 1.1.2

    • Replaced deprecated LocalBroadcastManager

  • 1.1.1

    • Extend Warranty model with notification flag

  • 1.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

PDF

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.

Packages