I'd like to create a shopping cart price rule that gives a user 10% off their order when and if they complete a process on my Magento site.
There's a method here that inserts the rule directly to the database. That's a bit invasive for my tastes.
How would I go about this using Magento methods?
As a general principle, you should be able to do anything that the Magento system itself does without writing a single line of SQL. Almost all the Magento data structures use Magento Model classes.
Run the following code somewhere to see what a salesrule/rule model looks like. This assumes you've created a single Shopping Cart Price Rule in the admin with an ID of 1
$coupon = Mage::getModel('salesrule/rule')->load(1);
var_dump($coupon->getData());
Using the dumped data as a guide, we can programatically create a model using the following
$coupon = Mage::getModel('salesrule/rule');
$coupon->setName('test coupon')
->setDescription('this is a description')
->setFromDate('2010-05-09')
->setCouponCode('CODENAME')
->setUsesPerCoupon(1)
->setUsesPerCustomer(1)
->setCustomerGroupIds(array(1)) //an array of customer grou pids
->setIsActive(1)
//serialized conditions. the following examples are empty
->setConditionsSerialized('a:6:{s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}')
->setActionsSerialized('a:6:{s:4:"type";s:40:"salesrule/rule_condition_product_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}')
->setStopRulesProcessing(0)
->setIsAdvanced(1)
->setProductIds('')
->setSortOrder(0)
->setSimpleAction('by_percent')
->setDiscountAmount(10)
->setDiscountQty(null)
->setDiscountStep('0')
->setSimpleFreeShipping('0')
->setApplyToShipping('0')
->setIsRss(0)
->setWebsiteIds(array(1));
$coupon->save();
For anyone that's curious, the above is generated code, using the technique discussed here
Have a look at my code.It will add Action condition.
$coupon_rule = Mage::getModel('salesrule/rule');
$coupon_rule->setName($c_data[1])
->setDescription($c_data[2])
->setFromDate($fromDate)
->setToDate($toDate)
->setUsesPerCustomer(0)
->setCustomerGroupIds(array(0,1,2,3)) //an array of customer grou pids
->setIsActive(1)
->setCouponType(2)
->setCouponCode($c_data[0])
->setUsesPerCoupon(1)
//serialized conditions. the following examples are empty
->setConditionsSerialized('')
->setActionsSerialized('')
->setStopRulesProcessing(0)
->setIsAdvanced(1)
->setProductIds('')
->setSortOrder(0)
->setSimpleAction('by_percent')
->setDiscountAmount($c_data[5])
->setDiscountQty(1)
->setDiscountStep('0')
->setSimpleFreeShipping('0')
->setApplyToShipping('1')
->setIsRss(1)
->setWebsiteIds(explode(',',$c_data[6]));
$sku =$c_data[7]; // Put your product SKU here
$skuCond = Mage::getModel('salesrule/rule_condition_product')
->setType('salesrule/rule_condition_product')
->setAttribute('sku')
->setOperator('==')
->setValue($sku);
$coupon_rule->getActions()->addCondition($skuCond);
$coupon_rule->save();
echo "New Coupon was added and its ID is ".$coupon_rule->getId().'<br/>';<br/>
If you want to add Condition for shopping cart price rule then follow this example.
$sku =$c_data[7]; // Put your product SKU here
$found = Mage::getModel('salesrule/rule_condition_product_found')
->setType('salesrule/rule_condition_product_found')
->setValue(1) // 1 == FOUND
->setAggregator('all'); // match ALL conditions
$coupon_rule->getConditions()->addCondition($found);
$skuCond = Mage::getModel('salesrule/rule_condition_product')
->setType('salesrule/rule_condition_product')
->setAttribute('sku')
->setOperator('==')
->setValue($sku);
$found->addCondition($skuCond);
$coupon_rule->save();
Related
I'm currently working on a shopping application but i stumbled upon a problem. The problem is that i can't select the JSON values from my "shopping cart". See the following code and description.
So by using add to cart buttons and such i'm creating the shopping cart. The shopping cart is actually a JSON object. An example of the cart:
{"cartItems":{"2":{"id":"2","name":"Blouse","price":26.99,"size":"M","quantity":"3","total_product_price":80.97},"5":{"id":"5","name":"Bedrukte Zomerjurk","price":30.5,"size":"L","quantity":"4","total_product_price":122}},"totalPrice":202.97,"totalItems":2,"customerSelect":{"id":"1","firstname":"John","lastname":"TestStefans"}}
As you can see the design of my JSON cart is:
cart:{"cartItems":{"id":{ product information }}}
The problem now is trying to select the values like the "name" and "price". This due to the "id"{ segment. But i need that piece for removing one item by id from the cart.
So my question is:
How would i be able to select all the product information and create an foreach for placing the information in the database / email template. I've been trying this but this only gave me the first product:
$cart_encode = json_encode($_SESSION['cart']['cartItems']);
$cartDecode = json_decode($cart_encode);
// Adding the product items
foreach ($cartDecode as $key => $cartItem) {
$resource->associations->cart_rows->cart_row->id_product = $cartItem->{"id"};
$resource->associations->cart_rows->cart_row->id_product_attribute = 1;
$resource->associations->cart_rows->cart_row->id_address_delivery = 1;
$resource->associations->cart_rows->cart_row->quantity = $cartItem->{"quantity"};
}
Take note that i'm using XML for database input. For the email template i've tried:
$testName = $_SESSION['cart']['cartItems']['name'];
$testPrice = $_SESSION['cart']['cartItems']['price'];
$testQuantity = $_SESSION['cart']['cartItems']['quantity'];
$testTotal = $_SESSION['cart']['cartItems']['total_product_price'];
$testProduct = array(
"Name:" => $testName,
"Price:" => $testPrice,
"Quantity" => $testQuantity,
"Total" => $testTotal
);
Iknow that the id number is missing but i cant dynamicly avoid that layer.
I hope that my question is clear
As always. Thanks in advance!
I need add coupon code from $100 to newsletter. I did rewrite \Magento\Newsletter\Model\Subscriber in the method sendConfirmationSuccessEmail
->setTemplateVars(
['subscriber' => $this,
'coupon_code' => $this->getCouponCode()
])
protected function getCouponCode() {
. . .
. . .
return $couponCode;
}
How automatically generate coupon code in magento 2?
Have you defined a Shopping Cart Price Rule? If not, that's where to start. In the admin area, go to Promotions > Shopping Cart Price Rules > Add New Rule, and define a Specific Coupon with Use Auto Generation selected.
Once you have defined the rule for whatever specific discount you wish to offer, save the rule and make a note of the rule ID from the the Shopping Cart Price Rules row showing the rule you just created.
Then add something like the following, using the rule ID of the rule you just created:
The function below takes an associative array with the following options:
rule_id = the rule ID, from above
qty = number of coupon codes to instruct Magento to generate
length = length of each generated coupon code
format = alphanum (for alphanumeric codes) OR alpha (for alphabetical codes) OR num (for numeric codes)
protected function getCouponCode($couponData)
{
$rule = $this->_loadSalesRule($ruleId);
// Reference the MassGenerator on this rule.
/** #var Mage_SalesRule_Model_Coupon_Massgenerator $generator */
$generator = $rule->getCouponMassGenerator();
// Validate the generator
if (!$generator->validateData($couponData)) {
$this->_critical(Mage::helper('salesrule')->__('Coupon AutoGen API: Invalid parameters passed in.'),
Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
} else {
// Set the data for the generator
$generator->setData($couponData);
// Generate a pool of coupon codes for the Generate Coupons rule
$generator->generatePool();
}
}
I've create my custom payment module, it works on payment gateway, everything is working fine but I would like to set the order as paid when the return url give back a succes code. So far I've understand that I have to create an invoice for the order to be able to ave it set as paid into Magento panel.
So first of all please tell me if I'm wron until here.
Then I'm trying to create invoice on success.phtml with some codes like:
$invoice = Mage::getModel('sales/service_order', $order->prepareInvoice());
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(true);
$invoice->getOrder()->setIsInProcess(true);
$order->addStatusHistoryComment('Automatically INVOICED by Rico.', false);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transactionSave->save();
But it gives me back always a magento error, so probably is not a good idea.
Any help will be appreciated
EDIT
From this http://blog.chapagain.com.np/magento-quick-way-to-create-order-invoice-programmatically/
I've used
$invoiceId = Mage::getModel('sales/order_invoice_api')
->create($_order->getIncrementId(), array());
instead the code above and it seems that the order is paid. But I'm not sure, if is enough.
I suggest you when customer is returning to your site from payment gateway and then it must goes to a magento controller and it an action you need to add your code at there
$order=Mage::getModel('sales/order')->load($orderID);
if($order->canInvoice() and $order->getIncrementId())
{
$items = array();
foreach ($order->getAllItems() as $item) {
$items[$item->getId()] = $item->getQtyOrdered();
}
$invoiceId=Mage::getModel('sales/order_invoice_api')->create($order->getIncrementId(),$items,null,false,true);
Mage::getModel('sales/order_invoice_api')->capture($invoiceId)};
}
See http://www.amitbera.com/programmatically-create-invoice-of-a-new-order-in-magento/
I am trying to update the inventory level of a products but unfortunately not getting success.Here is my code.
I want to update product's "inventory_level" but enable to do so..
<?php
require "bigcommerce.php";
use Bigcommerce\Api\Client as Bigcommerce;
Bigcommerce::configure(array(
'store_url' => 'https://store-nos85a.mybigcommerce.com/',
'username' => 'admin',
'api_key' => '4b7c4bba19f290a728e00be6ae7133cda71f477b'
));
Bigcommerce::setCipher('RC4-SHA');
Bigcommerce::verifyPeer(false);
$product = Bigcommerce::getProduct(76);
print_r($product->skus);
foreach($product->skus as $sku)
{
if($sku->id==5)
{
$fields = array("inventory_level"=>112);
Bigcommerce::updateProduct(76,$fields);
}
echo "id : ".$sku->id;
echo " Invntory Level: ".$sku->inventory_level."<br/>";
echo " SKU : ".$sku->sku."<br/>";
}
?>
Here Bigcommerce::updateProduct(76,$field); is not working.
No need to download ALL products, why not retrieve JUST the product that has the sku you need?
GET: /api/v2/products?sku=sku-that-I'm-interested-in
parse the response for the id (that's the product ID for the product with that SKU)
Then do a PUT using that product ID.
I am trying to do the same thing (different programming language). I have a call into their support. It seems like you still must reference the product_id.
You cannot update simply by SKU. You must know the product_id. I got around this by requesting all products and loading the response into an array (product_id, sku, etc.). I then read thru the array, get the quantity from our system using the SKU, and post (PUT) the inventory_level using the associated product_id.
IMHO this is a huge oversight on their part. Who cares what the product_id is on the website?
I have asked for an enhancement that allows updating by SKU.
Whenever you load the cart page in Magento, the following code is run
$cart->init();
$cart->save();
One side effect of this is that the prices for any items in the cart are updated if the price of the product has been updated. This actually updates the entry in sales_flat_quote_item. I'm trying to track down where in code the price is updated on each quote item, and where each quote item is saved.
I know the myrid locations it could be set. I'm hoping someone knows where it actually is set. Magento 1.7x branch specifically, although info from all versions is welcome.
Dug this one up myself. So there's this
#File: app/code/core/Mage/Sales/Model/Quote.php
foreach ($this->getAllAddresses() as $address) {
...
$address->collectTotals();
...
}
which leads to this
#File: app/code/core/Mage/Sales/Model/Quote/Address.php
public function collectTotals()
{
Mage::dispatchEvent($this->_eventPrefix . '_collect_totals_before', array($this->_eventObject => $this));
foreach ($this->getTotalCollector()->getCollectors() as $model) {
$model->collect($this);
}
Mage::dispatchEvent($this->_eventPrefix . '_collect_totals_after', array($this->_eventObject => $this));
return $this;
}
The getTotalCollector object returns a sales/quote_address_total_collector object, which loads a series of collector models from global/sales/quote/totals and calls collect on them. The sub-total collector's collect method ultimately calls this
#File: app/code/core/Mage/Sales/Model/Quote/Address/Total/Subtotal.php
protected function _initItem($address, $item)
{
//...
if ($quoteItem->getParentItem() && $quoteItem->isChildrenCalculated()) {
$finalPrice = $quoteItem->getParentItem()->getProduct()->getPriceModel()->getChildFinalPrice(
$quoteItem->getParentItem()->getProduct(),
$quoteItem->getParentItem()->getQty(),
$quoteItem->getProduct(),
$quoteItem->getQty()
);
$item->setPrice($finalPrice)
->setBaseOriginalPrice($finalPrice);
$item->calcRowTotal();
} else if (!$quoteItem->getParentItem()) {
$finalPrice = $product->getFinalPrice($quoteItem->getQty());
$item->setPrice($finalPrice)
->setBaseOriginalPrice($finalPrice);
$item->calcRowTotal();
$this->_addAmount($item->getRowTotal());
$this->_addBaseAmount($item->getBaseRowTotal());
$address->setTotalQty($address->getTotalQty() + $item->getQty());
}
//...
}
and this is where the quote item gets it's price set/rest.
From a high level, the code that starts the whole process are lines 464 and 465 of Mage_Checkout_Model_Cart :
$this->getQuote()->collectTotals();
$this->getQuote()->save();
The new product price is being set against the quote in Mage_Sales_Model_Quote_Address_Total_Subtotal in the _initItem method. You will see $item->setPrice in the the if / else statement starting at line 104
If you are trying to do custom price changes on products in the cart, rather than extend and modify core classes, I use an observer sales_quote_save_before. It works great if you are trying to customize pricing (especially when I have products that can be custom length).