I'm trying to import an orders file with a custom order status.
Code for new custom status:
register_post_status(
'wc-cc-shipping',
array(
'label' => 'CC Awaiting shipping',
'public' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'CC shipping (%s)', 'CC shipping (%s)' ),
)
);
On the site, everything works as excepted.
but when I'm trying to import a csv file with this custom order status, it does not recognize this order status.
So my first question is, is it possible to import with different order statuses?
and if it is possible, what status name do I need to point in my csv file? to the wc-cc-shipping (like in the example)?
Related
I have a script that creates a configurable product and the simple products associated to it. After the creation, in the backend, all of them seems fine (stock, website, status, visibility and association between the simple products and the configurable are ok). The problem is when I try to search for the configurable product or add it to a category, it doesn't display.
All products (configurable and simple) are firstly created with this method:
private function createBaseProduct($sku)
{
$_product = Mage::getModel('catalog/product');
$_product->setSku($sku);
$_product->setAttributeSetId(4);
$_product->setTypeId('simple');
$_product->setWebsiteIDs(array(1));
$_product->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH);
$_product->setStatus(1);
$_product->setTaxClassId(0);
$_product->setStockData(array(
'use_config_manage_stock' => 0,
'manage_stock' => 1,
'is_in_stock' => 1,
'qty' => 100
));
return $_product;
}
In case the product is configurable, it then goes to this method:
private function setData($configurable)
{
$configurable->setTypeId('configurable');
$configurable->setStockData(array(
'use_config_manage_stock' => 0,
'manage_stock' => 0,
'is_in_stock' => 1,
'qty' => 0,
));
--> $configurable = $this->setAssociativeAttributes($configurable);
$configurableAttributesData = $configurable->getTypeInstance()->getConfigurableAttributesAsArray();
$configurable->setCanSaveConfigurableAttributes(true);
$configurable->setConfigurableAttributesData($configurableAttributesData);
return $configurable;
}
Where the method setAssociateAttributes() set the attributes IDs of the configurable product being created:
private function setAssociativeAttributes()
{
$configurable->getTypeInstance()->setUsedProductAttributeIds($this->configurableAttrsIds);
return $configurable;
}
After that, the configurable product returned in setData() is saved using $product->save(). Then, the simple product's are created (using the createBaseProduct() method), saved, and assigned to the configurable product using this method:
public function associateChildProduct($configurableId, $childProduct)
{
$configurable = Mage::getModel('catalog/product')->load($configurableId);
$childProducts = $configurable->getTypeInstance()->getUsedProducts();
array_push($childProducts, $childProduct);
$childProductsIds = array();
foreach($childProducts as $product) {
array_push($childProductsIds, $product->getId());
}
Mage::getResourceSingleton('catalog/product_type_configurable')
->saveProducts($configurable, $childProductsIds);
}
And all seems good, products are created and correctly assigned to configurable. But in the frontend the configurable product isn't displayed (only if I access it via URL it opens correctly, with the variations and all).
Obs.: simple products are displayed in search correctly, only the configurable is missing.
I believe there's something wrong in the configurable's data, but I can't figure it out :(
----- EDIT -----
So I debugged it a little more and seems that the problem is actually in the attribute used to create the configurable product (I'm also creating this attribute programmatically). If I save the attribute created programatically again, in my admin panel, the link between simple products and their configurable disapear (they don't show linked in the admin panel anymore).The attribute is created before the configurable product using class "CustomAttribute":
public function __construct($attrCode)
{
$attrData = array(
'group' => '',
'type' => 'varchar',
'backend' => '',
'frontend' => '',
'label' => ucfirst($attrCode),
'input' => 'select',
'class' => '',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
'visible' => true,
'required' => false,
'user_defined' => true,
'default' => '0',
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'is_configurable' => true,
'unique' => false,
);
$installer = new Mage_Eav_Model_Entity_Setup('core_setup');
$installer->startSetup();
$installer->addAttribute(Mage_Catalog_Model_Product::ENTITY, $attrCode, $attributeData);
$this->addAttributeToDefaultSet();
$installer->endSetup();
}
And this attribute is set to child products (during their creation) using the following method:
private function setCustomAttribute($chidlProduct, $attrCode, $optionLabel)
{
$customAttribute = new CustomAttribute($attrCode);
$customAttribute->addOptionIfNotExists($optionLabel, $attrCode);
$optionId = $customAttribute->getOptionId($optionLabel);
$product->setData($attrCode, $optionId);
}
Where the method $customAttribute->addOptionIfNotExists() creates the attribute's option if not already created:
public function addOptionIfNotExists($optionLabel, $attrCode)
{
$value['option'] = array($optionLabel);
$order['option'] = 0;
$optionData = array(
'value' => $value,
'order' => $order
);
$attribute = Mage::getSingleton('eav/config')
->getAttribute(Mage_Catalog_Model_Product::ENTITY, $attrCode);
$attribute->setData('option', $optionData);
$attribute->save();
}
And after added the method associateChildProduct() is called to associate simple products to their configurable.
Obs.: configurable product is displayed correctly via URL, even the attribute variations are shown.
Obs2.: if I save the attribute via admin panel, delete simple products and create new ones using "Quick create" (with the same values) the configurable product is displayed in search and categories.
Just to put my comments in form of an answer, and organize it...
There are many reasons for a recently created product or one created programmatically to not being displayed in some collection.
Index
The first and most common one is related to indexation.
This could be related to issues in the cronjob (not configured, or not working properly).
You can manually trigger the reindex process by doing:
Magento 1: php shell/indexer.php reindexall
Magento 2: bin/magento indexer:reindex
Product not added to the website or not visible
Check if the product is enabled and visible in catalog. If they are simple products from a configurable product, make sure they are both enabled.
Also check if there is enough inventory of the item and if they are not marked as "out of inventory" (regardless the stock qty).
In multi website stores, check the "Website" group in the product edit page, and see if it's checked to appear in that website. Also check the product scope. Sometimes you disable the product in a inner level (i.e. store view or website).
Some condition is not met
If you believe that you've checked everything, now it's time to debug the collection.
Magento 1 and Magento 2 have the getSelect() method available in collection objects.
Find the phtml or block where your products are being looped, and find the collection variable (generally used in the foreach).
Then, add something like echo (string)$collection->getSelect().
This will show the query used to search the products. See which join or where condition is not met by your missing product.
Here's an example of category collection queries in Magento 1:
SELECT `e`.*,
`cat_index`.`position` AS `cat_index_position`,
`price_index`.`price`,
`price_index`.`tax_class_id`,
`price_index`.`final_price`,
IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price),
price_index.min_price) AS `minimal_price`,
`price_index`.`min_price`,
`price_index`.`max_price`,
`price_index`.`tier_price`
FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_category_product_index` AS `cat_index`
ON cat_index.product_id = e.entity_id AND cat_index.store_id = 4 AND
cat_index.visibility IN (2, 4) AND cat_index.category_id = '10'
INNER JOIN `catalog_product_index_price` AS `price_index`
ON price_index.entity_id = e.entity_id AND price_index.website_id = '4' AND
price_index.customer_group_id = 0
ORDER BY `cat_index`.`position` ASC
LIMIT 12
1 'New Arrivals' category from Magento 1 sample data.
With Ricardo Martins help I was able to debug the problem and discover that the configurable product wasn't being displayed because it's entity_id wasn't being added to the table catalog_product_index_price. This problem seems to be caused because the attribute used in the configurable product's creation had the backend_type set to varchar, instead int (Reference).
So I changed my code for attribute's creation to:
public function __construct($attrCode)
{
$attrData = array(
'group' => '',
--> 'type' => 'int',
'backend' => '',
'frontend' => '',
'label' => ucfirst($attrCode),
'input' => 'select',
'class' => '',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
'visible' => true,
'required' => false,
'user_defined' => true,
'default' => '0',
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'is_configurable' => true,
'unique' => false,
);
$installer = new Mage_Eav_Model_Entity_Setup('core_setup');
$installer->startSetup();
$installer->addAttribute(Mage_Catalog_Model_Product::ENTITY, $attrCode, $attributeData);
$this->addAttributeToDefaultSet();
$installer->endSetup();
}
Where in the indicated line the attribute's backend_type is set to int. After this, the configurable product is now being correctly displayed in category and search :)
I am building a WooCommerce based store. I have a list of postcodes, each one has a different shipping cost attached through Shipping Zones (some provide free shipping, some have a flat rate).
When the customer goes to the checkout page, he needs to type his postcode number in the input field. Depending on postcode, an order preview will show different shipping total (free or flat rate).
Here's how the input field looks like in class-wc-countries.php:
public function get_default_address_fields() {
$fields = array(
'postcode' => array(
'label' => __( 'Postcode/ZIP', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-first', 'address-field' ),
'clear' => true,
'validate' => array( 'postcode' ),
'autocomplete' => 'postal-code',
),
);
However, what I want to do is to turn this field into a drop-down menu, so the customer could just select his postcode option rather than type it.
I managed to make it drop-down, but whenever I choose any option it doesn't seem to change shipping total as it would with input field.
Here's what I did:
public function get_default_address_fields() {
$fields = array(
'postcode' => array(
'label' => __( 'Postcode/ZIP', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-first', 'address-field' ),
'clear' => true,
'validate' => array( 'postcode' ),
'autocomplete' => 'postal-code',
'type' => 'select',
'options' => array(
'opt1' => "001122", "112200", "334400")
),
);
But this don't work.
Am I missing something?
How do I make these drop-down options change shipping total?
Thanks
This will answer very partially to your question, and just show you the way to customize checkout fields.
Overriding core files is not really something to do, as you will loose everithing each time Woocommerce is going to be updated and is not recommended.
To override checkout fields in a clean way, first you need to use a custom function hooked in one of that 2 filter hooks:
woocommerce_default_address_fields (when customizing billing and shipping address default fields)
woocommerce_checkout_fields (when customizing billing or shipping address fields and also others fields).
Related official documentation: Customizing checkout fields using actions and filters
So here I have chose the first hook, and I have corrected your post codes array. You will get that:
Here is that functional and tested code:
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_postcode_field' );
function custom_override_default_postcode_field( $address_fields ) {
// Your postcodes array
$postcode_array = array(
'opt1' => "001122",
'opt2' => "112200",
'opt3' => "334400"
);
$address_fields['postcode']['type'] = 'select';
$address_fields['postcode']['options'] = $postcode_array;
return $address_fields;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
As selecting a post-code is a live front-end event, you will need to use a complex javascript/ajax script with some remote php function to achieve what you want to do, and this is a real development... It also depends on your settings and is complex to handle as there is already some woocommerce ajax scripts operating in that checkout page.
I'm creating products by code.
I'm using Fixed Product Tax with attributo (eco_tax)
It turns out that is not being inserted the rate information, which are they (country, state, value) other product information is OK and the product is created normally, but without the fee.
I am using the following code
->setFpt(array(
'website_id'=>0,
'country'=>'BR',
'state'=>'0',
'price'=>10.0000,
));
What am I doing wrong?
Solution
I found the solution
->setData("eco_tax", array(
array(
'website_id' => 0,
'country' => 'BR',
'state' => '',
'price' => 10.000,
'delete' => ''
)0
));
I'm trying to use S2Members 'Payment Notification API' to create an order in WooCommerce when a payment is processed.
I'm going to be batch shipping my product once a month to all members who've paid for access that month, I plan on exporting a CSV from WooCommerce and shipping to all of the orders for that month. I figure this is the easiest way to track my paid orders and ensure all paying subscribers receive their product.
I'm using this as a base for my work:
http://www.s2member.com/kb/building-an-api-notification-handler/
In my S2Member notification URL I've got the following:
http://www.MYURL.co.uk/?s2_payment_notification=yes&first_name=%%first_name%%&last_name=%%last_name%%&payer_email=%%payer_email%%&address_one=%%address_one%%&address_two=%%address_two%%&address_three=%%address_three%%&postcode=%%postcode%%
In my mu-plugin I've got the following PHP
<?php
add_action('init', 's2_payment_notification'); function s2_payment_notification()
{
if(!empty($_GET['s2_payment_notification']))
{
if(!empty($_GET['first_name']) && !empty($_GET['last_name']) && !empty($_GET['payer_email']) && !empty($_GET['address_one']) && !empty($_GET['address_two']) && !empty($_GET['address_three']) && !empty($_GET['postcode']))
{
$address = array(
'first_name' => '%%first_name%%',
'last_name' => '%%last_name%%',
'company' => '',
'email' => '%%payer_email%%',
'phone' => '',
'address_1' => '%%address_one%%',
'address_2' => '%%address_two%%',
'city' => '%%address_three%%',
'state' => '',
'postcode' => '%%postcode%%',
'country' => ''
);
$order = wc_create_order();
$order->add_product( get_product( '99' ), 1 );
$order->set_address( $address, 'billing' );
$order->set_address( $address, 'shipping' );
$order->calculate_totals();
}
exit;
}
}
The custom fields are set up in S2Member for the address and postcode and I have a product that's got the ID '99'
From what I can see, this should be adding my payees details to a new woocommerce order for 1 of product '99' when a payment notification is received from Stripe...but I can't seem to get it working
What am I missing?
Essentially what I wasn't doing here was actually telling the array what the variables were. Create the variables by using GET to parse the URL and this works perfectly.
I'm quite new in magento, I work version 1.6.2.0.
I'm trying to add my own Custom Shipping Method module and I have few problems.
My magento has already custom checkout module - Threestep checkout, what I'm trying to do is save additional shipping info which I choose in 3rd step (Payment and Shipping) (something like Store Pickup place) to Quote, and then in Review retrive Quote data and save it to Order.
I'm using Events to do this:
checkout_controller_onepage_save_shipping_method to save data to Quote
checkout_type_onepage_save_order to save data to Order
The problem is that Quote and Order doesn't have any free place where i can save my data, so I created installer for my module:
$installer = $this;
$installer->startSetup();
$packboxName = array(
'type' => 'varchar',
'backend' => '',
'frontend' => '',
'label' => 'packboxname',
'input' => '',
'class' => '',
'source' => '',
'global' => 1,
'visible' => true,
'required' => false,
'user_defined' => false,
'default' => '',
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'visible_in_advanced_search' => false,
'unique' => false
);
$installer->addAttribute('order', "packboxname", $packboxName);
$installer->getConnection()->addColumn($installer->getTable('sales/order'), 'packboxname', 'varchar(255) DEFAULT NULL');
$installer->addAttribute('quote', "packboxname", $packboxName);
$installer->getConnection()->addColumn($installer->getTable('sales/quote'), 'packboxname', 'varchar(255) DEFAULT NULL');
$installer->endSetup();
And i got a error saying that
$installer->addAttribute('quote'
has wrong Entity Id.
So I checked DB, table: eav_entity_type and there wasn't any 'quote' type (hopefully there was a 'order') I didn't really know what I should do so, I tried to google something, I found tutorial and modified my installer.
$installer->addEntityType('quote', array(
'entity_model' => 'sales/quote',
'table' =>'sales/quote',
));
Now it's working I have additional place where I can save my info, but my friend told me that I shouldn't use addEntityType, Is there any other way to achive what I need?
I think perhaps what you're looking for can be found in this answer: https://stackoverflow.com/a/4389786/823549
An important point made in that answer is the event fired, sales_convert_quote_to_order - this will get fired when the quote is being converted to an order, and will happen regardless of what your other checkout module does. This answer is also useful as you can see the details of your custom column in the orders grid page.