/** * Calculate first payment for upgraded/downgraded subscription * calculated move from $item -> $to billling plan * @return Invoice */ function createUpgradeInvoice(Invoice $exInvoice, InvoiceItem $item) { $row = array('user_id' => $exInvoice->user_id, 'paysys_id' => $exInvoice->paysys_id, 'currency' => $exInvoice->currency, 'tax_type' => $exInvoice->tax_rate, 'tax_rate' => $exInvoice->tax_type, 'tax_title' => $exInvoice->tax_title, 'is_confirmed' => 1); $invoice = $this->getDi()->invoiceTable->createRecord($row); $to = $this->getToPlan(); if (!$to) { throw new Am_Exception_Configuration("Upgrade: cannot load [to] plan {$this->to_billing_plan_id}"); } $pr = $to->getProduct(); if (!$pr) { throw new Am_Exception_Configuration("Upgrade: cannot load [to] product {$to->product_id}"); } $invoice->add($pr, $item->qty); $newItem = $invoice->getItem(0); /* @var $newItem InvoiceItem */ $invoice->data()->set(Invoice::UPGRADE_INVOICE_ID, $exInvoice->pk()); $invoice->data()->set(Invoice::UPGRADE_INVOICE_ITEM_ID, $item->pk()); $invoice->calculate(); // now calculate discounts and surcharges $unusedAmount = $this->getUnusedAmount($exInvoice, $item); $newItem->data()->set('orig_first_price', null); if ($this->type == self::TYPE_FLAT) { $newItem->first_price = $this->surcharge; } else { $unusedAmount = $this->getUnusedAmount($exInvoice, $item); // magic upgrade formula! $newItem->first_price = moneyRound($newItem->first_price - $unusedAmount + $this->surcharge); } if ($newItem->first_price < 0) { $invoice->data()->set(Invoice::UPGRADE_REFUND, moneyRound($unusedAmount + $newItem->first_price)); $newItem->first_price = 0.0; } $invoice->calculate(); $this->getDi()->hook->call(Am_Event::BEFORE_PRODUCT_UPGRADE, array('invoice' => $invoice, 'exItem' => $item, 'exInvoice' => $exInvoice, 'upgrade' => $this)); return $invoice; }