merging with upstream
This commit is contained in:
@@ -44,9 +44,10 @@ AWS_S3_BUCKET="..."
|
||||
AWS_ACCESS_KEY_ID="..."
|
||||
AWS_SECRET_ACCESS_KEY="..."
|
||||
|
||||
SF_BASE_URL="https://test.salesforce.com"
|
||||
SFDC_BASE_URL="https://test.salesforce.com"
|
||||
SFDC_ACCESS_KEY_ID="..."
|
||||
SFDC_SECRET_ACCESS_KEY="..."
|
||||
SFDC_API_URL="https://sunpower--qa.cs8.my.salesforce.com"
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ def s3_upload(bytes_or_file_like, filename=None, file_extension=None):
|
||||
|
||||
# Assuming bucket already exists
|
||||
s3.Bucket(bucket_name).put_object(Key=filename, Body=bytes_or_file_like.read(), ACL='public-read')
|
||||
file_url = 'https://s3.amazonaws.com/{}/{}'.format(bucket_name, filename)
|
||||
# file_url = 'https://s3.amazonaws.com/{}/{}'.format(bucket_name, filename) # PermanentRedirect error
|
||||
file_url = 'https://{}.s3.amazonaws.com/{}'.format(bucket_name, filename)
|
||||
print('Uploaded filename {} to S3: {}'.format(filename, file_url))
|
||||
return file_url
|
||||
|
||||
@@ -5,12 +5,18 @@ except ImportError:
|
||||
|
||||
|
||||
class JsonBuilder:
|
||||
def build_bom_output(self, rows):
|
||||
def build_bom(self, rows):
|
||||
data = []
|
||||
headers = ['Part #', 'Description', 'Total']
|
||||
headers = ['itemId', 'description', 'quantity']
|
||||
for row in rows:
|
||||
d = {}
|
||||
for i, value in enumerate(row):
|
||||
d[headers[i]] = value
|
||||
data.append(d)
|
||||
return data
|
||||
|
||||
def bom_to_json(self, data):
|
||||
return json.dumps(data)
|
||||
|
||||
def build_bom_output(self, rows):
|
||||
return self.bom_to_json(self.build_bom(rows))
|
||||
|
||||
@@ -41,16 +41,21 @@ app.config['PROFILE'] = True
|
||||
|
||||
# Sales Force integrations
|
||||
oauth = OAuth()
|
||||
SF_BASE_URL = os.getenv('SFDC_BASE_URL', 'https://test.salesforce.com')
|
||||
sales_force = oauth.remote_app('sales_force',
|
||||
consumer_key=os.getenv('SFDC_ACCESS_KEY_ID'),
|
||||
consumer_secret=os.getenv('SFDC_SECRET_ACCESS_KEY'),
|
||||
base_url=SF_BASE_URL,
|
||||
request_token_url=None, # OAuth 2
|
||||
access_token_method='POST', # Sales Force requirement
|
||||
access_token_url=SF_BASE_URL + '/services/oauth2/token',
|
||||
authorize_url=SF_BASE_URL + '/services/oauth2/authorize',
|
||||
)
|
||||
SFDC_BASE_URL = os.getenv('SFDC_BASE_URL', 'https://test.salesforce.com')
|
||||
try:
|
||||
sales_force = oauth.remote_app('sales_force',
|
||||
consumer_key=os.getenv('SFDC_ACCESS_KEY_ID'),
|
||||
consumer_secret=os.getenv('SFDC_SECRET_ACCESS_KEY'),
|
||||
base_url=SFDC_BASE_URL,
|
||||
request_token_url=None, # OAuth 2
|
||||
access_token_method='POST', # Sales Force requirement
|
||||
access_token_url=SFDC_BASE_URL + '/services/oauth2/token',
|
||||
authorize_url=SFDC_BASE_URL + '/services/oauth2/authorize',
|
||||
)
|
||||
except TypeError:
|
||||
print('Sales Force integration disabled')
|
||||
sales_force = None
|
||||
|
||||
|
||||
assets_env = assets.Environment(app)
|
||||
assets_env.init_app(app)
|
||||
@@ -186,7 +191,7 @@ def summary():
|
||||
return render_template('site_summary.html.jinja', context=context)
|
||||
|
||||
|
||||
def handle_dxf_file(session_manager, file_contents, filename=None):
|
||||
def handle_dxf_file(session_manager, file_contents, filename=None, save_file=True):
|
||||
errors = []
|
||||
user_values = session_manager.user_values()
|
||||
validator = FileValidator(user_values)
|
||||
@@ -210,7 +215,8 @@ def handle_dxf_file(session_manager, file_contents, filename=None):
|
||||
DXFHelper(),
|
||||
SubarrayValidator())
|
||||
csv = CsvBuilder().build_cad_output(dxf_data['panels'])
|
||||
session_manager.save_uploaded_file(csv, dxf_file_name=filename)
|
||||
if save_file:
|
||||
session_manager.save_uploaded_file(csv, dxf_file_name=filename)
|
||||
|
||||
buildings = dxf_data['buildings']
|
||||
session_manager.save_buildings_polygons(buildings)
|
||||
@@ -334,7 +340,7 @@ def load_dxf_file():
|
||||
db_session = sql_constant.sql_session_maker()
|
||||
session_manager = SessionManager(session, redis_constant.redis_store, db_session)
|
||||
|
||||
success, errors = handle_dxf_file(session_manager, file_contents, filename=filename)
|
||||
success, errors = handle_dxf_file(session_manager, file_contents, filename=filename, save_file=False)
|
||||
session['dxf_link_loaded'] = True
|
||||
if success:
|
||||
return jsonify({'status': 'success'})
|
||||
@@ -424,6 +430,10 @@ def download():
|
||||
session_manager = SessionManager(session, redis_constant.redis_store, db_session)
|
||||
context = session_manager.context()
|
||||
context['current_step'] = 5
|
||||
error, data = session.pop('sfdc_export_urls', (None, None))
|
||||
if data is not None:
|
||||
context['sfdc_export_error'] = error
|
||||
context['sfdc_export_urls'] = data
|
||||
db_session.close()
|
||||
return render_template('download.html.jinja', context=context)
|
||||
|
||||
@@ -540,7 +550,7 @@ def sales_force_authorized():
|
||||
session_manager = SessionManager(session, redis_constant.redis_store, db_session)
|
||||
session['sales_force_token'] = resp['access_token']
|
||||
|
||||
data = sf_tasks.get_site_characterization_from_sales_force(session, resp['instance_url'])
|
||||
data = sf_tasks.get_site_characterization_from_sales_force(session)
|
||||
if data:
|
||||
session['dxf_link'] = data['dxf_link']
|
||||
session_manager.save_form_submission(data)
|
||||
@@ -549,23 +559,27 @@ def sales_force_authorized():
|
||||
return sales_force_logout()
|
||||
|
||||
|
||||
# FIXME
|
||||
@app.route("/export-sfdc")
|
||||
def export_sfdc():
|
||||
if not is_sfdc_session():
|
||||
return redirect('/')
|
||||
db_session = sql_constant.sql_session_maker()
|
||||
session_manager = SessionManager(session, redis_constant.redis_store, db_session)
|
||||
session_id = session_manager.session['id']
|
||||
data = sf_tasks.export_to_sfdc(session_id)
|
||||
helix_session_id = session_manager.session['id']
|
||||
access_token = session['sales_force_token']
|
||||
sfid = session['SFID']
|
||||
error, data = sf_tasks.export_to_sfdc(helix_session_id, access_token, sfid)
|
||||
data.pop('bom', None)
|
||||
data['dxfUrlFromSF'] = session['dxf_link']
|
||||
session['sfdc_export_urls'] = (error, data)
|
||||
db_session.close()
|
||||
return jsonify(data)
|
||||
# return redirect('/download')
|
||||
return redirect('/download')
|
||||
|
||||
|
||||
@sales_force.tokengetter
|
||||
def get_sales_force_token(token=None):
|
||||
return session.get('sales_force_token')
|
||||
if sales_force:
|
||||
@sales_force.tokengetter
|
||||
def get_sales_force_token(token=None):
|
||||
return session.get('sales_force_token')
|
||||
|
||||
|
||||
@app.route('/sales_force_logout')
|
||||
@@ -574,6 +588,7 @@ def sales_force_logout():
|
||||
session.pop('sales_force_token', None)
|
||||
session.pop('dxf_link', None)
|
||||
session.pop('dxf_link_loaded', None)
|
||||
session.pop('sfdc_export_urls', None)
|
||||
session.clear()
|
||||
return redirect('/')
|
||||
# End of Sales Force Integration
|
||||
|
||||
@@ -68,7 +68,7 @@ class ProjectPresenter(object):
|
||||
# origin = self.find_origin(building)
|
||||
for point in building:
|
||||
point.x = point.x * spacing_x
|
||||
point.y = abs((point.y * spacing_y - max_y))
|
||||
point.y = abs((point.y * spacing_y) - max_y)
|
||||
presentable_building.append(point.__dict__)
|
||||
|
||||
return result
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import io
|
||||
import os
|
||||
import uuid
|
||||
|
||||
import requests
|
||||
@@ -16,14 +17,12 @@ from helix.Services.s3_helper import s3_upload
|
||||
from helix.session_manager import SessionManager
|
||||
|
||||
|
||||
def get_site_characterization_from_sales_force(session, base_url):
|
||||
'''
|
||||
@base_url: Avoid URL_NOT_RESET errors
|
||||
'''
|
||||
def get_site_characterization_from_sales_force(session):
|
||||
access_token = session['sales_force_token']
|
||||
sfid = session['SFID']
|
||||
helix_id = session['id']
|
||||
url = base_url + '/services/apexrest/v1/HelixRoofDetails'
|
||||
SFDC_API_URL = os.getenv('SFDC_API_URL', 'https://sunpower--qa.cs8.my.salesforce.com')
|
||||
url = SFDC_API_URL + '/services/apexrest/v1/HelixRoofDetails'
|
||||
headers = {'Authorization': 'Bearer {}'.format(access_token)}
|
||||
result = requests.get(url, headers=headers, params={'SFID': sfid, 'helix_session_id': helix_id})
|
||||
if result.status_code == 200:
|
||||
@@ -50,12 +49,12 @@ def convert_sales_force_data_format_to_helix(data):
|
||||
# data['spectral_response_acceleration']
|
||||
|
||||
|
||||
def export_to_sfdc(session_id):
|
||||
def export_to_sfdc(helix_session_id, access_token, sfid):
|
||||
step = 'Exporting to SFDC'
|
||||
try:
|
||||
# 1. Load User Values
|
||||
step = 'Loading User Values'
|
||||
session = {'id': session_id}
|
||||
session = {'id': helix_session_id}
|
||||
db_session = sql_constant.sql_session_maker()
|
||||
session_manager = SessionManager(session, redis_constant.redis_store, db_session)
|
||||
user_values = session_manager.user_values()
|
||||
@@ -67,7 +66,9 @@ def export_to_sfdc(session_id):
|
||||
csv_file = CsvBuilder().build_bom_output(bom)
|
||||
# 2.1 Generate BOM CSV file
|
||||
step = 'Generating BOM as JSON'
|
||||
json_str = JsonBuilder().build_bom_output(bom)
|
||||
json_builder = JsonBuilder()
|
||||
bom_list = json_builder.build_bom(bom)
|
||||
bom_list_json = json_builder.bom_to_json(bom_list)
|
||||
|
||||
# 3. Generate DOCUMENTATION PDF file
|
||||
step = 'Generating Documentation'
|
||||
@@ -84,8 +85,8 @@ def export_to_sfdc(session_id):
|
||||
step = 'Uploading to S3'
|
||||
filename = uuid.uuid4().hex
|
||||
bom_csv_url = s3_upload(io.StringIO(csv_file), filename=filename + '.csv')
|
||||
bom_json_url = s3_upload(io.StringIO(json_str), filename=filename + '.json')
|
||||
doc_url = s3_upload(io.BytesIO(document), filename=filename + '.pdf')
|
||||
bom_json_url = s3_upload(io.StringIO(bom_list_json), filename=filename + '.json')
|
||||
if dxf_contents: # Optional
|
||||
dxf_url = s3_upload(io.StringIO(dxf_contents), filename=filename + '.dxf')
|
||||
else:
|
||||
@@ -93,26 +94,34 @@ def export_to_sfdc(session_id):
|
||||
|
||||
# 6. Notify SFDC system with an API request
|
||||
step = 'Notifying SFDC'
|
||||
SFDC_API_URL = 'https://localhost:8443/' # FIXME
|
||||
data = {
|
||||
'dxf_url': dxf_url,
|
||||
'bom_csv_url': bom_csv_url,
|
||||
'bom_json_url': bom_json_url,
|
||||
'documentation_url': doc_url,
|
||||
'dxfUrl': dxf_url,
|
||||
'bomCsvUrl': bom_csv_url,
|
||||
'documentationUrl': doc_url,
|
||||
'bom': bom_list,
|
||||
'helixSessionId': helix_session_id,
|
||||
'SFID': sfid,
|
||||
}
|
||||
print(data)
|
||||
# result = requests.post(SFDC_API_URL, data=data, timeout=30)
|
||||
|
||||
headers = {'Authorization': 'Bearer {}'.format(access_token)}
|
||||
SFDC_API_URL = os.getenv('SFDC_API_URL', 'https://sunpower--qa.cs8.my.salesforce.com')
|
||||
url = SFDC_API_URL + '/services/apexrest/v1/HelixRoofDetails'
|
||||
result = requests.post(url, headers=headers, data=data, timeout=30)
|
||||
# 7. Internal logs
|
||||
# if result.status_code != 200: # FIXME
|
||||
# print('')
|
||||
# else:
|
||||
# print('')
|
||||
if result.status_code <= 299:
|
||||
print('Sales Force notified successfully for session {}.'.format(helix_session_id))
|
||||
# print(result.content)
|
||||
error = None
|
||||
else:
|
||||
error = 'Helix wasn\'t able to notify the Sales Force ({})'.format(result.status_code)
|
||||
print(error)
|
||||
print(result.content)
|
||||
|
||||
# Only Helix need this information for audit
|
||||
data['bomJsonUrl'] = bom_json_url
|
||||
|
||||
db_session.close()
|
||||
return data
|
||||
# return result.status_code
|
||||
return error, data
|
||||
except Exception as e:
|
||||
msg = 'Error while {} for session {}'.format(step, session_id)
|
||||
print(msg)
|
||||
raise e
|
||||
print('Error while {} for session {}'.format(step, helix_session_id))
|
||||
error = 'Error while {}'.format(step)
|
||||
return error, {}
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
{% extends "layout.html.jinja" %}
|
||||
{% set title = "Helix Calculator" %}
|
||||
{% block contents %}
|
||||
{% for warning in context['warning_messages'] %}
|
||||
<div class="summary_warning">{{ warning.value }}</div>
|
||||
{% endfor %}
|
||||
{% if 'sfdc_export_urls' in context %}
|
||||
{% if context['sfdc_export_error'] %}
|
||||
<div class="summary_warning" style="margin-top: 20px;">{{ context['sfdc_export_error'] }}</div>
|
||||
{% else %}
|
||||
<div class="msg-container">Documents exported to Sales Force succesffully.</div>
|
||||
{% endif %}
|
||||
|
||||
<ul class="msg-container">
|
||||
{% if context['sfdc_export_urls']['dxfUrl'] %}
|
||||
<li><a href="{{ context['sfdc_export_urls']['dxfUrl'] }}">DXF file</a> (uploaded on Helix)</li>
|
||||
{% else %}
|
||||
<li><a href="{{ context['sfdc_export_urls']['dxfUrlFromSF'] }}">DXF file</a> (uploaded on Sales Force)</li>
|
||||
{% endif %}
|
||||
<li><a href="{{ context['sfdc_export_urls']['documentationUrl'] }}">Documentation file</a></li>
|
||||
<li><a href="{{ context['sfdc_export_urls']['bomCsvUrl'] }}">BOM CSV file</a></li>
|
||||
<li><a href="{{ context['sfdc_export_urls']['bomJsonUrl'] }}">BOM JSON file</a></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<div class="form_section">
|
||||
<h3>Download</h3>
|
||||
|
||||
Reference in New Issue
Block a user