I'm trying to have a custom credit card payment attribute save to two different tables but I'm not sure how to do this.
The normal credit card information saves to two different tables.
sales_flat_quote_payment
sales_flat_order_payment
I created the new attribute and it should be saved to both tables. The column with the correct value has been set on both tables but it only saves to one "sales_flat_quote_payment" right when the customer places the order.
How can I make it so it saves the data to both tables?
I found this reference but I'm not sure how to implemente it to make it work with a credit card attribute value.
http://www.magentocommerce.com/boards/viewthread/19344/P0/
Can anyone confirm if this would work?
<sales_copy_order_payment>
<cc_bankname>
<to_order>*</to_order>
</cc_bankname>
</sales_copy_order_payment>
Did you configure Magento to convert the new attribute from quote to order? If you check the config.xml from the Mage_Sales module and search for sales_convert_quote_payment. You see something as follows:
<sales_convert_quote_payment>
<method><to_order_payment>*</to_order_payment></method>
<additional_data><to_order_payment>*</to_order_payment></additional_data>
<additional_information><to_order_payment>*</to_order_payment></additional_information>
<po_number><to_order_payment>*</to_order_payment></po_number>
<cc_type><to_order_payment>*</to_order_payment></cc_type>
<cc_number_enc><to_order_payment>*</to_order_payment></cc_number_enc>
<cc_last4><to_order_payment>*</to_order_payment></cc_last4>
<cc_owner><to_order_payment>*</to_order_payment></cc_owner>
<cc_exp_month><to_order_payment>*</to_order_payment></cc_exp_month>
<cc_exp_year><to_order_payment>*</to_order_payment></cc_exp_year>
<cc_number><to_order_payment>*</to_order_payment></cc_number>
<cc_cid><to_order_payment>*</to_order_payment></cc_cid>
<cc_ss_issue><to_order_payment>*</to_order_payment></cc_ss_issue>
<cc_ss_start_month><to_order_payment>*</to_order_payment></cc_ss_start_month>
<cc_ss_start_year><to_order_payment>*</to_order_payment></cc_ss_start_year>
</sales_convert_quote_payment>
Magento uses these fieldsets to transport data from entity to entity. In this case from the quote_payment to the order_payment.
Since all config XML is merged into one big heap of XML, you can add additional nodes from your own modules config.xml. Something like:
<global>
<fieldsets>
<sales_convert_quote_payment>
<your_attribute><to_order_payment>*</to_order_payment></your_attribute>
</sales_convert_quote_payment>
</fieldsets>
</global>
Hope this helps you get underway.
Related
I've added a custom attribute to the sales_order_flat table, and I'm trying to display this attribute in the grid at sales_order/index.
I've done this with customer attributes successfully, but I'm getting errors when trying the same thing with order data.
<global>
<blocks>
<adminhtml>
<rewrite>
<sales_order_grid>WACI_AdminHtmlExt_Block_Sales_Order_Grid</sales_order_grid>
</rewrite>
</adminhtml>
</blocks>
<!-- etc -->
app/code/local/namespace/module/Block/Sales/Order/Grid.php
class WACI_AdminHtmlExt_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid
{
protected function _prepareColumns()
{
$this->addColumn('dynamics_ord', array(
'header' => $this->__('Dynamics ID'),
'width' => '75px',
'index' => 'dynamics_ord',
));
$this->addColumnsOrder('dynamics_ord','entity_id');
return parent::_prepareColumns();
}
}
I see that _prepareCollection is sometimes used, but I'm trying to just amend the collection during setCollection for, if nothing else, simplicity.
Whatever the case, the column displays, but no data is produced. (And the page errors out when I try to sort).
Any ideas on this?
Update
This post is an extension of this SO thread I've updated it to match the modules current status. That is, I'm adding columns to both sales_flat_order and sales_flat_order_grid.
From that post, I've got an action that takes place to set this attribute value (after the order has been completed).
My question at this point is - how does updateGridRecords() come into play?
=> updateGridRecords appears to be called automatically when the $order->save() gets called (something I'm doing manually after the order is complete).
If I understand this correctly, because I'm not pulling data from any other model, the _prepareColumns call is all that's required.
=> yep. Displaying and sorting properly after the attr is saved. Win!
The difference between customer collection and order grid collection is that customer collection is derived from Mage_Eav_Model_Entity_Collection_Abstract and sales_flat_order_grid collection is derived from Mage_Sales_Model_Resource_Abstract which is not EAV.
Because of that you can't add attributes to select like you would normaly be able to do with EAV - all the attributes that you want to use must be represented as a table column in the flat table.
The function addAttributeToSelect that you are calling is implemented in Mage_Sales_Model_Resource_Collection_Abstract class and uses in background addFieldToSelect so in you case you should have a column with name dynamics_ord in sales_flat_order_grid table.
The function that moves attribute values from order EAV to order grid is Mage_Sales_Model_Resource_Order_Abstract::updateGridRecords and this function reads the structure of sales_flat_order_grid table to know which attributes should be written to sales_flat_order_grid table so if dynamics_ord column is missing you will have to add it in your module's install script.
I came across this stack overflow solution on how to add the column in install script and then add it to the grid. The answer is a bit outdated but I think it could work.
I have also found this out of the box solution on how to add an attribute that will be used on orders grid but haven't tested it so I can't be certain if it works.
When you make a join EAV table with FLAT table then you can not filter the data in grid.
I had faced same problem earlier and had invested 4 days in that with my seniors, then finally come 2 conclusion that you can not do that....!!!
I've followed some suggestions to have some data copied over from one table to another table on the DB but it's not working.
Based on the response I received on this questions: Magento: How to save data to order_payment and quote_payment
I tried to do the following on the Mage/Sales/etc/Config.xml file
<sales_convert_order_payment>
<cc_bankname>
<to_quote_payment>cc_bankname</to_quote_payment>
</cc_bankname>
</sales_convert_order_payment>
and this
<sales_convert_quote_payment>
<cc_bankname>
<to_order_payment>cc_bankname</to_order_payment>
</cc_bankname>
</sales_convert_quote_payment>
but the bank name is only saved on the sales_flat_quote_payment table and not on the sales_flat_order_payment table which is the one I need to have this new data displayed on the order invoice and on the admin back-end under order/view.
If I manually input the data on the DB (the bank name that is) I'm able to display this information where it's needed but I cannot keep track of every transaction to manually input the data upon order completion since customers get to see their order details once it has been sumbited and they would not be able to view the new data until I have done so myself.
does anyone know why the data is not being carried over to the sales_fat_order_payment table?
I'm having the same issue with a new mobile number attribute I created but I believe if I can solve this one, then I should be able to handle all other similar issues.
That technique (naming it using same name with Mage) won't work for config.xml.
How it works? You need to read this article written by Alanstorm http://alanstorm.com/magento_config_declared_modules_tutorial
You need to create your own module by defining it in app/etc/modules (of course you should name it other than Mage).
eg:
app/etc/modules/Test_Sales.xml
content:
<?xml version="1.0"?>
<config>
<modules>
<Test_Sales>
<active>true</active>
<codePool>local</codePool>
</Test_Sales>
</modules>
</config>
app/code/local/Test/Sales/etc/config.xml -> define your new config in here
In older version of magento, sales order stored in eav type.
In higher version, it has been flatten.
Look at the name: sales_flat_quote_payment, sales_flat_order_payment
Magento always keep their data backward compatible, that's why it has attribute name cc_owner in eav_attribute.
In your case, you don't need to create new value in eav_attribute (you just need to add column cc_bankname in sales_flat_quote_payment and sales_flat_order_payment which I'm pretty sure you have already created).
As you have said before, the problem why it is not saved to sales_flat_order_payment is because of cache issue (Magento cache the config.xml so you need to refresh it System > Cache Management > Configuration)
I'm trying to modify the credit card form to add some new custom fields named "Bank Name" and "Bank Phone Number" and it seems this cannot be done through the back-end.
I've searched the web and on here but I haven't been able to find anything in reference on how to add a new custom field to the credit card form. I would think it's almost the same as adding a new field to the customer registration form but I have no clue what to do database wise.
If anyone has anything I can use to work on this, I'd greatly appreciate it.
You should start by informing which version of Magento you are using and which methods you have already tried.
Without knowing that it is hard to help you, but you might want to try this possible solution, this one, or even one of these modules: Checkout Fields Manager or ADDITIONAL CHECKOUT ATTRIBUTES. If none of the above work, try this search.
No, Magento admin panel will not add custom columns for you. You need to do it yourself.
First, you need to edit the .phtml file to include these two fields to show up in frontend.
Second, you need to add two new columns (with same name as your fields, explained later) in relevant DB table (i guess sales_flat_order_payment). But that will affect for all payment methods, so define it something like VARCHAR(255) NULL.
Third, when Magento saves the CC info, you need to check if it is saving whole data array, then your field's name posted will match your table field and get inserted automatically. Else you need to edit it.
Also, next time please post some code, atleast something you have tried.
I've never set a store up to use Price Alerts before, and now that I've gone through and gotten it to work, it appears as though the alert is only triggered when a product's 'Price' attribute changes.
This is nice, but what about tiered pricing? Looking through the ProductAlert core module, I am not sure where this attribute is being filtered.
I'm guessing that an additional model, say 'productalert/tierprice' will need to be created, followed by a new method in Observer.php, likely _processTierprice(). Just not sure if this concept is correct... could use a little guidance.
Thanks!
This shouldn't be too difficult; lots of options (it's Magento, after all)!
I'd add new methods to deal with tier price alerts. For products with tier pricing, you'd need to capture the relevant tier data along with the final price (either in a new table or in new columns on the existing product alert table). The alerts are sent out via scheduled job. So, in a nutshell (overrides where necessary):
Alter the product alert schema as necessary, and amend the frontend form fields to suit
In the overridden Mage_ProductAlert_AddController add a tierPriceAction() method to process the alert subscription, or adjust its existing priceAction() to handle the data being posted in / tier condition
Override Mage_ProductAlert_Model_Observer as needed; I'd include a _processesTierPrice method() similar to _processPrice().
Add a resource model method to get the tier-related prices
Add a tier price email block and template (reference Mage_ProductAlert_Block_Email_Abstract)
Profit!
As a reference for your price logic, see Mage_Catalog_Model_Product_Type_Price.
I understand how to programmatically create a product and also add to cart. I know this might sound dumb but is it is possible to generate a product on the fly and add that to the cart/quote but never actually save it in the database.
We want to create a made to order interface and I was thinking at the end it could add a bundle product with all the selections but that bundle product wouldn't actually exist in the backend.
I figured as long as you can make sure the quote and order has what it needs in terms of the product it would be ok, but obviously there is probably a lot that is tied to looking up stuff in the db on a specific sku or ID. I know that if you delete a product and then look at an order in the admin that causes issues, at least it did for this one scenario I was dealing with.
I was thinking of creating a giant bundle product that had like 6 different bundle items and each item could potentially have like 500 products and then based on what the user selects I programmatically add the bundle to cart. But then I wasn't sure if there would be a negative affect with having a gigantic bundle product like that as well.
UPDATE:
I don't think this will work, obviously there are a lot of information tied to the product in the database and we setup a test and right away we get an error for $item->getProduct(). We are moving forward with creating a giant bundle product and also the generic product with adding custom options on the fly, which Anda pointed out below. Any other suggestions will be greatly appreciated.
I'm not sure that clockworkgeek's approach is going to work. On every page load, Magento loads the items from the cart to make sure that they are still valid (in-stock, prices correct, etc), and amends the cart to reflect those values. My understanding of the system in the past has been that a product in the cart needs to have a corresponding database value to survive this process.
The "giant bundle product" approach is a pain, but in the past has been the best approach I have found. Attempting to change the values of the product (such as price or attributes) will be overridden by the cart checks, so you need a product w/ maximal flexibility, such as an overly-customized bundle product or configurable product.
Hope that helps!
Thanks,
Joe
Why not create a generic product in db and then set the product customization as custom options (additional_options) on the fly depending on the user selection. You can add custom options to the product (actually to the quote item) without having to save them in the database. I did this once for a website that sells glasses with prescription. The prescription was added as an option.
You can programmatically create Mage_Sales_Model_Quote_Items and add them to the cart. You've noticed it needs a product to match it's product ID but it needn't be a useful one. It could be a blank, disabled product, also created in code. All that's needed is a stub.
The necessary stuff for the cart is stored in the quote item - fields like name, value and quantity. Those fields are then copied directly to the order without using a product.
Mage::getModel('catalog/product')
creates a new product. you can add it to a cart, by doing something like this:
$cart = Mage::getSingleton('checkout/cart');
$product = Mage::getModel('catalog/product')
->setStoreId($storeid)
->setTypeId($type_id)
->setQty($quantyty)
->setWhatAttributYouWant($attribute);
$cart->addProduct($product);
product attributes you can find in the DB in tables that start like catalog_product_... or take an already created product, and see what attributes it has in the _data array (with debugger or just print_r($product->getData))