# Assess Property

## Overview

The **Property Assessment** configuration guide explains how to configure and set up the necessary **MDMS configurations**, **persister mappings**, and **workflow integrations** required to create, update, and manage assessments. It also covers how assessments interact with downstream components like the **PT Calculator** and **Billing Service**, and how citizens are kept informed through **workflow-driven notifications**.

## **Key Functionalities**

The **Assessment of Property** feature allows the system to:

* **Create**, **update**, and **search** assessments associated with a property.
* Serve as the basis for **tax calculation and demand generation**.
* Capture a **snapshot of property characteristics** for a given financial year.
* Only operate on properties that are already registered in the system.

## **Configuration Steps** <a href="#configuration-details" id="configuration-details"></a>

{% stepper %}
{% step %}

### Configure MDMS

**Shared Configs**

Assessment largely **inherits configs from the Property Tax module**, so start by including the PropertyTax MDMS templates from the [repository here](https://github.com/egovernments/egov-mdms-data/tree/DEV/data/pb/PropertyTax).

**Assessment-Specific MDMS Settings**

<table><thead><tr><th width="198.86328125">Config Key</th><th width="194.44140625">Example Value</th><th>Purpose</th></tr></thead><tbody><tr><td><code>assessment id format</code></td><td><code>PB-AS-[cy:yyyy-MM-dd]-[SEQ_EG_PT_ASSM]</code></td><td>Format for generating unique IDs for assessments</td></tr><tr><td><code>kafka create assessment topic</code></td><td><code>save-pt-assessment</code></td><td>Kafka topic for new assessment events</td></tr><tr><td><code>kafka update assessment topic</code></td><td><code>update-pt-assessment</code></td><td>Kafka topic for assessment updates</td></tr><tr><td><code>assessment.workflow.enabled</code></td><td><code>true/false</code></td><td>Enable workflow for assessments</td></tr><tr><td><code>assessment.workflow.trigger.param</code></td><td><code>usageCategory,occupancyType,occupancyDate</code></td><td>Fields that trigger workflow when changed</td></tr></tbody></table>

{% hint style="info" %}
👩‍💼 *Note:* You may need to adjust workflow parameters based on local assessment criteria.
{% endhint %}
{% endstep %}

{% step %}

### Configure Persister

Assessment data is stored and updated through the Persister service.

* Add the [**assessment-persister.yml** ](https://raw.githubusercontent.com/egovernments/configs/master/egov-persister/assessment-persister.yml?token=AE4Z2KFWEQBDCUY6AZLGGIK6AM3QQ)config to your Persister configs.

```
serviceMaps:
  serviceName: property-services
  mappings:
  - version: 1.0
    description: Persists assessment details to eg_pt_asmt_assessment table
    fromTopic: save-pt-assessment
    isTransaction: true
    queryMaps:

    - query: INSERT INTO eg_pt_asmt_assessment(id, tenantid, assessmentnumber, financialyear, propertyid, status, source, channel, assessmentdate, additionaldetails, createdby, createdtime, lastmodifiedby, lastmodifiedtime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
      basePath: Assessment
      jsonMaps:

      - jsonPath: $.Assessment.id

      - jsonPath: $.Assessment.tenantId

      - jsonPath: $.Assessment.assessmentNumber

      - jsonPath: $.Assessment.financialYear

      - jsonPath: $.Assessment.propertyId

      - jsonPath: $.Assessment.status

      - jsonPath: $.Assessment.source

      - jsonPath: $.Assessment.channel

      - jsonPath: $.Assessment.assessmentDate

      - jsonPath: $.Assessment.additionalDetails
        type: JSON
        dbType: JSONB

      - jsonPath: $.Assessment.auditDetails.createdBy

      - jsonPath: $.Assessment.auditDetails.createdTime

      - jsonPath: $.Assessment.auditDetails.lastModifiedBy

      - jsonPath: $.Assessment.auditDetails.lastModifiedTime



    - query: INSERT INTO eg_pt_asmt_unitusage (tenantid, id, assessmentid, unitid, usagecategory, occupancytype, occupancydate, active, createdby, createdtime, lastmodifiedby, lastmodifiedtime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
      basePath: Assessment.unitUsageList.*
      jsonMaps:

      - jsonPath: $.Assessment.unitUsageList.*.tenantId

      - jsonPath: $.Assessment.unitUsageList.*.id

      - jsonPath: $.Assessment[?({id} in @.unitUsageList[*].id)].id

      - jsonPath: $.Assessment.unitUsageList.*.unitId

      - jsonPath: $.Assessment.unitUsageList.*.usageCategory

      - jsonPath: $.Assessment.unitUsageList.*.occupancyType

      - jsonPath: $.Assessment.unitUsageList.*.occupancyDate

      - jsonPath: $.Assessment.unitUsageList.*.active

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.createdBy

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.createdTime

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.lastModifiedBy

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.lastModifiedTime



    - query: INSERT INTO eg_pt_asmt_document (id, tenantid, entityid, documenttype, filestoreid, documentuid, status, createdby, lastmodifiedby, createdtime, lastmodifiedtime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
      basePath: $.Assessment.documents.*
      jsonMaps:

      - jsonPath: $.Assessment.documents.*.id

      - jsonPath: $.Assessment.tenantId

      - jsonPath: $.Assessment.id

      - jsonPath: $.Assessment.documents.*.documentType

      - jsonPath: $.Assessment.documents.*.fileStoreId

      - jsonPath: $.Assessment.documents.*.documentUid

      - jsonPath: $.Assessment.documents.*.status

      - jsonPath: $.Assessment.documents.*.auditDetails.createdBy

      - jsonPath: $.Assessment.documents.*.auditDetails.lastModifiedBy

      - jsonPath: $.Assessment.documents.*.auditDetails.createdTime

      - jsonPath: $.Assessment.documents.*.auditDetails.lastModifiedTime



  - version: 1.0
    description: Updates assessment details to eg_pt_asmt_assessment table
    fromTopic: update-pt-assessment
    isTransaction: true
    queryMaps:

    - query: INSERT INTO eg_pt_asmt_assessment_audit SELECT *, (SELECT extract(epoch from now())) FROM eg_pt_asmt_assessment WHERE id = ?;
      basePath: Assessment
      jsonMaps:

      - jsonPath: $.Assessment.id


    - query: INSERT INTO eg_pt_asmt_unitusage_audit SELECT *, (SELECT extract(epoch from now())) FROM eg_pt_asmt_unitusage WHERE id = ?;
      basePath: Assessment.unitUsageList.*
      jsonMaps:

      - jsonPath: $.Assessment.unitUsageList.*.id


    - query: UPDATE eg_pt_asmt_assessment SET financialyear = ?, status = ?, source = ?, assessmentDate = ?, additionaldetails = ?, lastmodifiedby = ?, lastmodifiedtime = ? WHERE id = ?;
      basePath: Assessment
      jsonMaps:

      - jsonPath: $.Assessment.financialYear

      - jsonPath: $.Assessment.status

      - jsonPath: $.Assessment.source

      - jsonPath: $.Assessment.assessmentDate

      - jsonPath: $.Assessment.additionalDetails
        type: JSON
        dbType: JSONB

      - jsonPath: $.Assessment.auditDetails.lastModifiedBy

      - jsonPath: $.Assessment.auditDetails.lastModifiedTime

      - jsonPath: $.Assessment.id




    - query: INSERT INTO eg_pt_asmt_unitusage (tenantid, id, assessmentId, unitid, usageCategory, occupancyType, occupancyDate, active, createdby, createdtime, lastmodifiedby, lastmodifiedtime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT (id) DO UPDATE SET usageCategory = ?, occupancyType = ?, occupancyDate = ?, active = ?, lastmodifiedby = ?, lastmodifiedtime = ?;
      basePath: Assessment.unitUsageList.*
      jsonMaps:

      - jsonPath: $.Assessment.unitUsageList.*.tenantId

      - jsonPath: $.Assessment.unitUsageList.*.id

      - jsonPath: $.Assessment[?({id} in @.unitUsageList[*].id)].id

      - jsonPath: $.Assessment.unitUsageList.*.unitId

      - jsonPath: $.Assessment.unitUsageList.*.usageCategory

      - jsonPath: $.Assessment.unitUsageList.*.occupancyType

      - jsonPath: $.Assessment.unitUsageList.*.occupancyDate

      - jsonPath: $.Assessment.unitUsageList.*.active

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.createdBy

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.createdTime

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.lastModifiedBy

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.lastModifiedTime

      - jsonPath: $.Assessment.unitUsageList.*.usageCategory

      - jsonPath: $.Assessment.unitUsageList.*.occupancyType

      - jsonPath: $.Assessment.unitUsageList.*.occupancyDate

      - jsonPath: $.Assessment.unitUsageList.*.active

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.lastModifiedBy

      - jsonPath: $.Assessment.unitUsageList.*.auditDetails.lastModifiedTime




    - query: INSERT INTO eg_pt_asmt_document (id, tenantid, entityid, documenttype, filestoreid, documentuid, status, createdby, lastmodifiedby, createdtime, lastmodifiedtime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT (id) DO UPDATE documenttype = ?, documentuid = ?, status = ?, lastmodifiedby = ?, lastmodifiedtime = ?;
      basePath: $.Assessment.documents.*
      jsonMaps:

      - jsonPath: $.Assessment.documents.*.id

      - jsonPath: $.Assessment.tenantId

      - jsonPath: $.Assessment.id

      - jsonPath: $.Assessment.documents.*.documentType

      - jsonPath: $.Assessment.documents.*.fileStoreId

      - jsonPath: $.Assessment.documents.*.documentUid

      - jsonPath: $.Assessment.documents.*.status

      - jsonPath: $.Assessment.documents.*.auditDetails.createdBy

      - jsonPath: $.Assessment.documents.*.auditDetails.lastModifiedBy

      - jsonPath: $.Assessment.documents.*.auditDetails.createdTime

      - jsonPath: $.Assessment.documents.*.auditDetails.lastModifiedTime

      - jsonPath: $.Assessment.documents.*.documentType

      - jsonPath: $.Assessment.documents.*.documentUid

      - jsonPath: $.Assessment.documents.*.status

      - jsonPath: $.Assessment.documents.*.auditDetails.lastModifiedBy

      - jsonPath: $.Assessment.documents.*.auditDetails.lastModifiedTime

```

* It specifies SQL mappings for tables such as:
  * `eg_pt_asmt_assessment`
  * `eg_pt_asmt_unitusage`
  * `eg_pt_asmt_document`
* These mappings ensure assessment data and related unit usage/documents are persisted correctly.
  {% endstep %}

{% step %}

### Configure Workflow

To handle assessment processes via workflow:

1. **Enable assessment workflow** via `assessment.workflow.enabled` flag.
2. Create a corresponding **businessService definition** for assessments:
   * Use **/egov-workflow-v2/egov-wf/businessservice/\_create** API.
   * Typically, the businessService is named something like `"ASMT"` (example in MDMS).

This enables statuses like **INITIATED → APPLIED → APPROVED** to be managed with actions like **APPLY, FORWARD, REJECT**, etc.

Below is a sample businessService create API body for the  Assessment workflow:

```
{
  "RequestInfo": {
    "apiId": "Rainmaker",
    "action": "",
    "did": 1,
    "key": "",
    "msgId": "20170310130900|en_IN",
    "requesterId": "",
    "ts": 1513579888683,
    "ver": ".01",
    "authToken": "b39181b1-5c6b-484a-b825-6be2f62012b8"
  },
 "BusinessServices": [
    {
      "tenantId": "pb",
      "businessService": "ASMT",
      "business": "pt-services",
      "businessServiceSla": 172800000,
      "states": [
        {
          "sla": null,
          "state": null,
          "applicationStatus": null,
          "docUploadRequired": false,
          "isStartState": true,
          "isTerminateState": false,
          "isStateUpdatable": true,
          "actions": [
            {
              "action": "INITIATE",
              "nextState": "INITIATED",
              "roles": [
                "CITIZEN",
                "PT_CEMP"
              ]
            }
          ]
        },
        {
          "sla": null,
          "state": "INITIATED",
          "applicationStatus": "INITIATED",
          "docUploadRequired": false,
          "isStartState": true,
          "isTerminateState": false,
          "actions": [
            {
              "action": "APPLY",
              "nextState": "APPLIED",
              "roles": [
                "CITIZEN",
                "PT_CEMP"
              ]
            },
            {
              "action": "INITIATE",
              "nextState": "INITIATED",
              "roles": [
                "CITIZEN",
                "PT_CEMP"
              ]
            }
          ]
        },
        {
          "sla": null,
          "state": "APPLIED",
          "applicationStatus": "APPLIED",
          "docUploadRequired": false,
          "isStartState": false,
          "isTerminateState": false,
          "isStateUpdatable": true,
          "actions": [
            {
              "action": "FORWARD",
              "nextState": "FIELDINSPECTION",
              "roles": [
                "PT_DOC_VERIFIER"
              ]
            },
            {
              "action": "REJECT",
              "nextState": "REJECTED",
              "roles": [
                "PT_DOC_VERIFIER"
              ]
            },
            {
              "action" : "SENDBACKTOCITIZEN",
              "nextState" : "INITIATED",
              "roles":["PT_DOC_VERIFIER"]
            }
          ]
        },
        {
          "sla": null,
          "state": "REJECTED",
          "applicationStatus": "REJECTED",
          "isStateUpdatable": false,
          "docUploadRequired": false,
          "isStartState": false,
          "isTerminateState": true
        },
        {
          "sla": 86400000,
          "state": "FIELDINSPECTION",
          "applicationStatus": "FIELDINSPECTION",
          "docUploadRequired": false,
          "isStartState": false,
          "isStateUpdatable": true,
          "isTerminateState": false,
          "actions": [
            {
              "action": "FORWARD",
              "nextState": "PENDINGAPPROVAL",
              "roles": [
                "PT_FIELD_INSPECTOR"
              ]
            },
            {
              "action": "REJECT",
              "nextState": "REJECTED",
              "roles": [
                "PT_FIELD_INSPECTOR"
              ]
            },
            {
              "action": "SENDBACK",
              "nextState": "APPLIED",
              "roles": [
                "PT_FIELD_INSPECTOR"
              ]
            }
          ]
        },
        {
          "sla": 43200000,
          "state": "PENDINGAPPROVAL",
          "applicationStatus": "PENDINGAPPROVAL",
          "docUploadRequired": false,
          "isStartState": false,
          "isStateUpdatable": false,
          "isTerminateState": false,
          "actions": [
            {
              "action": "APPROVE",
              "nextState": "PENDINGPAYMENT",
              "roles": [
                "PT_APPROVER"
              ]
            },
            {
              "action": "REJECT",
              "nextState": "REJECTED",
              "roles": [
                "PT_APPROVER"
              ]
            },
            {
              "action": "SENDBACK",
              "nextState": "FIELDINSPECTION",
              "roles": [
                "PT_APPROVER"
              ]
            }
          ]
        },
        {
          "sla": 43200000,
          "state": "PENDINGPAYMENT",
          "applicationStatus": "PENDINGPAYMENT",
          "docUploadRequired": false,
          "isStartState": false,
          "isTerminateState": false,
          "isStateUpdatable": false,
          "actions": [
            {
              "action": "PAY",
              "nextState": "APPROVED",
              "roles": [
                "CITIZEN",
                "PT_CEMP",
                "SYSTEM_PAYMENT"
              ]
            },
            {
              "action": "ADHOC",
              "nextState": "PENDINGPAYMENT",
              "roles": [
                "PT_CEMP"
              ]
            }
          ]
        },
        {
          "sla": null,
          "state": "APPROVED",
          "applicationStatus": "APPROVED",
          "isStateUpdatable": false,
          "docUploadRequired": false,
          "isStartState": false,
          "isTerminateState": true
        }
      ]
    }
  ]
}	
```

{% endstep %}

{% step %}

### Setup Notifications

Notifications help notify citizens about assessment progress:

* Define notification messages and templates in the **rainmaker-pt** locale module.
* Use message codes such as:
  * `ASMT_CREATE` – When a new assessment is created
  * `ASMT_UPDATE` – When an assessment is updated
  * `ASMT_APPROVED` – When an assessment is approved
* For additional statuses, prefix with `ASMT_` and for messages use `ASMT_MSG_`.

Sample payment notification:

```
    {
      "code": "PT_NOTIFICATION_PAYMENT_FAIL",
      "message": "Dear Citizen, Your payment of Rs. <insert amount to pay> for Property Tax Unique ID <insert ID> has failed. Your assessment is pending. Please try again. Ignore this message if you have completed your payment. You can pay your Property Tax online here - <payLink>",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    },
    {
      "code": "PT_NOTIFICATION_PAYMENT_OFFILE",
      "message": "Dear Citizen,  Your Property Tax payment of Rs. <amount>  has been accepted. Mode of Payment: <insert mode of payment> Pending Amount: <Enter pending amount>.",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    },
    {
      "code": "PT_NOTIFICATION_PAYMENT_ONLINE",
      "message": "Dear Citizen, Your payment of Rs.< insert amount paid> with payment transaction id < insert payment transaction id from PG> has been made successfully. Assessment for Property Tax Unique ID <insert Property Tax Assessment ID>  was succesful. Property Tax due is Rs.<pt due>.",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    },
    {
      "code": "PT_NOTIFICATION_PAYMENT_PARTIAL_OFFLINE",
      "message": "Dear Citizen,  Your Property Tax payment of Rs. <amount>  has been accepted. Mode of Payment: <insert mode of payment> Pending Amount: <Enter pending amount>. You can pay your Property Tax online here - <payLink>",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    },
    {
      "code": "PT_NOTIFICATION_PAYMENT_PARTIAL_ONLINE",
      "message": "Dear Citizen, Your payment of Rs.< insert amount paid> with payment transaction id < insert payment transaction id from PG> has been made successfully. Assessment for Property Tax Unique ID <insert ID>  was succesful. Property Tax due is Rs.<pt due>. You can pay your Property Tax here - <payLink>",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    }
```

Sample Assessment notification:

```
    {
      "code": "ASMT_APPLIED",
      "message": "Applied",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    },
    {
      "code": "ASMT_APPROVED",
      "message": "Approved",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    },
    {
      "code": "ASMT_CREATE",
      "message": "Dear {OWNER_NAME}, Your assessment with {ASSESSMENTNUMBER} for financial year {FINANCIALYEAR} and property id {PROPERTYID} is created.",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    },
    {
      "code": "ASMT_UPDATE",
      "message": "Dear {OWNER_NAME}, Your assessment with {ASSESSMENTNUMBER} for financial year {FINANCIALYEAR} and property id {PROPERTYID} is reassessed.",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    },
    {
      "code": "ASMT_MSG_APPLIED",
      "message": "Dear {OWNER_NAME}, Your assessment with {ASSESSMENTNUMBER} for financial year {FINANCIALYEAR} and property id {PROPERTYID} is updated to {STATUS}.",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    },
    {
      "code": "ASMT_MSG_APPROVED",
      "message": "Dear {OWNER_NAME}, Your assessment with {ASSESSMENTNUMBER} for financial year {FINANCIALYEAR} and property id {PROPERTYID} is {STATUS}.",
      "module": "rainmaker-pt",
      "locale": "en_IN"
    }
```

{% endstep %}

{% step %}

### Generate Demand

Assessment triggers downstream processes:

* After a successful assessment creation or update, the **PT Calculator** can be invoked to calculate tax and create **demand in the billing service** using:
  * Estimate API (for non-persistent preview)
  * Calculate API (to generate demand for payment)
    {% endstep %}
    {% endstepper %}

## **References**

Refer to the property document[ Property Services | Doc-Links](https://docs.digit.org/local-governance/access/local-governance-stack/property-tax/property-tax-service)

**API LIST**

<table><thead><tr><th width="195.234375">API Endpoint</th><th></th></tr></thead><tbody><tr><td>/assessment/_create</td><td><a href="https://www.getpostman.com/collections/d1a02a29203d110df289">https://www.getpostman.com/collections/d1a02a29203d110df289</a></td></tr><tr><td>/assessment/_update</td><td><a href="https://www.getpostman.com/collections/d1a02a29203d110df289">https://www.getpostman.com/collections/d1a02a29203d110df289</a></td></tr><tr><td>/assessment/_search</td><td><a href="https://www.getpostman.com/collections/d1a02a29203d110df289">https://www.getpostman.com/collections/d1a02a29203d110df289</a></td></tr></tbody></table>
