public function calculate(Invoice $invoice, InvoiceItem $item, User $aff, $paymentNumber = 0, $tier = 0, $paymentAmount = 0.0, $paymentDate = 'now', &$matchedRules = array()) { // take aff.commission_days in account for 1-tier only if ($tier == 0 && ($commissionDays = $this->getDi()->config->get('aff.commission_days'))) { $signupDays = $this->getDi()->time - strtotime($invoice->getUser()->aff_added ? $invoice->getUser()->aff_added : $invoice->getUser()->added); $signupDays = intval($signupDays / (3600 * 24)); // to days if ($commissionDays < $signupDays) { return; } // no commission for this case, affiliate<->user relation is expired } $multi = 1.0; $isFirst = $paymentNumber <= 1; $prefix = $isFirst && (double) $item->first_total ? 'first' : 'second'; if ($tier == 0) { if ($invoice->get("{$prefix}_total") == 0) { $paidForItem = 0; } else { $paidForItem = $paymentAmount * $item->get("{$prefix}_total") / $invoice->get("{$prefix}_total"); } } else { // for higher tier just take amount paid to previous tier $paidForItem = $paymentAmount; } $paidForItem = $tier ? $paidForItem : $paidForItem / $invoice->base_currency_multi; foreach ($this->findRules($invoice, $item, $aff, $paymentNumber, $tier, $paymentDate) as $rule) { array_push($matchedRules, $rule); // Second tier commission have to be calculated as percent from First tier commission. if ($tier > 0) { return moneyRound($rule->first_payment_c * $paidForItem / 100); } if ($rule->type == AffCommissionRule::TYPE_MULTI) { $multi *= $rule->multi; } else { if ($paidForItem == 0) { // free signup? if ($paymentNumber == 0 && $rule->free_signup_c) { return moneyRound($multi * $rule->free_signup_c); } } elseif ($isFirst) { // first payment if ($rule->first_payment_t == '%') { return moneyRound($multi * $rule->first_payment_c * $paidForItem / 100); } else { return moneyRound($multi * $rule->first_payment_c); } } else { // recurring payment if ($rule->recurring_t == '%') { return moneyRound($multi * $rule->recurring_c * $paidForItem / 100); } else { return moneyRound($multi * $rule->recurring_c); } } } } }
public function calculate(Invoice $invoice, InvoiceItem $item, User $aff, $paymentNumber = 0, $tier = 0, $paymentAmount = 0.0, $paymentDate = 'now') { // take aff.commission_days in account for 1-tier only if ($tier == 0 && ($commissionDays = $this->getDi()->config->get('aff.commission_days'))) { $signupDays = $this->getDi()->time - strtotime($invoice->getUser()->added); $signupDays = intval($signupDays / 3600 * 24); // to days if ($commissionDays < $signupDays) { return; } // no commission for this case, affiliate<->user relation is expired // however, the relation still works for 2-level commissions } $multi = 1.0; $prefix = $paymentNumber == 0 ? 'first' : 'second'; if ($tier == 0) { if ($invoice->get("{$prefix}_total") == 0) { $paidForItem = 0; } else { $paidForItem = $paymentAmount * $item->get("{$prefix}_total") / $invoice->get("{$prefix}_total"); } } else { // for higher tier just take amount paid to previous tier $paidForItem = $paymentAmount; } foreach ($this->findRules($invoice, $item, $aff, $paymentNumber, $tier, $paymentDate) as $rule) { if ($rule->type == AffCommissionRule::TYPE_MULTI) { $multi *= $rule->multi; } else { if ($paidForItem == 0) { // free signup? if ($paymentNumber == 0 && $rule->free_signup_c) { return moneyRound($multi * $rule->free_signup_c); } } elseif ($paymentNumber == 0) { // first payment if ($rule->first_payment_t == '%') { return moneyRound($multi * $rule->first_payment_c * $paidForItem / 100); } else { return moneyRound($multi * $rule->first_payment_c); } } else { // first payment if ($rule->recurring_t == '%') { return moneyRound($multi * $rule->recurring_c * $paidForItem / 100); } else { return moneyRound($multi * $rule->recurring_c); } } } } }
/** * @param InvoiceItem $old * @param InvoiceItem $new * @return float old_price / new_price */ function compareDayCost(InvoiceItem $old, InvoiceItem $new) { // calculate difference in money // if both products have second_period we can compare prices $k = 1.0; foreach (array('second_', 'first_') as $k) { $period_o = $old->get($k . 'period'); $period_n = $new->get($k . 'period'); $price_o = (double) $old->get($k . 'price'); $price_n = (double) $new->get($k . 'price'); if (!$price_n || !$price_o || !$period_o || !$period_n) { continue; } if ($period_o == $period_n) { return round($price_o / $price_n, 4); } // else we need to recalculate both periods to days $po = new Am_Period($period_o); $pn = new Am_Period($period_n); $days_o = strtotime($po->addTo('2012-04-01') . ' 00:00:00') - strtotime('2012-04-01 00:00:00'); $days_o = intval($days_o / (3600 * 24)); $days_n = strtotime($pn->addTo('2012-04-01') . ' 00:00:00') - strtotime('2012-04-01 00:00:00'); $days_n = intval($days_n / (3600 * 24)); $price_o /= $days_o; $price_n /= $days_n; return round($price_o / $price_n, 4); } }