Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 539,595
» Latest member: ableigpqvu
» Forum threads: 1,745
» Forum posts: 9,084

Full Statistics

Online Users
There are currently 4 online users.
» 0 Member(s) | 1 Guest(s)
Bing, Google, Yandex

Latest Threads
Finetuning the way you se...
Forum: coreBOS Development
Last Post: alexandy40d
12-06-2024, 07:38 AM
» Replies: 4
» Views: 8,134
MariaDB Version
Forum: Administrator Support
Last Post: joebordes
11-01-2024, 11:49 AM
» Replies: 1
» Views: 616
Product Catalog / parts c...
Forum: Modules/Extension Support
Last Post: joebordes
09-15-2024, 09:40 AM
» Replies: 1
» Views: 1,106
Challenges and Best Pract...
Forum: coreBOS Development
Last Post: wishforbes
08-30-2024, 04:21 PM
» Replies: 0
» Views: 717
PRODUCTS IN ACCOUNTS BY O...
Forum: User Support
Last Post: jonathanmoore858
08-03-2024, 04:14 PM
» Replies: 4
» Views: 2,756
Zapier | Integration
Forum: Modules/Extension Support
Last Post: bernardgbailey
07-29-2024, 11:45 PM
» Replies: 7
» Views: 9,841
Versión PHP recomendada
Forum: International
Last Post: joebordes
07-04-2024, 05:42 PM
» Replies: 7
» Views: 3,318
Could Someone Give me Adv...
Forum: Open Discussions
Last Post: joebordes
06-27-2024, 08:32 AM
» Replies: 1
» Views: 1,696
RESTRICTED FILE
Forum: Administrator Support
Last Post: inspectorflint
06-22-2024, 08:08 AM
» Replies: 7
» Views: 5,653
GENDOC imágenes
Forum: Open Discussions
Last Post: joebordes
06-02-2024, 05:11 PM
» Replies: 4
» Views: 2,018

 
  I don't understand the 'getFieldNames()' function in the workflow tasks
Posted by: Guido1982 - 11-24-2015, 09:44 PM - Forum: coreBOS Development - Replies (2)

I've been studying the workflow task in the development wiki, and the suggested github commit on adding tags, but I don't understand the 'getFieldNames' method. It simply returns an array (are the values database columns in the tasks table?), and later on they get cheched on as if they were class attributes. Is this some magic function in the system that checks if a particular entry in the database is there or something? Something that is automatically invoked when the workflow starts?

Print this item

  Where does the function 'getSalesEntityType' come from?
Posted by: Guido1982 - 11-24-2015, 08:59 PM - Forum: coreBOS Development - Replies (5)

I was studying this example from the documentation, and noticed this function called 'getSalesEntityType' that checks the entitytype on the id pulled in from the 'data' object. Since no files were included in this function file, I can't see how where this function comes from, although I can understand what it does from the name, I'd rather have a better understanding so I know what I'm doing when writing my own workflow methods. Can anyone explain?

Print this item

  For anyone looking for development tips
Posted by: Guido1982 - 11-24-2015, 08:39 PM - Forum: coreBOS - No Replies

Maybe you ended up here on the forum via Google or whatever, a good place to start is: http://corebos.org/documentation/ if you are looking for general instruction on classes, methods and vtlib.

Print this item

  Empezando con triggers o workflows
Posted by: unaitwo - 11-24-2015, 04:51 PM - Forum: Spanish - Replies (6)

Hola estoy intentado crear un sistema que tras que el usuario introduzca una entidad esta dispare la creación de otra usando valores de la primera, a modo de ejemplo, al introducir un prepuesto, en el calendario se programe automáticamente una llamada, usando los valores del presupuesto, como pueda ser el contacto y la fecha. Por donde tengo que empezar para programar un comportamiento como este???

Print this item

  jqueryversion on github
Posted by: saidmsl - 11-23-2015, 04:25 AM - Forum: coreBOS - Replies (7)

Hi,

while surfing on github project, i notice there is a branch jqueryversion

what i understand is that it remove all scriptaculous and prototype librairies and clean the javscript librairies

do you plan to merge it to master branch? 

when could  it be usable?

Rgds

Print this item

  A simple way to check if all sales orders are invoiced
Posted by: Guido1982 - 11-18-2015, 02:41 PM - Forum: Modules/Extension Support - Replies (6)

I wrote a small file that does only one simple thing: Check if the sum of all invoices related to a sales order is at least equal to the sales order total. I other words, you can check if you didn't forget to create invoices. It creates a very simple table. Take this code and place it in a NEW file called SO_Invoiced.php, in the modules/SalesOrder folder:

PHP Code:
<?php

// error_reporting(E_ALL);
// ini_set("display_errors", "on");

include_once('vtlib/Vtiger/Module.php');
global 
$adb;

// Set a new date object for the first of the year
$firstofyear = new DateTime();
// Set a new date object for the last of the year
// $lastofyear = new DateTime();
// Get the current year
$currentYear Date("Y");
// Get the first day of the current year
$firstofyear $firstofyear->modify("first day of january".$currentYear);
// Get the last day of the current year
// $lastofyear = $lastofyear->modify("last day of december".$currentYear);
// Format the firstofyear to match database formatting
$firstofyear $firstofyear->format('Y-m-d G:i:s');

// Create the master array
$SOArray = array();

// Get all the sales orders for the timeframe from the 'crmentity' table
$SOresult $adb->pquery('SELECT crmid, createdtime FROM vtiger_crmentity WHERE setype=? AND deleted=? AND createdtime > ?',array("SalesOrder",0,$firstofyear));

while(
$SalesOrderEntity=$adb->fetch_array($SOresult)) {
 
// Get the salesorders from the actual salesorders table
 
$SalesOrders $adb->pquery('SELECT salesorderid, subject, salesorder_no, total, accountid, sostatus FROM vtiger_salesorder WHERE salesorderid=?',array($SalesOrderEntity[crmid]));
 
// Loop these
 
while($SO=$adb->fetch_array($SalesOrders)) {
 
// Create array for this sales orders
 
$SalesOrder = array();
 
// Create empty slot for invoices
 
$SalesOrder["Invoices"] = array();
 
// Fill it with the order info
 
$SODate = new DateTime($SalesOrderEntity[createdtime]);
 
$SalesOrder["createdtime"] = $SODate->format('d-m-Y');
 
$SalesOrder["crmid"] = $SO[salesorderid];
 
$SalesOrder["SO_number"] = $SO[salesorder_no];
 
$SalesOrder["subject"] = $SO[subject];
 
$SalesOrder["total"] = $SO[total];
 
$SalesOrder["sostatus"] = $SO[sostatus];
 
// Get the associated account
 
$SOAccountResult $adb->pquery('SELECT accountname FROM vtiger_account WHERE accountid=?',array($SO[accountid]));
 
$SOAccount $adb->query_result_rowdata($SOAccountResult);
 
// Place it in the SalesOrder array
 
$SalesOrder["Accountname"] = $SOAccount[accountname];
 
$SOArray[$SO[salesorder_no]] = $SalesOrder;
 }
}

// Now loop the SOArray and look up all invoices for each Sales Order
foreach($SOArray as $ThisSO){
 
// Create an array for invoices
 
$Invoices = array();
 
// Search the database for Invoices
 
$InvoiceResult $adb->pquery('SELECT subject, invoicedate, total, invoice_no, invoicestatus FROM vtiger_invoice WHERE salesorderid=?',array($ThisSO["crmid"]));
 while (
$Invoice=$adb->fetch_array($InvoiceResult)) {
 
$ThisInvoice = array();
 
$ThisInvoice["subject"] = $Invoice["subject"];
 
$Invoicedate = new DateTime($Invoice["invoicedate"]);
 
$ThisInvoice["invoicedate"] = $Invoicedate->format('d-m-Y');
 
$ThisInvoice["total"] = $Invoice["total"];
 
$ThisInvoice["invoice_no"] = $Invoice["invoice_no"];
 
$ThisInvoice["status"] = $Invoice["invoicestatus"];
 
$Invoices[] = $ThisInvoice;
 }
 
// Append all found invoices to the master array
 
$SOArray[$ThisSO[SO_number]]["Invoices"] = $Invoices;
}

echo 
"<table cellpadding='5' border='1' style='width: 80%; margin-left: 10%; border-collapse: collapse'><tbody><tr><td>Orderno:<br>(Except cancelled)</td><td>SO subject line:</td><td>SO date</td><td>Klant</td><td>SO total incl. VAT</td><td>Sum of all invoices <br>(excluding invoices with negative amount)</td><td>Difference</td></tr>";
// Loop through the SO's

foreach ($SOArray as $SO) {
    // Loop through the invoices for this SO
    foreach ($SO["Invoices"] as $Invoice) {
        // Add each invoice amount to the last, creating a sum, but only if the invoice was not a credit invoice
        if ($Invoice["total"] > 0) {
            $Invoiceamount += $Invoice["total"];
        }
    }
    // Now create a line for each SO that was not fully invoiced
    if ($SO["total"] > $Invoiceamount && $SO["sostatus"] != "Cancelled") {
        echo "<tr>";
        echo "<td><a href='/index.php?module=SalesOrder&parenttab=Sales&action=DetailView&record=".$SO["crmid"]."' target='_blank'>".$SO["SO_number"]."</a></td><td>".$SO["subject"]."</td><td>".$SO["createdtime"]."</td><td>".$SO["Accountname"]."</td><td> &euro; ".number_format($SO["total"], 2',''.')."</td><td> &euro; ".number_format($Invoiceamount2',''.')."</td><td>&euro; ".number_format(($SO["total"] - $Invoiceamount), 2',''.')."</td>";
        echo "</tr>";
        // Create a sum of ALL SO amounts by adding the current
        // Total to the last ones
        $totallySold += $SO["total"];
        // This value is not reset at the end of the loop and so is a total of all invoiced amount in the table
        $totallyInvoiced += $Invoiceamount;
    }
    // Reset the sum to zero for the next SO
    $Invoiceamount 0;
}
echo 
"</tbody></table>";

echo 
"Total Amount of SO's:<b>&euro; ".number_format($totallySold2',''.')."</b><br>";
echo 
"Total Amount of Invoices:<b>&euro; ".number_format($totallyInvoiced2',''.')."</b><br>";
echo 
"Difference:<b>&euro; ".number_format(($totallySold $totallyInvoiced), 2',''.')."</b><br><br><br><br><br><br>";

?>

No point your browser to
Code:
http://{your-crm-url}/index.php?module=SalesOrder&action=SalesOrderAjax&file=SO_Invoiced

If you used a different filename, change the last part of the URL (after 'file=') to your file name.

Print this item

  Calendar location field automatically links to google maps
Posted by: Guido1982 - 11-17-2015, 05:53 PM - Forum: Administrator Support - No Replies

I have altered the function 'transferForAddIntoTitle' in the CalendarUtils.php file a little:

PHP Code:
function transferForAddIntoTitle($type$row$CD) {
 if (
$CD["uitype"] == "66"
 
$Col_Field = array($CD["fieldname"]=> $row["parent_id"]);
 else
 
$Col_Field = array($CD["fieldname"]=> $row[$CD["columnname"]]);

 if (
$CD["fieldname"] == "duration_hours"
 
$Col_Field["duration_minutes"] = $row["duration_minutes"];

 if (
$CD["fieldname"] == "contact_id") {
 
$Col_Field["contact_id"] = getAssignedContactsForEvent($row["crmid"]);
 
$CD["uitype"] = "1"  
 
}
 
$Cal_Data getDetailViewOutputHtml($CD["uitype"], $CD["fieldname"], $CD["fieldlabel"], $Col_Field"2"$calendar_tabid"Calendar");

 if (
$CD["uitype"] == "15")
 
$value getTranslatedString($Cal_Data[1],'Calendar');
 else
 
$value $Cal_Data[1];
 if (
$CD["fieldname"] == "location" {
 
$value "<a href='https://www.google.nl/maps/place/".$row['location']."' target='_blank'>".$row['location']."</a>";
 }
 if (
$type == "1")
 return 
$Cal_Data[1];
 else
 return 
'<br><b>'.$Cal_Data[0].'</b>: <span onmouseover="vtlib_listview.trigger(\'cell.onmouseover\', $(this))" onmouseout="vtlib_listview.trigger(\'cell.onmouseout\', $(this))">'.$value.'</span>';
 
// return '<table><tr><th>'.$Cal_Data[0].':</th><td onmouseover="vtlib_listview.trigger(\'cell.onmouseover\', $(this))" onmouseout="vtlib_listview.trigger(\'cell.onmouseout\', $(this))">'.$value.'</td></tr></table>';


Now, when you add a location the event will automatically create a link to google maps with that address or location pre-filled out.

If you adopt my account-selection autocomplete, the address for the appointment will automatically fill the location. To do so, change the 'select' in the autocomplete call to:

PHP Code:
         select: function( eventui) {
             
 // Add crmentity id to hidden input
             
 jQuery('input[name=parent_id]').attr('value',ui.item.value);
             
 // Also update the activity name with the activity type and account name
             
 jQuery('input[name=subject]').val(jQuery('#activitytype option:selected').text() + " " ui.item.label);
             
 // Overwrite the input field with the account name in stead of the crmentity
             
 jQuery('#account_autocomplete').val(ui.item.label);
             
 // Update the address automatically
             
 jQuery('input[name=location]').val(ui.item.street " " ui.item.city);
             
 return false;
         
 }, 

Print this item

  Adding a related sales order to the calendar event
Posted by: Guido1982 - 11-17-2015, 11:37 AM - Forum: Administrator Support - Replies (10)

I am in the process of relating activities directly to sales orders. I created a table that relates them and made a query in 'SaveEvent.php' that saves it, so far so good. Now I want every event to show that sales order as other related modules do. I saw that the Events.php file creates a JSON of all events, that I guess the 'fullcalendar.js' file uses to build the calendar. But now for the moment I am stumped on how to implement my query here and use it in the calendar. I think I should also edit 'CalendarView.tpl' (the jQuery to be exact), so that the JSON is expanded and the jQuery call uses this to build the calendar items. Does anyone have more detailled info?

Print this item

  vTiger developer handbook
Posted by: Guido1982 - 11-16-2015, 05:03 PM - Forum: Administrator Support - Replies (1)

In my search for a better understanding of vTigerm I found this PDF. Now this is a vTiger PDF, that is not extremely recent. Still, if you're starting with CoreBOS development (like me), I think you'll find some nice basic structures about the application in here. Just thought I'd share it in case anyone else is looking for something like this.



Attached Files
.pdf   vtiger5.x-developer-manual.pdf (Size: 446.24 KB / Downloads: 7)
Print this item

  Autocomplete in the Calendar UI
Posted by: Guido1982 - 11-16-2015, 03:49 PM - Forum: Administrator Support - Replies (9)

Okay, so I've done some quick 'n dirty work on the 'Add Event' UI in the calendar. I've edited the 'addEventUI.php' file as follows:

PHP Code:
    <!-- Dynamically add jQuery UI from a CDN -->
    <
script type="text/javascript">
    var 
script document.createElement("script");
    
script.type "text/javascript";
    
script.src "https://code.jquery.com/ui/1.11.4/jquery-ui.min.js";
    var 
uiCSS document.createElement("link");
    
uiCSS.type "text/css";
    
uiCSS.rel "stylesheet";
    
uiCSS.href "https://code.jquery.com/ui/1.11.4/themes/cupertino/jquery-ui.css";
    
document.head.appendChild(script);
    
document.head.appendChild(uiCSS);
    </
script>
    <!-- 
End include of jQuery UI -->
    <!-- 
Autocomplete jQuery -->
  <
script>
  
jQuery(window).load(function(){
        
jQuery"#account_autocomplete" ).autocomplete({
        
// Beware: Autocomplete sets a search term as GET parameter to the URL
        // The php file has to take this into account and use the search term
        // in its mySQL query
          
source"JSON_Accounts.php",
        
// On open we have to set a high z-index to the UL, else it will
        // fall behind the 'addEvent' UI box
          
open: function(){
            
jQuery(this).autocomplete('widget').css('z-index'999999);
            return 
false;
          },
          
// Here we add the result on selection to a hidden input field
          // That the calendar module uses to connect a crmentity
          
select: function( eventui) {
              
// Add crmentity id to hidden input
              
jQuery('input[name=parent_id]').attr('value',ui.item.value);
              
// Also update the activity name with the activity type and account name
              
jQuery('input[name=subject]').val(jQuery('#activitytype option:selected').text() + " " ui.item.label);
              
// Overwrite the input field with the account name in stead of the crmentity
              
jQuery('#account_autocomplete').val(ui.item.label);
              return 
false;
          },
          
// Also update the input field with the label during focus
          
focus: function( eventui ) {
              
// Overwrite the input field with the account name in stead of the crmentity
              
jQuery('#account_autocomplete').val(ui.item.label);
              return 
false;
          },
          
minLength2
        
// Make sure 'autocomplete' is turned on for this field
        
}).attr("autocomplete","on")
        
// Add '_renderItem' to use HTML in the results, so we can use
        // things like address fields and better readable markup
        
.autocomplete"instance" )._renderItem = function( ulitem ) {
          return 
jQuery"<li>" )
            .
append"<a>" "<b>" item.label "</b>" "<br>" item.street "<br>" item.code " " item.city "</a>" )
            .
appendToul );
        };
    });
  </
script>
    <!-- 
End autocomplete --> 

Added to include jQuery UI and the cupertino theme (which is what the calendar uses), and I added:

PHP Code:
            <tr>
                <
td nowrap align="right"><b>Account</b></td>
                <
td align="left"><input name="account_autocomplete" type="text" id="account_autocomplete" value="" style="width:50%;"></td>
            </
tr

To add the field I use for autocomplete. The JSON file for accounts looks like this:

PHP Code:
<?php

// error_reporting(E_ALL);
// ini_set("display_errors", "on");

    
include_once('vtlib/Vtiger/Module.php');
    global 
$adb;
    
    
// Lines 11-24 from http://www.wowww.nl/2014/02/01/jquery-autocomplete-tutorial-php-mysql/
    /* prevent direct access to this page */
    
$isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND
    
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
    if(!
$isAjax) {
      
$user_error 'Access denied - direct call is not allowed...';
      
trigger_error($user_errorE_USER_ERROR);
    }
    
ini_set('display_errors',1);
     
    
/* if the 'term' variable is not sent with the request, exit */
    
if ( !isset($_REQUEST['term']) ) {
        exit;
    }
    
    
// Start the empty 'allaccounts' array
    
$allaccounts = array();
    
    
// Get the term from the jQuery autocomplete GET request
    
$term trim(strip_tags($_GET['term'])); 
    
    
// Get the accounts that match part of the search term
    
$accountresults $adb->query("SELECT accountid, account_no, accountname FROM vtiger_account WHERE accountname LIKE '%$term%'");

    
// Loop accounts
    
while($account=$adb->fetch_array($accountresults)) {
        
        
// Create empty JSON array for this account
        
$JsonAccount = array();
        
        
// 'vtiger_account' table has no address data, so another query for the table that has those,
        // for the current account (in the array parameter)
        
$accountaddressres $adb->pquery("SELECT accountaddressid, ship_code, ship_street, ship_city FROM vtiger_accountshipads WHERE accountaddressid=?", array($account[accountid]));
        
        
// Loop the shipping address resultset
        
while ($address=$adb->fetch_array($accountaddressres)) {
            
// Add the account name and address as the JSON label
            
$JsonAccount['label'] = $account[accountname];
            
$JsonAccount['value'] = $account[accountid];
            
$JsonAccount['code'] = $address[ship_code];
            
$JsonAccount['street'] = $address[ship_street];
            
$JsonAccount['city'] = $address[ship_city];
        }
        
        
// Push the current account with address info to the 'allaccounts' array
        
$allaccounts[] = $JsonAccount;
    }
    
    
// echo "<pre>";
    // print_r($allaccounts);
    // echo "</pre>";
    
    
echo json_encode($allaccountsJSON_HEX_APOS JSON_HEX_QUOT JSON_HEX_AMP JSON_UNESCAPED_UNICODE);

?>

Obviously this gets the job done, but is not the most elegant solution. My main problems now are:
  • How to get the label for the input autocomplete field to take the system variable for the 'Accounts' module. I do want to use this like this and not use the standard 'related to' because I feel this requires too many clicks. I intend to re-design the entire "Add Event" UI in the future to increase workflow speed and use more keyboard input.
  • I have to place the JSON_Accounts.php file in the root, because I can't include the 'Module.php' file otherwise. Joe suggested that other module files could use this becuase they use the 'set_include_path()' function, but I don't see that function being used in the standard module files. My guess is that the other files can use includes as if they were files in the root because they get passed through the index.php root file. My file is not registered by the system and so does not pass through the index.php file. Sadly, I don't know how to change this so any help would be appreciated.
  • I'm thinking the Calendar module already uses a 'jQuery UI' include (haven't done the full research on this), so maybe the double include could be deleted?
  • Probably the javascript could be moved to a separate file and included in the 'AddEventUI.php' file to make the code less messy.
  • In the future, I'd like to offer the possibility to connect an event to both an Account as well as a Sales Order. I think this will require a new column in the database and some code that saves this when the event is saved. If anyone has some pointers on this, help is appreciated.

Print this item