Welcome, Guest |
You have to register before you can post on our site.
|
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?
|
|
|
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?
|
|
|
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???
|
|
|
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
|
|
|
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> € ".number_format($SO["total"], 2, ',', '.')."</td><td> € ".number_format($Invoiceamount, 2, ',', '.')."</td><td>€ ".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>€ ".number_format($totallySold, 2, ',', '.')."</b><br>"; echo "Total Amount of Invoices:<b>€ ".number_format($totallyInvoiced, 2, ',', '.')."</b><br>"; echo "Difference:<b>€ ".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.
|
|
|
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( event, ui) { // 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; },
|
|
|
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?
|
|
|
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( event, ui) { // 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( event, ui ) { // Overwrite the input field with the account name in stead of the crmentity jQuery('#account_autocomplete').val(ui.item.label); return false; }, minLength: 2 // 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( ul, item ) { return jQuery( "<li>" ) .append( "<a>" + "<b>" + item.label + "</b>" + "<br>" + item.street + "<br>" + item.code + " " + item.city + "</a>" ) .appendTo( ul ); }; }); </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_error, E_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($allaccounts, JSON_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.
|
|
|
|