class ReceiptDatabaseAdapter implements SelectionBackedDatabaseAdapter<Receipt, Trip> {

    @NonNull
    @Override
    public ContentValues write(@NonNull Receipt receipt, @NonNull DatabaseOperationMetadata databaseOperationMetadata) {
        final ContentValues values = new ContentValues();

        // Add core data
        values.put(ReceiptsTable.COLUMN_PARENT_TRIP_ID, receipt.getTrip().getId());
        values.put(ReceiptsTable.COLUMN_NAME, receipt.getName().trim());
        values.put(ReceiptsTable.COLUMN_CATEGORY_ID, receipt.getCategory().getId());
        values.put(ReceiptsTable.COLUMN_DATE, receipt.getDate().getTime());
        values.put(ReceiptsTable.COLUMN_TIMEZONE, receipt.getTimeZone().getID());
        values.put(ReceiptsTable.COLUMN_COMMENT, receipt.getComment());
        values.put(ReceiptsTable.COLUMN_ISO4217, receipt.getPrice().getCurrencyCode());
        values.put(ReceiptsTable.COLUMN_REIMBURSABLE, receipt.isReimbursable());
        values.put(ReceiptsTable.COLUMN_NOTFULLPAGEIMAGE, !receipt.isFullPage());
        values.put(ReceiptsTable.COLUMN_UUID, receipt.getUuid().toString());
        values.put(ReceiptsTable.COLUMN_NAME_HIDDEN_AUTO_COMPLETE, receipt.getAutoCompleteMetadata().isNameHiddenFromAutoComplete());
        values.put(ReceiptsTable.COLUMN_COMMENT_HIDDEN_AUTO_COMPLETE, receipt.getAutoCompleteMetadata().isCommentHiddenFromAutoComplete());

        // Add file
        final File file = receipt.getFile();
        if (file != null) {
            values.put(ReceiptsTable.COLUMN_PATH, file.getName());
        } else {
            values.put(ReceiptsTable.COLUMN_PATH, (String) null);
        }

        // Add payment method if one exists
        values.put(ReceiptsTable.COLUMN_PAYMENT_METHOD_ID, receipt.getPaymentMethod().getId());


        // Note: We replace the commas here with decimals to avoid database bugs around parsing decimal values
        // TODO: Ensure this logic works for prices like "1,234.56"
        values.put(ReceiptsTable.COLUMN_PRICE, receipt.getPrice().getPrice().doubleValue());
        values.put(ReceiptsTable.COLUMN_TAX, receipt.getTax().getPrice().doubleValue());
        values.put(ReceiptsTable.COLUMN_TAX2, receipt.getTax2().getPrice().doubleValue());
        final BigDecimal exchangeRate = receipt.getPrice().getExchangeRate().getExchangeRate(receipt.getTrip().getDefaultCurrencyCode());
        if (exchangeRate != null) {
            values.put(ReceiptsTable.COLUMN_EXCHANGE_RATE, exchangeRate.doubleValue());
        }

        // Add extras
        values.put(ReceiptsTable.COLUMN_EXTRA_EDITTEXT_1, receipt.getExtraEditText1());
        values.put(ReceiptsTable.COLUMN_EXTRA_EDITTEXT_2, receipt.getExtraEditText2());
        values.put(ReceiptsTable.COLUMN_EXTRA_EDITTEXT_3, receipt.getExtraEditText3());
        if (databaseOperationMetadata.getOperationFamilyType() == OperationFamilyType.Sync) {
            values.putAll(mSyncStateAdapter.write(receipt.getSyncState()));
        } else {
            values.putAll(mSyncStateAdapter.writeUnsynced(receipt.getSyncState()));
        }

        values.put(ReceiptsTable.COLUMN_CUSTOM_ORDER_ID, receipt.getCustomOrderId());

        return values;
    }

    public  ReceiptDatabaseAdapter(@NonNull Table<Trip> tripsTable, @NonNull Table<PaymentMethod> paymentMethodTable,
                                  @NonNull Table<Category> categoriesTable, @NonNull StorageManager storageManager);
    public  ReceiptDatabaseAdapter(@NonNull Table<Trip> tripsTable, @NonNull Table<PaymentMethod> paymentMethodTable,
                                  @NonNull Table<Category> categoriesTable, @NonNull StorageManager storageManager,
                                  @NonNull SyncStateAdapter syncStateAdapter);

}