Fiscalisation options for Manager users in Zimbabwe

There have been several other discussions over the course of the year by Manager users in Zimbabwe struggling to get set up for the FDMS requirements. Most of them have focussed on specific challenges, such as renaming column headings on invoices to meet the requirements of third party providers offering fiscal integration services. I’m starting this topic in the hope it can serve as a resource for others wondering where to start, give the developer a focussed summary of our challenges, and perhaps generate some collaboration among Zimbabwean users to get some better solutions set up for users of Manager.

A brief summary of the issue: Our tax authority requires VAT-registered businesses to integrate with their Fiscalisation Data Management System (FDMS), providing them with real-time data on sales invoices and credit notes issued. This can be done directly with their API by users with sufficient technical skills, or through a third-party provider.

There are several options for third-party providers, and I haven’t researched them all. However, based on my current knowledge and experience I think they can be grouped into three categories:

1. Those that use a separate physical device
Example: Corsol
Pros: Simple to use with minimal setup; does not require any changes to Manager or integration with it
Cons: High initial purchase price; requires manual entry of all sales invoices and credit notes on the device, making it labour intensive for those processing a large number of transactions, and prone to errors; very limited control over appearance of fiscalised documents; potentially no easy option to retain digital versions of fiscalised documents

2. Those that “read” PDFs to extract the data and send it electronically to ZIMRA
Example: RevMax by Axis Solutions
Pros: Simple to use once set up; for those already generating PDFs of sales invoices and credit notes it requires very little extra work; less prone to errors, as the data is entered only once, in Manager; lots of potential for customisation of document appearance, within the limits of the template requirements; digital copies of fiscalised documents saved locally during normal workflow
Cons: Complex to set up for users of Manager, as it requires very specific customisation of templates, which is a deprecated feature of Manager; some requirements of the templates may not be possible for Manager users (see further notes below)

3. Those that integrate directly with the accounting software (Manager, for us)
Example: Fiscal Harmony
Pros: Potentially low setup cost (see further notes below); easy to use, requiring minimal extra work; less prone to errors, as it extracts data directly from accounting software
Cons: No current Manager integration in place (see further notes below); limited options for customisation of document appearance

Both Axis Solutions and Fiscal Harmony offer templates or integrations with Microsoft Excel, so another option would be to copy the transaction details from Manager and paste them into the Excel template and submit it to ZIMRA like that. This obviously involves quite a bit of extra work and introduces greater potential for errors. It also requires the user to have Excel.

Before the FDMS system was introduced, we were using Axis Solutions’ RevMax for our fiscalisation. It stopped working with the introduction of the FDMS. I have since put a considerable amount of work into customising our theme to meet Axis Solutions’ template requirements. I realise custom themes are a deprecated feature of Manager, but I couldn’t see any other option I was happy to use or had the technical skills to implement. I have succeeded in modifying our theme accordingly, with one exception: I haven’t found a way to show “0.00” in the VAT column for VAT-exempt or zero-rated line items (the VAT column is the Tax Amount column that I renamed in the theme to meet Axis’ template requirements). This isn’t such an issue for us, as everything we sell has 15% VAT applied, but obviously it could be a problem for other businesses. Axis Solutions told us our templates were fine, and they were tested and approved by ZIMRA. However, when we came to use them we received error messages, and on following up with Axis were told that our PDFs are encrypted and we had to find a way to provide unencrypted PDFs. We have been making our PDFs through the Print button in Manager and selecting Print to PDF. I haven’t been able to figure out how our PDFs are “encrypted” or how to remove this encryption, so our fiscal integration has stalled again.

In my frustration with Axis Solutions at their inability or unwillingness to help us resolve the “encrypted PDF” issue, and on the recommendation of several other local business owners, I approached Fiscal Harmony. They don’t currently have a Manager integration, but they have added it to their requested features list and could develop it if there is sufficient demand. If you are interested, please visit the page and add your vote (you will need to create a free user account and log in to be able to vote). I met with one of the directors of the business, and he said that even without sufficient interest in a Manager integration we could still get it if we contract his software development company to do the development. He quoted USD 800.00 and up to two weeks of development time for this. It would be a once-off cost, and once the integration is in place it would be available to any Manager user who pays the Fiscal Harmony subscription. So, if there are other Manager users who would like this, we could split the development cost between us. Please message me directly if you would like to do this.

Having explored all these third-party options, my first preference would be to get support within Manager to interface directly with the ZIMRA API, removing the need to use a third party and pay their subscription, device, and development costs. I hoped maybe Manager’s Relay functionality would be the answer, but having looked through the FDMS API documentation I think there are some requirements that Relay alone could not fulfil (I would be happy to be proven wrong). I understand that the developer is unlikely to devote resources to meeting our unique FMDS requirements.

Without direct Manager integration, the options I can think of are:

  1. Use a third party provider of type 1 above – I’m not keen on this, because of the extra work it will give us.
  2. Use a third party provider of type 2 above – I’ve been trying with Axis Solutions, but seem to have hit a wall. Any suggestions for alternative providers would be welcome.
  3. Use a third party provider of type 3 above – May pursue this option, but would be glad to split development costs among others who may want to do this.
  4. Use Microsoft Excel templates/integration from a third party provider – I’m not keen on this, because of the extra work it will give us.
  5. Change to an accounting system that is more widely used and has existing templates or integrations with a local third party fiscal integration provider – I’m not keen on this because of the amount of work it would take to change over, because I have invested a lot of time into learning Manager and setting up our business to suit our needs, and because I like the way Manager works and suits our needs and I think I’m unlikely to be as happy with the other available options.

If anyone has any suggestions for alternative solutions I would love to hear them. I will update this topic if Fiscal Harmony (or anyone else) develops a Manager integration, and I would be happy to share my theme template if it would be useful to others.

I have skimmed through the api guide from the link you mentioned. I still can’t understand it, maybe I need more resources to understand how and what the procedure is like.

Or if you can explain how this system works and what the manager should do, that would be very helpful.

If you have an excel example of what you mean here, or you have other resources such as detailed guides, please share them with me.

2 Likes

This should work with all combination of Tax Code
Exempt - NonVat (0%) - Vat 9% - Vat 15%

<tr>
		<td colspan="2">
			<!-- Table Item Section -->
			<table style="width: 100%">
				<thead>
					<tr>
						<th style="padding: 5px 10px; text-align: left; vertical-align: middle; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; background-color: #f8f9fa;;">Item</th>
						<th style="padding: 5px 10px; text-align: left; vertical-align: middle; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; background-color: #f8f9fa;;">Description</th>
						<th style="padding: 5px 10px; text-align: right; vertical-align: middle; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; background-color: #f8f9fa;; width: 80px;">Qty</th>
						<th style="padding: 5px 10px; text-align: right; vertical-align: middle; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; background-color: #f8f9fa;; width: 80px;">Unit Price</th>
						<th style="padding: 5px 10px; text-align: right; vertical-align: middle; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; background-color: #f8f9fa;; width: 80px;">Amount<br/>(excl. VAT)</th>
						<th style="padding: 5px 10px; text-align: right; vertical-align: middle; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; background-color: #f8f9fa;; width: 50px;">VAT</th>
						<th style="padding: 5px 10px; text-align: right; vertical-align: middle; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; background-color: #f8f9fa;; width: 100px;">Amount<br/>(incl. VAT)</th>
					</tr>
				</thead>
				<tbody>
                    {% assign itemIdx = nil %}
                    {% assign descriptionIdx = nil %}
                    {% assign qtyIdx = nil %}
                    {% assign unitPriceIdx = nil %}
                    {% assign amountIdx = nil %}
                    {% assign taxIdx = nil %}
                    {% assign taxAmountIdx = nil %}
                    {% assign totalIdx = nil %}
                
                    <!-- Identify column indexes -->
                    {% for column in table.columns %}
                        {% if column.label == "Item" %}
                            {% assign itemIdx = forloop.index0 %}
                        {% elsif column.label == "Description" %}
                            {% assign descriptionIdx = forloop.index0 %}
                        {% elsif column.label == "Unit price" %}
                            {% assign unitPriceIdx = forloop.index0 %}
                            {% assign qtyIdx = forloop.index0 | minus: 1 %} <!-- Qty is one index before Unit price -->
                        {% elsif column.label == "Tax" %}
                            {% assign taxIdx = forloop.index0 %}
                        {% elsif column.label == "Tax Amount" %}
                            {% assign taxAmountIdx = forloop.index0 %}
                        {% elsif column.label == "Total" %}
                            {% assign totalIdx = forloop.index0 %}
                        {% endif %}
                    {% endfor %}
                
                    <!-- Iterate through rows and extract data -->
                    {% for row in table.rows %}
                        {% assign itemText = nil %}
                        {% assign descriptionText = nil %}
                        {% assign qty = nil %}
                        {% assign qtyText = nil %}
                        {% assign unitPrice = nil %}
                        {% assign unitPriceText = nil %}
                        {% assign amount = 0 %}
                        {% assign amountText = nil %}
                        {% assign taxText = '&nbsp;' %}
                        {% assign taxAmount = nil %}
                        {% assign taxAmountText = '&nbsp;' %}
                        {% assign total = 0 %}
                        {% assign totalText = nil %}
                
                        <!-- Extract data from each cell -->
                        {% for cell in row.cells %}
                            {% if forloop.index0 == itemIdx %}
                                {% assign itemText = cell.text %}
                            {% elsif forloop.index0 == descriptionIdx %}
                                {% assign descriptionText = cell.text %}
                            {% elsif forloop.index0 == qtyIdx %}
                                {% assign qty = cell.value %}
                                {% assign qtyText = cell.value %}
                            {% elsif forloop.index0 == unitPriceIdx %}
                                {% assign unitPrice = cell.value %}
                                {% assign unitPriceText = cell.text %}
                            {% elsif forloop.index0 == taxIdx %}
                                {% assign taxText = cell.text %}
                            {% elsif forloop.index0 == taxAmountIdx %}
                                {% assign taxAmount = cell.value %}
                                {% assign taxAmountText = cell.text %}
                            {% elsif forloop.index0 == totalIdx %}
                                {% assign total = cell.value %}
                                {% assign totalText = cell.text %}
                            {% endif %}
                        {% endfor %}
                
                        <!-- Check tax and tax amount conditions -->
                        {% if taxText == '&nbsp;' and taxAmountText == '&nbsp;' %}
                            {% assign taxAmountText = '&nbsp;' %}
                            {% assign taxAmount = 0 %}
                        {% elsif taxText != '&nbsp;' and taxAmountText == '&nbsp;' %}
                            {% assign taxAmountText = '0.00' %}
                            {% assign taxAmount = 0 %}
                        {% endif %}
                
                        <!-- Calculate Amount and Total if needed -->
                        {% if amount == 0 %}
                            {% assign amountText = totalText %}
                        {% endif %}
                
                        <!-- Output the row -->
					<tr>
						<td style="padding: 5px 10px; text-align: left; vertical-align: top; width: 50px;">{{ itemText }}</td>
						<td style="padding: 5px 10px; text-align: left; vertical-align: top;">{{ descriptionText }}</td>
						<td style="padding: 5px 10px; text-align: right; vertical-align: top; width: 80px;">{{ qtyText }}</td>
						<td style="padding: 5px 10px; text-align: right; vertical-align: top; width: 80px;">{{ unitPriceText }}</td>
						<td style="padding: 5px 10px; text-align: right; vertical-align: top; width: 80px;">{{ amountText }}</td>
						<td style="padding: 5px 10px; text-align: right; vertical-align: top; width: 50px;">{{ taxAmountText }}</td>
						<td style="padding: 5px 10px; text-align: right; vertical-align: top; width: 100px;">{{ totalText }}</td>
					</tr>
                    {% endfor %}
                    <tr style="border-bottom: 1px solid #ddd;">
						<td colspan="99">&nbsp;</td>
					</tr>
				</tbody>
			</table>

{% assign amountInWords = "" %}  <!-- Initialize variable -->

{% for cf in custom_fields %}
    {% if cf.label == "Total amount in words" %}
        {% assign amountInWords = cf.text %}
    {% endif %}
{% endfor %}


<table style="width: 100%;">
				<tbody>
        {% assign rowCount = 0 %}
        
        {% for total in table.totals %}
            {% assign rowCount = forloop.index %}  <!-- This assigns the current row index -->
        {% endfor %}

        {% for total in table.totals %}
            <tr>
                {% if forloop.first %}
                    <!-- Placeholder cell with rowspan set to row count and border-top for the first row -->
						<td rowspan="{{ rowCount }}" colspan="4" style="padding: 5px 10px; text-align: left; border-top: 1px solid #dddddd; background-color: #f8f9fa;">
							<!-- Now you can use amountInWords variable where needed -->
                        {% if amountInWords != "" %}<p>
								<strong>Total amount in words: </strong>
								<br/>
								<i>{{ amountInWords }}</i>
							</p>{% endif %}
                    </td>
                {% endif %}
                
                {% assign textArray = total.text | split: " " %}
                {% assign firstIndex = textArray | first %}
                {% assign lastIndex = textArray | last %}

                <!-- Label cell spanning 2 columns, aligned right, only first row gets border-top -->
						<td colspan="2" style="padding: 5px 10px; text-align: right; {% if forloop.first %} border-top: 1px solid #dddddd; {% endif %} background-color: #f8f9fa;">
							<span style="{% if total.emphasis %} font-weight: bold; {% else %} font-weight: normal; {% endif %}">
                        {% if total.label == "Sub-total" %}
                            Total (excl. tax)
                        {% elsif total.label == "Total" %}
                            Invoice total, {{ firstIndex }}
                        {% elsif total.class == "taxAmount" %}
                            Total {{ total.label }}
                        {% else %}
                            {{ total.label }}
                        {% endif %}
                    </span>
						</td>
						<!-- Value cell with fixed width, only first row gets border-top -->
						<td style="padding: 5px 10px; text-align: right; {% if forloop.first %} border-top: 1px solid #dddddd; {% endif %} background-color: #f8f9fa; width: 100px;">
							<span style="{% if total.emphasis %} font-weight: bold; {% else %} font-weight: normal; {% endif %}">
                        {{ lastIndex }}
                    </span>
						</td>
					</tr>
        {% endfor %}
    </tbody>
			</table>
		</td>
	</tr>
	

and modify this code from "&nbsp;" to “0.00” if you want show Vat Exempt to “0.00”

<!-- Check tax and tax amount conditions -->
                        {% if taxText == '&nbsp;' and taxAmountText == '&nbsp;' %}
                            {% assign taxAmountText = '&nbsp;' %}

Hello, Kindly share a complete invoice code for this extract Mabaega.

Not finished yet, I just tried it again.

I am still learning how FDMS works and how to prepare Manager to integrate with FDMS.

I will share it later, once all the pieces are in place.

I don’t know much more than what is in the API documentation linked above. My understanding is that the process should work something like this:

  1. At the beginning of a trading day, the user opens a “fiscal day” by sending a request to ZIMRA’s server. ZIMRA’s server responds with an approval and the user’s business details. There are several counters, relating to the fiscal day sequence, the global invoice sequence, and the daily invoice sequence. Some of these can be reset daily, while others cannot. I’m not sure if these are saved locally or on ZIMRA’s server, or both.
  2. Assuming the request to open a fiscal day was approved, the user submits all sales invoices and credit notes to ZIMRA through the API. Ideally this should happen as they are issued, in the correct sequence. However, there is some provision to submit them out of order, as long as any missing transactions are submitted before the end of the fiscal day. For each transaction that is submitted to ZIMRA’s API, some of the details such as the customer information is verified against their records. If all the required information is present and the transaction data is accepted by ZIMRA, a response is sent to the user. This includes the data needed for a QR code which should be printed on the invoice that is given to the customer. The customer can use the QR code to verify that the transaction is valid and was recorded successfully by ZIMRA.
  3. At the end of the day, the user submits a “Z-report” to ZIMRA. This contains a summary of the transactions for the day. If it matches what ZIMRA has recorded during the day and there are no missing transactions from the sequences, ZIMRA sends a response to the user acknowledging the successful submission of the Z-report and closes the fiscal day.

So, it looks to me like Manager could probably handle the submission of transaction data (step 2) to ZIMRA’s server through the relay service, but I don’t see how it could handle the opening and closing of the fiscal day, the Z-report, etc.

I did also read a few other things in the API documentation that I am not sure of, such as:

  1. The method of payment and amount paid are listed as required information, but this was never brought up in our attempted setup with Axis Solutions.
  2. I saw mention of a periodic “ping” that ZIMRA’s server would send to the user at a set interval during a fiscal day to check that the user’s device is online.

The Excel methods would vary depending on the third-party supplier. For example, Axis Solutions I think just has a simple Excel template that has the wording and column structure that they have trained their device to read when it is saved as a PDF. Fiscal Harmony has an Excel plugin and a template. You can read some more about their method on their support page.

1 Like

@GrahamvdR I think the best is to find a programmer in Zimbabwe to take on this.

See: https://github.com/lubos for more details.

@Mabaega can provide feedback and advice as he is the most experienced in this area right now. So I think we can get it done fairly quickly but it would be better to have dedicated programmer in Zimbabwe for this.

3 Likes

Thank you @lubos. I will probably engage the developer at Fiscal Harmony who said he could do the integration.

1 Like