Ejemplo n.º 1
0
 /**
  *  "Close" the order for modifications and fix its state
  *
  *  1) fix current product prices and total (so the total doesn't change if product prices change)
  *  2) save created shipments
  *
  *  @return CustomerOrder New order instance containing wishlist items
  */
 public function finalize($options = array())
 {
     if ($this->isFinalized->get() && empty($options['allowRefinalize'])) {
         return;
     }
     self::beginTransaction();
     $this->event('before-finalize');
     $this->loadAll();
     $currency = $this->getCurrency();
     foreach ($this->getShipments() as $shipment) {
         if ($shipment->isExistingRecord()) {
             $shipment->deleteRecordSet('ShipmentTax', new ARDeleteFilter());
         }
         // clone shipping addresses
         if ($shipment->shippingAddress->get()) {
             $shippingAddress = clone $shipment->shippingAddress->get();
             $shippingAddress->save();
             $shipment->shippingAddress->set($shippingAddress);
         }
         $shipment->order->set($this);
         $shipment->save();
     }
     $reserveProducts = self::getApplication()->isInventoryTracking();
     foreach ($this->getShoppingCartItems() as $item) {
         if (empty($options['customPrice'])) {
             $item->price->set($item->getSubTotalBeforeTax() / $item->getCount());
         }
         $item->name->set($item->getProduct()->getParent()->name->get());
         $item->setValueByLang('name', 'sku', $item->getProduct()->sku->get());
         $item->save();
         // create sub-items for bundled products
         if ($item->getProduct()->isBundle()) {
             foreach ($item->getProduct()->getBundledProducts() as $bundled) {
                 $bundledItem = OrderedItem::getNewInstance($this, $bundled->relatedProduct->get(), $bundled->getCount());
                 $bundledItem->parent->set($item);
                 $bundledItem->save();
             }
         }
         // reserve products if inventory is enabled
         if ($reserveProducts) {
             $item->reserve();
             $item->save();
         }
     }
     if (!$this->shippingAddress->get() && $this->user->get() && $this->user->get()->defaultShippingAddress->get() && $this->isShippingRequired()) {
         $this->shippingAddress->set($this->user->get()->defaultShippingAddress->get()->userAddress->get());
     }
     if (!$this->billingAddress->get() && $this->user->get() && $this->user->get()->defaultBillingAddress->get()) {
         $this->billingAddress->set($this->user->get()->defaultBillingAddress->get()->userAddress->get());
     }
     // clone billing/shipping addresses
     if (!$this->isFinalized->get()) {
         foreach (array('billingAddress', 'shippingAddress') as $address) {
             if ($this->{$address}->get()) {
                 $this->{$address}->get()->load();
                 $this->{$address}->get()->getSpecification();
                 $cloned = clone $this->{$address}->get();
                 $cloned->save();
                 $cloned->loadEav();
                 $this->{$address}->set($cloned);
             }
         }
     }
     // move wish list items to a separate order
     if ($this->getWishListItems()) {
         $wishList = CustomerOrder::getNewInstance($this->user->get());
         foreach ($this->getWishListItems() as $item) {
             $wishList->addItem($item);
         }
         $wishList->save();
     } else {
         $wishList = null;
     }
     // set order total
     $this->totalAmount->set($this->getTotal(true));
     // save shipment taxes
     foreach ($this->shipments as $shipment) {
         $shipment->save();
     }
     // save discounts
     foreach ($this->orderDiscounts as $discount) {
         $discount->save();
     }
     // @todo: remove the 0.99 multiplicator for currency conversion "tolerance" (a cent going missing when converting amounts between currencies back and forth)
     if (round($this->totalAmount->get(), 2) * 0.99 <= round($this->getPaidAmount(), 2)) {
         $this->isPaid->set(true);
     }
     $this->dateCompleted->set(new ARSerializableDateTime());
     $this->isFinalized->set(true);
     // @todo: fix order total calculation
     $shipments = $this->shipments;
     unset($this->shipments);
     if (!$this->invoiceNumber->get()) {
         $generator = InvoiceNumberGenerator::getGenerator($this);
         $saved = false;
         while (!$saved) {
             try {
                 $this->invoiceNumber->set($generator->getNumber());
                 $this->save();
                 $saved = true;
             } catch (SQLException $e) {
             }
         }
     }
     $this->event('after-finalize');
     self::commit();
     // @todo: see above
     $this->shipments = $shipments;
     // force updating array representation
     $this->resetArrayData();
     return $wishList;
 }
Ejemplo n.º 2
0
 /**
  *  "Close" the order for modifications and fix its state
  *
  *  1) fix current product prices and total (so the total doesn't change if product prices change)
  *  2) save created shipments
  *
  *  @return CustomerOrder New order instance containing wishlist items
  */
 public function finalize($options = array())
 {
     $rebillsLeft = 0;
     if ($this->isFinalized->get() && empty($options['allowRefinalize'])) {
         return;
     }
     self::beginTransaction();
     $this->event('before-finalize');
     $currency = $this->getCurrency();
     $this->loadAll();
     foreach ($this->getShipments() as $shipment) {
         if ($shipment->isExistingRecord()) {
             $shipment->deleteRecordSet('ShipmentTax', new ARDeleteFilter());
         }
         $shipment->order->set($this);
         $shipment->save();
         // clone shipping addresses
         if ($shipment->shippingAddress->get()) {
             $shippingAddress = clone $shipment->shippingAddress->get();
             $shippingAddress->save();
             $shipment->shippingAddress->set($shippingAddress);
         }
     }
     $reserveProducts = self::getApplication()->isInventoryTracking();
     $rebillsLeft = 0;
     $groupedRebillsLeft = array();
     $isFirstOrder = !$this->parentID->get();
     foreach ($this->getShoppingCartItems() as $item) {
         // workround for failing tests.
         //if (!empty($options['customPrice']))
         //{
         $item->price->set($item->getSubTotalBeforeTax() / $item->getCount());
         //}
         $item->name->set($item->getProduct()->getParent()->name->get());
         $item->setValueByLang('name', 'sku', $item->getProduct()->sku->get());
         $item->save();
         // create sub-items for bundled products
         if ($item->getProduct()->isBundle()) {
             foreach ($item->getProduct()->getBundledProducts() as $bundled) {
                 $bundledItem = OrderedItem::getNewInstance($this, $bundled->relatedProduct->get(), $bundled->getCount());
                 $bundledItem->parent->set($item);
                 $bundledItem->save();
             }
         }
         // reserve products if inventory is enabled
         if ($reserveProducts) {
             $item->reserve();
             $item->save();
         }
         if ($isFirstOrder) {
             $ri = RecurringItem::getInstanceByOrderedItem($item);
             if ($ri && $ri->isExistingRecord()) {
                 $rebillCount = $ri->rebillCount->get();
                 // also here recurring item grouping
                 $key = sprintf('%s_%s_%s', $ri->periodType->get(), $ri->periodLength->get(), $rebillCount === null ? 'NULL' : $rebillCount);
                 if ($rebillCount !== null) {
                     $groupedRebillsLeft[$key] = $rebillCount;
                 } else {
                     $groupedRebillsLeft[$key] = -1;
                     // -1 means infinite rebill count
                 }
                 $this->isRecurring->set(true);
                 // orders with at least one recurring billing plan must have isRecurring flag, if already not set.
             }
         } else {
             $rparentItem = $item->recurringParentID->get();
             if ($rparentItem) {
                 $ri = RecurringItem::getInstanceByOrderedItem($rparentItem, true);
                 $ri->reload();
                 // if was bulk update, then cached data are outdated.
                 if ($ri && $ri->isExistingRecord()) {
                     // are RecurringItems grouped?
                     // probably yes..
                     $rebillsLeft = $ri->rebillCount->get() - $ri->processedRebillCount->get();
                 }
             }
         }
     }
     if ($isFirstOrder) {
         foreach ($groupedRebillsLeft as $value) {
             if ($value == -1) {
                 $rebillsLeft = -1;
                 break;
             } else {
                 $rebillsLeft += $value;
             }
         }
     }
     if (!$this->shippingAddress->get() && $this->user->get() && $this->user->get()->defaultShippingAddress->get() && $this->isShippingRequired()) {
         $this->shippingAddress->set($this->user->get()->defaultShippingAddress->get()->userAddress->get());
     }
     if (!$this->billingAddress->get() && $this->user->get() && $this->user->get()->defaultBillingAddress->get()) {
         $this->billingAddress->set($this->user->get()->defaultBillingAddress->get()->userAddress->get());
     }
     // clone billing/shipping addresses
     if (!$this->isFinalized->get()) {
         foreach (array('billingAddress', 'shippingAddress') as $address) {
             if ($this->{$address}->get()) {
                 $this->{$address}->get()->load();
                 $this->{$address}->get()->getSpecification();
                 $cloned = clone $this->{$address}->get();
                 $cloned->save();
                 $cloned->loadEav();
                 $this->{$address}->set($cloned);
             }
         }
     }
     // move wish list items to a separate order
     if ($this->getWishListItems()) {
         $wishList = CustomerOrder::getNewInstance($this->user->get());
         foreach ($this->getWishListItems() as $item) {
             $wishList->addItem($item);
         }
         $wishList->save();
     } else {
         $wishList = null;
     }
     // set order total
     $this->totalAmount->set($this->getTotal(true));
     // save shipment taxes
     foreach ($this->shipments as $shipment) {
         $shipment->save();
     }
     // save discounts
     foreach ($this->orderDiscounts as $discount) {
         $discount->save();
     }
     // @todo: remove the 0.99 multiplicator for currency conversion "tolerance" (a cent going missing when converting amounts between currencies back and forth)
     if (round($this->totalAmount->get(), 2) * 0.99 <= round($this->getPaidAmount(), 2)) {
         $this->isPaid->set(true);
     }
     $this->dateCompleted->set(new ARSerializableDateTime());
     $this->isFinalized->set(true);
     // @todo: fix order total calculation
     $shipments = $this->shipments;
     unset($this->shipments);
     if (!$this->invoiceNumber->get()) {
         $generator = InvoiceNumberGenerator::getGenerator($this);
         $saved = false;
         while (!$saved) {
             try {
                 $this->invoiceNumber->set($generator->getNumber());
                 $this->save();
                 $saved = true;
             } catch (SQLException $e) {
             }
         }
     }
     if ($this->isRecurring->get()) {
         $changed = false;
         if (!strlen($this->startDate->get())) {
             $this->startDate->set(date('Y-m-d H:i:s', time()));
             $changed = true;
         }
         if ($rebillsLeft != $this->rebillsLeft->get()) {
             $this->rebillsLeft->set($rebillsLeft);
             $changed = true;
         }
         if ($changed) {
             $this->save();
         }
     }
     $this->event('after-finalize');
     self::commit();
     // @todo: see above
     $this->shipments = $shipments;
     // force updating array representation
     $this->resetArrayData();
     return $wishList;
 }
Ejemplo n.º 3
0
 public function create()
 {
     $request = $this->getRequest();
     $query = $request->get('query');
     if (strlen($query)) {
         $products = $this->getProductsFromSearchQuery($query);
     } else {
         $products = new ARSet();
         $products->add(Product::getInstanceById((int) $this->request->get('productID'), true));
     }
     $saveResponse = array('errors' => array(), 'items' => array());
     $composite = new CompositeJSONResponse();
     $order = CustomerOrder::getInstanceByID((int) $this->request->get('orderID'), true);
     $order->loadAll();
     foreach ($products as $product) {
         if ($product->isDownloadable()) {
             $shipment = $order->getDownloadShipment();
         } else {
             if ((int) $this->request->get('shipmentID')) {
                 $shipment = Shipment::getInstanceById('Shipment', (int) $this->request->get('shipmentID'), true, array('Order' => 'CustomerOrder', 'ShippingService', 'ShippingAddress' => 'UserAddress', 'Currency'));
             }
         }
         if (empty($shipment)) {
             $shipment = $order->getShipments()->get(0);
         }
         if (!$shipment) {
             $shipment = Shipment::getNewInstance($order);
         }
         if (!$shipment->order->get()) {
             $shipment->order->set($order);
         }
         $history = new OrderHistory($order, $this->user);
         $existingItem = false;
         foreach ($shipment->getItems() as $item) {
             if ($item->getProduct() === $product) {
                 if (!$product->getOptions(true)) {
                     $existingItem = $item;
                 }
                 break;
             }
         }
         if ($existingItem) {
             $item = $existingItem;
             if ($product->isDownloadable()) {
                 return new JSONResponse(false, 'failure', $this->translate('_downloadable_item_already_exists_in_this_order'));
             } else {
                 $item->count->set($item->count->get() + 1);
             }
         } else {
             $currency = $shipment->getCurrency();
             $item = OrderedItem::getNewInstance($order, $product);
             $item->count->set(1);
             $item->price->set($currency->round($item->reduceBaseTaxes($product->getPrice($currency->getID()))));
             $order->addItem($item);
             $shipment->addItem($item);
             $shipment->save();
         }
         $resp = $this->save($item, $shipment, $existingItem ? true : false);
         if (array_key_exists('errors', $resp)) {
             $saveResponse['errors'] = array_merge($saveResponse['errors'], $resp['errors']);
         } else {
             if (array_key_exists('item', $resp)) {
                 $saveResponse['items'][] = $resp['item'];
             }
         }
     }
     // for each product
     if (count($saveResponse['errors']) == 0) {
         unset($saveResponse['errors']);
     }
     if (isset($saveResponse['errors'])) {
         $response = new JSONResponse(array('errors' => $validator->getErrorList()), 'failure', $this->translate('_unable_to_update_items_quantity'));
     } else {
         $response = new JSONResponse($saveResponse, 'success', $this->translate('_item_has_been_successfuly_saved'));
     }
     $composite->addResponse('data', $response, $this, 'create');
     $ids = array();
     foreach ($saveResponse['items'] as $item) {
         $ids[] = $item['ID'];
     }
     $composite->addAction('html', 'backend.orderedItem', 'items');
     $this->request->set('item_ids', implode(',', $ids));
     $history->saveLog();
     return $composite;
 }
Ejemplo n.º 4
0
 /**
  *  Import or update an ordered product
  */
 protected function set_OrderedItem_sku($instance, $value, $record, CsvImportProfile $profile)
 {
     if (!$value) {
         return;
     }
     $product = Product::getInstanceBySKU($value);
     if (!$product) {
         return;
     }
     $items = $instance->getItemsByProduct($product);
     // create initial shipment
     if (!$instance->getShipments()->size()) {
         $shipment = Shipment::getNewInstance($instance);
         $shipment->save();
     }
     // any particular shipment?
     $shipment = $item = null;
     if ($profile->isColumnSet('OrderedItem.shipment')) {
         // internal indexes are 0-based, but the import references are 1-based
         $shipmentNo = $this->getColumnValue($record, $profile, 'OrderedItem.shipment') - 1;
         if (is_numeric($this->getColumnValue($record, $profile, 'OrderedItem.shipment'))) {
             foreach ($instance->getShipments() as $key => $shipment) {
                 if ($key == $shipmentNo) {
                     break;
                 }
                 $shipment = null;
             }
             // create a new shipment
             if (!$shipment) {
                 $shipment = Shipment::getNewInstance($instance);
                 $shipment->save();
             }
             foreach ($items as $item) {
                 if ($item->shipment->get() == $shipment) {
                     break;
                 }
                 unset($item);
             }
         }
     }
     if (!$item) {
         $item = array_shift($items);
     }
     if (!$item) {
         $count = $this->getColumnValue($record, $profile, 'OrderedItem.count');
         $item = OrderedItem::getNewInstance($instance, $product, max(1, $count));
         $instance->addItem($item);
     }
     if ($profile->isColumnSet('OrderedItem.count')) {
         $count = $this->getColumnValue($record, $profile, 'OrderedItem.count');
         $item->count->set(max(1, $count));
     }
     if ($profile->isColumnSet('OrderedItem.price')) {
         $item->price->set($this->getColumnValue($record, $profile, 'OrderedItem.price'));
     }
     if (!$shipment) {
         $shipment = $instance->getShipments()->get(0);
     }
     $item->shipment->set($shipment);
     $item->save();
     $instance->finalize(array('customPrice' => true, 'allowRefinalize' => true));
 }