Now that my plugin is in a solid beta stage and I have populated my database with NetSuite data related to my customer I need to start building my views. The first step I have is pulling the necessary date out of my database and putting it into read able objects for my view to then loop through and display the information I need. I am going to code this in my model for the orderlist view. If you need to look back for reference this is a continuation from my post on setting up MVC.
Let’s create our objects for use in the view by opening up the com_joomsuite/models/orderlist.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla modelitem library
jimport('joomla.application.component.modelitem');
/**
* OrderList Model
* @since 0.1.0
*/
class JoomSuiteModelOrderList extends JModelItem
{
/**
* @var object orders
* @var object customer
*/
protected $customer;
protected $orders;
/**
* Get the message we set in the controller
* @return string The message to be displayed to the user
*/
public function getCustomer() {
if (!isset($this->customer)){
//Get the current user
$user =& JFactory::getUser();
//Set the database
if(!isset($this->db)){
$this->db = JFactory::getDBO();
}
if(!isset($this->app)){
$this->app = &JFactory::getApplication();
}
//Get users's NetSuite Data from out JoomSuite customer table
$query = $this->db->getQuery(true);
$query->select('*');
$query->from('#__joomsuite_customers');
//$this->app->enqueueMessage( JText::_( "User E-Mail:" . $user->email ), 'message' );
$query->where('email = "'. 'donngibson@aol.com' . '"');//replace with $user->email
$this->db->setQuery((string)$query);
$results = $this->db->loadObjectList();
if($results){
$this->customer = $results[0];
}else{
//Add a part that hides this menu item if here are no record associated with the user.... yeah how are you gonna do that... ;)
}
}
//Now we return the data that the view wants.
return $this->customer;
}
public function getOrders(){
if(isset($this->customer)){
//Set the database
if(!isset($this->db)){
$this->db = JFactory::getDBO();
}
if(!isset($this->app)){
$this->app = &JFactory::getApplication();
}
if($this->customer->customer_type == "Customer"){
$where = "customer = '" . $this->customer->name . "'";
}else if ($this->customer->customer_type == "Employee"){
$where = "sales_rep = '" . $this->customer->name . "'";
}else{
return null;
}
$query = $this->db->getQuery(true);
$query->select('*');
$query->from('#__joomsuite_sales_orders');
$query->where($where);
$this->db->setQuery((string)$query);
$results = $this->db->loadObjectList();
if($results){
$this->orders = $results;
}else{
//No orders :(
}
return $this->orders;
}else{
//Set the customer and re-run
$this->customer = $this->getCustomer();
getOrders();
}
}
}
As you can see all we are doing is creating a customer object so that we only pull information on the customer we want. Then we pull the the orders from our other table that reference the user. Now that we have the necessary objects. Now that we have the necessary objects we need to assign them in the view.html.php. We really don’t need to do much as far as changes go here it’s just a standard template display.
function display($tpl = null)
{
$this->customer = $this->get('customer');
$this->orders = $this->get('orders');
// Check for errors, becasue its just a good practice.
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));
return false;
}
// Display the view
parent::display($tpl);
}
As you can see we only made some minor adjustments to the view.html.php’s display function. Now the fun part creating our view. Open up the tmpl/defualt.php. This is how I pulled mine off this part is basically just structuring your HTML and designing your page with a few Joomla pieces added in and some php for loops
<?php
/**
* @author Joe Motacek
* @since 0.1.0
*/
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
//Load custom CSS
$document =& JFactory::getDocument();
$document->addStyleSheet(JURI::base() . 'components/com_joomsuite/assets/css/joomsuite.css');
$document->addScript("http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js");
$document->addScript(JURI::base() . 'components/com_joomsuite/assets/js/jquery.tablesorter.js');
?>
<div class="joomsuite">
<h1>Orders</h1>
<?php if( count($this->orders) == 0 ){?>
<h3>You have no orders on file.</h3>
<?php }else{?>
<!-- Pending Orders -->
<fieldset>
<legend>Pending Approval</legend>
<table id="pendAppTbl" class="tablesorter">
<thead>
<tr>
<th>Requested Ship</th>
<th>Sales Order</th>
<th>PO Number</th>
<th>Customer</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php
$pendingOrders = 0;
foreach ($this->orders as $order){
if($order->status == "Pending Approval"){?>
<tr>
<td><?php echo $order->requested_ship_date?></td>
<td><<?php echo $order->order_number?></td>
<td><?php echo $order->po_number?></td>
<td><?php echo $order->customer?></td>
<td><?php setlocale(LC_MONETARY, 'en_US');
echo money_format("%n", $order->total)?></td>
</tr>
<?php
$pendingOrders ++;
}
}?>
</tbody>
</table>
<?php if($pendingOrders == 0){ echo "<p>You have no pending orders</p>"; }?>
</fieldset>
<?php if($pendingOrders != 0){?><script type="text/javascript">
$(document).ready(function(){
$("#pendAppTbl").tablesorter({sortList: [[0,0]]});
}
);</script><?php }?>
<!-- Pending Fulfillment -->
<fieldset>
<legend>Pending Fulfillment</legend>
<table id="pendFulTbl" class="tablesorter">
<thead>
<tr>
<th>Requested Ship</th>
<th>Sales Order</th>
<th>PO Number</th>
<th>Customer</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php
$approvedOrders = 0;
foreach ($this->orders as $order){
if($order->status == "Pending Fulfillment"){?>
<tr>
<td><?php echo $order->requested_ship_date?></td>
<td><?php echo $order->order_number?></td>
<td><?php echo $order->po_number?></td>
<td><?php echo $order->customer?></td>
<td><?php setlocale(LC_MONETARY, 'en_US');
echo money_format("%n", $order->total)?></td>
</tr>
<?php
$approvedOrders ++;
}
}?>
</tbody>
</table>
<?php if($approvedOrders == 0){ echo "<p>You have no bookings</p>"; }?>
</fieldset>
<?php if($approvedOrders != 0){?><script type="text/javascript">
$(document).ready(function(){
$("#pendFulTbl").tablesorter({sortList: [[0,0]]});
}
);</script><?php }?>
<!-- Billed -->
<fieldset>
<legend>Shipped</legend>
<table id="shipTbl" class="tablesorter">
<thead>
<tr>
<th>Requested Ship</th>
<th>Sales Order</th>
<th>PO Number</th>
<th>Customer</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php
$shippedOrders = 0;
foreach ($this->orders as $order){
if($order->status == "Billed"){?>
<tr>
<td><?php echo $order->requested_ship_date?></td>
<td><?php echo $order->order_number?></td>
<td><?php echo $order->po_number?></td>
<td><?php echo $order->customer?></td>
<td><?php setlocale(LC_MONETARY, 'en_US');
echo money_format("%n", $order->total)?></td>
</tr>
<?php
$shippedOrders ++;
}
}?>
</tbody>
</table>
<?php if($shippedOrders == 0){ echo "<p>You have no shipments</p>"; }?>
</fieldset>
<?php if($shippedOrders != 0){?><script type="text/javascript">
$(document).ready(function(){
$("#shipTbl").tablesorter({sortList: [[0,0]]});
}
);</script><?php }?>
<br/><h5>* Click the column header to sort the data. <br/>
* Sort multiple columns simultaneously by holding down the shift key and clicking a second column header.</h5>
<?php }//END ELSE?>
</div>
At the top your see some lines were I added a custom CSS so I could override and default CSS and make my tables look how I want. You’ll also notice that I added in tabblesorter jQuery library. Since I was using a table I figured why not make it sortable
This breaks my table data down into 3 sections: Pending Approval, Pending Fulfillment and Shipped. These are based on the type set in the database. The data is pulled from a web service scraper I built, please check the plug-in for a reference to the basics of it. Now that I’ve gotten my base list displaying the way I need I will start working on the order details page which will link from each order.
I wanted to give everyone an example of how to I use the search pagination with the PHP Toolkit. In this example I am taking the results of a transaction search and paging through it. This technique can be very helpful if you start hitting script timeouts. The key parts to look at here are:
Line 2: the digit you set in the search preferences determines the page size.
Lines 23, 24, 26: this is where you set up you loop for the pagination. Since we are working with PHP and have not established an active session with login we need to get the SearchId.
Lines 28 – 73: here I’m just processing the order for entry into my database. I have not included the referenced methods here. You’ll be able to see them once I release the full component later.
Lines 74 – 82: This is where we advance to the next set of records.
if(isset($this->myNSclient)){
$this->myNSclient->setSearchPreferences(false, 10);
}else{
$this->app->enqueueMessage( JText::_( "The client is not set" ), 'error' );
return true;
}
try
{
$response = $this->myNSclient->search($orderSearch);
}catch(Exception $e){
$this->app->enqueueMessage( JText::_( $e ), 'error' );
}
if ($response->isSuccess == true)
{
echo "<br/>Total results: " . (int) $response->totalRecords;
echo "Search ID: " . $response->searchId;
echo "--Page size: " . (int) $response->pageSize;
echo "--Total pages: " . (int) $response->totalPages;
echo "--Current page: " . (int) $response->pageIndex;
$totalPages = (int) $response->totalPages;
$searchId = $response->searchId;
for($i=1; $i <= $totalPages; $i++){
$orders = $response->recordList;
if((string)$order->nsComplexObject_type === "SalesOrder"){
//Check if order exists and it's last modified date
if($this->recordExists($order)){
//the order is in the database
}else{
$orderObject = $this->createOrder($order);
$this->updateRecord($orderObject, '#__joomsuite_sales_orders', 'order_id', true);
}
//Create Order Items
$orderItemList = $order->getField('itemList');
$orderItems = $orderItemList->getField('item');
if(count($orderItems) == 1){
$item = $orderItems;
$item->order_number = $order->getField('tranId');
if($this->recordExists($item)){
//the order is in the database
}else{
$itemObject = $this->createItem($item, true);
$this->updateRecord($itemObject, '#__joomsuite_order_items', 'item_id', true);
}
}else if (count($orderItems) >= 2){
if( isset($orderItems) ){
foreach ($orderItems as $item){
if($item->nsComplexObject_type == "SalesOrderItem"){
$item->order_number = $order->getField('tranId');
}
if($this->recordExists($item)){
//the order is in the database
}else{
$itemObject = $this->createItem($item);
$this->updateRecord($itemObject, '#__joomsuite_order_items', 'item_id', true);
}
}
}
}else{
$this->app->enqueueMessage( JText::_( "Item Unavailable" ), 'error' );
}
}//END IF SALES ORDER
}// END FOREACH
$i++;
if($totalPages > 1){
try{
$response = $this->myNSclient->searchMoreWithId($searchId, $i);
}catch(Exception $e){
$this->app->enqueueMessage( JText::_( $e ), 'error' );
}
}
}//END PAGINATION FOR LOOP
I’ve seen some people try to do this multiple times across multiple searches. Something that you want to note is that you can NOT have more than 2 active SearchId with NetSuite ata time unless you get for the WebService plus package.
Thats it for this week. I’m about 95% done with the plug-in and I am gearing up to start coding the component so every one who has been waiting for me to start coding my views and database connections on the Joomsuite component your wait is almost over.
-Moto OUT
I’m hoping someone out there can tell me that there is a better way to access custom fields than this. It seems that when working with custom fields there is an easy way and a hard way. If your working with most custom field types you can use the example on the last line but if your working with the ListOrRecordRef type your in for hell. The only way I could get the data out I needed was through the convoluted code above the last line (a.k.a. the easy way
) I would love if someone out in the big wide internet knew a better way.
BTW THX NETSUITE FOR MAKING THIS SO EASY! ( = sarcasm )
Both ways:
$customFieldList = $record->getField('customFieldList');
$customFields = $customFieldList->getField('customField');
$salesOrderType = "";
foreach($customFields as $customField){
$fieldInfo = $customField->getFields();
foreach ($fieldInfo as $key => $value){
if ($value == "custbody7"){
$orderType = $customField->getField('value');
$orderTypeList = $orderType->getFields();
foreach ($orderTypeList as $key => $value){
if($key =="typeId"){
switch($value){
case "1":
$salesOrderType = 'New Order';
break;
case "2":
$salesOrderType = 'Reorder';
break;
case "3":
$salesOrderType = 'Reorder with Modifications';
break;
}
}
}
}
}
//$i++;
}
$createdOnDate = $customFieldList->getCustomFieldValue('custbody10');
Well I am still working on my plugin to pull my data from NetSuite and today was fun. The more I work with this ToolKit the more I think “How very un-intuitive!” This was obviously written by someone who primarily develops in another language. Any who… enough ranting. One of the struggles I ran into today was how to set a date range in PHP for my transaction search. Well here you go:
$orderSearch = new nsComplexObject('TransactionSearchBasic');
$todaysDate = date("c");
$pastDate = strtotime ( '-1 year' , strtotime ( $todaysDate ) ) ;
$pastDate = date("c", $pastDate);
$this->app->enqueueMessage( JText::_( "Today's Date: " . $todaysDate ."\n Previous Time: ". $pastDate), 'notice' );
$typeSearchField = new nsComplexObject('SearchEnumMultiSelectField');
$typeSearchField->setFields(array('searchValue' => array('_salesOrder'),
'operator' => 'anyOf'));
$orderSearch->setFields(array(
"nameText" => array(
"operator" => "is",
"searchValue" => $this->customerName
),
"type"=>$typeSearchField,
"dateCreated" => array(
"operator" => "within",
"searchValue" => $pastDate,
"searchValue2" => $todaysDate
)
));
Originally I set it up the same way I setup my ‘SearchEnumMultiSelectField’ because after reading the documentation I figured “hey this is the same thing right!” NO, dead wrong you can’t try and set dateTime in PHP because you’ll get this stupid “ComplexType reference was not found in directory. ComplexTypeName = dateTime” error which makes you think… huh BUT IT”S NS’s STUPID field there must be something wrong with this stupid directory or toolkit. Yeah well it’s just picky is all.
Hope that helps anyone out there who might be stuck on this too
Have you ever used var_dump or print_r only to see next nothing in your echo? I was reading articles all day on how to display the contents of an object in readable human form. I am working with NetSuite’s PHP ToolKit right now and their WebService returns some interesting objects that rely on NetSuite’s variable conventions. Here’s a quick tip if you want to see the content of an object in PHP and your standard methods of display are not working.
<?php
if ($response->isSuccess == true)
{
$orders = $response->recordList;
foreach($orders as $order){
$this->app->enqueueMessage( JText::_( "---Record Information---" ), 'message' );
$fieldArray = $order->getFields();
foreach($fieldArray as $key => $value){
$this->app->enqueueMessage( JText::_( "Fields : " . $key . " : " . $value ), 'message' );
}
if($record->type =="Sales Order")
{
$this->app->enqueueMessage( JText::_( "Create New Order" ), 'message' );
//$order = $this->createOrder($record);
}
}
}
?>
Line 8,9 & 10 are the meat of the tip, the foreach with a $key => $value is the real trick. I’m sure plenty of people know about this already but I forgot about it until today so thought I would share. Most of the outlying code is for context only….
I am working in Joomla which is why there is a reference to the app->enqueMessage method, which you can easily replace with an echo or how ever you prefer to debug
Moto OUT

Categories
Tag Cloud
Blog RSS
Comments RSS
Last 50 Posts
Back
Back
Void « Default
Life
Earth
Wind
Water
Fire
Light 