Esempio n. 1
0
 /**
  * @expectedException \Tbmt\ProvisionExceedMemberFeeException
  */
 public function testProvisionExceedMemberFreeException()
 {
     $marketingLeader = DbEntityHelper::createMember(null, ['type' => Member::TYPE_MARKETINGLEADER, 'LastName' => 'vl']);
     $marketingLeader->reload(self::$propelCon);
     $m1 = DbEntityHelper::createSignupMember($marketingLeader, true, ['lastName' => 'm1']);
     $m1->activity_setBonusLevel(\Tbmt\Config::get('member_fee', \Tbmt\TYPE_FLOAT, 100) + 10, self::$propelCon);
     $m1_3 = DbEntityHelper::createSignupMember($m1, true, ['lastName' => 'm1_3']);
 }
Esempio n. 2
0
 public function testReceivingChildrenOfDeletedFirstMemberWithDeepTree()
 {
     // NOTE: This tests what happen if my first advertising gets
     // deleted due to not paying fee.
     /* Setup
        ---------------------------------------------*/
     DbEntityHelper::setCon(self::$propelCon);
     $promoter1 = DbEntityHelper::createMember();
     $MYSELF = DbEntityHelper::createSignupMember($promoter1);
     $MYSELF_total = new TransactionTotalsAssertions($MYSELF, $this);
     $this->assertEquals($MYSELF->getFundsLevel(), Member::FUNDS_LEVEL1);
     /* Advertise 2 users
        ---------------------------------------------*/
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_LVL1);
     $franz = DbEntityHelper::createSignupMember($MYSELF);
     $WILL_NOT_PAY = DbEntityHelper::createSignupMember($MYSELF, false);
     /* WILL_NOT_PAY advertises 3 and these does either advertise a view
        ---------------------------------------------*/
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_LVL1);
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_LVL2, 4);
     DbEntityHelper::createSignupMember($WILL_NOT_PAY);
     DbEntityHelper::createSignupMember($WILL_NOT_PAY);
     DbEntityHelper::createSignupMember($WILL_NOT_PAY);
     $deep1 = DbEntityHelper::createSignupMember($WILL_NOT_PAY);
     $deep1_lazy = DbEntityHelper::createSignupMember($WILL_NOT_PAY, false);
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_INDIRECT, 2);
     $deep2 = DbEntityHelper::createSignupMember($deep1);
     DbEntityHelper::createSignupMember($deep1);
     DbEntityHelper::createSignupMember($deep1);
     DbEntityHelper::createSignupMember($deep1);
     $deep2_lazy = DbEntityHelper::createSignupMember($deep1, false);
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_INDIRECT, 2);
     $deep3 = DbEntityHelper::createSignupMember($deep2, false);
     DbEntityHelper::createSignupMember($deep2);
     $WILL_NOT_PAY->deleteAndUpdateTree(self::$propelCon);
     DbEntityHelper::fireReceivedMemberFee($deep1_lazy, time());
     DbEntityHelper::fireReceivedMemberFee($deep2_lazy, time());
     DbEntityHelper::fireReceivedMemberFee($deep3, time());
     // ---- assert - ME
     $MYSELF_total->assertTotals();
 }
Esempio n. 3
0
 public function testInvitationCanFreeFromFee()
 {
     // NOTE: This tests what happen if one of my third+ advertisings gets
     // deleted due to not paiing fee.
     /* Setup
        ---------------------------------------------*/
     DbEntityHelper::setCon(self::$propelCon);
     $marketingLeader = DbEntityHelper::createMember(null, ['type' => Member::TYPE_MARKETINGLEADER]);
     $marketingLeader->reload(self::$propelCon);
     /* Create invitation
        ---------------------------------------------*/
     $invitation = Invitation::create($marketingLeader, ['type' => Member::TYPE_ORGLEADER, 'free_signup' => 1], self::$propelCon);
     /* Create member with created invitation code
        ---------------------------------------------*/
     list($valid, $data, $referralMember, $invitation) = \Member::validateSignupForm(array_merge(self::$singupFormData, ['referral_member_num' => $marketingLeader->getNum(), 'invitation_code' => $invitation->getHash()]));
     $member = \Member::createFromSignup($data, $marketingLeader, $invitation, self::$propelCon);
     $member->reload(self::$propelCon);
     /* Assert proper member type
        ---------------------------------------------*/
     $this->assertEquals(Member::TYPE_ORGLEADER, $member->getType());
     $this->assertNotNull($member->getPaidDate());
 }
Esempio n. 4
0
 public function testSnowballModelLazyIncommingFeeExtensiv()
 {
     // NOTE: this is basically the exact same scenario as @see $this->testSnowballModel
     // with the only difference that the incomming of the member fee
     // happens lazy and in different order. Later advertised members does
     // pay earlier so that ReservedPaidEvents get created and triggered.
     /* Setup
        ---------------------------------------------*/
     $now = time();
     $promoter1 = DbEntityHelper::createMember();
     $MYSELF = DbEntityHelper::createSignupMember($promoter1);
     $MYSELF_total = new TransactionTotalsAssertions($MYSELF, $this);
     $this->assertEquals($MYSELF->getFundsLevel(), Member::FUNDS_LEVEL1);
     /* Advertise 2 users
        ---------------------------------------------*/
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_LVL1, 2);
     $far_l1_1 = DbEntityHelper::createSignupMember($MYSELF, false);
     $bea_l1_2 = DbEntityHelper::createSignupMember($MYSELF, false);
     /* Advertise 1 more user - chris
        ---------------------------------------------*/
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_LVL2);
     $CHRIS_l1_3 = DbEntityHelper::createSignupMember($MYSELF, false);
     $CHRIS_total = new TransactionTotalsAssertions($CHRIS_l1_3, $this);
     /* chris advertise 1 user - dean
        ---------------------------------------------*/
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_INDIRECT);
     $CHRIS_total->add(Transaction::REASON_ADVERTISED_LVL1);
     $DEAN_l2_1 = DbEntityHelper::createSignupMember($CHRIS_l1_3, false);
     /* chris advertise 1 user - emi
        ---------------------------------------------*/
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_INDIRECT);
     $CHRIS_total->add(Transaction::REASON_ADVERTISED_LVL1);
     $EMI_l2_2 = DbEntityHelper::createSignupMember($CHRIS_l1_3, false);
     /* dean advertise 1 user - franz
        ---------------------------------------------*/
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_INDIRECT);
     $FRANZ_l3_1 = DbEntityHelper::createSignupMember($DEAN_l2_1, false);
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_INDIRECT, 3);
     $anonym1 = DbEntityHelper::createSignupMember($DEAN_l2_1, false);
     $anonym2 = DbEntityHelper::createSignupMember($EMI_l2_2, false);
     $anonym3 = DbEntityHelper::createSignupMember($EMI_l2_2, false);
     $CHRIS_total->add(Transaction::REASON_ADVERTISED_LVL2);
     $CHRIS_total->add(Transaction::REASON_ADVERTISED_INDIRECT, 4);
     $ALF_l2_3 = DbEntityHelper::createSignupMember($CHRIS_l1_3, false);
     $GUST_l3_1 = DbEntityHelper::createSignupMember($ALF_l2_3, false);
     $anonym4 = DbEntityHelper::createSignupMember($ALF_l2_3, false);
     $anonym5 = DbEntityHelper::createSignupMember($GUST_l3_1, false);
     $anonym6 = DbEntityHelper::createSignupMember($GUST_l3_1, false);
     /* fee incomming in different order for all users
        ---------------------------------------------*/
     DbEntityHelper::fireReceivedMemberFee($anonym6, $now);
     DbEntityHelper::fireReceivedMemberFee($anonym5, $now);
     DbEntityHelper::fireReceivedMemberFee($anonym4, $now);
     DbEntityHelper::fireReceivedMemberFee($GUST_l3_1, $now);
     DbEntityHelper::fireReceivedMemberFee($anonym3, $now);
     DbEntityHelper::fireReceivedMemberFee($anonym2, $now);
     DbEntityHelper::fireReceivedMemberFee($anonym1, $now);
     DbEntityHelper::fireReceivedMemberFee($FRANZ_l3_1, $now);
     // the following order does matter. ALF has to be the third so that
     // MYSELF does not receive anynthing from his advertisings
     DbEntityHelper::fireReceivedMemberFee($DEAN_l2_1, $now);
     DbEntityHelper::fireReceivedMemberFee($EMI_l2_2, $now);
     DbEntityHelper::fireReceivedMemberFee($ALF_l2_3, $now);
     DbEntityHelper::fireReceivedMemberFee($bea_l1_2, $now);
     DbEntityHelper::fireReceivedMemberFee($far_l1_1, $now);
     // ---- assert - correct reserved paid events count
     $this->assertEquals(ReservedPaidEventQuery::create()->count(), 11);
     // ---- assert - ME got 10 since chris has not paid yet
     $MYSELF_total_before = new TransactionTotalsAssertions($MYSELF, $this);
     $MYSELF_total_before->add(Transaction::REASON_ADVERTISED_LVL1, 2);
     $MYSELF_total_before->assertTotals();
     // ---- assert - chris pais now as least. this trigger all remaining
     // reserved paid events
     DbEntityHelper::fireReceivedMemberFee($CHRIS_l1_3, $now);
     $this->assertEquals($MYSELF->getFundsLevel(), Member::FUNDS_LEVEL2);
     $this->assertEquals(ReservedPaidEventQuery::create()->count(), 0);
     // ---- assert - CHRIS - should be 90 euro
     $CHRIS_total->assertTotals();
     // ---- assert - ME
     $MYSELF_total->assertTotals();
 }
Esempio n. 5
0
 public function testFixRecursiveIndirectBonusSpreading()
 {
     $promoter1 = DbEntityHelper::createMember(null, ['LastName' => 'promoter1', 'FundsLevel' => \Member::FUNDS_LEVEL2]);
     $S1 = DbEntityHelper::createSignupMember($promoter1, true, ['lastName' => 'S1']);
     $S2 = DbEntityHelper::createSignupMember($S1, true, ['lastName' => 'S2']);
     $S3 = DbEntityHelper::createSignupMember($S2, true, ['lastName' => 'S3']);
     $S4 = DbEntityHelper::createSignupMember($S3, true, ['lastName' => 'S4']);
     // DbEntityHelper::createSignupMember($egal);
     $promoter1_total = new TransactionTotalsAssertions($promoter1, $this);
     $S1_total = new TransactionTotalsAssertions($S1, $this);
     $S2_total = new TransactionTotalsAssertions($S2, $this);
     $S3_total = new TransactionTotalsAssertions($S3, $this);
     $S4_total = new TransactionTotalsAssertions($S4, $this);
     // Zahlung s1
     $promoter1_total->add(Transaction::REASON_ADVERTISED_LVL2);
     // zahlung s2
     $promoter1_total->add(Transaction::REASON_ADVERTISED_INDIRECT);
     $S1_total->add(Transaction::REASON_ADVERTISED_LVL1);
     // zahlung s3
     $promoter1_total->add(Transaction::REASON_ADVERTISED_INDIRECT);
     $S2_total->add(Transaction::REASON_ADVERTISED_LVL1);
     // zahlung s4
     $promoter1_total->add(Transaction::REASON_ADVERTISED_INDIRECT);
     $S3_total->add(Transaction::REASON_ADVERTISED_LVL1);
     $promoter1_total->assertTotals();
     $S1_total->assertTotals();
     $S2_total->assertTotals();
     $S3_total->assertTotals();
 }
Esempio n. 6
0
 public static function setUpBonusMembers($doReset = true, $options = false)
 {
     if (!\MemberQuery::create()->findOneByNum(SystemStats::ACCOUNT_NUM_SYSTEM)) {
         \Tbmt\SystemSetup::setCon(self::$con);
         \Tbmt\SystemSetup::doSetup();
     }
     $options = array_merge(['IT' => true, 'VL' => true, 'OL' => true, 'PM' => true, 'VS2' => true, 'VS1' => true], $options ? $options : []);
     $currentParent = null;
     $currentBonusIds = '[]';
     /* it specialists
        ---------------------------------------------*/
     $IT_t = 0;
     $IT = null;
     if ($options['IT']) {
         if ($doReset === true || self::$it_member === null) {
             $IT_t = 0;
             $IT = self::$it_member = DbEntityHelper::createMember($currentParent, ['Type' => Member::TYPE_ITSPECIALIST, 'FundsLevel' => Member::FUNDS_LEVEL2]);
         } else {
             $IT = self::$it_member;
             $IT_t = self::$it_member->getOutstandingTotal()[DbEntityHelper::$currency];
         }
         $currentBonusIds = MemberBonusIds::populate($IT, '[]');
     }
     /* marketing leader
        ---------------------------------------------*/
     $VL_t = 0;
     $VL = null;
     if ($options['VL']) {
         $VL = DbEntityHelper::createMember($currentParent, ['Type' => Member::TYPE_MARKETINGLEADER, 'FundsLevel' => Member::FUNDS_LEVEL2, 'BonusIds' => $currentBonusIds]);
         $currentBonusIds = MemberBonusIds::populate($VL, $VL->getBonusIds());
         $currentParent = $VL;
     }
     /* org leader
        ---------------------------------------------*/
     $OL_t = 0;
     $OL = null;
     if ($options['OL']) {
         $OL = DbEntityHelper::createMember($currentParent, ['Type' => Member::TYPE_ORGLEADER, 'FundsLevel' => Member::FUNDS_LEVEL2, 'BonusIds' => $currentBonusIds]);
         $currentBonusIds = MemberBonusIds::populate($OL, $OL->getBonusIds());
         $currentParent = $OL;
     }
     /* promoter
        ---------------------------------------------*/
     $PM_t = 0;
     $PM = null;
     if ($options['PM']) {
         $IT_t += Transaction::getAmountForReason(Transaction::REASON_IT_BONUS);
         $VL_t += Transaction::getAmountForReason(Transaction::REASON_VL_BONUS);
         if (!$OL) {
             $OL_t =& $VL_t;
         }
         $OL_t += Transaction::getAmountForReason(Transaction::REASON_ADVERTISED_LVL2) + Transaction::getAmountForReason(Transaction::REASON_OL_BONUS) + Transaction::getAmountForReason(Transaction::REASON_PM_BONUS);
         // TODO question:
         // kriegt der ol in diesem fall 22 oder 21 euro ?
         // 22 weil der ja den bonus der promoters kriegt wenn er jemand
         // wirbt ohne das ein promoter dazwischen ist?
         if ($currentParent) {
             $PM = DbEntityHelper::createSignupMember($currentParent);
         } else {
             $PM = DbEntityHelper::createMember($currentParent, ['BonusIds' => $currentBonusIds]);
             $IT_t -= Transaction::getAmountForReason(Transaction::REASON_IT_BONUS);
             $VL_t -= Transaction::getAmountForReason(Transaction::REASON_VL_BONUS);
             $OL_t -= Transaction::getAmountForReason(Transaction::REASON_ADVERTISED_LVL2) + Transaction::getAmountForReason(Transaction::REASON_OL_BONUS) + Transaction::getAmountForReason(Transaction::REASON_PM_BONUS);
         }
         $PM->setType(Member::TYPE_PROMOTER)->setFundsLevel(Member::FUNDS_LEVEL2)->save(self::$con);
         $currentParent = $PM;
     }
     /* funds level 2
        ---------------------------------------------*/
     $VS2_t = 0;
     $VS2 = null;
     if ($options['VS2']) {
         $IT_t += Transaction::getAmountForReason(Transaction::REASON_IT_BONUS) * 3;
         $VL_t += Transaction::getAmountForReason(Transaction::REASON_VL_BONUS) * 3;
         if (!$OL) {
             $OL_t =& $VL_t;
         }
         $OL_t += Transaction::getAmountForReason(Transaction::REASON_OL_BONUS) * 3;
         if (!$PM) {
             $PM_t =& $OL_t;
         }
         $PM_t += Transaction::getAmountForReason(Transaction::REASON_ADVERTISED_LVL2) + Transaction::getAmountForReason(Transaction::REASON_PM_BONUS) + 2 * (Transaction::getAmountForReason(Transaction::REASON_PM_BONUS) + Transaction::getAmountForReason(Transaction::REASON_ADVERTISED_INDIRECT));
         $VS2_t += 2 * Transaction::getAmountForReason(Transaction::REASON_ADVERTISED_LVL1);
         $VS2 = DbEntityHelper::createSignupMember($currentParent);
         DbEntityHelper::createSignupMember($VS2);
         DbEntityHelper::createSignupMember($VS2);
         $currentParent = $VS2;
     }
     /* funds level 1
        ---------------------------------------------*/
     $VS1_t = 0;
     $VS1 = null;
     if ($options['VS1']) {
         $IT_t += Transaction::getAmountForReason(Transaction::REASON_IT_BONUS);
         $VL_t += Transaction::getAmountForReason(Transaction::REASON_VL_BONUS);
         if (!$OL) {
             $OL_t =& $VL_t;
         }
         $OL_t += Transaction::getAmountForReason(Transaction::REASON_OL_BONUS);
         if (!$PM) {
             $PM_t =& $OL_t;
         }
         $PM_t += Transaction::getAmountForReason(Transaction::REASON_PM_BONUS);
         if (!$VS2) {
             $VS2_t =& $PM_t;
         }
         $VS2_t += Transaction::getAmountForReason(Transaction::REASON_ADVERTISED_LVL2);
         $VS1 = DbEntityHelper::createSignupMember($currentParent);
     }
     return [[$IT, $VL, $OL, $PM, $VS2, $VS1], [$IT_t, $VL_t, $OL_t, $PM_t, $VS2_t, $VS1_t]];
 }
Esempio n. 7
0
 public function testDirectorInviteDirectorWillReceiveSameParent()
 {
     $sylvheim = Member::getByNum(\SystemStats::ACCOUNT_SYLVHEIM);
     $marketingLeader = DbEntityHelper::createMember($sylvheim, ['Type' => Member::TYPE_MARKETINGLEADER]);
     $marketingLeader->reload(self::$propelCon);
     $marketingLeader2 = DbEntityHelper::createMemberWithInvitation($marketingLeader, Member::TYPE_MARKETINGLEADER, self::$singupFormData);
     /* Assert proper member type
        ---------------------------------------------*/
     $this->assertEquals(Member::TYPE_MARKETINGLEADER, $marketingLeader->getType());
     $this->assertEquals(Member::TYPE_MARKETINGLEADER, $marketingLeader2->getType());
     $this->assertEquals($marketingLeader->getReferrerId(), $marketingLeader2->getReferrerId());
 }
 public function testSingleDistributionModel()
 {
     /* Setup
        ---------------------------------------------*/
     $systemAccount = SystemStats::getSystemAccount();
     $systemTransfer = new TransactionTotalsAssertions($systemAccount, $this);
     $promoter1 = DbEntityHelper::createMember();
     $MYSELF = DbEntityHelper::createSignupMember($promoter1);
     $this->assertEquals($MYSELF->getFundsLevel(), Member::FUNDS_LEVEL1);
     /* Advertise 2 users
        ---------------------------------------------*/
     $far_l1_1 = DbEntityHelper::createSignupMember($MYSELF);
     $bea_l1_2 = DbEntityHelper::createSignupMember($MYSELF);
     // Funds level never changes
     $this->assertEquals($MYSELF->getFundsLevel(), Member::FUNDS_LEVEL1);
     $MYSELF_total = new TransactionTotalsAssertions($MYSELF, $this);
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_LVL1, 2);
     $MYSELF_total->assertTotals();
     /* Advertise 1 more user - chris
        ---------------------------------------------*/
     $CHRIS_l1_3 = DbEntityHelper::createSignupMember($MYSELF);
     // ---- assert - ME
     $MYSELF_total->add(Transaction::REASON_ADVERTISED_LVL1);
     $MYSELF_total->assertTotals();
     /* chris advertise 1 user - dean
        ---------------------------------------------*/
     $DEAN_l2_1 = DbEntityHelper::createSignupMember($CHRIS_l1_3);
     // ---- assert - CHRIS
     $CHRIS_transfer = DbEntityHelper::getCurrentTransferBundle($CHRIS_l1_3);
     $CHRIS_total = new TransactionTotalsAssertions($CHRIS_l1_3, $this);
     $CHRIS_total->add(Transaction::REASON_ADVERTISED_LVL1);
     $CHRIS_total->assertTotals();
     // ---- assert - ME
     // unchanged
     $MYSELF_total->assertTotals();
     /* chris advertise 1 user - emi
        ---------------------------------------------*/
     $EMI_l2_2 = DbEntityHelper::createSignupMember($CHRIS_l1_3);
     // ---- assert - CHRIS
     $CHRIS_total->add(Transaction::REASON_ADVERTISED_LVL1);
     $CHRIS_total->assertTotals();
     $this->assertEquals($CHRIS_l1_3->getFundsLevel(), Member::FUNDS_LEVEL1);
     // ---- assert - ME
     // unchanged
     $MYSELF_total->assertTotals();
     /* dean advertise 1 user - franz
        ---------------------------------------------*/
     $FRANZ_l3_1 = DbEntityHelper::createSignupMember($DEAN_l2_1);
     // ---- assert - CHRIS - remain at 10 euro
     $CHRIS_total->assertTotals();
     // ---- assert - ME
     // unchanged
     $MYSELF_total->assertTotals();
     DbEntityHelper::createSignupMember($DEAN_l2_1);
     DbEntityHelper::createSignupMember($EMI_l2_2);
     DbEntityHelper::createSignupMember($EMI_l2_2);
     $CHRIS_total->add(Transaction::REASON_ADVERTISED_LVL1);
     $ALF_l2_3 = DbEntityHelper::createSignupMember($CHRIS_l1_3);
     $GUST_l3_1 = DbEntityHelper::createSignupMember($ALF_l2_3);
     DbEntityHelper::createSignupMember($ALF_l2_3);
     // ---- assert - CHRIS - at 60 euro
     $CHRIS_total->assertTotals();
     // ---- assert - ME
     // unchanged
     $MYSELF_total->assertTotals();
     DbEntityHelper::createSignupMember($GUST_l3_1);
     DbEntityHelper::createSignupMember($GUST_l3_1);
     // ---- assert - CHRIS - at 90 euro
     // unchanged
     $CHRIS_total->assertTotals();
     /* if anyone advertised more than 2 user i dont get anything from the third on
        ---------------------------------------------*/
     DbEntityHelper::createSignupMember($CHRIS_l1_3);
     DbEntityHelper::createSignupMember($CHRIS_l1_3);
     DbEntityHelper::createSignupMember($CHRIS_l1_3);
     DbEntityHelper::createSignupMember($GUST_l3_1);
     DbEntityHelper::createSignupMember($GUST_l3_1);
     DbEntityHelper::createSignupMember($GUST_l3_1);
     DbEntityHelper::createSignupMember($ALF_l2_3);
     DbEntityHelper::createSignupMember($ALF_l2_3);
     DbEntityHelper::createSignupMember($ALF_l2_3);
     DbEntityHelper::createSignupMember($EMI_l2_2);
     DbEntityHelper::createSignupMember($EMI_l2_2);
     /* as well, i dont get anything but 5euro from my first advertisings
        ---------------------------------------------*/
     DbEntityHelper::createSignupMember($bea_l1_2);
     DbEntityHelper::createSignupMember($bea_l1_2);
     DbEntityHelper::createSignupMember($bea_l1_2);
     // ---- assert - MYSELF
     $MYSELF_total->assertTotals();
 }
 public function testSubPromoterBonusSpreading()
 {
     // Deprecated
     $this->assertTrue(true);
     return;
     /**
      *       PM
      *       1$
      *
      * VL -  S_PM - Neues Mitglied
      * 1$ -  1$  - 5$
      * ------------------------------------------*/
     /* Setup
        ---------------------------------------------*/
     DbEntityHelper::setCon(self::$propelCon);
     $marketingLeader = DbEntityHelper::createMember(null, ['Type' => Member::TYPE_MARKETINGLEADER, 'FundsLevel' => Member::FUNDS_LEVEL2]);
     $marketingLeader->reload(self::$propelCon);
     $mLeaderTransfer = new TransactionTotalsAssertions($marketingLeader, $this);
     $promoter = DbEntityHelper::createSignupMember($marketingLeader);
     $mLeaderTransfer->add(Transaction::REASON_ADVERTISED_LVL2);
     $mLeaderTransfer->add(Transaction::REASON_VL_BONUS);
     $mLeaderTransfer->add(Transaction::REASON_OL_BONUS);
     $mLeaderTransfer->add(Transaction::REASON_PM_BONUS);
     /* Create invitation
        ---------------------------------------------*/
     $invitation = Invitation::create($marketingLeader, ['type' => Member::TYPE_SUB_PROMOTER, 'free_signup' => 1, 'promoter_num' => $promoter->getNum(), 'promoter_id' => $promoter->getId()], self::$propelCon);
     /* Create member with created invitation code
        ---------------------------------------------*/
     list($valid, $data, $referralMember, $invitation) = \Member::validateSignupForm(array_merge(self::$singupFormData, ['referral_member_num' => $marketingLeader->getNum(), 'invitation_code' => $invitation->getHash()]));
     $subPromoter = \Member::createFromSignup($data, $marketingLeader, $invitation, self::$propelCon);
     $subPromoter->reload(self::$propelCon);
     /* Sub promoter recruits anyone
        ---------------------------------------------*/
     DbEntityHelper::createSignupMember($subPromoter);
     $subPromoterTransfer = new TransactionTotalsAssertions($subPromoter, $this);
     $promoterTransfer = new TransactionTotalsAssertions($promoter, $this);
     $mLeaderTransfer->add(Transaction::REASON_VL_BONUS);
     $mLeaderTransfer->add(Transaction::REASON_ADVERTISED_INDIRECT);
     $promoterTransfer->add(Transaction::REASON_SUB_PM_REF_BONUS);
     $subPromoterTransfer->add(Transaction::REASON_SUB_PM_BONUS);
     $subPromoterTransfer->add(Transaction::REASON_ADVERTISED_LVL1);
     $mLeaderTransfer->assertTotals();
     $promoterTransfer->assertTotals();
     $subPromoterTransfer->assertTotals();
 }