Certificate Generation
The final step in this process is the creation of configs to create a voter registration PDF for the citizens to download. For this, we will make use of DIGIT’s PDF service which uses PDFMake and Mustache libraries to generate PDF. A detailed documentation on PDF service and generating PDFs using PDF service can be found here - PDF Generation Service.
For our guide, we will follow the following steps to set up PDF service locally and generate PDF for our voter registration service -
i) Clone DIGIT Services repo.
> git clone -o upstream https://github.com/egovernments/DIGIT-Dev
ii) Clone Configs repo.
> git clone -o upstream https://github.com/egovernments/configs
iii) Now, go into the DIGIT-Dev repo and open up a terminal. Checkout DIGIT_DEVELOPER_GUIDE branch.
> cd DIGIT-Dev
> git checkout DIGIT_DEVELOPER_GUIDE
iv) Now, go inside configs folder and under pdf-service
data config and format config folders, create file by the name of digit-developer-guide.json
> cd configs/pdf-service/data-config
> touch digit-developer-guide.json
Add the following content in this newly created data config file -
{
"key": "vtcertificate",
"DataConfigs": {
"serviceName": "rainmaker-common",
"version": "1.0.0",
"baseKeyPath": "$.VoterRegistrationApplications.*",
"entityIdPath":"$.id",
"isCommonTableBorderRequired": true,
"mappings": [
{
"mappings": [
{
"direct": [
{
"variable": "logoImage",
"url":"https://raw.githubusercontent.com/egovernments/egov-web-app/master/web/rainmaker/dev-packages/egov-ui-kit-dev/src/assets/images/pblogo.png",
"type":"image"
},
{
"variable": "applicantName",
"value": {
"path": "$.applicant.name"
}
},
{
"variable": "applicationNo",
"value": {
"path": "$.applicationNumber"
}
},
{
"variable": "address",
"value": {
"path": "$.address.city"
}
},
{
"variable": "voterIdIssueDate",
"value": {
"path": "$.auditDetails.createdTime"
},
"type": "date"
},
{
"variable": "signedCertificateData",
"value": {
"path": "$.signedCertificate"
}
},
{
"variable": "to",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_RECEIPT_TO"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "municipal_corportaion",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_MUNICIPAL_CORPORATION"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "corporation_contact",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_LICENSE_CORPORATION_CONTACT"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "corporation_website",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_LICENSE_CORPORATION_WEBSITE"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "corporation_email",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_LICENSE_CORPORATION_EMAIL"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "application_no",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_APPLICATION_NO"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "reciept_no",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_RECIEPT_NO"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "financial_year",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_FINANCIAL_YEAR"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "trade_name",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_TRADE_NAME"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "trade_owner_name",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_TRADE_OWNER_NAME"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "trade_owner_contact",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_TRADE_OWNER_CONTACT"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "trade_address",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_TRADE_ADDRESS"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "trade_type",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_TRADE_TYPE"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "accessories_label",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_ACCESSORIES_LABEL"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "trade_license_fee",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_TRADE_LICENSE_FEE"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "license_issue_date",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_LICENSE_ISSUE_DATE"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "license_validity",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_LICENSE_VALIDITY"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "approved_by",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_APPROVED_BY"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
},
{
"variable": "commissioner",
"value": {
"path": "PDF_STATIC_LABEL_CONSOLIDATED_TLCERTIFICATE_COMMISSIONER"
},
"type": "label",
"localisation":{
"required":true,
"prefix": null,
"module":"rainmaker-common"
}
}
]
},
{
"externalAPI": [
{
"path": "http://localhost:8082/egov-mdms-service/v1/_get",
"queryParam": "moduleName=tenant&masterName=tenants&tenantId=pb&filter=%5B?(@.code=='{$.tenantId}')%5D",
"apiRequest": null,
"responseMapping":[
{
"variable":"ulb-address",
"value":"$.MdmsRes.tenant.tenants[0].address"
},
{
"variable":"corporationContact",
"value":"$.MdmsRes.tenant.tenants[0].contactNumber"
},
{
"variable":"corporationWebsite",
"value":"$.MdmsRes.tenant.tenants[0].domainUrl"
},
{
"variable":"corporationEmail",
"value":"$.MdmsRes.tenant.tenants[0].emailId"
}
]
},
{
"path": "http://localhost:8288/filestore/v1/files/url",
"queryParam": "tenantId=pb,fileStoreIds=$.tradeLicenseDetail.applicationDocuments[?(@.documentType== 'OWNERPHOTO')].fileStoreId",
"apiRequest": null,
"requesttype": "GET",
"responseMapping":[
{
"variable":"userpic",
"value":"$.fileStoreIds[0].url",
"type": "image"
}
]
},
{
"path": "http://localhost:8282/egov-workflow-v2/egov-wf/process/_search",
"queryParam": "businessIds=$.applicationNumber,history=true,tenantId=$.tenantId",
"apiRequest": null,
"responseMapping":[
{
"variable":"approvedBy",
"value":"$.ProcessInstances[?(@.action == 'APPROVE')].assigner.name"
}
]
}
]
},
{
"qrcodeConfig": [
{
"variable": "qrCode",
"value": "{{signedCertificateData}}"
}
]
}
]
}
]
}
}
v) Now, under format-config folder, again create a file by the name of digit-developer-guide.json
and put the following content into it -
{
"key": "vtcertificate",
"config": {
"defaultStyle": {
"font": "Cambay"
},
"content": [
{
"image": "{{qrCode}}",
"absolutePosition" : {
"x" : 480,
"y" : 5
},
"width": 100,
"height": 100
},
{
"style":"noc-head",
"table":{
"widths":[
"*"
],
"body":[
[
{
"image": "{{userpic}}",
"width": 70,
"height": 82,
"alignment": "center",
"margin": [
0,
10,
0,
10
]
}
],
[
{
"stack": [
{
"text":"{{municipal_corportaion}}",
"style":"receipt-logo-header"
},
{
"text":"{{ulb-address}}",
"style":"receipt-logo-sub-header"
},
{
"style": "noc-head",
"table": {
"widths": [
"*",
"*"
],
"body": [
[
{
"text": "{{corporation_contact}} : {{corporationContact}} ",
"style": "receipt-sub-address-sub-header"
}
]
]
},
"layout": "noBorders"
},
{
"style": "noc-head",
"table": {
"widths": [
"*",
"*"
],
"body": [
[
{
"text": "{{corporation_website}} : {{corporationWebsite}}",
"style": "receipt-sub-website-sub-header"
}
]
]
},
"layout": "noBorders"
},
{
"style": "noc-head",
"table": {
"widths": [
"*",
"*"
],
"body": [
[
{
"text": "{{corporation_email}} : {{corporationEmail}}",
"style": "receipt-sub-email-sub-header"
}
]
]
},
"layout": "noBorders"
}
],
"alignment":"left",
"margin":[
0,
10,
0,
0
]
}
],
[
{
"stack": [
{
"text":"Voter ID Certificate",
"style":"receipt-sub-logo-header"
},
{
"style":"noc-head",
"table":{
"widths":[
"35%",
"65%"
],
"body":[
[
{
"text":"Applicant Name",
"style":"receipt-sub-logo-sub-header"
},
{
"text":"{{applicantName}}",
"style":"receipt-sub-logo-sub-header"
}
]
]
},
"layout":"noBorders"
},
{
"style":"noc-head",
"table":{
"widths":[
"35%",
"65%"
],
"body":[
[
{
"text":"Application Number",
"style":"receipt-sub-logo-sub-header"
},
{
"text":"{{applicationNo}}",
"style":"receipt-sub-logo-sub-header"
}
]
]
},
"layout":"noBorders"
},
{
"style":"noc-head",
"table":{
"widths":[
"35%",
"65%"
],
"body":[
[
{
"text":"Applicant Address",
"style":"receipt-sub-logo-sub-header"
},
{
"text":"{{address}}",
"style":"receipt-sub-logo-sub-header"
}
]
]
},
"layout":"noBorders"
},
{
"style":"noc-head",
"table":{
"widths":[
"35%",
"65%"
],
"body":[
[
{
"text":"Voter ID issue date",
"style":"receipt-sub-logo-sub-header"
},
{
"text":"{{voterIdIssueDate}}",
"style":"receipt-sub-logo-sub-header"
}
]
]
},
"layout":"noBorders"
}
],
"alignment":"left",
"margin":[
0,
10,
0,
0
]
}
]
]
},
"layout":"noBorders"
},
{
"style":"receipt-approver",
"columns": [
{
"text":[
{
"text":"{{approved_by}} ",
"bold": true
},
{
"text":" {{approvedBy}}",
"bold": false
}
],
"alignment":"left"
},
{
"text":[
{
"text":"{{commissioner}}",
"bold": true
}
],
"alignment":"right"
}
]
}
],
"styles": {
"noc-head": {
"margin": [
-30,
-35,
0,
-2
]
},
"receipt-approver": {
"color": "#000000",
"fontSize": 14,
"letterSpacing": 0.6,
"alignment": "center",
"margin": [
-10,
50,
0,
1
]
},
"receipt-logo-header": {
"color": "#000000",
"fontSize": 20,
"letterSpacing": 0.74,
"alignment": "center",
"margin": [
0,
0,
0,
5
]
},
"receipt-sub-logo-header": {
"color": "#000000",
"fontSize": 18,
"letterSpacing": 0.74,
"alignment": "center",
"margin": [
0,
5,
0,
5
]
},
"receipt-logo-sub-header": {
"color": "#484848",
"fontSize": 14,
"letterSpacing": 0.6,
"alignment": "center",
"margin": [
0,
5,
0,
0
]
},
"receipt-sub-logo-sub-header": {
"color": "#484848",
"fontSize": 14,
"letterSpacing": 0.6,
"alignment": "left",
"margin": [
50,
40,
0,
0
]
},
"receipt-sub-address-sub-header": {
"color": "#484848",
"fontSize": 14,
"letterSpacing": 0.1,
"alignment": "right",
"margin": [
50,
30,
-90,
0
]
},
"receipt-sub-website-sub-header": {
"color": "#484848",
"fontSize": 14,
"letterSpacing": 0.1,
"alignment": "right",
"margin": [
50,
30,
-120,
0
]
},
"receipt-sub-email-sub-header": {
"color": "#484848",
"fontSize": 14,
"letterSpacing": 0.1,
"alignment": "right",
"margin": [
50,
30,
-110,
0
]
}
}
}
}
vi) Now, open PDF service (under core-services repository of DIGIT-Dev) on your IDE. Open Environment.js
file and change the following properties to point to the local config files that have been created. For example, in my local setup I have pointed these to the local files that I created -
DATA_CONFIG_URLS: "file:///eGov/configs/pdf-service/data-config/digit-developer-guide.json",
FORMAT_CONFIG_URLS: "file:///eGov/configs/pdf-service/format-config/digit-developer-guide.json"
vii) Now, make sure that kafka and workflow services are running locally and port-forward the following services -
egov-user to port 8284
egov-localization to port 8286
egov-filestore to 8288
egov-mdms to 8082
viii) PDF service is now ready to be started up. Execute the following commands to start it up -
> npm install
> npm run dev
ix) Once PDF service is up hit the following cURL to look at the created PDF -
To be added