Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 04352e2

Browse files
committed
Copilot payment support
1 parent 24511d3 commit 04352e2

21 files changed

+1029
-9
lines changed

TCXSequenceDiagrams.tcuml

53.4 KB
Binary file not shown.

src/config.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ module.exports = {
1515
MONGODB_URI: process.env.MONGODB_URI || 'mongodb://localhost:27017/topcoderx',
1616
SESSION_SECRET: process.env.SESSION_SECRET || 'kjsdfkj34857',
1717
// Github and gitlab client id and secret
18-
GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID || '',
19-
GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET || '',
20-
GITLAB_CLIENT_ID: process.env.GITLAB_CLIENT_ID || '',
21-
GITLAB_CLIENT_SECRET: process.env.GITLAB_CLIENT_SECRET || '',
18+
GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID || 'ae39bea2a2a23f1dd032',
19+
GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET || 'f31dd2da12015f60372a5312a40a06b517a88702',
20+
GITLAB_CLIENT_ID: process.env.GITLAB_CLIENT_ID || 'af4c1ea3d12783e55470a6604c169b2cdc03734c7e3969f7f4336325f6e0e6b4',
21+
GITLAB_CLIENT_SECRET: process.env.GITLAB_CLIENT_SECRET || '8906a8e924df81ddadd12b37ee98767cfba3084ca3c9d52a5753412da8d9879e',
2222

2323
// used as base to construct various URLs
2424
WEBSITE: process.env.WEBSITE || 'http://topcoderx.topcoder-dev.com',
@@ -30,9 +30,10 @@ module.exports = {
3030
ssl: {
3131
cert: process.env.KAFKA_CLIENT_CERT || fs.readFileSync('./kafka_client.cer'), // eslint-disable-line no-sync
3232
key: process.env.KAFKA_CLIENT_CERT_KEY || fs.readFileSync('./kafka_client.key'), // eslint-disable-line no-sync
33+
passphrase: 'secret', // NOTE:* This configuration specifies the private key passphrase used while creating it.
3334
},
3435
},
35-
HOOK_BASE_URL: process.env.HOOK_BASE_URL || 'http://x.topcoder-dev.com',
36+
HOOK_BASE_URL: process.env.HOOK_BASE_URL || 'http://topcoderx.topcoder-dev.com',
3637
TOPCODER_ENV: process.env.TOPCODER_ENV || 'dev',
3738
LABELS: process.env.LABELS || [{ name: 'Open for pickup', color: '428BCA' }, { name: 'Assigned', color: '004E00' }, { name: 'Ready for review', color: 'D1D100' }, { name: 'Paid', color: '7F8C8D' }, { name: 'Feedback', color: 'FF0000' }, { name: 'Fix accepted', color: '69D100' }],
3839
ALLOWED_TOPCODER_ROLES: process.env.ALLOWED_TOPCODER_ROLES || ['administrator', 'admin', 'connect manager', 'connect admin', 'copilot', 'connect copilot'],

src/controllers/PaymentController.js

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright (c) 2018 TopCoder, Inc. All rights reserved.
3+
*/
4+
5+
/**
6+
* This controller exposes payment endpoints.
7+
*
8+
* @author kevinkid
9+
* @version 1.0
10+
*/
11+
const helper = require('../common/helper');
12+
const PaymentService = require('../services/PaymentService');
13+
14+
/**
15+
* update payments status
16+
* @param {Object} req the request
17+
* @param {Object} res the response
18+
* @returns {Promise} fetch payment updates execution
19+
*/
20+
async function updateAll(req) {
21+
return await PaymentService.updateAll(req.currentUser);
22+
}
23+
24+
/**
25+
* get all the payment for the current copilot
26+
* @param {Object} req the request
27+
* @param {Object} res the response
28+
* @returns {Object} the result
29+
*/
30+
async function getAll(req) {
31+
const payments = await PaymentService.getAll(req.query);
32+
const active = [];
33+
const closed = [];
34+
35+
payments.forEach(function (payment) {
36+
if (payment.closed === "true") {
37+
closed.push(payment);
38+
} else {
39+
active.push(payment);
40+
}
41+
});
42+
return { activePayments: active, closedPayments: closed };
43+
}
44+
45+
/**
46+
* create payment
47+
* @param {Object} req the request
48+
* @param {Object} res the response
49+
* @returns {Object} the result
50+
*/
51+
async function create(req) {
52+
return await PaymentService.create(req.currentUser, req.body.payment);
53+
}
54+
55+
/**
56+
* update payment item
57+
* @param {Object} req the request
58+
* @param {Object} res the response
59+
* @returns {Object} the result
60+
*/
61+
async function update(req) {
62+
return await PaymentService.update(req.currentUser, req.body.payment);
63+
}
64+
65+
/**
66+
* remove payment item
67+
* @param {Object} req the request
68+
* @param {Object} res the response
69+
* @returns {Object} the result
70+
*/
71+
async function remove(req) {
72+
return await PaymentService.remove(req.params.id, req.currentUser);
73+
}
74+
75+
76+
module.exports = {
77+
getAll,
78+
create,
79+
update,
80+
remove,
81+
updateAll
82+
};
83+
84+
helper.buildController(module.exports);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
'use strict';
2+
3+
angular.module('topcoderX')
4+
.controller('AddPaymentController', ['$scope', '$log', '$state', 'PaymentService', 'ProjectService', '$filter', '$rootScope', '$timeout', 'Alert',
5+
function ($scope, $log, $state, PaymentService, ProjectService, $filter, $rootScope, $timeout, Alert) {
6+
// below logic is trying to identify whether we are editing a payment
7+
$scope.editing = true;
8+
$scope.projects = [];
9+
$scope.payment = {
10+
project: null,
11+
amount: null,
12+
description: '',
13+
challenge: '',
14+
};
15+
if ($rootScope.payment) {
16+
$scope.title = 'Edit a Payment';
17+
$scope.payment = $rootScope.payment;
18+
$scope.payment.id = $rootScope.payment.id;
19+
$scope.editing = true;
20+
} else {
21+
$scope.title = 'Add a Payment';
22+
$scope.editing = false;
23+
}
24+
25+
// get topcoderx projects
26+
$scope.getProjects = function () {
27+
ProjectService.getProjects().then(function (response) {
28+
$scope.projects = response.data;
29+
}).catch(function (error) {
30+
_handleError({
31+
data:
32+
{ error: error, message: 'There are not projects in Topcoder-X. Please create a project first.' }
33+
});
34+
});
35+
};
36+
37+
$scope.getProjects();
38+
39+
// handle error output
40+
function _handleError(error, defualtMsg) {
41+
const errMsg = error.data ? error.data.message : defualtMsg;
42+
Alert(errMsg, $scope);
43+
}
44+
45+
// create/update payment item
46+
$scope.save = function () {
47+
if (!$scope.editing) {
48+
PaymentService.create($scope.payment).then(function (res) {
49+
$log.info(res);
50+
$state.go('app.copilotPayments');
51+
}).catch(function () {
52+
Alert.error('Error Creating Payment', $scope);
53+
});
54+
}
55+
if ($scope.editing) {
56+
PaymentService.update({
57+
id: $scope.payment.id,
58+
project: $scope.payment.project,
59+
amount: $scope.payment.amount,
60+
description: $scope.payment.description,
61+
challenge: $scope.payment.challenge,
62+
closed: $scope.payment.closed
63+
}).then(function (res) {
64+
$timeout(function () {
65+
$log.info(res);
66+
$rootScope.payment = null;
67+
$state.go('app.copilotPayments');
68+
}, 6000);
69+
}).catch(function () {
70+
Alert.error('Error Updating Payment', $scope);
71+
});
72+
}
73+
};
74+
}
75+
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2018 TopCoder, Inc. All rights reserved.
3+
*
4+
* This is a service to access the backend api.
5+
*/
6+
'use strict';
7+
8+
angular.module('topcoderX')
9+
.factory('PaymentServices', ['$http', 'Helper', function ($http, Helper) {
10+
var baseUrl = Helper.baseUrl;
11+
var service = {};
12+
13+
14+
/**
15+
* get copilot payment items
16+
*
17+
*/
18+
service.getAll = function (query) {
19+
return $http.get(baseUrl + '/api/v1/payments/' + query).then(function (response) {
20+
return response;
21+
});
22+
};
23+
24+
/**
25+
* create a new payment item
26+
*
27+
*/
28+
service.create = function (bodyParam) {
29+
return $http.post(baseUrl + '/api/v1/payments/', { payment: bodyParam }).then(function (response) {
30+
return response;
31+
});
32+
};
33+
34+
/**
35+
* update pre-existing payment item
36+
*
37+
*/
38+
service.update = function (bodyParam) {
39+
return $http.put(baseUrl + '/api/v1/payments/', { payment: bodyParam }).then(function (response) {
40+
return response;
41+
});
42+
};
43+
44+
/**
45+
* remove payment item
46+
*
47+
*/
48+
service.delete = function (id) {
49+
return $http.delete(baseUrl + '/api/v1/payments/' + (id || '')).then(function (response) {
50+
return response;
51+
});
52+
};
53+
54+
return service;
55+
}]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<div ng-controller="AddPaymentController">
2+
<div class="col-md-10 col-md-offset-1" ng-include src="'components/alert/alert.html'"></div>
3+
<div class="row wrapper border-bottom white-bg page-heading">
4+
<div class="col-lg-4">
5+
<h2>{{title}}</h2>
6+
</div>
7+
</div>
8+
9+
<div class="wrapper wrapper-content animated fadeInRight">
10+
<div class="row">
11+
<div class="col-lg-12">
12+
<div class="text-center m-t-lg">
13+
<form name="paymentForm">
14+
<label class="form-label">Project:</label>
15+
<select ng-model="payment.project" class="form-control" required>
16+
<option ng-repeat="project in projects" value={{project.id}}>{{project.title}}</option>
17+
</select>
18+
<span ng-show="paymentForm.payment.project.$touched && paymentForm.payment.project.$invalid">The payment Project is required.</span>
19+
<br />
20+
<label class="form-label">Amount:</label>
21+
<input class="form-control" type="number" ng-model="payment.amount" required/>
22+
<span ng-show="paymentForm.payment.amount.$touched && paymentForm.payment.amount.$invalid">The payment Amount is required.</span>
23+
<br />
24+
<label class="form-label">Desciption:</label>
25+
<input class="form-control" type="text" ng-model="payment.description" required/>
26+
<span ng-show="paymentForm.payment.description.$touched && paymentForm.payment.description.$invalid">The payment Description is required.</span>
27+
<br />
28+
<label class="form-label">Challenge:</label>
29+
<input class="form-control" type="number" ng-model="payment.challenge" required/>
30+
<span ng-show="paymentForm.payment.challenge.$touched && paymentForm.payment.challenge.$invalid">The payment Challenge is required.</span>
31+
<br />
32+
<br />
33+
<button type="submit" class="with-button btn btn-sm btn-info" ng-click="paymentForm.$valid && save()">
34+
<strong>
35+
Save
36+
</strong>
37+
</button>
38+
</form>
39+
</div>
40+
</div>
41+
</div>
42+
</div>
43+
</div>
44+
45+
46+
47+

src/front/src/app/app.js

+15
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,23 @@ angular.module('topcoderX', [
128128
templateUrl: 'app/members/member.html',
129129
controller: 'MemberController',
130130
controllerAs: 'vm',
131+
})
132+
.state('app.copilotPayments', {
133+
url: '/copilot-payments',
134+
templateUrl: 'app/copilot-payments/copilot-payments.html',
135+
controller: 'CopilotPaymentsController',
136+
controllerAs: 'vm',
137+
resolve: { auth: authenticate }
138+
})
139+
.state('app.addPayment', {
140+
url: '/add-payment',
141+
templateUrl: 'app/add-payment/add-payment.html',
142+
controller: 'AddPaymentController',
143+
controllerAs: 'vm',
144+
resolve: { auth: authenticate }
131145
});
132146

147+
133148
$urlRouterProvider.otherwise('/app/main');
134149
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|blob):/);
135150
}]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2018 TopCoder, Inc. All rights reserved.
3+
*
4+
* This is a service to access the backend api.
5+
*/
6+
'use strict';
7+
8+
angular.module('topcoderX')
9+
.factory('PaymentService', ['$http', 'Helper', function ($http, Helper) {
10+
var baseUrl = Helper.baseUrl;
11+
var service = {};
12+
13+
/**
14+
* updates payment status
15+
*
16+
*/
17+
service.updateAll = function () {
18+
return $http.post(baseUrl + '/api/v1/payments/updates/').then(function (response) {
19+
return response;
20+
});
21+
};
22+
23+
/**
24+
* get copilot payment items
25+
*
26+
*/
27+
service.getAll = function (query) {
28+
return $http.get(baseUrl + '/api/v1/payments?sortBy=' + query).then(function (response) {
29+
return response;
30+
});
31+
};
32+
33+
/**
34+
* create a new payment item
35+
*
36+
*/
37+
service.create = function (bodyParam) {
38+
return $http.post(baseUrl + '/api/v1/payments/', { payment: bodyParam }).then(function (response) {
39+
return response;
40+
});
41+
};
42+
43+
/**
44+
* update pre-existing payment item
45+
*
46+
*/
47+
service.update = function (bodyParam) {
48+
return $http.put(baseUrl + '/api/v1/payments/', { payment: bodyParam }).then(function (response) {
49+
return response;
50+
});
51+
};
52+
53+
/**
54+
* remove payment item
55+
*
56+
*/
57+
service.delete = function (id) {
58+
return $http.delete(baseUrl + '/api/v1/payments/' + (id || '')).then(function (response) {
59+
return response.data;
60+
});
61+
};
62+
63+
return service;
64+
}]);

0 commit comments

Comments
 (0)