diff --git a/.env.default b/.env.default index 4032767cdfad786d7f17cdaf4f621c418bc8e640..c2d83f84852c78ae82ca425ccc7cc24968798861 100644 --- a/.env.default +++ b/.env.default @@ -18,4 +18,6 @@ CORS_ORIGIN_WHITELIST=$CORS_ORIGIN_WHITELIST BLOCPOWER_PHONE_NUMBER=$BLOCPOWER_PHONE_NUMBER TEST_EMAIL=$TEST_EMAIL PROD_EMAIL=$PROD_EMAIL -FROM_EMAIL=$FROM_EMAIL \ No newline at end of file +FROM_EMAIL=$FROM_EMAIL +AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID +AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 8dbea9179137a57cec455737f2aee4606fc009b9..682f9abe08e490d4c77287b2fd42dfeadca66a2c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -75,9 +75,18 @@ RUN rm EnergyPlus-8.6.0-198c6a3cff-Linux-x86_64.sh ENV ASHP_PPTX_TEMPLATE=$CODEROOT/bloclink/apps/pna/PNA_Report_Template.pptx ADD https://ashp-pna-template.s3.amazonaws.com/PNA_Report_Template.pptx $ASHP_PPTX_TEMPLATE -# Get Non-NYC PNA Template -ENV NON_NYC_PPTX_TEMPLATE=$CODEROOT/bloclink/apps/bis/NonNYC_Report_Template.pptx -ADD https://ashp-pna-template.s3.amazonaws.com/NonNYC_Report_Template.pptx $NON_NYC_PPTX_TEMPLATE +# Get Non-NYC PNA Templates +ENV NON_NYC_PPTX_TEMPLATE_1=$CODEROOT/bloclink/apps/bis/PNS_NonNYC_Template_1.pptx +ADD https://ashp-pna-template.s3.amazonaws.com/PNS_NonNYC_Template_1.pptx $NON_NYC_PPTX_TEMPLATE_1 + +ENV NON_NYC_PPTX_TEMPLATE_2=$CODEROOT/bloclink/apps/bis/PNS_NonNYC_Template_2.pptx +ADD https://ashp-pna-template.s3.amazonaws.com/PNS_NonNYC_Template_2.pptx $NON_NYC_PPTX_TEMPLATE_2 + +ENV NON_NYC_PPTX_TEMPLATE_3=$CODEROOT/bloclink/apps/bis/PNS_NonNYC_Template_3.pptx +ADD https://ashp-pna-template.s3.amazonaws.com/PNS_NonNYC_Template_3.pptx $NON_NYC_PPTX_TEMPLATE_3 + +ENV NON_NYC_PPTX_TEMPLATE_4=$CODEROOT/bloclink/apps/bis/PNS_NonNYC_Template_4.pptx +ADD https://ashp-pna-template.s3.amazonaws.com/PNS_NonNYC_Template_4.pptx $NON_NYC_PPTX_TEMPLATE_4 # Collect static files RUN cd $CODEROOT && python3 manage.py collectstatic --noinput diff --git a/bloclink/apps/bis/views.py b/bloclink/apps/bis/views.py index c3849d93c319253a8da48f3e35762540444984f0..ec583c5973bfcf971370040b4f68edd5fdcfb126 100644 --- a/bloclink/apps/bis/views.py +++ b/bloclink/apps/bis/views.py @@ -6,7 +6,7 @@ from django.conf import settings from django.http import HttpResponse, JsonResponse from django.shortcuts import render from django.views import View -from .models import Questions, MapBoxBuilding, Answers, SubmittedSurvey, Users, Surveys, SurveyAreas +from .models import Questions, MapBoxBuilding, Answers, SubmittedSurvey, Users, Surveys, SurveyAreas, RecommendationSetMap, Ecm, Report from django.forms.models import model_to_dict import smtplib from django.core.mail import send_mail @@ -18,6 +18,8 @@ from django.template.loader import render_to_string from django.core.mail import EmailMessage from django.db import connections import re +import boto3 +from bpeng.bis.report import generate_pns_report class SubmitBuilding(View): def put(self, request): @@ -178,9 +180,116 @@ class SubmitContact(View): class SubmitQuestionnaire(View): def put(self, request): put = json.loads(request.body.decode()) + buildingAddress = MapBoxBuilding.objects.using('bis').get(building_id=put['buildingId']).mapbox_address + if put['surveyId'] in [2,3] : + # Get building type + submittedBuildingType = model_to_dict(SubmittedSurvey.objects.using('bis').get(user_id=put['userId'], question_id=12).answer_id)['id'] + + # Get building sub type + submittedBuildingSubType = model_to_dict(SubmittedSurvey.objects.using('bis').get(user_id=put['userId'], question_id=13).answer_id)['id'] + + # Get recommendation set + recommendationSet = model_to_dict(RecommendationSetMap.objects.using('bis').get(building_type_id=submittedBuildingType, building_sub_type_id=submittedBuildingSubType).recommendation_id)['id'] + + # Get all the ecms for this recommendation set + possibleEcms = [] + ecms = Ecm.objects.using('bis').filter(recommendation_id=recommendationSet) + for ecm in ecms: + possibleEcms.append(model_to_dict(ecm)['id']) + + # Get all the question id and submitted answer id and put it in a dictionary + submittedQuestionAnswers = {} + submittedAnswers = SubmittedSurvey.objects.using('bis').filter(user_id=put['userId']).order_by('id') + for submittedAnswer in submittedAnswers: + submittedQuestionAnswers[model_to_dict(submittedAnswer)['question_id']] = submittedQuestionAnswers[model_to_dict(submittedAnswer)['question_id']] if model_to_dict(submittedAnswer)['question_id'] in submittedQuestionAnswers else [] + submittedQuestionAnswers[model_to_dict(submittedAnswer)['question_id']].append(model_to_dict(submittedAnswer)['answer_id']) + + if recommendationSet == 1: + # Single Family recommendation filtering + if 2 in submittedQuestionAnswers[24]: + possibleEcms.remove(6) + possibleEcms.remove(7) + if 1 not in submittedQuestionAnswers[43] and 1 in submittedQuestionAnswers[26]: + possibleEcms.remove(8) + if 1 not in submittedQuestionAnswers[41] and 1 in submittedQuestionAnswers[24]: + possibleEcms.remove(9) + if 99 not in submittedQuestionAnswers[16] and (100 in submittedQuestionAnswers[16] or 101 in submittedQuestionAnswers[16] or 1 in submittedQuestionAnswers[24]): + possibleEcms.remove(10) + possibleEcms.remove(12) + if 1 not in submittedQuestionAnswers[36] and (103 in submittedQuestionAnswers[17] or 105 in submittedQuestionAnswers[17] or 106 in submittedQuestionAnswers[17] or 107 in submittedQuestionAnswers[17] or 108 in submittedQuestionAnswers[17]): + possibleEcms.remove(11) + if 1 not in submittedQuestionAnswers[37] and (101 in submittedQuestionAnswers[16] and 107 in submittedQuestionAnswers[17]): + possibleEcms.remove(13) + if 98 not in submittedQuestionAnswers[16] and (102 in submittedQuestionAnswers[17] or 103 in submittedQuestionAnswers[17] or 106 in submittedQuestionAnswers[17] or 107 in submittedQuestionAnswers[17]): + possibleEcms.remove(15) + if 1 not in submittedQuestionAnswers[48] and 1 in submittedQuestionAnswers[31]: + possibleEcms.remove(16) + if 1 not in submittedQuestionAnswers[45] and 1 in submittedQuestionAnswers[28]: + possibleEcms.remove(17) + elif recommendationSet == 2: + # Multi Family recommendation filtering + if 1 in submittedQuestionAnswers[23]: + possibleEcms.remove(20) + if 104 not in submittedQuestionAnswers[17]: + possibleEcms.remove(23) + if 99 not in submittedQuestionAnswers[16] and 1 in submittedQuestionAnswers[18]: + possibleEcms.remove(24) + if 97 not in submittedQuestionAnswers[16]: + possibleEcms.remove(25) + if 101 in submittedQuestionAnswers[16] and 107 in submittedQuestionAnswers[17]: + possibleEcms.remove(26) + if 1 not in submittedQuestionAnswers[48] and 1 in submittedQuestionAnswers[31]: + possibleEcms.remove(37) + if 1 not in submittedQuestionAnswers[45] and 1 in submittedQuestionAnswers[28]: + possibleEcms.remove(27) + if 1 not in submittedQuestionAnswers[47] and 1 in submittedQuestionAnswers[30]: + possibleEcms.remove(28) + elif recommendationSet == 3: + # Small Commercial recommendation filtering + if 104 not in submittedQuestionAnswers[17]: + possibleEcms.remove(31) + possibleEcms.remove(34) + possibleEcms.remove(35) + if 99 not in submittedQuestionAnswers[16] and 1 in submittedQuestionAnswers[18]: + possibleEcms.remove(32) + if 1 not in submittedQuestionAnswers[48] and 1 in submittedQuestionAnswers[31]: + possibleEcms.remove(36) + if (101 in submittedQuestionAnswers[16] and 107 in submittedQuestionAnswers[17]) or 100 in submittedQuestionAnswers[16] or 102 in submittedQuestionAnswers[17] or 106 in submittedQuestionAnswers[17]: + possibleEcms.remove(33) + + # Get final ECMs + recommendations = [] + for ecm in possibleEcms: + recommendations.append(model_to_dict(Ecm.objects.using('bis').get(id=ecm))) + + # Get building info + building_info = {} + building_info['address'] = buildingAddress + # Generate Report + report = generate_pns_report(building_info, recommendations) + + # Store generated report in S3 bucket + dest_ppt_file = report.replace(',', '') + S3 = boto3.client('s3', + aws_access_key_id = os.environ['AWS_ACCESS_KEY_ID'], + aws_secret_access_key = os.environ['AWS_SECRET_ACCESS_KEY']) + BUCKET_NAME = 'blocpower.io' + S3_FileName = 'PNA_Reports/'+dest_ppt_file.split('/')[-1] + try: + S3.upload_file(report, BUCKET_NAME, S3_FileName) + except Exception as e: + print(e) + os.rename(report, dest_ppt_file) + + # Add entry into report object + Report( + survey_id = SubmittedSurvey.objects.using('bis').filter(user_id=put['userId'])[0], + resource = dest_ppt_file.split('/')[-1], + last_updated = datetime.now() + ).save(using='bis') + # Sending Emails - buildingAddress = MapBoxBuilding.objects.using('bis').get(building_id=put['buildingId']).mapbox_address firstName = put['firstName'] lastName = put['lastName'] toEmail = put['email'] @@ -205,7 +314,8 @@ class SubmitQuestionnaire(View): msg_html = render_to_string('thank_you_email.html', {'firstName': firstName, 'lastName': lastName, 'buildingAddress': buildingAddress, 'phone':settings.BLOCPOWER_PHONE_NUMBER}) msg = EmailMessage('Thank you', msg_html, from_email, [toEmail]) msg.content_subtype = "html" - # msg.attach_file('bloclink/templates/oaklandTemplate.pdf') + # We are not sending PPT to the user rn. + # msg.attach_file(dest_ppt_file) msg.send() # Get all building related data @@ -232,21 +342,18 @@ class SubmitQuestionnaire(View): 'buildingId': put['buildingId'], 'address': buildingData['address'], 'QA': buildingData['questions']}) + subject = 'BIS - ' + buildingData['address'] if os.environ['ENVIRONMENT'] == 'prod': - send_mail( subject, - msg_txt, - from_email, - [settings.PROD_EMAIL], - html_message=msg_html, - ) + msg = EmailMessage(subject, msg_html, from_email, [settings.PROD_EMAIL]) + msg.content_subtype = "html" + msg.attach_file(dest_ppt_file) + msg.send() else: - send_mail( "TEST - " + subject, - msg_txt, - from_email, - [settings.TEST_EMAIL], - html_message=msg_html, - ) + msg = EmailMessage("TEST - " + subject, msg_html, from_email, [settings.TEST_EMAIL]) + msg.content_subtype = "html" + msg.attach_file(dest_ppt_file) + msg.send() return JsonResponse({ 'success': True, diff --git a/bloclink/settings.py b/bloclink/settings.py index c9bf34668d8cddf0d66fca17b59bdf70e8ebf712..2bcc2c9e6d009df9cd19ed8a6762f784f9d42f4a 100644 --- a/bloclink/settings.py +++ b/bloclink/settings.py @@ -34,9 +34,11 @@ PENTAHO_PASSWORD = config('PENTAHO_PASSWORD') # Building Intake Survey URL BIS_URL = config('BIS_URL') BLOCPOWER_PHONE_NUMBER = config('BLOCPOWER_PHONE_NUMBER') -TEST_EMAIL= config('TEST_EMAIL') -PROD_EMAIL= config('PROD_EMAIL') -FROM_EMAIL= config('FROM_EMAIL') +TEST_EMAIL = config('TEST_EMAIL') +PROD_EMAIL = config('PROD_EMAIL') +FROM_EMAIL = config('FROM_EMAIL') +AWS_ACCESS_KEY_ID = config('AWS_ACCESS_KEY_ID') +AWS_SECRET_ACCESS_KEY = config('AWS_SECRET_ACCESS_KEY') if ENV == 'local': CORS_ORIGIN_WHITELIST = config('CORS_ORIGIN_WHITELIST', cast=Csv()) diff --git a/config/local/bloclink.Dockerfile b/config/local/bloclink.Dockerfile index 72a883a43cf96ae0c0386b9f42f62b4d215f89c2..062d0ccb1233ba628b2d8871150d17b9779a3257 100644 --- a/config/local/bloclink.Dockerfile +++ b/config/local/bloclink.Dockerfile @@ -41,6 +41,15 @@ COPY $service_path/ /app/ ENV ASHP_PPTX_TEMPLATE=$CODEROOT/bloclink/apps/pna/PNA_Report_Template.pptx ADD https://ashp-pna-template.s3.amazonaws.com/PNA_Report_Template.pptx $ASHP_PPTX_TEMPLATE -# Get Non-NYC PNA Template -ENV NON_NYC_PPTX_TEMPLATE=$CODEROOT/bloclink/apps/bis/NonNYC_Report_Template.pptx -ADD https://ashp-pna-template.s3.amazonaws.com/NonNYC_Report_Template.pptx $NON_NYC_PPTX_TEMPLATE +# Get Non-NYC PNA Templates +ENV NON_NYC_PPTX_TEMPLATE_1=$CODEROOT/bloclink/apps/bis/PNS_NonNYC_Template_1.pptx +ADD https://ashp-pna-template.s3.amazonaws.com/PNS_NonNYC_Template_1.pptx $NON_NYC_PPTX_TEMPLATE_1 + +ENV NON_NYC_PPTX_TEMPLATE_2=$CODEROOT/bloclink/apps/bis/PNS_NonNYC_Template_2.pptx +ADD https://ashp-pna-template.s3.amazonaws.com/PNS_NonNYC_Template_2.pptx $NON_NYC_PPTX_TEMPLATE_2 + +ENV NON_NYC_PPTX_TEMPLATE_3=$CODEROOT/bloclink/apps/bis/PNS_NonNYC_Template_3.pptx +ADD https://ashp-pna-template.s3.amazonaws.com/PNS_NonNYC_Template_3.pptx $NON_NYC_PPTX_TEMPLATE_3 + +ENV NON_NYC_PPTX_TEMPLATE_4=$CODEROOT/bloclink/apps/bis/PNS_NonNYC_Template_4.pptx +ADD https://ashp-pna-template.s3.amazonaws.com/PNS_NonNYC_Template_4.pptx $NON_NYC_PPTX_TEMPLATE_4 diff --git a/requirements.txt b/requirements.txt index e0bd14ea0941b793a507aec5c6442a483ab1009c..5cccf6da0f7f3e29981cf4187d727c0f93a53d47 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -git+https://[YOUR-GITHUB-TOKEN]:x-oauth-basic@github.com/Blocp/bpengine.git@v0.8.5 +git+https://[YOUR-GITHUB-TOKEN]:x-oauth-basic@github.com/Blocp/bpengine.git@v0.8.6 celery==4.0.2 Django==1.10.6 numpy==1.17.4