NHibernate criteria query multiple levels of child collections - nhibernate

I am having a lot of difficulty figuring out how to perform a query on 2 tables that don't have reference to each other in code, for example, I have
Customer -> Product* where customer and product have reference to each other
and
Inventory -> Product* where product does not have reference to Inventory
I would like to find all customer who dont have their product in inventory.
I have done this so far
var subQueryInv= DetachedCriteria.For<Inventory>();
subQueryInv
.Add(Restrictions.IsNotNull("Product.Id"))
.SetProjection(Projections.Property<Inventory>(inv=> inv.Product.Id));
var subQueryProd = DetachedCriteria.For<Product>();
subQueryTire
.Add(Subqueries.PropertyNotIn("Id", subQueryInv))
.SetProjection(Projections.Property<Tire>(prod=> prod.Customer.Id));
var subQueryCust= DetachedCriteria.For<Customer>();
subQueryCust
.Add(Subqueries.PropertyIn("Id", subQueryProd))
.SetProjection(Projections.Property<TireSet>(cust => cust.Id));
That works, bt the query is very innefficient, it is generating SQL like this for the Inventory part
...WHERE Product.Id NOT IN (SELECT Inventory.ProductId FROM Inventory WHERE Inventory.ProductId IS NOT NULL)
So for each product record, it is querying the entire Inventory table. How can I get the subquery to have a reference to the parent Id like this:
...WHERE Product.Id NOT IN (SELECT Inventory.ProductId FROM Inventory WHERE Inventory.ProductId IS NOT NULL AND Inventory.ProductId = Product.Id)
?

you can use an alias to reference the main criteria
var subQueryInv= DetachedCriteria.For<Inventory>();
.Add(Restrictions.IsNotNull("Product.Id"))
.Add(Restrictions.PropertyEq("Product", "product"))
.SetProjection(Projections.Property<Inventory>(inv => inv.Product.Id));
var subQueryProd = DetachedCriteria.For<Product>("product");

Related

Display Product Combinations in Prestashop Customer View

I am trying to get the product combinations displayed in Prestashop admin Customer detail view in addition to the products that are displayed for the customer.
This seems to be the relevant call from AdminCustomersController.php in public form renderForm():
$products = $customer->getBoughtProducts();
Then in the Customer class I found the method:
public function getBoughtProducts()
{
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT * FROM `'._DB_PREFIX_.'orders` o
LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
WHERE o.valid = 1 AND o.`id_customer` = '.(int)$this->id);
}
How can I modify this method to show the product combination alongside the product name?
I am using Prestashop version 1.6.0.9.
you can get it using 2 ways:
order_detail table already have field 'product_name' that contains value like 'Product Name - Combination', so you can use $products['product_name'] in that case.
or
if for some reason it is not good for you, same table contains also product_attribute_id field, it is combination id, so:
$combination = new Combination($product['product_attribute_id']);
$attributes = $combination->getAttributesName($id_lang);
var_dump($attributes);
will give you array of attributes that current combination contains.

ravendb check if item is in list

How can I query RavenDB for all "Products" which are in a list of categories?
Lets say I want all products that their category is "1" or "2" or "3". The list of categories(1,2,3) should by dynamic. it will change based on user input.
If a product can only have one category then it would something like this:
products = from p in session.Query<Product>()
where p.Category.In(new[] { 1,2,3 })
select p;
If multiple categories for a product the following should work:
products = from p in session.Query<Product>()
where p.Categories.Any(new[] { 1,2,3 })
select p;

Magento SQL Query to show product manufacturer

I am trying to query the Product Manufacturer in Magento 1.7.0.2 . I browse again and again all the table to where I can get the manufacturer table and connect it with product SKU.
I try this query to hope that I can get the manufacturers of the product:
SELECT
eav_attribute_option_value.value FROM
eav_attribute,
eav_attribute_option,
eav_attribute_option_value
WHERE
eav_attribute.attribute_code = 'manufacturer' AND
eav_attribute_option.attribute_id = eav_attribute.attribute_id AND
eav_attribute_option_value.option_id = eav_attribute_option.option_id
but it is not equal to the product manufacturer when I compare the result to my magento admin product manufacturer.
My question is that what should I do to query so that I can get the list of manufacturers of the product so that I can sql join in with catalog_product_enity's SKU.
Does anyone has an idea about my case? I am new with magento so please be gentle with me.
Any help will be appreciated, Thanks in advance
I hope I understood correctly.
If you want to get the manufacturer for a product, you don't need any query.
This should work. Let's assume that you already have the product in var $_product;
$_product->getAttributeText('manufacturer');//this gets you the label
$_product->getManufacturer(); //gets the manufacturer id
[EDIT]
To get this for all the products do this:
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('manufacturer');
$collection->addAttributeToFilter('status', 1);//optional for only enabled products
$collection->addAttributeToFilter('visibility', 4);//optional for products only visible in catalog and search
foreach ($collection as $product) {
$sku = $product->getSku();
$manufacturerId = $product->getManufacturer();
$manufacturerLabel = $product->getAttributeText('manufacturer');
//do something with the values above - like write them in a csv or excel
}
Little late, but this is what I came up with. Works like a charm.
SELECT cpe.sku, cpev.value, cpf1.manufacturer_value
FROM catalog_product_entity cpe
JOIN catalog_product_entity_varchar cpev ON cpev.entity_id = cpe.entity_id
JOIN catalog_product_flat_1 cpf1 ON cpf1.entity_id = cpe.entity_id
WHERE cpev.attribute_id = 191

NHibernate filter not applied on eagerly fetched child entities

I have a following data model:
Category
Date
Products
Product
Date
Payments
Payment
Date
I wish to eager load the whole tree using NHibernate. I thought of doing it like that:
var query = from cat in session.Query<Category>() select cat;
query = query.FetchMany(c => c.Products).ThenFetch(c=>c.Payments);
var result = query.Distinct().ToList();
This works fine. It creates an left outer join and returns the results.
But I also only want to get entities that are newer than say 01/01/2012. So I created a filter called DateFilter and added the following to the Category, Product and Payment mapping:
ApplyFilter<DateFilter>();
When I enabled the filter, I expected the generated SQL query would have the filter conditions in "WHERE" clause for Category, Product and Payment tables but it only had the condition for Category (top element).
Code:
using (var session = SessionProvider.OpenSession(ConnectionString))
{
session.EnableFilter("DateFilter")
.SetParameter("start", OracleHelper.ToDate(new DateTime(2012, 1, 1)));
var query = from cat in session.Query<Category>() select cat;
query = query.FetchMany(c => c.Products).ThenFetch(c=>c.Payments);
var result = query.Distinct().ToList();
}
Generated SQL:
SELECT ... FROM ... WHERE category_.Date >= '2012-01-01'
And what I expected was:
SELECT ... FROM ... WHERE category_.Date >= '2012-01-01'
and product_.Date >= '2012-01-01'
and payment_.Date >= '2012-01-01'
I also tried applying the filter in the mapping like this:
HasMany<Payment>(x => x.Payments).ApplyFilter<DateFilter>();
But it applies the filter on the join (puts the filter conditions in the join's ON clause) not in the "WHERE" clause, which gives wrong results using left outer join.
Is filter only appliable on the top entity and not on eager-fetched child entities ?
How else could I achieve what I want to do ?
Thanks!

Magento: Get Collection of Order Items for a product collection filtered by an attribute

I'm working on developing a category roll-up report for a Magento (1.6) store.
To that end, I want to get an Order Item collection for a subset of products - those product whose unique category id (that's a Magento product attribute that I created) match a particular value.
I can get the relevant result set by basing the collection on catalog/product.
$collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToFilter('unique_category_id', '75')
->joinTable('sales/order_item', 'product_id=entity_id', array('price'=>'price','qty_ordered' => 'qty_ordered'));
Magento doesn't like it, since there are duplicate entries for the same product id.
How do I craft the code to get this result set based on Order Items? Joining in the product collection filtered by an attribute is eluding me. This code isn't doing the trick, since it assumes that attribute is on the Order Item, and not the Product.
$collection = Mage::getModel('sales/order_item')
->getCollection()
->join('catalog/product', 'entity_id=product_id')
->addAttributeToFilter('unique_category_id', '75');
Any help is appreciated.
The only way to make cross entity selects work cleanly and efficiently is by building the SQL with the collections select object.
$attributeCode = 'unique_category_id';
$alias = $attributeCode.'_table';
$attribute = Mage::getSingleton('eav/config')
->getAttribute(Mage_Catalog_Model_Product::ENTITY, $attributeCode);
$collection = Mage::getResourceModel('sales/order_item_collection');
$select = $collection->getSelect()->join(
array($alias => $attribute->getBackendTable()),
"main_table.product_id = $alias.entity_id AND $alias.attribute_id={$attribute->getId()}",
array($attributeCode => 'value')
)
->where("$alias.value=?", 75);
This works quite well for me. I tend to skip going the full way of joining the eav_entity_type table, then eav_attribute, then the value table etc for performance reasons. Since the attribute_id is entity specific, that is all that is needed.
Depending on the scope of your attribute you might need to add in the store id, too.