I am trying to use magmi to import group and tier pricing for the not logged in group and am not sure what the format is for my csv headers or where to find it.
I have successfully used group and tier price imports with magmi on all (sku,price,tier_price:_all_), none (sku,group_price:None,tier_price:None) and other custom groups I have. A (sku,group_price:A,tier_price:A), B (sku,group_price:B,tier_price:B) and so on.
It is just the formatting for not logged in I can't figure out and I can't seem to find anything on it in the documentation.
Here is what I have tried so far.
sku,group_price:NOT LOGGED IN,tier_price:NOT LOGGED IN
sku,group_price:'NOT LOGGED IN',tier_price:'NOT LOGGED IN'
sku,group_price:_not_,tier_price:_not_
sku,group_price:General,tier_price:General
Any ideas?
yes it is works.. create directory /var/www/html/../magmi/plugins/extra/itemprocessors/groupprice
put this grouppriceprocessor.php on this directory ,
select this profile in magmi .. group_price:NOT LOGGED IN
this is header in csv file put value for this and it works ..
code of grouppriceprocessor.php
<?php
/**
* Class Tier price processor
* #author dweeves
*
* This imports tier prices for columns names called "group_price:"
*/
class GrouppriceProcessor extends Magmi_ItemProcessor
{
protected $_tpcol=array();
protected $_singlestore=0;
protected $__pricescope=2;
public function getPluginInfo()
{
return array(
"name" => "Group price importer",
"author" => "Dweeves,bepixeld,Jason",
"version" => "0.0.1",
);
}
/**
* you can add/remove columns for the item passed since it is passed by reference
* #param Magmi_Engine $mmi : reference to magmi engine instance (convenient to perform database operations)
* #param unknown_type $item : modifiable reference to item before import
* the $item is a key/value array with column names as keys and values as read from csv file.
* #return bool :
* true if you want the item to be imported after your custom processing
* false if you want to skip item import after your processing
*/
public function processItemAfterId(&$item,$params=null)
{
$pid=$params["product_id"];
$tpn=$this->tablename("catalog_product_entity_group_price");
$tpcol=array_intersect(array_keys($this->_tpcol),array_keys($item));
//do nothing if item has no group price info or has not change
if(count($tpcol)==0 )
{
return true;
}
else
{
//it seems that magento does not handle "per website" tier price on single store deployments , so force it to "default"
//so we test wether we have single store deployment or not.
//bepixeld patch : check pricescope from general config
if($this->_singlestore==0 && $this->_pricescope!=0)
{
$wsids=$this->getItemWebsites($item);
}
else
{
$wsids=array(0);
}
$wsstr=$this->arr2values($wsids);
//clear all existing tier price info for existing customer groups in csv
$cgids=array();
foreach($tpcol as $k)
{
$tpinf=$this->_tpcol[$k];
if($tpinf["id"]!=null)
{
$cgids[]=$tpinf["id"];
}
else
{
$cgids=array();
break;
}
}
//if we have specific customer groups
if(count($cgids)>0)
{
//delete only for thos customer groups
$instr=$this->arr2values($cgids);
//clear tier prices for selected tier price columns
$sql="DELETE FROM $tpn WHERE entity_id=? AND customer_group_id IN ($instr) AND website_id IN ($wsstr)";
$this->delete($sql,array_merge(array($pid),$cgids,$wsids));
}
else
{
//delete for all customer groups
$sql="DELETE FROM $tpn WHERE entity_id=? AND website_id IN ($wsstr)";
$this->delete($sql,array_merge(array($pid),$wsids));
}
}
foreach($tpcol as $k)
{
//get tier price column info
$tpinf=$this->_tpcol[$k];
//now we've got a customer group id
$cgid=$tpinf["id"];
//add tier price
$sql="INSERT INTO $tpn
(entity_id,all_groups,customer_group_id,value,website_id) VALUES ";
$inserts=array();
$data=array();
if($item[$k]=="")
{
continue;
}
$tpvals=explode(";",$item[$k]);
foreach($wsids as $wsid)
{
//for each tier price value definition
foreach($tpvals as $tpval)
{
$tpprice=str_replace(",",".",$tpval);
if($tpprice=="")
{
continue;
}
if(substr($tpprice,-1)=="%")
{
//if no reference price,skip % tier price
if(!isset($item["price"]))
{
$this->warning("No price define, cannot apply % on group price");
continue;
}
$fp=(float)(str_replace(",",".",$item["price"]));
$pc=(float)(substr($tpprice,0,-1));
$m=($pc<0?(100+$pc):$pc);
$tpprice=strval(($fp*($m))/100.0);
}
$inserts[]="(?,?,?,?,?)";
$data[]=$pid;
//if all , set all_groups flag
$data[]=(isset($cgid)?0:1);
$data[]=(isset($cgid)?$cgid:0);
$data[]=$tpprice;
$data[]=$wsid;
}
}
if(count($inserts)>0)
{
$sql.=implode(",",$inserts);
$sql.=" ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)";
$this->insert($sql,$data);
}
}
return true;
}
public function processColumnList(&$cols,$params=null)
{
//inspect column list for getting tier price columns info
foreach($cols as $col)
{
if(preg_match("|group_price:(.*)|",$col,$matches))
{
$tpinf=array("name"=>$matches[1],"id"=>null);
//if specific tier price
if($tpinf["name"]!=="_all_")
{
//get tier price customer group id
$sql="SELECT customer_group_id from ".$this->tablename("customer_group")." WHERE customer_group_code=?";
$cgid=$this->selectone($sql,$tpinf["name"],"customer_group_id");
$tpinf["id"]=$cgid;
}
else
{
$tpinf["id"]=null;
}
$this->_tpcol[$col]=$tpinf;
}
}
return true;
}
public function initialize($params)
{
$sql="SELECT COUNT(store_id) as cnt FROM ".$this->tablename("core_store")." WHERE store_id!=0";
$ns=$this->selectOne($sql,array(),"cnt");
if($ns==1)
{
$this->_singlestore=1;
}
//bepixeld patch : check pricescope from general config
$sql = "SELECT value FROM ". $this->tablename('core_config_data') ." WHERE path=?";
$this->_pricescope = intval($this->selectone($sql, array('catalog/price/scope'), 'value')); //0=global, 1=website
}
}
thanks
I found out from further testing that the tier pricing magmi plugin worked just fine with the above csv format. the original plugin I got to work with some code change but then decided to check for an update.
While searching I found an alternate magmi plugin for the group price importer and it worked.
Replace the current file in the magmi/plugins/extra/itemprocessors/groupprice folder with this one.
Here is the website found at if you would like to see more info.
Related
Trying to set the available inventory for a large amount of products within multiple locations.
The problem I am running into is there is just so many products that I need to find their inventory_item_id in order to utilize the inventoryActivate mutation.
How can I grab a list of ALL of my 9,000 products inventory_item_id without going one-by-one?
Use Case:
10 Locations used in Shopify
9,000 Products in Shopify
ERP creates and holds the physical inventory of each
Need to update the Inventory of each Product at its respective location every hour or so
I am looking at the docs found here.
You can export inventory in bulk and get your needed inventory item IDs, current quantities and location. Using that file (JSON) you can then loop through those and activate your inventory items.
I have found that we can utilize the bulkOperationRunQuery following the docs here.
I first ran the following to create the bulk operation with sku and inventoryItem:
mutation {
bulkOperationRunQuery(
query: """
{
products {
edges {
node {
id
variants(first: 5)
{
edges {
node {
id
sku
inventoryItem {
id #this is the inventory_item_id
}
}
}
}
}
}
}
}
"""
) {
bulkOperation {
id
status
}
userErrors {
field
message
}
}
}
After completed I then grabbed the Url returned from the Bulk Operation:
query {
node(id: "gid://shopify/BulkOperation/123456789") {
... on BulkOperation {
url
partialDataUrl
}
}
}
When we go to the URL we get a downloadable .jsonl file. I parsed it with PHP to grab only the sku and InventoryItem id:
print '<table>';
$file = #fopen("bulk.json", "r");
while (!feof($file)){
$line = fgets($file);
$obj = json_decode($line);
$sku = $obj->sku;
$inv_id = $obj->inventoryItem->id;
$inv_id = str_replace("gid://shopify/InventoryItem/", "", $inv_id);
if($inv_id != ''){
print "<tr>
<td>$sku</td>";
print "<td>$inv_id</td>
</tr>";
}
}
print '</table>';
This provided me with all 9,000 Products Inventory Item IDs to be used on any subsequent Inventory Updates we need to call with GraphQL.
How can to cancel particular item of an order not complete order in custom module
I found a solution for how to cancel a particular item from whole order for that set setQtyCanceled() for a particular order item :
$orderDetail = $this->_objectManager->create('Magento\Sales\Model\Order')->load(1);
if ($orderDetail->canCancel()) {
$orderItems = $orderDetail->getAllItems();
foreach ($orderItems as $value) {
if($value['product_id']==122))
{
$value->setQtyCanceled($value['qty_ordered']);
$value->save();
}
else
{
continue;
}
}
$orderDetail->save();
}
Here i want to cancel an order item of order no 1 and whose product id is 122.
This works for me
In my CE-1.9.0 store my products currently create the following url rewrites:
http://example.com/product-name
http://example.com/category/product-name
http://example.com/another-category/subcategory/product-name
However in my store I want to be able to stop creating the rewrites for the category versions. I have System > Configuration > Catalog > Catalog > Use Categories Path for Product URLs set to No so these extra rewrites are unnecessary. Plus my store has around 500,000 products and counting so these extra url's are taking up a lot of space in the core_url_rewrite` table.
So my aim is to only be left with these versions:
http://example.com/product-name
If I truncate the core_url_rewrite table and reindex then only these versions get created so it is only when new products are created. My catalog is so large so I cannot keep truncated and rebuilding the table from scratch as the rebuilding takes several hours.
With help from this question I have found the file that is responsible for creating the rewrites when a product is created. It is:
app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php
However the answer is no longer valid as the code has changed in the core file.
In this file on line #538 there is the _afterLoad function it is the line
$this->_addUrlRewrite($this->_urlRewriteCategory);
And this function _addUrlRewrite however i've tried changing a lot inside this function but have had no luck. The function in full is:
protected function _addUrlRewrite()
{
$urlRewrites = null;
if ($this->_cacheConf) {
if (!($urlRewrites = Mage::app()->loadCache($this->_cacheConf['prefix'] . 'urlrewrite'))) {
$urlRewrites = null;
} else {
$urlRewrites = unserialize($urlRewrites);
}
}
if (!$urlRewrites) {
$productIds = array();
foreach($this->getItems() as $item) {
$productIds[] = $item->getEntityId();
}
if (!count($productIds)) {
return;
}
$select = $this->_factory->getProductUrlRewriteHelper()
->getTableSelect($productIds, $this->_urlRewriteCategory, Mage::app()->getStore()->getId());
$urlRewrites = array();
foreach ($this->getConnection()->fetchAll($select) as $row) {
if (!isset($urlRewrites[$row['product_id']])) {
$urlRewrites[$row['product_id']] = $row['request_path'];
}
}
if ($this->_cacheConf) {
Mage::app()->saveCache(
serialize($urlRewrites),
$this->_cacheConf['prefix'] . 'urlrewrite',
array_merge($this->_cacheConf['tags'], array(Mage_Catalog_Model_Product_Url::CACHE_TAG)),
$this->_cacheLifetime
);
}
}
foreach($this->getItems() as $item) {
if (empty($this->_urlRewriteCategory)) {
$item->setDoNotUseCategoryId(true);
}
if (isset($urlRewrites[$item->getEntityId()])) {
$item->setData('request_path', $urlRewrites[$item->getEntityId()]);
} else {
$item->setData('request_path', false);
}
}
}
I am trying to create a new shipping method. This method allows users to COLLECT items from a paticular warehouse. So not much involved really.
I have followed a couple of tuts online, and have my module built and installed. It is working on the backend, i can enAble it, and set various values.
When i use the frontend checkout....or even use the following code:
Mage::getSingleton('shipping/config')->getAllCarriers();
I do not get the new shipping method name output.
The message i get on the frontend checkout is:
Sorry, no quotes are available for this order at this time.
Even though i have other shipping methods enabled.
I have another extension in use (regarding stock located in several warehouses). As part of this extension, it lists available shipping options...so that i can assign specific options to a specific warehouse. My new shipping method is not listed that shipping options list.
I seem to have everything required. My other extension is not picking up the method...so must be missing something.
Also, given i am getting no shipping options on frontend...confusing.
I was creating a complex shipping method...rather than a copy of the free shipping method. Turns out i actually needed a copy of the free shipping method, so made my life easier...
This was easier than i thought it would be.
Dont want to post all my code (you will also need a config.xml and system.xml file) but heres my carrier model logic file:
class Myco_Clickcollectshipping_Model_Carrier_Mymethod extends Mage_Shipping_Model_Carrier_Abstract {
protected $_code = 'mymethod ';
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
if (!$this->getConfigFlag('active')) {
return false;
}
$freeBoxes = 0;
if ($request->getAllItems()) {
foreach ($request->getAllItems() as $item) {
if ($item->getFreeShipping() && !$item->getProduct()->isVirtual()) {
$freeBoxes+=$item->getQty();
}
}
}
$this->setFreeBoxes($freeBoxes);
$result = Mage::getModel('shipping/rate_result');
if ($this->getConfigData('type') == 'O') { // per order
$shippingPrice = $this->getConfigData('price');
} elseif ($this->getConfigData('type') == 'I') { // per item
$shippingPrice = ($request->getPackageQty() * $this->getConfigData('price')) - ($this->getFreeBoxes() * $this->getConfigData('price'));
} else {
$shippingPrice = false;
}
$shippingPrice = $this->getFinalPriceWithHandlingFee($shippingPrice);
if ($shippingPrice !== false) {
$method = Mage::getModel('shipping/rate_result_method');
$method->setCarrier('mymethod ');
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod('mymethod ');
$method->setMethodTitle($this->getConfigData('name'));
if ($request->getFreeShipping() === true || $request->getPackageQty() == $this->getFreeBoxes()) {
$shippingPrice = '0.00';
}
$method->setPrice($shippingPrice);
$method->setCost($shippingPrice);
$result->append($method);
}
return $result;
}
public function getAllowedMethods()
{
return array('mymethod ' => $this->getConfigData('name'));
}
}
I have a magento site I'm building (1.6) my site has a bunch of configurable options with 6 or so attributes set as dropdowns for the customer to pick from. After saving a configurable product the order of the attributes changes. I've been able to find what I think is happening, it is reordering them according to the attribute id not the order I have them set up in the attribute set. I need to find a way to get magento to keep the order of the attributes the same as they are in the attribute set. Any help is greatly appreciated.
Trick is pretty simple.
Just drag'n'drop them in product->edit->associatedProduct tab ;)
The order of attributes from this page is saved to catalog_product_super_attribute table.
I was also looking for the same and finally i found this and it works for me hope it will work for others too.
From Admin Panel > Catalog > Attributes > Manage Attributes select the one like if you want to make it like for the capacity 4GB > 8GB > 16GB and so on then do this small changes.
Select Manage Label / Options > Manage Options (values of your attribute) and if you already created the variables just add the position manually, like:
4GB - 1
8GB - 2
16GB - 3
Save and flush the cache.
That's it, now it should show the attributes as per the position that you assign.
It is an old question but I have found a solution right now having the same problem.
If you are still interesting in changing the order of the configurable attribute you may want to look into this method:
Mage_Catalog_Model_Product_Type_Configurable::getConfigurableAttributes()
getConfigurableAttributes() load the collection of attributes.
The first time the collection is loaded, before saving the configurable, there is no position value, so I think the attribute ID rules on the display order.
If you want to alter this order you can only add a sort for attribute_id after the ->orderByPosition() and revert the order ( this will preserve the position functionality )
For example, here I have added ->setOrder('attribute_id','DESC')
public function getConfigurableAttributes($product = null)
{
Varien_Profiler::start('CONFIGURABLE:'.__METHOD__);
if (!$this->getProduct($product)->hasData($this->_configurableAttributes)) {
$configurableAttributes = $this->getConfigurableAttributeCollection($product)
->orderByPosition()
->setOrder('attribute_id','DESC')
->load();
$this->getProduct($product)->setData($this->_configurableAttributes, $configurableAttributes);
}
Varien_Profiler::stop('CONFIGURABLE:'.__METHOD__);
return $this->getProduct($product)->getData($this->_configurableAttributes);
}
OR
In case you want to modify the order in more radical way, you can also act on this method:
Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config::getAttributesJson()
This is basically calling the getConfigurableAttributes().
To understand if this is the first configurable load, you can check all the attributes in the array $attributes to see if they all have a position ==0 and then proceed with a manual reorder )
Example
I'm omitting all the module creation and the rewrite part.
Here an example modifying getAttributesJson() in order to have the color attribute always on the top.
public function getAttributesJson()
{
$attributes = $this->_getProduct()->getTypeInstance(true)
->getConfigurableAttributesAsArray($this->_getProduct());
if (!$attributes) {
return '[]';
} else {
// == START ==
// checking if I can re-order
if ($this->isNoSavedPosition($attributes)) {
$attributes = $this->attributeReorder($attributes);
}
// == END ==
// Hide price if needed
foreach ($attributes as &$attribute) {
if (isset($attribute['values']) && is_array($attribute['values'])) {
foreach ($attribute['values'] as &$attributeValue) {
if (!$this->getCanReadPrice()) {
$attributeValue['pricing_value'] = '';
$attributeValue['is_percent'] = 0;
}
$attributeValue['can_edit_price'] = $this->getCanEditPrice();
$attributeValue['can_read_price'] = $this->getCanReadPrice();
}
}
}
}
return Mage::helper('core')->jsonEncode($attributes);
}
public function isNoSavedPosition($attributes)
{
foreach ($attributes as $attribute) {
if (isset($attribute['position']) && $attribute['position'] != 0) {
return false;
}
}
// there is no position saved
// - this is the first time the configurable is loaded
// - (the position is saved on second save action)
return true;
}
public function attributeReorder($attributes)
{
// we want the Color attribute to be always on the top
$newAttributesOrderArray = array();
foreach ($attributes as $key => $attribute) {
if (isset($attribute['label']) && $attribute['label'] == 'Color') {
$newAttributesOrderArray[] = $attribute;
unset($attributes[$key]);
}
}
$newAttributesOrderArray = array_merge($newAttributesOrderArray,$attributes);
return $newAttributesOrderArray;
}