diff --git a/app/presenters/bill-runs/two-part-tariff/charge-reference-details.presenter.js b/app/presenters/bill-runs/two-part-tariff/charge-reference-details.presenter.js index 2a02eb0bf9..dadf1643dc 100644 --- a/app/presenters/bill-runs/two-part-tariff/charge-reference-details.presenter.js +++ b/app/presenters/bill-runs/two-part-tariff/charge-reference-details.presenter.js @@ -5,6 +5,8 @@ * @module ChargeReferenceDetailsPresenter */ +const Big = require('big.js') + const { formatLongDate, formatFinancialYear } = require('../../base.presenter.js') /** @@ -113,7 +115,7 @@ function _prepareDate (startDate, endDate) { function _totalBillableReturns (reviewChargeElements) { return reviewChargeElements.reduce((total, reviewChargeElement) => { - total += reviewChargeElement.amendedAllocated + total = Big(total).plus(reviewChargeElement.amendedAllocated).toNumber() return total }, 0) diff --git a/app/presenters/bill-runs/two-part-tariff/review-licence.presenter.js b/app/presenters/bill-runs/two-part-tariff/review-licence.presenter.js index e8b36d0379..d403d9bc61 100644 --- a/app/presenters/bill-runs/two-part-tariff/review-licence.presenter.js +++ b/app/presenters/bill-runs/two-part-tariff/review-licence.presenter.js @@ -5,6 +5,8 @@ * @module ReviewLicencePresenter */ +const Big = require('big.js') + const DetermineAbstractionPeriodService = require('../../../services/bill-runs/determine-abstraction-periods.service.js') const { formatLongDate } = require('../../base.presenter.js') @@ -277,7 +279,7 @@ function _totalBillableReturns (reviewChargeReference) { let totalBillableReturns = 0 reviewChargeReference.reviewChargeElements.forEach((reviewChargeElement) => { - totalBillableReturns += reviewChargeElement.amendedAllocated + totalBillableReturns = Big(totalBillableReturns).plus(reviewChargeElement.amendedAllocated).toNumber() }) return `${totalBillableReturns} ML / ${reviewChargeReference.amendedAuthorisedVolume} ML` diff --git a/app/services/bill-runs/two-part-tariff/allocate-returns-to-charge-element.service.js b/app/services/bill-runs/two-part-tariff/allocate-returns-to-charge-element.service.js index 127eb0c7b0..5cafabad38 100644 --- a/app/services/bill-runs/two-part-tariff/allocate-returns-to-charge-element.service.js +++ b/app/services/bill-runs/two-part-tariff/allocate-returns-to-charge-element.service.js @@ -5,6 +5,8 @@ * @module AllocateReturnsToChargeElementService */ +const Big = require('big.js') + const { periodsOverlap } = require('../../../lib/general.lib.js') /** @@ -34,8 +36,12 @@ function go (chargeElement, matchingReturns, chargePeriod, chargeReference) { function _allocateReturns (chargeElement, matchedReturn, chargePeriod, chargeReference, i, matchedLines) { matchedLines.forEach((matchedLine) => { - const chargeElementRemainingAllocation = chargeElement.authorisedAnnualQuantity - chargeElement.allocatedQuantity - const chargeReferenceRemainingAllocation = chargeReference.volume - chargeReference.allocatedQuantity + const chargeElementRemainingAllocation = Big(chargeElement.authorisedAnnualQuantity) + .minus(chargeElement.allocatedQuantity) + .toNumber() + const chargeReferenceRemainingAllocation = Big(chargeReference.volume) + .minus(chargeReference.allocatedQuantity) + .toNumber() const remainingAllocation = Math.min(chargeElementRemainingAllocation, chargeReferenceRemainingAllocation) @@ -56,33 +62,41 @@ function _allocateReturns (chargeElement, matchedReturn, chargePeriod, chargeRef chargeElement.chargeDatesOverlap = _chargeDatesOverlap(matchedLine, chargePeriod) } - chargeElement.allocatedQuantity += qtyToAllocate - chargeElement.returnLogs[i].allocatedQuantity += qtyToAllocate - matchedLine.unallocated -= qtyToAllocate - matchedReturn.allocatedQuantity += qtyToAllocate - chargeReference.allocatedQuantity += qtyToAllocate + chargeElement.allocatedQuantity = Big(chargeElement.allocatedQuantity).plus(qtyToAllocate).toNumber() + chargeElement.returnLogs[i].allocatedQuantity = Big(chargeElement.returnLogs[i].allocatedQuantity) + .plus(qtyToAllocate) + .toNumber() + matchedLine.unallocated = Big(matchedLine.unallocated).minus(qtyToAllocate).toNumber() + matchedReturn.allocatedQuantity = Big(matchedReturn.allocatedQuantity).plus(qtyToAllocate).toNumber() + chargeReference.allocatedQuantity = Big(chargeReference.allocatedQuantity).plus(qtyToAllocate).toNumber() } }) } function _allocateDueReturns (chargeElement, matchedReturn, chargeReference, i) { - const chargeElementRemainingAllocation = chargeElement.authorisedAnnualQuantity - chargeElement.allocatedQuantity + const chargeElementRemainingAllocation = Big(chargeElement.authorisedAnnualQuantity) + .minus(chargeElement.allocatedQuantity) + .toNumber() if (chargeElementRemainingAllocation > 0) { let qtyToAllocate = chargeElementRemainingAllocation // If the unallocated volume on the element is greater than that remaining on the reference the `qtyToAllocate` will // be set to whatever volume remains unallocated on the reference - const chargeReferenceRemainingAllocation = chargeReference.volume - chargeReference.allocatedQuantity + const chargeReferenceRemainingAllocation = Big(chargeReference.volume) + .minus(chargeReference.allocatedQuantity) + .toNumber() if (chargeElementRemainingAllocation > chargeReferenceRemainingAllocation) { qtyToAllocate = chargeReferenceRemainingAllocation } - chargeElement.allocatedQuantity += qtyToAllocate - chargeElement.returnLogs[i].allocatedQuantity += qtyToAllocate - matchedReturn.allocatedQuantity += qtyToAllocate - chargeReference.allocatedQuantity += qtyToAllocate + chargeElement.allocatedQuantity = Big(chargeElement.allocatedQuantity).plus(qtyToAllocate).toNumber() + chargeElement.returnLogs[i].allocatedQuantity = Big(chargeElement.returnLogs[i].allocatedQuantity) + .plus(qtyToAllocate) + .toNumber() + matchedReturn.allocatedQuantity = Big(matchedReturn.allocatedQuantity).plus(qtyToAllocate).toNumber() + chargeReference.allocatedQuantity = Big(chargeReference.allocatedQuantity).plus(qtyToAllocate).toNumber() } } diff --git a/app/services/bill-runs/two-part-tariff/prepare-return-logs.service.js b/app/services/bill-runs/two-part-tariff/prepare-return-logs.service.js index 902a276ae3..37c93c433c 100644 --- a/app/services/bill-runs/two-part-tariff/prepare-return-logs.service.js +++ b/app/services/bill-runs/two-part-tariff/prepare-return-logs.service.js @@ -5,6 +5,8 @@ * @module PrepareReturnLogsService */ +const Big = require('big.js') + const DetermineAbstractionPeriodService = require('../determine-abstraction-periods.service.js') const FetchReturnLogsForLicenceService = require('./fetch-return-logs-for-licence.service.js') const { periodsOverlap } = require('../../../lib/general.lib.js') @@ -53,8 +55,8 @@ function _prepReturnsForMatching (returnLogs, billingPeriod) { if (!abstractionOutsidePeriod) { abstractionOutsidePeriod = _abstractionOutsidePeriod(abstractionPeriods, returnSubmissionLine) } - returnSubmissionLine.unallocated = returnSubmissionLine.quantity / 1000 - quantity += returnSubmissionLine.unallocated + returnSubmissionLine.unallocated = Big(returnSubmissionLine.quantity).div(1000).toNumber() + quantity = Big(quantity).plus(returnSubmissionLine.unallocated).toNumber() }) returnLog.nilReturn = returnSubmissions[0]?.nilReturn ?? false diff --git a/package-lock.json b/package-lock.json index 7dc4e18dfc..4bd169e581 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@joi/date": "^2.1.0", "@smithy/node-http-handler": "^2.0.4", "bcryptjs": "^2.4.3", + "big.js": "^6.2.1", "blipp": "^4.0.2", "dotenv": "^16.3.1", "got": "^12.5.3", @@ -4486,6 +4487,18 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, + "node_modules/big.js": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz", + "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -13720,6 +13733,11 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, + "big.js": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz", + "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", diff --git a/package.json b/package.json index 1404b9ba53..465e3ecc47 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@joi/date": "^2.1.0", "@smithy/node-http-handler": "^2.0.4", "bcryptjs": "^2.4.3", + "big.js": "^6.2.1", "blipp": "^4.0.2", "dotenv": "^16.3.1", "got": "^12.5.3", diff --git a/test/services/bill-runs/two-part-tariff/review-licence.service.test.js b/test/services/bill-runs/two-part-tariff/review-licence.service.test.js index a2c8627c4d..59d5818bf9 100644 --- a/test/services/bill-runs/two-part-tariff/review-licence.service.test.js +++ b/test/services/bill-runs/two-part-tariff/review-licence.service.test.js @@ -97,6 +97,7 @@ function _fetchReviewLicenceResults () { reviewChargeReferenceId: '7759e0f9-5763-4b94-8d45-0621aea3edc1', chargeElementId: 'b1cd4f98-ad96-4901-9e21-4432f032492a', allocated: 0, + amendedAllocated: 0, chargeDatesOverlap: false, issues: '', status: 'ready' @@ -152,6 +153,7 @@ function _fetchReviewLicenceResults () { reviewChargeReferenceId: '2210bb45-1efc-4e69-85cb-c8cc6e75c4fd', chargeElementId: 'b1001716-cfb4-43c6-91f0-1863f4529223', allocated: 0, + amendedAllocated: 0, chargeDatesOverlap: false, issues: '', status: 'ready',