Bonus Program Bug Fixed for Descendants Program

This commit is contained in:
Luis Fernando Molina committed 2021-07-20 14:42:54 +02:00
1 parent 78b43f95c7
commit 476a1798f6
5 files changed
+133 -124

No files matched your search

@@ -12,12 +12,12 @@
"referralProgram": {
"type": "Referral Program",
"name": "New Referral Program",
"config": "{\n \"percentage\": 60\n}",
"config": "{\n \"percentage\": 2}",
"project": "Governance",
"userReferrers": [
{
"type": "User Referrer",
"name": "Jeremy",
"name": "Luis-Fernando-Molina",
"config": "{}",
"project": "Governance",
"id": "0aa9db01-7605-4a51-abd9-e233de6721d6",
@@ -43,8 +43,8 @@
},
"referenceParent": {
"type": "User Profile",
"name": "Jeremy",
"id": "759e9012-c995-47ed-92f1-7d204bf2b58e"
"name": "Luis-Fernando-Molina",
"id": "148911b3-b2f3-44fb-8cb4-017991789132"
}
}
}
@@ -18,12 +18,12 @@
"referralProgram": {
"type": "Referral Program",
"name": "New Referral Program",
"config": "{\n \"percentage\": 80\n}",
"config": "{\n \"percentage\": 0\n}",
"project": "Governance",
"userReferrers": [
{
"type": "User Referrer",
"name": "Julian-Molina",
"name": "Jeremy",
"config": "{}",
"project": "Governance",
"id": "fb0a076c-b0a8-4f16-9a47-10a3f3489a0a",
@@ -49,8 +49,8 @@
},
"referenceParent": {
"type": "User Profile",
"name": "Julian-Molina",
"id": "1fd95e41-4b22-48d5-be3a-904c37afcb11"
"name": "Jeremy",
"id": "759e9012-c995-47ed-92f1-7d204bf2b58e"
}
}
}
@@ -3936,7 +3936,7 @@
"userDelegates": [
{
"type": "User Delegate",
"name": "Julian-Molina",
"name": "",
"config": "{}",
"project": "Governance",
"id": "d684a95b-fc8a-4545-8db5-601128a924cf",
@@ -3959,11 +3959,6 @@
},
"uiObject": {
"isRunning": false
},
"referenceParent": {
"type": "User Profile",
"name": "Julian-Molina",
"id": "1fd95e41-4b22-48d5-be3a-904c37afcb11"
}
}
},
@@ -9,15 +9,6 @@ function newGovernanceFunctionLibraryReferralProgram() {
pools,
userProfiles
) {
UI.projects.governance.utilities.bonusProgram.run(
pools,
userProfiles,
"referralProgram",
"Referrals-Bonus",
"Referral Program"
)
UI.projects.governance.utilities.decendentProgram.run(
pools,
userProfiles,
@@ -28,5 +19,13 @@ function newGovernanceFunctionLibraryReferralProgram() {
"userReferrers",
"User Referrer"
)
UI.projects.governance.utilities.bonusProgram.run(
pools,
userProfiles,
"referralProgram",
"Referrals-Bonus",
"Referral Program"
)
}
}
@@ -15,7 +15,7 @@ function newGovernanceUtilitiesBonusProgram() {
let programPoolTokenReward
/*
In order to be able to calculate the share of the Program Pool for each User Profile,
we need to accumulate all the Participation Power that each User Profile at their Program
we need to accumulate all the Bonus Power that each User Profile at their Program
node has, because with that Power is that each Program node gets a share of the pool.
*/
let accumulatedProgramPower = 0
@@ -108,13 +108,12 @@ function newGovernanceUtilitiesBonusProgram() {
function distributeProgram(programNode) {
if (programNode === undefined || programNode.payload === undefined) { return }
/*
Here we will convert Token Power into Participation Power.
As per system rules Participation Powar = tokensPower
To get into the Bonus Sub-Program we will use the usedPower previously calculated by the Program.
That means that only token power effectively used at the program (not just directed to it) will
be used to compute Bonuses.
*/
let programPower = programNode.payload.tokenPower
programNode.payload[programPropertyName].bonusPower = programPower
accumulatedProgramPower = accumulatedProgramPower + programPower
programNode.payload[programPropertyName].bonusPower = programNode.payload[programPropertyName].usedPower | 0
accumulatedProgramPower = accumulatedProgramPower + programNode.payload[programPropertyName].bonusPower
}
function calculateProgram(programNode) {
@@ -135,7 +134,7 @@ function newGovernanceUtilitiesBonusProgram() {
if (totalPowerRewardRatio < 1) { totalPowerRewardRatio = 1 }
if (programNode.tokensBonus === undefined || programNode.tokensBonus.payload === undefined) {
programNode.payload.uiObject.setErrorMessage("Tokens Bonus Node is needed in order for this Program to get Tokens from the Program Pool.")
programNode.payload.uiObject.setErrorMessage("Tokens Bonus Node is needed in order for this Program to get Tokens from the Bonus Program Pool.")
return
}
programNode.payload[programPropertyName].bonus.tokens = programNode.payload[programPropertyName].bonusPower * totalPowerRewardRatio
@@ -1,4 +1,9 @@
function newGovernanceUtilitiesDecendentProgram() {
/*
This Utility Module is intended to be used by all programs that have the
concept of Decendents, and when the program requires to compute recursively
all decendents.
*/
let thisObject = {
run: run
}
@@ -91,6 +96,7 @@ function newGovernanceUtilitiesDecendentProgram() {
outgoingPower: 0,
ownPower: 0,
incomingPower: 0,
usedPower: 0,
awarded: {
tokens: 0,
percentage: 0
@@ -102,6 +108,7 @@ function newGovernanceUtilitiesDecendentProgram() {
node.payload[programPropertyName].outgoingPower = 0
node.payload[programPropertyName].ownPower = 0
node.payload[programPropertyName].incomingPower = 0
node.payload[programPropertyName].usedPower = 0
node.payload[programPropertyName].awarded = {
tokens: 0,
percentage: 0
@@ -193,109 +200,118 @@ function newGovernanceUtilitiesDecendentProgram() {
*/
programNode.payload[programPropertyName].ownPower = programPower
distributeProgramPower(programNode, programPower, count)
}
distributeProgramPower(programNode, programNode, programPower, count)
function distributeProgramPower(
node,
programPower,
count,
percentage
) {
if (node === undefined) { return }
if (node.payload === undefined) { return }
if (node.payload[programPropertyName] === undefined) { return }
function distributeProgramPower(
currentProgramNode,
node,
programPower,
count,
percentage
) {
if (node === undefined) { return }
if (node.payload === undefined) { return }
if (node.payload[programPropertyName] === undefined) { return }
switch (node.type) {
case programNodeType: {
/*
This is the point where we increase to our local count of descendents whatever it comes
at the count parameters. If we are processing the User Profile of this Program
then we will add zero, otherwise, 1.
*/
node.payload[programPropertyName].count = node.payload[programPropertyName].count + count
/*
The outgoingPower of this node will be accumulating all the programPower flowing
through it, no matter from where it comes.
*/
node.payload[programPropertyName].outgoingPower = node.payload[programPropertyName].outgoingPower + programPower
/*
We need to adjust the balance that holds the accumulationt of all incomingPower of all Program
nodes. To do this we will substratct the current incomingPower, bacause it is going to be recalculated
inmediatelly after this, and then we will add it again after the recalcualtion.
*/
accumulatedIncomingProgramPower = accumulatedIncomingProgramPower - node.payload[programPropertyName].incomingPower
/*
At any point in time, the incomingPower will be equal to the total of the outgoingPower minus
the ownPower. This is like this because the outgoingPower is the accumulation of all the
power flow that is leaving this node, which includes the ownPower. That means that if we
substract the ownPower, we will have the accumulation of all the incomingPower, which
means all the power coming from other User Profiles referencing this one.
*/
node.payload[programPropertyName].incomingPower = node.payload[programPropertyName].outgoingPower - node.payload[programPropertyName].ownPower
/*
Now that we have the incomingPower calculated again, we can add it again to the balance of all the incomingPower
of all Program nodes.
*/
accumulatedIncomingProgramPower = accumulatedIncomingProgramPower + node.payload[programPropertyName].incomingPower
if (node[usersArrayPropertyName] !== undefined) {
switch (node.type) {
case programNodeType: {
/*
Before distributing the program power, we will calculate how the power
is going to be switched between all nodes. The first pass is about
scanning all sibling nodes to see which ones have a percentage defined
at their config, and check that all percentages don't add more than 100.
This is the point where we increase to our local count of descendents whatever it comes
at the count parameters. If we are processing the User Profile of this Program
then we will add zero, otherwise, 1.
*/
let totalPercentage = 0
let totalNodesWithoutPercentage = 0
for (let i = 0; i < node[usersArrayPropertyName].length; i++) {
let childNode = node[usersArrayPropertyName][i]
let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage')
if (percentage !== undefined && isNaN(percentage) !== true) {
totalPercentage = totalPercentage + percentage
} else {
totalNodesWithoutPercentage++
node.payload[programPropertyName].count = node.payload[programPropertyName].count + count
/*
The outgoingPower of this node will be accumulating all the programPower flowing
through it, no matter from where it comes.
*/
node.payload[programPropertyName].outgoingPower = node.payload[programPropertyName].outgoingPower + programPower
/*
We need to adjust the balance that holds the accumulationt of all incomingPower of all Program
nodes. To do this we will substratct the current incomingPower, bacause it is going to be recalculated
inmediatelly after this, and then we will add it again after the recalcualtion.
*/
accumulatedIncomingProgramPower = accumulatedIncomingProgramPower - node.payload[programPropertyName].incomingPower
/*
At any point in time, the incomingPower will be equal to the total of the outgoingPower minus
the ownPower. This is like this because the outgoingPower is the accumulation of all the
power flow that is leaving this node, which includes the ownPower. That means that if we
substract the ownPower, we will have the accumulation of all the incomingPower, which
means all the power coming from other User Profiles referencing this one.
*/
node.payload[programPropertyName].incomingPower = node.payload[programPropertyName].outgoingPower - node.payload[programPropertyName].ownPower
/*
Now that we have the incomingPower calculated again, we can add it again to the balance of all the incomingPower
of all Program nodes.
*/
accumulatedIncomingProgramPower = accumulatedIncomingProgramPower + node.payload[programPropertyName].incomingPower
if (node[usersArrayPropertyName] !== undefined) {
/*
Before distributing the program power, we will calculate how the power
is going to be switched between all nodes. The first pass is about
scanning all sibling nodes to see which ones have a percentage defined
at their config, and check that all percentages don't add more than 100.
*/
let totalPercentage = 0
let totalNodesWithoutPercentage = 0
for (let i = 0; i < node[usersArrayPropertyName].length; i++) {
let childNode = node[usersArrayPropertyName][i]
let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage')
if (percentage !== undefined && isNaN(percentage) !== true) {
totalPercentage = totalPercentage + percentage
} else {
totalNodesWithoutPercentage++
}
}
if (totalPercentage > 100) {
node.payload.uiObject.setErrorMessage('Program Power Switching Error. Total Percentage of children nodes is grater that 100.')
return
}
let defaultPercentage = 0
if (totalNodesWithoutPercentage > 0) {
defaultPercentage = (100 - totalPercentage) / totalNodesWithoutPercentage
}
/*
Here we do the actual distribution.
*/
for (let i = 0; i < node[usersArrayPropertyName].length; i++) {
let childNode = node[usersArrayPropertyName][i]
let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage')
if (percentage === undefined || isNaN(percentage) === true) {
percentage = defaultPercentage
}
distributeProgramPower(currentProgramNode, childNode, programPower * percentage / 100, 0, percentage)
}
}
if (totalPercentage > 100) {
node.payload.uiObject.setErrorMessage('Program Power Switching Error. Total Percentage of children nodes is grater that 100.')
return
}
let defaultPercentage = 0
if (totalNodesWithoutPercentage > 0) {
defaultPercentage = (100 - totalPercentage) / totalNodesWithoutPercentage
}
/*
Here we do the actual distribution.
*/
for (let i = 0; i < node[usersArrayPropertyName].length; i++) {
let childNode = node[usersArrayPropertyName][i]
let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage')
if (percentage === undefined || isNaN(percentage) === true) {
percentage = defaultPercentage
}
distributeProgramPower(childNode, programPower * percentage / 100, 0, percentage)
}
return
}
return
}
case userNodeType: {
node.payload[programPropertyName].outgoingPower = node.payload.parentNode.payload[programPropertyName].outgoingPower * percentage / 100
case userNodeType: {
let previousOutgoing = node.payload[programPropertyName].outgoingPower
node.payload[programPropertyName].outgoingPower = node.payload.parentNode.payload[programPropertyName].outgoingPower * percentage / 100
drawUserNode(node, percentage)
if (node.payload.referenceParent !== undefined) {
distributeProgramPower(node.payload.referenceParent, programPower / 10, 0)
drawUserNode(node, percentage)
if (node.payload.referenceParent !== undefined) {
/*
We want to accumulate the usedPower, but to keep the right balance, everytime we add to it the outgoingPower
we need to substract the previous one, since this migth be executed at every user profile and also recurisvely.
*/
currentProgramNode.payload[programPropertyName].usedPower = currentProgramNode.payload[programPropertyName].usedPower - previousOutgoing
currentProgramNode.payload[programPropertyName].usedPower = currentProgramNode.payload[programPropertyName].usedPower + node.payload[programPropertyName].outgoingPower
distributeProgramPower(currentProgramNode, node.payload.referenceParent, programPower / 10, 0)
}
return
}
return
}
case 'User Profile': {
let program = UI.projects.governance.utilities.validations.onlyOneProgram(node, programNodeType)
if (program === undefined) { return }
if (program.payload === undefined) { return }
if (program.payload[programPropertyName].isActive === false) { return }
case 'User Profile': {
let program = UI.projects.governance.utilities.validations.onlyOneProgram(node, programNodeType)
if (program === undefined) { return }
if (program.payload === undefined) { return }
if (program.payload[programPropertyName].isActive === false) { return }
distributeProgramPower(program, programPower, 0)
return
distributeProgramPower(program, program, programPower, 0)
return
}
}
}
}