function repeatAction() { if (!$this->invoice) { throw new Am_Exception_InputError('No invoice found, cannot repeat'); } if ($this->invoice->isPaid()) { throw new Am_Exception_InputError("Invoice #{$id} is already paid"); } $found = false; foreach ($this->view->paysystems as $ps) { if ($ps['paysys_id'] == $this->getFiltered('paysys_id')) { $found = true; break; } } if (!$found) { return $this->indexAction(); } $this->invoice->updateQuick('paysys_id', $this->getFiltered('paysys_id')); if ($err = $this->invoice->validate()) { throw new Am_Exception_InputError($err[0]); } $payProcess = new Am_Paysystem_PayProcessMediator($this, $this->invoice); $result = $payProcess->process(); if ($result->isFailure()) { $this->view->error = $result->getErrorMessages(); return $this->indexAction(); } }
public function prorateInvoice(Invoice $invoice, EcheckRecord $echeck, Am_Paysystem_Result $result, $date) { /** @todo use "reattempt" config **/ $reattempt = array_filter($this->getConfig('reattempt', array())); sort($reattempt); if (!$reattempt) { $invoice->updateQuick('status', Invoice::RECURRING_FAILED); $invoice->updateQuick('rebill_date', null); return; } $first_failure = $invoice->data()->get(self::FIRST_REBILL_FAILURE); if (!$first_failure) { $invoice->data()->set(self::FIRST_REBILL_FAILURE, $date)->update(); $first_failure = $date; } $days_diff = (strtotime($date) - strtotime($first_failure)) / (24 * 3600); foreach ($reattempt as $day) { if ($day > $days_diff) { break; } } // we have found next rebill date to jump if ($day <= $days_diff) { // Several rebilling attempts failed already. // change status to RECURRING_FAILED; $invoice->updateQuick('status', Invoice::RECURRING_FAILED); $invoice->updateQuick('rebill_date', null); return; } $invoice->updateQuick('rebill_date', date('Y-m-d', strtotime($first_failure . " +{$day} days"))); $tr = new Am_Paysystem_Transaction_Manual($this); if ($invoice->getAccessExpire() < $invoice->rebill_date) { $invoice->extendAccessPeriod($invoice->rebill_date); } }
/** * Process invoice and insert necessary commissions for it * * External code should guarantee that this method with $payment = null will be called * only once for each user for First user invoice */ public function processPayment(Invoice $invoice, InvoicePayment $payment = null) { $aff_id = $invoice->aff_id; /* @var $coupon Coupon */ try { if (!$aff_id && ($coupon = $invoice->getCoupon())) { // try to find affiliate by coupon $aff_id = $coupon->aff_id ? $coupon->aff_id : $coupon->getBatch()->aff_id; } } catch (Am_Exception_Db_NotFound $e) { //coupon not found } if (empty($aff_id)) { $aff_id = $invoice->getUser()->aff_id; } if ($aff_id && empty($invoice->aff_id)) { // set aff_id to invoice for quick access next time $invoice->updateQuick('aff_id', $aff_id); } // run event to get plugins chance choose another affiliate $event = new Am_Event(Bootstrap_Aff::AFF_FIND_AFFILIATE, array('invoice' => $invoice, 'payment' => $payment)); $event->setReturn($aff_id); $this->getDi()->hook->call($event); $aff_id = $event->getReturn(); if (empty($aff_id)) { return; } // no affiliate id registered if ($aff_id == $invoice->getUser()->pk()) { return; } //strange situation // load affiliate and continue $aff = $this->getDi()->userTable->load($aff_id, false); if (!$aff || !$aff->is_affiliate) { return; } // affiliate not found $user = $invoice->getUser(); if (!$user->aff_id) { $user->aff_id = $aff->pk(); $user->aff_added = sqlTime('now'); $user->data()->set('aff-source', 'invoice-' . $invoice->pk()); $user->save(); } // try to load other tier affiliate $aff_tier = $aff; $aff_tiers = array(); $aff_tiers_exists = array($aff->pk()); for ($tier = 1; $tier <= $this->getMaxTier(); $tier++) { if (!$aff_tier->aff_id || $aff_tier->pk() == $invoice->getUser()->pk()) { break; } $aff_tier = $this->getDi()->userTable->load($aff_tier->aff_id, false); if (!$aff_tier || !$aff_tier->is_affiliate || $aff_tier->pk() == $invoice->getUser()->pk() || in_array($aff_tier->pk(), $aff_tiers_exists)) { //already in chain break; } $aff_tiers[$tier] = $aff_tier; $aff_tiers_exists[] = $aff_tier->pk(); } $isFirst = !$payment || $payment->isFirst(); //to define price field $paymentNumber = is_null($payment) ? 0 : $invoice->getPaymentsCount(); if (!$payment) { $tax = 0; } else { $tax = $this->getDi()->config->get('aff.commission_include_tax', false) ? 0 : doubleval($payment->tax); } $amount = $payment ? $payment->amount - $tax : 0; $date = $payment ? $payment->dattm : 'now'; // now calculate commissions $items = is_null($payment) ? array_slice($invoice->getItems(), 0, 1) : $invoice->getItems(); foreach ($items as $item) { //we do not calculate commission for free items in invoice $prefix = $isFirst ? 'first' : 'second'; if (!is_null($payment) && !(double) $item->get("{$prefix}_total")) { continue; } $comm = $this->getDi()->affCommissionRecord; $comm->date = sqlDate($date); $comm->record_type = AffCommission::COMMISSION; $comm->invoice_id = $invoice->invoice_id; $comm->invoice_item_id = $item->invoice_item_id; $comm->invoice_payment_id = $payment ? $payment->pk() : null; $comm->receipt_id = $payment ? $payment->receipt_id : null; $comm->product_id = $item->item_id; $comm->is_first = $paymentNumber <= 1; $comm->_setPayment($payment); $comm->_setInvoice($invoice); $comm_tier = clone $comm; $rules = array(); $topay_this = $topay = $this->calculate($invoice, $item, $aff, $paymentNumber, 0, $amount, $date, $rules); if ($topay > 0) { $comm->aff_id = $aff->pk(); $comm->amount = $topay; $comm->tier = 0; $comm->_setAff($aff); $comm->insert(); $comm->setCommissionRules(array_map(create_function('$el', 'return $el->pk();'), $rules)); } foreach ($aff_tiers as $tier => $aff_tier) { $rules = array(); $topay_this = $this->calculate($invoice, $item, $aff_tier, $paymentNumber, $tier, $topay_this, $date, $rules); if ($topay_this > 0) { $comm_this = clone $comm_tier; $comm_this->aff_id = $aff_tier->pk(); $comm_this->amount = $topay_this; $comm_this->tier = $tier; $comm_this->_setAff($aff_tier); $comm_this->insert(); $comm_this->setCommissionRules(array_map(create_function('$el', 'return $el->pk();'), $rules)); } } } }
public function prorateInvoice(Invoice $invoice, CcRecord $cc, Am_Paysystem_Result $result, $date) { /** @todo use "reattempt" config **/ $reattempt = array_filter($this->getConfig('reattempt')); sort($reattempt); if (!$reattempt) { return; } $first_failure = $invoice->data()->get(self::FIRST_REBILL_FAILURE); if (!$first_failure) { $invoice->data()->set(self::FIRST_REBILL_FAILURE, $date)->update(); $first_failure = $date; } $days_diff = (strtotime($date) - strtotime($first_failure)) / (24 * 3600); foreach ($reattempt as $day) { if ($day > $days_diff) { break; } } // we have found next rebill date to jump if (!$day) { return; } $invoice->updateQuick('rebill_date', date('Y-m-d', strtotime($first_failure) + $day * 24 * 3600)); $tr = new Am_Paysystem_Transaction_Manual($this); if ($invoice->getAccessExpire() < $invoice->rebill_date) { $invoice->extendAccessPeriod($invoice->rebill_date); } }