Magento and salesforce integration to create opportunity as closed won inside salesfore once order become complete in magento store - soap

I had implemented a salesforce integration with magento orders. To achieve this , i had followed the steps given below. I am doing something wrong in 4th step while inserting salesforce_company_id and salesforce_contact_id in user account.
1)Add custom option 'closed' in admin to make any order complete.
public function massCompleteAction(){
$orderIds = $this->getRequest()->getPost('order_ids', array());
$countCompleteOrder = 0;
foreach ($orderIds as $orderId) {
$order = Mage::getModel('sales/order')->load($orderId);
if ($order->canComplete()) {
$order->complete()->save();
$countCompleteOrder++;
}
}
if ($countCompleteOrder>0) {
$this->_getSession()->addSuccess($this->__('%s order(s) successfully put on complete', $countCompleteOrder));
}else {
// selected orders is not available for hold
}
$this->_redirect('*/*/');
}
2)Add two additional fields for user account, Salesforce Company and Salesforce Contact.
I had followed following link http://www.excellencemagentoblog.com/customer-registration-fields-magento1-6
3)Create a custom reseller registration form that will create a simple user in magento
public function createResellerAction()
{
$params = $this->getRequest()->getParams();
$customer = Mage::getModel('customer/customer');
$password = $params["password"];
$email = $params["email"];
$customer->setWebsiteId(Mage::app()->getWebsite()->getId());
$customer->loadByEmail($email);
//Zend_Debug::dump($customer->debug()); exit;
if(!$customer->getId()) {
$customer->setEmail($email);
$customer->setFirstname($params["firstname"]);
$customer->setLastname($params["lastname"]);
$customer->setPassword($password);
try {
$customer->save();
$customer->setConfirmation(null);
$customer->save();
Mage::getSingleton('customer/session')->loginById($customer->getId());
}
catch (Exception $ex) {
//Zend_Debug::dump($ex->getMessage());
}
$_custom_address = array (
'firstname' => $params["firstname"],
'lastname' => $params["lastname"],
'street' => array (
'0' => $params["add1"],
'1' => $params["add2"],
),
'city' => $params["city"],
'region_id' => '',
'region' => '',
'postcode' => $params["zipcode"],
'country_id' => '', /* Croatia */
'telephone' => $params["phone"],
);
$customAddress = Mage::getModel('customer/address');
$customAddress->setData($_custom_address)
->setCustomerId($customer->getId())
->setIsDefaultBilling('1')
->setIsDefaultShipping('1')
->setSaveInAddressBook('1');
try {
$customAddress->save();
}
catch (Exception $ex) {
//Zend_Debug::dump($ex->getMessage());
}
4) Create company and contact in salesforce during reseller action
$sObject1 = new stdclass();
$sObject1->Name = $params["company"];
$createResponse1 = $mySforceConnection->create(array($sObject1), 'Account');
foreach ($createResponse1 as $createResult1) {
$compid = $createResult1->id;
}
$sObject3 = new stdclass();
$sObject3->FirstName = $params["firstname"];
$sObject3->LastName = $params["lastname"];
$sObject3->Email = $params["email"];
$sObject3->AccountId = $compid;
$createResponse2 = $mySforceConnection->create(array($sObject3), 'Contact');
foreach ($createResponse2 as $createResult2) {
$contid = $createResult2->id;
}
$saledata = array (
'salesforce_company_id' => $compid,
'salesforce_contact_id' => $contid,
);
$customersale = Mage::getModel('customer/customer');
$customersale->setWebsiteId(Mage::app()->getWebsite()->getId());
$customersale->loadByEmail($email);
//Zend_Debug::dump($customer->debug()); exit;
if($customersale->getId()) {
$customersale->setData($saledata);
try {
$customersale->save();
$customersale->setConfirmation(null);
$customersale->save();
}
catch (Exception $ex) {
$message = $this->__($customer);
//Zend_Debug::dump($ex->getMessage());
Mage::getSingleton('core/session')->addError($message);
}
}
Please check the code where i am wrong at the bottem of 4th step
$saledata = array (
'salesforce_company_id' => $compid,
'salesforce_contact_id' => $contid,
);
$customersale = Mage::getModel('customer/customer');
$customersale->setWebsiteId(Mage::app()->getWebsite()->getId());
$customersale->loadByEmail($email);
//Zend_Debug::dump($customer->debug()); exit;
if($customersale->getId()) {
$customersale->setData($saledata);
try {
$customersale->save();
$customersale->setConfirmation(null);
$customersale->save();
}
catch (Exception $ex) {
$message = $this->__($customer);
//Zend_Debug::dump($ex->getMessage());
Mage::getSingleton('core/session')->addError($message);
}
}
I await your responses.

There is a great extension for magento which does that all for you and even more: https://products.crunchyconsulting.com/crunchy-products/crunchy-magforce.html
Take a look at help & docs tab where you can find even movies with use case scenarios
https://www.youtube.com/watch?v=TjxvjGcAGqY
https://www.youtube.com/watch?v=cmf4Ksv3uRM

Related

How can I add cart items to user meta table using WooCommerce REST_API

I'm building a Flutter app linked with WooCommerce through REST-API, and I want to add cart items to wc_session data in order to be able to update cart data for a specific user.
I found the below code and used it, It gives me a 200 response, but no items in the cart.
What's the problem? Should I implement a specific webhook for this task, or the rest API will do?
Also, how can I add session data to meta tables directly from the code, as I am afraid to corrupt the database.
The code:
<?php
defined( 'ABSPATH' ) || exit;
class WC_REST_Webhooks_Controller extends WC_REST_Webhooks_V2_Controller {
protected $namespace = 'wc/v3';
protected function get_default_api_version() {
return 'wp_api_v3';
}
protected $rest_base = 'custom';
function woocommerce_add_to_cart($param) {
global $wpdb;
$user_id = $param['user_id'];
wp_set_current_user($user_id);
$objProduct = new WC_Session_Handler();
$wc_session_data = $objProduct->get_session($user_id);
$full_user_meta = get_user_meta($user_id, '_woocommerce_persistent_cart_1', true);
if( defined( 'WC_ABSPATH' ) ){
include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
include_once WC_ABSPATH . 'includes/wc-notice-functions.php';
include_once WC_ABSPATH . 'includes/wc-template-hooks.php';
}
if ( null === WC()-> session ) {
$session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
WC()->session = new $session_class();
WC()->session->init();
}
if ( null === WC()->customer ) {
WC()->customer = new WC_Customer( get_current_user_id(), true );
}
if ( null === WC()->cart ) {
WC()->cart = new WC_Cart();
// force refresh cart contents from the session here.
WC()->cart->get_cart();
}
// create a new cart object
$cartObj = WC()->cart;
// Add old cart data to newly created cart obect:
if ($full_user_meta['cart']) {
foreach($full_user_meta['cart'] as $single_user_meta) {
$cartObj->add_to_cart( $single_user_meta['product_id'], $single_user_meta['quantity'] );
}
}
//Add product and quantities coming in request to the new cart object
if ($param['products']) {
WC()->cart->empty_cart();
foreach($param['products'] as $prod) {
$cartObj->add_to_cart( $prod['product_id'], $prod['quantity']);
}
}
$updatedCart = [];
foreach( $cartObj->cart_contents as $key => $val ){
unset($val['data']);
$updatedCart[$key] = $val;
}
// if there is a current session cart, overwrite it with the new cart
if( $wc_session_data ){
$wc_session_data['cart'] = serialize($updatedCart);
$serializedObj = maybe_serialize($wc_session_data);
$table_name = 'wp_woocommerce_sessions';
// Update wp session table with cart data:
$sql = "UPDATE $table_name SET session_value= '".$serializedObj."' WHERE session_key = '".$user_id."'";
// Execute the query:
$rez = $wpdb->query($sql);
}
// Overwrite the persistent cart with new cart data
$full_user_meta['cart'] = $updatedCart;
$productsInCart = [];
foreach($cartObj->cart_contents as $cart_item) {
$product = wc_get_product( $cart_item['product_id'] );
$image_id = $product->get_image_id();
$image_url = wp_get_attachment_image_url( $image_id, 'full');
$productsInCart[] = (object) [
"product_id" => $cart_item['product_id'],
"product_name" => $product->get_name(),
"product_regular_price" => $product->get_regular_price(),
"product_sale_price" => $product->get_sale_price(),
"thumbnail" => $image_url,
"qty" => $cart_item['quantity'],
"line_subtotal" => $cart_item['line_subtotal'],
"line_total" => $cart_item['line_total'],
];
}
update_user_meta(get_current_user_id(), '_woocommerce_persistent_cart_1', array('cart' => updatedCart, ));
$response = [
'status' => true,
'data' => $full_user_meta['cart'] != null ? $productsInCart : []
];
return rest_ensure_response($response);
}
function woocommerce_cart_list($param) {
$user_id = $param['user_id'];
$objProduct = new WC_Session_Handler();
$wc_session_data = $objProduct-> get_session($user_id);
// get the persistent cart may be _woocommerce_persistent_cart can be in ur case check in user_meta table
$full_user_meta = get_user_meta($user_id, ' _woocommerce_persistent_cart_1 ', true);
$productsInCard = [];
foreach($full_user_meta['cart'] as $cart_item) {
$product = wc_get_product( $cart_item['product_id'] );
$image_id = $product->get_image_id();
$image_url = wp_get_attachment_image_url( $image_id, 'full');
$productsInCart[] = (object) [
"product_id" => $cart_item['product_id'],
"product_name" => $product->get_name(),
"product_regular_price" => $product->get_regular_price(),
"product_sale_price" => $product->get_sale_price(),
"thumbnail" => $image_url,
"qty" => $cart_item['quantity'],
"line_subtotal" => $cart_item['line_subtotal'],
"line_total" => $cart_item['line_total'],
];
}
$response = [
'status' => true,
'data' => $full_user_meta['cart'] != null ? $productsInCart : []
];
return rest_ensure_response($response);
}
public function register_routes() {
register_rest_route(
$this->namespace,
'/addtocart',
array(
'methods' => 'POST',
'callback' => array( $this, 'woocommerce_add_to_cart'),
)
);
register_rest_route(
$this->namespace,
'/cart',
array(
'methods' => 'GET' ,
'callback' => array(
$this, 'woocommerce_cart_list'
),
)
);
}
}```

Upload multiple images using a many-to-many using Yii2

How to make loading multiple images and making many-to-many relationships on a table of apartments?
I have a model Apartment:
public function getApartmentImages()
{
return $this->hasMany(ApartmentImages::className(), ['apartment_id' => 'id']);
}
public function getImages()
{
return $this->hasMany(Images::className(), ['id' => 'image_id'])
->via('apartmentImages');
}
Model Images:
public function getApartmentImages()
{
return $this->hasMany(ApartmentImages::className(), ['image_id' => 'id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getApartments()
{
return $this->hasMany(Apartment::className(), ['id' => 'apartment_id'])
->via('apartmentImages');
}
Model ApartmentImages
public function getImage()
{
return $this->hasOne(Images::className(), ['id' => 'image_id']);
}
public function getApartment()
{
return $this->hasOne(Apartment::className(), ['id' => 'apartment_id']);
}
The apartment has a main image (layout) and many others.
I managed to make the layout load:
public function actionCreate()
{
$model = new Apartment();
$model->load(Yii::$app->getRequest()->getBodyParams(), '');
$layout = new Images();
$layout->imageFile = UploadedFile::getInstanceByName('layout');
if ($layout->upload()) {
$model->layout_id = $layout->id;
}
if ($model->validate()) {
if ($model->save()) {
$response = Yii::$app->getResponse();
$response->setStatusCode(201);
$id = implode(',', array_values($model->getPrimaryKey(true)));
$response->getHeaders()->set('Location', Url::toRoute(['view', 'id' => $id], true));
} elseif (!$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
}
}
return $model;
}
I filled the array with all the sent pictures, and in the loop I upload to the site, and using
//INSERT INTO `apartment_images` (`apartment_id`, `image_id`) VALUES (...)
$model->link('images', $images[0]);
I create an entry in the link table.
public function actionCreate()
{
$model = new Apartment();
$model->load(Yii::$app->getRequest()->getBodyParams(), '');
$layout = new Images();
$layout->imageFile = UploadedFile::getInstanceByName('layout');
$layout->validate();
if ($layout->upload()) {
$model->layout_id = $layout->id;
}
$count = count(UploadedFile::getInstancesByName('images'));//Get the number of images
$images = [new Images()];//First image required
$images[0]->imageFile = UploadedFile::getInstanceByName('images[0]');
if(!$images[0]->validate()) return $images[0]->errors;//Check errors
if ($model->validate()){
if ($model->save()) {
if ($images[0]->upload()) {
$model->link('images',$images[0]);//Binding many to many
}
for($i = 1; $i < $count; $i++) {//Check the rest and repeat again
$images[$i] = new Images();
$images[$i]->imageFile = UploadedFile::getInstanceByName('images['.$i.']');
if ($images[$i]->upload()) {
$model->link('images',$images[$i]);
}
}
$response = Yii::$app->getResponse();
$response->setStatusCode(201);
$id = implode(',', array_values($model->getPrimaryKey(true)));
$response->getHeaders()->set('Location', Url::toRoute(['view', 'id' => $id], true));
} elseif (!$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
}
}
else return $model->errors;
return $model;
}

Compare the token from an email to a user's token for account activation

I need to send a user an email with a link that they can click on to activate their account. Here is my code:
//ADD METHOD FROM USERS CONTROLLER, THIS SENDS THE EMAIL WHEN A NEW USER IS ADDED
public function add()
{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data);
$newAuthToken = bin2hex(openssl_random_pseudo_bytes(16));
$user['authtoken'] = $newAuthToken;
$user['activated'] = null;
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
$ms='Click on the link below to complete registration ';
$ms.='urlhere.com/users/activate/t:'.$newAuthToken.'';
$ms=wordwrap($ms,70);
$email = new Email('default');
$email->viewVars();
$email->template('default')->viewVars(array('user' => $user))
->emailFormat('html')
->to($user['email'])
->from('admin#example.com')
->subject('Hello ' . $user['email'])
->send($ms);
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
$groups = $this->Users->Groups->find('list', ['limit' => 200]);
$answers = $this->Users->Answers->find('list', ['limit' => 200]);
$courses = $this->Users->Courses->find('list', ['limit' => 200]);
$this->set(compact('user', 'groups', 'answers', 'courses'));
$this->set('_serialize', ['user']);
}
Here is the function that should compare the email token(from the link) with the tokens in the Users table and set the timestamp to Activated if they match:
//ACTIVATE FUNCTION FROM USERS CONTROLLER, SHOULD SET TIMESTAMP FOR ACTIVATED
public function activate($id = null)
{
if (!empty($this->passedArgs['t'])){
$tokenhash = $this->passedArgs['t'];
$results = $this->User->find('first', array('conditions' => array('authtoken' => $tokenhash)));
if($results['authtoken']==$tokenhash) {
$this->User->id = $results['id'];
$this->User->saveField('activated', current_datetime());
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'index']);
exit;
} else {
$this->Flash->error('Tokens do not match');
return $this->redirect(['action' => 'index']);
}
}
}
Any ideas as to why this isn't working?

Set 'enctype' form attribute in moodle form?

I am creating a form in moodle. I require multipart/form-data in enctype attributes to work with files. But I don't know where the attribute should be set. And how to set it.
Have a look at the Files API with the Forms API for uploading files.
http://docs.moodle.org/dev/Using_the_File_API_in_Moodle_forms
UPDATE: Haven't tested this but its a cut down version of some existing code I have
In your edit.php file have something like this:
require_once(dirname(__FILE__) . '/edit_form.php');
$id = optional_param('id', null, PARAM_INT);
if ($id) {
// Existing record
$record = $DB->get_record('mytablename');
} else {
// New record
$record = new stdClass();
$record->id = null;
$record->myfield = '';
...
}
// Prepare the files.
$fileoptions = array(
'maxbytes' => get_max_upload_file_size(),
'maxfiles' => '1', // Change this to how many files can be uploaded.
'subdirs' => 0, // No sub directories.
'context' => $context
);
$record = file_prepare_standard_filemanager($record, 'myfiles',
$fileoptions, $context, 'mypluginname', 'myfiles', $record->id);
$mform = new edit_form(null, array('fileoptions' => $fileoptions));
if ($formdata = $mform->get_data()) {
// Form has been submitted.
if (empty($formdata->id)) {
// New record so create it.
$recordid = $DB->insert_record('mytablename', $formdata);
$record = $DB->get_record('mytablename', array('id' => $recordid));
} else {
// Update it.
$DB->update_record('mytablename', $formdata);
$record = $DB->get_record('mytablename', array('id' => $id));
}
// Save the files.
$formdata = file_postupdate_standard_filemanager($formdata, 'myfiles',
$fileoptions, $context, 'mypluginname', 'myfiles', $record->id);
} else {
// Display the form.
$mform->set_data($record);
$mform->display();
}
And in your edit_form.php have something like this
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/formslib.php');
class edit_form extends moodleform {
public function definition() {
$fileoptions = $this->_customdata['fileoptions'];
$mform =& $this->_form;
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
...
$mform->addElement('filemanager', 'myfiles_filemanager',
get_string('myfiles', 'mypluginname'), null, $fileoptions);
$this->add_action_buttons(false, get_string('submit'));
}
}
I know this question is old but did not see anything in the Moodle documentation. This works as of Moodle 3.11.
class my_form extends moodleform {
...
$mform = $this->_form;
...
$attr = $mform->getAttributes();
$attr['enctype'] = "multipart/form-data";
$mform->setAttributes($attr);
}

Zend form validation multiple custom validation message for same field at the same time

I have a Zend form password custom validation.
I have set the addValidator functions IInd argument to false since I need to get all errors at once. Both of my validation classes have set the self::INVLID to corresponding error messages.
But when I look in the Zend controller even though both validations fail I'm getting only one (the last) error message.
I need all the error messages at once.
/* Form validation*/
$passwordSpecialValidator = new Passwordspecialvalidationvalidator();
$passwordHistoryValidator = new Passwordhistorylvalidationvalidator(new model(), $username, $newpass);
$this->newpass->addValidator($passwordSpecialValidator, false)
->addValidator($passwordHistoryValidator, false);
/* One validation class */
class Passwordhistorylvalidationvalidator extends Zend_Validate_Abstract {
const INVLID = '';
protected $_messageTemplates = array(
self::INVLID => 'Your password doesnt meet the history requirements'
);
public function __construct($model, $username, $password) {
$this->_model = $model;
$this->_username = $username;
$this->_password = $password;
}
public function isValid($value, $context = null) {
if ($this->_username == "") {
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$arrayResult = $auth->getIdentity();
if (isset($arrayResult->username)) {
$this->_username = $arrayResult->username;
}
}
}
$passwordExists = false;
$oldPasswords = $this->_model->getHistoryPasswords($this->_username, $this->_password);
if (count($oldPasswords) > 0) {
$passwordExists = true;
}
if ($passwordExists == false) {
return true;
} else {
$this->_setValue($value);
$this->_error(self::INVLID);
return false;
}
}
}
/* Getting error messages */
foreach ($objForm->getMessages() as $messages) {
foreach ($messages as $message) {
$errMessages[] = $message;
}
}
But the array $errMessages has only the last validation message (without index) even though both special validation and history validation fails. How would I get both error messages in an array if both validations fail?