public function changeRecurringProductPeriod() { $request = $this->getRequest(); $orderedItemID = $request->get('id'); $billingPlandropdownName = $request->get('recurringBillingPlan'); $recurringID = $request->get($billingPlandropdownName); $orderedItem = ActiveRecordModel::getInstanceByID('OrderedItem', $orderedItemID, true); $recurringItem = RecurringItem::getInstanceByOrderedItem($orderedItem); if ($recurringItem) { $recurringItem->setRecurringProductPeriod(RecurringProductPeriod::getInstanceByID($recurringID)); $recurringItem->save(); $orderedItem->updateBasePriceToCalculatedPrice(); } $this->order->loadItemData(); $this->order->mergeItems(); $this->order->save(); return new ActionRedirectResponse('order', 'index', array('query' => 'return=' . $this->request->get('return'))); }
public function __construct(CustomerOrder $order, Currency $currency) { parent::__construct(); $this->order = $order; $order->loadAll(); // billing address if ($address = $order->billingAddress->get()) { $fields = array('firstName', 'lastName', 'companyName', 'phone', 'city', 'postalCode', 'countryID' => 'country'); foreach ($fields as $key => $field) { $addressField = is_numeric($key) ? $field : $key; $this->{$field}->set($address->{$addressField}->get()); } $this->state->set($this->getStateValue($address)); $this->address->set($address->address1->get() . ' ' . $address->address2->get()); } // shipping address $address = $order->shippingAddress->get(); if (!$address) { $address = $order->billingAddress->get(); } if ($address) { foreach ($fields as $key => $field) { $addressField = is_numeric($key) ? $field : $key; $field = 'shipping' . ucfirst($field); $this->{$field}->set($address->{$addressField}->get()); } $this->shippingState->set($this->getStateValue($address)); $this->shippingAddress->set($address->address1->get() . ' ' . $address->address2->get()); } // amount $order->currency->set($currency); $this->amount->set(round($order->getDueAmount(), 2)); $this->currency->set($currency->getID()); // transaction identification $this->invoiceID->set($order->getID()); if (isset($_SERVER['REMOTE_ADDR'])) { $this->ipAddress->set($_SERVER['REMOTE_ADDR']); } // customer identification if ($order->user->get()) { $order->user->get()->load(); $this->shippingEmail->set($order->user->get()->email->get()); $this->email->set($order->user->get()->email->get()); $this->clientID->set($order->user->get()->getID()); } // order details // load variation data $variations = new ProductSet(); foreach ($order->getShoppingCartItems() as $item) { if ($item->product->get() && $item->product->get()->parent->get()) { $variations->unshift($item->product->get()); } } if ($variations->size()) { $variations->loadVariations(); } foreach ($order->getShoppingCartItems() as $item) { $product = $item->getProduct(); $variations = array(); foreach ($product->getRegisteredVariations() as $variation) { $variations[] = $variation->getValueByLang('name'); } $ri = RecurringItem::getInstanceByOrderedItem($item); if ($ri && $ri->isExistingRecord()) { $ri->load(); } else { $ri = null; } $this->addLineItem($product->getName() . ($variations ? ' (' . implode(' / ', $variations) . ')' : ''), $item->getPrice(false), $item->count->get(), $product->sku->get(), $ri); } if ($discount = $order->getFixedDiscountAmount()) { $this->addLineItem(CustomerOrder::getApplication()->translate('_discount'), $discount * -1, 1, 'discount'); } foreach ($order->getShipments() as $shipment) { if ($rate = $shipment->getSelectedRate()) { $rate = $rate->toArray(); $name = empty($rate['ShippingService']['name_lang']) ? $rate['serviceName'] : $rate['ShippingService']['name_lang']; $this->addLineItem($name, $shipment->getShippingTotalBeforeTax(), 1, 'shipping'); } } if ($taxes = $order->getTaxBreakdown()) { foreach ($taxes as $id => $amount) { $tax = Tax::getInstanceById($id, true); $this->addLineItem($tax->getValueByLang('name', null), $amount, 1, 'tax'); } } }
public function generateTestInvoices() { return; ClassLoader::import('application.model.category.*'); ClassLoader::import('application.model.product.*'); $config = ActiveRecordModel::getApplication()->getConfig(); $config->set('RECURRING_BILLING_PAYMENT_DUE_DATE_DAYS', 7); $config->save(); // data $userID = 110; $product1ID = 339; $recurringProductPeriodID = 19; // ~ // create first order $user = User::getInstanceByID($userID, true); $product1 = Product::getInstanceByID($product1ID, true); $order = CustomerOrder::getNewInstance($user); $order->save(true); $rpp = RecurringProductPeriod::getInstanceByID($recurringProductPeriodID); $item = $order->addProduct($product1, 1, true); $item->save(); $recurringItem = RecurringItem::getNewInstance($rpp, $item); $recurringItem->setupPrice->set(100); $recurringItem->periodPrice->set(25); $recurringItem->save(); $order->finalize(); // generate invoices echo '<pre>Invoices for {CustomerOrder ID:' . $order->getID() . '}:', "\n"; $now = time(); for ($ts = $now; $ts < strtotime('+20 months', $now); $ts = $ts + 60 * 60 * 24) { $z = CustomerOrder::generateRecurringInvoices(date('Y-m-d', $ts)); foreach ($z as $id) { echo '{CustomerOrder ID:' . $id . '}', "\n"; } } die('-done-</pre>'); }
/** * wrapper for BillingAgreementDescription and * */ public static function RecurringItemDescription(RecurringItem $recurringItem) { $recurringItem->recurringID->get()->load(); $recurringItem->orderedItemID->get()->load(); $recurringItemArray = $recurringItem->toArray(); $productName = $recurringItemArray['OrderedItem']['name']; if (strlen($productName) > 3) { $productName = substr($productName, 0, 60) . '..'; } $planName = $recurringItemArray['Recurring']['name']; if (strlen($planName) > 63) { $planName = substr($planName, 0, 60) . '..'; } return sprintf('%s %s', $productName, $planName); }
public function delete() { $ri = RecurringItem::getInstanceByOrderedItem($this); if ($ri) { $ri->delete(); } parent::delete(); }
private function addRecurringProduct($order, $product, $count, $recurringProductPeriod, $setupPrice = 0, $periodPrice = 0, $shipment = null) { $item = $order->addProduct($product, $count, true, $shipment); $item->save(); $recurringItem = RecurringItem::getNewInstance($recurringProductPeriod, $item); // pass setup and period prices here because createRecurringProductPeriod() does not create prices in ProductPrice table. $recurringItem->setupPrice->set((double) $setupPrice); $recurringItem->periodPrice->set((double) $periodPrice); $recurringItem->save(); $product->type->set(Product::TYPE_RECURRING); return array($item, $recurringItem); }
public static function generateRecurringInvoices($forDate = null) { $generatedInvoiceIDs = array(); // return only ids for generated invoice, because 1000+ CustomerOrder instances are expensive if ($forDate == null) { $ts = time(); } else { if (is_numeric($forDate)) { $ts = $forDate; } else { $ts = strtotime($forDate); } } $count = 0; $orderIDrecurringItemIDMapping = self::getRecurringPeriodsEndingTodayArray($ts); $orders = self::getRecurringOrders($orderIDrecurringItemIDMapping); if ($orders->size() == 0) { return $generatedInvoiceIDs; } /* echo "date: ", date('Y-m-d', $ts), "\n"; print_r($orderIDrecurringItemIDMapping); echo "\n"; */ $config = self::getApplication()->getConfig(); $daysDue = $config->get('RECURRING_BILLING_PAYMENT_DUE_DATE_DAYS'); $daysBefore = $config->get('RECURRING_BILLING_GENERATE_INVOICE'); foreach ($orders as $order) { $mainOrder = $order; $foundOrderID = $order->getID(); // order found with sql, this id is used in customerOrder+recurringItem mapping as key. $parent = $order->parentID->get(); if ($parent) { $mainOrder = $parent; } else { // echo 'generating from first invoice (could contain multiple plans merged!)'; } $mainOrderID = $mainOrder->getID(); $mainOrder->isRecurring->set(true); $mainOrder->save(); // group by recurring period type, length, (rebill count?) $groupedRecurringItems = array(); foreach ($mainOrder->getOrderedItems() as $item) { $recurringItem = RecurringItem::getInstanceByOrderedItem($item); $recurringItemID = $recurringItem->getID(); if (isset($orderIDrecurringItemIDMapping[$foundOrderID]) && in_array($recurringItemID, $orderIDrecurringItemIDMapping[$foundOrderID])) { $rpp = $recurringItem->recurringID->get(); $groupedRecurringItems[sprintf('%s_%s_%s', $rpp->periodType->get(), $rpp->periodLength->get(), $rpp->rebillCount->get() === null ? 'NULL' : $rpp->rebillCount->get())][] = array('item' => $item, 'recurringItem' => $recurringItem); } } foreach ($groupedRecurringItems as $itemGroups) { $recurringItemIDs = array(); $newOrder = clone $mainOrder; $newOrder->parentID->set($mainOrder); $newOrder->isFinalized->set(false); $newOrder->invoiceNumber->set($newOrder->getCalculatedRecurringInvoiceNumber()); $newOrder->dateDue->set(date('Y-m-d H:i:s', strtotime('+' . ($daysBefore + $daysDue) . ' day', $ts))); $newOrder->isRecurring->set(true); $newOrder->save(true); // order must be saved for setting recurringItem lastInvoiceID. // !! don't save order while it dont have any item or order will be deleted. foreach ($newOrder->getOrderedItems() as $itemToRemove) { $newOrder->removeItem($itemToRemove); } foreach ($newOrder->getShipments() as $shipment) { //echo '{Shipment ID:'.$shipment->getID().'}'; $newOrder->removeShipment($shipment); } foreach ($itemGroups as $itemGroup) { $item = $itemGroup['item']; $recurringItem = $itemGroup['recurringItem']; $newOrderShipment = Shipment::getNewInstance($newOrder); // ~ should have multiple shipments? $recurringItem->saveLastInvoice($newOrder); $periodLength = $recurringItem->periodLength->get(); $periodType = $recurringItem->periodType->get(); $recurringItemIDs[] = $recurringItem->getID(); // collect IDs for batch processedRebillCount update. $clone = clone $item; $clone->recurringParentID->set($item); $clone->shipmentID->set(null); $clone->save(); $newOrderShipment->addItem($clone); $newOrder->addShipment($newOrderShipment); } if (count($itemGroups) > 0) { $newOrder->updateStartAndEndDates($order, array_map(array(__CLASS__, '_filterRecurringItems'), $itemGroups)); } if ($newOrder->isExistingRecord()) { $generatedInvoiceIDs[] = $newOrder->getID(); } if (count($recurringItemIDs)) { // nedd to be done before CustomerOrder::finalize() because finalize() also updates CustomerOrder.rebillsLeft field. // therefore can't really do batch for all, need to do for every order. still, can reuse batch method. RecurringItem::batchIncreaseProcessedRebillCount($recurringItemIDs); } $newOrder->save(); $newOrder->finalize(); } } return $generatedInvoiceIDs; }