update level one

This commit is contained in:
Henry Jordan
2021-08-04 16:25:56 +00:00
17 changed files with 802 additions and 519 deletions

View File

@@ -60,6 +60,11 @@ $factory->state(\ProcessMaker\Model\Delegation::class, 'foreign_keys', function
'APP_CUR_USER' => $user->USR_UID
]);
$delegateDate = $faker->dateTime();
$initDate = $faker->dateTimeInInterval($delegateDate, '+30 minutes');
$riskDate = $faker->dateTimeInInterval($initDate, '+1 day');
$taskDueDate = $faker->dateTimeInInterval($riskDate, '+2 day');
// Return with default values
return [
'DELEGATION_ID' => $faker->unique()->numberBetween(5000),
@@ -74,10 +79,10 @@ $factory->state(\ProcessMaker\Model\Delegation::class, 'foreign_keys', function
'DEL_THREAD' => 1,
'DEL_THREAD_STATUS' => 'OPEN',
'DEL_PRIORITY' => 3,
'DEL_DELEGATE_DATE' => $faker->dateTime(),
'DEL_INIT_DATE' => $faker->dateTime(),
'DEL_TASK_DUE_DATE' => $faker->dateTime(),
'DEL_RISK_DATE' => $faker->dateTime(),
'DEL_DELEGATE_DATE' => $delegateDate,
'DEL_INIT_DATE' => $initDate,
'DEL_TASK_DUE_DATE' => $taskDueDate,
'DEL_RISK_DATE' => $riskDate,
'DEL_LAST_INDEX' => 1,
'USR_ID' => $user->USR_ID,
'PRO_ID' => $process->PRO_ID,
@@ -138,7 +143,7 @@ $factory->state(\ProcessMaker\Model\Delegation::class, 'open', function (Faker $
$delegateDate = $faker->dateTime();
$initDate = $faker->dateTimeInInterval($delegateDate, '+30 minutes');
$riskDate = $faker->dateTimeInInterval($initDate, '+1 day');
$taskDueDate = $faker->dateTimeInInterval($riskDate, '+1 day');
$taskDueDate = $faker->dateTimeInInterval($riskDate, '+2 day');
return [
'DEL_THREAD_STATUS' => 'OPEN',
@@ -156,7 +161,7 @@ $factory->state(\ProcessMaker\Model\Delegation::class, 'closed', function (Faker
$delegateDate = $faker->dateTime();
$initDate = $faker->dateTimeInInterval($delegateDate, '+30 minutes');
$riskDate = $faker->dateTimeInInterval($initDate, '+1 day');
$taskDueDate = $faker->dateTimeInInterval($riskDate, '+1 day');
$taskDueDate = $faker->dateTimeInInterval($riskDate, '+2 day');
$finishDate = $faker->dateTimeInInterval($initDate, '+10 days');
return [

View File

@@ -68,5 +68,9 @@
TASKS: "/home/tasks",
CATEGORIES: "/home/categories",
DEBUG_STATUS: "/home/process-debug-status?processUid={prj_uid}",
LIST_TOTAL_CASES: "/metrics/list-total-cases"
LIST_TOTAL_CASES: "/metrics/list-total-cases",
PAUSE_CASE: "/cases/{app_uid}/pause",
REASSIGN_CASE: "/cases/{app_uid}/reassign-case",
REASSIGN_USERS: "/light/userstoreassign/{task_uid}",
CATEGORIES: "/processcategory/categories"
};

View File

@@ -6,13 +6,20 @@
:style="{height: height + 'px'}"
>
<vue-card v-for="item in data" :key="item.id" :item="item" :options="options">
<slot
v-for="column in options.columns"
:name="column"
:item="item"
:column="column"
:headings="options.headings"
></slot>
<b-row>
<b-col sm="9">
<slot
v-for="column in options.columns"
:name="column"
:item="item"
:column="column"
:headings="options.headings"
></slot>
</b-col>
<b-col sm="3">
<slot name="actions"></slot>
</b-col>
</b-row>
</vue-card>
</div>

View File

@@ -6,13 +6,21 @@
:style="{height: height + 'px'}"
>
<vue-list v-for="item in data" :key="item.id" :item="item" :options="options">
<slot
v-for="column in options.columns"
:name="column"
:item="item"
:column="column"
:headings="options.headings"
></slot>
<b-row>
<b-col sm="10">
<slot
v-for="column in options.columns"
:name="column"
:item="item"
:column="column"
:headings="options.headings"
ref="containerList"
></slot>
</b-col>
<b-col sm="2">
<slot name="actions"></slot>
</b-col>
</b-row>
</vue-list>
</div>

View File

@@ -94,6 +94,7 @@ export default {
width: 0px;
z-index: 999;
display: inline-flex !important;
opacity: 1 !important;
}
.btn-outline-info {
border: none;

View File

@@ -48,10 +48,19 @@
:options="optionsVueView"
ref="vueCardView"
>
<div slot="detail" slot-scope="props">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
<div slot="actions" slot-scope="props">
<b-row>
<b-col sm="12">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @click="updateDataEllipsis(props.row)">
<ellipsis ref="ellipsis" v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
</b-col>
</b-row>
</div>
<div slot="case_number" slot-scope="props" class="v-card-text">
<span class="v-card-text-highlight"
@@ -105,10 +114,19 @@
:options="optionsVueView"
ref="vueListView"
>
<div slot="detail" slot-scope="props">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
<div slot="actions" slot-scope="props">
<b-row>
<b-col sm="12">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @click="updateDataEllipsis(props.row)">
<ellipsis ref="ellipsis" v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
</b-col>
</b-row>
</div>
<div slot="case_number" slot-scope="props" class="v-card-text">
<span class="v-card-text-highlight"
@@ -523,5 +541,7 @@ export default {
padding-left: 50px;
padding-right: 50px;
}
.ellipsis-container {
margin-top: 5em;
}
</style>

View File

@@ -61,10 +61,19 @@
:options="optionsVueView"
ref="vueCardView"
>
<div slot="detail" slot-scope="props">
<div @click="updateDataEllipsis(props.row)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
<div slot="actions" slot-scope="props">
<b-row>
<b-col sm="12">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @click="updateDataEllipsis(props.row)">
<ellipsis v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
</b-col>
</b-row>
</div>
<div slot="case_number" slot-scope="props" class="v-card-text">
<span class="v-card-text-highlight"
@@ -118,12 +127,21 @@
:options="optionsVueView"
ref="vueListView"
>
<div slot="detail" slot-scope="props">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
<div slot="actions" slot-scope="props">
<b-row>
<b-col sm="12">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @click="updateDataEllipsis(props.row)">
<ellipsis ref="ellipsis" v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
</b-col>
</b-row>
</div>
<div slot="case_number" slot-scope="props" class="v-card-text">
<div ref="text" slot="case_number" slot-scope="props" class="v-card-text">
<span class="v-card-text-highlight"
>{{ props["headings"][props.column] }} : {{ props["item"]["CASE_NUMBER"] }}</span
>
@@ -608,7 +626,8 @@ export default {
display: inline-block;
}
.v-card-text {
.ellipsis-container {
margin-top: 5em;
}
.v-pm-card-info{

View File

@@ -59,10 +59,19 @@
:options="optionsVueView"
ref="vueCardView"
>
<div slot="detail" slot-scope="props">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
<div slot="actions" slot-scope="props">
<b-row>
<b-col sm="12">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @click="updateDataEllipsis(props.row)">
<ellipsis ref="ellipsis" v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
</b-col>
</b-row>
</div>
<div slot="case_number" slot-scope="props" class="v-card-text">
<span class="v-card-text-highlight"
@@ -116,10 +125,19 @@
:options="optionsVueView"
ref="vueListView"
>
<div slot="detail" slot-scope="props">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
<div slot="actions" slot-scope="props">
<b-row>
<b-col sm="12">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @click="updateDataEllipsis(props.row)">
<ellipsis ref="ellipsis" v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
</b-col>
</b-row>
</div>
<div slot="case_number" slot-scope="props" class="v-card-text">
<span class="v-card-text-highlight"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,211 @@
<template>
<div id="v-pm-charts" ref="v-pm-charts" class="v-pm-charts vp-inline-block">
<div class="p-1 v-flex">
<h6 class="v-search-title">Number of tasks per Task Status</h6>
<apexchart
v-show="typeView === 'donut'"
ref="apexchart1"
:width="width"
:options="optionsDonut"
:series="seriesDonut"
></apexchart>
<apexchart
v-show="typeView === 'bar'"
ref="apexchart2"
:width="width"
:options="optionsBar"
:series="seriesBar"
></apexchart>
<div class="row">
<div class="col-sm vp-center">
<button
@click="changeView('donut')"
type="button"
class="btn btn-primary"
>
<i class="fas fa-chart-pie"></i
><span class="vp-padding-l10">View</span>
</button>
</div>
<div class="col-sm">
<button
@click="changeView('bar')"
type="button"
class="btn btn-primary"
>
<i class="fas fa-chart-bar"></i
><span class="vp-padding-l10">View</span>
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import _ from "lodash";
import Api from "../../api/index";
export default {
name: "VueChartLvZero",
mixins: [],
components: {},
props: [],
data() {
let that = this;
return {
typeView: "bar",
width: 0,
seriesDonut: [],
optionsDonut: {
labels: [
this.$i18n.t("ID_INBOX"),
this.$i18n.t("ID_DRAFT"),
this.$i18n.t("ID_PAUSED"),
this.$i18n.t("ID_UNASSIGNED"),
],
chart: {
id: "apexchart1",
type: "donut",
},
legend: {
position: "top",
offsetY: 0,
},
},
seriesBar: [
{
data: [400, 430, 448, 470],
},
],
optionsBar: {
chart: {
type: "bar",
id: "apexchart2",
toolbar: {
show: false,
},
},
plotOptions: {
bar: {
barHeight: "100%",
distributed: true,
},
},
legend: {
position: "top",
offsetY: 0,
},
colors: ["#33b2df", "#546E7A", "#d4526e", "#13d8aa"],
dataLabels: {
enabled: false,
},
xaxis: {
categories: [
this.$i18n.t("ID_INBOX"),
this.$i18n.t("ID_DRAFT"),
this.$i18n.t("ID_PAUSED"),
this.$i18n.t("ID_UNASSIGNED"),
],
},
tooltip: {
x: {
show: false,
},
y: {
title: {
formatter: function () {
return "";
},
},
},
},
},
};
},
created() {},
mounted() {
this.getBodyHeight();
//this.getDataDonut();
this.getData();
},
watch: {},
computed: {},
updated() {},
beforeCreate() {},
methods: {
/**
* Return the height for Vue Card View body
*/
getBodyHeight() {
this.width = window.innerHeight * 0.8;
},
/**
* Change view - donut/bar
*/
changeView(view) {
this.typeView = view;
this.getData();
},
/**
* Get data from rest API
*/
getData() {
let that = this;
Api.cases
.listTotalCases()
.then((response) => {
that.formatData(response.data);
})
.catch((response) => {});
},
/**
* Format the data for chart
*/
formatData(data) {
let l = [],
c = [],
s = [];
_.each(data, (el) => {
l.push(el["List Name"]);
s.push(el["Total"]);
if (el["Color"] == "green") {
c.push("#179a6e");
}
if (el["Color"] == "yellow") {
c.push("#feb019");
}
if (el["Color"] == "blue") {
c.push("#008ffb");
}
if (el["Color"] == "gray") {
c.push("#8f99a0");
}
});
this.seriesDonut = s;
this.seriesBar = [
{
data: s,
},
];
this.$refs["apexchart1"].updateOptions({ labels: l, colors: c });
this.$refs["apexchart2"].updateOptions({ labels: l, colors: c });
this.$apexcharts.exec("apexchart1", "updateSeries", s);
this.$apexcharts.exec("apexchart2", "updateSeries", [
{
data: s,
},
]);
},
},
};
</script>
<style>
.vp-center {
text-align: center;
}
.vp-padding-l10 {
padding-left: 10px;
}
</style>

View File

@@ -9,12 +9,14 @@
</template>
<script>
import VueChartLvZero from "./VueChartLvZero.vue";
import VueChartLvOne from "./VueChartLvOne.vue";
export default {
name: "VueCharts",
mixins: [],
components: {
VueChartLvZero,
VueChartLvOne,
},
props: [],

View File

@@ -54,10 +54,19 @@
:options="optionsVueList"
ref="vueCardView"
>
<div slot="detail" slot-scope="props">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
<div slot="actions" slot-scope="props">
<b-row>
<b-col sm="12">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @click="updateDataEllipsis(props.row)">
<ellipsis ref="ellipsis" v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
</b-col>
</b-row>
</div>
<div slot="case_number" slot-scope="props" class="v-card-text">
<span class="v-card-text-highlight"
@@ -110,10 +119,19 @@
:options="optionsVueList"
ref="vueListView"
>
<div slot="detail" slot-scope="props">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
<div slot="actions" slot-scope="props">
<b-row>
<b-col sm="12">
<div class="v-pm-card-info" @click="openCaseDetail(props.item)">
<i class="fas fa-info-circle"></i>
</div>
</b-col>
<b-col sm="12">
<div class="ellipsis-container" @click="updateDataEllipsis(props.row)">
<ellipsis ref="ellipsis" v-if="dataEllipsis" :data="dataEllipsis"> </ellipsis>
</div>
</b-col>
</b-row>
</div>
<div slot="case_number" slot-scope="props" class="v-card-text">
<span class="v-card-text-highlight"

View File

@@ -90,7 +90,7 @@ class EmailServerAjaxTest extends TestCase
$content = $this->requireOnceForEmailServerAjax();
$data = json_decode($content, JSON_OBJECT_AS_ARRAY);
$this->assertContains(200, $data);
$this->assertContains(500, $data);
}
/**

View File

@@ -426,6 +426,42 @@ class DelegationTest extends TestCase
$this->assertCount(1, $table->dueTo($table->DEL_TASK_DUE_DATE)->get());
}
/**
* This test scopeOnTime
*
* @covers \ProcessMaker\Model\Delegation::scopeOnTime()
* @test
*/
public function it_return_scope_on_time()
{
$table = factory(Delegation::class)->states('closed')->create();
$this->assertCount(1, $table->onTime($table->DEL_DELEGATE_DATE)->get());
}
/**
* This test scopeAtRisk
*
* @covers \ProcessMaker\Model\Delegation::scopeAtRisk()
* @test
*/
public function it_return_scope_at_risk()
{
$table = factory(Delegation::class)->states('closed')->create();
$this->assertCount(1, $table->atRisk($table->DEL_DELEGATE_DATE)->get());
}
/**
* This test scopeOverdue
*
* @covers \ProcessMaker\Model\Delegation::scopeOverdue()
* @test
*/
public function it_return_scope_overdue()
{
$table = factory(Delegation::class)->states('closed')->create();
$this->assertCount(1, $table->overdue($table->DEL_DELEGATE_DATE)->get());
}
/**
* This test scopeCase
*
@@ -3196,6 +3232,28 @@ class DelegationTest extends TestCase
$this->assertNotEmpty($result);
}
/**
* This check the return of thread info
*
* @covers \ProcessMaker\Model\Delegation::getDatesFromThread()
* @test
*/
public function it_get_thread_dates()
{
$delegation = factory(Delegation::class)->states('foreign_keys')->create();
$task = new Task();
$taskInfo = $task->load($delegation->TAS_UID);
$taskInfo = head($taskInfo);
$taskType = $taskInfo['TAS_TYPE'];
$result = Delegation::getDatesFromThread(
$delegation->APP_UID,
$delegation->DEL_INDEX,
$delegation->TAS_UID,
$taskType
);
$this->assertNotEmpty($result);
}
/**
* This check the return of pending threads
*
@@ -3207,6 +3265,8 @@ class DelegationTest extends TestCase
$delegation = factory(Delegation::class)->states('foreign_keys')->create();
$result = Delegation::getPendingThreads($delegation->APP_NUMBER);
$this->assertNotEmpty($result);
$result = Delegation::getPendingThreads($delegation->APP_NUMBER, false);
$this->assertNotEmpty($result);
}
/**
@@ -3283,9 +3343,9 @@ class DelegationTest extends TestCase
]);
$res = Delegation::hasActiveParentsCases($parents);
// Assert the result is true
$this->assertTrue($res);
$res = Delegation::hasActiveParentsCases([]);
$this->assertFalse($res);
}
/**
@@ -3296,9 +3356,9 @@ class DelegationTest extends TestCase
*/
public function it_get_cases_completed_by_specific_user()
{
$delegation = factory(Delegation::class)->states('foreign_keys')->create();
$delegation = factory(Delegation::class)->states('last_thread')->create();
$result = Delegation::casesCompletedBy($delegation->USR_ID);
$this->assertEmpty($result);
$this->assertNotEmpty($result);
}
/**

View File

@@ -799,41 +799,45 @@ class Calendar extends CalendarDefinition
return $return;
}
/**
* Calculate date adding a duration, will considerate the calendar
*
* @param string $initialDate
* @param string $duration
* @param string $formatDuration
* @param array $calendarData
*
* @return string
*/
public function dashCalculateDate($initialDate, $duration, $formatDuration, $calendarData = [])
{
if (G::toUpper($formatDuration) == 'DAYS') {
$duration = $duration * $calendarData['HOURS_FOR_DAY'];
}
if (G::toUpper($formatDuration) == 'MINUTES') {
$duration = $duration / 60;
}
$hoursDuration = (float)$duration;
$newDate = $initialDate;
/**************SLA classes***************/
public function dashCalculateDate ($iniDate, $duration, $formatDuration, $calendarData = array())
{
if ( G::toUpper($formatDuration) == 'DAYS' ) {
$duration = $duration*$calendarData['HOURS_FOR_DAY'];
}
if ( G::toUpper($formatDuration) == 'MINUTES' ) {
$duration = $duration/60;
}
$hoursDuration = (float)$duration;
$newDate = $iniDate;
while ($hoursDuration > 0) {
$newDate = $this->dashGetIniDate($newDate, $calendarData);
$rangeWorkHour = $this->dashGetRangeWorkHours($newDate, $calendarData['BUSINESS_DAY']);
$onlyDate = (date('Y-m-d',strtotime($newDate))) . ' ' . $rangeWorkHour['END'];
if ( (((float)$hoursDuration) >= ((float)$rangeWorkHour['TOTAL'])) ||
((strtotime($onlyDate) - strtotime($newDate)) < (((float)$hoursDuration)*3600))
) {
$secondRes = (float)(strtotime($onlyDate) - strtotime($newDate));
$newDate = $onlyDate;
$hoursDuration -= (float)($secondRes/3600);
} else {
$newDate = date('Y-m-d H:i:s', strtotime('+' . round((((float)$hoursDuration)*3600), 5) . ' seconds', strtotime($newDate)));
$hoursDuration = 0;
}
}
return $newDate;
}
while ($hoursDuration > 0) {
$newDate = $this->dashGetIniDate($newDate, $calendarData);
$rangeWorkHour = $this->dashGetRangeWorkHours($newDate, $calendarData['BUSINESS_DAY']);
$onlyDate = (date('Y-m-d', strtotime($newDate))) . ' ' . $rangeWorkHour['END'];
$rangeWorkHourTotal = (float)$rangeWorkHour['TOTAL'];
if ($hoursDuration >= $rangeWorkHourTotal ||
((strtotime($onlyDate) - strtotime($newDate)) < (($hoursDuration) * 3600))
) {
$secondRes = (float)(strtotime($onlyDate) - strtotime($newDate));
$newDate = $onlyDate;
$hoursDuration -= (float)($secondRes / 3600);
} else {
$newDate = date('Y-m-d H:i:s', strtotime('+' . round((($hoursDuration) * 3600), 5) . ' seconds', strtotime($newDate)));
$hoursDuration = 0;
}
}
return $newDate;
}
//Calculate the duration betwen two dates with a calendar
public function dashCalculateDurationWithCalendar ($iniDate, $finDate = null, $calendarData = array())

File diff suppressed because it is too large Load Diff

View File

@@ -381,36 +381,39 @@ class Delegation extends Model
* Scope a query to get only the date on time
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $now
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeOnTime($query)
public function scopeOnTime($query, $now)
{
return $query->whereRaw('TIMEDIFF(DEL_RISK_DATE, NOW()) > 0');
return $query->where('DEL_RISK_DATE', '>', $now);
}
/**
* Scope a query to get only the date at risk
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $now
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeAtRisk($query)
public function scopeAtRisk($query, $now)
{
return $query->whereRaw('TIMEDIFF(DEL_RISK_DATE, NOW()) < 0 AND TIMEDIFF(DEL_TASK_DUE_DATE, NOW()) > 0');
return $query->where('DEL_RISK_DATE', '>=', $now)->where('DEL_TASK_DUE_DATE', '>=', $now);
}
/**
* Scope a query to get only the date overdue
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $now
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeOverdue($query)
public function scopeOverdue($query, $now)
{
return $query->whereRaw('TIMEDIFF(DEL_TASK_DUE_DATE, NOW()) < 0');
return $query->where('DEL_TASK_DUE_DATE', '>', $now);
}
/**