Get Full Billing Address for Paypal Express [Magento] - magento

The paypal module tries to map the billing information that is returned (usually nothing) from Paypal over the billing information entered by the user during the checkout process. I've fond the code that does this in NVP.php model.
/**
* Create billing and shipping addresses basing on response data
* #param array $data
*/
protected function _exportAddressses($data)
{
$address = new Varien_Object();
Varien_Object_Mapper::accumulateByMap($data, $address, $this->_billingAddressMap);
$address->setExportedKeys(array_values($this->_billingAddressMap));
$this->_applyStreetAndRegionWorkarounds($address);
$this->setExportedBillingAddress($address);
// assume there is shipping address if there is at least one field specific to shipping
if (isset($data['SHIPTONAME'])) {
$shippingAddress = clone $address;
Varien_Object_Mapper::accumulateByMap($data, $shippingAddress, $this->_shippingAddressMap);
$this->_applyStreetAndRegionWorkarounds($shippingAddress);
// PayPal doesn't provide detailed shipping name fields, so the name will be overwritten
$shippingAddress->addData(array(
'prefix' => null,
'firstname' => $data['SHIPTONAME'],
'middlename' => null,
'lastname' => null,
'suffix' => null,
));
$this->setExportedShippingAddress($shippingAddress);
}
}
/**
* Adopt specified address object to be compatible with Magento
*
* #param Varien_Object $address
*/
protected function _applyStreetAndRegionWorkarounds(Varien_Object $address)
{
// merge street addresses into 1
if ($address->hasStreet2()) {
$address->setStreet(implode("\n", array($address->getStreet(), $address->getStreet2())));
$address->unsStreet2();
}
// attempt to fetch region_id from directory
if ($address->getCountryId() && $address->getRegion()) {
$regions = Mage::getModel('directory/country')->loadByCode($address->getCountryId())->getRegionCollection()
->addRegionCodeFilter($address->getRegion())
->setPageSize(1)
;
foreach ($regions as $region) {
$address->setRegionId($region->getId());
$address->setExportedKeys(array_merge($address->getExportedKeys(), array('region_id')));
break;
}
}
}
Has anyone had any success modifying this process to get back fuller billing information. We need to be able to send "Paid" invoices to customers who pay with Paypal, so we need to capture this information.

i have hacked a workaround for that problem. It is not the cleanest way but i can save the billing address data in the order after paying with PayPal. I spent 2 days working on it and at the end i coded only a few lines. I marked my workaround with the comment #103.
Override method of class Mage_Paypal_Model_Api_Nvp:
protected function _importAddresses(array $to)
{
// Original Code
//$billingAddress = ($this->getBillingAddress()) ? $this->getBillingAddress() : $this->getAddress();
// Workaround #103
if ($this->getBillingAddress())
{
$billingAddress = $this->getBillingAddress();
}
else
{
$chkout = Mage::getSingleton('checkout/session');
$quote = $chkout->getQuote();
$billingAddress = $quote->getBillingAddress();
$billingAddress->setData($billingAddress->getOrigData());
$session = Mage::getSingleton("core/session", array("name"=>"frontend"));
$session->setData("syn_paypal_original_billing_address", serialize($billingAddress->getOrigData()));
}
$shippingAddress = $this->getAddress();
$to = Varien_Object_Mapper::accumulateByMap($billingAddress, $to, array_flip($this->_billingAddressMap));
if ($regionCode = $this->_lookupRegionCodeFromAddress($billingAddress)) {
$to['STATE'] = $regionCode;
}
if (!$this->getSuppressShipping()) {
$to = Varien_Object_Mapper::accumulateByMap($shippingAddress, $to, array_flip($this->_shippingAddressMap));
if ($regionCode = $this->_lookupRegionCodeFromAddress($shippingAddress)) {
$to['SHIPTOSTATE'] = $regionCode;
}
$this->_importStreetFromAddress($shippingAddress, $to, 'SHIPTOSTREET', 'SHIPTOSTREET2');
$this->_importStreetFromAddress($billingAddress, $to, 'STREET', 'STREET2');
$to['SHIPTONAME'] = $shippingAddress->getName();
}
$this->_applyCountryWorkarounds($to);
return $to;
}
And override method in Mage_Paypal_Model_Express_Checkout:
public function returnFromPaypal($token)
{
$this->_getApi();
$this->_api->setToken($token)
->callGetExpressCheckoutDetails();
// import billing address
$billingAddress = $this->_quote->getBillingAddress();
$exportedBillingAddress = $this->_api->getExportedBillingAddress();
// Workaround #103
$session = Mage::getSingleton("core/session", array("name"=>"frontend"));
$dataOrg = unserialize($session->getData("syn_paypal_original_billing_address"));
if (true === is_object($billingAddress))
{
foreach ($exportedBillingAddress->getExportedKeys() as $key) {
if (array_key_exists($key, $dataOrg))
{
$billingAddress->setData($key, $dataOrg[$key]);
}
}
$this->_quote->setBillingAddress($billingAddress);
}
// import shipping address
$exportedShippingAddress = $this->_api->getExportedShippingAddress();
if (!$this->_quote->getIsVirtual()) {
$shippingAddress = $this->_quote->getShippingAddress();
if ($shippingAddress) {
if ($exportedShippingAddress) {
foreach ($exportedShippingAddress->getExportedKeys() as $key) {
$shippingAddress->setDataUsingMethod($key, $exportedShippingAddress->getData($key));
}
$shippingAddress->setCollectShippingRates(true);
}
// import shipping method
$code = '';
if ($this->_api->getShippingRateCode()) {
if ($code = $this->_matchShippingMethodCode($shippingAddress, $this->_api->getShippingRateCode())) {
// possible bug of double collecting rates :-/
$shippingAddress->setShippingMethod($code)->setCollectShippingRates(true);
}
}
$this->_quote->getPayment()->setAdditionalInformation(self::PAYMENT_INFO_TRANSPORT_SHIPPING_METHOD, $code);
}
}
$this->_ignoreAddressValidation();
// import payment info
$payment = $this->_quote->getPayment();
$payment->setMethod($this->_methodType);
Mage::getSingleton('paypal/info')->importToPayment($this->_api, $payment);
$payment->setAdditionalInformation(self::PAYMENT_INFO_TRANSPORT_PAYER_ID, $this->_api->getPayerId())
->setAdditionalInformation(self::PAYMENT_INFO_TRANSPORT_TOKEN, $token)
;
$this->_quote->collectTotals()->save();
}

Related

Object of class Illuminate\Routing\Redirector could not be converted to string. srmklive/laravel-paypal

I am currently working on a paypal checkout using paypal and https://github.com/srmklive/laravel-paypal. I'm using the express checkout which I modified it a little bit to fit the requirements of the my project. During testing it is working in a couple of tries, paypal show and payment executes properly but when I tried to run the exact same code. I get this error I don't know what it means.
I tried to check my routes if it all of the errors happens to my routes but all of it are working properly. I also tried dump and die like dd("check") just to check if its really going to my controller and it does. I did this in the method "payCommission" (this where the I think the error happens)
This is my route for the controller
api.php
Route::get('service/commissionfee/payment' , 'api\service\ExpressPaymentController#payCommission');
Route::get('paypal/ec-checkout-success', 'api\service\ExpressPaymentController#payCommissionSuccess');
ExpressPaymentController.php
<?php
namespace App\Http\Controllers\api\service;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Srmklive\PayPal\Services\ExpressCheckout;
class ExpressPaymentController extends Controller
{
protected $provider;
public function __construct()
{
try {
$this->provider = new ExpressCheckout();
}
catch(\Exception $e){
dd($e);
}
}
public function payCommission(Request $request)
{
$recurring = false;
$cart = $this->getCheckoutData($recurring);
try {
$response = $this->provider->setExpressCheckout($cart, $recurring);
return redirect($response['paypal_link']);
} catch (\Exception $e) {
dd($e);
return response()->json(['code' => 'danger', 'message' => "Error processing PayPal payment"]);
}
}
public function payCommissionSuccess(Request $request)
{
$recurring = false;
$token = $request->get('token');
$PayerID = $request->get('PayerID');
$cart = $this->getCheckoutData($recurring);
// ? Verify Express Checkout Token
$response = $this->provider->getExpressCheckoutDetails($token);
if (in_array(strtoupper($response['ACK']), ['SUCCESS', 'SUCCESSWITHWARNING'])) {
if ($recurring === true) {
$response = $this->provider->createMonthlySubscription($response['TOKEN'], 9.99, $cart['subscription_desc']);
if (!empty($response['PROFILESTATUS']) && in_array($response['PROFILESTATUS'], ['ActiveProfile', 'PendingProfile'])) {
$status = 'Processed';
} else {
$status = 'Invalid';
}
} else {
// ? Perform transaction on PayPal
$payment_status = $this->provider->doExpressCheckoutPayment($cart, $token, $PayerID);
$status = $payment_status['PAYMENTINFO_0_PAYMENTSTATUS'];
}
return response()->json(['success' => "payment complete"]);
}
}
private function getCheckoutData($recurring = false)
{
$data = [];
$order_id = 1;
$data['items'] = [
[
'name' => 'Product 1',
'price' => 9.99,
'qty' => 1,
],
];
$data['return_url'] = url('api/paypal/ec-checkout-success');
// !
$data['invoice_id'] = config('paypal.invoice_prefix').'_'.$order_id;
$data['invoice_description'] = "Commission Fee payment";
$data['cancel_url'] = url('/');
$total = 0;
foreach ($data['items'] as $item) {
$total += $item['price'] * $item['qty'];
}
$data['total'] = $total;
return $data;
}
}
Error I am getting
Object of class Illuminate\Routing\Redirector could not be converted to string
Thank you in advance
you may just go to the config/paypal.php and edit
'invoice_prefix' => env('PAYPAL_INVOICE_PREFIX', 'Life_saver_'),
you may use _ underline in this like Life_saver_, dont forget use underline at the end too.

yii user: upload image on registration form

I want to upload profile picture in yii user. By so much digging, i came to know that i need to make a profilefield, which i did and called "picture" and then in view of modules/user/registrtaion i need to write this code, given below is my registration view file.
<?php
$profileFields=$profile->getFields();
if ($profileFields) {
foreach($profileFields as $field) {
?>
<div class="row">
<?php
if ($widgetEdit = $field->widgetEdit($profile)) {
echo $widgetEdit;
} elseif ($field->range) {
echo $form->dropDownListControlGroup($profile,$field->varname,Profile::range($field->range));
} elseif ($field->field_type=="TEXT") {
echo$form->textArea($profile,$field->varname,array('rows'=>6, 'cols'=>50));
}
// I added this below elseif for picture upload
elseif ($field->field_type=="VARCHAR" && $field->field_size=="500") {
echo$form->fileField($profile,$field->varname,array('rows'=>6, 'cols'=>50));
}else {
echo $form->textFieldControlGroup($profile,$field->varname,array('size'=>60,'maxlength'=>(($field->field_size)?$field->field_size:255)));
}
?>
and i am hanlding this profile picture in modules/model/registration.php like this. Given below is the code.
<?php
class RegistrationForm extends User {
public $verifyPassword;
public $verifyCode;
public function rules() {
$rules = array(
array('username, password, verifyPassword, email', 'required'),
array('username', 'length', 'max'=>20, 'min' => 3,'message' => UserModule::t("Incorrect username (length between 3 and 20 characters).")),
array('password', 'length', 'max'=>128, 'min' => 4,'message' => UserModule::t("Incorrect password (minimal length 4 symbols).")),
array('email', 'email'),
array('username', 'unique', 'message' => UserModule::t("This user's name already exists.")),
array('email', 'unique', 'message' => UserModule::t("This user's email address already exists.")),
//array('verifyPassword', 'compare', 'compareAttribute'=>'password', 'message' => UserModule::t("Retype Password is incorrect.")),
array('username', 'match', 'pattern' => '/^[A-Za-z0-9_]+$/u','message' => UserModule::t("Incorrect symbols (A-z0-9).")),
// adding this liine
array('picture', 'file','types'=>'jpg, gif, png', 'allowEmpty'=>true, 'on'=>'update'), //
);
if (!(isset($_POST['ajax']) && $_POST['ajax']==='registration-form')) {
array_push($rules,array('verifyCode', 'captcha', 'allowEmpty'=>!UserModule::doCaptcha('registration')));
}
array_push($rules,array('verifyPassword', 'compare', 'compareAttribute'=>'password', 'message' => UserModule::t("Retype Password is incorrect.")));
return $rules;
}
}
and finally in the controller i handle the picture like this given below is the code.
<?php
class RegistrationController extends Controller
{
public $defaultAction = 'registration';
/**
* Declares class-based actions.
*/
public function actions()
{
return array(
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xFFFFFF,
),
);
}
/**
* Registration user
*/
public function actionRegistration() {
$model = new RegistrationForm;
$profile=new Profile;
$profile->regMode = true;
// ajax validator
if(isset($_POST['ajax']) && $_POST['ajax']==='registration-form')
{
echo UActiveForm::validate(array($model,$profile));
Yii::app()->end();
}
if (Yii::app()->user->id) {
$this->redirect(Yii::app()->controller->module->profileUrl);
} else {
if(isset($_POST['RegistrationForm'])) {
// handling picture
$rnd = rand(0, 9999); // generate random number between 0-9999
$model->attributes = $_POST['RegistrationForm'];
$uploadedFile = CUploadedFile::getInstance($model, 'picture');
$fileName = "{$rnd}-{$uploadedFile}"; // random number + file name
$model->picture = $fileName;
if ($model->save()) {
$uploadedFile->saveAs(Yii::app()->basePath . '/../img/' . $fileName);
$this->redirect(array('view', 'id' => $model->id));
}
// hanlding picture ends
$profile->attributes=((isset($_POST['Profile'])?$_POST['Profile']:array()));
if($model->validate()&&$profile->validate())
{
$soucePassword = $model->password;
$model->activkey=UserModule::encrypting(microtime().$model->password);
$model->password=UserModule::encrypting($model->password);
$model->verifyPassword=UserModule::encrypting($model->verifyPassword);
$model->superuser=0;
$model->status=((Yii::app()->controller->module->activeAfterRegister)?User::STATUS_ACTIVE:User::STATUS_NOACTIVE);
if ($model->save()) {
$profile->user_id=$model->id;
$profile->save();
if (Yii::app()->controller->module->sendActivationMail) {
$activation_url = $this->createAbsoluteUrl('/user/activation/activation',array("activkey" => $model->activkey, "email" => $model->email));
UserModule::sendMail($model->email,UserModule::t("You registered from {site_name}",array('{site_name}'=>Yii::app()->name)),UserModule::t("Please activate you account go to {activation_url}",array('{activation_url}'=>$activation_url)));
}
if ((Yii::app()->controller->module->loginNotActiv||(Yii::app()->controller->module->activeAfterRegister&&Yii::app()->controller->module->sendActivationMail==false))&&Yii::app()->controller->module->autoLogin) {
$identity=new UserIdentity($model->username,$soucePassword);
$identity->authenticate();
Yii::app()->user->login($identity,0);
$this->redirect(Yii::app()->controller->module->returnUrl);
} else {
if (!Yii::app()->controller->module->activeAfterRegister&&!Yii::app()->controller->module->sendActivationMail) {
Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Contact Admin to activate your account."));
} elseif(Yii::app()->controller->module->activeAfterRegister&&Yii::app()->controller->module->sendActivationMail==false) {
Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Please {{login}}.",array('{{login}}'=>CHtml::link(UserModule::t('Login'),Yii::app()->controller->module->loginUrl))));
} elseif(Yii::app()->controller->module->loginNotActiv) {
Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Please check your email or login."));
} else {
Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Please check your email."));
}
$this->refresh();
}
}
} else $profile->validate();
}
$this->render('/user/registration',array('model'=>$model,'profile'=>$profile));
}
}
}
so the problem is,, when i enter the details on registraion form and upload a picture i get this error Property "RegistrationForm.picture" is not defined. The problem lies in controller line number 45 which is
$model->picture = $fileName;
I already have picture field in "profiles" table. But the thing is i am totally confused, and neither at yii framework forum nor at stackoverflow i found a proper documentation over this thing. Please help.
My profile.php (model) code
<?php
class Profile extends UActiveRecord
{
/**
* The followings are the available columns in table 'profiles':
* #var integer $user_id
* #var boolean $regMode
*/
public $regMode = false;
private $_model;
private $_modelReg;
private $_rules = array();
/**
* Returns the static model of the specified AR class.
* #return CActiveRecord the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return Yii::app()->getModule('user')->tableProfiles;
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
if (!$this->_rules) {
$required = array();
$numerical = array();
$float = array();
$decimal = array();
$rules = array();
$model=$this->getFields();
foreach ($model as $field) {
$field_rule = array();
if ($field->required==ProfileField::REQUIRED_YES_NOT_SHOW_REG||$field->required==ProfileField::REQUIRED_YES_SHOW_REG)
array_push($required,$field->varname);
if ($field->field_type=='FLOAT')
array_push($float,$field->varname);
if ($field->field_type=='DECIMAL')
array_push($decimal,$field->varname);
if ($field->field_type=='INTEGER')
array_push($numerical,$field->varname);
if ($field->field_type=='VARCHAR'||$field->field_type=='TEXT') {
$field_rule = array($field->varname, 'length', 'max'=>$field->field_size, 'min' => $field->field_size_min);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
if ($field->other_validator) {
if (strpos($field->other_validator,'{')===0) {
$validator = (array)CJavaScript::jsonDecode($field->other_validator);
foreach ($validator as $name=>$val) {
$field_rule = array($field->varname, $name);
$field_rule = array_merge($field_rule,(array)$validator[$name]);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
} else {
$field_rule = array($field->varname, $field->other_validator);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
} elseif ($field->field_type=='DATE') {
$field_rule = array($field->varname, 'type', 'type' => 'date', 'dateFormat' => 'yyyy-mm-dd', 'allowEmpty'=>true);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
if ($field->match) {
$field_rule = array($field->varname, 'match', 'pattern' => $field->match);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
if ($field->range) {
$field_rule = array($field->varname, 'in', 'range' => self::rangeRules($field->range));
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
}
array_push($rules,array(implode(',',$required), 'required'));
array_push($rules,array(implode(',',$numerical), 'numerical', 'integerOnly'=>true));
array_push($rules,array(implode(',',$float), 'type', 'type'=>'float'));
array_push($rules,array(implode(',',$decimal), 'match', 'pattern' => '/^\s*[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\s*$/'));
$this->_rules = $rules;
}
return $this->_rules;
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
$relations = array(
'user'=>array(self::HAS_ONE, 'User', 'id'),
);
if (isset(Yii::app()->getModule('user')->profileRelations)) $relations = array_merge($relations,Yii::app()->getModule('user')->profileRelations);
return $relations;
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
$labels = array(
'user_id' => UserModule::t('User ID'),
);
$model=$this->getFields();
foreach ($model as $field)
$labels[$field->varname] = ((Yii::app()->getModule('user')->fieldsMessage)?UserModule::t($field->title,array(),Yii::app()->getModule('user')->fieldsMessage):UserModule::t($field->title));
return $labels;
}
private function rangeRules($str) {
$rules = explode(';',$str);
for ($i=0;$i<count($rules);$i++)
$rules[$i] = current(explode("==",$rules[$i]));
return $rules;
}
static public function range($str,$fieldValue=NULL) {
$rules = explode(';',$str);
$array = array();
for ($i=0;$i<count($rules);$i++) {
$item = explode("==",$rules[$i]);
if (isset($item[0])) $array[$item[0]] = ((isset($item[1]))?$item[1]:$item[0]);
}
if (isset($fieldValue))
if (isset($array[$fieldValue])) return $array[$fieldValue]; else return '';
else
return $array;
}
public function widgetAttributes() {
$data = array();
$model=$this->getFields();
foreach ($model as $field) {
if ($field->widget) $data[$field->varname]=$field->widget;
}
return $data;
}
public function widgetParams($fieldName) {
$data = array();
$model=$this->getFields();
foreach ($model as $field) {
if ($field->widget) $data[$field->varname]=$field->widgetparams;
}
return $data[$fieldName];
}
public function getFields() {
if ($this->regMode) {
if (!$this->_modelReg)
$this->_modelReg=ProfileField::model()->forRegistration()->findAll();
return $this->_modelReg;
} else {
if (!$this->_model)
$this->_model=ProfileField::model()->forOwner()->findAll();
return $this->_model;
}
}
}
Your registration form model extends user class. Your field picture is not the attribute of any of them.
It will be the attribute of profile model. You should move your rule to profile model.
Edit: In your profile model put this line
array_push($rules,array('picture', 'file','types'=>'jpg, gif, png', 'allowEmpty'=>true, 'on'=>'update'));
before the line
$this->_rules = $rules;
this code is not tested but it should work.

Magento Order History Comments: Modify Date

I am creating a script to add orders programmatically in Magento. I need help to change the date of the entries in the Comments History (quote, invoice, shipping, etc.). I can manipulate the date of the order itself (setCreatedAt) and some of the comments related to the creation of the order are correct (e.g. "Sep 29, 2008 8:59:25 AM|Pending Customer Notification Not Applicable"), but I cannot change the date of the comment when I use addStatusHistoryComment...
Here's a snippet of my code:
try {
if(!$order->canInvoice()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice.'));
}
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
if (!$invoice->getTotalQty()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
}
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
$invoice->setCreatedAt('2008-09-23 13:05:20');
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(true);
$invoice->getOrder()->setIsInProcess(true);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
- >addObject($invoice->getOrder());
$transactionSave->save();
//END Handle Invoice
//START Handle Shipment
$shipment = $order->prepareShipment();
$shipment->setCreatedAt('2008-09-23 14:20:10');
$shipment->register();
$order->setIsInProcess(true);
$order->addStatusHistoryComment('Shipping message goes here...', true);
$shipment->setEmailSent(true);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($shipment)
->addObject($shipment->getOrder())
->save();
$track = Mage::getModel('sales/order_shipment_track')
->setShipment($shipment)
->setData('title', 'Some tracking no.')
->setData('number', '111222333444')
->setData('carrier_code', 'fedex') //custom, fedex, ups, usps, dhl
->setData('order_id', $shipment->getData('order_id'))
->save();
//END Handle Shipment
}
catch (Mage_Core_Exception $ex) {
echo "Problem creating order invoice and/or shipment: ".$ex."\n";
}
Thanks in advance.
If I understand your question correctly, you just need to do this:
$comments = $order->getStatusHistoryCollection(true);
$comments now contains a collection of all the status history comments, and you can loop over them with whatever sort of criteria you like.
foreach ($comments as $c) {
if ( /* some stuff */ ) {
$c->setData('created_at',$new_date)->save();
}
}
So this is untested, but should work:
You need to create a new method based off addStatusHistoryComment:
/app/code/core/Mage/Sales/Model/Order.php
/*
* Add a comment to order
* Different or default status may be specified
*
* #param string $comment
* #param string $status
* #return Mage_Sales_Model_Order_Status_History
*/
public function addStatusHistoryComment($comment, $status = false)
{
if (false === $status) {
$status = $this->getStatus();
} elseif (true === $status) {
$status = $this->getConfig()->getStateDefaultStatus($this->getState());
} else {
$this->setStatus($status);
}
$history = Mage::getModel('sales/order_status_history')
->setStatus($status)
->setComment($comment)
->setEntityName($this->_historyEntityName);
->setCreatedAt('2008-09-23 14:20:10'); //I added this line
$this->addStatusHistory($history);
return $history;
}
Obviously you either need to rewrite this method, or refactor the code to do the same.

get the values of custom options

I'm trying to alter a price based on some custom options set. Therefore I'm trying to get the value a customer has entered, not the default values set in the backend. To do this I'm using the event catalog_product_get_final_price used in Mage_Bundle_Model_Product_Price. I have registered the following observer:
public function observer_callback($evt_obs)
{
$event = $evt_obs->getEvent();
$data = $event->getData();
/* #var $collection Mage_Catalog_Model_Resource_Product_Collection */
$collection = $data['collection'];
$items = $collection->getItems();
/* #var $item Mage_Catalog_Model_Product */
foreach ($items as $item) {
if ( $item->getName() == 'Bundel Test2') {
$options = $item->getCustomOptions();
/* #var $option Mage_Catalog_Model_Product_Option */
foreach ($options as $option) {
// Here I'm trying to get the value given by the user/customer
var_dump($option->getData());
}
}
}
return $this;
}
It is a custom option from a bundle type. So the product can't be configurable.
I'm new to magento so I'm probably missing something.
Can anyone help me?
Hope this piece of code can help you:
public function productFinalPrice($observer){
$product = $observer->getEvent()->getProduct();
$productType=$product->getTypeID();
if($productType == 'your_product_type')
{
$option = $product->getCustomOptions();
$searchedOption = null;
//search for your option;
foreach ($product->getOptions() as $o) {
if($o->getTitle()=="your_attribute_title" && $o->getType()=="your_type_of_option(eg. area"){
$optionId = $o->getOptionId();//got your searched optionId
break;
}
}
foreach($option as $key => $o) {
if($key == "option_".$optionId) {
$searchedOption = $o;
//here you get the option object with the values in it
}
}
$articleNumber = $searchedOption->getData('value'); // getthe value of your option
//calculate final price like you need it
$product->setFinalPrice($finalPrice);
}
return $this;
}
best regards

How to auto fill shipping method Magento for onepagechekout

I want to auto fill the shipping method automatically and not show it on the onepage checkout. I was able to hide the shipping method on my Onepagechekout by changing this on app/code/local/Mage/Checkout/controllers/OnepageController.php:
/**
* save checkout billing address
*/
public function saveBillingAction()
{
if ($this->_expireAjax()) {
return;
}
if ($this->getRequest()->isPost()) {
// $postData = $this->getRequest()->getPost('billing', array());
// $data = $this->_filterPostData($postData);
$data = $this->getRequest()->getPost('billing', array());
$customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
if (isset($data['email'])) {
$data['email'] = trim($data['email']);
}
$result = $this->getOnepage()->saveBilling($data, $customerAddressId);
if (!isset($result['error'])) {
/* check quote for virtual */
if ($this->getOnepage()->getQuote()->isVirtual())
{
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
} elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1)
{
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
$result['allow_sections'] = array('shipping');
$result['duplicateBillingInfo'] = 'true';
} else {
$result['goto_section'] = 'shipping';
}
}
$this->saveShippingMethodAction();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
}
As you can see I changed the link where I redirect the next step after billing action to the payment step.
In order to auto-save a shipping method, I added
$this->saveShippingMethodAction();
at the end of the function, and this method looks like here:
public function saveShippingMethodAction()
{
$this->_expireAjax();
if ($this->getRequest()->isPost()) {
/* $this->savePaymentAction(); */
$data = $this->getRequest()->getPost('shipping_method', 'flatrate_flatrate');
$result = $this->getOnepage()->saveShippingMethod($data);
$this->getResponse()->setBody(Zend_Json::encode($result));
}
}
So what I did is try to include automatically flatrate_flatrate method as the default one.
But when I try to finish a sale, it says I didn't specify a shipping method. Any idea on why it doesn't work?
Now you need to force the shipping_method in the quote and in the session :
$forcedMethod = "your_method_code";
$this->getOnePage()->getQuote()
->getShippingAddress()
->setShippingMethod($forcedMethod)
->save();
Mage::getSingleton('checkout/session')->setShippingMethod($forcedMethod);
And just before you call :
$this->saveShippingMethodAction();
add a :
$this->getRequest()->setPost('shipping_method', $forcedMethod);
It should work ;)

Resources