From a83c5e83f57251fa17520b2addd08a05483b7d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?= <76204082+iamsedatozturk@users.noreply.github.com> Date: Thu, 23 Oct 2025 11:35:35 +0300 Subject: [PATCH] Hr Overtime --- .../Seeds/HostData.json | 4 +- .../Seeds/ListFormsSeeder.cs | 662 +++++++++++++++++- .../Enums/TableNameEnum.cs | 3 +- .../PlatformConsts.cs | 9 +- .../TableNameResolver.cs | 3 +- .../Entities/Tenant/Hr/Employee.cs | 4 +- .../Entities/Tenant/Hr/Leave.cs | 12 +- .../Entities/Tenant/Hr/Overtime.cs | 30 + .../Queries/QueryHelper.cs | 15 +- .../EntityFrameworkCore/PlatformDbContext.cs | 33 +- ....cs => 20251023082453_Initial.Designer.cs} | 134 +++- ...9_Initial.cs => 20251023082453_Initial.cs} | 172 +++-- .../PlatformDbContextModelSnapshot.cs | 132 +++- .../DialogContext/DialogShowComponent.tsx | 8 + 14 files changed, 1125 insertions(+), 96 deletions(-) create mode 100644 api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Overtime.cs rename api/src/Kurs.Platform.EntityFrameworkCore/Migrations/{20251022102859_Initial.Designer.cs => 20251023082453_Initial.Designer.cs} (98%) rename api/src/Kurs.Platform.EntityFrameworkCore/Migrations/{20251022102859_Initial.cs => 20251023082453_Initial.cs} (98%) diff --git a/api/src/Kurs.Platform.DbMigrator/Seeds/HostData.json b/api/src/Kurs.Platform.DbMigrator/Seeds/HostData.json index 79825d5e..672fec97 100644 --- a/api/src/Kurs.Platform.DbMigrator/Seeds/HostData.json +++ b/api/src/Kurs.Platform.DbMigrator/Seeds/HostData.json @@ -15018,7 +15018,7 @@ "Code": "App.Hr.Leave", "DisplayName": "App.Hr.Leave", "Order": 8, - "Url": "/admin/hr/leave-management", + "Url": "/admin/list/list-leave", "Icon": "FcCalendar", "RequiredPermissionName": "App.Hr.Leave", "IsDisabled": false @@ -15028,7 +15028,7 @@ "Code": "App.Hr.Overtime", "DisplayName": "App.Hr.Overtime", "Order": 9, - "Url": "/admin/hr/overtimes-management", + "Url": "/admin/list/list-overtime", "Icon": "FcClock", "RequiredPermissionName": "App.Hr.Overtime", "IsDisabled": false diff --git a/api/src/Kurs.Platform.DbMigrator/Seeds/ListFormsSeeder.cs b/api/src/Kurs.Platform.DbMigrator/Seeds/ListFormsSeeder.cs index 593169d4..74b2950c 100644 --- a/api/src/Kurs.Platform.DbMigrator/Seeds/ListFormsSeeder.cs +++ b/api/src/Kurs.Platform.DbMigrator/Seeds/ListFormsSeeder.cs @@ -35399,8 +35399,8 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency new EditingFormItemDto { Order = 1, DataField = "AppliedDate", ColSpan = 2, IsRequired=true, EditorType2 = EditorTypes.dxDateBox}, new EditingFormItemDto { Order = 2, DataField = "EmployeeId", ColSpan = 2, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox }, new EditingFormItemDto { Order = 3, DataField = "LeaveType", ColSpan = 2, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox }, - new EditingFormItemDto { Order = 4, DataField = "StartDate", ColSpan = 2, IsRequired=true, EditorType2 = EditorTypes.dxDateBox, EditorScript = EditorOptionValues.DateDiffStartDateEndDate}, - new EditingFormItemDto { Order = 5, DataField = "EndDate", ColSpan = 2, IsRequired=true, EditorType2 = EditorTypes.dxDateBox, EditorScript = EditorOptionValues.DateDiffStartDateEndDate}, + new EditingFormItemDto { Order = 4, DataField = "StartDate", ColSpan = 2, IsRequired=true, EditorType2 = EditorTypes.dxDateBox, EditorScript = EditorScriptValues.CalcTotalDaysFromDates}, + new EditingFormItemDto { Order = 5, DataField = "EndDate", ColSpan = 2, IsRequired=true, EditorType2 = EditorTypes.dxDateBox, EditorScript = EditorScriptValues.CalcTotalDaysFromDates}, new EditingFormItemDto { Order = 6, DataField = "TotalDays", ColSpan = 2, EditorType2 = EditorTypes.dxNumberBox, EditorOptions = EditorOptionValues.Disabled}, new EditingFormItemDto { Order = 7, DataField = "IsHalfDay", ColSpan = 2, EditorType2 = EditorTypes.dxCheckBox}, new EditingFormItemDto { Order = 8, DataField = "Reason", ColSpan = 2, IsRequired = true, EditorType2 = EditorTypes.dxTextArea}, @@ -35654,7 +35654,7 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency RoleId = null, UserId = null, CultureName = LanguageCodes.En, - SourceDbType = DbType.Int32, + SourceDbType = DbType.Decimal, FieldName = "TotalDays", Width = 100, ListOrderNo = 6, @@ -35830,14 +35830,21 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency RoleId = null, UserId = null, CultureName = LanguageCodes.En, - SourceDbType = DbType.String, - FieldName = "ApprovedBy", + SourceDbType = DbType.Guid, + FieldName = "ApprovedById", Width = 100, ListOrderNo = 11, Visible = true, IsActive = true, IsDeleted = false, AllowSearch = true, + LookupJson = JsonSerializer.Serialize(new LookupDto + { + DataSourceType = UiLookupDataSourceTypeEnum.Query, + DisplayExpr = "name", + ValueExpr = "key", + LookupQuery = LookUpQueryValues.EmployeeValues + }), ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto { AllowReordering = true, @@ -35923,6 +35930,651 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency } #endregion + #region Overtime + if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == ListFormCodes.Lists.Overtime)) + { + var listFormOvertime = await _listFormRepository.InsertAsync( + new ListForm() + { + ListFormType = ListFormTypeEnum.List, + IsSubForm = true, + LayoutJson = JsonSerializer.Serialize(new LayoutDto() + { + Grid = true, + Card = true, + Pivot = true, + Chart = true, + DefaultLayout = "grid", + CardLayoutColumn = 3 + }), + CultureName = LanguageCodes.En, + ListFormCode = ListFormCodes.Lists.Overtime, + Name = AppCodes.Hr.Overtime, + Title = AppCodes.Hr.Overtime, + DataSourceCode = SeedConsts.DataSources.DefaultCode, + IsTenant = true, + IsBranch = false, + IsOrganizationUnit = false, + Description = AppCodes.Hr.Overtime, + SelectCommandType = SelectCommandTypeEnum.Table, + SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.Overtime)), + KeyFieldName = "Id", + KeyFieldDbSourceType = DbType.Guid, + DefaultFilter = "\"IsDeleted\" = 'false'", + SortMode = GridOptions.SortModeSingle, + FilterRowJson = JsonSerializer.Serialize(new GridFilterRowDto { Visible = true }), + HeaderFilterJson = JsonSerializer.Serialize(new { Visible = true }), + SearchPanelJson = JsonSerializer.Serialize(new { Visible = true }), + GroupPanelJson = JsonSerializer.Serialize(new { Visible = true }), + SelectionJson = JsonSerializer.Serialize(new SelectionDto + { + Mode = GridOptions.SelectionModeSingle, + AllowSelectAll = false + }), + ColumnOptionJson = JsonSerializer.Serialize(new + { + ColumnFixingEnabled = true, + ColumnAutoWidth = true, + ColumnChooserEnabled = true, + AllowColumnResizing = true, + AllowColumnReordering = true, + ColumnResizingMode = "widget", + }), + PermissionJson = JsonSerializer.Serialize(new PermissionCrudDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + D = AppCodes.Hr.Overtime + ".Delete", + E = AppCodes.Hr.Overtime + ".Export", + I = AppCodes.Hr.Overtime + ".Import", + A = AppCodes.Hr.Overtime + ".Activity", + }), + DeleteCommand = $"UPDATE \"{TableNameResolver.GetFullTableName(nameof(TableNameEnum.Overtime))}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id", + DeleteFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] { + new() { + FieldName = "DeleterId", + FieldDbType = DbType.Guid, + Value = "@USERID", + CustomValueType = FieldCustomValueTypeEnum.CustomKey }, + new() { + FieldName = "Id", + FieldDbType = DbType.Guid, + Value = "@ID", + CustomValueType = FieldCustomValueTypeEnum.CustomKey } + }), + PagerOptionJson = JsonSerializer.Serialize(new GridPagerOptionDto + { + Visible = true, + AllowedPageSizes = "10,20,50,100", + ShowPageSizeSelector = true, + ShowNavigationButtons = true, + ShowInfo = false, + InfoText = "Page {0} of {1} ({2} items)", + DisplayMode = GridColumnOptions.PagerDisplayModeAdaptive, + ScrollingMode = GridColumnOptions.ScrollingModeStandard, + LoadPanelEnabled = "auto", + LoadPanelText = "Loading..." + }), + EditingOptionJson = JsonSerializer.Serialize(new GridEditingDto + { + Popup = new GridEditingPopupDto() + { + Title = "Overtime Form", + Width = 500, + Height = 520 + }, + AllowDeleting = true, + AllowAdding = true, + AllowUpdating = true, + SendOnlyChangedFormValuesUpdate = false, + }), + InsertFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] { + new() { + FieldName = "CreationTime", + FieldDbType = DbType.DateTime, + Value = "@NOW", + CustomValueType = FieldCustomValueTypeEnum.CustomKey }, + new() { + FieldName = "CreatorId", + FieldDbType = DbType.Guid, + Value = "@USERID", + CustomValueType = FieldCustomValueTypeEnum.CustomKey }, + new() { + FieldName = "IsDeleted", + FieldDbType = DbType.Boolean, + Value = "false", + CustomValueType = FieldCustomValueTypeEnum.Value } + }), + EditingFormJson = JsonSerializer.Serialize(new List() + { + new() { + Order=1, ColCount=1, ColSpan=2, ItemType="group", Items = + [ + new EditingFormItemDto { Order = 1, DataField = "Date", ColSpan = 2, IsRequired=true, EditorType2 = EditorTypes.dxDateBox}, + new EditingFormItemDto { Order = 2, DataField = "EmployeeId", ColSpan = 2, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox }, + new EditingFormItemDto { Order = 4, DataField = "StartTime", ColSpan = 2, IsRequired=true, EditorType2 = EditorTypes.dxDateBox, EditorOptions = EditorOptionValues.TimeSpanOptions, EditorScript = EditorScriptValues.CalcTotalHoursFromTimes}, + new EditingFormItemDto { Order = 5, DataField = "EndTime", ColSpan = 2, IsRequired=true, EditorType2 = EditorTypes.dxDateBox, EditorOptions = EditorOptionValues.TimeSpanOptions, EditorScript = EditorScriptValues.CalcTotalHoursFromTimes}, + new EditingFormItemDto { Order = 6, DataField = "TotalHours", ColSpan = 2, EditorType2 = EditorTypes.dxNumberBox, EditorOptions = EditorOptionValues.Disabled}, + new EditingFormItemDto { Order = 7, DataField = "Reason", ColSpan = 2, IsRequired = true, EditorType2 = EditorTypes.dxTextArea}, + new EditingFormItemDto { Order = 8, DataField = "Rate", ColSpan = 2, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox}, + new EditingFormItemDto { Order = 9, DataField = "Amount", ColSpan = 2, EditorType2 = EditorTypes.dxNumberBox, EditorOptions = EditorOptionValues.Disabled}, + new EditingFormItemDto { Order = 10, DataField = "Status", ColSpan = 2, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox}, + ] + } + }), + FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] { + new() { + FieldName = "Status", + FieldDbType = DbType.String, + Value = "Pending", + CustomValueType = FieldCustomValueTypeEnum.Value }, + new() { + FieldName = "Date", + FieldDbType = DbType.Date, + Value = "@NOW", + CustomValueType = FieldCustomValueTypeEnum.CustomKey } + }), + CommandColumnJson = JsonSerializer.Serialize(new CommandColumnDto[] { + new() { + ButtonPosition = UiCommandButtonPositionTypeEnum.Toolbar, + Hint = "Toplu Mesai", + Text ="Toplu Mesai", + AuthName = AppCodes.Hr.Overtime + ".Update", + DialogName = "CollectiveOvertime", + DialogParameters = JsonSerializer.Serialize(new { + name = "@Name", + id = "@Id" + }) + }, + new() { + Hint = "Accept", + Text ="Accept", + UrlTarget="_blank", + AuthName = AppCodes.Hr.Overtime + ".Update", + Url="/admin/list/list-employees/@Id" + }, + new() { + Hint = "Reject", + Text ="Reject", + UrlTarget="_blank", + AuthName = AppCodes.Hr.Overtime + ".Update", + Url="/admin/list/list-employees/@Id" + }, + }), + } + ); + + #region Overtime Fields + await _listFormFieldRepository.InsertManyAsync([ + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Guid, + FieldName = "Id", + Width = 100, + ListOrderNo = 1, + Visible = false, + IsActive = true, + IsDeleted = false, + SortIndex = 0, + ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] { + new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) } + }), + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Guid, + FieldName = "EmployeeId", + Width = 200, + ListOrderNo = 2, + Visible = true, + IsActive = true, + IsDeleted = false, + SortIndex = 0, + ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] { + new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) } + }), + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + LookupJson = JsonSerializer.Serialize(new LookupDto + { + DataSourceType = UiLookupDataSourceTypeEnum.Query, + DisplayExpr = "name", + ValueExpr = "key", + LookupQuery = LookUpQueryValues.EmployeeValues + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Date, + FieldName = "StartTime", + Width = 150, + ListOrderNo = 3, + Visible = true, + IsActive = true, + IsDeleted = false, + ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] { + new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) } + }), + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Date, + FieldName = "EndTime", + Width = 150, + ListOrderNo = 4, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] { + new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) } + }), + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Decimal, + FieldName = "TotalHours", + Width = 100, + ListOrderNo = 5, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] { + new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) } + }), + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.String, + FieldName = "Reason", + Width = 250, + ListOrderNo = 6, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] { + new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) } + }), + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.String, + FieldName = "Rate", + Width = 150, + ListOrderNo = 7, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] { + new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) } + }), + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + LookupJson = JsonSerializer.Serialize(new LookupDto + { + DataSourceType = UiLookupDataSourceTypeEnum.StaticData, + DisplayExpr = "name", + ValueExpr = "key", + LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] { + new () { Key= 1.5, Name= "x1.5 (Normal Mesai)" }, + new () { Key= 2.0, Name= "x2.0 (Hafta Sonu/Tatil)" }, + new () { Key= 2.5, Name= "x2.5 (Resmi Tatil)"}, + }), + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Decimal, + FieldName = "Amount", + Width = 100, + ListOrderNo = 8, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.String, + FieldName = "Status", + Width = 100, + ListOrderNo = 9, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ValidationRuleJson = JsonSerializer.Serialize(new ValidationRuleDto[] { + new ValidationRuleDto() { Type = Enum.GetName(UiColumnValidationRuleTypeEnum.required) } + }), + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + LookupJson = JsonSerializer.Serialize(new LookupDto + { + DataSourceType = UiLookupDataSourceTypeEnum.StaticData, + DisplayExpr = "name", + ValueExpr = "key", + LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] { + new () { Key= "Pending", Name= "PENDING" }, + new () { Key= "Approved", Name= "APPROVED" }, + new () { Key= "Rejected", Name= "REJECTED"}, + new () { Key= "Cancelled", Name= "CANCELLED" }, + }), + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Date, + FieldName = "Date", + Width = 100, + ListOrderNo = 10, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Guid, + FieldName = "ApprovedById", + Width = 100, + ListOrderNo = 11, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + LookupJson = JsonSerializer.Serialize(new LookupDto + { + DataSourceType = UiLookupDataSourceTypeEnum.Query, + DisplayExpr = "name", + ValueExpr = "key", + LookupQuery = LookUpQueryValues.EmployeeValues + }), + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Date, + FieldName = "ApprovedDate", + Width = 100, + ListOrderNo = 12, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + new() { + ListFormCode = listFormOvertime.ListFormCode, + RoleId = null, + UserId = null, + CultureName = LanguageCodes.En, + SourceDbType = DbType.String, + FieldName = "RejectionReason", + Width = 250, + ListOrderNo = 13, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ColumnCustomizationJson = JsonSerializer.Serialize(new ColumnCustomizationDto + { + AllowReordering = true, + }), + PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto + { + C = AppCodes.Hr.Overtime + ".Create", + R = AppCodes.Hr.Overtime, + U = AppCodes.Hr.Overtime + ".Update", + E = true, + I = true, + Deny = false + }), + PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto + { + IsPivot = true + }) + }, + ]); + #endregion + } + #endregion + #endregion } } diff --git a/api/src/Kurs.Platform.Domain.Shared/Enums/TableNameEnum.cs b/api/src/Kurs.Platform.Domain.Shared/Enums/TableNameEnum.cs index b9861d22..0b6b03d6 100644 --- a/api/src/Kurs.Platform.Domain.Shared/Enums/TableNameEnum.cs +++ b/api/src/Kurs.Platform.Domain.Shared/Enums/TableNameEnum.cs @@ -111,5 +111,6 @@ public enum TableNameEnum Badge, CostCenter, Employee, - Leave + Leave, + Overtime } \ No newline at end of file diff --git a/api/src/Kurs.Platform.Domain.Shared/PlatformConsts.cs b/api/src/Kurs.Platform.Domain.Shared/PlatformConsts.cs index be61c74b..ba961ce0 100644 --- a/api/src/Kurs.Platform.Domain.Shared/PlatformConsts.cs +++ b/api/src/Kurs.Platform.Domain.Shared/PlatformConsts.cs @@ -23,7 +23,13 @@ public static class PlatformConsts public static string ShowClearButton = "{ \"showClearButton\" : true }"; public static string HtmlEditorOptions = "{\"toolbar\": {\"multiline\": true, \"items\": [{\"name\": \"undo\"},{\"name\": \"redo\"},{\"name\": \"separator\"},{\"name\": \"size\",\"acceptedValues\": [\"8pt\",\"10pt\",\"12pt\",\"14pt\",\"18pt\",\"24pt\",\"36pt\"],\"options\": {\"inputAttr\": {\"aria-label\": \"Font size\"}}},{\"name\": \"font\",\"acceptedValues\": [\"Arial\",\"Courier New\",\"Georgia\",\"Impact\",\"Lucida Console\",\"Tahoma\",\"Times New Roman\",\"Verdana\"],\"options\": {\"inputAttr\": {\"aria-label\": \"Font family\"}}},{\"name\": \"separator\"},{\"name\": \"bold\"},{\"name\": \"italic\"},{\"name\": \"strike\"},{\"name\": \"underline\"},{\"name\": \"separator\"},{\"name\": \"alignLeft\"},{\"name\": \"alignCenter\"},{\"name\": \"alignRight\"},{\"name\": \"alignJustify\"},{\"name\": \"separator\"},{\"name\": \"orderedList\"},{\"name\": \"bulletList\"},{\"name\": \"separator\"},{\"name\": \"header\",\"acceptedValues\": [false,1,2,3,4,5],\"options\": {\"inputAttr\": {\"aria-label\": \"Font family\"}}},{\"name\": \"separator\"},{\"name\": \"color\"},{\"name\": \"background\"},{\"name\": \"separator\"},{\"name\": \"link\"},{\"name\": \"image\"},{\"name\": \"separator\"},{\"name\": \"clear\"},{\"name\": \"codeBlock\"},{\"name\": \"blockquote\"},{\"name\": \"separator\"},{\"name\": \"insertTable\"},{\"name\": \"deleteTable\"},{\"name\": \"insertRowAbove\"},{\"name\": \"insertRowBelow\"},{\"name\": \"deleteRow\"},{\"name\": \"insertColumnLeft\"},{\"name\": \"insertColumnRight\"},{\"name\": \"deleteColumn\"}]}}"; public static string PhoneEditorOptions = "{\"format\": \"phoneGlobal\", \"mask\":\"(000) 000-0000\", \"maskInvalidMessage\":\"Lütfen geçerli bir telefon numarası girin\", \"useMaskedValue\":false, \"maskRules\": { \"X\": \"[1-9]\" }, \"placeholder\": \"(555) 123-4567\" }"; - public static string DateDiffStartDateEndDate = "(() => {const d=v=>!v?null:(v instanceof Date?v:new Date(v));const nf={...formData,[editor.dataField]:e?.value};const s=d(nf.StartDate),t=d(nf.EndDate);setFormData({...formData,TotalDays: s&&t?Math.max(0,Math.floor((Date.UTC(t.getFullYear(),t.getMonth(),t.getDate())-Date.UTC(s.getFullYear(),s.getMonth(),s.getDate()))/(24*60*60*1000))+1):null});})();"; + public static string TimeSpanOptions = "{\"type\":\"time\",\"pickerType\":\"list\",\"displayFormat\":\"HH:mm\",\"dateSerializationFormat\":\"yyyy-MM-ddTHH:mm:ss\",\"interval\":30,\"width\":\"100%\"}"; + } + + public static class EditorScriptValues + { + public static string CalcTotalDaysFromDates = "(() => {const d=v=>!v?null:(v instanceof Date?v:new Date(v));const nf={...formData,[editor.dataField]:e?.value};const s=d(nf.StartDate),t=d(nf.EndDate);setFormData({...formData,TotalDays: s&&t?Math.max(0,Math.floor((Date.UTC(t.getFullYear(),t.getMonth(),t.getDate())-Date.UTC(s.getFullYear(),s.getMonth(),s.getDate()))/(24*60*60*1000))+1):null});})();"; + public static string CalcTotalHoursFromTimes="(()=>{const toD=v=>!v?null:(v instanceof Date?v:new Date(v));const next={...formData,[e.dataField]:e.value};const s=toD(next.StartTime),t=toD(next.EndTime);let h=null;if(s&&t){h=(t-s)/36e5;if(h<0)h+=24;h=Math.round(h*10)/10;}setFormData({...next,TotalHours:h});})();"; } public static class Prefix @@ -508,6 +514,7 @@ public static class PlatformConsts public const string CostCenter = "list-costcenter"; public const string Employee = "list-employee"; public const string Leave = "list-leave"; + public const string Overtime = "list-overtime"; } } diff --git a/api/src/Kurs.Platform.Domain.Shared/TableNameResolver.cs b/api/src/Kurs.Platform.Domain.Shared/TableNameResolver.cs index 5ea0890d..8dc93cd2 100644 --- a/api/src/Kurs.Platform.Domain.Shared/TableNameResolver.cs +++ b/api/src/Kurs.Platform.Domain.Shared/TableNameResolver.cs @@ -43,10 +43,10 @@ public static class TableNameResolver { nameof(TableNameEnum.ForumPost), (PlatformConsts.TablePrefix.PlatformByName, MenuPrefix.Saas) }, // 🔹 TENANT TABLOLARI (GENEL) + { nameof(TableNameEnum.Activity), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Saas) }, { nameof(TableNameEnum.Branch), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Saas) }, { nameof(TableNameEnum.BranchUsers), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Saas) }, { nameof(TableNameEnum.GlobalSearch), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Saas) }, - { nameof(TableNameEnum.Activity), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Platform) }, { nameof(TableNameEnum.CustomEntity), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Saas) }, { nameof(TableNameEnum.CustomEntityField), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Saas) }, { nameof(TableNameEnum.ApiMigration), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Saas) }, @@ -129,6 +129,7 @@ public static class TableNameResolver { nameof(TableNameEnum.CostCenter), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Hr) }, { nameof(TableNameEnum.Employee), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Hr) }, { nameof(TableNameEnum.Leave), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Hr) }, + { nameof(TableNameEnum.Overtime), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Hr) }, // 🔹 ACCOUNTING { nameof(TableNameEnum.Bank), (PlatformConsts.TablePrefix.TenantByName, MenuPrefix.Accounting) }, diff --git a/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Employee.cs b/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Employee.cs index 87d70290..9afd1a80 100644 --- a/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Employee.cs +++ b/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Employee.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; @@ -66,7 +67,8 @@ public class Employee : FullAuditedEntity, IMultiTenant public bool IsActive { get; set; } // Navigation lists (placeholders) - // public ICollection Leaves { get; set; } + public ICollection Overtimes { get; set; } + public ICollection Leaves { get; set; } // public ICollection Evaluations { get; set; } // public ICollection Trainings { get; set; } // public ICollection DisciplinaryActions { get; set; } diff --git a/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Leave.cs b/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Leave.cs index 06339d3c..74bac413 100644 --- a/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Leave.cs +++ b/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Leave.cs @@ -10,16 +10,18 @@ public class Leave : FullAuditedEntity, IMultiTenant public Guid? TenantId { get; set; } public Guid EmployeeId { get; set; } + public Employee Employee { get; set; } + public string LeaveType { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } - public double TotalDays { get; set; } + public decimal TotalDays { get; set; } public bool IsHalfDay { get; set; } - public string? Reason { get; set; } + public string Reason { get; set; } public string Status { get; set; } public DateTime AppliedDate { get; set; } - public string? ApprovedBy { get; set; } + public Guid? ApprovedById { get; set; } public DateTime? ApprovedDate { get; set; } - public string? RejectionReason { get; set; } - public string? Attachments { get; set; } // JSON string (from string[]) + public string RejectionReason { get; set; } + public string Attachments { get; set; } // JSON string (from string[]) } diff --git a/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Overtime.cs b/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Overtime.cs new file mode 100644 index 00000000..e7490cd9 --- /dev/null +++ b/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/Overtime.cs @@ -0,0 +1,30 @@ +// Domain/Entities/HrOvertime.cs +using System; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; + +namespace Kurs.Platform.Entities +{ + // İnsan Kaynakları Fazla Mesai + public class Overtime : FullAuditedEntity, IMultiTenant + { + public Guid? TenantId { get; set; } + + // İlişkisel alanlar + public Guid EmployeeId { get; set; } + public Employee Employee { get; set; } + + // Fazla mesai detayları + public DateTime Date { get; set; } + public DateTime StartTime { get; set; } + public DateTime EndTime { get; set; } + public decimal TotalHours { get; set; } + public string Reason { get; set; } + public string Status { get; set; } + public Guid? ApprovedById { get; set; } + public DateTime? ApprovedDate { get; set; } + public string RejectionReason { get; set; } + public decimal Rate { get; set; } + public decimal? Amount { get; set; } + } +} diff --git a/api/src/Kurs.Platform.Domain/Queries/QueryHelper.cs b/api/src/Kurs.Platform.Domain/Queries/QueryHelper.cs index be90fbaf..ede06c78 100644 --- a/api/src/Kurs.Platform.Domain/Queries/QueryHelper.cs +++ b/api/src/Kurs.Platform.Domain/Queries/QueryHelper.cs @@ -88,8 +88,19 @@ public class QueryHelper case DbType.UInt16: case DbType.UInt32: case DbType.UInt64: - var intValues = values.Select(a => double.Parse(a.ToString())).ToArray(); - value = isArray ? intValues : intValues[0]; + var numericValues = values.Select(a => + { + if (a == null) + return (double?)null; + + var s = a.ToString(); + if (string.IsNullOrWhiteSpace(s)) + return (double?)null; + + return double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out var n) ? n : (double?)null; + }).ToArray(); + + value = isArray ? numericValues : numericValues[0]; break; case DbType.Boolean: var boolValues = values.Select(a => a != null && a.ToString().ToLower() != "false" && a.ToString() != "0").ToArray(); diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs b/api/src/Kurs.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs index 78c3044e..796990e4 100644 --- a/api/src/Kurs.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs +++ b/api/src/Kurs.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs @@ -1780,16 +1780,43 @@ public class PlatformDbContext : b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.Leave)), Prefix.DbSchema); b.ConfigureByConvention(); - b.Property(x => x.EmployeeId).IsRequired().HasMaxLength(20); + b.Property(x => x.EmployeeId).IsRequired(); b.Property(x => x.LeaveType).IsRequired(); b.Property(x => x.StartDate).IsRequired(); b.Property(x => x.EndDate).IsRequired(); - b.Property(x => x.TotalDays).IsRequired(); + b.Property(x => x.TotalDays).HasPrecision(18, 2); b.Property(x => x.Reason).HasMaxLength(500); b.Property(x => x.Status).IsRequired().HasMaxLength(20); b.Property(x => x.RejectionReason).HasMaxLength(500); - b.Property(x => x.ApprovedBy).HasMaxLength(100); b.Property(x => x.Attachments).HasMaxLength(2000); + + b.HasOne(x => x.Employee) + .WithMany(e => e.Leaves) + .HasForeignKey(x => x.EmployeeId) + .HasPrincipalKey(e => e.Id) + .OnDelete(DeleteBehavior.Restrict); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.Overtime)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.EmployeeId).IsRequired(); + b.Property(x => x.Date).IsRequired(); + b.Property(x => x.StartTime).IsRequired().HasMaxLength(10); + b.Property(x => x.EndTime).IsRequired().HasMaxLength(10); + b.Property(x => x.TotalHours).IsRequired().HasPrecision(18, 2); + b.Property(x => x.Reason).HasMaxLength(1000); + b.Property(x => x.Status).IsRequired(); + b.Property(x => x.Rate).IsRequired().HasPrecision(18, 2); + b.Property(x => x.Amount).HasPrecision(18, 2); + + b.HasOne(x => x.Employee) + .WithMany(e => e.Overtimes) + .HasForeignKey(x => x.EmployeeId) + .HasPrincipalKey(e => e.Id) + .OnDelete(DeleteBehavior.Restrict); }); } } diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251022102859_Initial.Designer.cs b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251023082453_Initial.Designer.cs similarity index 98% rename from api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251022102859_Initial.Designer.cs rename to api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251023082453_Initial.Designer.cs index e773f445..3c04ef8c 100644 --- a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251022102859_Initial.Designer.cs +++ b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251023082453_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace Kurs.Platform.Migrations { [DbContext(typeof(PlatformDbContext))] - [Migration("20251022102859_Initial")] + [Migration("20251023082453_Initial")] partial class Initial { /// @@ -689,7 +689,7 @@ namespace Kurs.Platform.Migrations b.HasKey("Id"); - b.ToTable("T_P_Activity", (string)null); + b.ToTable("T_Sas_Activity", (string)null); }); modelBuilder.Entity("Kurs.Platform.Entities.AiBot", b => @@ -4246,15 +4246,13 @@ namespace Kurs.Platform.Migrations modelBuilder.Entity("Kurs.Platform.Entities.Leave", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("AppliedDate") .HasColumnType("datetime2"); - b.Property("ApprovedBy") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); + b.Property("ApprovedById") + .HasColumnType("uniqueidentifier"); b.Property("ApprovedDate") .HasColumnType("datetime2"); @@ -4280,7 +4278,6 @@ namespace Kurs.Platform.Migrations .HasColumnName("DeletionTime"); b.Property("EmployeeId") - .HasMaxLength(20) .HasColumnType("uniqueidentifier"); b.Property("EndDate") @@ -4327,11 +4324,14 @@ namespace Kurs.Platform.Migrations .HasColumnType("uniqueidentifier") .HasColumnName("TenantId"); - b.Property("TotalDays") - .HasColumnType("float"); + b.Property("TotalDays") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); b.HasKey("Id"); + b.HasIndex("EmployeeId"); + b.ToTable("T_Hr_Leave", (string)null); }); @@ -5660,6 +5660,93 @@ namespace Kurs.Platform.Migrations b.ToTable("T_Adm_OrderItem", (string)null); }); + modelBuilder.Entity("Kurs.Platform.Entities.Overtime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(18,2)"); + + b.Property("ApprovedById") + .HasColumnType("uniqueidentifier"); + + b.Property("ApprovedDate") + .HasColumnType("datetime2"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EmployeeId") + .HasColumnType("uniqueidentifier"); + + b.Property("EndTime") + .HasMaxLength(10) + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Rate") + .HasColumnType("decimal(18,2)"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("RejectionReason") + .HasColumnType("nvarchar(max)"); + + b.Property("StartTime") + .HasMaxLength(10) + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalHours") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.ToTable("T_Hr_Overtime", (string)null); + }); + modelBuilder.Entity("Kurs.Platform.Entities.PaymentMethod", b => { b.Property("Id") @@ -10056,6 +10143,17 @@ namespace Kurs.Platform.Migrations b.Navigation("Department"); }); + modelBuilder.Entity("Kurs.Platform.Entities.Leave", b => + { + b.HasOne("Kurs.Platform.Entities.Employee", "Employee") + .WithMany("Leaves") + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + }); + modelBuilder.Entity("Kurs.Platform.Entities.Level", b => { b.HasOne("Kurs.Platform.Entities.ClassType", "ClassType") @@ -10117,6 +10215,17 @@ namespace Kurs.Platform.Migrations b.Navigation("Order"); }); + modelBuilder.Entity("Kurs.Platform.Entities.Overtime", b => + { + b.HasOne("Kurs.Platform.Entities.Employee", "Employee") + .WithMany("Overtimes") + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + }); + modelBuilder.Entity("Kurs.Platform.Entities.Question", b => { b.HasOne("Kurs.Platform.Entities.QuestionPool", "QuestionPool") @@ -10463,6 +10572,13 @@ namespace Kurs.Platform.Migrations b.Navigation("SubDepartments"); }); + modelBuilder.Entity("Kurs.Platform.Entities.Employee", b => + { + b.Navigation("Leaves"); + + b.Navigation("Overtimes"); + }); + modelBuilder.Entity("Kurs.Platform.Entities.Event", b => { b.Navigation("Comments"); diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251022102859_Initial.cs b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251023082453_Initial.cs similarity index 98% rename from api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251022102859_Initial.cs rename to api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251023082453_Initial.cs index 6a80cb92..adeee715 100644 --- a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251022102859_Initial.cs +++ b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251023082453_Initial.cs @@ -1798,63 +1798,6 @@ namespace Kurs.Platform.Migrations table.PrimaryKey("PK_T_Hr_EmploymentType", x => x.Id); }); - migrationBuilder.CreateTable( - name: "T_Hr_Leave", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - EmployeeId = table.Column(type: "uniqueidentifier", maxLength: 20, nullable: false), - LeaveType = table.Column(type: "nvarchar(max)", nullable: false), - StartDate = table.Column(type: "datetime2", nullable: false), - EndDate = table.Column(type: "datetime2", nullable: false), - TotalDays = table.Column(type: "float", nullable: false), - IsHalfDay = table.Column(type: "bit", nullable: false), - Reason = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), - Status = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: false), - AppliedDate = table.Column(type: "datetime2", nullable: false), - ApprovedBy = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: true), - ApprovedDate = table.Column(type: "datetime2", nullable: true), - RejectionReason = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), - Attachments = table.Column(type: "nvarchar(2000)", maxLength: 2000, nullable: true), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true), - LastModificationTime = table.Column(type: "datetime2", nullable: true), - LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), - IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), - DeleterId = table.Column(type: "uniqueidentifier", nullable: true), - DeletionTime = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_T_Hr_Leave", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "T_P_Activity", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - EntityName = table.Column(type: "nvarchar(max)", nullable: true), - EntityId = table.Column(type: "nvarchar(max)", nullable: true), - Type = table.Column(type: "nvarchar(max)", nullable: false), - Subject = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - Content = table.Column(type: "nvarchar(2000)", maxLength: 2000, nullable: false), - FilesJson = table.Column(type: "nvarchar(max)", nullable: true), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true), - LastModificationTime = table.Column(type: "datetime2", nullable: true), - LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), - IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), - DeleterId = table.Column(type: "uniqueidentifier", nullable: true), - DeletionTime = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_T_P_Activity", x => x.Id); - }); - migrationBuilder.CreateTable( name: "T_Prt_Interesting", columns: table => new @@ -1983,6 +1926,31 @@ namespace Kurs.Platform.Migrations table.PrimaryKey("PK_T_Prt_Source", x => x.Id); }); + migrationBuilder.CreateTable( + name: "T_Sas_Activity", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + EntityName = table.Column(type: "nvarchar(max)", nullable: true), + EntityId = table.Column(type: "nvarchar(max)", nullable: true), + Type = table.Column(type: "nvarchar(max)", nullable: false), + Subject = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Content = table.Column(type: "nvarchar(2000)", maxLength: 2000, nullable: false), + FilesJson = table.Column(type: "nvarchar(max)", nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_Sas_Activity", x => x.Id); + }); + migrationBuilder.CreateTable( name: "T_Sas_Branch", columns: table => new @@ -3968,6 +3936,81 @@ namespace Kurs.Platform.Migrations principalColumn: "Id"); }); + migrationBuilder.CreateTable( + name: "T_Hr_Leave", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + EmployeeId = table.Column(type: "uniqueidentifier", nullable: false), + LeaveType = table.Column(type: "nvarchar(max)", nullable: false), + StartDate = table.Column(type: "datetime2", nullable: false), + EndDate = table.Column(type: "datetime2", nullable: false), + TotalDays = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false), + IsHalfDay = table.Column(type: "bit", nullable: false), + Reason = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), + Status = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: false), + AppliedDate = table.Column(type: "datetime2", nullable: false), + ApprovedById = table.Column(type: "uniqueidentifier", nullable: true), + ApprovedDate = table.Column(type: "datetime2", nullable: true), + RejectionReason = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), + Attachments = table.Column(type: "nvarchar(2000)", maxLength: 2000, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_Hr_Leave", x => x.Id); + table.ForeignKey( + name: "FK_T_Hr_Leave_T_Hr_Employee_EmployeeId", + column: x => x.EmployeeId, + principalTable: "T_Hr_Employee", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "T_Hr_Overtime", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + EmployeeId = table.Column(type: "uniqueidentifier", nullable: false), + Date = table.Column(type: "datetime2", nullable: false), + StartTime = table.Column(type: "datetime2", maxLength: 10, nullable: false), + EndTime = table.Column(type: "datetime2", maxLength: 10, nullable: false), + TotalHours = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false), + Reason = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + Status = table.Column(type: "nvarchar(max)", nullable: false), + ApprovedById = table.Column(type: "uniqueidentifier", nullable: true), + ApprovedDate = table.Column(type: "datetime2", nullable: true), + RejectionReason = table.Column(type: "nvarchar(max)", nullable: true), + Rate = table.Column(type: "decimal(18,2)", nullable: false), + Amount = table.Column(type: "decimal(18,2)", nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_Hr_Overtime", x => x.Id); + table.ForeignKey( + name: "FK_T_Hr_Overtime_T_Hr_Employee_EmployeeId", + column: x => x.EmployeeId, + principalTable: "T_Hr_Employee", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + migrationBuilder.CreateIndex( name: "IX_AbpAuditLogActions_AuditLogId", table: "AbpAuditLogActions", @@ -4597,6 +4640,16 @@ namespace Kurs.Platform.Migrations table: "T_Hr_JobPosition", column: "DepartmentId"); + migrationBuilder.CreateIndex( + name: "IX_T_Hr_Leave_EmployeeId", + table: "T_Hr_Leave", + column: "EmployeeId"); + + migrationBuilder.CreateIndex( + name: "IX_T_Hr_Overtime_EmployeeId", + table: "T_Hr_Overtime", + column: "EmployeeId"); + migrationBuilder.CreateIndex( name: "IX_T_Sas_ApiEndpoint_EntityId", table: "T_Sas_ApiEndpoint", @@ -4923,7 +4976,7 @@ namespace Kurs.Platform.Migrations name: "T_Hr_Leave"); migrationBuilder.DropTable( - name: "T_P_Activity"); + name: "T_Hr_Overtime"); migrationBuilder.DropTable( name: "T_Prt_Interesting"); @@ -4943,6 +4996,9 @@ namespace Kurs.Platform.Migrations migrationBuilder.DropTable( name: "T_Prt_Source"); + migrationBuilder.DropTable( + name: "T_Sas_Activity"); + migrationBuilder.DropTable( name: "T_Sas_ApiEndpoint"); diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs index f74c2d23..77531725 100644 --- a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs +++ b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs @@ -686,7 +686,7 @@ namespace Kurs.Platform.Migrations b.HasKey("Id"); - b.ToTable("T_P_Activity", (string)null); + b.ToTable("T_Sas_Activity", (string)null); }); modelBuilder.Entity("Kurs.Platform.Entities.AiBot", b => @@ -4243,15 +4243,13 @@ namespace Kurs.Platform.Migrations modelBuilder.Entity("Kurs.Platform.Entities.Leave", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("AppliedDate") .HasColumnType("datetime2"); - b.Property("ApprovedBy") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); + b.Property("ApprovedById") + .HasColumnType("uniqueidentifier"); b.Property("ApprovedDate") .HasColumnType("datetime2"); @@ -4277,7 +4275,6 @@ namespace Kurs.Platform.Migrations .HasColumnName("DeletionTime"); b.Property("EmployeeId") - .HasMaxLength(20) .HasColumnType("uniqueidentifier"); b.Property("EndDate") @@ -4324,11 +4321,14 @@ namespace Kurs.Platform.Migrations .HasColumnType("uniqueidentifier") .HasColumnName("TenantId"); - b.Property("TotalDays") - .HasColumnType("float"); + b.Property("TotalDays") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); b.HasKey("Id"); + b.HasIndex("EmployeeId"); + b.ToTable("T_Hr_Leave", (string)null); }); @@ -5657,6 +5657,93 @@ namespace Kurs.Platform.Migrations b.ToTable("T_Adm_OrderItem", (string)null); }); + modelBuilder.Entity("Kurs.Platform.Entities.Overtime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(18,2)"); + + b.Property("ApprovedById") + .HasColumnType("uniqueidentifier"); + + b.Property("ApprovedDate") + .HasColumnType("datetime2"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EmployeeId") + .HasColumnType("uniqueidentifier"); + + b.Property("EndTime") + .HasMaxLength(10) + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Rate") + .HasColumnType("decimal(18,2)"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("RejectionReason") + .HasColumnType("nvarchar(max)"); + + b.Property("StartTime") + .HasMaxLength(10) + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalHours") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.ToTable("T_Hr_Overtime", (string)null); + }); + modelBuilder.Entity("Kurs.Platform.Entities.PaymentMethod", b => { b.Property("Id") @@ -10053,6 +10140,17 @@ namespace Kurs.Platform.Migrations b.Navigation("Department"); }); + modelBuilder.Entity("Kurs.Platform.Entities.Leave", b => + { + b.HasOne("Kurs.Platform.Entities.Employee", "Employee") + .WithMany("Leaves") + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + }); + modelBuilder.Entity("Kurs.Platform.Entities.Level", b => { b.HasOne("Kurs.Platform.Entities.ClassType", "ClassType") @@ -10114,6 +10212,17 @@ namespace Kurs.Platform.Migrations b.Navigation("Order"); }); + modelBuilder.Entity("Kurs.Platform.Entities.Overtime", b => + { + b.HasOne("Kurs.Platform.Entities.Employee", "Employee") + .WithMany("Overtimes") + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Employee"); + }); + modelBuilder.Entity("Kurs.Platform.Entities.Question", b => { b.HasOne("Kurs.Platform.Entities.QuestionPool", "QuestionPool") @@ -10460,6 +10569,13 @@ namespace Kurs.Platform.Migrations b.Navigation("SubDepartments"); }); + modelBuilder.Entity("Kurs.Platform.Entities.Employee", b => + { + b.Navigation("Leaves"); + + b.Navigation("Overtimes"); + }); + modelBuilder.Entity("Kurs.Platform.Entities.Event", b => { b.Navigation("Comments"); diff --git a/ui/src/views/shared/DialogContext/DialogShowComponent.tsx b/ui/src/views/shared/DialogContext/DialogShowComponent.tsx index ab60cb7f..ef070a70 100644 --- a/ui/src/views/shared/DialogContext/DialogShowComponent.tsx +++ b/ui/src/views/shared/DialogContext/DialogShowComponent.tsx @@ -83,6 +83,14 @@ const DialogShowComponent = (): JSX.Element => { {...dialogContext.config?.props} > ) + case 'CollectiveOvertime': + return ( + + ) default: return <> }