Skip to main content

GetLoanQuoteDocumentByIdQuery

Overview

The GetLoanQuoteDocumentByIdQuery retrieves a single document with its full content (base64 data) for download. Use this query when you need to download or display a specific document.

Handler File: CB.Administration.Api/Commands/BPM/SelfService/DocumentManagementCommand.cs

Use Cases

  • Download document for viewing
  • Export document to local file system
  • Display document in PDF viewer
  • Print document
  • Forward document via email

Key Difference from GetLoanQuoteDocumentsQuery

QueryReturns DataUse Case
GetLoanQuoteDocumentsQuery❌ NoList documents (fast)
GetLoanQuoteDocumentByIdQuery✅ YesDownload single document

Request Parameters

Required Parameters

ParameterTypeDescription
loanQuoteIdlongThe ID of the loan quote
documentIdstring (GUID)The unique identifier of the document

Request Example

{
"cmd": "GetLoanQuoteDocumentByIdQuery",
"data": {
"loanQuoteId": 110,
"documentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}

Response Format

Success Response

{
"statusCode": "00",
"statusMessage": "SUCCESS",
"data": {
"documentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"documentName": "National ID Card.pdf",
"documentType": 1,
"documentTypeName": "NATIONAL_ID",
"description": "Customer national ID card - front and back",
"documentNumber": "ABC123456",
"documentExpiry": "2030-12-31T00:00:00Z",
"documentIssueDate": "2020-01-15T00:00:00Z",
"documentIssuer": "National Identity Management Commission",
"documentData": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlL...",
"createdDate": "2026-01-10T14:30:00Z",
"createdBy": {
"userId": 25,
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@bank.com"
}
}
}

Error Responses

Document Not Found:

{
"statusCode": "01",
"statusMessage": "Document not found for the specified loan quote",
"data": null
}

Invalid GUID Format:

{
"statusCode": "01",
"statusMessage": "Invalid documentId format",
"data": null
}

Loan Quote Not Found:

{
"statusCode": "01",
"statusMessage": "Loan quote with ID 999 not found",
"data": null
}

Response Fields

FieldTypeDescription
documentIdstring (GUID)Unique identifier
documentNamestringFile name
documentTypeintDocument type enum
documentTypeNamestringType name
descriptionstringDescription
documentNumberstringOfficial number
documentExpiryDateTimeExpiration date
documentIssueDateDateTimeIssue date
documentIssuerstringIssuer
documentDatastringBase64 encoded file content
createdDateDateTimeUpload timestamp
createdByobjectUploader details

JavaScript Usage Example

Download Document

const downloadDocument = async (loanQuoteId, documentId) => {
try {
const result = await api.query({
cmd: "GetLoanQuoteDocumentByIdQuery",
data: JSON.stringify({
loanQuoteId: loanQuoteId,
documentId: documentId
})
});

if (result.statusCode === "00") {
const doc = result.data;

// Convert base64 to blob
const blob = base64ToBlob(doc.documentData, getMimeType(doc.documentName));

// Create download link
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = doc.documentName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);

// Clean up
URL.revokeObjectURL(url);

console.log("Document downloaded:", doc.documentName);
} else {
alert(`Error: ${result.statusMessage}`);
}
} catch (error) {
console.error("Download failed:", error);
alert("Failed to download document");
}
};

// Helper function to convert base64 to blob
const base64ToBlob = (base64, mimeType = 'application/octet-stream') => {
const byteCharacters = atob(base64);
const byteNumbers = new Array(byteCharacters.length);

for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}

const byteArray = new Uint8Array(byteNumbers);
return new Blob([byteArray], { type: mimeType });
};

// Helper function to get MIME type from filename
const getMimeType = (filename) => {
const ext = filename.split('.').pop().toLowerCase();
const mimeTypes = {
'pdf': 'application/pdf',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'png': 'image/png',
'doc': 'application/msword',
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xls': 'application/vnd.ms-excel',
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
};
return mimeTypes[ext] || 'application/octet-stream';
};

Display PDF in Browser

const displayPdfInViewer = async (loanQuoteId, documentId) => {
try {
const result = await api.query({
cmd: "GetLoanQuoteDocumentByIdQuery",
data: JSON.stringify({ loanQuoteId, documentId })
});

if (result.statusCode === "00") {
const doc = result.data;

// Convert to blob URL
const blob = base64ToBlob(doc.documentData, 'application/pdf');
const url = URL.createObjectURL(blob);

// Display in iframe
const iframe = document.getElementById('pdfViewer');
iframe.src = url;

// Or open in new tab
// window.open(url, '_blank');

}
} catch (error) {
console.error("Display failed:", error);
}
};

Display Image Preview

const showImagePreview = async (loanQuoteId, documentId) => {
try {
const result = await api.query({
cmd: "GetLoanQuoteDocumentByIdQuery",
data: JSON.stringify({ loanQuoteId, documentId })
});

if (result.statusCode === "00") {
const doc = result.data;

// Create data URL
const mimeType = getMimeType(doc.documentName);
const dataUrl = `data:${mimeType};base64,${doc.documentData}`;

// Display in image element
const img = document.getElementById('documentPreview');
img.src = dataUrl;
img.alt = doc.documentName;
}
} catch (error) {
console.error("Preview failed:", error);
}
};

Complete Download Component

class DocumentDownloader {
constructor(loanQuoteId) {
this.loanQuoteId = loanQuoteId;
}

async download(documentId, documentName = null) {
try {
// Show loading indicator
this.showLoading(true);

const result = await api.query({
cmd: "GetLoanQuoteDocumentByIdQuery",
data: JSON.stringify({
loanQuoteId: this.loanQuoteId,
documentId: documentId
})
});

this.showLoading(false);

if (result.statusCode === "00") {
const doc = result.data;
this.triggerDownload(
doc.documentData,
documentName || doc.documentName
);
return true;
} else {
this.showError(result.statusMessage);
return false;
}
} catch (error) {
this.showLoading(false);
this.showError("Network error: " + error.message);
return false;
}
}

triggerDownload(base64Data, filename) {
const blob = this.base64ToBlob(base64Data, this.getMimeType(filename));
const url = URL.createObjectURL(blob);

const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = filename;

document.body.appendChild(a);
a.click();

// Cleanup
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 100);
}

base64ToBlob(base64, mimeType = 'application/octet-stream') {
const byteCharacters = atob(base64);
const byteArray = new Uint8Array(byteCharacters.length);

for (let i = 0; i < byteCharacters.length; i++) {
byteArray[i] = byteCharacters.charCodeAt(i);
}

return new Blob([byteArray], { type: mimeType });
}

getMimeType(filename) {
const ext = filename.split('.').pop().toLowerCase();
const types = {
'pdf': 'application/pdf',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'png': 'image/png',
'gif': 'image/gif',
'doc': 'application/msword',
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
};
return types[ext] || 'application/octet-stream';
}

showLoading(show) {
const spinner = document.getElementById('downloadSpinner');
if (spinner) {
spinner.style.display = show ? 'block' : 'none';
}
}

showError(message) {
alert(`Download Error: ${message}`);
}
}

// Usage
const downloader = new DocumentDownloader(110);

// In your button click handler
document.getElementById('downloadBtn').addEventListener('click', () => {
const documentId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
downloader.download(documentId);
});

Validation Rules

  • loanQuoteId: Must exist in database
  • documentId: Must be valid GUID format
  • Document Association: Document must be associated with the specified loan quote

Error Codes

Status CodeDescription
00Success - document retrieved with data
01Document not found
01Invalid GUID format
01Loan quote not found
99General error

Performance Considerations

  • File Size: Larger files take longer to retrieve and transfer
  • Base64 Overhead: ~33% larger than original file
  • Network: Consider compression for large documents
  • Caching: Cache document metadata, fetch data only when needed

Security Notes

  • Validate user has permission to access the loan quote
  • Validate user has permission to download documents
  • Log all document downloads for audit
  • Consider implementing download limits/throttling
  • Scan downloaded files for viruses (client-side)

Testing Checklist

  • Download PDF document
  • Download image document (JPEG, PNG)
  • Download Office document (DOC, XLS)
  • Test with invalid documentId
  • Test with invalid GUID format
  • Test with wrong loanQuoteId
  • Verify documentData field is included
  • Verify downloaded file opens correctly
  • Test with large file (greater than 5MB)
  • Test error handling for missing document

Browser Compatibility

The download implementation uses:

  • Blob API (IE 10 and above, all modern browsers)
  • URL.createObjectURL() (IE 10 and above, all modern browsers)
  • atob() for base64 decoding (IE 10 and above, all modern browsers)

For older browsers, consider using a polyfill like js-base64.