From 8e278e75c585c742876f0437f4887ede7b947648 Mon Sep 17 00:00:00 2001 From: Hardik Prajapati Date: Fri, 8 May 2026 02:13:24 +0530 Subject: [PATCH 1/2] UA-164: add option to download invoice in billing page Co-authored-by: Copilot --- app/scripts/controllers/Billing.js | 64 ++++++++++++++++++++++++++++++ app/views/pages/billing.html | 17 +++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/app/scripts/controllers/Billing.js b/app/scripts/controllers/Billing.js index 12f71fe..4871f75 100644 --- a/app/scripts/controllers/Billing.js +++ b/app/scripts/controllers/Billing.js @@ -549,6 +549,70 @@ angular.module('Lineblocs') var token = getJWTTokenObj(); $window.location.replace(createUrl("/downloadBillingHistory?startDate=" + formatDate($scope.startDate) + "&endDate=" + formatDate($scope.endDate) + "&auth=" + token.token.auth)); } + + $scope.getInvoiceId = function(item) { + if (!item) { + return null; + } + return item.invoice_id || item.invoiceId || item.id || null; + } + + $scope.canDownloadInvoice = function(item) { + var invoiceId = $scope.getInvoiceId(item); + var sourceType = ((item && item.type) || "").toString().toLowerCase(); + return !!invoiceId && sourceType.indexOf("invoice") !== -1; + } + + $scope.downloadInvoice = function(item) { + var invoiceId = $scope.getInvoiceId(item); + if (!invoiceId) { + $mdToast.show( + $mdToast.simple() + .textContent('Invoice ID not found for this row') + .position("top right") + .hideDelay(3000) + ); + return; + } + + $shared.isCreateLoading = true; + Backend.get("/billing/invoices/" + invoiceId + "/download", { responseType: 'blob' }).then(function(res) { + var contentType = 'application/pdf'; + var contentDisposition = null; + if (res.headers) { + contentType = res.headers('content-type') || contentType; + contentDisposition = res.headers('content-disposition'); + } + + var filename = 'invoice-' + invoiceId + '.pdf'; + if (contentDisposition) { + var matches = /filename\*?=(?:UTF-8''|\")?([^\";]+)/i.exec(contentDisposition); + if (matches && matches[1]) { + filename = decodeURIComponent(matches[1].replace(/\"/g, '')); + } + } + + var blob = new Blob([res.data], { type: contentType }); + var url = window.URL.createObjectURL(blob); + var link = document.createElement('a'); + link.href = url; + link.download = filename; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + $shared.endIsCreateLoading(); + }, function(err) { + console.error('Error downloading invoice', err); + $shared.endIsCreateLoading(); + $mdToast.show( + $mdToast.simple() + .textContent('Failed to download invoice') + .position("top right") + .hideDelay(3000) + ); + }); + } $scope.makeNicePackageName = function(ugly) { var map = { "gold": "Gold Route", diff --git a/app/views/pages/billing.html b/app/views/pages/billing.html index e668ebb..1f0e6ee 100644 --- a/app/views/pages/billing.html +++ b/app/views/pages/billing.html @@ -422,7 +422,8 @@
History
Amount Balance Date/Time -   + Status + Action @@ -433,6 +434,20 @@
History
{{item.balance}} {{item.created_at}} {{item.status}} + + + + + + + Download + + + From 36af56dcfe390e7039047d19b14b8fb28b89f57b Mon Sep 17 00:00:00 2001 From: Hardik Prajapati Date: Fri, 8 May 2026 23:52:34 +0530 Subject: [PATCH 2/2] UA-164: Removed custom class for invoice id and used id --- app/scripts/controllers/Billing.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/app/scripts/controllers/Billing.js b/app/scripts/controllers/Billing.js index 4871f75..2fd0a7c 100644 --- a/app/scripts/controllers/Billing.js +++ b/app/scripts/controllers/Billing.js @@ -550,21 +550,14 @@ angular.module('Lineblocs') $window.location.replace(createUrl("/downloadBillingHistory?startDate=" + formatDate($scope.startDate) + "&endDate=" + formatDate($scope.endDate) + "&auth=" + token.token.auth)); } - $scope.getInvoiceId = function(item) { - if (!item) { - return null; - } - return item.invoice_id || item.invoiceId || item.id || null; - } - $scope.canDownloadInvoice = function(item) { - var invoiceId = $scope.getInvoiceId(item); + var invoiceId = item.id; var sourceType = ((item && item.type) || "").toString().toLowerCase(); return !!invoiceId && sourceType.indexOf("invoice") !== -1; } $scope.downloadInvoice = function(item) { - var invoiceId = $scope.getInvoiceId(item); + var invoiceId = item.id; if (!invoiceId) { $mdToast.show( $mdToast.simple()