Custom Magento Order Field and the Magento Database - php

Alright, so I've successfully added a custom order field to my page layout in magento. I require a "dealer" from which the user has to select a "dealer state" and then I use ajaxt to pull in all the dealers from that specific state into another field called "dealerid". The value of this field is in fact the dealer id in my database. My question is kind of a full one.
First, I need to add a field to the "order table" that saves the dealer id for the specific order and secondly I need to actually have magento take this field from the form and insert it. How do I go about doing these things? Mainly, what table would magento store this dealerid and what files do I modify to actually have magento access and insert this field value?
Note: I am using the one page checkout method only.

First of all, familiarize yourself with magento SQL update mechanism (its diffrent when your dealing with EAV - like customer tables - and regular tables - like orders). Create a module which will have a sql-update script in /YourNamespace/YourModule/sql/yourmodule_setup/mysql4-install-1.0.0.php for instance. You should use something like:
$installer = $this;
$installer->getConnection()->addColumn($installer->getTable('sales/order'), 'dealerid', 'decimal(12,4) NULL');
and in your config.xml:
<global>
(...)
<models>
(...)
<yourmodule>
<class>Mage_Sales_Model</class>
<resourceModel>yourmodule_mysql4</resourceModel>
</yourmodule>
<yourmodule_mysql4>
<class>YourNamespace_Yourmodule_Model_Mysql4</class>
<entities>
<order><table>sales_order</table></order>
</entities>
(...)
</yourmodule_mysql4>
(...)
</models>
<resources>
<yourmodule_setup>
<setup>
<module>YourNamespace_YourModule</module>
<class>YourNamespace_YourModule_Model_Mysql4_Setup</class>
</setup>
</yourmodule_setup>
</resources>
(...)
</global>
Remember to create your own classes: YourNamespace_YourModule_Model_Mysql4_Setup, YourNamespace_Yourmodule_Model_Mysql4. Check in app/code/core/Mage/Sales/ how they should look like (nothing special needed there, they just must inherit from proper core classes). Also check out the app/code/core/Mage/Sales/sql and app/code/core/Mage/Sales/etc/config.xml.
If you want to get a field from the onepage checkout, you must do a couple of things... I don't know what you really need from the user (and in what part of checkout its going to be taken). Adding an input is done by the templates (edit proper files in app/design/frontend/yourskin/default/template/checkout).
To capture the right data you must rewrite the checkout controller whit your own controller action (look at the app/code/core/Mage/Checkout/Controllers/OnepageController.php) to get the data from the form and store it in the checkout session. After that you must hook to the checkout_type_onepage_save_order_after event (its in the app/code/core/Mage/Checkou/Model/Type/Onepage.php), take the data from your session and put it in the Order model (and save it of course). Its kind of a standard procedure, so you shouldn't have a problem.
Its possible that you will also have add a column to the sales_flat_order (the structure of order tables changed in 1.4.x.x, so I'm not sure of it - you will have to do some experimenting).
If you want to see it in the adminhtml order view, you will have to override some Core/Adminhtml/Blocks/Sales/Order (and templates probably).
Its kind of a complex procedure, so you'll have to figure out some things by yourself. This post is kind of a general idea how it should be done.

Related

Magento how to save custom field in admin panel

In Manage Products -> Edit a product -> Images I've added 2 new columns (which are located in the catalog_product_entity_media_gallery_value table).
Those 2 columns are filled every time there is a media import and each field only show the value (you can't enter a new value). It's also used on the frontend.
I've modified in my own theme the correct admin template file and created a new product.js to display the 2 new fields.
So far everything is working as intended.
But whenever a user tries to modify something in the Images section, let say the label of an image or the position, my 2 custom fields are not saved and Magento give them the NULL value.
Because the 2 new columns are not input fields, I thought Magento would not update it, but looks like it does. I've been trying to find where the label and position are saved for the Images section so that I can add my custom values but I can't find it. Could somebody point me in the right direction?
Or would it be better to listen to the catalog_product_save_after event and create an observer to save my custom values?
Any help would be great, thank you.
Finally found it, I missed it during my previous searches. I'll answer it myself just in case it can help someone else. Code is in the Mage_Catalog_Model_Product_Attribute_Backend_Media class, inside the afterSave function.
All you have to do is to rewrite it.
Config.xml should contain the following :
<models>
<catalog_resource>
<rewrite>
<product_attribute_backend_media>
Namespace_Module_Model_Resource_Product_Attribute_Backend_Media
</product_attribute_backend_media>
</rewrite>
</catalog_resource>
</models>
And class should be : Namespace_Module_Model_Product_Attribute_Backend_Media extends Mage_Catalog_Model_Product_Attribute_Backend_Media

Adding a search field to the Magento admin

Is there a way to add a new search field in the Magento admin under "Orders"? I want to be able to search by coupon code usage (ex: search by coupon code: "sale2013", come up with all the orders that applied that coupon code during checkout).
I'm able to pull this data out of the Magento DB, but I'd really like to add this functionality to the Magento admin to make it easier for co-workers and my boss. Can it be done and, if so, ideas as to where I can start? Thanks guys.
The coupon code used during checkout is stored on the primary order table (sales_flat_order) when the customer checks out. If there is no value, then no coupon code was used. However, the data for the grid in the admin comes from the sales_flat_order_grid table; it comes from there instead of the primary order table for performance reasons which become particularly evident on very high traffic sites.
Now that we know where the data is that you need to filter on, and where the data for the grid comes from, we can move on to build it!
The first thing that you will need to do is add a coupon_code column to the sales_flat_order_grid table matching the definition of the column on the sales_flat_order table. The values in the coupon_code column of sales_flat_order should automatically populate into sales_flat_order_grid once the matching column is there and your cache storage has been flushed.
The data is updated on the order save, so to be specific, new orders and orders updated via the admin (even a comment on the order) will have the data populated. For existing orders, run a data upgrade script to copy the values over.
After the data/schemas are in place, you'll want to have the grid show a filterable column for it. For this you will want to rewrite the Mage_Adminhtml_Block_Sales_Order_Grid class from your custom module (please don't edit the core files directly, it will haunt you later) and override the _prepareColumns method with one that includes your column definition:
$this->addColumn('coupon_code', array(
'header' => Mage::helper('sales')->__('Coupon Code'),
'index' => 'coupon_code',
));
If you're very fresh on Magento development, I'd venture to say that I've only begun to help you. But you'll have plenty of reference points from which to dig in and build the functionality you need. HTH! :)
Adding new columns to a grid is easy with this extension:
https://github.com/magento-hackathon/GridControl
Add this extension, write your own with a gridcontrol.xml inside your etc directory
And then something like this should work:
<?xml version="1.0"?>
<gridcontrol>
<grids>
<order.grid>
<coupon_code>
<after>columnname</after>
<add>
<header>Coupon code</header>
<type>text</type>
<index>coupon_code</index>
<joinField>coupon_code|sales/order|coupon_code|entity_id=entity_id||left</joinField>
</add>
</coupon_code>
</order.grid>
</grids>
</gridcontrol>

How can I make duplicates of authorize.net module in magento?

I've been stuck on this for a couple of days now. For some reason, duplicating the Magento Authorize.net (Mage_Paygate) module just doesn't work on the front-end. I've managed to duplicate the module and have it show up with its own configuration options in the back-end, but I can't get the payment method to show up on front-end during check out.
So far I've tried copying the module and changing every single instance of the model names to avoid conflict, I've done this multiple times from scratch so I'm confident that it's not an issue of an invalid class call...
There's some kind of magic button that I'm missing. I'm really hoping to hear from someone who's successfully duplicated a core payment module, specifically Authorize.net
I need to create duplicates for accounting purposes. There is no other solution than to duplicate the authorize.net modules.
Thanks
EDIT: Some insight into why I need multiple copies of the authorize.net module: My company processes high volume sales, more than most merchant services will allow. The idea is that we will have several authorize.net modules pre-loaded with multiple authorize.net API credentials that each correspond to a different merchant, so that when one of the merchants caps out we can disable that payment method and enable the next one.
The reason I can't just switch the information in a single authorize.net module is that we need the funds for each credit card to be deposited into separate bank accounts - ECC, the software we use to transfer data from magento to quickbooks, accepts the payment method based on the Title field. In order to differentiate which credit card processor we are transferring funds for, we append a (ACRONYM) to the title field. When this title field changes, ECC poops itself because it suddenly doesn't know where the funds came from for the transactions it's downloading.
We've tried various things and feel that making copies of an authorize.net module would be the best solution. Thanks.
I managed to figure it out, here's what I did in case anyone else runs into this, it's very handy to be able to duplicate payment and shipping modules that follow different rules without having to rely on store view changes:
Create new module Namespace_Modulename , I used Mage_Paygate1 until my concept was proven.
Copy the etc folder from the module you'd like to duplicate
Copy the main model file, in my case Mage/Paygate/Model/Authorizenet.php
Edit the system.xml:
change group name so that a new block of configuration options will appear in the admin panel config, leave the module="" alone. We're going to refer to the original module files rather than copy them. I used authorizenet1.
Change the label node if you'd like, for clarity. In my case I named my copies Authorize.net (processor name)
Edit config.xml:
Module name, change to Namespace_Modulename, I used Mage_Paygate1.
Make sure there is a blocks declaration if the original config.xml didn't have one. We want to refer to the blocks folder in the original module, ie:
<blocks>
<directpost><class>Mage_Paygate_Block</class></directpost>
</blocks>
change the node in the bottom under
<default><section> (<default><payment>) to the group name used in system.xml
(authorizenet1)
Make sure the model node is correctly pointing to the new module, not the old. (paygate1/authorizenet)
Now edit the new model, (Authorizenet.php):
rename the Class to match the new Namespace_Modulename (Mage_Paygate1)
Make sure the $_code equals your group name from the config.xml file (authorize1)
That's what worked for me. The idea is to only copy the pieces that change the module's configuration and just recycle all of the original code.
There's probably an even cleaner way to do this but I'm no magento master by any means, so I very much welcome any advice on how to future-proof this sort of hack.
Along with below code we need to change the model also, in config.xml. if you not make below change new payment method will not displayed in checkout
<models>
<authorizenet1>
<class>Mage_Paygate1_Model</class>
</authorizenet1>
</models>

store values inside Magento attributes

I am setting up a magento feed and I stuck since I need the system to auto calculate the values for the last few attributes.
how can I have magento create an attribute with the MAX sale price, and MAX list price, and Rating, also I need 2 more attribites 1 for discount amount and the last for discount percentage.
any help is appreciated.
If I understand your problem correctly, you could probabaly use the afterLoad event of some Magento objects. This would work for most models within Magento.
Preface
In general, most of the Model used in Magento (that is, e.g. products, orders, etc. in the core libraries and every model you would define in a custom module with db access) extend the class Mage_Core_Model_Abstract, which provides certain "event"-based methods.
These methods are _afterDelete, _afterDeleteCommit, _afterLoad, _afterSave, _afterSavecommit, _beforeLoad, _beforeSave and _beforeDelete (in Magento >1.4.2.0).
Overriding a model
I assume, you would like to have automatic caluclated attributes on a product. The first step here would be to create a new custom module which overrides the core model for Magento products. In a newly created model, you can use the following entry in ./app/code/local/YourNamespace/YourModule/etc/config.xml:
[...]
<global>
[...]
<models>
<catalog>
<rewrite>
<product>YourNamespace_YourModule_Model_Product</product>
</rewrite>
</catalog>
</models>
[...]
<global>
[...]
You can then overwrite the Product Model as shown in a file called ./app/code/local/YourNamespace/YourModule/Model/Product.php:
<?php
class YourNamespace_YourModule_Model_Product extends Mage_Catalog_Model_Product
{
protected function _afterLoad()
{
parent::_afterLoad();
//your voodoo goes here.
$my_awesome_calculated_value = $this->getData('my_awesome_float_attribute') / 2;
$this->setData('my_awesome_calculated_value', $my_awesome_calculated_value);
}
}
With this, as long as you have a model loaded, you have the opportunity to use that calculated value in whatever way you could conceive. Keep in mind, that this code is executed every time a product is loaded, which can be quite often (if it's a product, that is), so don't get too temerarious with this.
Also keep in mind, that this value is lost, after your code execution is finished, as the value exists only as long as the model "lives". If you want to store it, you could also override _beforeSave or create placeholder attributes, which are filled each time a model is loaded and then saved afterwards.
For the attributes for discount_amountand discount_percentage i would use the same strategy:
load the model
calculate the dicount_amount and discount_percentage in _afterLoad and store it on the model
work with the model.
Addendum
If you're new to Magento and don't know explicitly how to create new modules, you can start with http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/custom_module_with_custom_database_table (although it's a bit outdated) or look around stackoverflow.
lg,
and good luck,
flo

Magento new user registration - inject own code

I'm trying to make a loose connection between a Magento installation and another application. In particular, there are only two things I care about at the moment - customers and their purchases. What I edited thus far is the file app/code/core/Mage/Customer/controllers/AccountController.php - function createPostAction() is augmented to send the customer's info to the other application. Another modification was made in success.phtml file to send out the details of the order once it's placed.
The problem I'm having is that if a user just places items in a cart (as a guest) and then registers as part of the checkout process - the customer's record in the second application is never created. It only works if the user first explicitly registers, and then checks out separately.
I suppose AccountController.php may be the wrong file to modify to achieve my desired result, which file should I use instead?
Edit: I am not including the code samples, as it's largely irrelevant - the problem is not with the code, but with the fact that it's apparently in the wrong place. Where would be a good place to add custom code which should run when a new customer is registered?
This is a bit tricky to do cleanly in Magento but possible to achieve. I've had the same task a while ago and solved using observers
First you need to create an observer which listens controller_action_postdispatch event:
<events>
<controller_action_postdispatch>
<observers>
<yourmodule_anything>
<type>singleton</type>
<class>yourmodule/observer</class>
<method>someMethod</method>
</yourmodule_anything>
</observers>
</controller_action_postdispatch>
</events>
Then in your observer method you can check action names as follows
<?php
$action = $observer->getEvent()->getControllerAction();
if ($action->getFullActionName() == 'customer_account_createpost') {
if (Mage::getSingleton('customer/session')->isLoggedIn()) { // this check allows to determine if customer session was created which means successfull registration
}
}
Something similar can be done for checkout registration. In general observers are great (and proper) way to extend Magento functionality. Read more about them here
Anton S is right - you should check if Magento is firing an event when this occurs. If so, your code should respond to that event.
If that is not the case, or you need custom logic to run before the account is created, please consider overriding/overloading the controller using a custom module: http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/how_to_overload_a_controller
This keeps the original core code intact. It essentially tells Magento to use your custom controller instead. If the method it needs to execute is not found in your controller, it will use the code from the core instead.

Categories