Hide Bundle Product if one of the Children is outofstock - magento-1.7

how can i filter product collection so it will return the collection which does not contain bundle product whose one of children is Out of stock.

Got the solution for my question
$collection = Mage::getResourceModel('catalog/product_collection');
$bundled_items = array();
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
foreach ($collection->getAllIds() as $proId)
{
$bundled_product=Mage::getModel('catalog/product')->load($proId);
if($bundled_product->getTypeId()=="bundle")
{
$selectionCollection = $bundled_product->getTypeInstance(true)->getSelectionsCollection(
$bundled_product->getTypeInstance(true)->getOptionsIds($bundled_product), $bundled_product
);
foreach($selectionCollection as $option)
{
$product = Mage::getModel('catalog/product')->load($option->getProductId());
$stockItem = $product->getStockItem();
if($product->stock_item->is_in_stock == 0)
{
$bundled_items[] = $proId;
}
}
}
}
if(isset($bundled_items) && !empty($bundled_items))
{
$collection->addFieldToFilter('entity_id',array( 'nin' => array_unique($bundled_items)));
}

Alternate answer
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
$otherProductIds = $collection->getAllIds();
//get only bundle
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToFilter('type_id','bundle');
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
$bundleIds = $collection->getAllIds();
//checking bundle associate product stock status
$readAdapter = Mage::getSingleton('core/resource')->getConnection('core_read');
$select = $readAdapter->select()
->from(array('css'=> Mage::getSingleton('core/resource')->getTableName('cataloginventory/stock_status')),array())
->join(
array('bs'=> Mage::getSingleton('core/resource')->getTableName('bundle/selection')),
'bs.product_id = css.product_id',
array('parent_product_id')
)
->where('bs.parent_product_id IN (?)',$bundleIds)
->where('css.stock_status = 0')
->group('bs.parent_product_id');
$excludeBundleIds = $readAdapter->fetchCol($select);//return outstock associated products parent ids
$allIds = array_merge($otherProductIds, array_diff($bundleIds,$excludeBundleIds));
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToFilter('entity_id',array( 'in' => $allIds))
->addMinimalPrice()
->addFinalPrice();
return $collection
Hope this will helpful

Related

Courses in moodle API

Get enrolled courses of a user:
$mcourses = enroll_get_my_courses();
$mycourses = new html_table();
$mycourses->head = array('userid', 'mycourses');
$mycourses->attributes['class'] = 'tabler';
foreach ($mcourses as $all) {
$mycourses->data[] = new html_table_row(array(implode(array($all->userid)), $all->fullname));
}
Get all courses in the moodle system:
$syscourses = enrol_get_all_users_courses();
$allcourses = new html_table();
$allcourses->head = array('allcourses');
$allcourses->attributes['class'] = 'tabler';
foreach ($syscourses as $sys) {
$allcourses->data[] = new html_table_row(array(implode(array($all->fullname)));
}
To get all courses of a particular user:
$mycourses = enrol_get_my_courses();
The word is "enrol" with a single "L" not two Ls
To get all the courses you have to use
$courses = get_courses();

How to get Filterable Attributes from a category in Magento 2

I have created category "Bag" in Magento 2. having filter attribute:
color
Size
I'm trying to get Filterable Attributes from category "Bag".
I have already done this in Magento 1.9:
Mage::app()->setCurrentStore($store);
$layer = Mage::getModel("catalog/layer");
$category = Mage::getModel("catalog/category")->load($categoryid);
$layer->setCurrentCategory($category);
$attributes = $layer->getFilterableAttributes();
But it does not seem to work for 2.x
I faced the same problem recently.
I documented my investigation here.
I was not able to find framework api to provide filterable attributes for specific category, however I will share workarounds.
Basically all filterable attributes in Magento 2 can be retrived from FilterableAttributeList:
$filterableAttributes = ObjectManager::getInstance()->get(\Magento\Catalog\Model\Layer\Category\FilterableAttributeList::class);
$attributes = $filterableAttributes->getList();
Please use DI instead of ObjectManager::getInstance(). I used it just to have more compact example :)
Retrieving filters involved in layered navigation is a bit more tricky.
$filterableAttributes = ObjectManager::getInstance()->get(\Magento\Catalog\Model\Layer\Category\FilterableAttributeList::class);
$appState = ObjectManager::getInstance()->get(\Magento\Framework\App\State::class);
$layerResolver = ObjectManager::getInstance()->get(\Magento\Catalog\Model\Layer\Resolver::class);
$filterList = ObjectManager::getInstance()->create(
\Magento\Catalog\Model\Layer\FilterList::class,
[
'filterableAttributes' => $filterableAttributes
]
);
$category = 1234;
$appState->setAreaCode('frontend');
$layer = $layerResolver->get();
$layer->setCurrentCategory($category);
$filters = $filterList->getFilters($layer);
However, this is not the final result. To be sure that filters are actual, it is required to check number of items for each filters. (that check is actually performed during core layered navigation rendering)
$finalFilters = [];
foreach ($filters as $filter) {
if ($filter->getItemsCount()) {
$finalFilters[] = $filter;
}
}
Then you can get filter names and values. ie:
$name = $filter->getName();
foreach ($filter->getItems() as $item) {
$value = $item->getValue();
}
Finally, I would like to add alternative solution, that is a bit brutal, thought :)
$categoryId = 1234;
$resource = ObjectManager::getInstance()->get(\Magento\Framework\App\ResourceConnection::class);
$connection = $resource->getConnection();
$select = $connection->select()->from(['ea' => $connection->getTableName('eav_attribute')], 'ea.attribute_id')
->join(['eea' => $connection->getTableName('eav_entity_attribute')], 'ea.attribute_id = eea.attribute_id')
->join(['cea' => $connection->getTableName('catalog_eav_attribute')], 'ea.attribute_id = cea.attribute_id')
->join(['cpe' => $connection->getTableName('catalog_product_entity')], 'eea.attribute_set_id = cpe.attribute_set_id')
->join(['ccp' => $connection->getTableName('catalog_category_product')], 'cpe.entity_id = ccp.product_id')
->where('cea.is_filterable = ?', 1)
->where('ccp.category_id = ?', $categoryId)
->group('ea.attribute_id');
$attributeIds = $connection->fetchCol($select);
Then it is possible to use attribute ids to load collection.
/** #var $collection \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection */
$collection = $this->collectionFactory->create();
$collection->setItemObjectClass('Magento\Catalog\Model\ResourceModel\Eav\Attribute')
->addStoreLabel($this->storeManager->getStore()->getId());
$collection->addFieldToFilter('attribute_id', ['in' => $attributeIds]);
If you know how to build module then you can take help from 'FiltersProvider.php' from 'module-catalog-graph-ql\Model\Resolver\Layer'.
use Magento\Catalog\Model\Layer\Category\FilterableAttributeList as CategoryFilterableAttributeList;
use Magento\Catalog\Model\Layer\FilterListFactory;
use Magento\Catalog\Model\Layer\Resolver;
use Magento\Framework\UrlInterface;
public function __construct(
Resolver $layerResolver,
FilterListFactory $filterListFactory,
CategoryFilterableAttributeList $categoryFilterableAttributeList,
UrlInterface $urlBuilder
) {
$this->_navigation = $navigation;
$this->layerResolver = $layerResolver;
$this->filterListFactory = $filterListFactory;
$this->urlBuilder = $urlBuilder;
$this->_categoryFilterableAttributeList = $categoryFilterableAttributeList;
}
public function getCatMenu($catid)
{
$fill_arr = [];
$filterList = $this->filterListFactory->create(['filterableAttributes' => $this->_categoryFilterableAttributeList]);
$layer = clone $this->layerResolver->get();
$layer->setCurrentCategory($catid);
$filters = $filterList->getFilters($layer);
return $fill_arr;
}

merge two Where with AND in zend 2

I have problem to merge two conditions in my query
public function GetInbox($user_id , $line_number = false , $seeall = false , $limit = 0,$SearchWhere = null)
{
if(!$SearchWhere)
$SearchWhere = new Where();
if(!$seeall)
{
$UsersLineTable = new UsersLinesTable($this->adapter);
$UsersLine = $UsersLineTable->fetchAll(array('user_id = ?' => $user_id,'owner_type = ?' => '1'));
if(!$UsersLine) return false;
$SearchWhere2 = new Where();
foreach ($UsersLine as $key => $value) {
$SearchWhere2->equalTo("recipient_number",$value['line_number'])
->or
->equalTo("recipient_number",'98'.$value['line_number'])
->or;
}
$Select = new Select();
$Select->where($SearchWhere2);
$Select->where($SearchWhere);
if($limit)
$Select->limit($limit);
$Select->order("receive_date DESC");
$MessageProvidersInboxTable = new MessageProvidersInboxTable($this->adapter);
return $MessageProvidersInboxTable->fetchBySelect($Select);
}else{
$MessageProvidersInboxTable = new MessageProvidersInboxTable($this->adapter);
return $MessageProvidersInboxTable->fetchAll($SearchWhere);
}
}
$SearchWhere is a Where class,
$SearchWhere2 is second conditions
In this case
$Select->where($SearchWhere2);
$Select->where($SearchWhere);
$select just contain $SearchWhere conditions.
I want this query
Where condition1 AND (condition2)
is that important that condition2 contain conditions include OR operand.
Sincerely
Try this, it should work. Writing without looking at zend\db code:
$where = new \Zend\Db\Sql\Where;
$where->addPredicate($SearchWhere, $where::OP_AND);
$where->addPredicate($SearchWhere2, $where::OP_AND);
$select->where($where);
Basically, Where object is a subclass of Predicate. So it should work as any other predicate.

Querying for dates in doctrine

I have a table called active_plans in which there are two columns: activated_date and last_billed_at. Basically, I want to create a query that looks at these two columns like this:
select all from active_plans
where last_billed_at = null AND activated_date + 1 month = today,
or if last_billed_at + 1 month = today.
I can't seem to figure out how to do this, though.
I wound up doing something a lot different:
public function getBillToday()
{
$activePlans = $this->entityManager
->createQuery('SELECT adp FROM adp
WHERE adp.activationDate IS NOT NULL')
->getResult();
$data = array();
foreach ($activePlans as $plan) {
$recur = $plan->getPlan()->getRecurringInMonths();
$nextBillTime = strtotime('-'.$recur.' months', time());
$nextBill = date('Y-m-d', $nextBillTime);
$activationDate = $plan->getActivationDate();
$lastBilledAt = $plan->getLastBilledAt() != NULL ? $plan->getLastBilledAt()->format('Y-m-d') : 0;
if ($activationDate == $nextBill || $lastBilledAt == $nextBill) {
$data[] = $plan->getId();
}
}
return $data;
}

Zend_Form_Element fails when i addElements

I have been having trouble adding a hidden zend form element.
when i invoke addElements the form fails and prints the following error to the page.
but only when i try and add $formContactID and $formCustomerID.
Fatal error: Call to a member function getOrder() on a non-object in /home/coder123/public_html/wms2/library/Zend/Form.php on line 3291
My code is as follows.
private function buildForm()
{
$Description = "";
$FirstName = "";
$LastName = "";
$ContactNumber = "";
$Fax = "";
$Position = "";
$Default = "";
$custAddressID = "";
$CustomerID = "";
$Email = "";
$ContactID = "";
if($this->contactDetails != null)
{
$Description = $this->contactDetails['Description'];
$CustomerID = $this->contactDetails['CustomerID'];
$FirstName = $this->contactDetails['FirstName'];
$LastName = $this->contactDetails['LastName'];
$ContactNumber = $this->contactDetails['ContactNumber'];
$Position = $this->contactDetails['Position'];
$Fax = $this->contactDetails['Fax'];
$Email = $this->contactDetails['Email'];
$Default = $this->contactDetails['Default'];
$custAddressID = $this->contactDetails['custAddressID'];
$ContactID = $this->contactDetails['custContactID'];
}
$formfirstname = new Zend_Form_Element_Text('FirstName');
$formfirstname->setValue($FirstName)->setLabel('First Name:')->setRequired();
$formlastname = new Zend_Form_Element_Text('LastName');
$formlastname->setLabel('Last Name:')->setValue($LastName)->setRequired();
$formPhone = new Zend_Form_Element_Text('ContactNumber');
$formPhone->setLabel('Phone Number:')->setValue($ContactNumber)->setRequired();
$formFax = new Zend_Form_Element_Text('FaxNumber');
$formFax->setLabel('Fax Number:')->setValue($Fax);
$FormPosition = new Zend_Form_Element_Text('Position');
$FormPosition->setLabel('Contacts Position:')->setValue($Position);
$FormDescription = new Zend_Form_Element_Text('Description');
$FormDescription->setLabel('Short Description:')->setValue($Description)->setRequired();
$formEmail = new Zend_Form_Element_Text('Email');
$formEmail->setLabel('Email Address:')->setValue($Email);
$FormDefault = new Zend_Form_Element_Checkbox('Default');
$FormDefault->setValue('Default')->setLabel('Set as defualt contact for this business:');
if($Default == 'Default')
{
$FormDefault->setChecked(true);
}
$formCustomerID = new Zend_Form_Element_Hidden('customerID');
$formCustomerID->setValue($customerID);
if($this->contactID != null)
{
$formContactID = new Zend_Form_Element_Hidden('ContactID');
$formContactID->setValue($this->contactID);
}
// FORM SELECT
$formSelectAddress = new Zend_Form_Element_Select('custAddress');
$pos = 0;
while($pos < count($this->customerAddressArray))
{
$formSelectAddress->addMultiOption($this->customerAddressArray[$pos]['custAddressID'], $this->customerAddressArray[$pos]['Description']);
$pos++;
}
$formSelectAddress->setValue(array($this->contactDetails['custAddressID']));
$formSelectAddress->setRequired()->setLabel('Default Address For this Contact:');
// END FORM SELECT
$this->setMethod('post');
$this->setName('FormCustomerEdit');
$formSubmit = new Zend_Form_Element_Submit('ContactSubmit');
$formSubmit->setLabel('Save Contact');
$this->setName('CustomerContactForm');
$this->setMethod('post');
$this->addElements(array($FormDescription, $formfirstname, $formlastname,
$FormPosition, $formPhone, $formFax, $FormDefault,
$formEmail, $formSelectAddress, $formContactID, $formCustomerID, $formSubmit));
$this->addElements(array($formSubmit));
}
Maybe you've already fixed, but just in case.
I was having the same issue and the problem was the name of certain attributes within the form. In your case you have:
if($this->contactID != null){
$formContactID = new Zend_Form_Element_Hidden('ContactID');
$formContactID->setValue($this->contactID);
}
In the moment that you have added $formContactID to the form a new internal attribute has been created for the form object, this being 'ContactID'. So now we have $this->ContactID and $this->contactID.
According to PHP standards this shouldn't be a problem because associative arrays keys and objects attribute names are case sensitive but I just wanted to use your code to illustrate the behaviour of Zend Form.
Revise the rest of the code in your form to see that you are not overriding any Zend Element. Sorry for the guess but since you didn't post all the code for the form file it's a bit more difficult to debug.
Thanks and I hope it helps.
I think the problem is on $this->addElements when $formContactID is missing because of if($this->contactID != null) rule.
You can update your code to fix the problem:
.....
$this->addElements(array($FormDescription, $formfirstname, $formlastname,
$FormPosition, $formPhone, $formFax, $FormDefault,
$formEmail, $formSelectAddress, $formCustomerID, $formSubmit));
if(isset($formContactID)) {
$this->addElements(array($formContactID));
}
......