change in cost calculation

This commit is contained in:
2025-08-15 18:01:35 +05:45
parent 5e0913b9f9
commit 6d6d1c9a8a
9 changed files with 2549 additions and 2877 deletions

View File

@@ -25,24 +25,77 @@ class CostCalculatorController extends Controller
$this->costCalculatorService = $costCalculatorService;
}
public function formatCostForStayType(CostCalculator $cost, string $stayTypeTitle)
{
$living = optional($cost->stayTypeLiving->firstWhere('title', $stayTypeTitle))->pivot;
$accomodation = optional($cost->stayTypeAccomodation->firstWhere('title', $stayTypeTitle))->pivot;
$onetime = optional($cost->stayTypeOnetime->firstWhere('title', $stayTypeTitle))->pivot;
$service = optional($cost->stayTypeService->firstWhere('title', $stayTypeTitle))->pivot;
$html = "<div style='font-size: 12px; line-height: 1.4;'>";
if ($living) {
$html .= "<div style='margin-bottom: 6px;'>
<span style='background:#e3f2fd; padding:2px 4px; border-radius:4px; font-weight:600;'>Living</span>
<b>{$living->monthly}</b> <i>/mo</i> | <b>{$living->yearly}</b> <i>/yr</i>
</div>";
}
if ($accomodation) {
$html .= "<div style='margin-bottom: 6px;'>
<span style='background:#fff3e0; padding:2px 4px; border-radius:4px; font-weight:600;'>Accommodation</span>
<b>{$accomodation->monthly}</b> <i>/mo</i> | <b>{$accomodation->yearly}</b> <i>/yr</i>
</div>";
}
if ($onetime) {
$html .= "<div style='margin-bottom: 6px;'>
<span style='background:#e8f5e9; padding:2px 4px; border-radius:4px; font-weight:600;'>One-time</span>
Visa: <b>{$onetime->visa}</b>, Bio: <b>{$onetime->biometrics}</b>,
Sevis: <b>{$onetime->sevis}</b>, App: <b>{$onetime->application}</b>
</div>";
}
if ($service) {
$html .= "<div style='margin-bottom: 6px;'>
<span style='background:#f3e5f5; padding:2px 4px; border-radius:4px; font-weight:600;'>Service</span>
Ticket: <b>{$service->flight_ticket}</b>, Ins: <b>{$service->insurance}</b>,
Extra: <b>{$service->extra}</b>
</div>";
}
$html .= "</div>";
return trim($html) ?: '-';
}
public function index(Request $request)
{
// $data['title'] = 'Cost Calculator List';
// $data['costs'] = $this->costCalculatorService->findAll($request);
// $data['countryOptions'] = Country::where('status', 1)->pluck('title', 'id');
// $data['programLevelOptions'] = ProgramLevel::where('status', 1)->pluck('title', 'id');
// $data['programOptions'] = Program::where('status', 1)->pluck('title', 'id');
// $data['livingStatusOptions'] = config('constants.living_status');
if ($request->ajax()) {
$model = CostCalculator::with([
'country',
'stayTypeLiving',
'stayTypeAccomodation',
'stayTypeOnetime',
'stayTypeService'
]);
// return view('costcalculator::cost.index', $data);
if (request()->ajax()) {
$model = CostCalculator::query()->orderBy('order');
return DataTables::eloquent($model)
->addIndexColumn()
->setRowClass('tableRow')
->editColumn('image', function (CostCalculator $cost) {
return $cost->getRawOriginal('image') ? "<img src='{$cost->country->image}' alt='{$cost->country->image}' class='rounded avatar-sm material-shadow ms-2 img-thumbnail'>" : '-';
->editColumn('country', function (CostCalculator $cost) {
return "<div class='d-flex align-items-start'>
<div class='flex-grow-1'>
<p class='mb-0 fs-14'>{$cost->country?->title}</p>
</div>
</div>";
})
->editColumn('alone', function (CostCalculator $cost) {
return $this->formatCostForStayType($cost, 'Alone');
})
->editColumn('with_spouse', function (CostCalculator $cost) {
return $this->formatCostForStayType($cost, 'With Spouse');
})
->editColumn('with_spouse_and_child', function (CostCalculator $cost) {
return $this->formatCostForStayType($cost, 'With Spouse and Child');
})
->editColumn('status', function (CostCalculator $cost) {
$status = $cost->status ? 'Published' : 'Draft';
@@ -50,25 +103,23 @@ class CostCalculatorController extends Controller
return "<p class='{$color}'>{$status}</p>";
})
->addColumn('action', 'costcalculator::cost.datatable.action')
->rawColumns(['image', 'status', 'action'])
->rawColumns(['country', 'alone', 'with_spouse', 'with_spouse_and_child', 'status', 'action'])
->toJson();
}
return view('costcalculator::cost.index', [
'title' => 'Cost Calculator List',
'title' => 'Estimated Cost Calculation',
]);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
$data['title'] = 'Create Cost Calculator';
$data['title'] = 'Create Estimated Cost Calculation';
$data['editable'] = false;
$data['countryOptions'] = Country::where('status', 1)->where('parent_id', null)->pluck('title', 'id');
$data['programLevelOptions'] = ProgramLevel::where('status', 1)->pluck('title', 'id');
$data['programOptions'] = Program::where('status', 1)->pluck('title', 'id');
$data['livingStatusOptions'] = StayType::where('status', 1)->pluck('title', 'id');
return view('costcalculator::cost.create', $data);
@@ -81,7 +132,6 @@ class CostCalculatorController extends Controller
{
$request->validate([
'country_id' => 'required',
'programlevel_id' => 'required',
]);
$input = $request->except(['living_cost', 'accomodation_cost', 'onetime_cost', 'service_cost']);
@@ -110,7 +160,7 @@ class CostCalculatorController extends Controller
}
foreach ($request->onetime_cost as $item) {
$attachLivingData[$item['stay_type_id']] = [
$attachOnetimeData[$item['stay_type_id']] = [
'visa' => $item['visa'],
'biometrics' => $item['biometrics'],
'sevis' => $item['sevis'],
@@ -119,7 +169,7 @@ class CostCalculatorController extends Controller
}
foreach ($request->service_cost as $item) {
$attachLivingData[$item['stay_type_id']] = [
$attachServiceData[$item['stay_type_id']] = [
'flight_ticket' => $item['flight_ticket'],
'insurance' => $item['insurance'],
'extra' => $item['extra'],
@@ -134,7 +184,7 @@ class CostCalculatorController extends Controller
flash()->success('Cost Calculation has been created!');
});
return redirect()->route('costCalculator.index');
return redirect()->route('cost.index');
}
/**
@@ -153,13 +203,11 @@ class CostCalculatorController extends Controller
*/
public function edit($id)
{
$data['title'] = 'Edit Cost Calculator';
$data['title'] = 'Edit Cost Calculator';
$data['editable'] = true;
$data['cost'] = CostCalculator::findOrFail($id);
$data['countryOptions'] = Country::where('status', 1)->pluck('title', 'id');
$data['programLevelOptions'] = ProgramLevel::where('status', 1)->pluck('title', 'id');
$data['programOptions'] = Program::where('status', 1)->pluck('title', 'id');
$data['livingStatusOptions'] = config('constants.living_status');
$data['countryOptions'] = Country::where('status', 1)->where('parent_id', null)->pluck('title', 'id');
$data['livingStatusOptions'] = StayType::where('status', 1)->pluck('title', 'id');
return view('costcalculator::cost.edit', $data);
}
@@ -174,10 +222,10 @@ class CostCalculatorController extends Controller
$program = CostCalculator::findOrFail($id);
$program->update($input);
flash()->success('Cost Calculation has been updated!');
flash()->success('Cost Calculation has been updated!');
});
return redirect()->route('costCalculator.index')->withSuccess('Program has been updated!');
return redirect()->route('cost.index')->withSuccess('Program has been updated!');
}
/**
@@ -195,5 +243,4 @@ class CostCalculatorController extends Controller
}
return response()->json(['status' => 200, 'message' => 'Cost Calculator has been deleted!'], 200);
}
}

View File

@@ -8,6 +8,7 @@ use Modules\CCMS\Models\Country;
use Modules\CourseFinder\Models\Program;
use Modules\CourseFinder\Models\ProgramLevel;
use Modules\CostCalculator\Models\StayType;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
// use Modules\CostCalculator\Database\Factories\CostCalculatorFactory;
@@ -30,16 +31,6 @@ class CostCalculator extends Model
return $this->belongsTo(Country::class, 'country_id');
}
public function programLevel()
{
return $this->belongsTo(ProgramLevel::class, 'programlevel_id');
}
public function program()
{
return $this->belongsTo(Program::class, 'program_id');
}
public function stayTypeLiving(): BelongsToMany
{
return $this->belongsToMany(StayType::class, 'living_costs', 'cost_calculator_id', 'stay_type_id')->withPivot('id', 'monthly', 'yearly')->withTimestamps();

View File

@@ -14,8 +14,6 @@ return new class extends Migration
Schema::create('cost_calculators', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('country_id')->nullable();
$table->unsignedInteger('programlevel_id')->nullable();
$table->unsignedInteger('program_id')->nullable();
$table->unsignedInteger('createdby')->nullable();
$table->unsignedInteger('updatedby')->nullable();
$table->boolean('status')->default(1);

View File

@@ -2,9 +2,9 @@
<a href="{{ route('cost.edit', $id) }}" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Edit"
class="link-success fs-15 edit-item-btn"><i class=" ri-edit-2-line"></i></a>
<a data-link="{{ route('cost.toggle', $id) }}" data-bs-toggle="tooltip" data-bs-placement="bottom"
{{-- <a data-link="{{ route('cost.toggle', $id) }}" data-bs-toggle="tooltip" data-bs-placement="bottom"
data-bs-title="Toggle" data-status="{{ $status == 1 ? 'Draft' : 'Published' }}"
class="link-info fs-15 toggle-item"><i class="{{ $status == 1 ? 'ri-toggle-line' : 'ri-toggle-fill' }}"></i></a>
class="link-info fs-15 toggle-item"><i class="{{ $status == 1 ? 'ri-toggle-line' : 'ri-toggle-fill' }}"></i></a> --}}
<a href="javascript:void(0);" data-link="{{ route('cost.destroy', $id) }}" class="link-danger fs-15 remove-item"
data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Delete"><i class="ri-delete-bin-6-line"></i>

View File

@@ -0,0 +1,10 @@
@extends('layouts.app')
@section('content')
<div class="container-fluid">
<x-dashboard.breadcumb :title="$title" />
{{ html()->modelForm($cost, 'PUT')->route('cost.update', $cost->id)->class(['needs-validation'])->attributes(['novalidate', 'enctype' => 'multipart/form-data', 'onkeydown' => "return event.key != 'Enter';"])->open() }}
@include('costcalculator::cost.partials.form')
{{ html()->closeModelForm() }}
</div>
@endsection

View File

@@ -12,7 +12,8 @@
<div class="card">
<div class="card-header d-flex align-items-center justify-content-between">
<h5 class="card-title mb-0">{{ $title }}</h5>
<a href="{{ route('cost.create') }}" class="btn btn-primary waves-effect waves-light text-white"><i class="ri-add-line align-middle"></i> Create</a>
<a href="{{ route('cost.create') }}" class="btn btn-primary waves-effect waves-light text-white"><i
class="ri-add-line align-middle"></i> Create</a>
</div>
<div class="card-body">
@php
@@ -25,9 +26,10 @@
'searchable' => false,
'sortable' => false,
],
['title' => 'Image', 'data' => 'image', 'name' => 'image'],
['title' => 'Program Level', 'data' => 'program_level', 'name' => 'title'],
['title' => 'Slug', 'data' => 'slug', 'name' => 'slug'],
['title' => 'Country', 'data' => 'country', 'name' => 'country'],
['title' => 'Alone', 'data' => 'alone', 'name' => 'alone'],
['title' => 'With Spouse', 'data' => 'with_spouse', 'name' => 'with_spouse'],
['title' => 'With Spouse and Child', 'data' => 'with_spouse_and_child', 'name' => 'with_spouse_and_child'],
['title' => 'Status', 'data' => 'status', 'name' => 'status'],
[
'title' => 'Action',
@@ -37,7 +39,7 @@
],
];
@endphp
<x-data-table-script :route="route('service.index')" :reorder="route('service.reorder')" :columns="$columns" />
<x-data-table-script :route="route('cost.index')" :columns="$columns" />
</div>
</div>
</div>

View File

@@ -4,7 +4,7 @@
<div class="card-header">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h6 class="card-title mb-0">Cost Calculator</h6>
<h6 class="card-title mb-0">Cost Calculation</h6>
</div>
<div class="flex-shrink-0">
<ul class="list-inline card-toolbar-menu d-flex align-items-center mb-0">
@@ -22,25 +22,12 @@
</div>
<div class="card-body show collapse" id="collapse-personal">
<div class="row gy-3">
<div class="col-md-6">
<div class="col-md-12">
{{ html()->label('Country')->class('form-label') }}
{{ html()->span('*')->class('text-danger') }}
{{ html()->select('country_id', $countryOptions)->placeholder('Select')->class('form-select choices-select')->required() }}
{{ html()->div('Please select country')->class('invalid-feedback') }}
</div>
<div class="col-md-6">
{{ html()->label('Program Level')->class('form-label')->for('programlevel_id') }}
{{ html()->span('*')->class('text-danger') }}
{{ html()->select('programlevel_id', $programLevelOptions)->placeholder('Select')->class('form-select choices-select') }}
{{ html()->div('Please select program level')->class('invalid-feedback') }}
</div>
<div class="col-md-12">
{{ html()->label('Program')->class('form-label')->for('program_id') }}
{{ html()->select('program_id', $programOptions)->placeholder('Select')->class('form-select choices-select') }}
{{ html()->div('Please select program')->class('invalid-feedback') }}
</div>
</div>
</div>
</div>
@@ -83,21 +70,16 @@
</thead>
<tbody>
@if ($editable)
@if ($cost->living_cost)
@forelse ($program->living_cost as $key => $item)
@include('costcalculator::cost.partials.living-cost', [
'numInc' => $key,
'value' => $item,
])
@empty
@endforelse
@else
@forelse ($cost->stayTypeLiving as $key => $item)
@include('costcalculator::cost.partials.living-cost', [
'numInc' => $key,
'value' => $item,
])
@empty
@include('costcalculator::cost.partials.living-cost', [
'numInc' => 0,
])
@endif
@endforelse
@else
@include('costcalculator::cost.partials.living-cost', [
'numInc' => 0,
@@ -142,7 +124,7 @@
</thead>
<tbody>
@if ($editable)
@forelse ($cost->accomodation_cost as $key => $item)
@forelse ($cost->stayTypeAccomodation as $key => $item)
@include('costcalculator::cost.partials.accomodation-cost', [
'numInc' => $key,
'value' => $item,
@@ -200,20 +182,17 @@
</thead>
<tbody>
@if ($editable)
@if ($cost->onetime_cost)
@forelse ($cost->onetime_cost as $key => $item)
@include('costcalculator::cost.partials.onetime-cost', [
'numInc' => $key,
'value' => $item,
])
@empty
@endforelse
@forelse ($cost->stayTypeOnetime as $key => $item)
@include('costcalculator::cost.partials.onetime-cost', [
'numInc' => $key,
'value' => $item,
])
@empty
@else
@include('costcalculator::cost.partials.onetime-cost', [
'numInc' => 0,
])
@endif
@endforelse
@else
@include('costcalculator::cost.partials.onetime-cost', [
'numInc' => 0,
@@ -259,20 +238,16 @@
</thead>
<tbody>
@if ($editable)
@if ($cost->other_services)
@forelse ($cost->other_services as $key => $item)
@include('costcalculator::cost.partials.service-cost', [
'numInc' => $key,
'value' => $item,
])
@empty
@endforelse
@else
@forelse ($cost->stayTypeService as $key => $item)
@include('costcalculator::cost.partials.service-cost', [
'numInc' => $key,
'value' => $item,
])
@empty
@include('costcalculator::cost.partials.service-cost', [
'numInc' => 0,
])
@endif
@endforelse
@else
@include('costcalculator::cost.partials.service-cost', [
'numInc' => 0,