Reducing the number of products in stock management - laravel

I want it to reduce the number of products in the cart from stock after the order is placed. sample: The product stock with 5 IDs is 50 pieces, if 5 orders are received from this product,I want it updated to be 50 - 5 = 45.
note:number=the quantity of the product in the current order
more detailed: There is number in the cart_product table, stock in the products table,Number of products in cart_product,Taking the number from the cart_product table and subtracting it from the stock in the product table, but i didn't succeed can you help me please
DB::table('products')
->join('products', 'products.id', 'cart_product.product_id')
->join('cart_product', 'cart.id', 'cart_product.main_cart_id')
->where(session('active_cart_id'),'=','cart_product.main_cart_id')
->orWhere('cart_product.product_id','=','products.id')
->update();

// Fetch items in the cart
$cartItems = DB::table('cart_product')
->where('main_cart_id', session('active_cart_id'))
->get();
foreach ($cartItems as $cartItem) {
// Update stocks in the "products" table
DB::table('products')
->where('id',$cartItem->product_id)
->decrement(
'AAAAA',
$cartItem->BBBBB;
);
}
I couldn't use the column names since I don't know. Keep in mind that you need to change the following texts in the code:
AAAAA => Column name of the purchased item amount in "cart_product" table.
$cartItem->BBBBB => Column name of item stock in "products" table.
For more information about increment and decrement methods, you can look at https://laravel.com/docs/9.x/queries#increment-and-decrement

it worked like this
// Fetch items in the cart
$cartItems = DB::table('cart_product')
->where('main_cart_id', session('active_cart_id'))
->get();
foreach ($cartItems as $cartItem) {
// Update stocks in the "products" table
DB::table('products')
->where('id',$cartItem->product_id)
->decrement(
'stock',
$cartItem->number
);}

Related

Product not shown with relation in Laravel

I have this two tables:
One is Product Table :
id
Title
Price
1
Title 1
5000
2
Product 2
7000
and the other is product attribute table:
id
product_id
attribute_id
attribute_name
value
1
1
5
Color
Red
2
1
6
Size
XL
3
2
5
Color
Green
Product and Product attribute is related with following relation (In the product model):
public function attributes()
{
return $this->hasMany(ProductsAttribute::class, 'product_id ');
}
I'm fetching data like this :
return Product::with('attributes')
->whereHas('attributes', function ($query) use ($attribute_id,$attribute_value){
$query->whereIn('attribute_id', $attribute_id);
$query->whereIn('value', $attribute_value);
})
->paginate(10);
Issue is if there is no attribute in the product attribute table which are related to a particular product then that product is not shown in the search, but my requirement is if related attribute is not there then also product should be shown in the result.
Any help is highly appreciated.
You are using the constraint in the whereHas that is why it excludes the product records from the results where the condition evaluates to false.
Try
return Product::with(['attributes' => function ($query) use ($attribute_id,$attribute_value){
$query->whereIn('attribute_id', $attribute_id)
->whereIn('value', $attribute_value);
})
->paginate(10);

Advice with Magento large productsfile csv import

I need to import 40.000 products.
These products together are generating 600.000 attribute values
There is a csv file with product info (Sku, Name, Description and Ean) and a seperate sheet with only the attributes(600K)
On each row i have:
Sku - Attribute - Value
e.g.
123 Color Green
123 Length 120
123 Size XL
456 Color White
456 Length 260
etc..
I have filtered all duplicates out which resulted in 2200 unique Attributes.
What should i Do with these attributes?
Put them all in one attributeset? Will it hurt the performance of the webshop?
And what about the attributesheet?
How should i convert the structure of the presented data so it will be usefull for for import in magent? Cause magento needs all attribute names as columnheaders?
I have tried to collect teh attribute values with VLOOKUP but run into memory problems on my MACbook Pro. Fill down one column with a formula doesn't work wit this amount of records.
Maybe there is a solution programmticly.
Thanks!
I would suggest to create product pragmatically.
Import product into a mysql table (tables) and create using magento code directly.
You can create configurable attributes and use its id when creating products.
You should think about using uRapidFlow.
While I am not a huge fan of the fact that it uses direct sql to import products, it has been around for some time and is known to be very reliable and very fast.
//add new products
$product = Mage::getModel('catalog/product');
$product->setSku($sku);
$product->setStatus(1);
$product->setName($name);
$product->setDescription($details);
$product->setShortDescription($description);
$product->setPrice(0);
$product->setTypeId('simple');
$product->setAttributeSetId(4); // enter the catalog attribute set id here
$product->setCategoryIds($categoryIds); // id of categories
$product->setWeight(1.0);
$product->setTaxClassId($taxClassId);
$product->setVisibility($visibility);
$product->setStatus($productStatus);
$product->setColor('color',$color_id); // u need to get attribute code for dropdown items
$product->setData('material', $avid);
$product->setBrand($brand);
/*$product->setStockData(
array(
'manage_stock' => 1,
'is_in_stock' => 1,
'qty' => $qty
)
);*/
// assign product to the default website
$product->setWebsiteIds(array(1,2,3,4));
try{
$product->save();
$i++;
;
}catch (Exception $e) {
echo Mage::logException($e->getMessage());
}
$id = Mage::getModel('catalog/product')->getIdBySku(trim($sku)); //get product id after create
//add dropdown items for attribute u created already, u need to make this as function to get option id before add a product
$attribute_model = Mage::getModel('eav/entity_attribute');
$attribute_options_model= Mage::getModel('eav/entity_attribute_source_table') ;
$attribute_code = $attribute_model->getIdByCode('catalog_product', $attribute_code);
$attribute = $attribute_model->load($attribute_code);
$attribute_table = $attribute_options_model->setAttribute($attribute);
$options = $attribute_options_model->getAllOptions(false);
foreach($options as $option)
{
if (strtolower($option['label']) == strtolower($label))
{
$optionId=$option['value'];
break;
}
}
//u need to run thru a loop to add products

Magento Shopping Cart Rule - Is this combination possible

Hoping some one can help me with a Magento Rule - is this rule even possible
I have numerous products of numerous sizes all part of the same category.
Each product regardless of size costs £3.98 - If a buyer buys 3 products of the same category regardless of the product or size they get it for £9.99. If they buy 4 products, they get 3 of them for 9.99 but pay full price for the 4th...Every group of 3 is £9.99
I have a rule created that seems to work perfect if a Customer buys 3 / 6 / 9 items of the same product and same size...However if they mix and match it doesn't work (though they are the same category)
The rule is:
IF ALL of these conditions are TRUE:
If total quantity equals or greater than 3 for a subselection of items in cart matching ALL of these conditions:
Category is 4
I have also set the Discount Qty Step to be 3
* UPDATE *
Thanks for your reply - I have tried to implement what you suggest and have got so far as to where I get the category id of the added products. I'm unsure how to set the price the previous products so it will be an automatically discounted price
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
$itemPrice = "3.33";
foreach ($cartItems as $items) {
$product = $items->getProduct();
$prodCats = $product->getCategoryIds();
if (in_array('4', $prodCats)) {
$itemQty = $items->getQty();
}
$totalItems += $itemQty;
}
So what I want to do is apply a discount for multiple of 3's for any product that has a category_id of 4...The price will be 3.33 instead of the normal 3.99
You need event - observer approach for this, that will give you the flexibility you need. You can build an observer that catches the add-to-cart event sales_quote_add_item and put your logic there.
Following code within your observer function will point you in the right direction:
// Get products in cart:
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
foreach ($cartItems as $item) {
$itemSku = $item->getSku();
$itemQty = $item->getQty();
}
// Added product:
$item = $observer->getEvent()->getQuoteItem();
$itemQty = $item->getQty();
$itemSku = $item->getSku();
// Change price of added product:
$item->setOriginalCustomPrice($newPrice);
Good luck!

Magento 1.7 Append Complex Data

I am trying to append a category id to a large number of SKUs in Magento 1.7. I have used the Import > Append Complex Data and, although it checked the file and ran ok, it did not add these SKUs to the category I wanted them in.
So, the objective is to leave all these SKUs in the categories there are in now but add an additional category.
Any help would be appreciated. Even if it is a different method entirely.
The fastest way to do this is to directly insert this as a SQL query using:
INSERT INTO `catalog_category_product` (
`category_id` ,
`product_id` ,
`position`
)
VALUES (
'4', '34', '0'
), (
'4', '35', '0'
);
In this case, it would add the category Id of 4 to the products with Id 34 and 35. You can create a small PHP script to dynamically create such a query from your file of SKUs and Category Ids.
Reindex after your query was successfully executed.
Alternatively, using the Magento eco-system and not the database, you can do this:
$categoryIds = array();
$toBeUpdatedProducts = array(4,6,7); // all the Ids you want to update
$newCategoryId = 65; // Id of new category
foreach ($toBeUpdatedProducts as $productId) {
$product = Mage::getModel('catalog/product')->load($productId);
$categoryIds = $product->getCategoryIds();
$categoryIds[] = $newCategoryId; // Add new category to existing ones
$product->setCategoryIds($categoryIds);
$product->save();
}

Magento - addStoreFilter not working?

When getting a product collection in Magento, I would expect the StoreFilter to do just that, filter by the current store. But I can't get it to work.
Say I have 2 stores set up like so:
And both stores have a different root category. Main Store is the default sample data, Store2 has just one product I added. I would have thought that using the store filter, only products within the root category of the current store would show up. But I'm getting every product showing. I'm testing this by placing the following in my category view template:
$store_id = Mage::app()->getStore()->getId();
$_testproductCollection = Mage::getResourceModel('reports/product_collection')
->setStoreId($storeId)
->addStoreFilter($store_id)
->addAttributeToSelect('*');
$_testproductCollection->load();
foreach($_testproductCollection as $_testproduct){
echo $this->htmlEscape($_testproduct->getName());
};
If I echo the store ID, it's giving me the correct number. I have only one product in Store 2, so why am I getting every product from all stores returned? I can set every product in Main Store to not show in Store2 and then add a visibility filter, but that would take forever.
Also, I just noticed, if I echo the products store ID, I get the current ID, not the store it's assigned to:
echo $_testproduct->getStoreId()
What's going on?
UPDATE (April 8 2011):
OK, so I tried joining the fields so that the store_id is included (as suggested below), the section of code {{table}}.store_id = 1 is just setting all the products to have a store_id of 1. How can I just get the store_id associated with the product?
$_testproductCollection = Mage::getResourceModel('catalog/product_collection');
$_testproductCollection->joinField('store_id', 'catalog_category_product_index', 'store_id', 'product_id=entity_id', '{{table}}.store_id = 1', 'left');
$_testproductCollection->getSelect()->distinct(true);
$_testproductCollection->addAttributeToSelect('*')->load();
foreach($_testproductCollection as $_testproduct){
echo $this->htmlEscape($_testproduct->getName())."<br/>";
echo "STORE IS ".$_testproduct->getData('store_id')."<br/>";
};
If I check the catalog_category_product_index table of my db, the store_id's are correct.
$_testproductCollection should look like this $_testproductCollection = Mage::getResourceModel('reports/product_collection')->addAttributeToSelect('*')->addStoreFilter().
If You print SELECT from that collection You will see that there ain't any store column, so addStoreFilter() can't apply WHERE.
You should use joinField() on Your collection and add store_id column from catalog_product_entity_varchar table.
EDIT
Sorry to keep You waiting ;)
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->joinField('store_id', 'catalog_category_product_index', 'store_id', 'product_id=entity_id', '{{table}}.store_id = 1', 'left');
$collection->getSelect()->distinct(true);
This should do the trick, but just to be sure, please check if you're getting right products :)
This worked for me:
Mage::app()->setCurrentStore($storeId);
$productCollection = Mage::getModel('catalog/product')
->getCollection()
->addStoreFilter()
->addAttributeToSelect(array('sku','price'));
OK, I think this works, haven't tested too much but seems to have done the trick. You need to first get your stores root category id, then join some fields so you have access to the products "category_id", then filter using that:
$_rootcatID = Mage::app()->getStore()->getRootCategoryId();
$_testproductCollection = Mage::getResourceModel('catalog/product_collection')
->joinField('category_id','catalog/category_product','category_id','product_id=entity_id',null,'left')
->addAttributeToFilter('category_id', array('in' => $_rootcatID))
->addAttributeToSelect('*');
$_testproductCollection->load();
foreach($_testproductCollection as $_testproduct){
echo $this->htmlEscape($_testproduct->getName())."<br/>";
};
I think
You don't need to do any joins as the magento's setStoreId() will work.
$collection = Mage::getModel("catalog/product")
->getCollection()
->setStoreId(1) //change store Id according your needs
->addAttributeToSelect(array('name','url','sku'))
->setPageSize(20);
This will get maximum 20 products from store id 1

Resources