Conflicts
This commit is contained in:
14
app/Jobs/GenerateReportTable.php
Normal file
14
app/Jobs/GenerateReportTable.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
class GenerateReportTable extends QueuedClosure
|
||||
{
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 1;
|
||||
|
||||
}
|
||||
@@ -6,9 +6,37 @@ use ProcessMaker\Model\ProcessVariables;
|
||||
$factory->define(ProcessVariables::class, function (Faker $faker) {
|
||||
return [
|
||||
'VAR_UID' => G::generateUniqueID(),
|
||||
'PRO_ID' => G::generateUniqueID(),
|
||||
'PRJ_UID' => G::generateUniqueID(),
|
||||
'VAR_NAME' => $faker->word,
|
||||
'VAR_FIELD_TYPE' => G::generateUniqueID(),
|
||||
'VAR_FIELD_TYPE_ID' => G::generateUniqueID(),
|
||||
'VAR_FIELD_SIZE' => 10,
|
||||
'VAR_LABEL' => 'string',
|
||||
'VAR_DBCONNECTION' => 'workflow',
|
||||
'VAR_SQL' => '',
|
||||
'VAR_NULL' => 0,
|
||||
'VAR_DEFAULT' => '',
|
||||
'VAR_ACCEPTED_VALUES' => '[]',
|
||||
'INP_DOC_UID' => ''
|
||||
];
|
||||
});
|
||||
|
||||
// Create a processVariables with the foreign keys
|
||||
$factory->state(ProcessVariables::class, 'foreign_keys', function (Faker $faker) {
|
||||
$types = ['string', 'integer', 'float', 'boolean', 'datetime', 'grid', 'array', 'file', 'multiplefile', 'object'];
|
||||
$varType = $faker->randomElement($types);
|
||||
$varTypeId = array_search($varType, $types) + 1;
|
||||
// Create values in the foreign key relations
|
||||
$process = factory(\ProcessMaker\Model\Process::class)->create();
|
||||
|
||||
return [
|
||||
'VAR_UID' => G::generateUniqueID(),
|
||||
'PRO_ID' => $process->PRO_ID,
|
||||
'PRJ_UID' => $process->PRO_UID,
|
||||
'VAR_NAME' => $faker->word,
|
||||
'VAR_FIELD_TYPE' => $varType,
|
||||
'VAR_FIELD_TYPE_ID' => $varTypeId,
|
||||
'VAR_FIELD_SIZE' => 10,
|
||||
'VAR_LABEL' => 'string',
|
||||
'VAR_DBCONNECTION' => 'workflow',
|
||||
|
||||
@@ -90,6 +90,10 @@
|
||||
var evaluateFunctionFunction = [evaluateFunction+"($gridName,$Expression)"];
|
||||
arrayFunctions[evaluateFunction] = evaluateFunctionFunction;
|
||||
|
||||
var PMFTotalCalculation = "PMFTotalCalculation";
|
||||
var PMFTotalCalculationFunction = [PMFTotalCalculation + "($gridName, $field, 'function')"];
|
||||
arrayFunctions[PMFTotalCalculation] = PMFTotalCalculationFunction;
|
||||
|
||||
var PMFTaskCase = "PMFTaskCase";
|
||||
var PMFTaskCaseFunction = [PMFTaskCase+"($caseId)"];
|
||||
arrayFunctions[PMFTaskCase] = PMFTaskCaseFunction;
|
||||
@@ -219,7 +223,7 @@
|
||||
arrayFunctions[PMFGetCaseNotes] = PMFGetCaseNotesFunction;
|
||||
|
||||
var phpPMFunctions = [formatDate,getCurrentDate,getCurrentTime,literalDate,capitalize,lowerCase,upperCase,userInfo,executeQuery,orderGrid,
|
||||
evaluateFunction,PMFTaskCase,PMFTaskList,PMFUserList,PMFGroupList,PMFRoleList,PMFCaseList,PMFProcessList,PMFSendVariables,PMFDerivateCase,
|
||||
evaluateFunction, PMFTotalCalculation, PMFTaskCase,PMFTaskList,PMFUserList,PMFGroupList,PMFRoleList,PMFCaseList,PMFProcessList,PMFSendVariables,PMFDerivateCase,
|
||||
PMFNewCaseImpersonate,PMFNewCase,PMFPauseCase,PMFUnpauseCase,PMFAssignUserToGroup,PMFCreateUser,PMFUpdateUser,PMFInformationUser,
|
||||
generateCode,setCaseTrackerCode,jumping,PMFRedirectToStep,pauseCase,PMFSendMessage,PMFgetLabelOption,PMFGenerateOutputDocument,
|
||||
PMFGetUserEmailAddress,PMFGetNextAssignedUser,PMFDeleteCase,PMFCancelCase,PMFAddInputDocument,PMFAddCaseNote,PMFGetCaseNotes];
|
||||
|
||||
1666
tests/resources/dynaform1.json
Normal file
1666
tests/resources/dynaform1.json
Normal file
File diff suppressed because it is too large
Load Diff
33
tests/resources/structureReportTable.json
Normal file
33
tests/resources/structureReportTable.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"data": {
|
||||
"var_Text1": "5298067855ed6e6893e1424067710552",
|
||||
"var_Textarea1": "4835809915ed6e6893e14a6079656976",
|
||||
"var_Dropdown1": "5287566085ed6e6893e14e0083475368",
|
||||
"var_Suggest1": "4813021735ed6e6893e1520081779769",
|
||||
"var_DateTime1": "1975-04-04 16:34:22",
|
||||
"var_String1": "7984290665ed6e6893e15b2092042769",
|
||||
"var_Integer1": "44"
|
||||
},
|
||||
"mapping": [{
|
||||
"sFieldName": "var_Text1",
|
||||
"sType": "char"
|
||||
}, {
|
||||
"sFieldName": "var_Textarea1",
|
||||
"sType": "text"
|
||||
}, {
|
||||
"sFieldName": "var_Dropdown1",
|
||||
"sType": "char"
|
||||
}, {
|
||||
"sFieldName": "var_Suggest1",
|
||||
"sType": "char"
|
||||
}, {
|
||||
"sFieldName": "var_DateTime1",
|
||||
"sType": "date"
|
||||
}, {
|
||||
"sFieldName": "var_String1",
|
||||
"sType": "char"
|
||||
}, {
|
||||
"sFieldName": "var_Integer1",
|
||||
"sType": "number"
|
||||
}]
|
||||
}
|
||||
@@ -984,6 +984,64 @@ class PmDynaformTest extends TestCase
|
||||
// Compare the values
|
||||
$this->assertEquals($dynaformTitle, $dynaform->DYN_TITLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This test should verify the setDependentOptionsForDatetime() method, to
|
||||
* add the dependentOptions property to the datetime control.
|
||||
* @test
|
||||
* @covers PmDynaform::jsonr()
|
||||
* @covers PmDynaform::setDependentOptionsForDatetime()
|
||||
*/
|
||||
public function it_should_test_dependent_options_for_datetime_control()
|
||||
{
|
||||
$pathData = PATH_TRUNK . "/tests/resources/dynaform1.json";
|
||||
$data = file_get_contents($pathData);
|
||||
$json = json_decode($data);
|
||||
|
||||
//assert for not contain property: dependentOptions
|
||||
$result = json_decode(json_encode($json), JSON_OBJECT_AS_ARRAY);
|
||||
$fn = function($item) use(&$fn) {
|
||||
if (is_array($item)) {
|
||||
if (isset($item['type']) && $item['type'] === 'datetime') {
|
||||
$this->assertArrayNotHasKey('dependentOptions', $item);
|
||||
}
|
||||
array_map($fn, $item);
|
||||
}
|
||||
};
|
||||
array_map($fn, $result);
|
||||
|
||||
//assert new property: dependentOptions
|
||||
$dynaform = new PmDynaform();
|
||||
$dynaform->jsonr($json);
|
||||
$result = json_decode(json_encode($json), JSON_OBJECT_AS_ARRAY);
|
||||
|
||||
$fn = function($item) use(&$fn) {
|
||||
if (is_array($item)) {
|
||||
if (isset($item['type']) && $item['type'] === 'datetime') {
|
||||
$this->assertArrayHasKey('dependentOptions', $item);
|
||||
$this->assertArrayHasKey('minDate', $item['dependentOptions']);
|
||||
$this->assertArrayHasKey('maxDate', $item['dependentOptions']);
|
||||
$this->assertArrayHasKey('defaultDate', $item['dependentOptions']);
|
||||
}
|
||||
array_map($fn, $item);
|
||||
}
|
||||
};
|
||||
array_map($fn, $result);
|
||||
|
||||
$dynaform = new PmDynaform();
|
||||
$reflection = new ReflectionClass($dynaform);
|
||||
$reflectionMethod = $reflection->getMethod('setDependentOptionsForDatetime');
|
||||
$reflectionMethod->setAccessible(true);
|
||||
|
||||
$a = new stdClass();
|
||||
$reflectionMethod->invokeArgs($dynaform, [&$a]);
|
||||
$this->assertInstanceOf('ReflectionMethod', $reflectionMethod);
|
||||
|
||||
$a = new stdClass();
|
||||
$a->type = 'suggest';
|
||||
$reflectionMethod->invokeArgs($dynaform, [&$a]);
|
||||
$this->assertInstanceOf('ReflectionMethod', $reflectionMethod);
|
||||
}
|
||||
}
|
||||
|
||||
// Dummy function used for the coverture
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\unit\workflow\engine\classes\PmFunctions;
|
||||
|
||||
use Faker\Factory;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* Test the PMFTotalCalculation() function
|
||||
*
|
||||
* @link https://wiki.processmaker.com/3.1/ProcessMaker_Functions#executeQuery.28.29
|
||||
*/
|
||||
class PMFTotalCalculationTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the sum
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_sum_of_the_method()
|
||||
{
|
||||
$grid = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 2
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 5
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 3
|
||||
]
|
||||
];
|
||||
$field = "field2";
|
||||
$this->assertEquals(10, PMFTotalCalculation($grid, $field, 'sum'));
|
||||
}
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the average
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_average_of_the_method()
|
||||
{
|
||||
$grid = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 2
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 5
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 3
|
||||
]
|
||||
];
|
||||
$this->assertEquals(3.3333333333, PMFTotalCalculation($grid, 'field2', 'average'));
|
||||
}
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the median
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_median_of_the_method()
|
||||
{
|
||||
$grid1 = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 2
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 5
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 3
|
||||
]
|
||||
];
|
||||
$grid2 = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 2
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 5
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 3
|
||||
],
|
||||
'4' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 8
|
||||
]
|
||||
];
|
||||
$this->assertEquals(3, PMFTotalCalculation($grid1, 'field2', 'median'));
|
||||
$this->assertEquals(4, PMFTotalCalculation($grid2, 'field2', 'median'));
|
||||
}
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the minimum
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_minimum_of_the_method()
|
||||
{
|
||||
$grid = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 5
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 2
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 3
|
||||
]
|
||||
];
|
||||
$this->assertEquals(2, PMFTotalCalculation($grid, 'field2', 'minimum'));
|
||||
}
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the maximum
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_maximum_of_the_method()
|
||||
{
|
||||
$grid = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 2
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 5
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 3
|
||||
]
|
||||
];
|
||||
$this->assertEquals(5, PMFTotalCalculation($grid, 'field2', 'maximum'));
|
||||
}
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the standardDeviation
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_standardDeviation_of_the_method()
|
||||
{
|
||||
$grid = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 25
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 40
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 10
|
||||
]
|
||||
];
|
||||
$this->assertEquals(12.2474487139, PMFTotalCalculation($grid, 'field2', 'standardDeviation'));
|
||||
}
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the variance
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_variance_of_the_method()
|
||||
{
|
||||
$grid = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 25
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 40
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 10
|
||||
]
|
||||
];
|
||||
$this->assertEquals(150, PMFTotalCalculation($grid, 'field2', 'variance'));
|
||||
}
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the percentile
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_percentile_of_the_method()
|
||||
{
|
||||
$grid = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 10
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 35
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 5
|
||||
]
|
||||
];
|
||||
$expectedArray = [
|
||||
"1" => 20,
|
||||
"2" => 70,
|
||||
"3" => 10,
|
||||
];
|
||||
$this->assertEquals($expectedArray, PMFTotalCalculation($grid, 'field2', 'percentile'));
|
||||
}
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the count
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_count_of_the_method()
|
||||
{
|
||||
$grid = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 25
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 40
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 10
|
||||
]
|
||||
];
|
||||
$this->assertEquals(3, PMFTotalCalculation($grid, 'field2', 'count'));
|
||||
}
|
||||
/**
|
||||
* This tests if the "PMFTotalCalculation" execute correctly the count distinct
|
||||
* @test
|
||||
*/
|
||||
public function it_must_return_the_count_distinct_of_the_method()
|
||||
{
|
||||
$grid = [
|
||||
'1' => [
|
||||
"field1" => "Value 1",
|
||||
"field2" => 20
|
||||
],
|
||||
'2' => [
|
||||
"field1" => "Value 2",
|
||||
"field2" => 20
|
||||
],
|
||||
'3' => [
|
||||
"field1" => "Value 3",
|
||||
"field2" => 10
|
||||
]
|
||||
];
|
||||
$this->assertEquals(2, PMFTotalCalculation($grid, 'field2', 'countDistinct'));
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ use Tests\TestCase;
|
||||
|
||||
class ReportTablesTest extends TestCase
|
||||
{
|
||||
|
||||
use CreateTestSite;
|
||||
use DatabaseTransactions;
|
||||
|
||||
@@ -21,14 +22,12 @@ class ReportTablesTest extends TestCase
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->markTestIncomplete(""
|
||||
. "This test has started using the ./processmaker command, this "
|
||||
. "command requires the file 'paths_installed.php', that is, a "
|
||||
. "valid installation of processmaker.");
|
||||
$_SERVER["REQUEST_URI"] = "";
|
||||
config(['queue.default' => 'sync']);
|
||||
config(["system.workspace" => "test"]);
|
||||
$workspace = config("system.workspace");
|
||||
$this->createDBFile($workspace);
|
||||
$this->createConstantsOfConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,6 +38,33 @@ class ReportTablesTest extends TestCase
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create constants of connection to databases.
|
||||
*/
|
||||
private function createConstantsOfConnection()
|
||||
{
|
||||
$constants = [
|
||||
'DB_ADAPTER' => env('mysql'),
|
||||
'DB_HOST' => env('DB_HOST'),
|
||||
'DB_NAME' => env('DB_DATABASE'),
|
||||
'DB_USER' => env('DB_USERNAME'),
|
||||
'DB_PASS' => env('DB_PASSWORD'),
|
||||
'DB_RBAC_HOST' => env('DB_HOST'),
|
||||
'DB_RBAC_NAME' => env('DB_DATABASE'),
|
||||
'DB_RBAC_USER' => env('DB_USERNAME'),
|
||||
'DB_RBAC_PASS' => env('DB_PASSWORD'),
|
||||
'DB_REPORT_HOST' => env('DB_HOST'),
|
||||
'DB_REPORT_NAME' => env('DB_DATABASE'),
|
||||
'DB_REPORT_USER' => env('DB_USERNAME'),
|
||||
'DB_REPORT_PASS' => env('DB_PASSWORD'),
|
||||
];
|
||||
foreach ($constants as $key => $value) {
|
||||
if (!defined($key)) {
|
||||
define($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the "populateTable" function returns an array value if entered all parameters.
|
||||
* @test
|
||||
@@ -565,97 +591,6 @@ class ReportTablesTest extends TestCase
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapping fields supported by report table.
|
||||
* @return array
|
||||
*/
|
||||
private function getMapFields()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'sFieldName' => 'var_Text1',
|
||||
'sType' => 'char'
|
||||
],
|
||||
[
|
||||
'sFieldName' => 'var_Textarea1',
|
||||
'sType' => 'text'
|
||||
],
|
||||
[
|
||||
'sFieldName' => 'var_Dropdown1',
|
||||
'sType' => 'char'
|
||||
],
|
||||
[
|
||||
'sFieldName' => 'var_Suggest1',
|
||||
'sType' => 'char'
|
||||
],
|
||||
[
|
||||
'sFieldName' => 'var_DateTime1',
|
||||
'sType' => 'date'
|
||||
],
|
||||
[
|
||||
'sFieldName' => 'var_String1',
|
||||
'sType' => 'char'
|
||||
],
|
||||
[
|
||||
'sFieldName' => 'var_Integer1',
|
||||
'sType' => 'number'
|
||||
],
|
||||
[
|
||||
'sFieldName' => 'var_Boolean1',
|
||||
'sType' => 'boolean'
|
||||
],
|
||||
[
|
||||
'sFieldName' => 'var_Array1',
|
||||
'sType' => 'array'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create fields data by type supported.
|
||||
* @param array $types
|
||||
* @return array
|
||||
*/
|
||||
private function createFieldsByType($types = [])
|
||||
{
|
||||
$fields = [];
|
||||
$mapping = [];
|
||||
$faker = Faker\Factory::create();
|
||||
$date = $faker->dateTime();
|
||||
$mapFields = $this->getMapFields();
|
||||
foreach ($mapFields as $key => $value) {
|
||||
if (!in_array($value['sType'], $types)) {
|
||||
continue;
|
||||
}
|
||||
switch ($value['sType']) {
|
||||
case 'number':
|
||||
$mapping[] = $value;
|
||||
$fields[$value['sFieldName']] = (string) random_int(0, 100);
|
||||
break;
|
||||
case 'char':
|
||||
$mapping[] = $value;
|
||||
$fields[$value['sFieldName']] = G::generateUniqueID();
|
||||
break;
|
||||
case 'text':
|
||||
$mapping[] = $value;
|
||||
$fields[$value['sFieldName']] = G::generateUniqueID();
|
||||
break;
|
||||
case 'date':
|
||||
$mapping[] = $value;
|
||||
$fields[$value['sFieldName']] = $date->format('Y-m-d H:i:s');
|
||||
break;
|
||||
case 'boolean':
|
||||
$mapping[] = $value;
|
||||
$fields[$value['sFieldName']] = ['0' => 0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return [
|
||||
'data' => $fields,
|
||||
'mapping' => $mapping
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare data initial for test, the grid parameter is optional if you want
|
||||
* to create a grid type field.
|
||||
@@ -665,7 +600,7 @@ class ReportTablesTest extends TestCase
|
||||
* @param boolean $grid
|
||||
* @return object
|
||||
*/
|
||||
private function prepareData($tableName, $grid = null)
|
||||
private function prepareData($tableName, $grid = null, $structure = [])
|
||||
{
|
||||
$applicationNumber = Application::max('APP_NUMBER');
|
||||
if (is_null($applicationNumber)) {
|
||||
@@ -681,7 +616,10 @@ class ReportTablesTest extends TestCase
|
||||
$taskUid = G::generateUniqueID();
|
||||
$applicationUid = G::generateUniqueID();
|
||||
|
||||
$structure = $this->createFieldsByType(['number', 'char', 'text', 'date']);
|
||||
if (empty($structure)) {
|
||||
$structure = $this->getDataFromFile('structureReportTable.json');
|
||||
}
|
||||
|
||||
$fields = $structure['mapping'];
|
||||
$dataFields = $structure['data'];
|
||||
$appData = [
|
||||
@@ -753,4 +691,157 @@ class ReportTablesTest extends TestCase
|
||||
$result->application = $application;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the "populateTable" method is it filling with missing values into app_data.
|
||||
* @test
|
||||
* @covers ReportTables::populateTable
|
||||
*/
|
||||
public function it_should_populating_data_with_fields_missing_in_to_app_data()
|
||||
{
|
||||
$tableName = 'TestReportTable';
|
||||
$result = $this->prepareData($tableName);
|
||||
$connectionShortName = 'wf';
|
||||
$type = 'NORMAL';
|
||||
$fields = $result->fields;
|
||||
$proUid = $result->processUid;
|
||||
$grid = '';
|
||||
|
||||
$app = Application::where('APP_UID', '=', $result->applicationUid)->get()->first();
|
||||
$appData = unserialize($app->APP_DATA);
|
||||
unset($appData['var_Textarea1']);
|
||||
$appData = serialize($appData);
|
||||
Application::where('APP_UID', '=', $result->applicationUid)->update(['APP_DATA' => $appData]);
|
||||
|
||||
$reportTables = new ReportTables();
|
||||
$reportTables->populateTable($tableName, $connectionShortName, $type, $fields, $proUid, $grid);
|
||||
|
||||
$expected = $result->dataFields;
|
||||
$expected['APP_UID'] = $result->applicationUid;
|
||||
$expected['APP_NUMBER'] = $result->applicationNumber;
|
||||
$expected['var_Textarea1'] = '';
|
||||
|
||||
$actual = (array) DB::table($tableName)
|
||||
->select()
|
||||
->first();
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the "populateTable" method is it filling with arrays values.
|
||||
* @test
|
||||
* @covers ReportTables::populateTable
|
||||
*/
|
||||
public function it_should_populating_data_with_arrays_values()
|
||||
{
|
||||
$tableName = 'TestReportTable';
|
||||
$result = $this->prepareData($tableName);
|
||||
$connectionShortName = 'wf';
|
||||
$type = 'NORMAL';
|
||||
$fields = $result->fields;
|
||||
$proUid = $result->processUid;
|
||||
$grid = '';
|
||||
|
||||
$app = Application::where('APP_UID', '=', $result->applicationUid)->get()->first();
|
||||
$appData = unserialize($app->APP_DATA);
|
||||
$appData['var_Textarea1'] = [];
|
||||
$appData = serialize($appData);
|
||||
Application::where('APP_UID', '=', $result->applicationUid)->update(['APP_DATA' => $appData]);
|
||||
|
||||
$reportTables = new ReportTables();
|
||||
$reportTables->populateTable($tableName, $connectionShortName, $type, $fields, $proUid, $grid);
|
||||
|
||||
$expected = $result->dataFields;
|
||||
$expected['APP_UID'] = $result->applicationUid;
|
||||
$expected['APP_NUMBER'] = $result->applicationNumber;
|
||||
$expected['var_Textarea1'] = '';
|
||||
|
||||
$actual = (array) DB::table($tableName)
|
||||
->select()
|
||||
->first();
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the "populateTable" method is it filling with missing values into app_data for grids control.
|
||||
* parameters and type and grid are correct values.
|
||||
* @test
|
||||
* @covers ReportTables::populateTable
|
||||
*/
|
||||
public function it_should_populating_data_with_all_parameters_with_type_is_grid_fields_missing_in_to_app_data()
|
||||
{
|
||||
$tableName = 'TestReportTable';
|
||||
$result = $this->prepareData($tableName, true);
|
||||
$connectionShortName = 'wf';
|
||||
$type = 'GRID';
|
||||
$fields = $result->fields;
|
||||
$proUid = $result->processUid;
|
||||
$grid = 'var_Grid1';
|
||||
|
||||
$app = Application::where('APP_UID', '=', $result->applicationUid)->get()->first();
|
||||
$appData = unserialize($app->APP_DATA);
|
||||
unset($appData['var_Grid1'][1]['var_Textarea1']);
|
||||
$appData = serialize($appData);
|
||||
Application::where('APP_UID', '=', $result->applicationUid)->update(['APP_DATA' => $appData]);
|
||||
|
||||
$reportTables = new ReportTables();
|
||||
$reportTables->populateTable($tableName, $connectionShortName, $type, $fields, $proUid, $grid);
|
||||
|
||||
$indexRow = 1;
|
||||
$expected = $result->appData[$grid];
|
||||
foreach ($expected as &$row) {
|
||||
$row['APP_UID'] = $result->applicationUid;
|
||||
$row['APP_NUMBER'] = $result->applicationNumber;
|
||||
$row['ROW'] = (string) ($indexRow++);
|
||||
}
|
||||
$expected = array_values($expected);
|
||||
$expected[0]['var_Textarea1'] = '';
|
||||
|
||||
$actual = DB::table($tableName)
|
||||
->select()
|
||||
->get();
|
||||
$actual->transform(function ($item, $key) {
|
||||
return (array) $item;
|
||||
});
|
||||
$actual = $actual->toArray();
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check an exception if the input parameters are wrong.
|
||||
* @test
|
||||
* @covers ReportTables::populateTable
|
||||
*/
|
||||
public function it_should_catch_an_exception()
|
||||
{
|
||||
$tableName = 'TestReportTable';
|
||||
$result = $this->prepareData($tableName, true);
|
||||
$connectionShortName = 'wf';
|
||||
$type = 'GRID';
|
||||
$fields = $result->fields;
|
||||
$proUid = $result->processUid;
|
||||
$grid = 'var_Grid1';
|
||||
|
||||
//assert exception
|
||||
$this->expectException(Exception::class);
|
||||
|
||||
$reportTables = new ReportTables();
|
||||
$reportTables->populateTable($tableName, $connectionShortName, $type, null, $proUid, $grid);
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets data from a json file.
|
||||
* @param string $pathData
|
||||
* @return array
|
||||
*/
|
||||
private function getDataFromFile(string $pathData): array
|
||||
{
|
||||
$pathData = PATH_TRUNK . "tests/resources/{$pathData}";
|
||||
$data = file_get_contents($pathData);
|
||||
$result = json_decode($data, JSON_OBJECT_AS_ARRAY);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,32 @@
|
||||
namespace Tests\unit\workflow\engine\classes\model;
|
||||
|
||||
use AdditionalTables;
|
||||
use App\Jobs\GenerateReportTable;
|
||||
use Exception;
|
||||
use G;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use ProcessMaker\BusinessModel\ReportTable;
|
||||
use ProcessMaker\Model\AdditionalTables as AdditionalTablesModel;
|
||||
use ProcessMaker\Model\Application;
|
||||
use ProcessMaker\Model\DbSource;
|
||||
use ProcessMaker\Model\Delegation;
|
||||
use ProcessMaker\Model\Process;
|
||||
use ProcessMaker\Model\Task;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdditionalTablesTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Set up method.
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* This tests the creation of a PMTable.
|
||||
* @test
|
||||
@@ -198,6 +213,74 @@ class AdditionalTablesTest extends TestCase
|
||||
$this->assertContains($actual[0], $expected, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if populate report table is added to job queue.
|
||||
* @test
|
||||
* @covers \AdditionalTables::populateReportTable
|
||||
*/
|
||||
public function it_should_test_populate_report_table()
|
||||
{
|
||||
$proUid = factory(Process::class)->create()->PRO_UID;
|
||||
|
||||
$task = factory(Task::class)->create([
|
||||
'PRO_UID' => $proUid
|
||||
]);
|
||||
|
||||
//local connections
|
||||
$dbSource = factory(DbSource::class)->create([
|
||||
'PRO_UID' => $proUid,
|
||||
'DBS_SERVER' => env('DB_HOST'),
|
||||
'DBS_DATABASE_NAME' => env('DB_DATABASE'),
|
||||
'DBS_USERNAME' => env('DB_USERNAME'),
|
||||
'DBS_PASSWORD' => G::encrypt(env('DB_PASSWORD'), env('DB_DATABASE')) . "_2NnV3ujj3w",
|
||||
'DBS_PORT' => '3306',
|
||||
'DBS_CONNECTION_TYPE' => 'NORMAL'
|
||||
]);
|
||||
$additionalTable = factory(AdditionalTablesModel::class)->create([
|
||||
'PRO_UID' => $proUid,
|
||||
'DBS_UID' => $dbSource->DBS_UID,
|
||||
]);
|
||||
$tableName = $additionalTable->ADD_TAB_NAME;
|
||||
$name = $additionalTable->ADD_TAB_CLASS_NAME;
|
||||
$this->createSchema($dbSource->DBS_DATABASE_NAME, $tableName, $name, $dbSource->DBS_UID);
|
||||
|
||||
//external connection
|
||||
$dbSource = factory(DbSource::class)->create([
|
||||
'PRO_UID' => $proUid,
|
||||
'DBS_SERVER' => config('database.connections.testexternal.host'),
|
||||
'DBS_DATABASE_NAME' => config('database.connections.testexternal.database'),
|
||||
'DBS_USERNAME' => config('database.connections.testexternal.username'),
|
||||
'DBS_PASSWORD' => G::encrypt(config('database.connections.testexternal.password'), config('database.connections.testexternal.database')) . "_2NnV3ujj3w",
|
||||
'DBS_PORT' => '3306',
|
||||
'DBS_CONNECTION_TYPE' => 'NORMAL'
|
||||
]);
|
||||
$additionalTable = factory(AdditionalTablesModel::class)->create([
|
||||
'PRO_UID' => $proUid,
|
||||
'DBS_UID' => $dbSource->DBS_UID,
|
||||
]);
|
||||
$tableNameExternal = $additionalTable->ADD_TAB_NAME;
|
||||
$nameExternal = $additionalTable->ADD_TAB_CLASS_NAME;
|
||||
$this->createSchema($dbSource->DBS_DATABASE_NAME, $tableNameExternal, $nameExternal, $dbSource->DBS_UID);
|
||||
|
||||
$application = factory(Application::class)->create([
|
||||
'PRO_UID' => $proUid
|
||||
]);
|
||||
factory(Delegation::class)->create([
|
||||
'DEL_THREAD_STATUS' => 'CLOSED',
|
||||
'APP_NUMBER' => $application->APP_NUMBER,
|
||||
'TAS_UID' => $task->TAS_UID,
|
||||
]);
|
||||
|
||||
//assertions
|
||||
Queue::fake();
|
||||
Queue::assertNothingPushed();
|
||||
|
||||
$additionalTables = new AdditionalTables();
|
||||
$additionalTables->populateReportTable($tableName, 'workflow', 'NORMAL', $proUid, '', $additionalTable->ADD_TAB_UID);
|
||||
|
||||
Queue::assertPushed(GenerateReportTable::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the content from template file.
|
||||
* @param string $pathData
|
||||
|
||||
@@ -188,4 +188,43 @@ class VariableTest extends TestCase
|
||||
$this->assertArrayHasKey('var_accepted_values', $res, "The result does not contains 'var_accepted_values' as key");
|
||||
$this->assertArrayHasKey('inp_doc_uid', $res, "The result does not contains 'inp_doc_uid' as key");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test it return the variables by type related to the PRO_UID
|
||||
*
|
||||
* @covers \ProcessMaker\BusinessModel\Variable::getVariablesByType()
|
||||
* @test
|
||||
*/
|
||||
public function it_list_variables_by_type_related_a_process()
|
||||
{
|
||||
$process = factory(Process::class)->create();
|
||||
$varType = 'integer';
|
||||
$varTypeId = 2;
|
||||
for ($x = 1; $x <= 5; $x++) {
|
||||
$processVar = factory(ProcessVariables::class)->states('foreign_keys')->create([
|
||||
'PRO_ID' => $process->PRO_ID,
|
||||
'PRJ_UID' => $process->PRO_UID,
|
||||
'VAR_FIELD_TYPE' => $varType,
|
||||
'VAR_FIELD_TYPE_ID' => $varTypeId,
|
||||
'VAR_NAME' => 'varTestName' . $x,
|
||||
]);
|
||||
}
|
||||
$variable = new Variable();
|
||||
// Get all results
|
||||
$res = $variable->getVariablesByType($process->PRO_UID, 2);
|
||||
$this->assertEquals(5, count($res));
|
||||
$res = head($res);
|
||||
$this->assertArrayHasKey('value', $res, "The result does not contains 'value' as key");
|
||||
// Get a specific start and limit
|
||||
$res = $variable->getVariablesByType($process->PRO_UID, 2, 0, 2);
|
||||
$this->assertNotEmpty($res);
|
||||
$this->assertEquals(2, count($res));
|
||||
// Get a specific search
|
||||
$res = $variable->getVariablesByType($process->PRO_UID, 2, 0, 4, 'varTest');
|
||||
$this->assertNotEmpty($res);
|
||||
$this->assertEquals(4, count($res));
|
||||
// When the search does not match
|
||||
$res = $variable->getVariablesByType($process->PRO_UID, 2, null, null, 'other');
|
||||
$this->assertEmpty($res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace ProcessMaker\Core;
|
||||
|
||||
use App\Jobs\Email;
|
||||
use Tests\TestCase;
|
||||
|
||||
class JobsManagerTest extends TestCase
|
||||
|
||||
@@ -70,4 +70,41 @@ class ProcessVariablesTest extends TestCase
|
||||
$result = ProcessVariables::getVariables($process->PRO_ID);
|
||||
$this->assertNotEmpty($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test it return the variables by type related to the PRO_ID
|
||||
*
|
||||
* @covers \ProcessMaker\Model\ProcessVariables::getVariablesByType()
|
||||
* @test
|
||||
*/
|
||||
public function it_list_variables_type_by_process()
|
||||
{
|
||||
$process = factory(Process::class)->create();
|
||||
$varType = 'integer';
|
||||
$varTypeId = 2;
|
||||
for ($x = 1; $x <= 5; $x++) {
|
||||
$processVar = factory(ProcessVariables::class)->states('foreign_keys')->create([
|
||||
'PRO_ID' => $process->PRO_ID,
|
||||
'PRJ_UID' => $process->PRO_UID,
|
||||
'VAR_FIELD_TYPE' => $varType,
|
||||
'VAR_FIELD_TYPE_ID' => $varTypeId,
|
||||
'VAR_NAME' => 'varTestName' . $x,
|
||||
]);
|
||||
}
|
||||
|
||||
$res = ProcessVariables::getVariablesByType($processVar->PRO_ID, 2, null, null, null);
|
||||
$this->assertNotEmpty($res);
|
||||
$this->assertEquals(5, count($res));
|
||||
// Get a specific start and limit
|
||||
$res = ProcessVariables::getVariablesByType($process->PRO_ID, 2, 0, 2);
|
||||
$this->assertNotEmpty($res);
|
||||
$this->assertEquals(2, count($res));
|
||||
// Get a specific search
|
||||
$res = ProcessVariables::getVariablesByType($process->PRO_ID, 2, 0, 4, 'varTest');
|
||||
$this->assertNotEmpty($res);
|
||||
$this->assertEquals(4, count($res));
|
||||
// When the search does not match
|
||||
$res = ProcessVariables::getVariablesByType($process->PRO_ID, 2, null, null, 'other');
|
||||
$this->assertEmpty($res);
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use ProcessMaker\Core\System;
|
||||
|
||||
CLI::taskName("generate-data-report");
|
||||
CLI::taskRun("generateDataReport");
|
||||
CLI::taskDescription("\nGenerate data report by process in a respective workspace, you must pass through arguments the project identifier and the processing interval.");
|
||||
CLI::taskArg("workspace", false);
|
||||
CLI::taskOpt("uid", "Identifier that represents the process, must be 32 characters.", "", "process=");
|
||||
CLI::taskOpt("start", "The start option skips so many rows before returning results.", "", "start=");
|
||||
CLI::taskOpt("limit", "The limit option restricts the number of rows returned.", "", "limit=");
|
||||
|
||||
/**
|
||||
* Generate data report by process in a respective workspace, you must pass through
|
||||
* arguments the project identifier and the processing interval.
|
||||
* @param array $options
|
||||
* @return void
|
||||
*/
|
||||
function generateDataReport(array $options): void
|
||||
{
|
||||
//get workspace
|
||||
if (empty($options[0])) {
|
||||
CLI::logging("Workspace undefined!\n");
|
||||
return;
|
||||
}
|
||||
$workspace = $options[0];
|
||||
|
||||
//get options
|
||||
$parameters = [
|
||||
"tableName=" => "",
|
||||
"type=" => "",
|
||||
"process=" => "",
|
||||
"gridKey=" => "",
|
||||
"additionalTable=" => "",
|
||||
"className=" => "",
|
||||
"pathWorkspace=" => "",
|
||||
"start=" => "",
|
||||
"limit=" => ""
|
||||
];
|
||||
foreach ($parameters as $key => $value) {
|
||||
for ($i = 1; $i < count($options); $i++) {
|
||||
if (strpos($options[$i], $key) !== false) {
|
||||
$parameters[$key] = str_replace($key, "", $options[$i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//validations
|
||||
$needed = [
|
||||
"process="
|
||||
];
|
||||
foreach ($needed as $value) {
|
||||
if (empty($parameters[$value])) {
|
||||
CLI::logging("Missing options {$value}.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//run method
|
||||
$workspaceTools = new WorkspaceTools($workspace);
|
||||
$workspaceTools->generateDataReport(
|
||||
$parameters["tableName="],
|
||||
$parameters["type="],
|
||||
$parameters["process="],
|
||||
$parameters["gridKey="],
|
||||
$parameters["additionalTable="],
|
||||
$parameters["className="],
|
||||
$parameters["pathWorkspace="],
|
||||
(int) $parameters["start="],
|
||||
(int) $parameters["limit="]
|
||||
);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
CLI::taskName("populate-table");
|
||||
CLI::taskRun("populateTable");
|
||||
CLI::taskDescription("\nThis function populates the report table with the APP_DATA data");
|
||||
CLI::taskArg("workspace", false);
|
||||
|
||||
/**
|
||||
* This function populates the report table with the APP_DATA data.
|
||||
* @return void
|
||||
*/
|
||||
function populateTable($options): void
|
||||
{
|
||||
//get options
|
||||
$workspaceName = $options[0];
|
||||
$query = base64_decode($options[1]);
|
||||
$isRbac = (bool) $options[2];
|
||||
|
||||
$workspace = new WorkspaceTools($workspaceName);
|
||||
$workspace->populateTableReport($query, $isRbac);
|
||||
}
|
||||
@@ -29,6 +29,7 @@ class PmDynaform
|
||||
public $lang = SYS_LANG;
|
||||
public $translations = null;
|
||||
public $onPropertyRead = "onPropertyReadFormInstance";
|
||||
public $onAfterPropertyRead = "onAfterPropertyReadFormInstance";
|
||||
public $pathRTLCss = '';
|
||||
public $record = null;
|
||||
public $records = null;
|
||||
@@ -545,6 +546,7 @@ class PmDynaform
|
||||
if (isset($this->fields["APP_DATA"][$json->name . "_label"])) {
|
||||
$json->data->label = $this->fields["APP_DATA"][$json->name . "_label"];
|
||||
}
|
||||
$this->setDependentOptionsForDatetime($json, $this->fields);
|
||||
}
|
||||
if ($key === "type" && ($value === "file") && isset($this->fields["APP_DATA"]["APPLICATION"])) {
|
||||
$oCriteriaAppDocument = new Criteria("workflow");
|
||||
@@ -771,6 +773,11 @@ class PmDynaform
|
||||
}
|
||||
}
|
||||
}
|
||||
//read event after
|
||||
$fn = $this->onAfterPropertyRead;
|
||||
if (is_callable($fn) || function_exists($fn)) {
|
||||
$fn($json, $key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2489,4 +2496,38 @@ class PmDynaform
|
||||
$json->dataSchema[$key] = $columnsData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dependentOptions property for datetime control, if it contains dependent fields.
|
||||
* @param stdClass $json
|
||||
* @param array $fields
|
||||
* @return void
|
||||
*/
|
||||
private function setDependentOptionsForDatetime(stdClass &$json, array $fields = []): void
|
||||
{
|
||||
if (!isset($json->type)) {
|
||||
return;
|
||||
}
|
||||
if ($json->type !== 'datetime') {
|
||||
return;
|
||||
}
|
||||
$json->dependentOptions = '';
|
||||
$backup = $this->onAfterPropertyRead;
|
||||
$properties = [
|
||||
'defaultDate' => $json->defaultDate,
|
||||
'minDate' => $json->minDate,
|
||||
'maxDate' => $json->maxDate
|
||||
];
|
||||
$this->onAfterPropertyRead = function(stdClass &$json, $key, $value) use($backup, $properties) {
|
||||
if (isset($json->type) && $json->type === 'datetime' && $key === "dependentOptions") {
|
||||
$json->dependentOptions = new stdClass();
|
||||
foreach ($properties as $property => $value) {
|
||||
if (is_string($value) && in_array(substr($value, 0, 2), self::$prefixs)) {
|
||||
$json->dependentOptions->{$property} = $value;
|
||||
}
|
||||
}
|
||||
$this->onAfterPropertyRead = $backup;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
use App\Jobs\GenerateReportTable;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use ProcessMaker\Core\MultiProcOpen;
|
||||
use ProcessMaker\Commands\PopulateTableReport;
|
||||
use ProcessMaker\Core\JobsManager;
|
||||
use ProcessMaker\Model\Application;
|
||||
|
||||
/**
|
||||
@@ -205,6 +205,9 @@ class ReportTables
|
||||
*/
|
||||
public function populateTable($tableName, $connectionShortName = 'report', $type = 'NORMAL', $fields = [], $proUid = '', $grid = '')
|
||||
{
|
||||
$config = System::getSystemConfiguration();
|
||||
$reportTableBatchRegeneration = $config['report_table_batch_regeneration'];
|
||||
|
||||
$tableName = $this->sPrefix . $tableName;
|
||||
//we have to do the propel connection
|
||||
$database = $this->chooseDB($connectionShortName);
|
||||
@@ -222,7 +225,7 @@ class ReportTables
|
||||
$applications = Application::getByProUid($proUid);
|
||||
$i = 1;
|
||||
$queryValues = "";
|
||||
$numberRecords = 1000;
|
||||
$numberRecords = $reportTableBatchRegeneration;
|
||||
$n = count($applications);
|
||||
foreach ($applications as $application) {
|
||||
$appData = $case->unserializeData($application->APP_DATA);
|
||||
@@ -262,11 +265,12 @@ class ReportTables
|
||||
$queryValues = rtrim($queryValues, ",");
|
||||
$query = $headQuery . $queryValues;
|
||||
$queryValues = "";
|
||||
$workspace = config("system.workspace");
|
||||
$processesManager = new MultiProcOpen();
|
||||
$processesManager->chunk(1, 1, function($size, $start, $limit) use ($query, $workspace) {
|
||||
return new PopulateTableReport($workspace, $query);
|
||||
});
|
||||
|
||||
//add to queue
|
||||
$closure = function() use($query) {
|
||||
DB::insert($query);
|
||||
};
|
||||
JobsManager::getSingleton()->dispatch(GenerateReportTable::class, $closure);
|
||||
}
|
||||
} else {
|
||||
if (isset($appData[$grid])) {
|
||||
@@ -304,11 +308,12 @@ class ReportTables
|
||||
$queryValues = rtrim($queryValues, ",");
|
||||
$query = $headQuery . $queryValues;
|
||||
$queryValues = "";
|
||||
$workspace = config("system.workspace");
|
||||
$processesManager = new MultiProcOpen();
|
||||
$processesManager->chunk(1, 1, function($size, $start, $limit) use ($query, $workspace) {
|
||||
return new PopulateTableReport($workspace, $query);
|
||||
});
|
||||
|
||||
//add to queue
|
||||
$closure = function() use($query) {
|
||||
DB::insert($query);
|
||||
};
|
||||
JobsManager::getSingleton()->dispatch(GenerateReportTable::class, $closure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,15 +249,16 @@ function executeQuery ($SqlStatement, $DBConnectionUID = 'workflow', $aParameter
|
||||
if (is_null(config('database.connections.' . $DBConnectionUID . '.driver'))) {
|
||||
// Force to load the external connections
|
||||
DbConnections::loadAdditionalConnections();
|
||||
if (config('database.connections.' . $DBConnectionUID . '.driver') !== 'oracle') {
|
||||
// If the connections drivers are "mysql", "pgsql" or "sqlsrv" we're using Laravel
|
||||
$con = DB::connection($DBConnectionUID);
|
||||
$con->beginTransaction();
|
||||
} else {
|
||||
// If the connection driver is "oracle" we're using the native oci8 functions
|
||||
$con = Propel::getConnection($DBConnectionUID);
|
||||
$con->begin();
|
||||
}
|
||||
}
|
||||
|
||||
if (config('database.connections.' . $DBConnectionUID . '.driver') !== 'oracle') {
|
||||
// If the connections drivers are "mysql", "pgsql" or "sqlsrv" we're using Laravel
|
||||
$con = DB::connection($DBConnectionUID);
|
||||
$con->beginTransaction();
|
||||
} else {
|
||||
// If the connection driver is "oracle" we are using the native oci8 functions
|
||||
$con = Propel::getConnection($DBConnectionUID);
|
||||
$con->begin();
|
||||
}
|
||||
|
||||
$blackList = System::getQueryBlackList();
|
||||
@@ -459,6 +460,123 @@ function evaluateFunction($aGrid, $sExpresion)
|
||||
return $aGrid;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @method
|
||||
*
|
||||
* Executes operations in the grid fields, such as sum, average, median, minimum, maximun,
|
||||
* stantard deviation, variance, percentile, count, count distinct
|
||||
*
|
||||
* @name PMFTotalCalculation
|
||||
* @label PMFTotalCalculation Function
|
||||
* @link http://wiki.processmaker.com/index.php/ProcessMaker_Functions#PMFTotalCalculation.28.29
|
||||
* @param array | $grid | Grid | The input grid.
|
||||
* @param string (32) | $field | Name of field | The name of the field.
|
||||
* @param string (32) | $function | Operation.
|
||||
* @return int|float|array | $result | Result | Result according of the function
|
||||
*
|
||||
*/
|
||||
function PMFTotalCalculation($grid, $field, $function)
|
||||
{
|
||||
$systemConfiguration = Bootstrap::getSystemConfiguration();
|
||||
$floatPointNumber = $systemConfiguration['pmftotalcalculation_floating_point_number'];
|
||||
$function = strtolower($function);
|
||||
$totalRows = count($grid);
|
||||
$result = 0;
|
||||
$sum = 0;
|
||||
|
||||
switch ($function) {
|
||||
case "sum":
|
||||
for ($i = 1; $i <= $totalRows; $i += 1) {
|
||||
$result += $grid[$i][$field];
|
||||
}
|
||||
break;
|
||||
case "average":
|
||||
for ($i = 1; $i <= $totalRows; $i += 1) {
|
||||
$result += $grid[$i][$field];
|
||||
}
|
||||
$result = $result / $totalRows;
|
||||
break;
|
||||
case "median":
|
||||
$arrayAux = [];
|
||||
for ($i = 1; $i <= $totalRows; $i += 1) {
|
||||
$arrayAux[] = $grid[$i][$field];
|
||||
}
|
||||
sort($arrayAux);
|
||||
$term = ($totalRows + 1) / 2;
|
||||
if ($totalRows % 2 === 0) {
|
||||
$term = floor($term);
|
||||
$result = ($arrayAux[$term - 1] + $arrayAux[$term]) / 2;
|
||||
} else {
|
||||
$result = $arrayAux[$term - 1];
|
||||
}
|
||||
break;
|
||||
case "minimum":
|
||||
$result = $grid[1][$field];
|
||||
for ($i = 2; $i <= $totalRows; $i += 1) {
|
||||
if ($grid[$i][$field] < $result) {
|
||||
$result = $grid[$i][$field];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "maximum":
|
||||
$result = $grid[1][$field];
|
||||
for ($i = 2; $i <= $totalRows; $i += 1) {
|
||||
if ($grid[$i][$field] > $result) {
|
||||
$result = $grid[$i][$field];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "standarddeviation":
|
||||
$mean = 0;
|
||||
for ($i = 1; $i <= $totalRows; $i += 1) {
|
||||
$mean += $grid[$i][$field];
|
||||
}
|
||||
$mean = $mean / $totalRows;
|
||||
for ($i = 1; $i <= $totalRows; $i += 1) {
|
||||
$result += pow($grid[$i][$field] - $mean, 2);
|
||||
}
|
||||
$result = sqrt($result / $totalRows);
|
||||
break;
|
||||
case "variance":
|
||||
$mean = 0;
|
||||
for ($i = 1; $i <= $totalRows; $i += 1) {
|
||||
$mean += $grid[$i][$field];
|
||||
}
|
||||
$mean = $mean / $totalRows;
|
||||
for ($i = 1; $i <= $totalRows; $i += 1) {
|
||||
$result += pow($grid[$i][$field] - $mean, 2);
|
||||
}
|
||||
$result = $result / $totalRows;
|
||||
break;
|
||||
case "percentile":
|
||||
$result = [];
|
||||
$arrayAux = [];
|
||||
for ($i = 1; $i <= $totalRows; $i += 1) {
|
||||
$sum += $grid[$i][$field];
|
||||
$arrayAux[$i] = $grid[$i][$field];
|
||||
}
|
||||
for ($i = 1; $i <= count($arrayAux); $i += 1) {
|
||||
$result[$i] = round(($arrayAux[$i] * 100) / $sum, $floatPointNumber);
|
||||
}
|
||||
break;
|
||||
case "count":
|
||||
$result = $totalRows;
|
||||
break;
|
||||
case "countdistinct":
|
||||
$arrayAux = [];
|
||||
for ($i = 1; $i <= $totalRows; $i += 1) {
|
||||
$arrayAux[] = $grid[$i][$field];
|
||||
}
|
||||
$result = count(array_count_values($arrayAux));
|
||||
break;
|
||||
}
|
||||
if ($function !== "percentile") {
|
||||
return round($result, $floatPointNumber);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Web Services Functions *
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
use App\Jobs\GenerateReportTable;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use ProcessMaker\Commands\GenerateDataReport;
|
||||
use ProcessMaker\Core\MultiProcOpen;
|
||||
use ProcessMaker\Core\JobsManager;
|
||||
use ProcessMaker\Core\System;
|
||||
use ProcessMaker\Model\Application;
|
||||
use ProcessMaker\Model\Fields;
|
||||
|
||||
@@ -735,28 +736,23 @@ class AdditionalTables extends BaseAdditionalTables
|
||||
$workspace = config("system.workspace");
|
||||
$pathWorkspace = PATH_WORKSPACE;
|
||||
$n = Application::count();
|
||||
$processesManager = new MultiProcOpen();
|
||||
$processesManager->chunk($n, 1000, function($size, $start, $limit) use(
|
||||
$workspace,
|
||||
$tableName,
|
||||
$type,
|
||||
$processUid,
|
||||
$gridKey,
|
||||
$addTabUid,
|
||||
$className,
|
||||
$pathWorkspace) {
|
||||
return new GenerateDataReport(
|
||||
$workspace,
|
||||
$tableName,
|
||||
$type,
|
||||
$processUid,
|
||||
$gridKey,
|
||||
$addTabUid,
|
||||
$className,
|
||||
$pathWorkspace,
|
||||
$start,
|
||||
$limit);
|
||||
});
|
||||
|
||||
//batch process
|
||||
$config = System::getSystemConfiguration();
|
||||
$reportTableBatchRegeneration = $config['report_table_batch_regeneration'];
|
||||
|
||||
$size = $n;
|
||||
$start = 0;
|
||||
$limit = $reportTableBatchRegeneration;
|
||||
|
||||
for ($i = 1; $start < $size; $i++) {
|
||||
$closure = function() use($workspace, $tableName, $type, $processUid, $gridKey, $addTabUid, $className, $pathWorkspace, $start, $limit) {
|
||||
$workspaceTools = new WorkspaceTools($workspace);
|
||||
$workspaceTools->generateDataReport($tableName, $type, $processUid, $gridKey, $addTabUid, $className, $pathWorkspace, $start, $limit);
|
||||
};
|
||||
JobsManager::getSingleton()->dispatch(GenerateReportTable::class, $closure);
|
||||
$start = $i * $limit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -77,7 +77,7 @@ class AppMessageMapBuilder
|
||||
|
||||
$tMap->addColumn('APP_MSG_TYPE_ID', 'AppMsgTypeId', 'int', CreoleTypes::TINYINT, false, null);
|
||||
|
||||
$tMap->addColumn('APP_MSG_SUBJECT', 'AppMsgSubject', 'string', CreoleTypes::VARCHAR, true, 150);
|
||||
$tMap->addColumn('APP_MSG_SUBJECT', 'AppMsgSubject', 'string', CreoleTypes::VARCHAR, true, 998);
|
||||
|
||||
$tMap->addColumn('APP_MSG_FROM', 'AppMsgFrom', 'string', CreoleTypes::VARCHAR, true, 100);
|
||||
|
||||
|
||||
@@ -579,9 +579,6 @@ abstract class BaseEmailServerPeer
|
||||
}
|
||||
} else {
|
||||
|
||||
if ($obj->isNew() || $obj->isColumnModified(EmailServerPeer::MESS_ENGINE))
|
||||
$columns[EmailServerPeer::MESS_ENGINE] = $obj->getMessEngine();
|
||||
|
||||
}
|
||||
|
||||
return BasePeer::doValidate(EmailServerPeer::DATABASE_NAME, EmailServerPeer::TABLE_NAME, $columns);
|
||||
|
||||
@@ -1,27 +1,4 @@
|
||||
<?php
|
||||
/**
|
||||
* databases.php
|
||||
*
|
||||
* ProcessMaker Open Source Edition
|
||||
* Copyright (C) 2004 - 2008 Colosa Inc.23
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For more information, contact Colosa Inc, 2566 Le Jeune Rd.,
|
||||
* Coral Gables, FL, 33134, USA, or email info@colosa.com.
|
||||
*
|
||||
*/
|
||||
|
||||
if (defined('PATH_DB') && !empty(config("system.workspace"))) {
|
||||
|
||||
@@ -29,7 +6,32 @@ if (defined('PATH_DB') && !empty(config("system.workspace"))) {
|
||||
throw new Exception("Could not find db.php in current workspace " . config("system.workspace"));
|
||||
}
|
||||
|
||||
require_once(PATH_DB . config("system.workspace") . '/db.php');
|
||||
//These constants must not exist, they will be created by "db.php".
|
||||
$constants = [
|
||||
'DB_ADAPTER',
|
||||
'DB_HOST',
|
||||
'DB_NAME',
|
||||
'DB_USER',
|
||||
'DB_PASS',
|
||||
'DB_RBAC_HOST',
|
||||
'DB_RBAC_NAME',
|
||||
'DB_RBAC_USER',
|
||||
'DB_RBAC_PASS' ,
|
||||
'DB_REPORT_HOST',
|
||||
'DB_REPORT_NAME',
|
||||
'DB_REPORT_USER',
|
||||
'DB_REPORT_PASS',
|
||||
];
|
||||
$load = true;
|
||||
foreach ($constants as $value) {
|
||||
if (defined($value)) {
|
||||
$load = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($load === true) {
|
||||
require_once(PATH_DB . config("system.workspace") . '/db.php');
|
||||
}
|
||||
//to do: enable for other databases
|
||||
$dbType = DB_ADAPTER;
|
||||
$dsn = DB_ADAPTER . '://' . DB_USER . ':' . urlencode(DB_PASS) . '@' . DB_HOST . '/' . DB_NAME;
|
||||
@@ -42,15 +44,12 @@ if (defined('PATH_DB') && !empty(config("system.workspace"))) {
|
||||
|
||||
switch (DB_ADAPTER) {
|
||||
case 'mysql':
|
||||
$dsn .= '?encoding=utf8';
|
||||
$dsnRbac .= '?encoding=utf8';
|
||||
$dsn .= '?encoding=utf8';
|
||||
$dsnRbac .= '?encoding=utf8';
|
||||
$dsnReport .= '?encoding=utf8';
|
||||
break;
|
||||
case 'mssql':
|
||||
case 'sqlsrv':
|
||||
//$dsn .= '?sendStringAsUnicode=false';
|
||||
//$dsnRbac .= '?sendStringAsUnicode=false';
|
||||
//$dsnReport .= '?sendStringAsUnicode=false';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -64,7 +63,7 @@ if (defined('PATH_DB') && !empty(config("system.workspace"))) {
|
||||
|
||||
$pro ['datasources']['rp']['connection'] = $dsnReport;
|
||||
$pro ['datasources']['rp']['adapter'] = DB_ADAPTER;
|
||||
|
||||
|
||||
$dbHost = explode(':', DB_HOST);
|
||||
config(['database.connections.workflow.host' => $dbHost[0]]);
|
||||
config(['database.connections.workflow.database' => DB_NAME]);
|
||||
@@ -76,6 +75,6 @@ if (defined('PATH_DB') && !empty(config("system.workspace"))) {
|
||||
}
|
||||
|
||||
$pro ['datasources']['dbarray']['connection'] = 'dbarray://user:pass@localhost/pm_os';
|
||||
$pro ['datasources']['dbarray']['adapter'] = 'dbarray';
|
||||
$pro ['datasources']['dbarray']['adapter'] = 'dbarray';
|
||||
|
||||
return $pro;
|
||||
|
||||
@@ -25325,6 +25325,12 @@ msgstr "The PHP files execution was disabled please contact the system administr
|
||||
msgid "Please complete the reassign reason."
|
||||
msgstr "Please complete the reassign reason."
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_THE_REPORT_TABLE_IS_REGENERATING_PLEASE_COME_BACK_IN_A_FEW_MINUTES
|
||||
#: LABEL/ID_THE_REPORT_TABLE_IS_REGENERATING_PLEASE_COME_BACK_IN_A_FEW_MINUTES
|
||||
msgid "The report table is regenerating please come back in a few minutes."
|
||||
msgstr "The report table is regenerating please come back in a few minutes."
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED
|
||||
#: LABEL/ID_THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED
|
||||
|
||||
@@ -1215,7 +1215,7 @@ class pmTablesProxy extends HttpProxyController
|
||||
if (!empty($table) && $table['PRO_UID'] != '') {
|
||||
try {
|
||||
$additionalTables->populateReportTable($table['ADD_TAB_NAME'], PmTable::resolveDbSource($table['DBS_UID']), $table['ADD_TAB_TYPE'], $table['PRO_UID'], $table['ADD_TAB_GRID'], $table['ADD_TAB_UID']);
|
||||
$result->message = 'Generated for table ' . $table['ADD_TAB_NAME'];
|
||||
$result->message = G::LoadTranslation("ID_THE_REPORT_TABLE_IS_REGENERATING_PLEASE_COME_BACK_IN_A_FEW_MINUTES");
|
||||
} catch (Exception $e) {
|
||||
$context = Bootstrap::getDefaultContextLog();
|
||||
$context['proUid'] = $table['PRO_UID'];
|
||||
|
||||
@@ -61112,6 +61112,7 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE
|
||||
( 'LABEL','ID_THE_NAME_CHANGE_MAY_CAUSE_DATA_LOSS','en','The change might cause data loss in the PM table. Do you want to continue?','2017-03-30') ,
|
||||
( 'LABEL','ID_THE_PHP_FILES_EXECUTION_WAS_DISABLED','en','The PHP files execution was disabled please contact the system administrator.','2018-04-20') ,
|
||||
( 'LABEL','ID_THE_REASON_REASSIGN_USER_EMPTY','en','Please complete the reassign reason.','2016-10-20') ,
|
||||
( 'LABEL','ID_THE_REPORT_TABLE_IS_REGENERATING_PLEASE_COME_BACK_IN_A_FEW_MINUTES','en','The report table is regenerating please come back in a few minutes.','2020-06-01') ,
|
||||
( 'LABEL','ID_THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED','en','The upload of PHP files was disabled please contact the system administrator.','2018-04-20') ,
|
||||
( 'LABEL','ID_THE_USERNAME_EMAIL_IS_INCORRECT','en','The username or email is incorrect','2018-01-18') ,
|
||||
( 'LABEL','ID_THIS_MONTH','en','This Month','2014-01-15') ,
|
||||
|
||||
@@ -1178,7 +1178,9 @@ class DynaForm
|
||||
}
|
||||
foreach ($oldColumns as $oldColumn) {
|
||||
if (strtolower(AdditionalTables::getPHPName($column->id)) === strtolower(AdditionalTables::getPHPName($oldColumn->id))) {
|
||||
$identicals[] = "'" . $column->id . "' - '" . $oldColumn->id . "'";
|
||||
if (strtolower(AdditionalTables::getPHPName($column->var_name)) === strtolower(AdditionalTables::getPHPName($oldColumn->var_name))) {
|
||||
$identicals[] = "'" . $column->id . "' - '" . $oldColumn->id . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,16 @@ class Variable
|
||||
'object' => 10
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the variables types accepted
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVariableTypes()
|
||||
{
|
||||
return $this->variableTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Variable for a Process
|
||||
*
|
||||
@@ -355,6 +365,33 @@ class Variable
|
||||
return $arrayVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data of Variables related to the specific type
|
||||
*
|
||||
* @param string $processUid Unique id of Process
|
||||
* @param int $typeVarId
|
||||
* @param int $start
|
||||
* @param int $limit
|
||||
* @param string $search
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return array, return an array with varaibles filter by type
|
||||
*/
|
||||
public function getVariablesByType($processUid, $typeVarId = 0, $start = null, $limit = null, $search = null, $prefix = null)
|
||||
{
|
||||
//Verify data
|
||||
$proId = Validator::proUid($processUid, '$prj_uid');
|
||||
$variables = ProcessVariables::getVariablesByType($proId, $typeVarId, $start, $limit, $search);
|
||||
$arrayVariables = [];
|
||||
foreach ($variables as $var) {
|
||||
$arrayVariables[] = [
|
||||
'value' => is_null($prefix) ? $var['VAR_NAME'] : $prefix . $var['VAR_NAME'],
|
||||
];
|
||||
}
|
||||
|
||||
return $arrayVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify field definition
|
||||
*
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Commands;
|
||||
|
||||
use ProcessMaker\Core\ProcOpen;
|
||||
|
||||
class GenerateDataReport extends ProcOpen
|
||||
{
|
||||
private $workspace;
|
||||
private $tableName;
|
||||
private $type;
|
||||
private $processUid;
|
||||
private $gridKey;
|
||||
private $addTabUid;
|
||||
private $className;
|
||||
private $pathWorkspace;
|
||||
private $start;
|
||||
private $limit;
|
||||
|
||||
/**
|
||||
* Initializes the command parameters.
|
||||
* @param string $workspace
|
||||
* @param string $tableName
|
||||
* @param string $type
|
||||
* @param string $processUid
|
||||
* @param string $gridKey
|
||||
* @param string $addTabUid
|
||||
* @param string $className
|
||||
* @param string $pathWorkspace
|
||||
* @param integer $start
|
||||
* @param integer $limit
|
||||
*/
|
||||
public function __construct(
|
||||
$workspace,
|
||||
$tableName,
|
||||
$type = 'NORMAL',
|
||||
$processUid = '',
|
||||
$gridKey = '',
|
||||
$addTabUid = '',
|
||||
$className = '',
|
||||
$pathWorkspace,
|
||||
$start = 0,
|
||||
$limit = 10)
|
||||
{
|
||||
$this->workspace = $workspace;
|
||||
$this->tableName = $tableName;
|
||||
$this->type = $type;
|
||||
$this->processUid = $processUid;
|
||||
$this->gridKey = $gridKey;
|
||||
$this->addTabUid = $addTabUid;
|
||||
$this->className = $className;
|
||||
$this->pathWorkspace = $pathWorkspace;
|
||||
$this->start = $start;
|
||||
$this->limit = $limit;
|
||||
$this->setCwd(PATH_TRUNK);
|
||||
parent::__construct($this->buildCommand());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command to execute.
|
||||
* @return string
|
||||
*/
|
||||
private function buildCommand(): string
|
||||
{
|
||||
$command = PHP_BINDIR . "/php "
|
||||
. "./processmaker "
|
||||
. "'generate-data-report' "
|
||||
. "'{$this->workspace}' "
|
||||
. "'tableName={$this->tableName}' "
|
||||
. "'type={$this->type}' "
|
||||
. "'process={$this->processUid}' "
|
||||
. "'gridKey={$this->gridKey}' "
|
||||
. "'additionalTable={$this->addTabUid}' "
|
||||
. "'className={$this->className}' "
|
||||
. "'pathWorkspace={$this->pathWorkspace}' "
|
||||
. "'start={$this->start}' "
|
||||
. "'limit={$this->limit}' ";
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Commands;
|
||||
|
||||
use ProcessMaker\Core\ProcOpen;
|
||||
|
||||
class PopulateTableReport extends ProcOpen
|
||||
{
|
||||
private $workspace;
|
||||
private $sql;
|
||||
private $isRbac;
|
||||
|
||||
/**
|
||||
* Initializes the command parameters.
|
||||
* @param string $workspace
|
||||
* @param string $sql
|
||||
* @param boolean $isRbac
|
||||
*/
|
||||
public function __construct($workspace, $sql, $isRbac = false)
|
||||
{
|
||||
$this->workspace = $workspace;
|
||||
$this->sql = $sql;
|
||||
$this->isRbac = $isRbac;
|
||||
$this->setCwd(PATH_TRUNK);
|
||||
parent::__construct($this->buildCommand());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command to execute.
|
||||
* @return string
|
||||
*/
|
||||
public function buildCommand()
|
||||
{
|
||||
$command = PHP_BINDIR . "/php "
|
||||
. "./processmaker "
|
||||
. "'populate-table' "
|
||||
. "'{$this->workspace}' "
|
||||
. base64_encode($this->sql) . " "
|
||||
. ($this->isRbac ? "'1'" : "'0'");
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Core;
|
||||
|
||||
class MultiProcOpen
|
||||
{
|
||||
/**
|
||||
* Represents the waiting time before starting the process monitoring.
|
||||
* @var integer
|
||||
*/
|
||||
private $sleepTime = 1;
|
||||
|
||||
/**
|
||||
* This method obtains a paging by returning the start and limit indexes
|
||||
* compatible with the mysql pagination in its call function.
|
||||
* The return function must return an instance of the object "ProcessMaker\Core\ProcOpen".
|
||||
* Returns an array containing the status, content, and errors generated by
|
||||
* the open process.
|
||||
* @param int $size
|
||||
* @param int $chunk
|
||||
* @param callable $callback
|
||||
* @return array
|
||||
*/
|
||||
public function chunk(int $size, int $chunk, callable $callback): array
|
||||
{
|
||||
$start = 0;
|
||||
$limit = $chunk;
|
||||
$queries = [];
|
||||
for ($i = 1; $start < $size; $i++) {
|
||||
$queries[] = $callback($size, $start, $limit);
|
||||
$start = $i * $limit;
|
||||
}
|
||||
return $this->run($queries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a set of background processes.
|
||||
* The array must contain one or more instances of the object inherited from
|
||||
* the class "ProcessMaker\Core\ProcOpen"
|
||||
* Returns an array containing the status, content, and errors generated by
|
||||
* the open process.
|
||||
* @param array $processes
|
||||
* @return array
|
||||
*/
|
||||
public function run(array $processes): array
|
||||
{
|
||||
foreach ($processes as $procOpen) {
|
||||
$procOpen->open();
|
||||
}
|
||||
return $this->processMonitoring($processes);
|
||||
}
|
||||
|
||||
/**
|
||||
* It monitors the open processes, verifying if they have ended or thrown an
|
||||
* error and later closing the resources related to the process.
|
||||
* Returns an array containing the status, content, and errors generated by
|
||||
* the open process.
|
||||
* @param array $processes
|
||||
* @return array
|
||||
*/
|
||||
private function processMonitoring(array $processes): array
|
||||
{
|
||||
sleep($this->sleepTime); //this sleep is very important
|
||||
$i = 0;
|
||||
$n = count($processes);
|
||||
if ($n === 0) {
|
||||
return [];
|
||||
}
|
||||
$outputs = [];
|
||||
do {
|
||||
$index = $i % $n;
|
||||
if (isset($processes[$index])) {
|
||||
$procOpen = $processes[$index];
|
||||
$status = $procOpen->getStatus();
|
||||
$contents = $procOpen->getContents();
|
||||
$errors = $procOpen->getErrors();
|
||||
if ($status->running === false || !empty($errors)) {
|
||||
$outputs[] = [
|
||||
"status" => $status,
|
||||
"contents" => $contents,
|
||||
"errors" => $errors,
|
||||
];
|
||||
$procOpen->terminate();
|
||||
$procOpen->close();
|
||||
unset($processes[$index]);
|
||||
}
|
||||
}
|
||||
$i = $i + 1;
|
||||
} while (!empty($processes));
|
||||
return $outputs;
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Core;
|
||||
|
||||
class ProcOpen
|
||||
{
|
||||
private $command;
|
||||
private $resource;
|
||||
private $descriptorspec;
|
||||
private $pipes;
|
||||
private $cwd;
|
||||
|
||||
/**
|
||||
* This initializes the descriptors and the command for the open process.
|
||||
* @param string $command
|
||||
*/
|
||||
public function __construct(string $command)
|
||||
{
|
||||
$this->descriptorspec = [
|
||||
['pipe', 'r'],
|
||||
['pipe', 'w'],
|
||||
['pipe', 'w']
|
||||
];
|
||||
$this->command = $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the resource that represents the process.
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the process execution directory.
|
||||
* @param string $cwd
|
||||
*/
|
||||
public function setCwd(string $cwd)
|
||||
{
|
||||
$this->cwd = $cwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a background process.
|
||||
*/
|
||||
public function open()
|
||||
{
|
||||
if (empty($this->cwd)) {
|
||||
$this->resource = proc_open($this->command, $this->descriptorspec, $this->pipes);
|
||||
} else {
|
||||
$this->resource = proc_open($this->command, $this->descriptorspec, $this->pipes, $this->cwd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of the process when it is finished.
|
||||
* @return string
|
||||
*/
|
||||
public function getContents()
|
||||
{
|
||||
if (is_resource($this->pipes[1])) {
|
||||
return stream_get_contents($this->pipes[1]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the process errors when it is finished.
|
||||
* @return string
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
if (is_resource($this->pipes[2])) {
|
||||
return stream_get_contents($this->pipes[2]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the resources related to the open process.
|
||||
* return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
foreach ($this->pipes as $value) {
|
||||
fclose($value);
|
||||
}
|
||||
proc_close($this->resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End the process before it ends.
|
||||
*/
|
||||
public function terminate()
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
proc_terminate($this->resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status of the process.
|
||||
* @return object
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
$status = [
|
||||
"command" => $this->command,
|
||||
"pid" => null,
|
||||
"running" => false,
|
||||
"signaled" => false,
|
||||
"stopped" => false,
|
||||
"exitcode" => -1,
|
||||
"termsig" => 0,
|
||||
"stopsig" => 0
|
||||
];
|
||||
if (is_resource($this->resource)) {
|
||||
$status = proc_get_status($this->resource);
|
||||
}
|
||||
return (object) $status;
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,9 @@ class System
|
||||
'highlight_home_folder_enable' => 0,
|
||||
'highlight_home_folder_refresh_time' => 10,
|
||||
'highlight_home_folder_scope' => 'unassigned', // For now only this list is supported
|
||||
'disable_advanced_search_case_title_fulltext' => 0
|
||||
'disable_advanced_search_case_title_fulltext' => 0,
|
||||
'pmftotalcalculation_floating_point_number' => 10,
|
||||
'report_table_batch_regeneration' => 1000
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -72,8 +72,21 @@ class ProcessVariables extends Model
|
||||
*/
|
||||
public function scopeProcessId($query, int $proId)
|
||||
{
|
||||
return $query->where('PRO_ID', $proId);
|
||||
return $query->where('PROCESS_VARIABLES.PRO_ID', $proId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to filter a specific type for variable
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param int $typeId
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeTypeId($query, int $typeId)
|
||||
{
|
||||
return $query->where('VAR_FIELD_TYPE_ID', $typeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the variables list
|
||||
*
|
||||
@@ -96,4 +109,46 @@ class ProcessVariables extends Model
|
||||
|
||||
return $variablesList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the variables list
|
||||
*
|
||||
* @param int $proId
|
||||
* @param int $typeId
|
||||
* @param int $start
|
||||
* @param int $limit
|
||||
* @param string $search
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getVariablesByType(int $proId, int $typeId = 0, $start = null, $limit = null, $search = null)
|
||||
{
|
||||
$query = ProcessVariables::query()->select();
|
||||
$query->leftJoin('DB_SOURCE', function ($join) {
|
||||
$join->on('DB_SOURCE.PRO_ID', '=', 'PROCESS_VARIABLES.PRO_ID');
|
||||
});
|
||||
$query->processId($proId);
|
||||
// Check if we need to filter the type of variables
|
||||
if ($typeId > 0) {
|
||||
$query->typeId($typeId);
|
||||
}
|
||||
// search a specific variable name
|
||||
if (!empty($search)) {
|
||||
$query->where('VAR_NAME', 'LIKE', "${search}%");
|
||||
}
|
||||
// order by varNane
|
||||
$query->orderBy('VAR_NAME', 'ASC');
|
||||
// Check if we need to add a pagination
|
||||
if(!is_null($start) && !is_null($limit)) {
|
||||
$query->offset($start)->limit($limit);
|
||||
}
|
||||
// Get records
|
||||
$results = $query->get();
|
||||
$variablesList = [];
|
||||
$results->each(function ($item, $key) use (&$variablesList) {
|
||||
$variablesList[] = $item->toArray();
|
||||
});
|
||||
|
||||
return $variablesList;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
<?php
|
||||
namespace ProcessMaker\Services\Api\Project;
|
||||
|
||||
use \ProcessMaker\Services\Api;
|
||||
use \Luracast\Restler\RestException;
|
||||
use Exception;
|
||||
use G;
|
||||
use Luracast\Restler\RestException;
|
||||
use ProcessMaker\BusinessModel\Variable as BmVariable;
|
||||
use ProcessMaker\Services\Api;
|
||||
|
||||
/**
|
||||
* Project\Variable Api Controller
|
||||
*
|
||||
@@ -28,6 +32,43 @@ class Variable extends Api
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get variables by type
|
||||
*
|
||||
* @url GET /:prj_uid/process-variables/:typeVariable/paged
|
||||
*
|
||||
* @param string $prj_uid {@min 32}{@max 32}
|
||||
* @param string $typeVariable {@from path}
|
||||
* @param int $start {@from path}
|
||||
* @param int $limit {@from path}
|
||||
* @param string $search {@from path}
|
||||
*/
|
||||
public function doGetVariablesByType($prj_uid, $typeVariable, $start = null, $limit = null, $search = null)
|
||||
{
|
||||
try {
|
||||
$variable = new BmVariable();
|
||||
$typesAccepted = $variable::$varTypesValues;
|
||||
if (!empty($typesAccepted[$typeVariable])) {
|
||||
$typeVatId = $typesAccepted[$typeVariable];
|
||||
} else {
|
||||
throw new Exception(G::LoadTranslation("ID_INVALID_VALUE_ONLY_ACCEPTS_VALUES", ['$typeVariable', implode(',', $variable->getVariableTypes())]));
|
||||
}
|
||||
// Review if the word has the prefix
|
||||
$count = preg_match_all('/\@(?:([\@\%\#\?\$\=\&Qq\!])|([a-zA-Z\_][\w\-\>\:]*)\(((?:[^\\\\\)]*(?:[\\\\][\w\W])?)*)\))((?:\s*\[[\'"]?\w+[\'"]?\])+|\-\>([a-zA-Z\_]\w*))?/', $search, $match, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
|
||||
// Check if the search has some prefix
|
||||
$prefix = '';
|
||||
if ($count) {
|
||||
$prefix = substr($search,0,2);
|
||||
$search = substr($search,2);
|
||||
}
|
||||
$response = $variable->getVariablesByType($prj_uid, $typeVatId, $start, $limit, $search, $prefix);
|
||||
|
||||
return $response;
|
||||
} catch (Exception $e) {
|
||||
throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @url GET /:prj_uid/process-variable/:var_uid
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user