def setUp(self): super(TestOpportunitiesAdminBase, self).setUp() try: mkdir(current_app.config.get('UPLOAD_DESTINATION')) except OSError: rmtree(current_app.config.get('UPLOAD_DESTINATION')) mkdir(current_app.config.get('UPLOAD_DESTINATION')) import_nigp(current_app.config.get('PROJECT_ROOT') + '/test/mock/nigp.csv') self.department1 = DepartmentFactory(name='test') self.opportunity_type = OpportunityTypeFactory.create() self.admin = UserFactory.create( email='*****@*****.**', role=RoleFactory.create(name='admin') ) self.staff = UserFactory.create( email='*****@*****.**', role=RoleFactory.create(name='staff') ) self.document = RequiredBidDocumentFactory.create() self.vendor = Vendor.create(email='*****@*****.**', business_name='foo2') self.opportunity1 = OpportunityFactory.create( contact=self.admin, created_by=self.staff, title=u'tést unïcode title', description=u'tést unïcode déscription', is_public=True, is_archived=False, planned_publish=datetime.date.today() + datetime.timedelta(1), planned_submission_start=datetime.date.today() + datetime.timedelta(2), planned_submission_end=datetime.datetime.today() + datetime.timedelta(2), vendor_documents_needed=[self.document.id], categories=(Category.query.first(),) ) self.opportunity2 = OpportunityFactory.create( contact=self.admin, created_by=self.staff, is_public=True, is_archived=False, planned_publish=datetime.date.today(), planned_submission_start=datetime.date.today() + datetime.timedelta(2), planned_submission_end=datetime.datetime.today() + datetime.timedelta(2), categories=(Category.query.first(),) ) self.opportunity3 = OpportunityFactory.create( contact=self.admin, created_by=self.staff, is_public=True, is_archived=False, planned_publish=datetime.date.today() - datetime.timedelta(2), planned_submission_start=datetime.date.today() - datetime.timedelta(2), planned_submission_end=datetime.datetime.today() - datetime.timedelta(1), categories=(Category.query.first(),) ) self.opportunity4 = OpportunityFactory.create( contact=self.admin, created_by=self.staff, is_public=True, is_archived=False, planned_publish=datetime.date.today() - datetime.timedelta(1), planned_submission_start=datetime.date.today(), planned_submission_end=datetime.datetime.today() + datetime.timedelta(2), title='TEST TITLE!', categories=(Category.query.first(),) )
def build_notifications(self): '''Implements EmailJobBase build_notifications method Returns: list of :py:class:`~purchasing.notifications.Notification` objects, one for each non-expired opportunity that has been published since the last Beacon newsletter was sent out ''' notifications = [] opportunities = self.get_opportunities() notifications.append( Notification( to_email=set([i.email for i in Vendor.newsletter_subscribers()]), from_email=current_app.config['BEACON_SENDER'], subject='Your biweekly Beacon opportunity summary', html_template='beacon/emails/biweeklydigest.html', txt_template='beacon/emails/biweeklydigest.txt', opportunities=opportunities ) ) return notifications
def signup(): '''The signup page for vendors :status 200: Render the :py:class:`~purchasing.forms.front.SignupForm` :status 302: Process the signup form post, redirect the vendor back to the splash page ''' session_vendor = Vendor.query.filter( Vendor.email == session.get('email'), Vendor.business_name == session.get('business_name') ).first() form = init_form(VendorSignupForm, model=session_vendor) if form.validate_on_submit(): vendor = Vendor.query.filter(Vendor.email == form.data.get('email')).first() if vendor: current_app.logger.info(''' OPPUPDATEVENDOR - Vendor updated: EMAIL: {old_email} -> {email} at BUSINESS: {old_bis} -> {bis_name} signed up for: CATEGORIES: {old_cats} -> {categories}'''.format( old_email=vendor.email, email=form.data['email'], old_bis=vendor.business_name, bis_name=form.data['business_name'], old_cats=[i.__unicode__() for i in vendor.categories], categories=[i.__unicode__() for i in form.data['categories']] )) vendor.update( **form.pop_categories(categories=False) ) flash("You are already signed up! Your profile was updated with this new information", 'alert-info') else: current_app.logger.info( 'OPPNEWVENDOR - New vendor signed up: EMAIL: {email} at BUSINESS: {bis_name} signed up for:\n' + 'CATEGORIES: {categories}'.format( email=form.data['email'], bis_name=form.data['business_name'], categories=[i.__unicode__() for i in form.data['categories']] ) ) vendor = Vendor.create( **form.pop_categories(categories=False) ) confirmation_sent = Notification( to_email=vendor.email, subject='Thank you for signing up!', html_template='beacon/emails/signup.html', txt_template='beacon/emails/signup.txt', categories=form.data['categories'] ).send() if confirmation_sent: admins = db.session.query(User.email).join(Role, User.role_id == Role.id).filter( Role.name.in_(['admin', 'superadmin']) ).all() Notification( to_email=admins, subject='A new vendor has signed up on beacon', categories=form.data['categories'], vendor=form.data['email'], convert_args=True, business_name=form.data['business_name'] ).send() flash('Thank you for signing up! Check your email for more information', 'alert-success') else: flash('Uh oh, something went wrong. We are investigating.', 'alert-danger') session['email'] = form.data.get('email') session['business_name'] = form.data.get('business_name') return redirect(url_for('front.splash')) page_email = request.args.get('email', None) if page_email: current_app.logger.info( 'OPPSIGNUPVIEW - User clicked through to signup with email {}'.format(page_email) ) session['email'] = page_email return redirect(url_for('front.signup')) if 'email' in session: if not form.email.validate(form): session.pop('email', None) form.display_cleanup() return render_template( 'beacon/front/signup.html', form=form, categories=form.get_categories(), subcategories=form.get_subcategories() )
def manage(): '''Manage a vendor's signups :status 200: render the :py:class:`~purchasing.forms.front.UnsubscribeForm` :status 302: post the :py:class:`~purchasing.forms.front.UnsubscribeForm` and change the user's email subscriptions and redirect them back to the management page. ''' form = init_form(UnsubscribeForm) form_categories = [] form_opportunities = [] vendor = None if form.validate_on_submit(): email = form.data.get('email') vendor = Vendor.query.filter(Vendor.email == email).first() if vendor is None: current_app.logger.info( 'OPPMANAGEVIEW - Unsuccessful search for email {}'.format(email) ) form.email.errors = ['We could not find the email {}'.format(email)] if request.form.get('button', '').lower() == 'update email preferences': remove_categories = set([Category.query.get(i) for i in form.categories.data]) remove_opportunities = set([Opportunity.query.get(i) for i in form.opportunities.data]) # remove none types if any remove_categories.discard(None) remove_opportunities.discard(None) vendor.categories = vendor.categories.difference(remove_categories) vendor.opportunities = vendor.opportunities.difference(remove_opportunities) if form.data.get('subscribed_to_newsletter'): vendor.subscribed_to_newsletter = False current_app.logger.info( '''OPPMANAGEVIEW - Vendor {} unsubscribed from: Categories: {} Opportunities: {} Subscribed from newsletter: {} '''.format( email, ', '.join([i.category_friendly_name for i in remove_categories if remove_categories and len(remove_categories) > 0]), ', '.join([i.description for i in remove_opportunities if remove_opportunities and len(remove_opportunities) > 0]), vendor.subscribed_to_newsletter ) ) db.session.commit() flash('Preferences updated!', 'alert-success') if vendor: for subscription in vendor.categories: form_categories.append((subscription.id, subscription.category_friendly_name)) for subscription in vendor.opportunities: form_opportunities.append((subscription.id, subscription.title)) form = init_form(UnsubscribeForm) form.opportunities.choices = form_opportunities form.categories.choices = form_categories return render_template( 'beacon/front/manage.html', form=form, vendor=vendor if vendor else Vendor() )
def signup_for_opp(form, opportunity, multi=False): '''Sign a vendor up for an opportunity Generic helper method to handle subscriptions from both the list view (signing up form multiple opportunities) and the detail view (signing up for a single opportunity). Responsible for creation of new Vendor objects if necessary, and sending emails based on the opportunities selected to receive updates about. Arguments: form: The relevant subscription form opportunity: Either an opportunity model or a list of opportunity ids multi: A boolean to flag if there are multiple opportunities that should to subscribe to or a single opportunity Returns: True if email sent successfully, false otherwise ''' send_email = True email_opportunities = [] if opportunity is None or (isinstance(opportunity, list) and len(opportunity) == 0): form.errors['opportunities'] = ['You must select at least one opportunity!'] return False # add the email/business name to the session session['email'] = form.data.get('email') session['business_name'] = form.data.get('business_name') # subscribe the vendor to the opportunity vendor = Vendor.query.filter( Vendor.email == form.data.get('email') ).first() if vendor is None: vendor = Vendor( email=form.data.get('email'), business_name=form.data.get('business_name') ) db.session.add(vendor) db.session.commit() else: vendor.update(business_name=form.data.get('business_name')) if multi: for opp in opportunity: _opp = Opportunity.query.get(int(opp)) if not _opp.is_public: db.session.rollback() form.errors['opportunities'] = ['That\'s not a valid choice.'] return False if _opp in vendor.opportunities: send_email = False else: vendor.opportunities.add(_opp) email_opportunities.append(_opp) else: if opportunity in vendor.opportunities: send_email = False else: vendor.opportunities.add(opportunity) email_opportunities.append(opportunity) if form.data.get('also_categories'): # TODO -- add support for categories pass db.session.commit() current_app.logger.info( 'OPPSIGNUP - Vendor has signed up for opportunities: EMAIL: {email} at BUSINESS: {bis_name} signed up for:\n' + 'OPPORTUNITY: {opportunities}'.format( email=form.data.get('email'), business_name=form.data.get('business_name'), opportunities=', '.join([i.title.encode('ascii', 'ignore') for i in email_opportunities]) ) ) if send_email: Notification( to_email=vendor.email, from_email=current_app.config['BEACON_SENDER'], subject='Subscription confirmation from Beacon', html_template='beacon/emails/oppselected.html', txt_template='beacon/emails/oppselected.txt', opportunities=email_opportunities ).send() return True
def signup_for_opp(form, opportunity, multi=False): '''Sign a vendor up for an opportunity Generic helper method to handle subscriptions from both the list view (signing up form multiple opportunities) and the detail view (signing up for a single opportunity). Responsible for creation of new Vendor objects if necessary, and sending emails based on the opportunities selected to receive updates about. Arguments: form: The relevant subscription form opportunity: Either an opportunity model or a list of opportunity ids multi: A boolean to flag if there are multiple opportunities that should to subscribe to or a single opportunity Returns: True if email sent successfully, false otherwise ''' send_email = True email_opportunities = [] if opportunity is None or (isinstance(opportunity, list) and len(opportunity) == 0): form.errors['opportunities'] = [ 'You must select at least one opportunity!' ] return False # add the email/business name to the session session['email'] = form.data.get('email') session['business_name'] = form.data.get('business_name') # subscribe the vendor to the opportunity vendor = Vendor.query.filter( Vendor.email == form.data.get('email')).first() if vendor is None: vendor = Vendor(email=form.data.get('email'), business_name=form.data.get('business_name')) db.session.add(vendor) db.session.commit() else: vendor.update(business_name=form.data.get('business_name')) if multi: for opp in opportunity: _opp = Opportunity.query.get(int(opp)) if not _opp.is_public: db.session.rollback() form.errors['opportunities'] = ['That\'s not a valid choice.'] return False if _opp in vendor.opportunities: send_email = False else: vendor.opportunities.add(_opp) email_opportunities.append(_opp) else: if opportunity in vendor.opportunities: send_email = False else: vendor.opportunities.add(opportunity) email_opportunities.append(opportunity) if form.data.get('also_categories'): # TODO -- add support for categories pass db.session.commit() current_app.logger.info( 'OPPSIGNUP - Vendor has signed up for opportunities: EMAIL: {email} at BUSINESS: {bis_name} signed up for:\n' + 'OPPORTUNITY: {opportunities}'.format( email=form.data.get('email'), business_name=form.data.get('business_name'), opportunities=', '.join([ i.title.encode('ascii', 'ignore') for i in email_opportunities ]))) if send_email: Notification(to_email=vendor.email, from_email=current_app.config['BEACON_SENDER'], subject='Subscription confirmation from Beacon', html_template='beacon/emails/oppselected.html', txt_template='beacon/emails/oppselected.txt', opportunities=email_opportunities).send() return True