Merge pull request 'Attendance Manual Entry' (#40) from dev_mashfiq into devqc

Reviewed-on: http://103.197.204.162:3025/CelHRTeam/EchoTex_Payroll/pulls/40
This commit is contained in:
chapal 2025-04-28 10:08:05 +06:00
commit 8169c0791b
12 changed files with 223 additions and 59 deletions

View File

@ -441,20 +441,21 @@ namespace HRM.BO
} }
} }
public bool OnlyManualInTime //public bool OnlyManualInTime
{ //{
get { // get {
return (this.IsManualEntry == true && this.ActualInTime != null) ? true : false;} // return (this.IsManualEntry == true && this.ActualInTime != null) ? true : false;}
}
public bool OnlyManualOutTime
{
get
{
return (this.IsManualEntry == true && this.ActualOutTime != null) ? true : false;
}
}
//}
//public bool OnlyManualOutTime
//{
// get
// {
// return (this.IsManualEntry == true && this.ActualOutTime != null) ? true : false;
// }
//}
public bool OnlyManualInTime { get; set; }
public bool OnlyManualOutTime { get; set; }
@ -3382,6 +3383,7 @@ namespace HRM.BO
DataTable getTopEmpAbsentData(Employee oEmp, EnumAttendanceType type); DataTable getTopEmpAbsentData(Employee oEmp, EnumAttendanceType type);
DataTable getcorehrAbsentData(Employee oEmp, EnumAttendanceType type); DataTable getcorehrAbsentData(Employee oEmp, EnumAttendanceType type);
DataSet AttnDaysSummaryForSalaryProcess(DateTime FromDate, DateTime ToDate); DataSet AttnDaysSummaryForSalaryProcess(DateTime FromDate, DateTime ToDate);
List<DailyAttnProcess> GetByEmployees(DateTime attnDate, string employeeIDs);
} }
#endregion #endregion

View File

@ -24,19 +24,37 @@ namespace HRM.DA
#region Insert function #region Insert function
//internal static void Insert(TransactionContext tc, DailyAttnProcess item) internal static void Insert(TransactionContext tc, DailyAttnProcess item)
//{ {
// tc.ExecuteNonQuery( //tc.ExecuteNonQuery(
// "INSERT INTO DailyAttnProcess(DailyAttnProcessID, EmployeeID, AttnDate, ShiftID, InTime, OutTime,WorkDayType, AttenType, Comments,Reason, IsManualEntry,IsLate, LateHour, EarlyHour, OTHour, ReferenceID, CreatedBy, CreatedDate, OtRemarks, BenefitRemarks, TempShiftID, WFStatus, ApprovedOTHOUR, LMRemarks, DHRemarks, SalaryMonth, ActualInTime, ActualOutTime, CLAIMWFSTATUS)" + // "INSERT INTO DailyAttnProcess(DailyAttnProcessID, EmployeeID, AttnDate, ShiftID, InTime, OutTime,WorkDayType, AttenType, Comments,Reason, IsManualEntry,IsLate, LateHour, EarlyHour, OTHour, ReferenceID, CreatedBy, CreatedDate, OtRemarks, BenefitRemarks, TempShiftID, WFStatus, ApprovedOTHOUR, LMRemarks, DHRemarks, SalaryMonth, ActualInTime, ActualOutTime, CLAIMWFSTATUS)" +
// " VALUES(%n, %n, %d, %n, %D, %D, %n, %n, %s,%s,%b, %b, %n, %n, %n, %n, %n, %d, %s, %s, %n,%n,%n, %s, %s, %d,%D,%D, %n)", // " VALUES(%n, %n, %d, %n, %D, %D, %n, %n, %s,%s,%b, %b, %n, %n, %n, %n, %n, %d, %s, %s, %n,%n,%n, %s, %s, %d,%D,%D, %n)",
// item.ID, item.EmployeeID, item.AttnDate, DataReader.GetNullValue(item.ShiftID), // item.ID, item.EmployeeID, item.AttnDate, DataReader.GetNullValue(item.ShiftID),
// DataReader.GetNullValue(item.EmpInTime), DataReader.GetNullValue(item.EmpOutTime), item.WorkDayType, // DataReader.GetNullValue(item.EmpInTime), DataReader.GetNullValue(item.EmpOutTime), item.WorkDayType,
// item.AttenType, item.Comments, item.Reason, item.IsManualEntry, item.IsLate, item.LateHour, // item.AttenType, item.Comments, item.Reason, item.IsManualEntry, item.IsLate, item.LateHour,
// item.EarlyHour, item.OTHour, DataReader.GetNullValue(item.ReferenceID, 0), item.CreatedBy, // item.EarlyHour, item.OTHour, DataReader.GetNullValue(item.ReferenceID, 0), item.CreatedBy,
// item.CreatedDate, item.OtRemarks, item.BenefitRemarks, item.TempShiftID, // item.CreatedDate, item.OtRemarks, item.BenefitRemarks, item.TempShiftID,
// item.WFStatus, item.ApprovedOTHour, item.LMRemarks, item.DHRemarks, item.SalaryMonth, item.ActualInTime, // item.WFStatus, item.ApprovedOTHour, item.LMRemarks, item.DHRemarks, item.SalaryMonth, item.ActualInTime,
// item.ActualOutTime, (int)EnumClaimWFStatus.None); // item.ActualOutTime, (int)EnumClaimWFStatus.None);
//} tc.ExecuteNonQuery(@"INSERT INTO DailyAttnProcess(DailyAttnProcessID, EmployeeID, AttnDate,
ShiftID, InTime, OutTime,
WorkDayType, ATTENTYPE, Comments,
IsManualEntry,OnlyManualInTime,OnlyManualOutTime,
LateHour, EarlyHour, OTHour,
ReferenceID, CreatedBy, CreatedDate)
VALUES(%n, %n, %d,
%n, %D, %D,
%n, %n, %s,
%b, %b, %b,
%n, %n, %n,
%n, %n, %d)",
item.ID, item.EmployeeID, item.AttnDate,
DataReader.GetNullValue(item.ShiftID), DataReader.GetNullValue(item.InTime), DataReader.GetNullValue(item.OutTime),
item.WorkDayType, item.AttenType, item.Comments,
item.IsManualEntry, item.OnlyManualInTime, item.OnlyManualOutTime,
item.LateHour, item.EarlyHour, item.OTHour,
DataReader.GetNullValue(item.ReferenceID), item.CreatedBy, item.CreatedDate);
}
#endregion #endregion
@ -4092,6 +4110,11 @@ namespace HRM.DA
return ds.Tables[0]; return ds.Tables[0];
} }
internal static IDataReader GetByEmployees(TransactionContext tc, DateTime attnDate, string employeeIDs)
{
return tc.ExecuteReader("SELECT * FROM DailyAttnProcess WHERE AttnDate=%d And employeeid in (%q)", attnDate, employeeIDs);
}
} }
#endregion #endregion

View File

@ -46,7 +46,9 @@ namespace HRM.DA
oDailyAttnProcess.AttenType = (EnumAttendanceType)oReader.GetInt32("AttenType").Value; oDailyAttnProcess.AttenType = (EnumAttendanceType)oReader.GetInt32("AttenType").Value;
oDailyAttnProcess.Comments = oReader.GetString("Comments") == null ? "" : oReader.GetString("Comments"); oDailyAttnProcess.Comments = oReader.GetString("Comments") == null ? "" : oReader.GetString("Comments");
oDailyAttnProcess.Reason = oReader.GetString("Reason") == null ? "" : oReader.GetString("Reason"); oDailyAttnProcess.Reason = oReader.GetString("Reason") == null ? "" : oReader.GetString("Reason");
oDailyAttnProcess.IsManualEntry = oReader.GetBoolean("IsManualEntry").Value; oDailyAttnProcess.IsManualEntry = oReader.GetBoolean("IsManualEntry", false);
oDailyAttnProcess.OnlyManualInTime = oReader.GetBoolean("OnlyManualInTime", false);
oDailyAttnProcess.OnlyManualOutTime = oReader.GetBoolean("OnlyManualOutTime", false);
oDailyAttnProcess.IsFromMobile = (EnumIsFromMobile)oReader.GetInt32("IsFromMobile").Value; oDailyAttnProcess.IsFromMobile = (EnumIsFromMobile)oReader.GetInt32("IsFromMobile").Value;
oDailyAttnProcess.InTimeLatitude = oReader.GetString("InTimeLatitude") == null ? 0.0m : Convert.ToDecimal(oReader.GetString("InTimeLatitude")); oDailyAttnProcess.InTimeLatitude = oReader.GetString("InTimeLatitude") == null ? 0.0m : Convert.ToDecimal(oReader.GetString("InTimeLatitude"));
oDailyAttnProcess.OutTimeLatitude = oReader.GetString("OutTimeLatitude") == null ? 0.0m : Convert.ToDecimal(oReader.GetString("OutTimeLatitude")); oDailyAttnProcess.OutTimeLatitude = oReader.GetString("OutTimeLatitude") == null ? 0.0m : Convert.ToDecimal(oReader.GetString("OutTimeLatitude"));
@ -1135,7 +1137,16 @@ namespace HRM.DA
tc = TransactionContext.Begin(true); tc = TransactionContext.Begin(true);
foreach (DailyAttnProcess item in oDAttnProcessess) foreach (DailyAttnProcess item in oDAttnProcessess)
{ {
DailyAttnProcessDA.ManualEditUpdate(tc, item); if (item.IsNew)
{
int id = tc.GenerateID("DailyAttnProcess", "DAILYATTNPROCESSID");
base.SetObjectID(item, id);
DailyAttnProcessDA.Insert(tc, item);
}
else
{
DailyAttnProcessDA.ManualEditUpdate(tc, item);
}
} }
//if (attnMonthlyBenefit.Count > 0) //if (attnMonthlyBenefit.Count > 0)
@ -4807,6 +4818,29 @@ namespace HRM.DA
return dt; return dt;
} }
public List<DailyAttnProcess> GetByEmployees(DateTime attnDate, string employeeIDs)
{
List<DailyAttnProcess> dailyAttnProcesses = new List<DailyAttnProcess>();
TransactionContext tc = null;
try
{
tc = TransactionContext.Begin();
DataReader dr = new DataReader(DailyAttnProcessDA.GetByEmployees(tc, attnDate, employeeIDs));
dailyAttnProcesses = this.CreateObjects<DailyAttnProcess>(dr);
dr.Close();
tc.End();
}
catch (Exception e)
{
#region Handle Exception
if (tc != null)
tc.HandleError();
ExceptionLog.Write(e);
throw new ServiceException(e.Message, e);
#endregion
}
return dailyAttnProcesses;
}
} }

View File

@ -48,6 +48,8 @@ export class DailyAttnProcess extends BaseObject {
this.actualOutTime = new Date(); this.actualOutTime = new Date();
this.actualShiftID = null; this.actualShiftID = null;
this.shift= null; this.shift= null;
this.onlyManualInTime = false;
this.onlyManualOutTime = false;
} }
attnDate: Date; attnDate: Date;
inTime: Date; inTime: Date;
@ -90,6 +92,9 @@ export class DailyAttnProcess extends BaseObject {
shift: Shift; shift: Shift;
remarksType: number; remarksType: number;
onlyManualInTime: boolean;
onlyManualOutTime: boolean;

View File

@ -276,6 +276,9 @@ export class AttendanceServices {
getDailyAttnProcessByEmp(empList: any) { getDailyAttnProcessByEmp(empList: any) {
return this.apiService.httpPost<DailyAttnProcess[]>('/Attendance' + '/getDailyAttnProcessByEmp', empList); return this.apiService.httpPost<DailyAttnProcess[]>('/Attendance' + '/getDailyAttnProcessByEmp', empList);
} }
getDailyAttnProcessByEmpForManualEntry(empList: any) {
return this.apiService.httpPost<DailyAttnProcess[]>('/Attendance' + '/getDailyAttnProcessByEmpForManualEntry', empList);
}
// DailyAttnProcess // DailyAttnProcess
getDailyAttnProcessByEmployeeId(employeeId: number) { getDailyAttnProcessByEmployeeId(employeeId: number) {

View File

@ -14,7 +14,7 @@ export class ApiService {
public isSSO = false; public isSSO = false;
public versionDeployement = false; public versionDeployement = false;
// public versionNumber = `V-${GlobalfunctionExtension.generateVersionNumber(new Date(2025, 1, 25))}-`+"01"; // public versionNumber = `V-${GlobalfunctionExtension.generateVersionNumber(new Date(2025, 1, 25))}-`+"01";
public versionNumber = `V-20250421-`+"01"; public versionNumber = `V-20250427-`+"01";
public static BASE_URL = ''; public static BASE_URL = '';
public base_url = ''; public base_url = '';
// public currentLink = ''; // public currentLink = '';

View File

@ -329,7 +329,7 @@
<div class="p-col-12" align="right"> <div class="p-col-12" align="right">
<button kendoButton icon="arrow-left" style="margin-right: 20px;" class="k-button k-primary" *ngIf="isVisibleCordinatorPicker" (click)="goBack()"> <button kendoButton icon="arrow-left" style="margin-right: 20px;" class="k-button k-primary" *ngIf="isVisibleCordinatorPicker" (click)="goBack()">
Back </button> Back </button>
<button icon="rotate" kendoButton class="k-button k-primary" (click)="update()"> <button icon="save" kendoButton class="k-button k-primary" (click)="update()">
Update Update
</button> </button>
</div> </div>

View File

@ -34,7 +34,7 @@ export class AttendanceManualEditForMultipleEmployeeComponent implements OnInit
approvalRole: string; approvalRole: string;
isVisibleEmpPicker: boolean = false; isVisibleEmpPicker: boolean = false;
isVisibleCordinatorPicker: boolean = false; isVisibleCordinatorPicker: boolean = false;
isVisiblelmPicker: boolean= false; isVisiblelmPicker: boolean = false;
selectedShiftID: number; selectedShiftID: number;
selectedStatus: EnumAttendanceType; selectedStatus: EnumAttendanceType;
selectedAttnDate: Date; selectedAttnDate: Date;
@ -85,7 +85,7 @@ export class AttendanceManualEditForMultipleEmployeeComponent implements OnInit
this.selectInTime = new Date(); this.selectInTime = new Date();
this.selectedOutTime = new Date(); this.selectedOutTime = new Date();
this.loadDropDownLists(); this.loadDropDownLists();
// this.selectedStatus = EnumAttendanceType.Present; // this.selectedStatus = EnumAttendanceType.Present;
this.getPendindBillings(); this.getPendindBillings();
} }
@ -143,7 +143,7 @@ export class AttendanceManualEditForMultipleEmployeeComponent implements OnInit
}, },
() => { () => {
if (this.shifts.length > 0) { if (this.shifts.length > 0) {
// this.selectedShiftID = this.shifts[0].id; // this.selectedShiftID = this.shifts[0].id;
this.shifts[0].inTime = new Date(this.shifts[0].inTime); this.shifts[0].inTime = new Date(this.shifts[0].inTime);
this.shifts[0].outTime = new Date(this.shifts[0].outTime); this.shifts[0].outTime = new Date(this.shifts[0].outTime);
this.dateChange(); this.dateChange();
@ -274,7 +274,8 @@ export class AttendanceManualEditForMultipleEmployeeComponent implements OnInit
if (attnRequest.length == 0) return; if (attnRequest.length == 0) return;
this.attendanceServices.getDailyAttnProcessByEmp(attnRequest).subscribe( // this.attendanceServices.getDailyAttnProcessByEmp(attnRequest).subscribe(
this.attendanceServices.getDailyAttnProcessByEmpForManualEntry(attnRequest).subscribe(
(resp) => { (resp) => {
if (this.dailyAttenProcessList == undefined || this.dailyAttenProcessList.length == 0) { if (this.dailyAttenProcessList == undefined || this.dailyAttenProcessList.length == 0) {
@ -371,8 +372,17 @@ export class AttendanceManualEditForMultipleEmployeeComponent implements OnInit
} }
if ((x.inTime == null || x.outTime == null) && x.attenType == EnumAttendanceType.Present) { if ((x.inTime == null && x.outTime == null) && x.attenType == EnumAttendanceType.Present) {
msg = msg + "Employee: " + x.employee.employeeNo + ", Status present is not allowed while inTime and outTime is not entered.; "; msg = msg + "Employee: " + x.employee.employeeNo + ", Status present is not allowed while In Time and Out Time is not entered.; ";
}
else {
if (x.inTime != null && x.outTime == null) {
x.onlyManualInTime = true;
}
if (x.inTime == null && x.outTime != null) {
x.onlyManualOutTime = true;
}
} }
var bvalid = false; var bvalid = false;

View File

@ -1,21 +1,23 @@
<app-loading-panel></app-loading-panel> <app-loading-panel></app-loading-panel>
<form [formGroup]="_salaryDaysDeductEdit"> <form [formGroup]="_salaryDaysDeductEdit">
<div class="card"> <div class="card">
<div class="p-grid"> <div class="p-col-12">
<div class="p-col-2"> <div class="p-grid">
<label>Unauthorized Leave</label> <div class="p-col-2">
</div> <label>Unauthorized Leave</label>
<div class="p-col-10"> </div>
<kendo-dropdownlist [data]="_unAuthLeaves" <div class="p-col-10">
[(ngModel)]="_uaLeaveParam.unAhuthorizeLeaveID" <kendo-dropdownlist [data]="_unAuthLeaves"
[defaultItem]="{ name: 'Select..', value: null }" [(ngModel)]="_uaLeaveParam.unAhuthorizeLeaveID"
[textField]="'name'" [defaultItem]="{ name: 'Select..', value: null }"
[valueField]="'id'" [textField]="'name'"
[valuePrimitive]="true" [valueField]="'id'"
class="form-control form-control-sm input-sm" [valuePrimitive]="true"
(selectionChange)="paramselectionChange($event)" class="form-control form-control-sm input-sm"
formControlName="unauthorizedLeaveDropDown"> (selectionChange)="paramselectionChange($event)"
</kendo-dropdownlist> formControlName="unauthorizedLeaveDropDown">
</kendo-dropdownlist>
</div>
</div> </div>
</div> </div>
<div class="p-grid"> <div class="p-grid">
@ -26,7 +28,7 @@
[selectable]="{enabled: true, checkboxOnly: true, mode: 'multiple'}" [selectable]="{enabled: true, checkboxOnly: true, mode: 'multiple'}"
[selectedKeys]="_selectedgrades" [selectedKeys]="_selectedgrades"
[kendoGridSelectBy]="'id'" [kendoGridSelectBy]="'id'"
[height]="200"> [height]="500">
<kendo-grid-checkbox-column [class]="{'text-center': true}" <kendo-grid-checkbox-column [class]="{'text-center': true}"
[columnMenu]="false" [columnMenu]="false"
[headerClass]="{'text-center': true}" [headerClass]="{'text-center': true}"
@ -43,10 +45,10 @@
</div> </div>
<div class="p-col-6"> <div class="p-col-6">
<h3>salary components</h3> <h3>Salary components</h3>
<kendo-grid [data]="_uaLeaveParamDetail" <kendo-grid [data]="_uaLeaveParamDetail"
[selectedKeys]="_selectedcomponent" [selectedKeys]="_selectedcomponent"
[height]="200" [height]="500"
[kendoGridSelectBy]="'allowanceID'"> [kendoGridSelectBy]="'allowanceID'">
<kendo-grid-column field="componenetName" title="Name"> <kendo-grid-column field="componenetName" title="Name">
@ -70,8 +72,14 @@
</div> </div>
<div class="card"> <div class="card">
<div class="p-col-12 p-md-12" align="right"> <div class="p-col-12 p-md-12" align="right">
<button pButton type="button" label="Go Back" style="margin-bottom: 10px; margin-right: 20px; width: 100px; background:red; color:white" (click)="cancel();" class="ui-button-danger"></button> <!-- <button pButton type="button" label="Go Back" style="margin-bottom: 10px; margin-right: 20px; width: 100px; background:red; color:white" (click)="cancel();" class="ui-button-danger"></button>
<button pButton type="submit" label="Save" (click)="Save()" style="margin-bottom: 10px; width: 100px; background:#50AF47; color: white" class="ui-button-success"></button> <button pButton type="submit" label="Save" (click)="Save()" style="margin-bottom: 10px; width: 100px; background:#50AF47; color: white" class="ui-button-success"></button> -->
<button icon="undo" kendoButton class="k-button k-primary" (click)="cancel()" style="margin-right: 5px;">
Go Back
</button>
<button icon="save" kendoButton class="k-button k-primary" (click)="Save()">
Save
</button>
</div> </div>
</div> </div>
</form> </form>

View File

@ -211,6 +211,6 @@ export class SalaryDaysDeductEditComponent implements OnInit {
} }
cancel() { cancel() {
this.router.navigateByUrl('/payroll/absent-deduction-Policy');
} }
} }

View File

@ -6,7 +6,7 @@
(edit)="editHandler($event)" (edit)="editHandler($event)"
(remove)="removeHandler($event)"> (remove)="removeHandler($event)">
<ng-template kendoGridToolbarTemplate> <ng-template kendoGridToolbarTemplate>
<button [primary]="true" kendoGridAddCommand (click)="new()">Add New</button> <button icon="plus" [primary]="true" kendoGridAddCommand (click)="new()">Add New</button>
</ng-template> </ng-template>
<kendo-grid-column field="unAuthLeaveName" title="Name" width="80%"> <kendo-grid-column field="unAuthLeaveName" title="Name" width="80%">
</kendo-grid-column> </kendo-grid-column>

View File

@ -1331,6 +1331,85 @@ namespace HRM.UI.Controllers.Attendance
return Ok(attnProcesses); return Ok(attnProcesses);
} }
[HttpPost("getDailyAttnProcessByEmpForManualEntry")]
public ActionResult getDailyAttnProcessByEmpForManualEntry(dynamic data)
{
List<DailyAttnProcess> _dAttnProcessess = new List<DailyAttnProcess>();
DailyAttnProcess _dAttnProcess = null;
CurrentUser currentUser = CurrentUser.GetCurrentUser(HttpContext.User);
try
{
var items = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(data));
string empids = "";
DateTime attnDate = DateTime.Today;
List<int> empIdList = new List<int>();
foreach (var item in items)
{
int empID = (int)item["employeeid"].ToObject<int>();
empids = empids + empID.ToString() + ",";
attnDate = (DateTime)item["attnDate"].ToObject<DateTime>();
empIdList.Add(empID);
}
if (empids.Length > 0) empids = empids.Substring(0, empids.Length - 1);
attnDate = new DateTime(attnDate.Year, attnDate.Month, attnDate.Day);
List<DailyAttnProcess> dAttnProcessess = this._dailyAttnProcessService.GetByEmployees(attnDate, empids);
foreach (var empid in empIdList)
{
bool existInList = false;
foreach (DailyAttnProcess dattnPs in _dAttnProcessess)
{
if (dattnPs.EmployeeID == empid)
{
existInList = true;
}
}
if (!existInList)
{
bool ExistInSavedData = false;
if (dAttnProcessess != null && dAttnProcessess.Count > 0)
{
foreach (DailyAttnProcess dAttnProcess in dAttnProcessess)
{
if (dAttnProcess.EmployeeID == empid)
{
ExistInSavedData = true;
_dAttnProcessess.Add(dAttnProcess);
}
}
}
if (!ExistInSavedData)
{
_dAttnProcess = new DailyAttnProcess();
_dAttnProcess.EmployeeID = empid;
_dAttnProcess.AttnDate = attnDate;
_dAttnProcessess.Add(_dAttnProcess);
}
}
}
//if (_dAttnProcessess != null && _dAttnProcessess.Count > 0)
//{
// int serial = 1;
// foreach (DailyAttnProcess dAttnProcess in _dAttnProcessess)
// {
// if (dAttnProcess.IsNew)
// {
// }
// }
//}
}
catch (Exception e)
{
return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
}
return Ok(_dAttnProcessess);
}
// DailyAttnProcess // DailyAttnProcess
[HttpGet("getDailyAttnProcessByEmployeeId/{employeeId}")] [HttpGet("getDailyAttnProcessByEmployeeId/{employeeId}")]