Autobilling
Solutech Licensing and Billing Automation System
Solutech SAT Autobilling
Welcome to the Autobilling section of Solutech SAT documentation. This section provides an overview of the Autobilling system, which automates the licensing and billing processes for Solutech SAT users.
Solutech Products Licensing
Technical Documentation
Purpose
The purpose of this document is to document how Solutech is going to implement licensing of its products across the board. From Kodie, SAT, KaziTime and any future innovations. Why we are doing this is to avoid the following scenarios:
- Having back and forth with the finance team on how much should be billed. We spent a lot of time waiting for customers to approve estimates.
- This document will contain up to date information of the any new innovation and their billable details hence information for everyone in the organization
- A software license documentation also provides legally binding definitions for the distribution and use of the software. End-user rights, such as installation, warranties, and liabilities, are also often spelled out in the software license, including protection of the developer’s intellectual property.
Solutech Products
Solutech Products refer to any Solutech Innovations. Currently, these are:
- Solutech SAT (We need a better name for this)
- Kodie
- KaziTime
- Dukasoft
- CRM
Explanation
For any client to use Solutech Products, they will be required to purchase licenses first. The key metrics will be:
- Type of Product
- Billing Cycle - Daily, Monthly, Bi Monthly, Quarterly, Semi Annually, Annually
- Number of Licenses
- Amount (Will be pre determined by the sales/finance team and set for that client on the Admin Portal). Solutech might need to pre-define non-negotiable prices in future.
Process Flow
Single Tenant Flow
- Client Account is created on Admin Portal.
- Client Contact for Finance is added to the created account. The contact has to be per the contact in the blue print document from the project kick off meeting.
- These details are synched to Zoho Books and a new account is created. The following fields are required for a new account creation on Zoho Books
- Company Name
- Clients Address
- Clients Tax PIN
- Currency i.e KES or USD
- Tax rule i.e. Tax rule for VAT , Zero rated or Exempt
- Billing Cycle (Monthly, Two Months, Quarterly etc)
- Credit Term (30 Days, 60 Days etc)
- Amount of licenses the client needs are set on the billing account of the client per the explanation above by:
- Selecting the product i.e. Solutech SAT
- Selecting the product item i.e. Software License
- Selecting the license (i.e. Billable, Free)
- Selecting the license type (i.e Users, Admins, All Users)
- Entering the number of Licenses.
- Entering the amount (Per the Sales Contract) as at the time being, various clients have different negotiated rates.
- Selecting the billing cycle (i.e Monthly, Quarterly etc)
- Selecting the start of the billing period. This will auto populate the client_billing_cycles per the billing cycle. E.g. for a monthly client with a start billing_date of 1st April, this table will be auto populated with the rest of the months in the year.
- Once the Licenses information has been fed into the system, a Billing License Email will be sent to the Client Finance Contact, copying Solutech’s Accounts on the details of the licenses.
- The license quantities should be pushed to SAT deployment of the client with information about:
- Billable Licenses Qty - Licenses which need to be billed. Can be : Admins, Users or All Users
- Free Licenses Qty - Licenses issued to client for free (mostly for admins)
- Non Billable Licenses Qty - Solutech accounts only
- When creating/importing users in SAT, a check should always be made against the allowable licenses and the sub license type (admin, users, all users). Only the permissible licenses should be displayed on SAT i.e if a client only has Billable Licenses, when creating a user, the system should only show option for allocating Billable License. When a Client has run out of Licenses, they won’t be able to create new user accounts on SAT. The system should inform that their Finance Personnel should purchase or requisition the licenses.
Purchasing Additional Licenses
- To purchase additional licenses, the Finance Contact Personnel will login to SAT and specify: The number of licenses to purchase per license type. E.g. 5 All Users Licenses
Depending the existing rate for the client, this will compute new additional amount that will be added to the client’s invoicing depending on the billing cycle of the client:
For monthly billing, depending on the date the new licenses are purchased, the total amount will be prorated per the remaining days in the month and added into the current month's billing, to be billed at the end of the month with clear definition of the licenses added and when they were added.
For example, if a client has 10 licenses and on 20th March, they purchase 2 additional licenses, their billing on 1st April will be 10 licenses for 30 days (for April) and 2 licenses for 42 days (20th to 31st March plus 30 days in April). Remember invoices are billed in advance.
For quarterly billing, the above procedure for monthly will be followed and the invoice will be added into the quarterly billing. For quarterly in advance billing, the invoice will be sent immediately to the client. For quarterly after, the invoice will be sent in the next billing cycle.
For annual billing, the above procedure for monthly will be followed but the invoice will be send immediately to the client.
Reducing Number of Licenses
- If a client requires to reduce their licenses, the Finance Personnel will login to SAT and deactivate a user(s). The system should indicate how many available licenses are left unused and let the personnel decide if to delete them or leave them. De activating a user does not reduce number of licenses. To reduce number of licenses, after deactivating a user, the license has to be deleted. NB: To see option to delete a license, a user has to be deactivated first. (Alternatively, deleting their license deactivates the user automatically) Once a user is deactivated, they can be:
- Re-activated if the license has not been re-used by adding another user.
- Else, if license has been used, a user cannot be re-activated, and a license has to be purchased first.
Deleting a license will have no impact on the invoice as the client has already been billed. Licenses have to be deleted before the start of the customer’s billing cycle, otherwise, we will bill based on the licenses a client has on 1st of every month at 8AM EAT.
Proposed Changes
- Solutech needs to adopt a multi layered pricing model for monthly, quarterly and annual billing.
- Higher pricing for monthly customers, moderate for quarterly customers and cheap for annual customers. e.g.
| Monthly | Quarterly | Semi Annually | Annually | |
|---|---|---|---|---|
| Price (KES) | KES 2,500 | KES 2,000 | KES 1750 | KES 1,500 |
| Price (USD) | USD 25 | USD 20 | USD 17.5 | USD 15 |
Cancelling Subscription
If a customer intends to cancel their subscription of a Solutech product, they can only do so at the end of their current billing cycle. This means that for a monthly customer, they cannot cancel in between the month, quarterly cannot cancel in between a quarter, semi annually cannot canel in between this period of 6 months, yearly cannot cancel in between the year.
Handling Credit Limits
All customers invoice will have 30 days credit limit and all invoices will fall due at the end of the current invoicing month, whichever comes first. This means that for a Feb invoice, it falls due on 28th or 29th.
It is expected that a customer settles their invoice within the credit days and failure to do so will result in the following measures being taken:
Depending on the day they make the payment, their credit days will be reduced per the days the payment surpassed the credit days. For example, for an invoice done on 1st March due on 31st March, and the client pays on 5th April, means that Solutech will have switched off services on 1st April.
Solutech will not issue an invoice on 1st April as the client’s services have been suspended temporarily until a payment is done.
When the payment is done on 5th April, Solutech will restore services and issue an invoice for the remaining days in April
Multi Tenant Flow
- For Multi Tenant Clients, the client will create their own account from the respective system. (We will determine if to create an extra subdomain e.g users.solutechapp.com to just allow onboarding of new tenants or whether to do this from admin.
- During the onboarding process, the client will be required to enter their details the details of the company including all tax data requirements, the number of licenses they require etc. We can determine if to offer a free trial and the period for such trials. Thereafter, the billing cycle will kick in.
- Depending on the name of the company per registration documents, the system will generate a client code. The code generation algorithm needs to be really good to ensure suitable client codes are generated correctly. However, we will need an extra eye to confirm the code before it is allocated to the client and communicated to email.
- The confirmation of the client code will be done after the client purchases licenses to begin using the system.
Technical
ADMIN PORTAL TABLES
licenses Fully documented on Jira ✅
This table will hold all the license information to distinguish the different licenses Solutech offers as sometimes we do offer free licenses to customers.
| id | Auto Increment |
|---|---|
| category | license, amc |
| name | Billable LicensesFree LicensesNon Billable LicensesAMC Promoters |
| slug | billable, free, non_billable, amc, promoters |
| bill | yes/no |
| status_id | Status ID from Status Table |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
license_types
Fully documented on Jira ✅
This table will hold info about the types of licenses for the various licenses.
| id | Auto Increment |
|---|---|
| name | AdminsUsersAll Users |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
products Fully documented on Jira ✅
This table will hold all the products information e.g. Solutech SAT, Kodie etc. This is because a client might be being offered multiple products by Solutech with different pricing and license quantities.
| id | Auto Increment |
|---|---|
| name | Solutech SAT, Kodie |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
product_items Fully documented on Jira ✅
A product has multiple items like licenses, setup fees, etc, but for now we will depend on the items created in Zoho Books
| id | Auto Increment |
|---|---|
| erp_code (Nullable) | Line Item Code from Zoho Books |
| hs_id (Nullable) | Product Item HS ID |
| name | Name of Line Item |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time of syncing to ERP |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
payment_modes Fully documented on Jira ✅
This table will hold all the payment modes.
| id | Auto Increment |
|---|---|
| name | Cheque, Mpesa, Bank Transfer, etc |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
In future, we might look at having payment aggregators to enable clients make payments directly to us.
taxes Fully documented on Jira ✅
Different countries we serve might impose various taxes on the services we offer to clients in those countries. Hence, this table will contain the tax information of such taxes.
| id | Auto Increment |
|---|---|
| erp_code (Nullable, Unique) | Tax ID on Zoho Books |
| name | 16% Digital Tax |
| rate | 16 |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time of syncing to ERP |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
product_items_hs_codes Fully documented on Jira ✅
For non vatable clients, when sending invoice to KRA, we need to define the export services hs code on the invoice if the product item has been tied to a product hs code.
| id | Auto Increment |
|---|---|
| tax_id | Tax ID |
| code | HS Code |
| name | Zero Rated Services |
| description | Zero Tax on Export Services |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
billing_cycles Fully documented on Jira ✅
This will hold the frequency of how clients are billed, i.e. Monthly, Quarterly etc
| id | Auto Increment |
|---|---|
| name | MonthlyTwo MonthsQuarterlyBi AnnuallyAnnually |
| months | 123612 |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
credit_terms Fully documented on Jira ✅
Different clients might have various credit terms with Solutech and these will be kept in this table.
| id | Auto Increment |
|---|---|
| name | 30 Days, 60 Days, 90 Days etc. |
| days | 30, 60, 90 |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
accounts Fully documented on Jira ✅
A client may pay into a specific account maintained by Solutech and this needs to be captured.
| id | Auto Increment |
|---|---|
| erp_code (Nullable) | Account ID on Zoho Books |
| name | Name |
| currency_id | Currency ID on Admin |
| bank_name | Bank Name |
| bank_branch | Branch |
| bank_account_number | Account Number |
| bank_code | Bank Code |
| paybill_type | Mpesa etc |
| paybill_number | 982800 |
| paybill_account_number | Some cases can be different from Account Number |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time of syncing to ERP |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
currencies Fully documented on Jira ✅
This will hold the details of the currencies Solutech invoices in.
| id | Auto Increment |
|---|---|
| erp_code (Nullable) | Currency ID on Zoho Books |
| code | USD, KES |
| symbol | $, KES |
| base | True, False |
| name | United States Dollar, Kenya Shillings |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time of syncing to ERP |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
currency_rates Fully documented on Jira ✅
This will hold the details of the exchange rates of the currencies
| id | Auto Increment |
|---|---|
| base_currency_id | Base Currency ID |
| exchange_currency_id | The Currency being exchanged |
| rate | 140 |
| date | Date (Unique for the specific day) |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
tax_devices Fully documented on Jira ✅
This will hold the details of the TIMS device.
| id | Auto Increment |
|---|---|
| name | Tevin Device |
| type | Tevin, Aclas (Dropdown) |
| ip_address | IP Address of the Device |
| sender_id | Sender ID of the Device |
| serial_number | Serial Number of the Device |
| port_number | Port Number of the Device |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
subscription_types Fully documented on Jira ✅
This table will differentiate subscription types because of training purposes and go live.
| id | Auto Increment |
|---|---|
| name | Name |
| slug | |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
integrations Fully documented on Jira ✅
This will hold the details of the Integrations Service.
| id | Auto Increment |
|---|---|
| name | Integration Service e.g. Zoho Books |
| slug | erp |
| client_id | Oauth Client ID |
| client_secret | Oauth Client Secret |
| oauth_url | Oauth URL |
| redirect_url | Redirect URL |
| status_id | Status ID (Active, Inactive) |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
integration_details Fully documented on Jira ✅
This will hold the details of the Integrations Service for token management.
| id | Auto Increment |
|---|---|
| integration_id | Integration ID |
| access_token | Access Token generated by the service |
| refresh_token | Refresh Token for generating new token when existing one expires |
| expires_in | Time in seconds when the token expires |
| expired_at | Date when the token expired/will expire |
| status_id | Status ID (Active, Inactive) |
| created_at, updated_at, deleted_at |
tbl_clients_configurations Fully documented on Jira ✅
New additions to clients table.
| tax_id | Tax ID |
|---|---|
| credit_term_id | This will determine when the invoice falls due. If invoice is not settled by this date, the client will be unable to use the system. |
| billing_cycle_id | Billing Cycle ID |
| address | The billing address |
| postal_code (Nullable) | The postal code |
| city (Nullable) | City |
| sync_to_erp | Yes, No (To prevent demo clients in Zoho) |
| erp_code (Nullable) | Customer ID from Zoho Books |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time of syncing to ERP |
tbl_users Fully documented on Jira ✅
New additions to users table.
When a new user is added, the following should be done: If they are of contact type - solutech_account (check using slug), create an entry in client_users for all active clients with sync_to_solutech as Yes so that the user can be synced to all clients.
| erp_code (Nullable) | Contact ID from Zoho Books |
|---|---|
| contact_type_id (Nullable) | Contact Type ID |
| sync_to_erp | Yes, No |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time of syncing to ERP |
contact_types Fully documented on Jira ✅
New table to cater for contact types. This is not to be confused with user types (Admin, Supervisor, User)
| id | Auto Increment |
|---|---|
| name | Billing, Super Admin, Solutech Account |
| slug | billing, super_admin, solutech_account |
| status_id | Status ID |
| created_by | |
| updated_by (Nullable) | |
| created_at, updated_at, deleted_at |
countries Fully documented on Jira ✅
New additions to countries table.
| tax_authority | Name of Tax Authority in each country |
|---|---|
| updated_by (Nullable) | User ID |
client_contacts Fully documented on Jira ✅
The contacts of each client.
When a new client contact is added, the following should be done, create an entry into client_users as well with sync_to_solutech as Yes so that the contact can be synced to SAT of that specific client.
| id | Auto Increment |
|---|---|
| erp_code (Nullable) | Client Contact ID in ERP |
| client_id | Client ID |
| user_id | User ID |
| user_type_id | User Type ID |
| contact_type_id | Contact Type ID |
| erp_sync_status | Yes, No |
| erp_sync_time | Time synced to ERP |
| solutech_sync_status | Yes, No |
| solutech_sync_time | Time synced to Solutech System |
| status_id | Status ID (Active, Inactive) |
| created_by | |
| updated_by (Nullable) | |
| created_at, updated_at, deleted_at |
email_logs Fully documented on Jira ✅
This table will log all communications sent from the system.
| id | Auto Increment |
|---|---|
| user_id | User ID (Nullable) |
| type | invoice, payments etc |
| email_address | Incase an email address is entered manually |
| subject | Subject of the email |
| description | Body of the email |
| created_at, updated_at, deleted_at |
client_subscriptions Fully documented on Jira ✅
This will track which product each client is subscribed to and their billing cycle. If a client’s subscription changes, we unsubscribe the current subscription and create a new record with the new changes. Subsequently, we end the current client licenses and create a new record and update the client_licenses_history accordingly.
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| solutech_id (Nullable) | Solutech System ID |
| product_id | Product ID |
| product_item_id | Product Item ID |
| currency_id | Since we invoice in KES and USD for international clients, we need to keep a track of this in the subscriptions table. In future, we might decide to invoice in a single currency, hence this is important. |
| date_subscribed | Date the client’s subscription starts |
| discount_total (Nullable) | Discount issued to client |
| discount_percent (Nullable) | Discount issued to client |
| date_unsubscribed (Nullable) | Date the client’s subscription ends |
| reason_unsubscribed (Nullable) | |
| created_by | The user who created the subscription |
| updated_by (Nullable) | The user who updated the subscription |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
client_licenses Fully documented on Jira ✅
To keep track of the quantities for each license for the various subscriptions, we create the client_licenses table. If the quantities change, we update the quantities accordingly and create a new record in \ table. Subsequently, we create a new invoice per the existing subscription billing cycle with the new line items.
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| solutech_id (Nullable) | Solutech System ID |
| subscription_id | Subscription ID |
| license_id | License ID |
| license_type_id | License Type ID |
| quantity | The number of licenses for the subscribed product and type of license |
| rate | The rate per the license. (This was removed from client_subscriptions because a client can have different licenses with different rates) |
| rate_type | per_month, per_day |
| start_date | Start date of the license (Available Only For Promoters) |
| end_date | End date/Expiry date of the license (Available Only For Promoters) |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
client_licenses_history Fully documented on Jira ✅
When a client adds new licenses or reduces them, we need to keep track of these changes. We will add this information in this table to preserve the history of the changes.
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| solutech_id (Nullable) | Solutech System ID |
| subscription_id | The existing Subscription ID |
| client_license_id | Client License ID |
| license_type_id | License Type ID |
| current_qty | The existing number of licenses |
| added_qty (Nullable) | Any added licenses |
| removed_qty (Nullable) | Any removed licenses |
| final_qty | The final tally of licenses to be invoiced in the next billing cycle. |
| rate | Incase the rate changes |
| rate_type | per_month, per_day |
| start_date | Start date of the license (Available Only For Promoters) |
| end_date | End date/Expiry date of the license (Available Only For Promoters) |
| change_date (Nullable) | Date when the licenses were changed |
| created_by | User ID |
| updated_by (Nullable) | |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
client_license_days Fully documented on Jira ✅
To keep track of the days a promoter license should be active.
| id | Auto Increment |
|---|---|
| client_license_id | Client License ID |
| solutech_id (Nullable) | Solutech ID |
| day | List of all the license weekdays applicable for promoters. I.e Monday, Tuesday e.t.c This will be used to generate the total number of billable days between the start and the end date, and the days the license should be active. |
| created_by | User ID |
| updated_by | User ID |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
client_billing_cycles Fully documented on Jira ✅
This table will contain information about billing cycles for the purposes of generating invoices through a scheduler. These cycles should always be generated at the start of the year for the entire year. If a client cancels their subscription, the remaining cycles from the date of cancellation should be disabled so that the client is not invoiced.
First, the cron should check the client’s billing cycle, if monthly, run each month If Quarterly, run at the start of the quarter If Semi-Annually, run at the start of Jan and June If Annually, run on 1st Jan.
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| subscription_id | Subscription ID |
| billing_cycle_id | Billing Cycle ID |
| billing_date | The date we expect to bill the client |
| days | The number of days to invoice |
| invoice_date (Nullable) | The date the invoice was generated |
| sent_status | Yes,No |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
invoice_reminders Fully documented on Jira ✅
| id | Auto Increment |
|---|---|
| name | 1st Reminder |
| email_template_id | Select email template for this invoice reminder |
| type | Before_due_date, on_due_date, after_due_date, before_next_billing_cycle |
| days | Days before creation/dispatch of the invoice reminder |
| credit_term_id | Select the credit term to match the client |
| banner_message (optional) | Invoice Banner Message |
| banner_color (optional) | Warning, danger, info, success |
| send_email_reminder (true by default) | Boolean, if set to true, it sends the email reminder to the contacts users |
| is_countdown (optional) | Boolean, if set to true, the reminder works as a countdown banner |
| product_item_id (optional) | Select the product Item that when set, will generate an invoice reminder based on the product item, i.e System setup |
| countdown_days (optional) | Initial countdown days |
| status_id | Status ID (Active, Inactive) |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
invoices Fully documented on Jira ✅
This table will contain information about all invoices generated for clients per their billing cycle.
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| invoice_number | Unique number generated by Solutech |
| doc_id | Document ID |
| erp_code | Unique code generated by Zoho Books |
| solutech_id (Nullable) | Solutech ID |
| tax_invoice_number | Unique number generated by KRA |
| The email to where the invoice is emailed | |
| phone | Phone number of the finance personnel |
| name | The name of the invoice |
| currency_id | The currency in which the invoice is invoiced in |
| address | The billing address of the client |
| city (Nullable) | |
| postal_code (Nullable) | |
| invoice_date | The date the invoice is generated, which should be in line with the billing period |
| sub_total | Qty X Unit Price |
| tax_total | Total tax amount if any |
| discount_total (Nullable) | Total discount issued if any |
| discount_percent (Nullable) | Discount percentage if any |
| gross_total | Sub Total - Discount + Tax Amount |
| due_date | When the invoice is due, per the subscription plan. This is calculated per the credit terms. Consideration for Feb as 1 Month is not necessarily 30 Days. |
| sent_date (Nullable) | The date the invoice was sent to the customer. Because an invoice can be generated before billing cycle due to additions/removals of licenses. |
| tax_qr_code (Nullable) | QR Code generated by KRA TIMS device |
| tax_response (Nullable) | Tax response |
| tax_sync_time (Nullable) | The time the invoice was synced to KRA |
| tax_device (Nullable) | Device used to sync the invoice |
| reminders (Nullable) | Number of reminders sent (Default 0) |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time the invoice is synced to ERP |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| status_id | Status ID (Draft, Partially Paid, Fully Paid, Unpaid) |
| created_at, updated_at, deleted_at |
invoice_items Fully documented on Jira ✅
This table will contain information about all invoices generated for clients per their billing periods.
| id | Auto Increment |
|---|---|
| invoice_id | Invoice ID |
| client_license_id | Client License ID (To keep a track of the product and license which was invoiced) |
| qty | Total number of licenses |
| unit_price | The rate from the subscription table |
| sub_total | Qty X Unit Price |
| tax_total | Total tax amount if any |
| discount_total (Nullable) | Total discount issued if any |
| discount_percent (Nullable) | Discount percentage if any |
| gross_total | Sub Total - Discount + Tax Amount |
| description | Narration of the invoice items e.g. 2 new licenses added on 10th March 2023 |
| status_id | Status ID |
| invoice_item_type | [Upgrade, main] this is used in SAT to display or hide the banner |
| created_at, updated_at, deleted_at |
client_invoice_reminders
Fully documented on Jira ✅
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| invoice_id | Invoice ID |
| reminder_id | Reminder ID |
| date | Date when reminder was done |
| status_id | Active, Inactive |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
payments Fully documented on Jira ✅
When a client makes a payment, we need to capture this information to keep track of unpaid invoices. Once a client makes a full payment, we update the invoice accordingly.
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| invoice_id | Invoice ID |
| erp_code (Nullable) | Unique code generated by Zoho Books |
| solutech_id (Nullable) | Solutech System ID |
| amount | The invoiced amount |
| amount_paid | To keep track of partial payments |
| payment_mode_id | Payment Mode ID |
| account_id | Account ID |
| date_paid | The date the invoice was paid |
| reference | Payment transaction number |
| payer_name (Nullable) | Name of who made payment |
| payer_email (Nullable) | Email of who made payment |
| payer_phone (Nullable) | Phone number of who made payment |
| receipt_date (Nullable) | Date when the receipt was generated |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time of syncing to ERP |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| created_at, updated_at, deleted_at |
receipts
Fully documented on Jira ✅
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| payment_id | Payment ID |
| doc_id | Document ID from documents table |
| erp_code (Nullable) | Unique code generated by Zoho Books |
| solutech_id (Nullable) | Solutech System ID |
| reference | Payment transaction number |
| sent_date | The date the receipt was sent to recipients (payer_email and contact person) |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time of syncing to ERP |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
documents
Fully documented on Jira ✅
This table will keep a track of all uploaded documents - invoices, receipts
| id | Auto Increment |
|---|---|
| reference | Unique reference for updating the document on cloud |
| path | Document ID from documents table |
| name | Invoice, Receipt |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
email_templates
Fully documented on Jira ✅
This table will maintain the data of email templates to ensure there is uniforming of system communication.
| id | Auto Increment |
|---|---|
| name | Invoice Notification |
| slug | new_invoice |
| subject | New Invoice ##Invoice_Number## from Solutech Limited |
| body | The body of the email |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
email_users
Fully documented on Jira ✅
This table will maintain the data of email users to determine who should receive which email communication.
| id | Auto Increment |
|---|---|
| user_id | User ID |
| email_template_id | Email Template ID |
| status_id | Status ID |
| created_by | User ID |
| updated_by (Nullable) | User ID |
| created_at, updated_at, deleted_at |
client_users Fully documented on Jira ✅
When a new account is created, it should be synced to all client deployments.
Modify the existing client_users table to add the following columns
| sat_id | Already Exists (Rename to solutech_id). Make it Nullable. |
|---|---|
| sync_to_solutech | Yes, No |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
Clients, Accounts and Sub Accounts
Rename current tbl_client_configuration to accounts
| tbl_client_configuration | tbl_client_configuration | |||
|---|---|---|---|---|
| clients | client_accounts | client_accounts | sub_accounts | Key |
| id | id | id | id | Clients |
| category_id | client_name | client_id | account_id | Accounts |
| erp_code | client_code | name | country_id | Sub Accounts |
| country_id | account_manager_id | url | cluster_id | Dropped |
| tax_id | category_id | client_oauth_id | manager_id | |
| currency_id | client_url | client_oauth_secret | client_code | |
| credit_term_id | client_type | sync_modules | sat_code | |
| sector_id | client_id | sync_languages | name | |
| type | client_secret | sync_translation_labels | app_icon | |
| logo_image_id | sync_modules | sync_translations | logo_image_id | |
| name | sync_languages | sync_schedules | document_image_id | |
| tax_authority_pin | sync_translation_labels | sync_frequencys | primary_color | |
| tax_number | sync_translations | api_key | accent_color | |
| address | sync_schedules | solutech_sync_status | contrast_color | |
| postal_code | sync_frequencys | solutech_sync_time | splash_icon_size | |
| city | sector_id | created_at | login_icon_size | |
| sync_to_erp | cluster_id | updated_at | solutech_sync_status | |
| erp_sync_status | api_key | deleted_at | solutech_sync_time | |
| erp_sync_time | app_icon | created_at | ||
| status_id | image_id | updated_at | ||
| created_at | database_name | deleted_at | ||
| updated_at | primary_color | |||
| deleted_at | accent_color | |||
| contrast_color | ||||
| splash_icon_size | ||||
| login_icon_size | ||||
| dukasoft_icon | ||||
| status | ||||
| tax_id | ||||
| erp_code | ||||
| erp_sync_status | ||||
| erp_sync_time | ||||
| tax_number | ||||
| address | ||||
| postal_code | ||||
| city | ||||
| country_id | ||||
| currency_id | ||||
| sync_to_erp | ||||
| tax_authority_pin | ||||
| created_at | ||||
| updated_at | ||||
| deleted_at | ||||
| credit_term_id |
Clients
Create table called clients
Fully documented on Jira ✅
| id | Auto Increment |
|---|---|
| solutech_id (Nullable) | Solutech System ID |
| category_id | Category ID |
| erp_code | ERP Code |
| country_id | Country ID |
| tax_id | Tax ID |
| currency_id | Currency ID |
| credit_term_id | Credit Term ID |
| sector_id | Sector ID |
| type_id | Type ID |
| logo_image_id | Logo Image |
| name | Name of Client |
| tax_authority_pin | Tax PIN |
| tax_number | Tax Number |
| address | Address |
| postal_code | Postal Code |
| city | Address City |
| sync_to_erp | Yes, No |
| erp_sync_status | Yes, No |
| erp_sync_time | Timestamp |
| solutech_sync_status | Yes, No |
| solutech_sync_time | Sync Timestamp |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
Client Accounts
Rename tbl_client_configuration to client_accounts
Fully documented on Jira ✅
| id | Auto Increment |
|---|---|
| solutech_id (Nullable) | Solutech System ID |
| client_id | Client ID |
| name | Account Name |
| url | Oauth URL |
| client_oauth_id | Client Oauth ID |
| client_oauth_secret | Client Oauth Secret |
| sync_modules | Boolean (True, False - 1, 0) |
| sync_languages | Boolean (True, False - 1, 0) |
| sync_translation_labels | Boolean (True, False - 1, 0) |
| sync_translations | Boolean (True, False - 1, 0) |
| sync_schedules | Boolean (True, False - 1, 0) |
| sync_frequencys | Boolean (True, False - 1, 0) |
| api_key | API Key |
| solutech_sync_status | Yes, No |
| solutech_sync_time | Sync Timestamp |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
Sub Accounts
Create a table called client_sub_accounts
Fully documented on Jira ✅
| id | Auto Increment |
|---|---|
| solutech_id (Nullable) | Solutech System ID |
| sat_id (Nullable) | |
| account_id | Account ID |
| country_id | Country ID |
| cluster_id | Cluster ID |
| manager_id | Manager ID |
| client_code | Client Code |
| solutech_code | Solutech Code |
| name | Sub Account Name |
| app_icon | App Icon |
| logo_image_id | Logo Image ID |
| document_image_id | Document Image ID |
| primary_color | Primary Colour |
| accent_color | Accent Colour |
| contrast_color | Contrast Colour |
| splash_icon_size | Splash Icon Size |
| login_icon_size | Login Icon Size |
| solutech_sync_status | Sync Status |
| solutech_sync_time | Sync Timestamp |
| created_at, updated_at, deleted_at |
credit_notes Fully documented on Jira ✅
This table will contain information about credit notes on SAT Admin.
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| invoice_id | Invoice ID |
| product_item_id | Product Item |
| credit_note_number | Unique number generated by Solutech |
| doc_id | Document ID |
| erp_code | Zoho Books Credit Note ID |
| erp_credit_note_number | Zoho Books Credit Note Number |
| solutech_id (Nullable) | Solutech ID |
| tax_number (Nullable) | Unique number generated by KRA |
| email (Nullable) | The email to where the credit note is emailed |
| phone | Phone number of the finance personnel |
| name | The name of the credit note |
| currency_id | Currency |
| tax_id | Tax ID |
| address | The billing address of the client |
| city (Nullable) | |
| postal_code (Nullable) | |
| sub_total | Qty X Unit Price |
| discount_total | Total Discount |
| tax_total | Total tax amount if any |
| gross_total | Sub Total - Discount + Tax Amount |
| balance | |
| sent_date (Nullable) | The date the invoice was sent to the customer. Because an invoice can be generated before billing cycle due to additions/removals of licenses. |
| tax_qr_code (Nullable) | QR Code generated by KRA TIMS device |
| tax_response (Nullable) | Tax response |
| tax_sync_time (Nullable) | The time the invoice was synced to KRA |
| tax_device (Nullable) | Device used to sync the invoice |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time the invoice is synced to ERP |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| is_emailed | True, False |
| status_id | Status ID (Draft, Partially Paid, Fully Paid, Unpaid) |
| created_time | Zoho Books timestamp the credit note was generated |
| updated_time | Zoho Books timestamp the credit note was updated |
| created_at, updated_at, deleted_at |
credit_note_items Fully documented on Jira ✅
This table will contain information about credit note line items.
| id | Auto Increment |
|---|---|
| credit_note_id | Credit Note ID |
| account_id | |
| name | |
| qty | Total number of product items |
| unit_price | The rate from the subscription table |
| sub_total | Qty X Unit Price |
| discount_total | Total Discount |
| tax_total | Total tax amount if any |
| gross_total | Sub Total - Discount + Tax Amount |
| description | Narration of the credit note |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
Over Payments
Add bank_charges, refund_amount to payments table
When a customer makes a payment, insert into customer statement and customer statement items accordingly
customer_statements Fully documented on Jira ✅
Create a table called customer_statements to hold customer statement information.
| id | Auto Increment |
|---|---|
| client_id | Client ID |
| solutech_id (Nullable) | Solutech System ID |
| currency_id | Currency ID of the transaction |
| opening_balance | Opening Balance |
| transaction_id | Transaction ID for the type_slug |
| type_slug | invoice, tax, payment, credit_note |
| amount | Amount |
| closing_balance | Closing Balance |
| created_time | Transaction Timestamp |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Timestamp of syncing to Solutech System |
| description | Notes |
| status_id | Status ID |
| created_at, updated_at, deleted_at |
Creating Invoices and Credit Notes on Admin
Invoices
Create invoice from having a Create Invoice button from Clients, or from Invoices Page
If from Clients Page, no need to select the Client, should be auto selected.
Create Invoice by entering the following fields:
- Select Client
- Select Client Account (Limit by clients)
- Select Invoice Date
- Select the Credit Terms and display the due date based on the Credit Terms
Have functionality to add multiple line items by:
Select the Product Item by either selecting or search selecting
- Enter the Quantity
- Enter the Rate
- Select the Tax Rate
Have ability to delete a line item
Calculate the total amount on the fly and display it on the screen
After entering the line items, have the ability to specify the discount (if any)
The discount can be as a % or as an amount.
Add a field for adjustment (both positive and negative).
Then calculate the Sub Total, Tax Amount and Gross Total
Specify the Terms and Conditions
Have ability to save the invoice as:
- Save as Draft or
- Save and Send or (Send to Contact Persons)
If Saved as Draft, have ability to update the status of the invoice to Pending
If Save and Send, save status as Pending then
- Sync the invoice to KRA TIMS
- Sync the invoice to Zoho Books
- Send the invoice to the contact persons per the email template
Credit Notes
Create Credit Noted from having a Create Credit Note button from Invoices, or from Credit Notes Page
If from Invoices Page, no need to select the Client, should be auto selected
Create Credit Note by entering the following fields:
- Select Invoice
- Prepoulate the Client/Customer field based on the invoice
- Select Credit Note Date
Pre populate the line items with what is on the invoice already.
Allow the user to be able to update the quantities with the following validations:
- Quantity cannot be updated upwards. Can only be same or less but not zero.
- Tax rate should not change.
Calculate the updated total amount on the fly and display it on the screen
Then calculate the Sub Total, Tax Amount and Gross Total
Specify the Terms and Conditions
Have ability to save the invoice as:
- Save as Draft or
- Save as Open
If Saved as Draft, have ability to update the status of the Credit Note to Open
If Save as Open:
- Sync the credit note to KRA TIMS
- Sync the credit note to Zoho Books
- Update the credit note on Admin with the erp_code and erp_credit_note_number from Zoho Books
- Send the credit note to the contact persons per the email template
- Sync the credit note to SAT
SAT TABLES
On SAT, we need visibility of the following:
- Ability of the configured Finance Admin to view licenses and history.
- Ability for Finance Admin to add new licenses.
- Ability for admins who can add users to add users based on the available licenses for that user category.
- Ability for admins who can add users to delete licenses. (Deleted licenses will not be refunded, but the change will be reflected in the next billing invoice. Such change of licenses has to be done before the billing/invoice date 8:00 AM EAT).
Working Methodology
Licenses Management
- Once licenses are created on Admin, they will be synced to the specific clients deployment.
- On SAT Admin, we will generate license keys per the number of the licenses issued. I.e. if 5 licenses are issued, generate random numbers concatenated with the clients Code. E.g. A59D-E89H-I4KL, AB14-KL8D-M4P8 etc
- When a new license is created, we will add a new license key.
- When licenses are removed, we will deactivate a subsequent number of license keys which were removed.
- To add new licenses, the system will display current licenses, then the admin can specify how many licenses they want to add, and the system will indicate how many total licenses they will have.
- Then they will get an estimate of their next months billing, broken down by with the changes.
- Then if they are okay, they can submit.
- The changes will be inserted in licenses and license_history tables accordingly.
- Then we will generate new license keys per the number of new licenses added (after activating any unallocated license keys).
- This will then sync to SAT Admin (Can be a separate scheduler).
- Then the client can now add users.
Users Management
- When a new user is added in Solutech SAT, an unused license key will be picked from the license_keys table, assigned to a user in users table, then marked as allocated in license_keys table.
- When a user is deactivated, their license key will be un allocated.
- If a license is unallocated, it can be removed (Made Inactive), which will reduce the clients licenses instantly, and this change will reflect in the next billing cycle.
- If a user needs to be re-activated, they can only be re-activated if there is an unallocated license key (Active). If not, the system should not allow them to be re-activated.
- If a user needs to be added and there are no licenses, the system should not allow them to add the user.
- The finance admin should first request for new licenses.
Contacts Management
When a contact is added in Admin for that client, we should create the user per the respective client in SAT.
The Process:
| Adding New User | |
|---|---|
| 1 | Check if client has multiple license types |
| 2 | If multiple, User has to select user type, then, check if there is Un Allocated and Active License for that user type |
| 3 | If not multiple, check if there is Un Allocated and Active License |
| 4 | If No, deny user addition |
| 5 | If Yes, allow user addition |
| Deactivating User | |
| 1 | A user can be deactivated |
| 2 | Remove the license from users table |
| 3 | Set the license key as un allocated in license_keys table |
| Reactivating User | |
| 1 | Same follow procedure for adding new user |
| Adding New Licenses | |
| 1 | Display current licenses |
| 2 | Allow Admin to specify how many new licenses they will need.If they have multiple licenses, specify which ones they are adding per category |
| 3 | Calculate the new licenses and rates and display them to userFactor in any discountsGive breakdown per the billing cycle of the client |
| 4 | User submits the application |
| 5 | Update the record in licenses table (change keys_generated to No) |
| 6 | Insert license_history table accordingly |
| 7 | In license_keys, if there were unallocated inactive keys, activate them depending on number of added licenses, and create new ones if necessary. |
| 8 | Submit the data to SAT Admin |
| 9 | In SAT Admin, Update the record in client_licenses table |
| 10 | Insert client_licenses_history table accordingly |
| 11 | Create draft invoice and insert into invoice and invoice_items accordingly |
| License Key Algorithm | |
| 1 | Generate a unique key of 12 characters chunked into 3s of 4 characters, separated by a dash |
| 2 | Check if it exists in the database |
| 3 | If Yes, Store it and generate the next |
| 4 | If No, generate another one |
tbl_users
Add license_key_id to keep track of license allocated to a user
Add contact_type to keep track of Billing, Super Admin. Super Admin should have overall system administration not limited to roles.
| license_key_id | License Key ID |
|---|---|
| is_suspended | The column is a boolean which is set to true when a user is suspended due to payment |
user_types Modify the table to add solutech_id (Nullable)
We will use this column to reference the type of licenses a client has to determine if the client has enough licenses to add users or not.
license_subscriptions Fully documented on Jira ✅
| id | Auto Increment |
|---|---|
| erp_code | Admin ID |
| product_name | Product name (Solutech SAT) |
| product_item_name | Product Item name (Solutech SAT License) |
| currency | Currency name (KES, USD) etc |
| date_subscribed | Date the client’s subscription starts |
| billing_cycle | Monthly, Bi Monthly, Quarterly, Annual |
| discount_total (Nullable) | Discount issued to client |
| discount_percent (Nullable) | Discount issued to client |
| date_unsubscribed (Nullable) | Date the client’s subscription ends |
| reason_unsubscribed (Nullable) | |
| created_by | The user who created the subscription |
| updated_by (Nullable) | The user who updated the subscription |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| status_name | Status |
| created_at, updated_at, deleted_at |
licenses Fully documented on Jira ✅
This table will maintain the data of licenses a client is entitled to at any given time.
| id | Auto Increment |
|---|---|
| erp_code (Nullable) | |
| subscription_id | License Subscription ID on SAT |
| company_erp_code | The company erp_code on SAT referencing the sub account code on Admin |
| type_name | Admins, Users, All Users |
| name | BillableFreeNon Billable |
| slug | billable, free, non_billable |
| quantity | Number of Licenses |
| rate | The rate the customer is billed |
| rate_type | Per Month, Per Day |
| currency | Name of currency (KES, USD) |
| keys_generated | Yes, No |
| erp_sync_status | Y,N |
| erp_sync_time | Time of Syncing to Solutech Admin |
| erp_sync_response | Sync response from Solutech Admin |
| status_name | Status of the License |
| start_date (Nullable) | Start date of the license if available(For promoters) |
| end_date (Nullable) | End date of the license if available(For Training and promoters) |
| created_by_name | Name of user on SAT Admin |
| updated_by_name (Nullable) | Name of user on SAT Admin |
| created_at, updated_at, deleted_at |
licenses_history Fully documented on Jira ✅
This table will maintain the data of licenses history so that the client can check any changes on their deployment.
| id | Auto Increment |
|---|---|
| license_id | License ID |
| erp_code (Nullable) | |
| type_name | Admins, Users, All Users |
| name | BillableFreeNon Billable |
| current_qty | Current number of licenses |
| added_qty (Nullable) | Number of licenses added (if any) |
| removed_qty (Nullable) | Number of licenses removed (if any) |
| final_qty | Final number of licenses |
| change_date | The date the change occured |
| rate | To track rate rate changes |
| rate_type | Per Day , Per Month |
| currency | Name of the currency (KES, USD) |
| start_date (Nullable) | Start date of the license if available(For promoters) |
| end_date (Nullable) | End date of the license if available(For Training and promoters) |
| created_by_name | Name of user |
| updated_by_name (Nullable) | Name of user |
| created_at, updated_at, deleted_at |
license_days Fully documented on Jira ✅
This table will maintain the data of license days for promoters license type..
| id | Auto Increment |
|---|---|
| license_id | License ID on SAT |
| erp_code | ID of the record on SAT Admin |
| day | Applicable for promoters. The days they are allowed to use Solutech SAT |
| created_at, updated_at, deleted_at |
license_keys Fully documented on Jira ✅
This table will maintain the data of licenses a client is entitled to at any given time.
| id | Auto Increment |
|---|---|
| license_id | License ID on SAT |
| key | Generated License Key |
| allocated | Yes, No |
| expiry_date (Nullable) | The date the key will expire |
| status | Active, Inactive |
| created_at, updated_at, deleted_at |
license_keys_history Fully documented on Jira ✅
This table will maintain the history of license keys assigned to users at any given time and their expiration date.
| id | Auto Increment |
|---|---|
| license_key_id | License Key ID on SAT |
| user_id (Nullable) | Generated License Key |
| expiry_date | The date key expired |
| created_at, updated_at, deleted_at |
license_invoices Fully documented on Jira ✅
This table will maintain the data of licenses history so that the client can check any changes on their deployment.
| id | Auto Increment |
|---|---|
| invoice_number | Unique number generated by Admin |
| erp_code | Unique code generated by Zoho Books |
| tax_invoice_number | Unique number generated by KRA |
| name | The name of the invoice |
| currency | The name currency in which the invoice is invoiced in |
| invoice_date | The date the invoice is generated, which should be in line with the billing period |
| doc_path | Document path |
| sub_total | Qty X Unit Price |
| tax_total | Total tax amount if any |
| discount_total (Nullable) | Total discount issued if any |
| discount_percent (Nullable) | Discount percentage if any |
| gross_total | Sub Total - Discount + Tax Amount |
| due_date | When the invoice is due, per the subscription plan. This is calculated per the credit terms. Consideration for Feb as 1 Month is not necessarily 30 Days. |
| sent_date (Nullable) | The date the invoice was sent to the customer. Because an invoice can be generated before billing cycle due to additions/removals of licenses. |
| tax_qr_code (Nullable) | QR Code generated by KRA TIMS device |
| tax_response (Nullable) | Tax response |
| tax_sync_time (Nullable) | The time the invoice was synced to KRA |
| tax_device (Nullable) | Device used to sync the invoice |
| reminders (Nullable) | Number of reminders sent (Default 0) |
| invoice_status | Draft, Partially Paid, Fully Paid, Unpaid |
| payment_status | Paid, Partially Paid, Unpaid |
| created_at, updated_at, deleted_at |
license_invoice_items Fully documented on Jira ✅
This table will contain information of invoiced items.
| id | Auto Increment |
|---|---|
| invoice_id | Invoice ID from SAT |
| license_id | License ID (To keep a track of the product and license which was invoiced) |
| organization_erp_code | The organization which the invoice items belongs to |
| type | Main or Upgrade |
| qty | Total number of licenses |
| unit_price | The rate from the subscription table |
| sub_total | Qty X Unit Price |
| tax_total | Total tax amount if any |
| discount_total (Nullable) | Total discount issued if any |
| discount_percent (Nullable) | Discount percentage if any |
| gross_total | Sub Total - Discount + Tax Amount |
| description | Narration of the invoice items e.g. 2 new licenses added on 10th March 2023 |
| created_at, updated_at, deleted_at |
license_payments Fully documented on Jira ✅
Payments information from all tables.
| id | Auto Increment |
|---|---|
| invoice_id | Invoice ID from SAT |
| erp_code | Unique code generated by Zoho Books |
| amount | The invoiced amount |
| amount_paid | To keep track of partial payments |
| currency | Currency Name |
| payment_mode | Payment Mode |
| date_paid | The date the invoice was paid |
| reference | Payment transaction number |
| payer_name (Nullable) | Name of who made payment |
| payer_email (Nullable) | Email of who made payment |
| payer_phone (Nullable) | Phone number of who made payment |
| receipt_date (Nullable) | Date when the receipt was generated |
| doc_path | Document path |
| status | Status |
| created_at, updated_at, deleted_at |
Demo Users
There will be no provision for demo accounts once the billing system is operationalised. Therefore no functionality will be developed to cater for demo users.
Separation of Users and Support Accounts
With the introduction of a super admin, we need to limit the super admin to only view their users (Client users).
Therefore, System Users should be separated and a new menu for Support Accounts introduced. System users should contain all billable and free users. Support Accounts should contain non billable accounts which is Solutech users.
Companies
Fully documented on Jira ✅
Companies Changes on SAT
Rename product_company table to companies
Add the following columns
| client_code | Client Codes per the Sub Account on Admin Portal |
|---|---|
| erp_code | Unique Code Shared for Admin Portal |
| image_url | Image URL |
| erp_sync_status | Yes, No |
| erp_sync_time | Timestamp of sync to/from Admin Portal |
Amend the Companies CRUD to persist the above data with the following validations:
- Client Codes have to be unique (on creation and update as well)
- You cannot deactivate/delete a company which has products or brands or users attached to it.
- Once client Code and ERP Code have been set, they cannot be modified. They can only be modified by a re-sync of new data from Admin.
license_credit_notes Fully documented on Jira ✅
This table will contain information about credit notes on SAT.
| id | Auto Increment |
|---|---|
| invoice_id | Invoice ID on SAT |
| credit_note_number | Unique number generated by Solutech |
| doc_path | Document Path URL |
| erp_code | Zoho Books Credit Note ID |
| erp_credit_note_number | Zoho Books Credit Note Number |
| tax_number (Nullable) | Unique number generated by KRA |
| The email to where the credit note is emailed | |
| phone | Phone number of the finance personnel |
| name | The name of the credit note |
| currency_name | Currency |
| tax_name | Tax |
| address | The billing address of the client |
| city (Nullable) | |
| postal_code (Nullable) | |
| sub_total | Qty X Unit Price |
| discount_total | Total Discount |
| tax_total | Total tax amount if any |
| gross_total | Sub Total - Discount + Tax Amount |
| balance | |
| sent_date (Nullable) | The date the invoice was sent to the customer. Because an invoice can be generated before billing cycle due to additions/removals of licenses. |
| tax_qr_code (Nullable) | QR Code generated by KRA TIMS device |
| tax_response (Nullable) | Tax response |
| tax_sync_time (Nullable) | The time the invoice was synced to KRA |
| tax_device (Nullable) | Device used to sync the invoice |
| erp_sync_status | Yes, No |
| erp_sync_time (Nullable) | Time the invoice is synced to ERP |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Time of syncing to Solutech System |
| is_emailed | True, False |
| status_name | (Draft, Partially Paid, Fully Paid, Unpaid) |
| created_time | Zoho Books timestamp the credit note was generated |
| updated_time | Zoho Books timestamp the credit note was updated |
| created_at, updated_at, deleted_at |
credit_note_items Fully documented on Jira ✅
This table will contain information about credit note line items.
| id | Auto Increment |
|---|---|
| license_credit_note_id | Credit Note ID on SAT |
| account_name | |
| name | |
| qty | Total number of product items |
| unit_price | The rate from the subscription table |
| sub_total | Qty X Unit Price |
| discount_total | Total Discount |
| tax_total | Total tax amount if any |
| gross_total | Sub Total - Discount + Tax Amount |
| description | Narration of the credit note |
| status_name | Status Name |
| created_at, updated_at, deleted_at |
Over Payments
Add bank_charges, refund_amount to payments table
license_customer_statements Fully documented on Jira ✅
Create a table called license_customer_statements to hold customer statement information.
| id | Auto Increment |
|---|---|
| erp_code | Admin ID |
| currency_name | Currency Name |
| opening_balance | Opening Balance |
| closing_balance | Closing Balance |
| created_time | Transaction Timestamp |
| solutech_sync_status | Yes, No |
| solutech_sync_time (Nullable) | Timestamp of syncing to Solutech System |
| description | Notes |
| status_name | Status Name |
| created_at, updated_at, deleted_at |
license_customer_statement_items Fully documented on Jira ✅
Create a table called customer_statement_items.
| id | Auto Increment |
|---|---|
| statement_id | Customer Statement ID from SAT |
| transaction_id | Transaction ID for the type_slug from SAT |
| type_slug | invoice, payment, credit_note |
| amount | Amount |
| description | Notes |
| status_name | Status Name |
| created_at, updated_at, deleted_at |
Are there scenarios where we do refund customers?
Upgrade Invoicing
Banner
Suspension
Manage Users - Licenses / Unlicensed
EMAIL TEMPLATES
Billing Subscription Email Template
Subject: Product Name Subscription Details
Dear [User Name], (Should be the name of the billing users)
[Client Name] [main/training] subscription for [Product Name] has been successfully created. Below you will find all the key information about your subscription.
Subscription Details:
-
Product: [Product Name]
-
Item: [Product Item Name]
-
Start Date: [Start Date]
-
End Date: [End Date] - Displayed if the Subscription is training or promoters.
-
Billing Cycle: [Monthly/Annual]
License Details:
12 All Users Licenses @ KES 4,000.00 Per User Per Month
Support:
For assistance or subscription changes, reach us at +(254) 795462921 | +(254) 742650893 Thank you for trusting [Product] for your journey ahead. Here’s to making data-driven decisions.
Best regards,
Finance Team
Invoice Email Template
Subject: [Product Name] [Billing Cycle] Invoice
Dear [User Name], (Should be the name of the billing users)
Your [billing cycle] [Client Name] invoice for [Product Name] is now available. Below are the invoice details and attached in this email is the PDF invoice.
Invoice Number: INV000010
Billing Period: 1st Oct 2023 - 31st Oct 2023
Billing Cycle: Monthly
Invoiced Amount: KES 120,000.00
Due Date: 31st Oct 2023
Please make a wire transfer payment to the following bank account:
Bank Name: PRIME BANK
Bank Country: KENYA
Bank Code: 010
SWIFT Code:
Account Name: SOLUTECH LIMITED
Account Number:
Bank Branch: PARKLANDS
Branch Code:
Lipa na Mpesa Paybill Number: (Displayed in currency is KES only)
Account Number is the Bank Account Number (Displayed in currency is KES only)
For assistance reach us at accounts@solutech.co.ke | +(254) 795462921.
Thank you for your business.
Best regards,
Solutech Finance Team
Invoice Reminder Email Template
Subject: [Product Name] [1st] Invoice Payment Reminder
Dear [User Name], (Should be the name of the billing users)
This is a billing reminder that your [Billing Cycle] [Product Name] invoice number [Invoice Number] which was generated on [Date Generated] is due on [Due Date].
Below are the invoice details and attached in this email is the PDF invoice.
Invoice Number: INV000010
Billing Period: 1st Oct 2023 - 31st Oct 2023
Billing Cycle: Monthly
Invoiced Amount: KES 120,000.00
Due Date: 31st Oct 2023
Please make a wire transfer payment to the following bank account:
Bank Name: PRIME BANK
Bank Country: KENYA
Bank Code: 010
SWIFT Code:
Account Name: SOLUTECH LIMITED
Account Number:
Account Currency:
Bank Branch: PARKLANDS
Lipa na Mpesa Paybill Number: (Displayed in currency is KES only)
Account Number is the Bank Account Number (Displayed in currency is KES only)
For assistance reach us at [Finance Email and Phone Number].
Thank you for your business.
Best regards,
Solutech Finance Team
Invoice Due Date Email Template
Subject: [Product Name] Invoice Is Due
Dear [User Name], (Should be the name of the billing users)
This is a billing reminder that your [Billing Cycle] [Product Name] invoice number [Invoice Number] which was generated on [Date Generated] is due.
Your account is at risk of suspension in the next 7 days if no payment is received.
Below are the invoice details and attached in this email is the PDF invoice.
Invoice Number: INV000010
Billing Period: 1st Oct 2023 - 31st Oct 2023
Billing Cycle: Monthly
Invoiced Amount: KES 120,000.00
Due Date: 31st Oct 2023
Please make a wire transfer payment to the following bank account:
Bank Name: PRIME BANK
Bank Country: KENYA
Bank Code: 010
SWIFT Code:
Account Name: SOLUTECH LIMITED
Account Number:
Account Currency:
Bank Branch: PARKLANDS
Lipa na Mpesa Paybill Number: (Displayed in currency is KES only)
Account Number is the Bank Account Number (Displayed in currency is KES only)
For assistance reach us at [Finance Email and Phone Number].
Thank you for your business.
Best regards,
Solutech Finance Team
Suspension Notice Email Template
Subject: Your [Product Name] Account Is At Risk of Suspension
Dear [User Name], (Should be the name of the billing users)
Your [Client Name] subscription for [Product Name] is at risk of suspension in the next 2days due to an unpaid balance of [Invoice Amount].
To avoid interruption of your [Product Name] services, please settle the due amount immediately.
Below are the invoice details and attached in this email is the PDF invoice.
Invoice Number: INV000010
Billing Period: 1st Oct 2023 - 31st Oct 2023
Billing Cycle: Monthly
Invoiced Amount: KES 120,000.00
Due Date: 31st Oct 2023
Please make a wire transfer payment to the following bank account:
Bank Name: PRIME BANK
Bank Country: KENYA
Bank Code: 010
SWIFT Code:
Account Name: SOLUTECH LIMITED
Account Number:
Account Currency:
Bank Branch: PARKLANDS
Lipa na Mpesa Paybill Number: (Displayed in currency is KES only)
Account Number is the Bank Account Number (Displayed in currency is KES only)
For assistance reach us at [Finance Email and Phone Number].
Thank you for your business.
For assistance reach us at [Finance Email and Phone Number].
Thank you for your business.
Best regards,
Solutech Finance Team
Suspended Notice Email Template
Subject: Your [Product Name] Account Is Temporarily Suspended
Dear [User Name], (Should be the name of the billing users)
Your [Client Name] subscription for [Product Name] has been temporarily suspended due to an unpaid balance of [Invoice Amount].
Please make a payment immediately to reactivate your account and continue enjoying your [Product Name] services.
Below are the invoice details and attached in this email is the PDF invoice.
Invoice Number: INV000010
Billing Period: 1st Oct 2023 - 31st Oct 2023
Billing Cycle: Monthly
Invoiced Amount: KES 120,000.00
Due Date: 31st Oct 2023
Please make a wire transfer payment to the following bank account:
Bank Name: PRIME BANK
Bank Country: KENYA
Bank Code: 010
SWIFT Code:
Account Name: SOLUTECH LIMITED
Account Number:
Account Currency:
Bank Branch: PARKLANDS
Lipa na Mpesa Paybill Number: (Displayed in currency is KES only)
Account Number is the Bank Account Number (Displayed in currency is KES only)
For assistance reach us at [Finance Email and Phone Number].
Thank you for your business.
For assistance reach us at [Finance Email and Phone Number].
Thank you for your business.
Best regards,
Solutech Finance Team
Receipt Email Template
Subject: [Product Name] Payment Receipt
Dear [User Name], (Should be the name of the billing users)
Payment of [Amount Paid] for Invoice Number [Invoice Number] has been confirmed successfully.
Attached in this email is the PDF receipt for your records.
For assistance reach us at [Finance Email and Phone Number].
Thank you for your business.
Best regards,
Solutech Finance Team
P.S. Stay updated via [Social Media Links] for [Product Name] news and insights.
Subscription Upgrade Email Template
Subject: [Product Name] Licenses Upgrade
Dear [User Name], (Should be the name of the billing users)
Your [Client Name] [Product Name] [Subscription Type] subscription licenses have been successfully upgraded as detailed below:
License Details:
Previous: 12 All Users Licenses @ KES 4,000.00 Per User Per Month Upgraded: 5 All Users Licenses @ KES 4,000.00 Per User Per Month
Total: 17 All Users Licenses @ KES 4,000.00 Per User Per Month
Your next estimated billing at the end of the month will be [Estimated Billing Amount]
Best regards,
Solutech Finance Team
Subscription Downgrade Email Template
Subject: [Product Name] Licenses Downgrade
Dear [User Name], (Should be the name of the billing users)
Your [Product Name] [Subscription Type] subscription licenses have been successfully downgraded as detailed below:
License Details:
Previous: 12 All Users Licenses @ KES 4,000.00 Per User Per Month Downgraded: 5 All Users Licenses @ KES 4,000.00 Per User Per Month
Total: 7 All Users Licenses @ KES 4,000.00 Per User Per Month
Your next estimated billing in your next [Billing Cycle] billing cycle will be [Estimated Billing Amount]
Best regards,
Finance Team
P.S. Stay updated via [Social Media Links] for [Product Name] news and insights.
Customer Statement Email Template
Subject: Solutech Customer Statement - Customer Name - Start Date to End Date
Dear [User Name], (Should be the name of the billing users)
Below is Customer Name customer statement for the period 1st September 2023 to 30th October 2023 Start Date to End Date:
To view and download your complete statement, please click on the following link: [Customer Statement Link].
For assistance reach us at [Finance Email and Phone Number]. Thank you for your business.
Best regards, Solutech Finance Team P.S. Stay updated via [Social Media Links] for [Product Name] news and insights.
Credit Note Email Template
Subject: [Product Name] Credit Note for Invoice # Invoice No.
Dear [User Name], (Should be the name of the billing users)
Your [Client Name] invoice for [Product Name] has been generated. Below are the credit note details and attached in this email is the PDF document.
Credit Note Number: CN000004
Invoice Number: INV000010
Invoice Amount: KES 350,000.00
Credit Note Amount: KES 120,000.00
For assistance reach us at [Finance Email and Phone Number].
Thank you for your business.
Best regards,
Solutech Finance Team
P.S. Stay updated via [Social Media Links] for [Product Name] news and insights.
ROLL OUT PLAN
The development of this feature is approximated to take 1 month and 3 weeks of QA Testing and re-fixing bugs if at all any. Once a green light is given by the QA team, the Marketing and Finance teams will need to roll out the implementation as follows:
- Marketing Team will need to communicate with all finance admins for the various Solutech Products detailing the following key information:
- Changes in how Solutech will be handling licensing going forward.
- Cease of sending estimates.
- Cut off date of when the new billing implementation will begin.
- Finance Admins to confirm their Solutech licenses with Solutech Finance Team at least a week prior to the cut off date.
- Invoices will be shared on the first day of the month.
- Invoice credit terms will be 30 days, upon which non payment will lead to automated system shut down.
- If no payment is received, reminders will be sent on the following frequency:
- Payment Reminder - 10th, 15th, 20th date of the month.
- Account Suspension Warning - 25th date of the month.
- Your Solutech Account has been suspended - On the last date of that month (per the credit terms)
- Finance Team will need to consolidate the Licenses for all the clients before the cut off period which the COO will advise upon getting green light from QA.
TIMELINE
Below is the set timeline for the development and implementation of this project.
| # | ITEM | RESPONSIBLE | STATUS | PERIOD | START DATE | END DATE |
|---|---|---|---|---|---|---|
| 1 | Development on Admin Portal | backend@solutech.co.ke | In Progress | 10 Days | 17th July 2023 | 31st July 2023 |
| 2 | Development on SAT | backend@solutech.co.ke | In Progress | 4 Days | 25th July 2023 | 31st July 2023 |
| 3 | QA Testing + Fixes | qa@solutech.co.kebackend@solutech.co.ke | In Progress | 5 Days | 17th July 2023 | 4th Aug 2023 |
| 4 | Training to Solutech Internal Users | backend@solutech.co.keSolutech Accounts | Pending | 1 Day | 7th Aug 2023 | 7th Aug 2023 |
| 5 | Newsletter Content Generation | Solutech Marketing | Done | 1 Day | 25th July 2023 | 31st July 2023 |
| 6 | Aggregating Finance Admins Data on Zoho Campaigns | Solutech Marketing Solutech Accounts | Done | 1 Day | 17th July 2023 | 28th July 2023 |
| 7 | Newsletter Communication with Finance Admins | Solutech Marketing | Done | 1 Day | 1st Aug 2023 | 1st Aug 2023 |
| 8 | Harmonizing Client Solutech Licenses | Solutech Accounts | Pending | 2 Months | 2nd Aug 2023 | 5th Sept 2023 |
| CUT OFF PERIOD | ||||||
| 9 | Deployment of the New Billing Process | backend@solutech.co.keSolutech Accounts | Pending | 1 Day | 30th Sept 2023 | 30th Sept 2023 |
Improvements
The below screen makes users think that there is an issue with the system, and users might not know what is the issue and who is responsible for it.
![][image1]
Therefore:
-
We should not log out the users. Therefore, we need to change the logic of checking license during login and create a middleware which, when a user tries to do anything on the app, the license check is done and the appropriate message displayed to the user, and logout is not actioned.
-
We need to a screen similar to the Fake GPS one with a clear message Your account license has been suspended, please contact your Finance Team. Then we can have a call button below the message with the company Admin Number. E.g. Call Jane Doe Call John Doe Call Jane John And a refresh button
-
Once the billing issue is resolved they just need to refresh and resume operations. If they retry to refresh and the billing issue is not resolved, there should be a response that the account is still suspended. We can add a small caption that the user needs to tap on the refresh button once the billing issue is resolved.
-
License Expiry Email Notifications
We need to add the following functionalities:
- When a customer downgrades, we will notify the users affected by the downgrade of their license expiry due to the downgrade.
- When a user is allocated to a license with an expiry, we will notify them of the expiry period of the license.
- For the two above scenarios, we will notify the user a day before that their license will expire the next day.
- For the above two scenarios, we will notify the user on the d-day once their license has been deactivated because of the expiry.
This will enable a user to have full knowledge of their license status.
Create a table on SAT user_license_notification_logs
| id | Auto Increment |
|---|---|
| user_id | The ID of the user being notified |
| license_key_id | The license key that the user has |
| subject | The subject of the notification |
| message | The message being sent out |
| created_at, updated_at, deleted_at |
We need to add functionality to enable Finance Team to group upgrade invoices for a client, which will combine all upgrade invoices into the billing cycle licenses invoices as one invoice.
Therefore, when the monthly, quarterly etc invoices are being sent, all upgrade invoices done in the previous billing cycle, need to be added into the license invoice with the correct narrations.
This will make it easier for clients to reconcile their invoices easily especially the clients who do many upgrades within the billing cycle.
Admin Portal
Clients Table
In Admin, in clients table, add a field, combine_upgrade_invoices which should accept 1 and 0. By default this should be 0. 1 means Yes, 0 means No.
clients table:
| combine_upgrade_invoices | Tinyint | Mandatory | Default 0 |
|---|
Combined Invoices Table
In Admin, create a new table called combined_invoices with the following fields.
combined_invoices table:
| id | Int (12) | Mandatory | Auto Increment |
|---|---|---|---|
| doc_id | Int (12) | Mandatory | Foreign key from Documents Table |
| client_id | Int (12) | Mandatory | The id of the client from clients table |
| client_viewable | Boolean | Mandatory | 1- means the client can see the invoice 0 - means the client can not view the document since another one has been generated or the invoices in the document are fully paid |
| created_at, updated_at, deleted_at | Timestamp |
Modify client creation UI on the frontend to add a field for Combine Upgrade Invoices. The choices should be a checkbox, with values of 1 if checked and 0 if unchecked, and default as 0.
-
Modify the client Model to add the new field.
-
Modify the API for saving a client to accept the new field.
-
Modify the API for retrieving client info to add the new field.
-
On the frontend UI for displaying a client, display the new field data accordingly.
-
Develop a new scheduler which runs at the end , which does the following:
-
Loop through all clients who have combine_upgrade_invoices column checked and have unpaid or pending upgrade invoices.
-
The scheduler should fetch the invoice details together with the invoice items.
-
The scheduler should generate a new combined invoice document based on the upgrade invoices that are unpaid or pending and save it to spaces and the link in the documents model.
-
Create a new combined invoice record with a doc_id as the reference to the newly created document and client_viewable as true. For all the other existing combined invoices for the client set them to client_viewable false
-
If all the upgrade invoices are paid the scheduler shouldnt generate a new document. It should just set the existing document to client_viewable false
Create an api to be called by SAT which accepts the clientcode and returns the latest combined invoice document which is client viewable for that client. If not combined invoice exists, return the error message to the client that no combined invoice exists
Create a module called Can Request Combined Upgrade Invoice
SAT
Users assigned the module ‘Can Request Combined Upgrade Invoice’ should be able to see the request Invoices button on the invoices page. Once the button is clicked, an API call is made to the admin portal to get the document and display it to the user if it exists
We need to add a functionality where by default, customers get the customer statement on email when the billing cycle invoice email is sent as well.
By default, the period can be from the start of the year, or the last one year (decision needs to be made on this)
This will enable customers to be aware of what they owe us and reduce the back and forth with our Finance Team.
Finance require these two key reports every month to file to KRA.
Currently we generate them manually which is quite some work we can automate to prevent the need of Finance Team having to ask for it from the engineering team.
We need to create two separate reports with filterable options for dates to pull credit notes and invoices reports with the following columns:
Credit Notes
| id | 68 |
|---|---|
| client_name | KINANGOP DAIRY LIMITED |
| kra_pin | P051136314M |
| invoice_number | INV0001831 |
| invoice_tax_invoice_number | 0020116240000000573 |
| invoice_date | 2024-02-01 00:00 |
| invoice_tax_sync_time | 2024-02-01 08:01 |
| credit_note_tax_number | 0020116240000000620 |
| credit_note_number | CN-0000059 |
| erp_credit_note_number | CN-0000059 |
| credit_note_name | Credit Note for INV0001831 |
| tax_device | KRAMW002202111011624 |
| credit_note_tax_sync_time | 2024-02-01 09:16 |
| invoice_sub_total | 1800 |
| invoice_tax_total | 288 |
| invoice_gross_total | 2088 |
| credit_note_sub_total | 1800 |
| credit_note_tax_total | 288 |
| credit_note_gross_total | 2088 |
| balance | 208800 |
| credit_note_date | 2024-02-01 09:16 |
Invoices
| id | 722 |
|---|---|
| client_name | BAKHRESA GROUP |
| kra_pin | NULL |
| invoiced_name | BAKHRESA GROUP |
| invoice_number | INV0001820 |
| tax_invoice_number | 0020116240000000562 |
| tax_device | KRAMW002202111011624 |
| invoice_date | 2024-02-01 00:00 |
| tax_sync_time | 2024-02-01 00:21 |
| invoice_type | invoice |
| sub_total | 1000 |
| tax_total | 0 |
| gross_total | 1000 |
The current listing of subscriptions is limited to a few records.
A pagination needs to be added, with the active subscriptions displayed first.
The system should be notified to ensure clients are also suspended due to the final setup invoice being overdue. This change was brought about because of customers not paying for the setup cost balance but continuing to pay the monthly license costs. Hence, if a customer has not paid the final setup cost, they should get reminders and suspension notifications, and suspension once the invoice is overdue.
TODO
Handle credit notes on SAT i.e if a credit note is issued on a license invoice the license keys associated with it should be deactivated
Proforma Invoices and Invoices Separation
Proforma Invoices Separation
On Admin Portal, the Proforma Invoices should be listed separately from the invoices.
On SAT Portals for clients, the Proforma Invoices should be listed separately from the invoices so that there is better clarity to clients as well.