From 7e89b6ce9f25be92222fb7e95920aaa034a87897 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Tue, 9 May 2017 10:13:15 -0400 Subject: [PATCH 1/6] Sort utility accounts by id --- src/components/Utilities/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/Utilities/index.js b/src/components/Utilities/index.js index 0dc7d2fd..2c14f1b2 100644 --- a/src/components/Utilities/index.js +++ b/src/components/Utilities/index.js @@ -61,6 +61,10 @@ class Utilities extends Component { }, []); // Fetch the documents for all of the accounts for this building this.props.getDocuments([], allDocumentKeys, 'utilityBills'); + // Sort by ID in the database + data.utilities.sort((a, b) => ( + a.id - b.id + )); const allAccounts = data.utilities.map((account) => { const documentKeys = { scrape: account.bill_document_key, -- GitLab From 26a95b74479834ba9d730bb4fe2a208cb2d03a7e Mon Sep 17 00:00:00 2001 From: Conrad S Date: Tue, 9 May 2017 14:05:58 -0400 Subject: [PATCH 2/6] Remove all references to documents/box in utility components and download bill data from list --- src/components/Utilities/index.js | 72 ++--------- src/components/UtilityAccount/index.js | 170 +++++++++++++++---------- 2 files changed, 109 insertions(+), 133 deletions(-) diff --git a/src/components/Utilities/index.js b/src/components/Utilities/index.js index 2c14f1b2..5a266815 100644 --- a/src/components/Utilities/index.js +++ b/src/components/Utilities/index.js @@ -1,9 +1,8 @@ -import React, { Component, PropTypes, cloneElement } from 'react'; +import React, { Component, PropTypes } from 'react'; import buildingDetailPropTypes from '../../containers/Building/propTypes'; import request from '../../utils/request'; import { getHeaders, scrapeURL, accountURL } from '../../utils/restServices'; -import documentsPropType from '../../containers/Documents/propTypes'; import UtilityAccount from '../UtilityAccount'; @@ -23,29 +22,6 @@ class Utilities extends Component { this.getUtilityAccounts(address); } - componentWillReceiveProps(nextProps) { - // Pass down the document URLs to the children once doc service is done - const nextDocuments = nextProps.documents.files.utilityBills; - const curDocuments = this.props.documents.files.utilityBills; - if (nextDocuments !== curDocuments) { - const newAccounts = this.state.accountLines.map((account) => { - /* eslint-disable no-param-reassign */ - const documentURLs = nextDocuments.reduce((acc, val) => { - if (val.key === account.props.documentKeys.scrape) { - acc.scrape = val.url_download; - } else if (val.key === account.props.documentKeys.disaggregate) { - acc.disaggregate = val.url_download; - } - return acc; - }, {}); - return cloneElement(account, { - documentURLs, - }); - }); - this.setState({ accountLines: newAccounts }); - } - } - getUtilityAccounts = (address) => { // First reqeust gets the utility account information request(`${accountURL}${this.props.buildingId}`, { @@ -54,23 +30,12 @@ class Utilities extends Component { }).then((res) => { const data = res.data; if (!res.err && data.utilities) { - const allDocumentKeys = data.utilities.reduce((acc, val) => { - acc.push(val.bill_document_key); - acc.push(val.disaggregate_document_key); - return acc; - }, []); - // Fetch the documents for all of the accounts for this building - this.props.getDocuments([], allDocumentKeys, 'utilityBills'); // Sort by ID in the database data.utilities.sort((a, b) => ( a.id - b.id )); - const allAccounts = data.utilities.map((account) => { - const documentKeys = { - scrape: account.bill_document_key, - disaggregate: account.disaggregate_document_key, - }; - return this.createUtilityComponent( + const allAccounts = data.utilities.map(account => ( + this.createUtilityComponent( { building_address: address, utility: account.type, @@ -80,11 +45,10 @@ class Utilities extends Component { access_code: account.access_code, }, account.id, - documentKeys, account.bill_database_output, this.parseDisaggregateData(account.disaggregated_database_output), - ); - }); + ) + )); const blankAccount = this.createUtilityComponent(); this.setState({ accountLines: this.state.accountLines.concat(allAccounts, blankAccount), @@ -102,7 +66,6 @@ class Utilities extends Component { updateLoadingFetchState, setBillData, setDisaggregateData, - setDocumentURLs ) => { request(scrapeURL, { method: 'POST', @@ -118,11 +81,6 @@ class Utilities extends Component { this.setState({ error: `Failed to retrieve utility bill. | ${res.err.message}` }); } else { const data = res.data; - const documentURLs = { - disaggregate: data.disaggregate_download_url, - scrape: data.bill_download_url, - }; - setDocumentURLs(documentURLs); setBillData(data.bill_database_output); const disaggregateData = this.parseDisaggregateData(data.disaggregate_database_output); setDisaggregateData(disaggregateData); @@ -140,7 +98,6 @@ class Utilities extends Component { updateLoadingUploadState, setBillData, setDisaggregateData, - setDocumentURLs, dataType, ) => { request(`${scrapeURL}${accountId}`, { @@ -159,14 +116,6 @@ class Utilities extends Component { this.setState({ error: `Failed to update utility bill. | ${res.err.message}` }); } else { const data = res.data; - const documentURLs = { - disaggregate: data.disaggregate_download_url, - }; - // If we upload a new disaggregated bill there will be no bill document key - if (data.bill_download_url) { - documentURLs.scrape = data.bill_download_url; - } - setDocumentURLs(documentURLs); // If we upload disaggregated bill there will be no bill data if (data.bill_database_output) { setBillData(data.bill_database_output); @@ -181,9 +130,9 @@ class Utilities extends Component { parseDisaggregateData = (data) => { const disaggregateData = data.map(val => ({ - billFromDate: val.bill_from_date, - billToDate: val.bill_to_date, - daysInBill: val.days_in_bill, + bill_from_date: val.bill_from_date, + bill_to_date: val.bill_to_date, + days_in_bill: val.days_in_bill, usage: val.usage, heating: val.heating_usage, cooling: val.cooling_usage, @@ -258,7 +207,6 @@ class Utilities extends Component { createUtilityComponent = ( incForm, accountId = null, - documentKeys = {}, billData = [], disaggregateData = [], ) => { @@ -270,8 +218,6 @@ class Utilities extends Component { account_id: accountId, billData, disaggregateData, - documentKeys, - documentURLs: {}, disabled: true, }; } @@ -314,8 +260,6 @@ class Utilities extends Component { Utilities.propTypes = { buildingId: PropTypes.string, building: buildingDetailPropTypes, - getDocuments: PropTypes.func, - documents: documentsPropType, }; export default Utilities; diff --git a/src/components/UtilityAccount/index.js b/src/components/UtilityAccount/index.js index 7b456526..09bb5f81 100644 --- a/src/components/UtilityAccount/index.js +++ b/src/components/UtilityAccount/index.js @@ -19,14 +19,6 @@ class UtilityAccount extends Component { account_id: this.props.account_id, billData: this.props.billData, disaggregateData: this.props.disaggregateData, - documentKeys: { - scrape: this.props.documentKeys.scrape, - disaggregate: this.props.documentKeys.disaggregate, - }, - documentURLs: { - scrape: this.props.documentURLs.scrape, - disaggregate: this.props.documentURLs.disaggregate, - }, disabled: this.props.disabled, convertingFile: false, displayBillData: false, @@ -37,24 +29,6 @@ class UtilityAccount extends Component { }; } - componentWillReceiveProps(nextProps) { - // Update the document URLs - this.setState({ documentURLs: nextProps.documentURLs }); - } - - setDocumentURLs = urls => ( - this.setState({ - documentURLs: { - ...this.state.documentURLs, - ...urls, - }, - }) - ) - - setDisaggregateData = data => ( - this.setState({ disaggregateData: data }) - ) - setBillData = data => ( this.setState({ billData: data }) ) @@ -91,6 +65,71 @@ class UtilityAccount extends Component { }); } + // Generate the href to download a bill + // Works for disaggregate bill data and normal bill data + generateBillDownload = (data) => { + if (data.length > 0) { + let csvString = '' + + 'Bill From Date,' + + 'Bill To Date,' + + 'Days In Bill,' + + 'Usage,' + + ''; + if ('delivery_charge' in data[0]) { + // Normal Bill + csvString += '' + + 'Supply Charge,' + + 'Delivery Charge,' + + 'Total Charge,' + + ''; + } else { + // Disaggregated Bill + csvString += '' + + 'Heating Usage,' + + 'Cooling Usage,' + + 'Other Usage,' + + ''; + } + + csvString += '\n'; + csvString += data.reduce((acc, val) => { + const d1 = new Date(val.bill_from_date); + const d2 = new Date(val.bill_to_date); + const timeDiff = Math.abs(d2.getTime() - d1.getTime()); + const daysInBill = Math.ceil(timeDiff / (1000 * 3600 * 24)); + let line = ''; + line += `${val.bill_from_date},`; + line += `${val.bill_to_date},`; + line += `${daysInBill},`; + if ('delivery_charge' in val) { + // Normal bill + line += `${val.usage},`; + line += `${val.delivery_charge},`; + line += `${val.supply_charge},`; + line += `${val.total_charge_bill},`; + } else { + const totalUsage = ( + val.heating + val.cooling + val.other + ); + // Disaggregated Bill + line += `${totalUsage},`; + line += `${val.heating},`; + line += `${val.cooling},`; + line += `${val.other},`; + } + // Remove whitespace created by the template formatting + line = line.replace(' ', ''); + return `${acc}${line}\n`; + }, ''); + const mimeType = 'text/csv;encoding:utf-8'; + const href = URL.createObjectURL(new Blob([csvString], { + type: mimeType, + })); + return href; + } + return null; + } + handleFetchingUtilityBill = (event) => { event.preventDefault(); this.updateLoadingFetchState(true); @@ -100,7 +139,6 @@ class UtilityAccount extends Component { this.updateLoadingFetchState, this.setBillData, this.setDisaggregateData, - this.setDocumentURLs ); } @@ -163,7 +201,6 @@ class UtilityAccount extends Component { this.updateLoadingUploadState, this.setBillData, this.setDisaggregateData, - this.setDocumentURLs, dataType, ); }.bind(this); @@ -258,46 +295,38 @@ class UtilityAccount extends Component { ) renderBillButtons = () => { - const scrapeKey = this.state.documentKeys.scrape; - const disaggregateKey = this.state.documentKeys.disaggregate; - const scrapeUrl = this.state.documentURLs.scrape; - const disaggregateUrl = this.state.documentURLs.disaggregate; - - let scrapeVisibility = 'hidden'; - if (scrapeUrl !== undefined && scrapeUrl !== '') { - scrapeVisibility = 'visible'; + const { billData, disaggregateData } = this.state; + + let billVisibility = 'hidden'; + if (billData.length > 0) { + billVisibility = 'visible'; } let disaggregateVisibility = 'hidden'; - if (disaggregateUrl !== undefined && disaggregateUrl !== '') { + if (disaggregateData.length > 0) { disaggregateVisibility = 'visible'; } - let scrapeText = 'Download Scraped Bill'; + let billText = 'Download Raw Bill'; let disaggregateText = 'Download Disaggregated Bill'; - if (scrapeVisibility === 'hidden') { - if (scrapeKey) { - scrapeText = 'Loading scraped bill..'; - } else if (this.state.form.utility.startsWith('other')) { - scrapeText = 'No raw bill. Upload a bill'; + if (billVisibility === 'hidden') { + if (this.state.form.utility.startsWith('other')) { + billText = 'No raw bill. Upload a bill'; } else { - scrapeText = 'No scraped bill. Try fetching'; + billText = 'No raw bill. Try fetching or uploading'; } } if (disaggregateVisibility === 'hidden') { - if (disaggregateKey) { - disaggregateText = 'Loading disaggregated bill..'; - } else { - disaggregateText = 'No disaggregated bill.'; - } + disaggregateText = 'No disaggregated bill.'; } return (
- {scrapeText} + {billText}
{this.renderUploadButton('Bill')} @@ -305,8 +334,9 @@ class UtilityAccount extends Component {
{disaggregateText} @@ -395,6 +425,7 @@ class UtilityAccount extends Component { Bill From Date Bill To Date + Days In Bill Heating Usage Cooling Usage Other Usage @@ -420,11 +451,16 @@ class UtilityAccount extends Component { const totalUsage = ( val.heating + val.cooling + val.other ); - const trKey = `disaggregate${val.billFromDate}${val.billToDate}${this.state.account_id}`; + const d1 = new Date(val.bill_from_date); + const d2 = new Date(val.bill_to_date); + const timeDiff = Math.abs(d2.getTime() - d1.getTime()); + const daysInBill = Math.ceil(timeDiff / (1000 * 3600 * 24)); + const trKey = `disaggregate${val.bill_from_date}${val.bill_to_date}${this.state.account_id}`; return ( - {val.billFromDate} - {val.billToDate} + {val.bill_from_date} + {val.bill_to_date} + {daysInBill} {val.heating.toFixed(2)} {val.cooling.toFixed(2)} {val.other.toFixed(2)} @@ -448,6 +484,7 @@ class UtilityAccount extends Component { Bill From Date Bill To Date + Days In Bill Usage Delivery Charge Supply Charge @@ -474,11 +511,16 @@ class UtilityAccount extends Component { const diff = ( val.delivery_charge + val.supply_charge ) - val.total_charge_bill; + const d1 = new Date(val.bill_from_date); + const d2 = new Date(val.bill_to_date); + const timeDiff = Math.abs(d2.getTime() - d1.getTime()); + const daysInBill = Math.ceil(timeDiff / (1000 * 3600 * 24)); const trKey = `bill${val.bill_from_date}${val.bill_to_date}${this.state.account_id}`; return ( {val.bill_from_date} {val.bill_to_date} + {daysInBill} {val.usage} {val.delivery_charge} {val.supply_charge} @@ -494,7 +536,7 @@ class UtilityAccount extends Component { renderDisaggregateChart = () => { if (this.state.disaggregateData && this.state.displayDisaggregateChart) { const data = this.state.disaggregateData.map(val => ({ - name: val.billFromDate, + name: val.bill_from_date, heating: val.heating, cooling: val.cooling, other: val.other, @@ -668,21 +710,13 @@ UtilityAccount.propTypes = { ), disaggregateData: PropTypes.arrayOf( PropTypes.shape({ - billFromDate: PropTypes.string, - billToDate: PropTypes.string, + bill_from_date: PropTypes.string, + bill_to_date: PropTypes.string, heating: PropTypes.number, cooling: PropTypes.number, other: PropTypes.number, }) ), - documentKeys: PropTypes.shape({ - scrape: PropTypes.string, - disaggregate: PropTypes.string, - }), - documentURLs: PropTypes.shape({ - scrape: PropTypes.string, - disaggregate: PropTypes.string, - }), disabled: PropTypes.bool, createAccount: PropTypes.func, deleteAccount: PropTypes.func, @@ -702,8 +736,6 @@ UtilityAccount.defaultProps = { account_id: null, disaggregateData: [], billData: [], - documentKeys: {}, - documentURLs: {}, disabled: false, }; -- GitLab From ad45ee79821b8e77b56536b41c55df20e9a56db3 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Tue, 9 May 2017 14:21:37 -0400 Subject: [PATCH 3/6] Add back setDisaggregateData function --- src/components/UtilityAccount/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/UtilityAccount/index.js b/src/components/UtilityAccount/index.js index 09bb5f81..ce31607a 100644 --- a/src/components/UtilityAccount/index.js +++ b/src/components/UtilityAccount/index.js @@ -29,6 +29,10 @@ class UtilityAccount extends Component { }; } + setDisaggregateData = data => ( + this.setState({ disaggregateData: data }) + ) + setBillData = data => ( this.setState({ billData: data }) ) -- GitLab From ffb9829bf96fc4a030a490dd1d51bf39283ddd88 Mon Sep 17 00:00:00 2001 From: Conrad Date: Thu, 11 May 2017 14:32:08 -0400 Subject: [PATCH 4/6] Change name of variables in utilities --- src/components/Utilities/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Utilities/index.js b/src/components/Utilities/index.js index 5a266815..5fd1dc15 100644 --- a/src/components/Utilities/index.js +++ b/src/components/Utilities/index.js @@ -31,8 +31,8 @@ class Utilities extends Component { const data = res.data; if (!res.err && data.utilities) { // Sort by ID in the database - data.utilities.sort((a, b) => ( - a.id - b.id + data.utilities.sort((item1, item2) => ( + item1.id - item2.id )); const allAccounts = data.utilities.map(account => ( this.createUtilityComponent( -- GitLab From b3b0fab79597f6b907315eaf7dcc5eb8c6438ed5 Mon Sep 17 00:00:00 2001 From: Conrad Date: Thu, 11 May 2017 14:36:31 -0400 Subject: [PATCH 5/6] Merge all date comparisons into one function --- src/components/UtilityAccount/index.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/components/UtilityAccount/index.js b/src/components/UtilityAccount/index.js index ce31607a..763a008a 100644 --- a/src/components/UtilityAccount/index.js +++ b/src/components/UtilityAccount/index.js @@ -97,10 +97,7 @@ class UtilityAccount extends Component { csvString += '\n'; csvString += data.reduce((acc, val) => { - const d1 = new Date(val.bill_from_date); - const d2 = new Date(val.bill_to_date); - const timeDiff = Math.abs(d2.getTime() - d1.getTime()); - const daysInBill = Math.ceil(timeDiff / (1000 * 3600 * 24)); + const daysInBill = getDateDiff(val.bill_from_date, val.bill_to_date); let line = ''; line += `${val.bill_from_date},`; line += `${val.bill_to_date},`; @@ -178,6 +175,14 @@ class UtilityAccount extends Component { }); } + getDateDiff = (date1String, date2String) => { + const d1 = new Date(date1String); + const d2 = new Date(date2String); + const timeDiff = Math.abs(d2.getTime() - d1.getTime()); + const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)); + return daysDiff; + } + isAccountNumberLong = () => this.state.form.account_number.length > 15; showAccountWarning = () => (this.isAccountNumberLong() ? @@ -455,10 +460,7 @@ class UtilityAccount extends Component { const totalUsage = ( val.heating + val.cooling + val.other ); - const d1 = new Date(val.bill_from_date); - const d2 = new Date(val.bill_to_date); - const timeDiff = Math.abs(d2.getTime() - d1.getTime()); - const daysInBill = Math.ceil(timeDiff / (1000 * 3600 * 24)); + const daysInBill = getDateDiff(val.bill_from_date, val.bill_to_date); const trKey = `disaggregate${val.bill_from_date}${val.bill_to_date}${this.state.account_id}`; return ( @@ -515,10 +517,7 @@ class UtilityAccount extends Component { const diff = ( val.delivery_charge + val.supply_charge ) - val.total_charge_bill; - const d1 = new Date(val.bill_from_date); - const d2 = new Date(val.bill_to_date); - const timeDiff = Math.abs(d2.getTime() - d1.getTime()); - const daysInBill = Math.ceil(timeDiff / (1000 * 3600 * 24)); + const daysInBill = getDateDiff(val.bill_from_date, val.bill_to_date); const trKey = `bill${val.bill_from_date}${val.bill_to_date}${this.state.account_id}`; return ( -- GitLab From 59a645bafc8f121749f154d7e2245ccecdef5610 Mon Sep 17 00:00:00 2001 From: Conrad Date: Thu, 11 May 2017 14:42:14 -0400 Subject: [PATCH 6/6] Add prefix this to functions calls --- src/components/UtilityAccount/index.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/UtilityAccount/index.js b/src/components/UtilityAccount/index.js index 763a008a..7eff0fc9 100644 --- a/src/components/UtilityAccount/index.js +++ b/src/components/UtilityAccount/index.js @@ -37,6 +37,15 @@ class UtilityAccount extends Component { this.setState({ billData: data }) ) + getDateDiff = (date1String, date2String) => { + const d1 = new Date(date1String); + const d2 = new Date(date2String); + const timeDiff = Math.abs(d2.getTime() - d1.getTime()); + const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)); + return daysDiff; + } + + updateLoadingFetchState = isLoading => ( this.setState({ loadingFetch: isLoading }) ) @@ -97,7 +106,7 @@ class UtilityAccount extends Component { csvString += '\n'; csvString += data.reduce((acc, val) => { - const daysInBill = getDateDiff(val.bill_from_date, val.bill_to_date); + const daysInBill = this.getDateDiff(val.bill_from_date, val.bill_to_date); let line = ''; line += `${val.bill_from_date},`; line += `${val.bill_to_date},`; @@ -175,14 +184,6 @@ class UtilityAccount extends Component { }); } - getDateDiff = (date1String, date2String) => { - const d1 = new Date(date1String); - const d2 = new Date(date2String); - const timeDiff = Math.abs(d2.getTime() - d1.getTime()); - const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)); - return daysDiff; - } - isAccountNumberLong = () => this.state.form.account_number.length > 15; showAccountWarning = () => (this.isAccountNumberLong() ? @@ -460,7 +461,7 @@ class UtilityAccount extends Component { const totalUsage = ( val.heating + val.cooling + val.other ); - const daysInBill = getDateDiff(val.bill_from_date, val.bill_to_date); + const daysInBill = this.getDateDiff(val.bill_from_date, val.bill_to_date); const trKey = `disaggregate${val.bill_from_date}${val.bill_to_date}${this.state.account_id}`; return ( @@ -517,7 +518,7 @@ class UtilityAccount extends Component { const diff = ( val.delivery_charge + val.supply_charge ) - val.total_charge_bill; - const daysInBill = getDateDiff(val.bill_from_date, val.bill_to_date); + const daysInBill = this.getDateDiff(val.bill_from_date, val.bill_to_date); const trKey = `bill${val.bill_from_date}${val.bill_to_date}${this.state.account_id}`; return ( -- GitLab