How can I get the value from method in my model? - view

I have some trouble displaying my result from a method in my model. this is the method:
/**
* #return \yii\db\ActiveQuery
*/
public function getSchoolFee()
{
return $this->hasOne(SibuSchool::className(), ['school_fee_id' => 'school_fee_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getScholarshipFee()
{
return $this->hasOne(SibuScholarship::className(),['scholarship_id'=>'scholarship_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getDiscountFee()
{
$scholarship= $this->getScholarshipFee();
$school= $this->getSchoolFee();
$data= new SibuPayment();
$data->total_payment=$school->amount-($scholarship->school_discount*$school->amount);
return $data;
}
i want to display the result from getDiscountFee method. I use this code on my View:
<?php echo $this->render('_search3', ['model' => $searchModel]); ?>
<?=
GridView::widget([
'dataProvider' => $dataProvider,
// 'filterModel' => $searchModel,
'columns' => [
[
// 'filterModel'=>'dataProviderSearch',
'attribute' => 'Nama',
'value' => 'virtual.student_name'
],
[
'attribute' => 'Uang Sekolah',
'value' => 'discountFee.total_payment'
],
[
'attribute' => 'Uang Kantin',
'value' => 'canteenFee.total_amount'
],
[
'attribute' => 'Uang Asrama',
'value' => 'dormitoryFee.amount'
],
[
'attribute' => 'Uang Perpustakaan',
'value' => 'libraryFee.amount'
],
[
'attribute' => 'Uang Les',
'value' => 'courseFee.amount'
],
[
'attribute' => 'Adm. Bank',
'value' => 'administration'
],
[
'attribute' => 'status',
'value' => function ($model) {
if ($model->scholarship_id == 0) {
return 'Tanpa Beasiswa';
} else if ($model->scholarship_id == 1) {
return 'Beasiswa Ekonomi Kategori A 100%';
} else if ($model->scholarship_id == 2) {
return 'Beasiswa Ekonomi Kategori B 50%';
} else if ($model->scholarship_id == 3) {
return 'Beasiswa Prestasi Kategori 50%';
} else if ($model->scholarship_id == 4) {
return 'Beasiswa Prestasi Kategori 25%';
} else {
return 'Beasiswa Prestasi Kategori 10%';
}
},
],
//'payment_class',
[
'attribute' => 'payment_class',
'value' => function ($model) {
if ($model->payment_class == 0) {
return 'Tanpa Golongan';
} else if ($model->payment_class == 1) {
return 'Golongan 1';
} else if ($model->payment_class == 2) {
return 'Golongan 2';
} else if ($model->payment_class == 3) {
return 'Golongan 3';
} else if ($model->payment_class == 4) {
return 'Golongan 4';
}
},
],
[
'attribute' => 'Total',
'value' => 'total_payment'
],
['class' => 'yii\grid\ActionColumn',
'template' => '{update_r}{del}',
'buttons' => [
'update_r' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => Yii::t('yii', 'View_r'),
]);
},
'del' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('yii', 'Del'),
]);
},
]
],
],
]);
?>
it works fine if i display this:
[
'attribute' => 'Uang Sekolah',
'value' => 'scholarshipFee.school_discount'
],
and this:
[
'attribute' => 'Uang Sekolah',
'value' => 'schoolFee.amount'
],
can anybody help me? if you need anything feel free to ask.

[
'attribute' => 'Uang Sekolah',
'value' => 'discountFee.total_payment'
],
discountFee is a function of a model, it will never work until you put there the model too. You can just do a
[
'attribute' => 'Uang Sekolah',
'value' => function ($model) {
return $model->getDiscountFee()->total_payment;
}
},
],

Related

How to override the select2 action that disables subfield options selected in a previous subfield in Backpack for Laravel?

Controller (field definition):
$this->crud->addField([
'name' => 'precios',
'type' => "relationship",
'pivotSelect' => [
'ajax' => true,
'inline_create' => [ 'entity' => 'precio' ],
'data_source' => backpack_url('presupuesto/fetch/precio'),
'minimum_input_length' => 0,
'wrapper' => [
'class' => 'col-md-3 order-2'
],
'attributes' => [
'required' => 'required',
],
'dependencies' => ['categoria_precio_id']
],
'subfields' => [
[
'name' => 'categoria_precio_id',
'type' => 'relationship',
'label' => 'Categoría',
'wrapper' => [
'class' => 'form-group col-md-2 order-1',
],
'dependencies' => ['tipo'],
'ajax' => true,
'data_source' => backpack_url('presupuesto/fetch/categoria-precio'),
'minimum_input_length' => 0
],
[
'name' => 'costo',
'type' => 'text',
'label' => 'Costo Unitario',
'wrapper' => [
'class' => 'form-group col-md-1 order-3',
],
],
[
'name' => 'cantidad',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-md-1 order-4',
],
],
[
'name' => 'duracion',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-md-2 order-5',
]
],
[
'name' => 'costo_final',
'type' => 'text',
'label' => 'Costo',
'wrapper' => [
'class' => 'form-group col-md-1 order-6 costo_final',
],
'attributes' => array('readonly' => 'readonly', 'disabled' => 'disabled')
],
],
'tab' => "Precios",
'force_delete' => true]);
My Form capture
When I tried to select an option that I selected previously it does not allow me. For example, in the image "animación 2d" (ID:82).
First I have in my table "precio_presupuesto"
precio_id (PK)
presupuesto_id (PK)
costo
...
created_at
updated_at
And I change that for:
id (PK)
precio_id (FK)
presupuest_id (FK)
costo
...
created_at
updated_at
In my model I had:
public function precios()
{
return $this->belongsToMany(\App\Models\Precio::class)->withPivot('costo', 'cantidad', 'duracion', 'categoria_precio_id', 'costo_final')->withTimestamps();
}
And I change that for:
public function precios()
{
return $this->belongsToMany(\App\Models\Precio::class,'precio_presupuesto', 'presupuesto_id','precio_id', 'id')->withPivot('costo', 'cantidad', 'duracion', 'categoria_precio_id', 'costo_final')->withTimestamps();
}
I'm new to Laravel and Backpack, but I think my definition is fine, I just don't know how to tell Backpack to allow adding two elements with repeated "price_id" and "presupuesto_id", this because there will be cases where you can change the "cantidad" field or the "costo" field for the same combination (precio_id, presupuesto_id).
In other words I just want the "Select2" subfields not to disable previously selected options.
My model
I have tried changing the definition of my models again. Create a class for the pivot table following the documentation and example of:
doc
example
Presupuesto Model
class Presupuesto extends Model implements Auditable{
public function precio_presupuesto(){
return $this->hasMany(PrecioPresupuesto::class, 'presupuesto_id');
}
public function precios(){
return $this->belongsToMany(\App\Models\Precio::class)->using(\App\Models\PrecioPresupuesto::class)->
withPivot('costo', 'cantidad', 'duracion', 'categoria_precio_id', 'costo_final')->withTimestamps();
}
}
Precio Model:
class Precio extends Model{
public function precio_presupuesto()
{
return $this->hasMany(PrecioPresupuesto::class, 'precio_id');
}
public function presupuestos()
{
// return $this->belongsToMany(\App\Models\Presupuesto::class);
return $this->belongsToMany(\App\Models\Presupuesto::class)->using(\App\Models\PrecioPresupuesto::class)->
withPivot('costo', 'cantidad', 'duracion', 'categoria_precio_id', 'costo_final')->withTimestamps();
}}
Pivot Model:
class PrecioPresupuesto extends Pivot{
public function presupuesto(){
return $this->belongsTo(Presupuesto::class, 'presupuesto_id');
}
public function precio(){
return $this->belongsTo(Precio::class, 'precio_id');
}}
Does Backpack allow me to save several pairs of elements like in the image pivot table precio_presupuesto? what is what I need? because it currently does not allow me.

Display Each Column sum on footer Yajra Laravel

The following screenshot shows the list of database results by enabling server-side processing. It shows the column total computed by using the Yajra DataTables.
HTML Code for DataTables with Column Total
To display the footer using html builder, pass true as 2nd argument on $builder->table([], true) api.
{!! $dataTable->table([], true) !!}
script
update th values
#push('scripts')
{!! $dataTable->scripts() !!}
<script>
var hours = JSON.parse("{{json_encode($hours)}}");
$(document).ready(function(){
$("tfoot tr>th:nth-child(2)").text("Total")
for (let i = 0; i < hours.length; i++) {
$('tfoot tr>th:nth-child('+ (i+3) +')').text(hours[i])
}
})
</script>
#endpush
Report Datatable File
In Query function we are getting reports record from database and use query result in dataTable function make column according to our requirement and finally set values to getColumns function.
public function dataTable($query)
{
$reports = ($query['data']);
return datatables()->make($reports)
->addColumn('name', function ($reports) {
return isset($reports['user_name']) ? $reports['user_name'] : null;
})
->addColumn('monday', function ($reports) {
return isset($reports['Mon']) ? ($reports['Mon']) : '-';
})
->addColumn('tuesday', function ($reports) {
return isset($reports['Tue']) ? $reports['Tue'] : '-';
})
->addColumn('wednesday', function ($reports) {
return isset($reports['Wed']) ? $reports['Wed'] : '-';
})
->addColumn('thursday', function ($reports) {
return isset($reports['Thu']) ? $reports['Thu'] : '-';
})
->addColumn('friday', function ($reports) {
return isset($reports['Fri']) ? $reports['Fri'] : '-';
})
->addColumn('total', function ($reports) {
return (isset($reports['Mon']) ? $reports['Mon'] : 0) +
(isset($reports['Tue']) ? $reports['Tue'] : 0) +
(isset($reports['Wed']) ? $reports['Wed'] : 0) +
(isset($reports['Thu']) ? $reports['Thu'] : 0) +
(isset($reports['Fri']) ? $reports['Fri'] : 0);
})
->addIndexColumn();
}
public function query(Lot $model)
{
$data = Reports.....;
return compact('data');
}
public function html()
{
return $this->builder()
->setTableId('userrequestdatatable-table')
->columns($this->getColumns())
->minifiedAjax()
->dom('Bfrtip')
->orderBy(1)
->buttons(
Button::make('export'),
);
}
protected function getColumns()
{
return [
'#' => [
'data' => 'DT_RowIndex',
'name' => 'DT_RowIndex',
'orderable' => false,
'searchable' => false
],
'user name'=> [
'data' => 'name',
'name' => 'name',
],
'monday'=> [
'data' => 'monday',
'name' => 'monday',
],
'tuesday'=> [
'data' => 'tuesday',
'name' => 'tuesday',
],
'wednesday'=> [
'data' => 'wednesday',
'name' => 'wednesday',
],
'thursday'=> [
'data' => 'thursday',
'name' => 'thursday',
],
'friday'=> [
'data' => 'friday',
'name' => 'friday',
],
'total'=> [
'data' => 'total',
'name' => 'total',
]
];
}

Laravel: How to access Object inside an array

I trying to return access the attributes inside a array of object and it is giving this error Exception: Property [id] does not exist on this collection instance.
Here is what I have tried:
protected function formatted($classroom)
{
return [
'courses' => [
'id' => $classroom->courses->id,
'name' => $classroom->courses->name,
'slug' => $classroom->courses->slug,
'coursteachers' => [
'id' => '$classroom->courses->coursteachers->id',
'email' => '$classroom->courses->coursteachers->email',
'uid' => '$classroom->courses->coursteachers->uid',
]
],
];
}
And here is the actual data:
"courses": [
{
"id": 1,
"name": "Analytics",
"slug": "analytics",
"status_id": 1,
"deleted_at": null,
"pivot": {
"classroom_id": 2,
"courses_id": 1
},
"coursteachers": [
{
"id": 3,
"uid": "S0120-46890",
"email": "teacher#vschool.com",
"user_type": "Teacher",
}]
}]
You need to iterate through courses and also courseteachers since they both represent an array but rather an object
protected function formatted($classroom)
{
$result = [];
foreach($classroom->courses as $course) {
$result[] = [
'courses' => [
'id' => $classroom->courses->id,
'name' => $classroom->courses->name,
'slug' => $classroom->courses->slug,
'coursteachers' => $this->getCourseTeachers($cours)
],
];
}
return $result;
}
private function getClassroomTeachers($classroom) {
$result = [];
foreach($classroom->courses as $cours)
{
foreach ($cours->coursteachers as $key => $teacher) {
$result[] = [
// 'coursteachers'=> [
'id' => $teacher->id,
'email' => $teacher->email,
'uid' => $teacher->uid,
'last_name' => $teacher->profile->last_name,
'first_name' => $teacher->profile->first_name,
'middle_name' => $teacher->profile->middle_name,
// ],
];
}
}
return $result;
}
Since courses is an array, you should pick an object using the proper index.
Foe example: try $classroom->courses[0]->id instead of $classroom->courses->id. Here, '0' is the index.
Also it is better if you check if the index exists before you do it. For an example.
'id' : isset($classroom->courses[$index]) ? $classroom->courses[$index]->id : ''
Edit:
In case of a Eloquent collection you should use $classroom->courses->get($index)->id instead of array like retrieval.

Search in Laravel Datatables

In my datatables, the search function works only on the name column. The name column ist different that the others. It means, the name column gives the value of the database back, while the others gives a value back with the function add column
In the column array there are the following values:
´´´
protected function getColumns()
{
return [
'status',
'name' => [
'title' => 'Name',
'orderable' => true,
'searchable' => true
],
'location' => [
'title' => 'Standort',
],
'department' => [
'title' => 'Abteilung',
'orderable' => true,
'searchable' => true
],
'division' => [
'title' => 'Bereich',
'orderable' => true,
'searchable' => true
],
'leader' => [
'title' => 'Verantwortlicher',
'orderable' => true,
'searchable' => true
],
'start_date' => [
'title' => 'Startdatum',
'searchable'=> true,
],
'end_date' => [
'title' => 'Enddatum',
'searchable'=> true
]
];
}
```
Why it doesn't search on all columns? What i have to do?
Try to search by using this code.
return Datatables::of($tasks)
->filter(function ($query) use ($request) {
$title = $request->title;
if (isset($title) && !empty($title)) {
$query->where('title', 'like', '%'.$title.'%');
}
})->make(true);
OR
return Datatables::of($tasks)
->filterColumn('title', function($query, $value) {
$query->whereRaw("title like ?", ["%{$value}%"]);
})->make(true);

yii2 pjax gridview issue

I am using gridview with pjax in yii2 advanced. When i add/update/delete any record the pjax loads the very first html of page. For example, i have 10 records after deleting a record there should be 9 records, but it still loads 10 records and this continues even if you have deleted all the records. Same goes for add and update as well.
But if i hit F5 then it loads the actual records fetched from the database table and if i do any of the actions again then it again shows 10 records.
Here is the Gridview code with Pjax
$this->registerJs("$('.js-delete').on('click', function(e) {
ajax_actions(this, true, {
'pjax_container': '#products-grid'
});
return false;
});");
Pjax::begin([
"id" => "products-grid",
"enablePushState" => false
]);
echo GridView::widget([
'dataProvider' => $dataProvider,
"summary" => '',
"rowOptions" => function($model) {
if($model->status == Common::STATUS_INACTIVE)
{
return ["class" => "inactive"];
}
},
'columns' => [
[
"class" => 'yii\grid\SerialColumn',
"headerOptions" => [
"class" => 'hidden-480'
],
"contentOptions" => [
"class" => 'hidden-480'
]
], [
"attribute" => "title",
"label" => "Product"
], [
"attribute" => "companies_id",
"label" => "Companies",
"value" => "companies.title"
], [
"attribute" => "product_types_id",
"header" => "Category",
"value" => "productTypes.title"
], [
"attribute" => "part_number",
"header" => "<span class=\"hidden-360\">Part </span>Number"
], [
"attribute" => "created_on",
"label" => "Added On",
"format" => ["date", "php:" . Common::DATETIME_FORMAT_DISPLAY],
"headerOptions" => [
"class" => 'textRight hidden-360'
],
"contentOptions" => [
"class" => 'textRight hidden-360'
]
], [
"class" => 'yii\grid\ActionColumn',
"header" => "Actions",
"headerOptions" => [
"class" => "textRight actions"
],
"contentOptions" => [
"class" => "textRight actions"
],
"template" => "{view} {edit} {delete}",
"buttons" => [
'view' => function($url, $model) {
return Html::a('<i class="' . Common::ICON_VIEW . '"></i> <span class="hidden-640">View</span>', ['view', 'token' => $model->token], ["class" => "call-ajax"]);
},
'edit' => function($url, $model) {
return Html::a('<i class="' . Common::ICON_EDIT . '"></i> <span class="hidden-640">Edit</span>', ['update', 'token' => $model->token], ["class" => "call-ajax"]);
},
'delete' => function($url, $model) {
return Html::a('<i class="' . Common::ICON_DELETE . '"></i> <span class="hidden-640">Delete</span>', ['delete', 'token' => $model->token], [
'class' => 'js-delete'
]);
}
]
]
]
]);
Pjax::end();
functions
function ajax_submit(element, pjax_container)
{
var form = $(element);
if(form.find('.has-error').length) return false;
$.post(form.attr('action'),form.serialize()).done(function(result){
var result = JSON.parse(result);
if(result.type=='error')
{
result.container = '.error-container';
messages(result)
}
else
{
if(pjax_container) $.pjax.reload({container: pjax_container});
$('.overlay').click();
result.container = '.message-container';
messages(result);
}
});
return false;
}
function ajax_actions(element, ask_me, params)
{
if(ask_me == true && ask() == false)
{
return false;
}
var $this = $(element);
var $params = {
callBacks: {
beforeSendAfter: function() {},
completeAfter: function() {}
}
};
if(params != undefined) $.extend(true, $params, params);
$.ajax({
type: 'POST',
url: $this.attr("href"),
cache: false,
beforeSend: function() {
if($params.callBacks.beforeSendAfter != undefined && $.isFunction($params.callBacks.beforeSendAfter)) $params.callBacks.beforeSendAfter();
},
success: function(response) {},
complete: function(response) {
var result = $.parseJSON(JSON.parse(response.responseText));
if(result.type=='error')
{
result.container = '.error-container';
messages(result)
}
else
{
result.container = '.message-container';
$('.overlay').click();
$.pjax.reload({container: $params.pjax_container});
messages(result);
}
if($params.callBacks.completeAfter != undefined && $.isFunction($params.callBacks.completeAfter)) $params.callBacks.completeAfter();
}
})
return false;
}

Resources