Skip to content

Commit

Permalink
Merge pull request #145 from alphamanuscript/master
Browse files Browse the repository at this point in the history
v0.5.1
  • Loading branch information
habbes authored Oct 4, 2020
2 parents 64977c7 + cfdae68 commit d5082d0
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 6 deletions.
1 change: 1 addition & 0 deletions server/src/core/distribution/distribution-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class DonationDistributions implements DonationDistributionService {

const results: DonationDistributionResults = {
_id: generateId(),
onlyVettedBeneficiaries,
startedAt,
finishedAt,
distributions
Expand Down
9 changes: 4 additions & 5 deletions server/src/core/distribution/run-distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export async function runDonationDistribution(db: Db, args: DonationDistribution
donors = await computeDonorsBalances(db, Array.from(new Set(donorIds)));
}

const plan = createDistributionPlan(beneficiaries, donors);
const plan = createDistributionPlan(beneficiaries, donors, onlyVettedBeneficiaries);
const result = await executeDistributionPlan(users, plan.transfers);
return result;
}
Expand All @@ -77,7 +77,6 @@ export async function runDonationDistribution(db: Db, args: DonationDistribution
*/
export async function findEligibleBeneficiaries(db: Db, periodLimit: number, periodLength: number, filter: any | BeneficiaryFilter = {}): Promise<EligibleBeneficiary[]> {
const periodMilliseconds = periodLength * 24 * 3600 * 1000;
const projectDonors: number = !filter.isVetted ? 1 : 0;
const result = db.collection(USERS_COLL).aggregate<EligibleBeneficiary>([
{
$match: { ...filter, beneficiaryStatus: 'verified', roles: 'beneficiary' },
Expand Down Expand Up @@ -126,7 +125,7 @@ export async function findEligibleBeneficiaries(db: Db, periodLimit: number, per
$match: { totalReceived: { $lt: periodLimit } }
},
{
$project: { _id: 1, donors: projectDonors, totalReceived: 1, remaining: { $subtract: [periodLimit, '$totalReceived']} }
$project: { _id: 1, donors: 1, totalReceived: 1, remaining: { $subtract: [periodLimit, '$totalReceived']} }
}
]);

Expand Down Expand Up @@ -206,7 +205,7 @@ export async function computeDonorsBalances(db: Db, donors?: string[]): Promise<
return result.toArray();
}

export function createDistributionPlan(beneficiaries: EligibleBeneficiary[], donors: DonorBalance[]): CreateDistributionPlanResult {
export function createDistributionPlan(beneficiaries: EligibleBeneficiary[], donors: DonorBalance[], onlyVettedBeneficiaries: boolean = false): CreateDistributionPlanResult {
const transfers: DistributionPlanTransfer[] = [];

const beneficiariesSummaries = beneficiaries.reduce((acc, b) => ({
Expand All @@ -220,7 +219,7 @@ export function createDistributionPlan(beneficiaries: EligibleBeneficiary[], don
}), {} as DistributionPlanDonorsSummaries);

beneficiaries.forEach((beneficiary) => {
const beneficiaryDonors = beneficiary.donors ? beneficiary.donors : donors;
const beneficiaryDonors = onlyVettedBeneficiaries ? donors : beneficiary.donors;
beneficiaryDonors.forEach((donor: string | DonorBalance) => {
const beneficiarySummary = beneficiariesSummaries[beneficiary._id];
const donorSummary = typeof donor === "object" ? donorsSummaries[donor._id] : donorsSummaries[donor];
Expand Down
23 changes: 23 additions & 0 deletions server/src/core/distribution/tests/distribution-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,34 @@ describe('DonationDistributionService tests', () => {
}
]);

expect(savedData.onlyVettedBeneficiaries).not.toBe(true);

expect(lock.lock).toHaveBeenCalledTimes(1);
expect(lock.unlock).toHaveBeenCalledTimes(1);
await lock.ensureUnlocked();
});

describe('Vetted distribution', () => {
test('should distribute only to vetted beneficiaries, from any donor', async () => {
const distributionService = createDistributionService();
const res = await distributionService.distributeDonations(true);

const savedData: DonationDistributionResults = await dbUtils.getCollection(COLL).findOne({ _id: res._id });
const { distributions } = savedData;
// beneficiary3 should receive 630
expect(distributions.filter(d => d.beneficiary === 'beneficiary3').reduce((a, b) => a + b.amount, 0)).toEqual(630);
// beneficiary4 should receive 2000
expect(distributions.filter(d => d.beneficiary === 'beneficiary4').reduce((a, b) => a + b.amount, 0)).toEqual(2000);
// beneficiary5 should receive 2000
expect(distributions.filter(d => d.beneficiary === 'beneficiary5').reduce((a, b) => a + b.amount, 0)).toEqual(2000);

// confirm the total is 4630 to ensure no other beneficiary was included in the distribution
expect(distributions.reduce((a, b) => a + b.amount, 0)).toEqual(4630);

expect(savedData.onlyVettedBeneficiaries).toBe(true);
});
});

test('should not run if distribution lock is locked', async () => {
const lock = systemLockService.distribution();
const lock2 = systemLockService.distribution();
Expand Down
5 changes: 4 additions & 1 deletion server/src/core/distribution/tests/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,26 @@ export const users = [
},
{
_id: 'beneficiary3',
isVetted: true,
beneficiaryStatus: 'verified',
roles: ['beneficiary'],
donors: ['donor1', 'donor2']
},
// this beneficiary has no associated transactions
{
_id: 'beneficiary4',
isVetted: true,
beneficiaryStatus: 'verified',
roles: ['beneficiary'],
donors: ['donor3']
},
// this beneficiary has neither donors nor transactions
{
_id: 'beneficiary5',
isVetted: true,
beneficiaryStatus: 'verified',
roles: ['beneficiary'],
donors: []
donors: <string[]>[]
}
];

Expand Down
1 change: 1 addition & 0 deletions server/src/core/distribution/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface DonationDistributionEvent {

export interface DonationDistributionResults {
_id: string;
onlyVettedBeneficiaries?: boolean;
startedAt: Date;
finishedAt: Date;
distributions: DonationDistributionEvent[];
Expand Down

0 comments on commit d5082d0

Please sign in to comment.