Skip to content
This repository has been archived by the owner on Sep 3, 2020. It is now read-only.

Issue #236 Workflow for ADM notification #273

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions modules/core/server/controllers/core.server.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ exports.renderIndex = function (req, res) {
linkedIn : req.user.linkedIn,
isPublicProfile : req.user.isPublicProfile,
isAutoAdd : req.user.isAutoAdd,
capabilityDetails : req.user.capabilityDetails,
capabilitySkills : req.user.capabilitySkills
capabilityDetails : req.user.capabilityDetails,
capabilitySkills : req.user.capabilitySkills,
admEmail : req.user.admEmail,
dfsEmail : req.user.dfsEmail,
bfsEmail : req.user.bfsEmail
};
}
var features = config.features.split ('-');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{#markdown this}}
![BC Dev Exchange](https://bcdevexchange.org/modules/core/client/img/logo/new-logo-220px.png)

### Dear {{data.username}},

Opportunity {{data.name}} {{data._id}} was submitted.

---

Details:

*Unique ID: {{data._id}}

*Associated RFP control: {{data.rfp}}

*Posting date: {{data.postingDate}}

*Value of opportunity: High

*Required Skills: {{data.requiredSkills}}

*Closing date: {{data.closingDate}}

### [Agree](some/url/agree)
### [Disagree](some/url/disagree)
{{/markdown}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Opportunity {{ data.name }} has been submitted.
27 changes: 27 additions & 0 deletions modules/opportunities/client/config/opportunities.client.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,33 @@
})
// -------------------------------------------------------------------------
//
// submit an opportunity
//
// -------------------------------------------------------------------------
.state('opportunityadmin.submitcwu', {
url: '/:opportunityId/submitcwu',
templateUrl: '/modules/opportunities/client/views/cwu-opportunity-submit.html',
controller: 'OpportunitySubmitController',
controllerAs: 'vm',
resolve: {
opportunity: function ($stateParams, OpportunitiesService) {
return OpportunitiesService.get({
opportunityId: $stateParams.opportunityId
}).$promise;
},
submitting: function () { return true; }
},
data: {
roles: ['admin', 'gov'],
pageTitle: 'Submit Opportunity: {{ opportunity.name }}'
},
ncyBreadcrumb: {
label: 'Submit Opportunity',
parent: 'opportunities.list'
}
})
// -------------------------------------------------------------------------
//
// edit a opportunity
//
// -------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
//
// -------------------------------------------------------------------------
vm.errorFields = OpportunitiesCommon.publishStatus (vm.opportunity);
vm.canPublish = (vm.errorFields.length === 0);
vm.canSubmit = (vm.errorFields.length === 0);
// -------------------------------------------------------------------------
//
// issue a request for membership
Expand Down Expand Up @@ -367,14 +367,14 @@
// publish or un publish the opportunity
//
// -------------------------------------------------------------------------
vm.publish = function (opportunity, state) {
var publishedState = opportunity.isPublished;
vm.submit = function (opportunity, state) {
var publishedState = opportunity.isPublished;
var t = state ? 'Published' : 'Unpublished';

var savemeSeymour = true;
var promise = Promise.resolve ();
if (state) {
var question = 'When you publish this opportunity, we\'ll notify all our subscribed users. Are you sure you\'ve got it just the way you want it?';
var question = 'When you submit this opportunity, we\'ll notify all our subscribed users. Are you sure you\'ve got it just the way you want it?';
promise = ask.yesNo (question).then (function (result) {
savemeSeymour = result;
});
Expand Down Expand Up @@ -514,7 +514,7 @@
//
// -------------------------------------------------------------------------
vm.errorFields = OpportunitiesCommon.publishStatus (vm.opportunity);
vm.canPublish = vm.errorFields > 0;
vm.canSubmit = vm.errorFields > 0;
//
// set up the dropdown amounts for code with us earnings
//
Expand Down Expand Up @@ -688,6 +688,12 @@
}
}
//
// if status was Pending, set to Draft. happens on first save
//
if (vm.opportunity.status === 'Pending') {
vm.opportunity.status = 'Draft';
}
//
// ensure that there is a trailing '/' on the github field
//
if (vm.opportunity.github && vm.opportunity.github.substr (-1, 1) !== '/') vm.opportunity.github += '/';
Expand Down Expand Up @@ -762,5 +768,52 @@
vm.displayHelp[field] = ! vm.displayHelp[field];
};
})
// =========================================================================
//
// Controller for submitting opportunities
//
// =========================================================================
.controller('OpportunitySubmitController', function ($scope, $state, Authentication, OpportunitiesService, UsersService, Notification, opportunity, $stateParams) {
var vm = this;
vm.opportunity = opportunity;
vm.user = Authentication.user;

vm.submit = function(isValid) {
if (!isValid) {
// console.log (vm.opportunityForm);
$scope.$broadcast('show-errors-check-validity', 'vm.opportunitySubmitForm');
Notification.error ({
message : 'There are errors on the page, please review your work and re-save',
title : '<i class=\'glyphicon glyphicon-remove\'></i> Errors on Page'
});
return false;
}

// TODO could be one API call
// might improve performance

// Set opportunity status to Pending
vm.opportunity.status = 'Pending';
var opportunityPromise = vm.opportunity.createOrUpdate();

// Save email addresses to user profile, ng-model sets them
var userPromise = UsersService.update(user).$promise;

// Send email to ADM
var body = {
recipient: vm.user.admEmail,
opportunityId: vm.opportunity._id,
template: 'opportunity-notification',
};
var admNotificationPromise = OpportunitiesService.opportunityNotification(body).$promise;

// Resolve all promises
Promise.all([opportunityPromise, userPromise, admNotificationPromise]).then(function() {
// success and redirect
$state.go('opportunities.viewcwu', {opportunityId:vm.opportunity.code});
});

};
})
;
}());
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
url: '/api/my/opportunities',
isArray: true
},
opportunityNotification: {
method: 'POST',
url: '/api/opportunity/opportunityNotification'
},
publish: {
method: 'GET',
url :'/api/opportunities/publish/:opportunityId'
Expand Down
78 changes: 78 additions & 0 deletions modules/opportunities/client/views/cwu-opportunity-submit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<section class="edit-form-background" role="main">

<form id="opportunitySubmitForm" warn-on-exit name="vm.opportunitySubmitForm" class="form" ng-submit="vm.submit(vm.opportunitySubmitForm.$valid)" novalidate>

<div class="container edit-form">

<div class="edit-form-tab-content">
<fieldset>

<form-display
class="col-sm-12"
x-options='{
"title":"Opportunity",
"name":"opportunity",
"help":"This is the opportunity"
}'>
<span>
{{vm.opportunity.name}}
</span>
</form-display>

<form-input
class="col-sm-12"
type="email"
ng-model="vm.user.admEmail"
x-form="vm.opportunitySubmitForm"
x-options='{
"title":"ADM&#39;s Email",
"help":"Enter the Assistant Deputy Minister&#39;s email.",
"id":"admEmail",
"name":"admEmail",
"placeholder":"[email protected]"
}'>
</form-input>

<form-input
class="col-sm-12"
type="email"
ng-model="vm.user.dfsEmail"
x-form="vm.opportunitySubmitForm"
x-options='{
"title":"DFS&#39;s Email",
"help":"Enter the Divisonal Financial Staff&#39;s email.",
"id":"dfsEmail",
"name":"dfsEmail",
"placeholder":"[email protected]"
}'>
</form-input>

<form-input
class="col-sm-12"
type="email"
ng-model="vm.user.bfsEmail"
x-form="vm.opportunitySubmitForm"
x-options='{
"title":"BFS&#39;s Email",
"help":"Enter the Branch Financial Staff&#39;s email.",
"id":"bfsEmail",
"name":"bfsEmail",
"placeholder":"[email protected]"
}'>
</form-input>
</fieldset>
</div>

<div class="edit-form-footer">
<div class="row">
<div class="col-xs-12">
<button type="submit" href="javascript:void(0);" class="btn btn-primary pull-right"><i class="fa fa-save"></i> Submit</button>
</div>
</div>
</div>

</div>

</form>

</section>
12 changes: 7 additions & 5 deletions modules/opportunities/client/views/cwu-opportunity-view.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,25 @@ <h4 class="opp-detail" class="card-title" style="font-size: 17px; padding-top: 6
</div>

<div class="container">
<!-- // Admin View / if opportunity is in DRAFT and INCOMPLETE // -->
<div class="row" ng-if="!vm.canPublish && vm.canEdit">
<!-- // Admin View / if opportunity is in DRAFT/PENDING and INCOMPLETE // -->
<div class="row" ng-if="!vm.canSubmit && vm.canEdit && (vm.opportunity.status === 'Draft' || vm.opportunity.status === 'Pending')">
<div class="col-xs-12">
<div class="alert alert-important">
<span class="strong"><i class="fa fa-exclamation-triangle"></i> Your opportunity is missing stuff!</span> Before you can publish, you'll need to define these things:
<span class="strong"><i class="fa fa-exclamation-triangle"></i> Your opportunity is missing stuff!</span> Before you can submit, you'll need to define these things:
<ul style="text-align: left;"><li ng-repeat="fname in vm.errorFields">{{fname}}</li></ul>
</div>
</div>
</div>


<!-- // Admin Controls / if opportunity is in DRAFT and COMPLETE // -->
<div class="row" ng-if="vm.canEdit && !vm.opportunity.isPublished">
<div class="row" ng-if="vm.canEdit">
<div class="col-xs-12">
<div class="pull-right" role="group">
<button type="button" class="btn btn-sm btn-text-only" ng-if="vm.canEdit" ui-sref="opportunityadmin.editcwu({opportunityId:vm.opportunity.code})"><i class="fa fa-pencil"></i> EDIT</button>
<a href="javascript:void(0);" ng-if="vm.canPublish && vm.opportunity.project.isPublished && vm.canEdit && !vm.opportunity.isPublished" class="btn btn-sm btn-primary" ng-click="vm.publish(vm.opportunity, true)"><i class="fa fa-bullhorn"></i> PUBLISH</a>

<button type="button" class="btn btn-sm btn-primary" ng-if="vm.canSubmit && vm.opportunity.project.isPublished && vm.canEdit && vm.opportunity.status === 'Draft'" ui-sref="opportunityadmin.submitcwu({opportunityId:vm.opportunity.code})"><i class="fa fa-bullhorn"></i> SUBMIT</button>

</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,33 @@ exports.create = function(req, res) {
});
};

// -------------------------------------------------------------------------
//
// Sends email to ADM when opportunity is submitted
//
// -------------------------------------------------------------------------
exports.opportunityNotification = function (req, res) {
console.log(req.body.opportunityId);
Opportunity.findById (req.body.opportunityId)
.exec (function (err, opportunity) {
var data = setNotificationData (opportunity);
data.username = '';
data.useremail = req.body.recipient;
data._id = opportunity._id;
data.name = opportunity.name;
data.rfp = opportunity.proposal;
data.postingDate = data.dateStart;
data.requiredSkills = opportunity.skills.join(', ');
data.closingDate = opportunity.dateDeadline
Notifications.notifyUserAdHoc(req.body.template, data);
res.status(200);
});

//TODO better error handling

res.status(500);
};

// -------------------------------------------------------------------------
//
// this just takes the already queried object and pass it back
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ var OpportunitySchema = new Schema({
views : {type: Number, default: 1},
program : {type: Schema.ObjectId, ref: 'Program', default: null, required: 'Program cannot be blank'},
project : {type: Schema.ObjectId, ref: 'Project', default: null, required: 'Project cannot be blank'},
status : {type: String, default:'Pending', enum:['Pending', 'Assigned', 'In Progress', 'Completed']},
status : {type: String, default:'Pending', enum:['Draft', 'Pending', 'Assigned', 'In Progress', 'Completed']},
onsite : {type: String, default:'mixed', enum:['mixed', 'onsite', 'offsite']},
location : {type: String, default:''},
isPublished : {type: Boolean, default: false},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ module.exports = function(app) {
app.route('/api/my/opportunities').all(opportunitiesPolicy.isAllowed)
.get(opportunities.my);

app.route('/api/opportunity/opportunityNotification').post(opportunities.opportunityNotification);

//
// opportunities for project
//
Expand Down Expand Up @@ -64,7 +66,6 @@ module.exports = function(app) {
app.route('/api/request/opportunity/:opportunityId')
.get(opportunities.request)


// Finish by binding the Opportunity middleware
app.param('opportunityId', opportunities.opportunityByID);
};
21 changes: 21 additions & 0 deletions modules/users/server/models/user.server.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,27 @@ var UserSchema = new Schema({
lowercase: true,
trim: true
},
admEmail : {
type: String,
lowercase: true,
trim: true,
default: '',
validate: [validateLocalStrategyEmail, 'Please fill a valid email address']
},
dfsEmail : {
type: String,
lowercase: true,
trim: true,
default: '',
validate: [validateLocalStrategyEmail, 'Please fill a valid email address']
},
bfsEmail : {
type: String,
lowercase: true,
trim: true,
default: '',
validate: [validateLocalStrategyEmail, 'Please fill a valid email address']
},
orgsAdmin : {type:[{type:Schema.ObjectId, ref:'Org'}], default:[]},
orgsMember : {type:[{type:Schema.ObjectId, ref:'Org'}], default:[]},
orgsPending : {type:[{type:Schema.ObjectId, ref:'Org'}], default:[]},
Expand Down