Skip to content

yllibed/TenantCloudClient

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Yllibed's TenantCloud API Client Library

This is an unofficial dotnet API client library to connect to TenantCloud, a cheap / free online Rental Accounting and Management system.

Build Status Nuget

Note: the goal of this API right now is to query the TenantCloud system. There's no way to make updates to data yet.

Quickstart

  1. Add a reference to the Yllibed.TenantCloudClient nuget package in the project
  2. Create a TenantCloud context:
        var tcContext = new InMemoryTcContext("username@domain.tld", "password");
  3. Make a call:
    public async RefreshTenants(CancellationToken ct, TenantCloudContext tcContext)
    {
        var client = new TcClient(tcContext);
        var activeTenants = await client.Tenants.GetAll(ct);
    
        // do something funny with activeTenants here...
    }

Features

  • Coded using DOTNETSTANDARD2.1, it means it works on:
    • Dotnet Core 3.0+
    • Xamarin (iOS 12.16+ & Android 10+)
    • Most other Mono 6.4+ environment, except WebAssembly like Blazor or Uno.BootStrapper because they need a custom http handler - open an issue if you need support for those.
  • Will automatically renew the authentication token.
  • Absolutely no external dependency (except System.Text.Json but it's now part of the framework)
  • No enforced patterns: your code is responsible for the token persistence and the security of credentials.
  • Compatible with most/all IoC containers.

API Details

ITcClient:

Implemented by the class Yllibed.TenantCloudClient.TcClient.

Member Type Usage
GetUserInfo (method) Task<TcUserInfo?> Get information about the current signed-in user.
Tenants (property) IPaginatedSource<TcTenantDetails> Get information about tenants
Properties (property) IPaginatedSource<TcProperty> Get information about properties
Units (property) IPaginatedSource<TcUnit> Get information about rented units
Transactions (property) IPaginatedSource<TcTransaction> Get transactions. Transactions are always in reversed chronologic order.

IPaginatedSource<T>:

This interface let you get the T items from the API. Results are actually fetched when the .GetAll() method is used.

  • It's possible to specify a maxResults to the .GetAll() method to limit the number of results. The TenantCloud API will be fetched using their pagination system until the maxResults is reached. This means the .GetAll() can return more items than speficied, since it won't slice the last page to the number of maxResults. Example:

    var results = await tcCLient.Transactions
       .ForCategory(TcTransactionCategory.Expense)
       .ForStatus(TcTransactionStatus.Overdue)
       .GetAll(ct, maxResults: 20);
  • The .GetAll() method is returning the type ReadOnlySequence<T>, which is specialized in returning a list with multiple segments (one per fetched page). If you need to process the results using standard LINQ operators, there's a .AsEnumerable() extension method available for that. Example:

    var results = await tcClient.Tenants.OnlyNoLease().GetAll(ct);
    var nameEmailsAndPhones = results // results is of type ReadOnlySequence<TcTenantDetails>
        .AsEnumerable() // required to use LINQ operators
        .Select(t=>(t.Name, t.ValidEmails, t.ValidPhones))
        .ToArray();

Tenants (of type IPaginatedSource<TcTenantDetails>)

Will return all non-archived tenants.

  • .OnlyMovedIn() to filter to "moved in" tenants (with at lease one active lease)
  • .OnlyArchived() to get archived tenants (this one is not filtering the result, but will return archived instead)
  • .OnlyNoLease() to filter to tenants without active leases (not "moved in")

Properties (of type IPaginatedSource<TcProperty>)

Will return all active (non-archived) properties. No extension methods for this yet.

Units (of type IPaginatedSource<TcUnit>)

Will return tenants. Following filters are possible:

  • .OnlyOccuped() to filter to units with at least one active lease
  • .OnlyVacant() to filter to vacant units
  • .ForProperty(propertyId) to filter for a specific property

Transactions (of type IPaginatedSource<TcTransaction>)

Will return transactions in reversed chronological order. Following filters are possible:

  • .ForTenant(tenantId) to filter for a specific tenant
  • .ForProperty(propertyId) to filter for a specific property
  • .ForUnit(unitId) to filter for a specific unit
  • .ForStatus(status) to filter to a specific TcTransactionStatus. Possible values:
    • TcTransactionStatus.Due
    • TcTransactionStatus.Paid
    • TcTransactionStatus.Partial
    • TcTransactionStatus.Pending
    • TcTransactionStatus.Void
    • TcTransactionStatus.WithBalance
    • TcTransactionStatus.Overdue
    • TcTransactionStatus.Waive
  • .ForCategory(category) to filter to a specific TcTransactionCategory. Possible values:
    • TcTransactionCategory.Income
    • TcTransactionCategory.Expense
    • TcTransactionCategory.Refund
    • TcTransactionCategory.Credits
    • TcTransactionCategory.Liability

Example usages of .Transactions:

// Check if a tenant is having any overdue lease
var isHavingOverdue = (await tcClient.Transactions
	    .ForCategory(TcTransactionCategory.Income)
	    .ForStatus(TcTransactionStatus.Overdue)
	    .ForTenant(tenantId)
	    .GetAll(ct, maxResults: 1))
    .AsEnumerable()
    .Any();

// Get total balance of per property
var balancePerProperty = (await tcClient.Transactions
	    .ForCategory(TcTransactionCategory.Income)
	    .ForStatus(TcTransactionStatus.WithBalance)
	    .GetAll(ct))
    .AsEnumerable()
	.Where(t => t.PropertyId != null) // only property-specific income
    .GroupBy(t => (long)t.PropertyId, t => t.Balance) // group them
    .Select(g => (property: g.Key, balance: g.Sum())) // summarize
    .ToArray(); // create final array