Export Orders from Magento for shipment - php

I am working on an online store on the Magento platform and have hit a major roadblock: For some reason I cannot figure out how to export current orders (with shipping information/shipment type/etc). Does anyone have any suggestions? This seems as if it should be one of the most basic things for a system like this to do, but I have not been able to find out how.

Seeing as you want this for shipping you might want to ask whoever handles your shipping whether they have some sort of API so you can build/buy/download an appropriate shipping module and spare yourself the hassle of mucking about with CSV files.
If you really want a CSV file however I can show you how to create it. You didn't mention where this script will run so I'll assume it's an external script (which will make it easier to use with a cron job).
You want to do the following:
//External script - Load magento framework
require_once("C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\magento\app\Mage.php");
Mage::app('default');
$myOrder=Mage::getModel('sales/order');
$orders=Mage::getModel('sales/mysql4_order_collection');
//Optional filters you might want to use - more available operations in method _getConditionSql in Varien_Data_Collection_Db.
$orders->addFieldToFilter('total_paid',Array('gt'=>0)); //Amount paid larger than 0
$orders->addFieldToFilter('status',Array('eq'=>"processing")); //Status is "processing"
$allIds=$orders->getAllIds();
foreach($allIds as $thisId) {
$myOrder->reset()->load($thisId);
//echo "<pre>";
//print_r($myOrder);
//echo "</pre>";
//Some random fields
echo "'" . $myOrder->getBillingAddress()->getLastname() . "',";
echo "'" . $myOrder->getTotal_paid() . "',";
echo "'" . $myOrder->getShippingAddress()->getTelephone() . "',";
echo "'" . $myOrder->getPayment()->getCc_type() . "',";
echo "'" . $myOrder->getStatus() . "',";
echo "\r\n";
}
For the sake of brevity (and sanity) I haven't listed all the available order information. You can find out what fields are available by dumping the relevant objects and taking a look at their fields.
For example if you were to do print_r($myOrder->getBillingAddress()); you'd see fields like "address_type" and "lastname". You can use these with
$myOrder->getBillingAddress()->getAddress_type() and
$myOrder->getBillingAddress()->getLastname() respectively.
Edit:
Changed code according to craig.michael.morris's answer

I was in the process of implementing your solution and noticed that it was only returning the first values for all the foreign keys such as billing address, shipping address, payment etc...
This can be fixed by changing
$myOrder->load($thisId);
to
$myOrder->reset()->load($thisId);

You may also want to look at this extension: http://www.magentocommerce.com/extension/1158/manual-order-export
Also you can connect via soap: This example is set up for localhost and assumes you have set up a web services user and role under system>>web services in the admin.
<?php
$time = microtime();
$time = explode(' ', $time);
$time = $time[1] + $time[0];
$begintime = $time;
?>
<?php
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1);
// hostname
$host= '127.0.0.1';
// if store in /magento change /shop, if store in root remove /shop
$client= new SoapClient('http://'.$host.'/magento/index.php/api/soap/?wsdl');
// Can be added in Magento-Admin -> Web Services with role set to admin
$apiuser= 'soap';
// API key is password
$apikey = '******';
$sess_id= $client->login($apiuser, $apikey);
echo "<html>";
echo "<head>";
echo "<LINK REL=StyleSheet HREF=\"style.css\" TYPE=\"text/css\" MEDIA=screen>";
echo "</head>";
echo "<body>";
$result= $client->call($sess_id, 'sales_order.list', array(array('status'=>array('='=>'Pending'))));
echo '<pre>';
print_r($result);
echo '<pre>';
?>
<?php
// Let's see how long this took…
$time = microtime();
$time = explode(" ", $time);
$time = $time[1] + $time[0];
$endtime = $time;
$totaltime = ($endtime - $begintime);
echo '<br /><br /><em>This Magento SOAP API script took ' .$totaltime. ' seconds, precisely.</em>';
// ...and close the HTML document
echo "</body>";
echo "</html>";
?>

In case this helps any one, you can use the invoice table as a key. An invoice in magento with a auth+capture credit card setup means the money has come in. In our case we only needed a sql query to run in phpmyadmin that would export order numbers and invoice numbers for us to reconcile to check that the order export extension from xtento was working. This is what we used:
SELECT sales_flat_order.increment_id AS 'order', sales_flat_invoice.increment_id AS 'invoice'
FROM sales_flat_order
RIGHT JOIN sales_flat_invoice ON sales_flat_invoice.order_id = sales_flat_order.entity_id
WHERE sales_flat_invoice.updated_at >= "2011-07-01 00:00:00"
ORDER BY sales_flat_order.increment_id DESC

If the system doesn't support any direct way to export orders, you could create a view in the database that lists the orders you need to export. Then use something like phpMyAdmin to export the data from the view as CSV.

Saho's suggestion for using SOAP is great, but it may take a long time (Apache can only assign a limited CPU resource to tread to handle that request)
Suggest you to write a php script and then run it through terminal.
Sonam

Related

how can I define how long a client was visiting a site

I have a site and I want to measure how long a client was connected to my site, one hour or two hour... or? how is it possible?
can someone help me in this regard.
it will be appreciated.
As mentioned in the comments, it's best to use analytic software but if you are looking for something simple (or just learning experience)
<?php
session_start();
if(!isset($_SESSION['sessionId'])) // No session, first time (subject to session timeout)
{
mysqli_query("INSERT INTO visitor_sessions(`started_on`, `last_checkin`) (" . time() . ", " . time() .")");
$_SESSION['sessionId'] = mysqli_insert_id(); // start the 'visiting session'
}
else
{
mysqli_query("UPDATE visitor set `last_checkin` = " . time() . " WHERE id = " .$_SESSION['sessionId']); // Update last checkin
}
?>
visitor_sessions is a table with 3 columns, id, started_on and last_checkin (timestamps).
You can include this script in your pages thus updating last check_in with each new page opened or have jquery call it every x seconds to maintain time even if they just view a page.
PS: Code was not tested but this is the general idea

PHP not retrieving new data until page refresh

What is happening is I think my code is selecting the data first (basically old data) then updating it but what I want is for it to update then select the data (new data). How can I do this?
I am going to post where it goes wrong and if you need the full code just ask:
$select_links = $db->query("SELECT pid, added_by,link_title,lid,link_order FROM " . TABLE_PREFIX . "homepage_links WHERE pid='$pid'
ORDER BY link_order DESC LIMIT $start,$show");
$check_link_count_rows = $db->num_rows($select_links);
echo "<b> You Current Have " . $check_link_count_rows . " Links On Your Page: </b><br>";
echo "<form action='' method='POST'>
";
while($select_links_array = $db->fetch_array($select_links)) {
$link_title_display = $select_links_array['link_title'];
$link_id_display = $select_links_array['lid'];
if(!$mybb->input["order_edit_$link_id_display"]) {
$link_order_display = $select_links_array['link_order'];
} else {
$link_order_display = $mybb->input["order_edit_$link_id_display"];
}
$order_edit_value1 = $mybb->input["order_edit_$link_id_display"];
$order_edit_value = $db->escape_string($order_edit_value1);
echo "<br>" . $link_title_display . " <a href='?operation=edit_links&link=$link_id_display'> (edit) </a>
<input type='number' name='order_edit_$link_id_display' value='$link_order_display' style='width:40px;'>
<input type='hidden' name='get_link_id_display_value_$link_id_display' value='$link_id_display'><br>
";
$get_link_id_display_value1 = $mybb->input["get_link_id_display_value_$link_id_display"];
$get_link_id_display_value = $db->escape_string($get_link_id_display_value1);
$update_quick_edit_query = $db->query("UPDATE spud_homepage_links SET link_order='$order_edit_value'
WHERE lid='$get_link_id_display_value'");
}
I cannot find a solution as everything is in the right place for it to work besides this bug.
After a discussion in the comments, I determined that you were attempting to render a page after a post form submission that amends the database. It is perfectly possible to re-read your new database state and render it in a post operation, but it is inadvisable, since browsers cannot refresh the page without asking you if you wish to run the operation again. This does not make for a good user experience, especially in relation to using the back/forward buttons.
The reason for this behaviour is that post operations generally modify the database. They are used for example in credit card purchases or profile amendments where some change in the state of the server is expected. Thus, it is good practice to execute a new round-trip to the server, after the write operation, to change the page method from post to get.
The header() call I linked to will do this, and will resolve your rendering problem too.

TeamSpeak: Query Number of Connected Clients

I am currently using TeamSpeak's ServerQuery feature to display all channels and connected users via PHP on my website. Right now it looks like this: (apologies for the crude usernames/channel titles)
It works to display channels and user names. However, I do not want it to do this.
Instead of showing all channels and user names that have connected, I would prefer it just to fetch the amount of users that are currently connected and the maximum amount of users that can connect and display them as seen above. (Along with the server status, i.e online or offline.)
This is the API I am using to connect to the TeamSpeak server via PHP.
Discovered a solution by myself!
Framework
TeamSpeak PHP Framework.
We only really need the libraries folder for this situation, so feel free to delete the docs and images folders.
--
PHP (Thanks to SilentStorm)
<?php
date_default_timezone_set("Europe/London");
require_once("libraries/TeamSpeak3/TeamSpeak3.php");
TeamSpeak3::init();
header('Content-Type: text/html; charset=utf8');
$status = "offline";
$count = 0;
$max = 0;
try {
$ts3 = TeamSpeak3::factory("serverquery://<USER>:<PASSWORD>#<SERVER IP>:<QUERY PORT>/?server_port=<SERVER PORT>&use_offline_as_virtual=1&no_query_clients=1");
$status = $ts3->getProperty("virtualserver_status");
$count = $ts3->getProperty("virtualserver_clientsonline") - $ts3->getProperty("virtualserver_queryclientsonline");
$max = $ts3->getProperty("virtualserver_maxclients");
}
catch (Exception $e) {
echo '<div style="background-color:red; color:white; display:block; font-weight:bold;">QueryError: ' . $e->getCode() . ' ' . $e->getMessage() . '</div>';
}
echo '<span class="ts3status">TS3 Server Status: ' . $status . '</span><br/><span class="ts3_clientcount">Clients online: ' . $count . '/' . $max . '</span>';
?>
Customise
- ServerQuery username (Can be found in TeamSpeak, Tools -> ServerQuery Login
- ServerQuery password (Can be found in TeamSpeak, Tools -> ServerQuery Login
- The server's IP address
- The ServerQuery port (Default - 10011)
- The server's port (Default - 9987)
Save the file appropriately, in the same directory that includes the libraries folder. To display it on a page put the code:
<?php
include('path/to/file/filename.php');
?>
This will then display the TeamSpeak server information on the page! Hope I could help.

Run php script monthly on windows based server

I need your help to run following php script automatically on 05th day of the every month. Currently I run this manually. Is this possible using schedule task?
Also I don't have admin access to the web server. Therefore cannot use third party automation tools.
PS:
Is it possible to schedule this in a local machine with windows 7 xampp environment and then later update remote db?
session_start();
if($_SESSION['log'] != "log" || $_SESSION['type'] != "***"){
header("Location: ***.php");
}
require_once('conf.php');
date_default_timezone_set('Asia/Kolkata');
$date = date("j"); //get current date
$today = date("d-m-Y");
$now = date("F j, Y, g:i a"); // March 10, 2001, 5:16 pm
if ($date === 5){
//get interest rate
$sql = mysql_query("SELECT Rate FROM Interest WHERE Ref = 'Loan' ORDER BY Date DESC LIMIT 1");
$r = mysql_fetch_assoc($sql);
$rate = $r['Rate'];
//check for not settled loans
$check = mysql_query("SELECT LID FROM Registry WHERE Status = 0");
if (mysql_num_rows($check) > 0){
while ($list = mysql_fetch_assoc($check)) { // while there are rows to be fetched...
//*** Start Transaction ***//
mysql_query("BEGIN");
$loanID = $list['LID'];
//get loan data
$sql = mysql_query("SELECT Registry.Amount, SUM(Account.Total) AS Paid, SUM(Account.Interest) AS intPaid FROM Registry LEFT JOIN Account ON Registry.LID = Account.LID WHERE Registry.Status = 0 AND Account.Auto = 0 AND (Account.LID = '$loanID') GROUP BY Account.LID");
$r = mysql_fetch_assoc($sql);
$amount = $r['Amount']; //loan amount
$paid = $r['Paid']; //sum of paid
$intPaid = $r['intPaid']; //sum of interest paid
//get sum of monthly automatically updated interest
$sql = mysql_query("SELECT SUM(Interest) AS Interest FROM Account WHERE Payment = 0 AND Auto = 1 AND LID = '$loanID'");
$r = mysql_fetch_assoc($sql);
$autoInt = $r['Interest'];
$total = ($amount + $autoInt); //total to be paid
$balance = ($total - $paid); //with no interest
if ($paid >= $balance){
// echo "Loan completed <br/>";
}else{
$int = ($balance * $rate) / 100;
$update = mysql_query("INSERT INTO Account (LID, Date, Interest, Total, Auto) VALUES ('$loanID', NOW(), '$int', '$int', 1)") or die(mysql_error());
if (! $update){
//*** RollBack Transaction ***//
mysql_query("ROLLBACK");
// $_SESSION['error'] = "Interest saving failed.!";
echo "Loan ID: " . $loanID . ", Interest: Rs. " . $int . "/= - Update Failed.!<br>";
}else{
//*** Commit Transaction ***//
mysql_query("COMMIT");
// $_SESSION['error'] = "Interest saved successfully";
echo "Loan ID: " . $loanID . ", Interest: Rs. " . $int . "/= - Update Succeeded.!<br>";
}
}
}
}
}else{
echo "Monthly Interest can be update only by 05th day of the month.!";
}
I dont think at needs admin permissions
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/at.mspx?mfr=true
EDIT:
or even try MySQL Events
http://dev.mysql.com/doc/refman/5.1/en/events.html
It looks all database work which should be easily do able
If it is a publicly accesseable web server, you can use a cronjob service like https://www.cronjobservice.net/. After registration you enter an url and the time they shall call it. I advice using multiple of those services for the case one fails. (your script must execute on first call and exit on subsequent calls from other services.)
Please be sure to properly deal with .htaccess and make sure to have no security relevant output.
Have you asked the peoples that are hosting your site if they have a solution?
Most hosting companies have solutions for this (even on Windows servers)
If the hosting company has no solution for this (what I seriously doubt) you can call the script externally from another server that has cron possibilities or have it called by the first visitor on that day.
I any case you will want to include a check in your script that your script only runs on the set date (you already have that) and also make sure that calling the script more than once on that day is no problem.
PS : if the script is called by the first visitor you will have to consider the fact that you could not have any visitor that particular day, so the script will have to run whenever the next visitor comes along.
If you don't have administrative access to Windows, you won't be able to create a scheduled task. Your only alternative is to create some sort of custom task component in your application that checks / stores the last time a script was run. The problem with this is that it relies on user activity and it may not run on the exact date that you want it to.
The other alternative is to find Linux hosting so that you can avail of Cron.

Get records from a table with timestamps / echo a message in the row when the timestamp difference is more than 5 minutes

I get a list of records and each record is a question / answer / timestamp.
I created a basic PHP report:
<?php
$con = mysql_connect("localhost", "login", "pass");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("db", $con);
$result = mysql_query(" SELECT *
FROM `experiment`
where userid = 73");
while ($row = mysql_fetch_array($result)) {
echo "question " . $row['question'] . "answer " . $row['answer'] .
"time " . $row['time'] . "stamp " . $row['createdAt'] . "<br>";
}
I need some way to compare the row in front of createdAt and the row after createdAt.
If the difference between two rows is bigger then 2 minutes, the thing should echo "warning".
I'll assume a couple of things on your behalf. This may change the value of the answer, but you simply haven't provided the necessary information for an answer to be feasible at this point.
I am going to assume that you are looping through the data records. You imply this by stating that there is a display of multiple rows. Your SQL query only gets the data of one row. I'll assume that you actually have gotten an entire record set instead. Because otherwise, the data structure needs to be examined for its design choices. I am also making an assumption on how userid is used in a table, mind, so that's my personal bias.
As record sets are collected, they can be manipulated. You're using the ancient mysql_* method here. I recommend that you read the PDO methodology that php has available at 5.2.7+ and consider upgrading your php version if you don't already have it.
The manipulation can take many forms.
$previousRecord = 0;
foreach ($recordSet as $index=>$record){
$recordSet[$index]['warningTime'] = FALSE;
if ($previousRecord){
if (($record['createdAt']-$previousRecord) > 120){
$recordSet[$index]['warningTime'] = TRUE;
}
}
$previousRecord = $record['createdAt'];
// Other data manipulation logic for page presentation
}
This should inject the warning right into the dataset that can be displayed whenever you want it to be. I do prefer a seperation of functions for maintainability; calling the database, extracting/formatting the data, displaying the data. It makes future changes much easier, also allows for code portability. You do not have this in your code, which means that whenever you do something like this again, well, you'll re-invent the wheel.
$createdAt = null;
while($row = mysql_fetch_array($result)) :
// initialise on first run
if ($createdAt === null) :
$createdAt = $row['createdAt'];
endif;
// now $createdAt is the value of the last row... if so, echo warning, else echo nothing
echo checkCreatedIsOlderThanTwoMinutes($createdAt, $row['createdAt']) === true ? "WARNING!" : "";
echo "question ". $row['question']. "answer ". $row['answer']. "time ".$row['time']."stamp ". $row['createdAt']."<br>";
endwhile;
I don't have a clue what the format of your createdAt looks like, so I use this pseudo-function:
function checkCreatedIsOlderThanTwoMinutes($oldCreatedAt, $newCreatedAd)
{
// check that stuff
}
Hope that helps.

Categories