How to show Invoice Creation Date on Magento - magento

Now on magento when I print an Invoice as PDF, it shows "Order date".. we need to replace it with the "Invoice Creation Date".
Can you tell me how to do that?
Thanks.

Load the invoice by
$invoice = Mage::getModel('sales/order_invoice')->loadByIncrementId($invoiceIncrementId);
and then get the invoice date using
$createdDate = $invoice->getCreatedAt();
and put $createdDate and modify the below code from
$page->drawText(
Mage::helper('sales')->__('Order Date: ') . Mage::helper('core')->formatDate(
$order->getCreatedAtStoreDate(), 'medium', false
),
35,
($top -= 15),
'UTF-8'
);
To
$page->drawText(
Mage::helper('sales')->__('Invoice Creation Date: ') . Mage::helper('core')->formatDate(
$createdDate, 'medium', false
),
35,
($top -= 15),
'UTF-8'
);
NOTE :-
If you have multiple invoices for the same order then you can get the all invoice increment id by
$_invoices = $_order->getInvoiceCollection();
foreach($_invoices as $_invoice){
$_invoice->getIncrementId() = $_invoice->getIncrementId();
}

Since Magento is creating PDF of orders strictly via PHP code (means it doesn't use any html->pdf parser or any similar idea), you will have to extend the class that does that and modify it accordingly. So, the class that you are looking for is:
Mage_Sales_Model_Order_Pdf_Invoice
with the method
protected function insertOrder(&$page, $obj, $putOrderId = true)
then search for
$page->drawText( Mage::helper('sales')->__('Order Date: ') . Mage::helper('core')->formatDate($order->getCreatedAtStoreDate(), 'medium', false), 35, ($top -= 15), 'UTF-8');
And I would guess that you know how to extend it with your own module. If not, the process is described in How to create a simple 'Hello World' module in Magento?.

I had same problem and added invoice date to app/code/core/Mage/Sales/Model/Order/invoice.php at line 132
/* Add document text and number */
$this->insertDocumentNumber(
$page,
Mage::helper('sales')->__('Invoice # ') . $invoice->getIncrementId()
.' '.
Mage::helper('sales')->__('Invoice date: ') . Mage::helper('core')->formatDate(
$invoice->getCreatedAt(), 'medium', false
),
35,
($top -= 15),
'UTF-8'
);

Related

How to filter {ITEM_TITLE} and {ITEM_DESCRIPTION} osclass keywords before using them in emails?

How to filter {ITEM_TITLE} and {ITEM_DESCRIPTION} osclass keywords before using them in emails?
I want to apply a function on the item_title and item_description before using them in emails.
Ex.
Title: Sell bmw_ x5__
To become
Sell bmw x5
without changing the database values
I have the function
removeunderline(argument) that works, I only need to know from where to call it or where to use it.
(Osclass forums are blocked for new users, that's why I ask here)
/oc-includes/osclass/emails.php
Put removeunderline() at {ITEM_TITLE} and {ITEM_DESCRIPTION} values.
Example:
$words = array();
$words[] = array(
'{ITEM_DESCRIPTION_ALL_LANGUAGES}',
'{ITEM_DESCRIPTION}',
'{ITEM_COUNTRY}',
'{ITEM_PRICE}',
'{ITEM_REGION}',
'{ITEM_CITY}',
'{ITEM_ID}',
'{USER_NAME}',
'{USER_EMAIL}',
'{ITEM_TITLE}',
'{ITEM_URL}',
'{ITEM_LINK}',
'{VALIDATION_LINK}',
'{VALIDATION_URL}',
'{EDIT_LINK}',
'{EDIT_URL}',
'{DELETE_LINK}',
'{DELETE_URL}'
);
$words[] = array(
$all,
removeunderline($item['s_description']), // here
$item['s_country'],
osc_format_price($item['i_price']),
$item['s_region'],
$item['s_city'],
$item['pk_i_id'],
$item['s_contact_name'],
$item['s_contact_email'],
removeunderline($item['s_title']), // here
$item_url,
$item_link,
'<a href="' . $validation_url . '" >' . $validation_url . '</a>',
$validation_url,
'' . $edit_url . '',
$edit_url,
'' . $delete_url . '',
$delete_url
);
Do the same for all {ITEM_TITLE} in this file (10 replacements).
Do the same for all {ITEM_DESCRIPTION} in this file (3 replacements).

Catalog Price Rules applied to special_price

First question on stackoverflow...i am excited :)
Currently magento is using the special price if its lower than the applied catalog price rule. If the catalog price rule makes the product cheaper than the special price, then the catalog price rule defines the shop price.
I am looking for an elegant way to make catalog price rules be applied
to the special price (additionally). Maybe there is some store config for it? Maybe
there is some neat observer way?
Thank you so much!
Works up to current Magento 1.9.3.10. Just tested it in a project after update. Josef tried another approach which might work as well.
I am sad to say, I solved my first real stackoverflow question for my own:
Goto Mage_CatalogRule_Model_Resource_Rule
Goto method _getRuleProductsStmt
Add this to the initial select of the method before the first original ->from:
$select->from(null, array('default_price' => new Zend_Db_Expr("CASE
WHEN pp_default_special.value THEN pp_default_special.value ELSE
pp_default_normal.value END")));
Add this after the first join() has happened
$specialPriceAttr = Mage::getSingleton('eav/config')
->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'special_price');
$specialPriceTable = $specialPriceAttr->getBackend()->getTable();
$specialPriceAttributeId= $specialPriceAttr->getId();
$joinCondition2 = '%1$s.entity_id=rp.product_id AND (%1$s.attribute_id=' . $specialPriceAttributeId . ')
AND %1$s.store_id=%2$s';
$select->join(
array('pp_default_special'=>$specialPriceTable),
sprintf($joinCondition2, 'pp_default_special', Mage_Core_Model_App::ADMIN_STORE_ID), null
);
How it works:
When a catalog price rule is applied (via backend or cron) the db table catalogrule_product_price is populated. The above SQL magic joins the special_price (if exists) to the resultset as column default_value, if no special_price is found the regular price gets joined.
The result has been checked and is working.
Have fun! And dont hack the core!
There seem to be some changes in newer Magento releases!
For 1.9 i had to:
copy app/code/core/Mage/CatalogRule/Model/Action/Index/Refresh.php to app/code/local/Mage/CatalogRule/Model/Action/Index/Refresh.php
Change _prepareTemporarySelect.
I post the function in full here. Joins for special_price are added and then the price added to the selection of the price field. It still prefers group prices, becuas I never use them, but that can be changed easily!
protected
function _prepareTemporarySelect(Mage_Core_Model_Website $website)
{
/** #var $catalogFlatHelper Mage_Catalog_Helper_Product_Flat */
$catalogFlatHelper = $this->_factory->getHelper('catalog/product_flat');
/** #var $eavConfig Mage_Eav_Model_Config */
$eavConfig = $this->_factory->getSingleton('eav/config');
$priceAttribute = $eavConfig->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'price');
$specialPriceAttr = Mage::getSingleton('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'special_price');
$specialPriceTable = $specialPriceAttr->getBackend()->getTable();
$specialPriceAttributeId = $specialPriceAttr->getId();
$select = $this->_connection->select()->from(array(
'rp' => $this->_resource->getTable('catalogrule/rule_product')
) , array())->joinInner(array(
'r' => $this->_resource->getTable('catalogrule/rule')
) , 'r.rule_id = rp.rule_id', array())->where('rp.website_id = ?', $website->getId())->order(array(
'rp.product_id',
'rp.customer_group_id',
'rp.sort_order',
'rp.rule_product_id'
))->joinLeft(array(
'pg' => $this->_resource->getTable('catalog/product_attribute_group_price')
) , 'pg.entity_id = rp.product_id AND pg.customer_group_id = rp.customer_group_id' . ' AND pg.website_id = rp.website_id', array())->joinLeft(array(
'pgd' => $this->_resource->getTable('catalog/product_attribute_group_price')
) , 'pgd.entity_id = rp.product_id AND pgd.customer_group_id = rp.customer_group_id' . ' AND pgd.website_id = 0', array());
$storeId = $website->getDefaultStore()->getId();
if ($catalogFlatHelper->isEnabled() && $storeId && $catalogFlatHelper->isBuilt($storeId))
{
$select->joinInner(array(
'p' => $this->_resource->getTable('catalog/product_flat') . '_' . $storeId
) , 'p.entity_id = rp.product_id', array());
$priceColumn = $this->_connection->getIfNullSql($this->_connection->getIfNullSql('pg.value', 'pgd.value') , $this->_connection->getIfNullSql('p.special_price', 'p.price'));
}
else
{
$select->joinInner(array(
'pd' => $this->_resource->getTable(array(
'catalog/product',
$priceAttribute->getBackendType()
))
) , 'pd.entity_id = rp.product_id AND pd.store_id = 0 AND pd.attribute_id = ' . $priceAttribute->getId() , array())->joinLeft(array(
'pspd' => $specialPriceTable
) , 'pspd.entity_id = rp.product_id AND (pspd.attribute_id=' . $specialPriceAttributeId . ')' . 'AND pspd.store_id = 0', array())->joinLeft(array(
'p' => $this->_resource->getTable(array(
'catalog/product',
$priceAttribute->getBackendType()
))
) , 'p.entity_id = rp.product_id AND p.store_id = ' . $storeId . ' AND p.attribute_id = pd.attribute_id', array())->joinLeft(array(
'psp' => $specialPriceTable
) , 'psp.entity_id = rp.product_id AND (psp.attribute_id=' . $specialPriceAttributeId . ')' . 'AND psp.store_id = ' . $storeId, array());
$priceColumn = $this->_connection->getIfNullSql($this->_connection->getIfNullSql('pg.value', 'pgd.value') , $this->_connection->getIfNullSql('psp.value', $this->_connection->getIfNullSql('pspd.value', $this->_connection->getIfNullSql('p.value', 'pd.value'))));
}
$select->columns(array(
'grouped_id' => $this->_connection->getConcatSql(array(
'rp.product_id',
'rp.customer_group_id'
) , '-') ,
'product_id' => 'rp.product_id',
'customer_group_id' => 'rp.customer_group_id',
'from_date' => 'r.from_date',
'to_date' => 'r.to_date',
'action_amount' => 'rp.action_amount',
'action_operator' => 'rp.action_operator',
'action_stop' => 'rp.action_stop',
'sort_order' => 'rp.sort_order',
'price' => $priceColumn,
'rule_product_id' => 'rp.rule_product_id',
'from_time' => 'rp.from_time',
'to_time' => 'rp.to_time'
));
return $select;
}
I fixed it in another way. It was just easy to put into the price field for example 100 and then into special price field 90 when there was 10% discount on product page but now I removed special price from product page and just created catalog price rule 10% discount to that product(s) and now other rules also work:)

Magento: How to remove the price for bundled product options on the shopping cart page, checkout etc

Please help me removing the price for bundled product options on the shopping cart page, checkout, etc. Here is a pic.
What do i need to do?
To remove this edit:
Mage_Bundle_Block_Checkout_Cart_Item_Renderer
Look for the _getBundleOptions() method and at around line 77 change it as follows
//$option['value'][] = $this->_getSelectionQty($bundleSelection->getSelectionId()).' x '. $this->htmlEscape($bundleSelection->getName()). ' ' .Mage::helper('core')->currency($this->_getSelectionFinalPrice($bundleSelection));
//New line
$option['value'][] = $this->_getSelectionQty($bundleSelection->getSelectionId()).' x '. $this->htmlEscape($bundleSelection->getName());
Then edit:
Mage_Bundle_Block_Sales_Order_Items_Renderer
Look for the getValueHtml() method at around line 115 change the code as follows
public function getValueHtml($item)
{
if ($attributes = $this->getSelectionAttributes($item)) {
//Old code
/*
return sprintf('%d', $attributes['qty']) . ' x ' .
$this->htmlEscape($item->getName()) .
" " . $this->getOrder()->formatPrice($attributes['price']);
*/
return sprintf('%d', $attributes['qty']) . ' x ' .
$this->htmlEscape($item->getName());
} else {
return $this->htmlEscape($item->getName());
}
}
The usual caveats about not editing core code and using local or module rewrites apply!
let me know if i can help you more.
OR Also you can hide with css like below
Assuming that you want to remove it from all items regardless of the price, then you could add this css
#shopping-cart-table dd span.price{
display:none;
}
If you only want to remove the price if it is zero,you can also do in this way
/app/design/frontend/default/{theme path}/template/checkout/cart/item/default.phtml (around line # 46)
Figure out where it is add the price and only append the price if it is greater than 0
or
Do a find a replace str_replace("$0.00", "", $_formatedOptionValue['value']) on the string that display that line (make sure to add the currency sign so that $10.00 dont get replace)
I found another way to do it. Hopefully it will help somebody.
1 - Go to /public_html/app/code/core/Mage/Bundle/Helper/Catalog/Product
2 - open the file Configuration.php
3 - from about line 119 till about 127 you will find this code:
foreach ($bundleSelections as $bundleSelection) {
$qty = $this->getSelectionQty($product, $bundleSelection->getSelectionId()) * 1;
if ($qty) {
$option['value'][] = $qty . ' x ' . $this->escapeHtml($bundleSelection->getName())
. ' ' . Mage::helper('core')->currency(
$this->getSelectionFinalPrice($item, $bundleSelection)
);
}
}
Change that with this code:
foreach ($bundleSelections as $bundleSelection) {
$qty = $this->getSelectionQty($product, $bundleSelection->getSelectionId()) * 1;
if ($qty) {
$option['value'][] = $this->escapeHtml($bundleSelection->getName());
}
}
One caution note, be careful about editing the core file. You can also use local or module rewrites.

Codeigniter CSV upload then explode

I have some code that uploads the CSV file to the specified folder, but it doesn't update the database.
public function do_upload()
{
$csv_path = realpath(APPPATH . '/../assets/uploads/CSV/');
$config['upload_path'] = $csv_path;
$config['allowed_types'] = '*'; // All types of files allowed
$config['overwrite'] = true; // Overwrites the existing file
$this->upload->initialize($config);
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload('userfile'))
{
$error = array('error' => $this->upload->display_errors());
$this->layout->buffer('content', 'program/upload', $error);
$this->layout->render();
}
else
{
$image_data = $this->upload->data();
$fname = $image_data['file_name'];
$fpath = $image_data['file_path'].$fname;
$fh = fopen($fpath, "r");
$insert_str = 'INSERT INTO wc_program (JobRef, Area, Parish, AbbrWorkType, WorkType, Timing, TrafficManagement, Location, Duration, Start, Finish) VALUES '."\n";
if ($fh) {
// Create each set of values.
while (($csv_row = fgetcsv($fh, 2000, ',')) !== false) {
foreach ($csv_row as &$row) {
$row = strtr($row, array("'" => "\'", '"' => '\"'));
}
$insert_str .= '("'
// Implode the array and fix pesky apostrophes.
.implode('","', $csv_row)
.'"),'."\n";
}
// Remove the trailing comma.
$insert_str = rtrim($insert_str, ",\n");
// Insert all of the values at once.
$this->db->set($insert_str);
echo '<script type="text/javascript">
alert("Document successfully uploaded and saved to the database.");
location = "program/index";
</script>';
}
else {
echo '<script type="text/javascript">
alert("Sorry! Something went wrong please proceed to try again.");
location = "program/upload";
</script>';
}
}
}
When I run var_dump($fh); it shows: resource(89) of type (stream)
When I run var_dump($fpath) it shows: string(66) "/Applications/MAMP/htdocs/site/assets/uploads/CSV/wc_program.csv"
So it all uploads but what is wrong with it not updating the database?
I have tried all kinds of changing the fopen method but still no joy, I really need it to add to the database and the insert query and set query should do the trick but it doesn't.
Any help greatly appreciated!
You are not running any query on the database. You are mixing active record syntax with simple query syntax. The active record insert query will be executed by calling.
$this->db->insert('my_table');
db::set() does not actually query the database. It takes in a key/value pair that will be inserted or updated after db::insert() or db::update() is called. If you build the query yourself you need to use the db::query() function.
Review the active directory documentation.
You can use $this->db->query('put your query here'), but you lose the benefit of CodeIgniter's built in security. Review CodeIgniter's query functions.
I'll give you examples of just a few of the many ways you can insert into a database using CodeIgniter. The examples will generate the query from your comment. You will need to adjust your code accordingly.
EXAMPLE 1:
$result = $this->db
->set('JobRef', 911847)
->set('Area', 'Coastal')
->set('Parish', 'Yapton')
->set('AbbrWorkType', 'Micro')
->set('WorkType', 'Micro-Asphalt Surfacing')
->set('Timing', 'TBC')
->set('TrafficManagement', 'No Positive Traffic Management')
->set('Location', 'Canal Road (added PMI 16/07/12)')
->set('Duration', '2 days')
->set('Start', '0000-00-00')
->set('Finish', '0000-00-00')
->insert('wc_program');
echo $this->db->last_query() . "\n\n";
echo "RESULT: \n\n";
print_r($result);
EXAMPLE 2 (Using an associative array):
$row = array(
'JobRef' => 911847,
'Area' => 'Coastal',
'Parish' => 'Yapton',
'AbbrWorkType' => 'Micro',
'WorkType' => 'Micro-Asphalt Surfacing',
'Timing' => 'TBC',
'TrafficManagement' => 'No Positive Traffic Management',
'Location' => 'Canal Road (added PMI 16/07/12)',
'Duration' => '2 days',
'Start' => '0000-00-00',
'Finish' => '0000-00-00'
);
$this->db->insert('wc_program', $row);
// This will do the same thing
// $this->db->set($row);
// $this->db->insert('wc_program');
echo $this->db->last_query();
Example 1 and 2 are using the Active Record. The information is stored piece by piece and then the query is built when you make the final call. This has several advantages. It allows you to build queries dynamically without worrying about SQL syntax and order of the keywords. It also escapes your data.
EXAMPLE 3 (Simple Query):
$query = 'INSERT INTO
wc_program
(JobRef, Area, Parish, AbbrWorkType, WorkType, Timing, TrafficManagement, Location, Duration, Start, Finish)
VALUES
("911847","Coastal","Yapton","Micro","Micro-Asphalt Surfacing","TBC","No Positive Traffic Management","Canal Road (added PMI 16/07/12)","2 days","0000-00-00","0000-00-00")';
$result = $this->db->query($query);
echo $this->db->last_query() . "\n\n";
echo "RESULT: \n";
print_r($result);
This way leaves all the protection against injection up to you, can lead to more errors, and is harder to change/maintain.
If you are going to do it this way you should use the following syntax, which will protect against injection.
EXAMPLE 4:
$query = 'INSERT INTO
wc_program
(JobRef, Area, Parish, AbbrWorkType, WorkType, Timing, TrafficManagement, Location, Duration, Start, Finish)
VALUES
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);';
$row = array(
911847,
'Coastal',
'Yapton',
'Micro',
'Micro-Asphalt Surfacing',
'TBC',
'No Positive Traffic Management',
'Canal Road (added PMI 16/07/12)',
'2 days',
'0000-00-00',
'0000-00-00'
);
$result = $this->db->query($query, $row);
echo $this->db->last_query() . "\n\n";
echo "RESULT: \n";
print_r($result);
CodeIgniter will replace each "?" in the query with the corresponding value from the array after it is escaped. You can use this to run many queries that are of the same form, but have different data just by updating the $row array and benefit from CI's built in security.

Export comments from fb:comments

I'm a little desperate about this. I have a site with a comments box with around 183000 comments that I want to backup. But every time I do an fql.query, I only get 100 items. I had tried:
SELECT xid, object_id, post_id, time, text, id FROM comment WHERE xid='bdatapoyo' ORDER BY time DESC
and after that, using the last "time"
SELECT xid, object_id, post_id, time, text, id FROM comment WHERE xid='bdatapoyo' AND time >= xxxxxxx ORDER BY time DESC
but the latter only gives me one comment..
I made an PHP page with this code, but again, it only grabs 100 items:
<?php
require 'php-sdk/src/facebook.php';
$facebook = new Facebook(array(
'appId' => 'XXXXXXXXXX',
'secret' => 'XXXXXXXXXX',
'cookie' => true,
));
$conexion = mysql_connect("localhost", "XXXX", "XXXX");
mysql_select_db("TVN", $conexion);
$time_old = "1315070888";
do {
$fql = "SELECT fromid,time,text FROM comment WHERE xid='bdatapoyo' AND time >= " . $time_old . " ORDER BY time";
$response = $facebook->api(array(
'method' => 'fql.query',
'query' =>$fql,
));
foreach($response as $key => $value) {
$sql = "INSERT INTO comment (text, uuid, time) VALUES ('" . $value["text"] . "', '" . $value["fromid"] . "', '" . $value["time"] . "')";
$result = mysql_query($sql);
}
$time_old = $response[count($response)-1]["time"];
print_r($time_old);
} while (count($response) > 0);
?>
OK, I was able to pull this out with LIMIT and OFFSET. The correct FQL is
SELECT fromid,time,text FROM comment WHERE xid='bdatapoyo' LIMIT 100 OFFSET 0
and then paging with the OFFSET
is this code setup to import every single comment to a db from all users on your site? What is xid=bdatapoyo?

Resources