Kaynağa Gözat

Stat tree line reports

Vijayakrishnan 3 yıl önce
ebeveyn
işleme
a8e9356e5e

+ 91 - 12
app/Http/Controllers/StatTreeLineController.php

@@ -5,12 +5,14 @@ namespace App\Http\Controllers;
 
 use App\Models\Clause;
 use App\Models\StatTreeLineClause;
+use App\Models\StatTreeLineReportColumn;
 use Illuminate\Http\Request;
 use App\Models\StatTree;
 use App\Models\StatTreeLine;
 use App\Models\Client;
 use App\Models\Pro;
 use Illuminate\Pagination\LengthAwarePaginator;
+use Illuminate\Pagination\Paginator;
 use Illuminate\Support\Facades\DB;
 use Ramsey\Uuid\Uuid;
 
@@ -22,13 +24,44 @@ class StatTreeLineController extends Controller
         return view('app.stat-tree.stat-tree-line-reports.list', compact('statTreeLines'));
     }
 
-    public function editReport(StatTreeLine $statTreeLine) {
+    public function editReport(Request $request, StatTreeLine $statTreeLine) {
         $allClauses = Clause::orderByRaw('position_index ASC NULLS FIRST')->get();
         return view('app.stat-tree.stat-tree-line-reports.edit', compact('statTreeLine', 'allClauses'));
     }
 
-    public function viewReport(StatTreeLine $statTreeLine) {
-
+    public function viewReport(Request $request, StatTreeLine $statTreeLine) {
+        $total = 0;
+        $rows = [];
+        $columns = [];
+        $selectColumns = [];
+        $paginator = null;
+        $line = $statTreeLine;
+        foreach ($line->reportColumns as $reportColumn) {
+            $columns[] = [
+                "label" => $reportColumn->label,
+                "column" => $reportColumn->display_key,
+                "type" => $reportColumn->field_type,
+                "as" => "v_{$reportColumn->id}"
+            ];
+            $selectColumns[] = "{$reportColumn->display_key} as v_{$reportColumn->id}";
+        }
+        if(count($line->reportColumns)) {
+            $result = $this->queryStatTreeLineData($line, $selectColumns, $columns, $request);
+            if($result[0] === false) {
+                $total = 0;
+                $rows = [];
+                $paginator = new Paginator($rows, 20, 1);
+                $error = $result[1];
+            }
+            else {
+                $total = $result[0];
+                $rows = $result[1];
+                $paginator = new LengthAwarePaginator($rows, $total, $request->input('per_page') ?: 20, $request->input('page') ?: 1);
+                $paginator->setPath(route('practice-management.statTreeLines.view-data', compact('line')));
+                $error = '';
+            }
+        }
+        return view('app.stat-tree.stat-tree-line-reports.view-data', compact('line', 'total', 'rows', 'columns', 'paginator', 'error'));
     }
 
 
@@ -178,7 +211,7 @@ class StatTreeLineController extends Controller
     protected function queryStatTreeLineData(StatTreeLine $statTreeLine, $selectColumns, $columns, Request $request)
     {
 
-        $model = $statTreeLine->statTree->model;
+        $model = $statTreeLine->statTree ? $statTreeLine->statTree->model : $statTreeLine->model;
 
         $clauses = [];
         foreach ($statTreeLine->lineClauses as $lineClause) {
@@ -207,14 +240,16 @@ class StatTreeLineController extends Controller
         }
 
         // if stat tree bound to a pro, apply pro_scope_clause
-        if($request->input('proUid') && $statTreeLine->statTree->pro_scope_clause) {
-            $pro = Pro::where('uid', $request->input('proUid'))->first();
-            if($pro) {
-                $clauses[] = str_replace('@PRO_ID', $pro->id, $statTreeLine->statTree->pro_scope_clause);
+        if($statTreeLine->statTree) {
+            if($request->input('proUid') && $statTreeLine->statTree->pro_scope_clause) {
+                $pro = Pro::where('uid', $request->input('proUid'))->first();
+                if($pro) {
+                    $clauses[] = str_replace('@PRO_ID', $pro->id, $statTreeLine->statTree->pro_scope_clause);
+                }
+            }
+            elseif($statTreeLine->statTree->pro && $statTreeLine->statTree->pro_scope_clause) {
+                $clauses[] = str_replace('@PRO_ID', $statTreeLine->statTree->pro->id, $statTreeLine->statTree->pro_scope_clause);
             }
-        }
-        elseif($statTreeLine->statTree->pro && $statTreeLine->statTree->pro_scope_clause) {
-            $clauses[] = str_replace('@PRO_ID', $statTreeLine->statTree->pro->id, $statTreeLine->statTree->pro_scope_clause);
         }
 
         // filters from view-data UI
@@ -275,7 +310,7 @@ class StatTreeLineController extends Controller
             $result = [$total, $result];
         }
         catch (\Exception $ex) {
-            $result = 'error';
+            $result = [false, $ex->getMessage()];
         }
         return $result;
     }
@@ -425,4 +460,48 @@ class StatTreeLineController extends Controller
         DB::select("delete from stat_tree_line_clause where id = {$statTreeLineClause->id}");
         return $this->pass();
     }
+    public function addReportColumn(Request $request) {
+        $statTreeLine = StatTreeLine::where('uid', $request->input('uid'))->first();
+        if(!$statTreeLine) return $this->fail('Stat tree line not found!');
+        $column = new StatTreeLineReportColumn();
+        $nextId = DB::select("select nextval('stat_tree_line_report_column_id_seq')");
+        $column->id = $nextId[0]->nextval;
+        $column->uid = Uuid::uuid4();
+        $column->stat_tree_line_id = $statTreeLine->id;
+        $column->label = $request->input('label');
+        $column->display_key = $request->input('column');
+        $positionIndex = DB::select("select max(position_index) from stat_tree_line_report_column where stat_tree_line_id = {$column->stat_tree_line_id}");
+        $column->position_index = is_numeric($positionIndex[0]->max) ? $positionIndex[0]->max + 1 : 1;
+        $column->field_type = $request->input('fieldType');
+        $column->save();
+        return $this->pass();
+    }
+    public function updateReportColumn(Request $request) {
+        $column = StatTreeLineReportColumn::where('uid', $request->input('uid'))->first();
+        if(!$column) return $this->fail('Stat tree line report column not found!');
+        $column->label = $request->input('label');
+        $column->display_key = $request->input('column');
+        $column->field_type = $request->input('fieldType');
+        $column->save();
+        return $this->pass();
+    }
+    public function removeReportColumn(Request $request) {
+        $column = StatTreeLineReportColumn::where('uid', $request->input('uid'))->first();
+        if(!$column) return $this->fail('Stat tree line report column not found!');
+        DB::select("delete from stat_tree_line_report_column where id = {$column->id}");
+        return $this->pass();
+    }
+    public function reorderReportColumns(Request $request) {
+        $uids = json_decode($request->input('uids'));
+        $position = 1;
+        for ($i = 0; $i < count($uids); $i++) {
+            $column = StatTreeLineReportColumn::where('uid', $uids[$i])->first();
+            if($column) {
+                $column->position_index = $position;
+                $column->save();
+                $position++;
+            }
+        }
+        return $this->pass();
+    }
 }

+ 6 - 0
public/css/style.css

@@ -3018,3 +3018,9 @@ body .vakata-context .vakata-context-separator>a {
     border: 1px solid #ddd;
     padding: 10px;
 }
+.table-columns tr:first-child .move-up {
+    display: none;
+}
+.table-columns tr:last-child .move-down {
+    display: none;
+}

+ 130 - 4
resources/views/app/stat-tree/stat-tree-line-reports/edit.blade.php

@@ -19,9 +19,14 @@
                 </div>
             </form>
         </div>
+        <a native class="ml-3 btn btn-sm btn-info text-white font-weight-bold" href="{{route('practice-management.statTreeLineReports.view', ['statTreeLine' => $statTreeLine])}}"
+           open-in-stag-popup
+           popup-style="medium"
+           title="View Data"
+        >View Data</a>
     </div>
     <div class="row mx-0 flex-grow-1">
-        <div class="col-5 px-0 border-right">
+        <div class="col-6 px-0 border-right">
             <div class="p-3 border-bottom">
                 <div class="d-flex align-items-baseline">
                     <span class="font-weight-bold text-secondary">Model</span>
@@ -108,7 +113,7 @@
                             <td class="text-monospace">{{$lineClause->clause->clause_text}}</td>
                             <td class="width-100px">
                                 <div moe>
-                                    <a start show href="#" class="text-danger on-hover-opaque">Remove</a>
+                                    <a start show href="#" class="text-danger">Remove</a>
                                     <form url="{{ route("practice-management.api.statTreeLineReport.removeClause") }}">
                                         @csrf
                                         <input type="hidden" name="uid" value="{{$lineClause->uid}}">
@@ -126,18 +131,122 @@
                 @endif
             </div>
         </div>
-        <div class="col-7 px-0">
+        <div class="col-6 px-0">
             <div class="p-3">
                 <div class="d-flex align-items-baseline">
                     <span class="font-weight-bold text-secondary mr-3">Report columns</span>
-                    <a>Add New</a>
+                    <div moe wide>
+                        <a href="#" start show>Add New</a>
+                        <form url="{{ route("practice-management.api.statTreeLineReport.addReportColumn") }}">
+                            @csrf
+                            <input type="hidden" name="uid" value="{{$statTreeLine->uid}}">
+                            <div class="mb-2">
+                                <label class="text-secondary text-sm mb-1">Label *</label>
+                                <input type="text" class="form-control form-control-sm" name="label" required>
+                            </div>
+                            <div class="mb-2">
+                                <label class="text-secondary text-sm mb-1">Column *</label>
+                                <input type="text" class="form-control form-control-sm" name="column" required>
+                            </div>
+                            <div class="mb-2">
+                                <label class="text-secondary text-sm mb-1">Field Type *</label>
+                                <select class="form-control form-control-sm" name="fieldType" required>
+                                    <option value="">-- select --</option>
+                                    <option value="numeric">Number</option>
+                                    <option value="date">Date</option>
+                                    <option value="text">String</option>
+                                    <option value="bool">Boolean</option>
+                                </select>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <button class="btn btn-sm btn-primary mr-2" type="button" submit>Save</button>
+                                <button class="btn btn-sm btn-default mr-2 border" type="button" cancel>Cancel</button>
+                            </div>
+                        </form>
+                    </div>
                 </div>
+                @if(count($statTreeLine->reportColumns))
+                    <table class="table table-sm table-bordered mt-2 table-columns">
+                        @foreach($statTreeLine->reportColumns as $reportColumn)
+                            <tr data-uid="{{$reportColumn->uid}}">
+                                <td class="width-30px">{{$reportColumn->position_index}}</td>
+                                <td class="text-nowrap text-info font-weight-bold">{{$reportColumn->label}}</td>
+                                <td class="text-monospace">{{$reportColumn->display_key}}</td>
+                                <td class="text-monospace">{{$reportColumn->field_type}}</td>
+                                <td class="width-100px text-nowrap">
+                                    <div class="d-flex align-items-baseline">
+                                        <div moe relative>
+                                            <a start show href="#">Edit</a>
+                                            <form url="{{ route("practice-management.api.statTreeLineReport.updateReportColumn") }}" right>
+                                                @csrf
+                                                <input type="hidden" name="uid" value="{{$reportColumn->uid}}">
+                                                <div class="mb-2">
+                                                    <label class="text-secondary text-sm mb-1">Label *</label>
+                                                    <input type="text" class="form-control form-control-sm" name="label" value="{{$reportColumn->label}}" required>
+                                                </div>
+                                                <div class="mb-2">
+                                                    <label class="text-secondary text-sm mb-1">Column *</label>
+                                                    <input type="text" class="form-control form-control-sm" name="column" value="{{$reportColumn->display_key}}" required>
+                                                </div>
+                                                <div class="mb-2">
+                                                    <label class="text-secondary text-sm mb-1">Field Type *</label>
+                                                    <select class="form-control form-control-sm" name="fieldType" required>
+                                                        <option value="">-- select --</option>
+                                                        <option {{$reportColumn->field_type === 'numeric' ? 'selected' : ''}} value="numeric">Number</option>
+                                                        <option {{$reportColumn->field_type === 'date' ? 'selected' : ''}} value="date">Date</option>
+                                                        <option {{$reportColumn->field_type === 'text' ? 'selected' : ''}} value="text">String</option>
+                                                        <option {{$reportColumn->field_type === 'bool' ? 'selected' : ''}} value="bool">Boolean</option>
+                                                    </select>
+                                                </div>
+                                                <div class="d-flex align-items-center">
+                                                    <button class="btn btn-sm btn-primary mr-2" submit>Save</button>
+                                                    <button class="btn btn-sm btn-default mr-2 border" cancel>Cancel</button>
+                                                </div>
+                                            </form>
+                                        </div>
+                                        <div moe relative class="ml-2 mr-2">
+                                            <a start show href="#" class="text-danger">Remove</a>
+                                            <form url="{{ route("practice-management.api.statTreeLineReport.removeReportColumn") }}" right>
+                                                @csrf
+                                                <input type="hidden" name="uid" value="{{$reportColumn->uid}}">
+                                                <p class="mb-2 text-nowrap">Are you sure?</p>
+                                                <div class="d-flex align-items-center">
+                                                    <button class="btn btn-sm btn-primary mr-2" submit>Save</button>
+                                                    <button class="btn btn-sm btn-default mr-2 border" cancel>Cancel</button>
+                                                </div>
+                                            </form>
+                                        </div>
+                                        <a href="#" class="move-up mr-2"><i class="fa fa-arrow-up"></i></a>
+                                        <a href="#" class="move-down mr-2"><i class="fa fa-arrow-down"></i></a>
+                                    </div>
+                                </td>
+                            </tr>
+                        @endforeach
+                    </table>
+                @endif
             </div>
         </div>
     </div>
 </div>
 <script>
     (function() {
+        function saveColumnOrder() {
+            let uids = [];
+            $('.table-columns tr').each(function() {
+                uids.push($(this).attr('data-uid'));
+            });
+            if(uids.length > 1) {
+                showMask();
+                $.post('{{route("practice-management.api.statTreeLineReport.reorderReportColumns")}}', {
+                    _token: '{{csrf_token()}}',
+                    uids: JSON.stringify(uids)
+                }, _data => {
+                    if(!hasResponseError(_data)) {
+                        fastReload();
+                    }
+                }, 'json').then(hideMask());
+            }
+        }
         function init() {
             $(document)
                 .off('input change paste', '.frm-clause-add-edit input[name="question"], .frm-clause-add-edit input[name="answer"]')
@@ -147,6 +256,23 @@
                         $.trim(form.find('input[name="answer"]').val());
                     form.find('input[name="label"]').val(label);
                 });
+            $(document)
+                .off('click.move-up', '.table-columns .move-up')
+                .on('click.move-up', '.table-columns .move-up', function() {
+                    let tr = $(this).closest('tr');
+                    tr.insertBefore(tr.prev());
+                    saveColumnOrder();
+                    return false;
+                });
+            $(document)
+                .off('click.move-down', '.table-columns .move-down')
+                .on('click.move-down', '.table-columns .move-down', function() {
+                    let uids = [];
+                    let tr = $(this).closest('tr');
+                    tr.insertAfter(tr.next());
+                    saveColumnOrder();
+                    return false;
+                });
         }
         addMCInitializer('stat-tree-line-report-edit-{{$statTreeLine->uid}}', init, '#stat-tree-line-report-edit-{{$statTreeLine->uid}}');
     }).call(window);

+ 5 - 4
resources/views/app/stat-tree/stat-tree-line-reports/view-data.blade.php

@@ -1,8 +1,9 @@
 <div class="mcp-theme-1 popup-content-container p-3">
-    @if(@$rows === 'error')
-        <div class="text-secondary">
-            <i class="fa fa-exclamation-triangle"></i>
-            Query error / missing arg values!
+    @if(@$error || @$rows === 'error')
+        <div class="text-secondary d-flex align-items-baseline">
+            <i class="fa fa-exclamation-triangle text-danger"></i>
+            <p class="ml-2 my-0 font-weight-bold text-nowrap text-danger">Query Error:</p>
+            @if(@$error) <span class="text-monospace ml-2">{{ $error }}</span> @endif
         </div>
     @else
         @if(!count($columns))

+ 4 - 1
routes/web.php

@@ -419,7 +419,10 @@ Route::middleware('pro.auth')->group(function () {
                 Route::post('addExistingClause', 'StatTreeLineController@addExistingClause')->name('addExistingClause');
                 Route::post('addNewClause', 'StatTreeLineController@addNewClause')->name('addNewClause');
                 Route::post('removeClause', 'StatTreeLineController@removeClause')->name('removeClause');
-
+                Route::post('addReportColumn', 'StatTreeLineController@addReportColumn')->name('addReportColumn');
+                Route::post('updateReportColumn', 'StatTreeLineController@updateReportColumn')->name('updateReportColumn');
+                Route::post('removeReportColumn', 'StatTreeLineController@removeReportColumn')->name('removeReportColumn');
+                Route::post('reorderReportColumns', 'StatTreeLineController@reorderReportColumns')->name('reorderReportColumns');
             });
         });