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 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 delete() { $ri = RecurringItem::getInstanceByOrderedItem($this); if ($ri) { $ri->delete(); } parent::delete(); }
/** * @role login */ public function viewOrder() { $id = $this->request->get('id'); if ($order = $this->user->getOrder($id)) { $this->addAccountBreadcrumb(); $this->addBreadCrumb($this->translate('_your_orders'), $this->router->createUrl(array('controller' => 'user', 'action' => 'orders'), true)); $this->addBreadCrumb($order->invoiceNumber->get(), ''); // mark all notes as read $notes = $order->getNotes(); foreach ($notes as $note) { if (!$note->isRead->get() && $note->isAdmin->get()) { $note->isRead->set(true); $note->save(); } } $response = null; $orderArray = $order->toArray(); if ($order->isRecurring->get() == true) { // find invoices $page = $this->request->get('page', 1); $perPage = $this->getOrdersPerPage(); $f = $this->getOrderListPaginateFilter($page, $perPage); $f->mergeCondition(new AndChainCondition(array(new EqualsCond(new ARFieldHandle('CustomerOrder', 'parentID'), $order->getID()), new EqualsCond(new ARFieldHandle('CustomerOrder', 'isRecurring'), 1)))); $f->setOrder(new ARFieldHandle('CustomerOrder', 'dateDue')); $response = $this->getOrdersListResponse($this->loadOrders($f), $page, $perPage); $recurringProductPeriods = array(); foreach ($order->getShipments() as $shipment) { foreach ($shipment->getItems() as $orderedItem) { $recurringProductPeriods[$orderedItem->getID()] = RecurringItem::getInstanceByOrderedItem($orderedItem)->toArray(); } } ClassLoader::import('application.model.product.RecurringProductPeriod'); ClassLoader::import('application.model.product.RecurringItem'); $response->set('nextRebillDate', $order->getNextRebillDate()); $response->set('periodTypesPlural', RecurringProductPeriod::getAllPeriodTypes(RecurringProductPeriod::PERIOD_TYPE_NAME_PLURAL)); $response->set('periodTypesSingle', RecurringProductPeriod::getAllPeriodTypes(RecurringProductPeriod::PERIOD_TYPE_NAME_SINGLE)); $response->set('recurringProductPeriodsByItemId', $recurringProductPeriods); $this->loadLanguageFile('Product'); } if (!$response) { $response = new ActionResponse(); } $response->set('subscriptionStatus', $order->getSubscriptionStatus()); $response->set('canCancelRebills', $order->canUserCancelRebills()); $response->set('order', $orderArray); $response->set('notes', $notes->toArray()); $response->set('user', $this->user->toArray()); $response->set('noteForm', $this->buildNoteForm()); return $response; } else { return new ActionRedirectResponse('user', 'index'); } }
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; }