Documente Academic
Documente Profesional
Documente Cultură
TABLE OF CONTENTS
PROJECT DESCRIPTION 2
PROJECT OBJECTIVES 5
CONTRIBUTOR OBJECTIVES 5
CLIENT/END USER 5
DESIGN REQUIREMENTS 6
Functional decomposition of the project 6
Fields: 7
Buttons: 8
Selection of design criterion 8
Final Deliverables 10
Approach/Methodology 10
Legal Considerations 11
Ethical Considerations 13
TIMELINE / BUDGET 14
Original Timeline: 14
USABILITY TESTING/EVAL 18
Test cases: 18
CONCLUSION 22
Sources: 24
PROJECT DESCRIPTION
The residential solar industry is a relatively new one. The first residential home system
was installed in 2000. It was not until 2006 when the California Public Utilities Commission
passed the California Solar Initiative, which provided incentives over the next 10 years that
residential solar truly became affordable. Ever since the price of installing a residential solar
system has continued to drop with advanced in technology and subsidies from governments
abroad in Europe and China. Business models for acquisition of equipment, funding and
financing, and project management have continued to evolve. This has led to sales and project
models that do not follow traditional retail or construction processes and in turn created a hole in
business systems needed to help facilitate the unusual process involved in installing a residential
solar system.
In recent years the most common financing method for purchase of a residential
installation is called third party operation (TPO). Companies like SolarCity and Sunrun are the
most prominent examples of companies that have offered TPO solutions. Before its acquisition
by Tesla, SolarCity performed its own installations, that acquisition has allowed Sunrun to
become the country’s leading TPO provider, which works with independent installer “partners”.
This group of independent, small to medium business, installers is sometimes referred to as “the
long tail”.
The long tail of installers is the target market for the business that I work for. The result
is a very different business model where an installer works directly with a homeowner, but the
installation is eventually paid to the installer by the financing company, in phases as a project
completes milestones. In addition to the installer and the financier, a solar installation can also
include an originator, and an integrator. The originator can be a company that helps to originate a
project through marketing and can sometimes help to manage a project. An integrator is a third
party that acts as a middle man, managing the process and helping a customer to find a financier,
The difficulty for most solar installers using business systems such as quickbooks or
another ERP is that most ERP systems are designed to work through a standard business to
customer or business to business model where goods are purchased and then paid for in full
using cash or payment terms. Solar installations provide a challenge in the payments being made
by a third party and in phases rather than in one bulk payment. Each payment is made upon
completion of certain milestones in the projects completion such as signed contracts, installation
of the system, approval by the utility, etc. A way to manage when payments are to be made and
the paperwork needed for each milestone is needed industry wide. Installers often manage this
process through spreadsheets and meticulous manual management. This can often lead to errors
where payments are not made and invoices not collected due to lost or mishandled paperwork.
The goal of Blue Banyan Solutions is to create a business ERP solution through NetSuite, a
cloud based ERP owned by Oracle, for solar installers that helps to enable better management of
The scope of this project is one small piece to help business owners and/or accountants to
manage project cash flow through a custom page that performs a what-if cash flow analysis. An
upside to the system of having predetermined bills and invoices is the ability to predict when
those bills and invoices will be received or paid. This can be manually done in a spreadsheet
application like Microsoft Excel, but this is something that can be programmed and would save
many hours to have the process automated. The solution was done through a calculated set of
statistics, saved daily, on the length of time it takes on average for projects to move through each
milestone based on project type (through an integrator or not), the financing type (loan, cash,
TPO, etc.), and installation state. There are other statistics included like the number of projects in
each phase, average system size, revenue, costs, and margins. While they are not used in this
project, they are included so that additional statistics and dashboard reporting can utilize this
information at a later date. The end goal of this project, the what-if cash flow analysis allows a
user to see what happens to incoming and outgoing cash if the time between milestone
PROJECT OBJECTIVES
- A table where project statistics can be stored
- Reporting and Dashboard KPIs that takes current and open projects and uses the interval
averages from the most current project statistic record applicable, and calculates the
incoming and outgoing cash for the next 0-90 days in 30 day buckets.
- A script which collects the project statistics and saves them to the aforementioned table.
- What-if Cash flow analysis page.
- Form with fields for user input for each interval.
- Calculations to take user input and uses queries from the above reporting to
recalculate the incoming and outgoing cash.
- Visualizations for the results of the calculation to make the data more easily
interpreted.
CLIENT/END USER
The client and end user will be Blue Banyan Solutions and their clients respectively. The
client will guide the kind of user experience that the end user is meant to have. As there are not
any end users yet, but will be in the coming months, some last minute changes to design may
occur. Final testing will be performed by co-workers, but eventually will be by end users.
DESIGN REQUIREMENTS
Functional decomposition of the project
The end goal of this project is the custom page that performs the What-if analysis, this
will take input from the user and combine it with dates and amounts on unfinished projects to
estimate revenue and expenses being incurred in the immediate future (the next 90 days).
Additional custom records and scripts need to be created as part of this project, but many can
also be useful for other analyses or reports that the user can view to help to create additional
The first segment to this project is the custom record holding the project statistics and the
script to populate it on a nightly basis. This script populating the data, runs a query, or in
NetSuite called a Saved Search, which looks at all projects that have completed or are in various
stages of completion to see the average amount of time it takes to complete each of the project
milestones. Those numbers are then saved to the project statistics record to be used in later
queries and scripts to project into the future the amount of time it will take to complete a given
project and receive funds. This script should be scheduled to run on a nightly basis and save
additional records.
The second piece is to create queries to use the data from the project statistics record, and
using the most recently created project statistic record, use the averages to estimate for each
project how long it will take to reach each milestone and sum those amounts into buckets for the
Finally, the custom page is to be created. It should use the NetSuite API and use the
NetSuite layout. It should use form objects for field entry and should include the following:
Fields:
Major Criteria - the same groupings used in the KPI and project statistics queries and
are required here in order to ensure the calculated what-if uses the same data sets
➔ Project Type - A list of project types, use the native jobtype field
➔ Installation State - a list of installation states, use the custom record for states
Record Selection
➔ Project Statistic Record - a list of project statistic records that can be selected by
➔ Cash Flow What-if Record - a drop down menu of selected cash flow what-if
➔ name - a name for the record when it is saved, if a new one is being created.
Intervals - this is every interval between milestones from new through M3, and will start
at 4 looking at new to M0-M3, then M0-M3, etc. It should look like the following:
New M0 M1 M2
Ave. Days
New-M0
Chart Fields - There should be three of these, one for Revenue, expense, and net. These
are the result of the calculation of the analysis. It should compare the input in the interval
fields that have been added by the user, and compare it to the selected project statistic
record. This will use the google chart API to create the charts using a vertical bar chart.
These should also include a data table with the results of the data written out. This
will allow people to view the data in multiple ways for more easily digestible data.
Buttons:
➔ Load Project Statistic - loads data from the selected project statistic record into the Major
➔ Save and Calculate - saves or creates a new record, and performs the analysis.
onto which it is being created. As this is meant to work within a NetSuite implementation, using
NetSuite tools such as Saved Searches and Javascript API are a necessity.
Factors to keep in mind in creation of the script and designing the code logic:
➔ Load time. The calculations are large queries which take some time to be run. Some
thought needs to be given on how to minimize the data in the queries so that the load time
➔ User friendly form design. The idea of this is somewhat complicated and extra care needs
to be taken to ensure that the design of the page is obvious what steps come next and
➔ Error alerts. There should be alerts on all of the buttons for each of the following
scenarios:
◆ Clicking the “load project statistic” button but there is no project statistic selected.
◆ Clicking the “open saved analysis” button but there is no cash flow what-if record
selected.
◆ Clicking “save and calculate” and there is no selected cash flow what-if record,
and the selected project statistic record do not match. They cannot be compared if
◆ The following alerts are optional and should be reviewed to see if this would be
too many alerts in general and would cause the user to begin ignoring all pop up
alerts:
● Warning when opening an existing record that you will lose any data
● Warning when loading project statistic record if there is data input already
into the interval or major criteria fields that they will be overwritten.
Final Deliverables
➔ What-if analysis custom page (Suitelet), and all related scripts populating the what-if
Approach/Methodology
- All coding will be done using the netsuite API version 2, known as SuiteScript 2.0.
- Script types needed here are:
both the suitelet and client script (if required by both scripts) then this
- Creation of custom records is done using the interface within NetSuite for creation.
- Creation of the saved queries or saved searches can be done in two ways, using the
interface or using a script. These were created using the interface and saved so that they
can be run and debugged on demand, and then the id for the search is used in any
necessary scripts so they can be loaded and run in the context of the script.
Legal Considerations
There are three scenarios which should be considered for this project as having potential
legal ramifications, the use of the Google chart API and privacy of the data being passed into the
API, accuracy of the information with regards to business decisions being made by customers,
and intellectual property as it pertains to this project and sharing of any company information
An issue that has been given heavy news coverage in recent months has been the privacy
of data gathered by Facebook and with whom the data is being shared. The Cambridge Analytica
scandal has given many of us pause about how much information we post on social media, and to
give more credence to the agreement to share your personal data with outside vendors. Similarly,
using a Google API to create the revenue, expense, and net charts involves sending a title, and
data points to Google in return for the code for the chart. While this there is no name on the
chart, and this is a what-if scenario where the data may not have any basis in reality, it does give
some general idea of how much revenue a company is making and allows Google to see it.
Whether Google collects that data or uses it in any way is unknown, and the possibility should be
something to consider when presenting this to customers with the possibility of greater
Data accuracy is another potential pitfall that could bring legal trouble if not disclosed
heavily in the beginning with potential and current customers. This analysis takes the averages of
time between milestone completion dates for partially complete and finalized projects against
open projects to make a guess when to expect total incoming revenue for the next 0-90 days.
There are some pitfalls to this analysis though as outliers occur. A large project that takes
additional time to complete than similar projects would still be projected to be completed in the
same time frame as its predecessors and there is currently no way to earmark specific projects as
known outliers. Any use of these projects for business decisions should take into consideration
that this is a generalized analysis and the results are not a guarantee of future events. While it can
be used as one of many tools to help view business performance, it is not infallible.
This project also shares much of the code logic and methodology of NetSuite
development. The recordings that are made for this project including the capstone presentation
and final documentary, could potentially share information that belongs to Blue Banyan
Solutions legally, and/or NetSuite and will be publicly available on Youtube for anyone to view.
The API documentation is far from complete and much of this solution is devised by the
Ethical Considerations
While not entirely the same, many of the ethical concerns are the same as the legal ones,
possible sharing of data via use of the Google Charts API, data integrity, and incorrect use of the
The suitelet as designed uses Google Charts API to create the visualizations in the
calculation of the what-if analysis. Per the Google API terms of service, “by using our APIs,
Google may use submitted information in accordance with our privacy policies.” This makes no
promise whatsoever that Google does not collect the information being passed into the javascript
files, and Google does not allow the javascript files related to creation of the charts to be
downloaded and hosted locally. While the data being transmitted to google contains very little, if
any, context, since the data does not contain business names, and would only be for one
particular state/financing type/project type combination. However, even if taken out of context, it
Often the most important, but under appreciated aspect of any system is integrity of the
data. Keeping the item information up to date, or ensuring the projects have complete and correct
data is tedious, expensive, and boring. It is often easier to rely on memory of employees than it is
to fix existing data issues. However, if the data is not correct, the analysis based on it will not be
correct either. A common saying for this is “garbage in, garbage out”. Some of the situations that
could occur are sudden changes in company policy that changes the averages used in the
calculation, transactions that are not processed in a timely basis so that the data does not
Even in the best circumstances where the data is correct and the calculation in aggregate
is correct, misuse by the user is also a potential pitfall. The calculation takes averages over the
lifetime use of the solution to project the most likely timing of milestone completion for current
projects, but it by no means a guarantee of that outcome. No person can predict the future with
100% accuracy and this will be far from that. It is important to ensure that the user understands
this solution is to help give a general direction and see the potential gains or losses when changes
in the completion times for projects change, the user has to follow through on those numbers in
TIMELINE / BUDGET
Original Timeline:
The original timeline was for the 200 hours minimum for this project. The original
planned work was completed on time and about 20 hours over the projected amount. However
once it was completed there were some additional issues not originally accounted for in the
project estimate, but perhaps should have been. This caused a large increase in hours that added
an additional 20% onto the original estimate. The largest areas that needed additional hours were
changes to the design after the original design was completed, project data integrity, and changes
in project design that caused previously validated calculations to not work correctly and
requiring changes.
After the cash flow analysis had been completed according to the original spec, it was
decided that the design was not as user friendly as intended. This resulted in the following
changes:
should represent the intervals from the selected project statistic. This enables the
user to see the values being compared in the calculation and what changes to
- The ‘load project statistic’ button functionality changed. In the original design the
button worked by selecting a statistic record, and then loading the field values into
the fields when the button is pressed. Now, instead, when a project statistic is
selected the inline fields are automatically updated instead of the user input ones.
The button still exists, but instead of loading values from a selected statistic, it
takes the values for the installation state, project type, and financing type and
loads the most recent project statistic matching those values into the project
statistic field. That also in turn triggers automatic updating of the inline interval
fields.
- The button to load an existing project statistic was removed in favor of the URL
- Terminology for the form was updated. The project statistic record was changed
to “Baseline Project Statistic” and the inline fields were moved to a field group
called “Baseline Intervals”. The button to load the project statistic was then
labeled “Load Baseline Record”. This gave the fields and buttons a common
- The name field had previously been automatically updated when the installation
state, project type, or financing type had been added or updated. This was
removed and instead the name is loaded from the project statistic record or
- Comments field was added to allow the user to add notes about what the data
represents.
Data integrity was another difficult issue for this project. The account that this solution
was developed on was used for many months while this project took shape and hundreds of
projects were created and did not follow a traditional path that reflects the way these projects will
be used when live. The projection looks at all open projects, and uses average close times to
project when they will be completed. The issue with project data in the development
environment came in two parts: first that projects had been completed up to wherever the current
developer using them necessitated and then never closed or deleted them, and the calculations for
the first 30 day bucket used not “between 0 and 30” but “less than 30”. For projects that had been
abandoned for months were used in the projection, they realistically should have been completed
months earlier and would have been a number such as “-15” which is less than 30. Additional to
the projects that had been abandoned, there were projects that had been completed in the span of
only a few minutes in order to test functionality in later stages of the project, resulting in average
in the project statistics that were unrealistic to the extreme. Some include average times of 1 day
The solution to these issues has been very time consuming as there are hundreds of
projects that need to be updated. The calculations rely on the most recently completed milestone,
and thus to make the revenue and expenses fall into the correct buckets, they need to be updated
to the next milestone or previous milestones edited so that edits will be more recent. This has
been completed through a series of csv imports as well as manually editing projects where
necessary.
The final issue that needed correction involved process changes that caused calculation
errors. These were not intentional but not considered when making changes downstream. There
is a process for updating field ID’s that could be used in scripts, but report formulas are not
included in this. In the original calculations for projected revenue, the criteria for deciding which
phase the project was in used a field called the ‘project state’. This logic required that the project
stage be consistent until the first milestone is completed, however that functionality was changed
at some point and this was not considered in changes related to it. This meant troubleshooting
why the numbers were not matching and then updating all of the formulas to be based on
USABILITY TESTING/EVAL
Testing was completed by SCRUM team members, and is done using test cases in table
form. The following is the majority of the test cases, there are some additional ones that include
the formulas that were used but for reasons related intellectual property, I have not included them
here.
Test cases:
What if saved record is selected Automatically redirected to That an existing record is selected PASS
selected record
‘Load Baseline’ button pressed The most recent baseline project Financing Type, Project Type, PASS
statistic record is selected. and installation state are all
The values for the ‘baseline selected.
intervals’ are populated from the
selected statistic.
Name field, comments,
installation state, project type,
financing type are populated.
‘Load Baseline’ button pressed Error prompt One or more of the following is PASS
not selected:
Financing type, project type,
installation state.
‘Load Baseline’ button pressed Error Prompt The selected combination of PASS
financing type, project type, and
installation state does not result in
an existing project statistic
record.
Baseline project statistic is The values for the ‘baseline The selected statistic exists PASS
selected intervals’ are populated from the
selected statistic.
Name field, comments,
installation state, project type,
financing type are populated.
Save and calculate is pressed What-if analysis is created and Project statistic is selected PASS
user is redirected to created No existing project statistic is
record. selected
When it is reloaded the charts and
data table with calculated results
is displayed.
Save and calculate is pressed Error prompt The selected project statistic PASS
and/or the installation state,
project type, financing type do
not match
Final Implementation
The final product included some changes, but is for the most part the same as the
originally described solution. The table holding the statistics has been created and the script
populating it has been running for several months now, and the reporting and KPI’s have been
changed slightly but the goal remains the same. In order to be sensitive to intellectual property,
this will include some details but most code will be left out.
The suitelet has been created and includes the following fields:
Revenue Inline HTML Displays the calculation for revenue and google charts
with the calculation results
Expenses Inline HTML Displays the calculation for expenses and google
charts with the calculation results
Net Inline HTML Displays the calculation for net and google charts
with the calculation results
Cashflow What-if Record selection / drop-down Allows the user to select an existing analysis
Saved Record
Name text Text field for the user to give the record a name
Comments Text area Text area where the user can add comments
Project Type Record selection / drop-down Record selection for project type
Financing Type Record selection / drop-down Record selection for financing type
Installation State Record selection / drop-down Record selection for installation state
Average Days from Integer The New - M0 days from the project statistic record
New to M0 (inline) that is selected by the user.
Average Days from Integer The New - M1 days from the project statistic record
New to M1 (inline) that is selected by the user.
Average Days from Integer The New - M2 days from the project statistic record
New to M2 (inline) that is selected by the user.
Average Days from Integer The New - M3 days from the project statistic record
New to M3 (inline) that is selected by the user.
Average Days from Integer The M0 - M1 days from the project statistic record
M0 to M1 (inline) that is selected by the user.
Average Days from Integer The M0 - M2 days from the project statistic record
M0 to M2 (inline) that is selected by the user.
Average Days from Integer The M0 - M3 days from the project statistic record
M0 to M3 (inline) that is selected by the user.
Average Days from Integer The M1 - M2 days from the project statistic record
M1 to M2 (inline) that is selected by the user.
Average Days from Integer The M1 - M3 days from the project statistic record
M1 to M3 (inline) that is selected by the user.
Average Days from Integer The M2 - M2 days from the project statistic record
M2 to M3 (inline) that is selected by the user.
Average Days from Integer / User Entry The New - M0 days entered by the user for
New to M0 calculation.
Average Days from Integer / User Entry The New - M1 days entered by the user for
New to M1 calculation.
Average Days from Integer / User Entry The New - M2 days entered by the user for
New to M2 calculation.
Average Days from Integer / User Entry The New - M3 days entered by the user for
New to M3 calculation.
Average Days from Integer / User Entry The M0 - M1 days entered by the user for calculation.
M0 to M1
Average Days from Integer / User Entry The M0 - M2 days entered by the user for calculation.
M0 to M2
Average Days from Integer / User Entry The M0 - M3 days entered by the user for calculation.
M0 to M3
Average Days from Integer / User Entry The M1 - M2 days entered by the user for calculation.
M1 to M2
Average Days from Integer / User Entry The M1 - M3 days entered by the user for calculation.
M1 to M3
Average Days from Integer / User Entry The M2 - M2 days entered by the user for calculation.
M2 to M3
The original design called for three buttons, and ended with two, one for the
submit/POST, and one to load the most recent project statistic record.
Field groups are part of the form design within NetSuite, and this detail was not included
in the original design but needed to be included. There are four field groups, Projection, Primary
Information, Baseline Information, Baseline Intervals, and What-if intervals. The projection
holds the inline html fields that display the charts and data table results from the calculation. The
primary information holds the existing record selection field, name, and comments fields.
Baseline information and baseline intervals hold the selection project statistic data including
project type, project statistic selection, financing type, and installation state. What-if Intervals
The end solution for the Suitelet was completed using two scripts, two module libraries
and 11 template files. All files combined have just under 2000 lines of code. Suitelets all include
a Suitelet script type, optionally they can include a client script loaded into the script via API
methods. Custom script libraries were created for both the suitelet script and the client script.
Originally the plan had been to use one script library and share them between each script, but
modules required for each library created conflicts that could not be overcome and necessitated
The template files hold the SQL formulas for the calculation. They have been created as
freemarker templates so that they can be utilized multiple times in the script, as there are three
inline html fields that require population and create as little duplication of code as possible. This
makes up 9 of the 11 templates. The remaining two templates are the Google chart, and data
table that is added underneath the charts. The data table is also a free marker template, however
the HTML and Javascript in the template for the google chart did not work with the freemarker
engine used by NetSuite. Instead the script loads the file as text, and uses string replaces to add
The largest challenge in the creation of this project is in the lack of documentation for the
NetSuite javascript API. The API includes all methods and objects that are used, but the
examples are minimal and incomplete. Because using the NetSuite API is such a niche area of
interest, there are not many website with any dedication to it. In hindsight, the answers are all
available in the API, but it can be difficult to interpret them and see how they can all be used in
combination.
CONCLUSION
The original problem that this project aimed to solve was a programmed way to calculate
and visualize operational efficiency gains on solar installation projects in the NetSuite
customized solution being developed by Blue Banyan Solutions. The solution involved saving
project statistics, and using those to calculate projected revenue, expenses and net for unfinished
projects using SQL formulas. Those results should be visualized on a custom page that can also
take input from the user for changed milestone intervals and compare the actuals to the what-if
added by the end user. Additionally there was a goal to visualize the data in charts or graphs so
that the user can more easily see the impact and compare to the original calculation.
The solution was created using the NetSuite API, Google Charts API, HTML, CSS, and
Javascript. The design involved a set of input fields for summary information, installation state,
project type, and financing type as well as fields for all relevant intervals for user input. There
should be a selection for a statistic record to select from, and selection for an existing analysis.
There should be a submit button for calculation and to load existing statistic records.
Some of these things were changed for a better user experience. When selected, project
statistic data is auto-loaded into the form and for selection of an existing analysis the user is
redirected to the page with said record loaded. Additionally the button function was changed to
load the statistic record given information selected by the user rather than the button loading
information from a statistic selected by the user. Additionally a second set of interval fields was
added to hold the project statistic data so that the user can more easily see the differences and
The areas of greatest learning opportunity with this project were in figuring how to solve
problems for something that is not well documented and where online resources are extremely
limited, and in combining multiple code types and API’s to create something cohesive and user
friendly. This forced the understanding of what is happening at every point in the user experience
using the Suitelet, but beyond that how those same concepts can be expanded to the rest of the
This project is very specialized, but not at all unique in the area of creating custom
business solutions. The experience gained in completing this project has been invaluable in the
amount of experience building solutions with NetSuite. Many of the fundamentals learned here
can be applied to any cloud based business system such as Salesforce, dell Boomi, and many
others. I hope to be able to take what I have gained here and build on it to continue making
Sources:
“Amd Javascript Module Loader.” Why AMD?, requirejs.org/docs/whyamd.html.
Mond, Allison. “SolarCity Is No Longer the Top Residential Solar Lease Provider in the US.”
Greentech Media, Greentech Media, 15 Nov. 2017,
www.greentechmedia.com/articles/read/solarcity-is-no-longer-the-top-residential-solar-lea
se-provider-in-the-us#gs.Ezf9HI8.