update
This commit is contained in:
parent
c338ee7c6c
commit
e131348fb8
@ -10,6 +10,7 @@ using System.Threading.Tasks;
|
|||||||
namespace PSTW_CentralSystem.Areas.OTcalculate.Controllers
|
namespace PSTW_CentralSystem.Areas.OTcalculate.Controllers
|
||||||
{
|
{
|
||||||
[Area("OTcalculate")]
|
[Area("OTcalculate")]
|
||||||
|
|
||||||
public class HrDashboardController : Controller
|
public class HrDashboardController : Controller
|
||||||
{
|
{
|
||||||
private readonly CentralSystemContext _context;
|
private readonly CentralSystemContext _context;
|
||||||
@ -40,72 +41,5 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Controllers
|
|||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Rates
|
|
||||||
[HttpPost("UpdateRates")]
|
|
||||||
public async Task<IActionResult> UpdateRate([FromBody] List<RateModel> rates)
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
return BadRequest(ModelState);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (var Rate in rates)
|
|
||||||
{
|
|
||||||
var existingRate = await _context.Rates.FindAsync(Rate.RateId);
|
|
||||||
if (existingRate != null)
|
|
||||||
{
|
|
||||||
existingRate.RateValue = Rate.RateValue;
|
|
||||||
_context.Rates.Update(existingRate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await _context.SaveChangesAsync();
|
|
||||||
|
|
||||||
var updateRates = await _context.Rates
|
|
||||||
.Include(rates => rates.Users)
|
|
||||||
.Select(rates => new
|
|
||||||
{
|
|
||||||
rates.RateId,
|
|
||||||
rates.RateValue,
|
|
||||||
rates.UserId,
|
|
||||||
FullName = rates.Users.FullName,
|
|
||||||
DepartmentName = rates.Users.DepartmentName
|
|
||||||
})
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
return Json(updateRates);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return BadRequest(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[HttpPost("GetUserRates")]
|
|
||||||
public async Task<IActionResult> GetUserRates()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var userRates = await _context.Rates
|
|
||||||
.Include(rates => rates.Users)
|
|
||||||
.Select(rates => new
|
|
||||||
{
|
|
||||||
rates.RateId,
|
|
||||||
rates.RateValue,
|
|
||||||
rates.UserId,
|
|
||||||
FullName = rates.Users.FullName,
|
|
||||||
DepartmentName = rates.Users.DepartmentName
|
|
||||||
})
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
return Json(userRates);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return BadRequest(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,18 @@
|
|||||||
namespace PSTW_CentralSystem.Areas.OTcalculate.Models
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using PSTW_CentralSystem.Models;
|
||||||
|
|
||||||
|
namespace PSTW_CentralSystem.Areas.OTcalculate.Models
|
||||||
{
|
{
|
||||||
public class CalendarModel
|
public class CalendarModel
|
||||||
{
|
{
|
||||||
|
[Key]
|
||||||
|
public int HolidayId { get; set; }
|
||||||
|
public required string HolidayName { get; set; }
|
||||||
|
public DateTime HolidayDate { get; set; }
|
||||||
|
public int StateId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey("StateId")]
|
||||||
|
public virtual StateModel? States { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,6 +9,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Models
|
|||||||
[Key]
|
[Key]
|
||||||
public int RateId { get; set; }
|
public int RateId { get; set; }
|
||||||
|
|
||||||
|
[Column(TypeName = "decimal(10,2)")]
|
||||||
public decimal RateValue { get; set; }
|
public decimal RateValue { get; set; }
|
||||||
|
|
||||||
public int UserId { get; set; }
|
public int UserId { get; set; }
|
||||||
|
|||||||
13
Areas/OTcalculate/Models/StateModel.cs
Normal file
13
Areas/OTcalculate/Models/StateModel.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using PSTW_CentralSystem.Models;
|
||||||
|
|
||||||
|
namespace PSTW_CentralSystem.Areas.OTcalculate.Models
|
||||||
|
{
|
||||||
|
public class StateModel
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int StateId { get; set; }
|
||||||
|
public required string StateName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-6 col-md-6 col-lg-3">
|
<div class="col-6 col-md-6 col-lg-3">
|
||||||
@ -34,98 +35,201 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="app">
|
||||||
|
<div class="container mt-3">
|
||||||
|
|
||||||
<div id="calendarApp">
|
@* Tab Page *@
|
||||||
<div class="row">
|
<ul class="nav nav-tabs">
|
||||||
@* Holiday *@
|
<li class="nav-item">
|
||||||
<div class="col-md-6">
|
<a class="nav-link"
|
||||||
<div class="card">
|
:class="{ 'bg-purple text-white': activeTab === 'holiday', 'bg-light text-dark': activeTab !== 'holiday' }"
|
||||||
<div class="card-header bg-purple text-white">
|
style="border: 1px solid #ddd;"
|
||||||
<h4 class="text-center">UPDATE HOLIDAY</h4>
|
v-on:click="changeTab('holiday')">
|
||||||
</div>
|
Update Holiday
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link"
|
||||||
|
:class="{ 'bg-purple text-white': activeTab === 'weekend', 'bg-light text-dark': activeTab !== 'weekend' }"
|
||||||
|
style="border: 1px solid #ddd;"
|
||||||
|
v-on:click="changeTab('weekend')">
|
||||||
|
Update Weekend
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content mt-3">
|
||||||
|
|
||||||
|
@* Update Holiday *@
|
||||||
|
<div v-if="activeTab === 'holiday'" class="card shadow-sm">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<label>Date:</label>
|
<label>Date:</label>
|
||||||
<input type="date" v-model="holidayDate" class="form-control">
|
<input type="date" class="form-control" v-model="selectedDate">
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
<label>State:</label>
|
<label>State:</label>
|
||||||
<div class="form-group">
|
<div class="row">
|
||||||
<div v-for="state in states" class="form-check">
|
<div class="col-md-4" v-for="state in stateList" :key="state.stateId">
|
||||||
<input type="checkbox" class="form-check-input" :id="state" :value="state" v-model="selectedStates">
|
<div class="form-check">
|
||||||
<label class="form-check-label" :for="state">{{ state }}</label>
|
<input type="checkbox" class="form-check-input" :value="state.stateId" v-model="selectedStates">
|
||||||
|
<label class="form-check-label">{{ state.stateName }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
<label>Holiday:</label>
|
<label>Holiday:</label>
|
||||||
<input type="text" v-model="holidayName" class="form-control" placeholder="Enter Holiday Name">
|
<input type="text" class="form-control" v-model="holidayName" placeholder="Enter Holiday Name">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mt-3 text-right">
|
<div class="card-body text-center">
|
||||||
<button class="btn btn-danger" >Clear</button>
|
<button class="btn btn-danger" v-on:click="clearForm">Clear</button>
|
||||||
<button class="btn btn-success" >Save</button>
|
<button class="btn btn-success ms-3" v-on:click="updateHoliday">Save Holiday</button>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@* Weekend *@
|
<div v-if="activeTab === 'holiday'" class="card shadow-sm">
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header bg-purple text-white">
|
|
||||||
<h4 class="text-center">UPDATE WEEKEND</h4>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<label>State:</label>
|
<label for="stateDropdown">Select State:</label>
|
||||||
<div class="form-group">
|
<select id="stateDropdown" class="form-control" v-model="selectedState">
|
||||||
<div v-for="state in states" class="form-check">
|
<option v-for="state in stateList" :key="state.stateId" :value="state.stateId">
|
||||||
<input type="checkbox" class="form-check-input" :id="'weekend_' + state" :value="state" v-model="selectedWeekendStates">
|
{{ state.stateName }}
|
||||||
<label class="form-check-label" :for="'weekend_' + state">{{ state }}</label>
|
</option>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<label>Days:</label>
|
|
||||||
<select v-model="selectedWeekend" class="form-control">
|
|
||||||
<option>Friday & Saturday</option>
|
|
||||||
<option>Saturday & Sunday</option>
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<div class="mt-3 text-right">
|
|
||||||
<button class="btn btn-danger" >Clear</button>
|
|
||||||
<button class="btn btn-success" >Save</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@* Updated Data*@
|
|
||||||
<div class="row mt-4">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h4>Holiday Updates</h4>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<ul class="mt-3">
|
<h5>Holidays for Selected State</h5>
|
||||||
<li v-for="holiday in holidays">
|
<ul class="list-group">
|
||||||
<strong>{{ holiday.Date }}</strong>: {{ holiday.HolidayName }} ({{ holiday.States.join(', ') }})
|
<li class="list-group-item" v-for="holiday in filteredHolidays" :key="holiday.holidayId">
|
||||||
|
{{ formatDate(holiday.holidayDate) }} - {{ holiday.holidayName }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@* Update Weekend *@
|
||||||
|
<div v-if="activeTab === 'weekend'" class="card shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<p>Weekend Update Section</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h4>Weekend Updates</h4>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<ul>
|
|
||||||
<li v-for="weekend in weekends">
|
|
||||||
<strong>{{ weekend.States.join(', ') }}</strong>: {{ weekend.WeekendDays }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/vue@3.3.4/dist/vue.global.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const app = Vue.createApp({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeTab: 'holiday',
|
||||||
|
stateList: [],
|
||||||
|
selectedDate: '',
|
||||||
|
selectedStates: [],
|
||||||
|
holidayName: '',
|
||||||
|
selectedState: null,
|
||||||
|
holidayList: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.fetchStates();
|
||||||
|
this.fetchHolidays();
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
filteredHolidays() {
|
||||||
|
return this.selectedState
|
||||||
|
? this.holidayList.filter(h => h.stateId === this.selectedState)
|
||||||
|
: [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
changeTab(tab) {
|
||||||
|
this.activeTab = tab;
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchStates() {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/OvertimeAPI/GetStatesName");
|
||||||
|
if (!response.ok) throw new Error("Failed to fetch states");
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
this.stateList = data.map(state => ({
|
||||||
|
stateId: state.stateId,
|
||||||
|
stateName: state.stateName
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (this.stateList.length > 0) {
|
||||||
|
this.selectedState = this.stateList[0].stateId;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching states:", error);
|
||||||
|
alert("Failed to load state list.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchHolidays() {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/OvertimeAPI/GetAllHolidays");
|
||||||
|
if (!response.ok) throw new Error("Failed to fetch holidays");
|
||||||
|
|
||||||
|
this.holidayList = await response.json();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching holidays:", error);
|
||||||
|
alert("Failed to load holiday list.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
formatDate(date) {
|
||||||
|
return new Date(date).toLocaleDateString();
|
||||||
|
},
|
||||||
|
|
||||||
|
async updateHoliday() {
|
||||||
|
try {
|
||||||
|
if (!this.selectedDate || this.selectedStates.length === 0 || !this.holidayName) {
|
||||||
|
alert("Please fill in all fields.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = this.selectedStates.map(stateId => ({
|
||||||
|
holidayDate: this.selectedDate,
|
||||||
|
stateId: stateId,
|
||||||
|
holidayName: this.holidayName
|
||||||
|
}));
|
||||||
|
|
||||||
|
const response = await fetch("/OvertimeAPI/UpdateHoliday", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
alert("Holiday updated successfully!");
|
||||||
|
this.clearForm();
|
||||||
|
this.fetchHolidays();
|
||||||
|
} else {
|
||||||
|
alert("Failed to update holiday.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating holiday:", error);
|
||||||
|
alert("An error occurred while updating holiday.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clearForm() {
|
||||||
|
this.selectedDate = '';
|
||||||
|
this.selectedStates = [];
|
||||||
|
this.holidayName = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.mount('#app');
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@model List<PSTW_CentralSystem.Areas.OTcalculate.Models.RateModel>
|
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Rate Update";
|
ViewData["Title"] = "Rate Update";
|
||||||
@ -36,98 +36,173 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="app" class="row">
|
||||||
<div class="row">
|
<div class="card m-1">
|
||||||
<div id="rateUpdate" class="card m-1">
|
<form v-on:submit.prevent="updateRates" data-aos="fade-right">
|
||||||
<div class="row" v-if="addSection == true">
|
<div class="card-header bg-white text-center">
|
||||||
<form v-on:submit.prevent="updateRate" data-aos="fade-right">
|
<h3 class="rate-heading">UPDATE RATE</h3>
|
||||||
<div class="container update" data-aos="fade-right">
|
|
||||||
<div class="row" data-aos="fade-right">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="tab-content" id="myTabContent">
|
|
||||||
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
|
|
||||||
<div class="row update-form card-body">
|
|
||||||
<div class="card-header" style="background-color: white;">
|
|
||||||
<h3 class="rate-heading text-center">UPDATE RATE</h3>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
|
||||||
|
|
||||||
@* Enter Rate *@
|
@* Enter Rate *@
|
||||||
<div class="form-group row">
|
<div class="d-flex justify-content-center align-items-center">
|
||||||
<label for="rate" class="col-sm-3">Rate</label>
|
<div class="d-flex align-items-center gap-2">
|
||||||
<div class="col-sm-9">
|
<label for="rate" class="mb-0">Rate</label>
|
||||||
<input type="number" id="rate" class="form-control" v-model="rate" placeholder="Enter new rate">
|
<input type="number" id="rate" class="form-control text-center" v-model="rate" placeholder="Enter new rate" step="0.01">
|
||||||
|
<button type="button" class="btn btn-danger me-2" v-on:click="clearForm">Clear</button>
|
||||||
|
<button type="submit" class="btn btn-success col-4">Update Rates</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
</div>
|
<table id="rateDatatable" class="table table-bordered table-hover table-striped">
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@* User Table Rate *@
|
|
||||||
<div id="app">
|
|
||||||
<table class="table table-bordered table-hover table-striped">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Full Name</th>
|
<th>Full Name</th>
|
||||||
<th>Department</th>
|
<th>Department</th>
|
||||||
<th>Select Rate</th>
|
<th>Current Rate</th>
|
||||||
|
<th class="text-center">Select Rate</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
|
||||||
<tr v-for="user in users" :key="user.UserId">
|
|
||||||
<td>{{ user.FullName }}</td>
|
|
||||||
<td>{{ user.DepartmentName }}</td>
|
|
||||||
<td>
|
|
||||||
<input type="checkbox" v-model="selectedRates" :value="user.RateId">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
<button @click ="updateRates" class="btn btn-primary">Update Rates</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="d-flex align-items-center justify-content-end gap-2 my-3">
|
||||||
|
<button type="button" class="btn btn-danger" v-on:click="clearForm">Clear</button>
|
||||||
|
<button type="submit" class="btn btn-success">Update Rates</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
@{
|
@{
|
||||||
await Html.RenderPartialAsync("_ValidationScriptsPartial");
|
await Html.RenderPartialAsync("_ValidationScriptsPartial");
|
||||||
}
|
}
|
||||||
|
<script src="https://unpkg.com/vue@3.2.37/dist/vue.global.js"></script>
|
||||||
<script>
|
<script>
|
||||||
new Vue({
|
window.onload = function () {
|
||||||
el: "#app",
|
const app = Vue.createApp({
|
||||||
data: {
|
data() {
|
||||||
|
return {
|
||||||
users: [],
|
users: [],
|
||||||
selectedRates: []
|
selectedRates: [],
|
||||||
|
userList: [],
|
||||||
|
rate: null,
|
||||||
|
rateDatatable: null
|
||||||
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
console.log("Vue App Mounted Successfully");
|
||||||
|
this.fetchUser().then(() => {
|
||||||
this.fetchRates();
|
this.fetchRates();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchRates() {
|
async fetchRates() {
|
||||||
const response = await fetch("/HrDashboard/GetUserRates", {
|
try {
|
||||||
method: "POST",
|
const response = await fetch("/OvertimeAPI/GetUserRates", { method: "POST", headers: { "Content-Type": "application/json" }});
|
||||||
headers: { "Content-Type": "application/json" }
|
if (!response.ok) throw new Error("Failed to fetch rates");
|
||||||
|
const usersWithRates = await response.json();
|
||||||
|
this.userList = this.userList.map(user => {
|
||||||
|
const userRate = usersWithRates.find(rate => rate.userId === user.id);
|
||||||
|
return { ...user, rateValue: userRate ? userRate.rateValue : null };
|
||||||
});
|
});
|
||||||
this.users = await response.json();
|
this.initiateTable();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching rates:", error);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async updateRates() {
|
async updateRates() {
|
||||||
const response = await fetch("/HrDashboard/UpdateRates", {
|
try {
|
||||||
|
if (this.selectedRates.length === 0) {
|
||||||
|
alert("Please select at least one user.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let rateValue = parseFloat(this.rate);
|
||||||
|
if (isNaN(rateValue)) {
|
||||||
|
alert("Please enter a valid rate.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const payload = this.selectedRates.map(userId => ({ UserId: userId, RateValue: rateValue.toFixed(2) }));
|
||||||
|
const response = await fetch("/OvertimeAPI/UpdateRates", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify(this.selectedRates.map(id => ({ RateId: id })))
|
body: JSON.stringify(payload)
|
||||||
});
|
});
|
||||||
|
if (response.ok) {
|
||||||
|
alert("Rates updated successfully!");
|
||||||
|
this.selectedRates = [];
|
||||||
|
this.rate = null;
|
||||||
|
await this.fetchRates();
|
||||||
|
} else {
|
||||||
|
alert("Failed to update rates. Please try again.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating rates:", error);
|
||||||
|
alert("An error occurred while updating rates.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async fetchUser() {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/InvMainAPI/UserList/`, { method: 'POST' });
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
this.userList = data.filter(e => e.fullName !== "MAAdmin" && e.fullName !== "SysAdmin");
|
||||||
|
console.log(this.userList);
|
||||||
|
} else {
|
||||||
|
console.error(`Failed to fetch user: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('There was a problem with the fetch operation:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initiateTable() {
|
||||||
|
let self = this;
|
||||||
|
if ($.fn.dataTable.isDataTable('#rateDatatable')) {
|
||||||
|
$('#rateDatatable').DataTable().clear().destroy();
|
||||||
|
}
|
||||||
|
this.rateDatatable = $('#rateDatatable').DataTable({
|
||||||
|
"data": this.userList,
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"title": "Full Name",
|
||||||
|
"data": "fullName"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Department",
|
||||||
|
"data": "departmentName"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Current Rate",
|
||||||
|
"data": "rateValue",
|
||||||
|
"render": data => data ? parseFloat(data).toFixed(2) : 'N/A'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Select Rate",
|
||||||
|
"data": "id",
|
||||||
|
"render": function (data)
|
||||||
|
{
|
||||||
|
return `<input type='checkbox' class='rate-checkbox' value='${data}'>`;
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
responsive: true,
|
||||||
|
});
|
||||||
|
$('#rateDatatable tbody').on('change', '.rate-checkbox', function () {
|
||||||
|
const userId = $(this).val();
|
||||||
|
if (this.checked) self.selectedRates.push(userId);
|
||||||
|
else self.selectedRates = self.selectedRates.filter(id => id !== userId);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
clearForm() {
|
||||||
|
this.rate = null;
|
||||||
|
this.selectedRates = [];
|
||||||
|
|
||||||
const updatedUsers = await response.json();
|
document.querySelectorAll('.rate-checkbox').forEach(checkbox => {
|
||||||
this.users = updatedUsers;
|
checkbox.checked = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
app.mount('#app');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
@ -1195,8 +1195,14 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
[HttpPost("UserList")]
|
[HttpPost("UserList")]
|
||||||
public async Task<IActionResult> UserList()
|
public async Task<IActionResult> UserList()
|
||||||
{
|
{
|
||||||
var userList = await _centralDbContext.Users.ToListAsync();
|
var userList = await _centralDbContext.Users.Include(i => i.Department).ToListAsync();
|
||||||
return Json(userList);
|
return Json(userList.Select(i => new
|
||||||
|
{
|
||||||
|
i.Id,
|
||||||
|
i.FullName,
|
||||||
|
i.Department,
|
||||||
|
i.Department?.DepartmentName,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ using Mono.TextTemplating;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PSTW_CentralSystem.Areas.OTcalculate.Models;
|
using PSTW_CentralSystem.Areas.OTcalculate.Models;
|
||||||
using PSTW_CentralSystem.Controllers.API;
|
using PSTW_CentralSystem.Controllers.API;
|
||||||
|
using PSTW_CentralSystem.Controllers.API.Inventory;
|
||||||
using PSTW_CentralSystem.DBContext;
|
using PSTW_CentralSystem.DBContext;
|
||||||
using PSTW_CentralSystem.Models;
|
using PSTW_CentralSystem.Models;
|
||||||
using System.ComponentModel.Design;
|
using System.ComponentModel.Design;
|
||||||
@ -32,13 +33,169 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserDetails
|
#region Rate
|
||||||
|
[HttpPost("UpdateRates")]
|
||||||
|
public async Task<IActionResult> UpdateRate([FromBody] List<RateModel> rates)
|
||||||
{
|
{
|
||||||
public required string FullName { get; set; }
|
if (!ModelState.IsValid)
|
||||||
public int DepartmentId { get; set; }
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var rate in rates)
|
||||||
|
{
|
||||||
|
var existingRate = await _centralDbContext.Rates
|
||||||
|
.FirstOrDefaultAsync(r => r.UserId == rate.UserId);
|
||||||
|
|
||||||
|
if (existingRate != null)
|
||||||
|
{
|
||||||
|
existingRate.RateValue = rate.RateValue;
|
||||||
|
_centralDbContext.Rates.Update(existingRate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_centralDbContext.Rates.Add(new RateModel
|
||||||
|
{
|
||||||
|
UserId = rate.UserId,
|
||||||
|
RateValue = rate.RateValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _centralDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
var updatedRates = await _centralDbContext.Rates
|
||||||
|
.Include(r => r.Users)
|
||||||
|
.Select(r => new
|
||||||
|
{
|
||||||
|
r.RateId,
|
||||||
|
r.RateValue,
|
||||||
|
r.UserId,
|
||||||
|
FullName = r.Users.FullName,
|
||||||
|
DepartmentName = r.Users.Department.DepartmentName
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(updatedRates);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("GetUserRates")]
|
||||||
|
public async Task<IActionResult> GetUserRates()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var userRates = await _centralDbContext.Rates
|
||||||
|
.Include(rates => rates.Users)
|
||||||
|
.ThenInclude(user => user.Department)
|
||||||
|
.Select(rates => new
|
||||||
|
{
|
||||||
|
rates.RateId,
|
||||||
|
rates.RateValue,
|
||||||
|
rates.UserId,
|
||||||
|
rates.Users.FullName,
|
||||||
|
rates.Users.Department.DepartmentName
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(userRates);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Calendar
|
||||||
|
[HttpGet("GetStatesName")]
|
||||||
|
public async Task<IActionResult> GetStatesName()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var states = await _centralDbContext.States
|
||||||
|
.Select(s => new
|
||||||
|
{
|
||||||
|
s.StateId,
|
||||||
|
s.StateName
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(states);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost("UpdateHoliday")]
|
||||||
|
public async Task<IActionResult> UpdateHoliday([FromBody] List<CalendarModel> holidays)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var calendar in holidays)
|
||||||
|
{
|
||||||
|
var existingCalendar = await _centralDbContext.Holidays
|
||||||
|
.FirstOrDefaultAsync(h => h.StateId == calendar.StateId && h.HolidayDate == calendar.HolidayDate);
|
||||||
|
|
||||||
|
if (existingCalendar != null)
|
||||||
|
{
|
||||||
|
existingCalendar.HolidayName = calendar.HolidayName;
|
||||||
|
_centralDbContext.Holidays.Update(existingCalendar);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_centralDbContext.Holidays.Add(new CalendarModel
|
||||||
|
{
|
||||||
|
HolidayName = calendar.HolidayName,
|
||||||
|
HolidayDate = calendar.HolidayDate,
|
||||||
|
StateId = calendar.StateId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _centralDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
var updatedHoliday = await _centralDbContext.Holidays
|
||||||
|
.Include(h => h.States)
|
||||||
|
.Select(h => new
|
||||||
|
{
|
||||||
|
h.HolidayId,
|
||||||
|
h.HolidayName,
|
||||||
|
h.HolidayDate,
|
||||||
|
h.StateId,
|
||||||
|
StateName = h.States.StateName
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(updatedHoliday);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("GetAllHolidays")]
|
||||||
|
public IActionResult GetAllHolidays()
|
||||||
|
{
|
||||||
|
var holidays = _centralDbContext.Holidays.ToList();
|
||||||
|
return Ok(holidays);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,5 +100,7 @@ namespace PSTW_CentralSystem.DBContext
|
|||||||
public DbSet<StationModel> Stations { get; set; }
|
public DbSet<StationModel> Stations { get; set; }
|
||||||
public DbSet<StoreModel> Stores { get; set; }
|
public DbSet<StoreModel> Stores { get; set; }
|
||||||
public DbSet<RateModel> Rates { get; set; }
|
public DbSet<RateModel> Rates { get; set; }
|
||||||
|
public DbSet<CalendarModel> Holidays { get; set; }
|
||||||
|
public DbSet<StateModel> States { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user