private function _setLocation(Product &$product, $param)
 {
     if (isset($param->CallbackParameter->locations) && count($locations = $param->CallbackParameter->locations) > 0) {
         //delete all price first
         $deleteIds = array();
         foreach ($locations as $location) {
             if (trim($location->active) === '0' && isset($location->id)) {
                 $deleteIds[] = trim($location->id);
             }
         }
         if (count($deleteIds) > 0) {
             PreferredLocation::updateByCriteria('active = 0', 'id in (' . str_repeat('?', count($deleteIds)) . ')', $deleteIds);
         }
         //update or create new
         foreach ($locations as $location) {
             if (isset($location->id) && in_array(trim($location->id), $deleteIds)) {
                 continue;
             }
             if (!($type = PreferredLocationType::get(trim($location->typeId))) instanceof PreferredLocationType) {
                 continue;
             }
             $locationName = trim($location->value);
             $locs = Location::getAllByCriteria('name = ?', array($locationName), true, 1, 1);
             $loc = count($locs) > 0 ? $locs[0] : Location::create($locationName, $locationName);
             if (!isset($location->id) || ($id = trim($location->id)) === '') {
                 if (trim($location->active) === '1') {
                     PreferredLocation::create($loc, $product, $type);
                 }
                 //if it's deactivated one, ignore
             } else {
                 if (($preferredLocation = PreferredLocation::get($id)) instanceof PreferredLocation) {
                     $preferredLocation->setLocation($loc)->setActive(trim($location->active) === '1')->setProduct($product)->setType($type)->save();
                 }
             }
         }
     }
     return $this;
 }
 /**
  * Getting all the preferred locations
  * 
  * @param Product $product
  * @param PreferredLocationType $type
  * @param string $activeOnly
  * @param string $pageNo
  * @param unknown $pageSize
  * @param unknown $orderBy
  * @param unknown $stats
  * @return Ambigous <Ambigous, multitype:, multitype:BaseEntityAbstract >
  */
 public static function getPreferredLocations(Product $product, PreferredLocationType $type = null, $activeOnly = true, $pageNo = null, $pageSize = DaoQuery::DEFAUTL_PAGE_SIZE, $orderBy = array(), &$stats = array())
 {
     $where = array('productId = ? ');
     $params = array($product->getId());
     if ($type instanceof PreferredLocationType) {
         $where[] = 'typeId = ?';
         $params[] = $type->getId();
     }
     return self::getAllByCriteria(implode(' AND ', $where), $params, $activeOnly, $pageNo, $pageSize, $orderBy, $stats);
 }
 /**
  * saveOrder
  *
  * @param unknown $sender
  * @param unknown $param
  *
  * @throws Exception
  *
  */
 public function saveOrder($sender, $param)
 {
     $results = $errors = array();
     try {
         Dao::beginTransaction();
         $items = array();
         $purchaseOrder = PurchaseOrder::get(trim($param->CallbackParameter->purchaseOrder->id));
         if (!$purchaseOrder instanceof PurchaseOrder) {
             throw new Exception('Invalid PurchaseOrder passed in!');
         }
         $comment = trim($param->CallbackParameter->comments);
         $purchaseOrder->addComment(Comments::TYPE_WAREHOUSE, $comment);
         $products = $param->CallbackParameter->products;
         $outStandingOrders = array();
         $invoiceNos = array();
         foreach ($products->matched as $item) {
             $product = Product::get(trim($item->product->id));
             if (!$product instanceof Product) {
                 throw new Exception('Invalid Product passed in!');
             }
             if (isset($item->product->EANcode)) {
                 $EANcode = trim($item->product->EANcode);
                 $productcodes = ProductCode::getAllByCriteria('pro_code.productId = :productId and pro_code.typeId = :typeId', array('productId' => $product->getId(), 'typeId' => ProductCodeType::ID_EAN), true, 1, 1);
                 if (count($productcodes) > 0) {
                     $productcodes[0]->setCode($EANcode)->save();
                 } else {
                     ProductCode::create($product, ProductCodeType::get(ProductCodeType::ID_EAN), $EANcode);
                 }
             }
             if (isset($item->product->UPCcode)) {
                 $UPCcode = trim($item->product->UPCcode);
                 $productcodes = ProductCode::getAllByCriteria('pro_code.productId = :productId and pro_code.typeId = :typeId', array('productId' => $product->getId(), 'typeId' => ProductCodeType::ID_UPC), true, 1, 1);
                 if (sizeof($productcodes)) {
                     $productcodes[0]->setCode($UPCcode)->save();
                 } else {
                     ProductCode::create($product, ProductCodeType::get(ProductCodeType::ID_UPC), $UPCcode);
                 }
             }
             if (isset($item->product->warehouseLocation) && ($locationName = trim($item->product->warehouseLocation)) !== '') {
                 $locs = Location::getAllByCriteria('name = ?', array($locationName), true, 1, 1);
                 $loc = count($locs) > 0 ? $locs[0] : Location::create($locationName, $locationName);
                 $product->addLocation(PreferredLocationType::get(PreferredLocationType::ID_WAREHOUSE), $loc);
             }
             $serials = $item->serial;
             $totalQty = 0;
             foreach ($serials as $serial) {
                 $qty = trim($serial->qty);
                 $totalQty += intval($qty);
                 $serialNo = trim($serial->serialNo);
                 $unitPrice = trim($serial->unitPrice);
                 $invoiceNo = trim($serial->invoiceNo);
                 $invoiceNos[] = $invoiceNo;
                 $comments = trim($serial->comments);
                 ReceivingItem::create($purchaseOrder, $product, $unitPrice, $qty, $serialNo, $invoiceNo, $comments);
             }
             OrderItem::getQuery()->eagerLoad('OrderItem.order', 'inner join', 'ord', 'ord.id = ord_item.orderId and ord.active = 1 and ord.type = :ordType and ord_item.productId = :productId and ord.statusId in ( :statusId1, :statusId2, :statusId3)');
             $orderItems = OrderItem::getAllByCriteria('ord_item.active = 1', array('ordType' => Order::TYPE_INVOICE, 'productId' => $product->getId(), 'statusId1' => OrderStatus::ID_INSUFFICIENT_STOCK, 'statusId2' => OrderStatus::ID_ETA, 'statusId3' => OrderStatus::ID_STOCK_CHECKED_BY_PURCHASING));
             if (count($orderItems) > 0) {
                 $orders = array();
                 foreach ($orderItems as $orderItem) {
                     if (!array_key_exists($orderItem->getOrder()->getId(), $orders)) {
                         $orders[$orderItem->getOrder()->getId()] = $orderItem->getOrder()->getJson();
                     }
                 }
                 $outStandingOrders[$product->getId()] = array('product' => $product->getJson(), 'recievedQty' => $totalQty, 'outStandingOrders' => array_values($orders));
             }
         }
         $results['outStandingOrders'] = count($outStandingOrders) > 0 ? array_values($outStandingOrders) : array();
         $results['item'] = PurchaseOrder::get($purchaseOrder->getId())->getJson();
         $invoiceNos = array_unique($invoiceNos);
         $results['invoiceNos'] = $invoiceNos;
         Dao::commitTransaction();
     } catch (Exception $ex) {
         Dao::rollbackTransaction();
         $errors[] = $ex->getMessage();
     }
     $param->ResponseData = StringUtilsAbstract::getJson($results, $errors);
 }