diff --git a/.gitignore b/.gitignore index f925975..d27c6dc 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ obj /OnlineSalesAutoCrop/App_Data/RadUploadTemp /OnlineSalesAutoCrop/App/ClientApp/node_modules /App/ClientApp/node_modules +/Api/OnlineSalesAutoCrop.CoreAPI/.config/dotnet-tools.json diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/CustomerIntegration.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/CustomerIntegration.cs index 9de001e..9334dfb 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/CustomerIntegration.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/CustomerIntegration.cs @@ -1,57 +1,42 @@ -namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations; +using System.ComponentModel.DataAnnotations; + +namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations; public class CustomerIntegration { - public int CustomerId { get; set; } - public string CustomerNumber { get; set; } - public string CustomerName { get; set; } - - public string AccountGroup { get; set; } - public string AccountGroupDescription { get; set; } - - public string CompanyCode { get; set; } - public string CompanyCodeDescription { get; set; } - - public string SalesOrganization { get; set; } - public string SalesOrganizationDescription { get; set; } - - public string DistributionChannel { get; set; } - public string DistributionChannelDescription { get; set; } - - public string Division { get; set; } - public string DivisionDescription { get; set; } - - public string MobileNumber { get; set; } - public string EmailAddress { get; set; } - - public string BusinessTaxNumber { get; set; } - - public decimal? CreditLimit { get; set; } - - public string SalesOffice { get; set; } - public string SalesOfficeDescription { get; set; } - - public string SalesGroup { get; set; } - public string CustomerGroup { get; set; } - - public string Status { get; set; } - - public string PaymentTerms { get; set; } - - public string SearchTerm { get; set; } - - public string Region { get; set; } - public string RegionName { get; set; } - - public string Area { get; set; } - public string AreaName { get; set; } - - public string SalesUnit { get; set; } - public string SalesUnitName { get; set; } - - public string Territory { get; set; } - public string TerritoryName { get; set; } - + public string CustomerNumber { get; set; } + public string CustomerName { get; set; } + public string AccountGroup { get; set; } + public string AccountGroupDescription { get; set; } + public string CompanyCode { get; set; } + public string CompanyCodeDescription { get; set; } + public string SalesOrganization { get; set; } + public string SalesOrganizationDescription { get; set; } + public string DistributionChannel { get; set; } + public string DistributionChannelDescription { get; set; } + public string Division { get; set; } + public string DivisionDescription { get; set; } + public string MobileNumber { get; set; } + public string EmailAddress { get; set; } + public string BusinessTaxNumber { get; set; } + public decimal CreditLimit { get; set; } + public string SalesGroup { get; set; } + public string SalesGroupDescription { get; set; } + public string CustomerGroup { get; set; } + public string CustomerGroupDescription { get; set; } + public string CustomerPriceGroup { get; set; } + public string CustomerPriceGroupDescription { get; set; } + public string StatusCode { get; set; } + public string StatusDescription { get; set; } + public string PaymentTerms { get; set; } + public string PaymentTermsDescription { get; set; } + public string SearchTerm { get; set; } + public string AreaRegion { get; set; } + public string AreaRegionDescription { get; set; } + public string SalesUnitAreaAV { get; set; } + public string SalesUnitAreaAVDescription { get; set; } + public string Territory { get; set; } + public string TerritoryName { get; set; } public string Plant { get; set; } public string PlantName { get; set; } } \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/EmployeeIntegration.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/EmployeeIntegration.cs new file mode 100644 index 0000000..66cc82b --- /dev/null +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/EmployeeIntegration.cs @@ -0,0 +1,29 @@ +namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations; + +public class EmployeeIntegration +{ + public string EmployeeVendorCode { get; set; } + public string EmployeeVendorName { get; set; } + public string Designation { get; set; } + public string DesignationDescription { get; set; } + public string MobileNo { get; set; } + public string Mail { get; set; } + public string CompanyCode { get; set; } + public string CompanyName { get; set; } + public string SalesOrg { get; set; } + public string SalesOrgDescription { get; set; } + public string DistChannel { get; set; } + public string DistChannelDescription { get; set; } + public string Division { get; set; } + public string DivisionDescription { get; set; } + public string RegionAreaCode { get; set; } + public string RegionAreaDescription { get; set; } + public string AreaAVSalesUnitCode { get; set; } + public string AreaAVSalesUnitDescription { get; set; } + public string Territory { get; set; } + public string TerritoryDescription { get; set; } + public string Plant { get; set; } + public string PlantDescription { get; set; } + public string Status { get; set; } + public string StatusDescription { get; set; } +} diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/MaterialIntegration.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/MaterialIntegration.cs new file mode 100644 index 0000000..fa456d9 --- /dev/null +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/MaterialIntegration.cs @@ -0,0 +1,26 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations; + +public class MaterialIntegration +{ + public int MeterialId { get; set; } + public string MaterialType { get; set; } + public string MaterialTypeDescription { get; set; } + public string MaterialCode { get; set; } + public string MaterialDescription { get; set; } + public string MaterialGroupCode { get; set; } + public string MaterialGroupDescription { get; set; } + public string BaseUnitOfMeasure { get; set; } + public string SalesUnitOfMeasure { get; set; } + public decimal UnitConversionWithBaseUoM { get; set; } + public string PlantCode { get; set; } + public string PlantDescription { get; set; } + public string StorageLocationCode { get; set; } + public string StorageLocationDescription { get; set; } + public string SalesOrganization { get; set; } + public string SalesOrganizationDescription { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? UpdatedDate { get; set; } +} diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/CustomerIntegrationRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/CustomerIntegrationRequest.cs index 66fd027..ab15784 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/CustomerIntegrationRequest.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/CustomerIntegrationRequest.cs @@ -7,141 +7,150 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; public class CustomerIntegrationRequest { - [Required(ErrorMessage = "Customer Number is required")] - [StringLength(10, MinimumLength = 1, ErrorMessage = "Customer Number must be between 1 and 10 characters")] - public string CustomerNumber { get; set; } = string.Empty; + [Required(ErrorMessage = "Customer number is required.")] + [StringLength(10, ErrorMessage = "Customer number cannot exceed 10 characters.")] + public string CustomerNumber { get; set; } - [Required(ErrorMessage = "Customer Name is required")] - [StringLength(35, MinimumLength = 1, ErrorMessage = "Customer Name must be between 1 and 35 characters")] - public string CustomerName { get; set; } = string.Empty; + [Required(ErrorMessage = "Customer name is required.")] + [StringLength(35, ErrorMessage = "Customer name cannot exceed 35 characters.")] + public string CustomerName { get; set; } - [Required(ErrorMessage = "Account Group is required")] - [StringLength(3, MinimumLength = 1, ErrorMessage = "Account Group must be between 1 and 3 characters")] - public string AccountGroup { get; set; } = string.Empty; + [Required(ErrorMessage = "Account group is required.")] + [StringLength(4, ErrorMessage = "Account group cannot exceed 3 characters.")] + public string AccountGroup { get; set; } - [Required(ErrorMessage = "Account Group Description is required")] - [StringLength(30, ErrorMessage = "Account Group Description cannot exceed 30 characters")] - public string AccountGroupDescription { get; set; } = string.Empty; + [Required(ErrorMessage = "Account group description is required.")] + [StringLength(30, ErrorMessage = "Account group description cannot exceed 30 characters.")] + public string AccountGroupDescription { get; set; } - [Required(ErrorMessage = "Company Code is required")] - [StringLength(4, MinimumLength = 1, ErrorMessage = "Company Code must be between 1 and 4 characters")] - public string CompanyCode { get; set; } = string.Empty; + [Required(ErrorMessage = "Company code is required.")] + [StringLength(4, ErrorMessage = "Company code cannot exceed 4 characters.")] + public string CompanyCode { get; set; } - [Required(ErrorMessage = "Company Code Description is required")] - [StringLength(25, ErrorMessage = "Company Code Description cannot exceed 25 characters")] - public string CompanyCodeDescription { get; set; } = string.Empty; + [Required(ErrorMessage = "Company code description is required.")] + [StringLength(25, ErrorMessage = "Company code description cannot exceed 25 characters.")] + public string CompanyCodeDescription { get; set; } - [Required(ErrorMessage = "Sales Organization is required")] - [StringLength(4, MinimumLength = 1, ErrorMessage = "Sales Organization must be between 1 and 4 characters")] - public string SalesOrganization { get; set; } = string.Empty; + [Required(ErrorMessage = "Sales organization is required.")] + [StringLength(4, ErrorMessage = "Sales organization cannot exceed 4 characters.")] + public string SalesOrganization { get; set; } - [Required(ErrorMessage = "Sales Organization Description is required")] - [StringLength(40, ErrorMessage = "Sales Organization Description cannot exceed 40 characters")] - public string SalesOrganizationDescription { get; set; } = string.Empty; + [Required(ErrorMessage = "Sales organization description is required.")] + [StringLength(40, ErrorMessage = "Sales organization description cannot exceed 40 characters.")] + public string SalesOrganizationDescription { get; set; } - [Required(ErrorMessage = "Distribution Channel is required")] - [StringLength(2, MinimumLength = 1, ErrorMessage = "Distribution Channel must be between 1 and 2 characters")] - public string DistributionChannel { get; set; } = string.Empty; + [Required(ErrorMessage = "Distribution channel is required.")] + [StringLength(2, ErrorMessage = "Distribution channel cannot exceed 2 characters.")] + public string DistributionChannel { get; set; } - [Required(ErrorMessage = "Distribution Channel Description is required")] - [StringLength(20, ErrorMessage = "Distribution Channel Description cannot exceed 20 characters")] - public string DistributionChannelDescription { get; set; } = string.Empty; + [Required(ErrorMessage = "Distribution channel description is required.")] + [StringLength(20, ErrorMessage = "Distribution channel description cannot exceed 20 characters.")] + public string DistributionChannelDescription { get; set; } - [Required(ErrorMessage = "Division is required")] - [StringLength(2, MinimumLength = 1, ErrorMessage = "Division must be between 1 and 2 characters")] - public string Division { get; set; } = string.Empty; + [Required(ErrorMessage = "Division is required.")] + [StringLength(2, ErrorMessage = "Division cannot exceed 2 characters.")] + public string Division { get; set; } - [Required(ErrorMessage = "Division Description is required")] - [StringLength(20, ErrorMessage = "Division Description cannot exceed 20 characters")] - public string DivisionDescription { get; set; } = string.Empty; + [Required(ErrorMessage = "Division description is required.")] + [StringLength(20, ErrorMessage = "Division description cannot exceed 20 characters.")] + public string DivisionDescription { get; set; } - [Required(ErrorMessage = "Mobile Number is required")] - [StringLength(31, ErrorMessage = "Mobile Number cannot exceed 31 characters")] - [Phone(ErrorMessage = "Invalid mobile number format")] - public string MobileNumber { get; set; } = string.Empty; + [Required(ErrorMessage = "Mobile number is required.")] + [StringLength(31, ErrorMessage = "Mobile number cannot exceed 31 characters.")] + [Phone(ErrorMessage = "Mobile number is not a valid phone number.")] + public string MobileNumber { get; set; } - [Required(ErrorMessage = "Email Address is required")] - [StringLength(241, ErrorMessage = "Email Address cannot exceed 241 characters")] - [EmailAddress(ErrorMessage = "Invalid email address format")] - public string EmailAddress { get; set; } = string.Empty; + [Required(ErrorMessage = "Email address is required.")] + [StringLength(241, ErrorMessage = "Email address cannot exceed 241 characters.")] + [EmailAddress(ErrorMessage = "Email address is not valid.")] + public string EmailAddress { get; set; } - [Required(ErrorMessage = "Business/Tax Number is required")] - [StringLength(16, ErrorMessage = "Business/Tax Number cannot exceed 16 characters")] - public string BusinessTaxNumber { get; set; } = string.Empty; + [Required(ErrorMessage = "Business/Tax number is required.")] + [StringLength(16, ErrorMessage = "Business/Tax number cannot exceed 16 characters.")] + public string BusinessTaxNumber { get; set; } - [Required(ErrorMessage = "Credit Limit is required")] - [Range(0, 9999999999999, ErrorMessage = "Credit Limit must be a valid number")] + [Required(ErrorMessage = "Credit limit is required.")] + [Range(0, 9999999999999.99, ErrorMessage = "Credit limit must be between 0 and 9,999,999,999,999.99.")] public decimal CreditLimit { get; set; } - [Required(ErrorMessage = "Sales Office is required")] - [StringLength(4, MinimumLength = 1, ErrorMessage = "Sales Office must be between 1 and 4 characters")] - public string SalesOffice { get; set; } = string.Empty; + [Required(ErrorMessage = "Sales group is required.")] + [StringLength(3, ErrorMessage = "Sales group cannot exceed 3 characters.")] + public string SalesGroup { get; set; } - [StringLength(255, ErrorMessage = "Sales Office Description cannot exceed 255 characters")] - public string? SalesOfficeDescription { get; set; } + [Required(ErrorMessage = "Sales group description is required.")] + [StringLength(20, ErrorMessage = "Sales group description cannot exceed 20 characters.")] + public string SalesGroupDescription { get; set; } - [Required(ErrorMessage = "Sales Group is required")] - [StringLength(3, MinimumLength = 1, ErrorMessage = "Sales Group must be between 1 and 3 characters")] - public string SalesGroup { get; set; } = string.Empty; + [Required(ErrorMessage = "Customer group is required.")] + [StringLength(2, ErrorMessage = "Customer group cannot exceed 2 characters.")] + public string CustomerGroup { get; set; } - [Required(ErrorMessage = "Customer Group is required")] - [StringLength(2, MinimumLength = 1, ErrorMessage = "Customer Group must be between 1 and 2 characters")] - public string CustomerGroup { get; set; } = string.Empty; + [Required(ErrorMessage = "Customer group description is required.")] + [StringLength(20, ErrorMessage = "Customer group description cannot exceed 20 characters.")] + public string CustomerGroupDescription { get; set; } - [Required(ErrorMessage = "Status is required")] - [StringLength(1, MinimumLength = 1, ErrorMessage = "Status must be exactly 1 character")] - public string Status { get; set; } = string.Empty; + [Required(ErrorMessage = "Customer price group is required.")] + [StringLength(2, ErrorMessage = "Customer price group cannot exceed 2 characters.")] + public string CustomerPriceGroup { get; set; } - [Required(ErrorMessage = "Payment Terms are required")] - [StringLength(4, MinimumLength = 1, ErrorMessage = "Payment Terms must be between 1 and 4 characters")] - public string PaymentTerms { get; set; } = string.Empty; + [Required(ErrorMessage = "Customer price group description is required.")] + [StringLength(20, ErrorMessage = "Customer price group description cannot exceed 20 characters.")] + public string CustomerPriceGroupDescription { get; set; } - [Required(ErrorMessage = "Search Term is required")] - [StringLength(20, ErrorMessage = "Search Term cannot exceed 20 characters")] - public string SearchTerm { get; set; } = string.Empty; + [Required(ErrorMessage = "Status code is required.")] + [StringLength(1, ErrorMessage = "Status code cannot exceed 1 character.")] + public string StatusCode { get; set; } - [Required(ErrorMessage = "Region is required")] - [StringLength(3, MinimumLength = 1, ErrorMessage = "Region must be between 1 and 3 characters")] - public string Region { get; set; } = string.Empty; + [Required(ErrorMessage = "Status description is required.")] + [StringLength(30, ErrorMessage = "Status description cannot exceed 30 characters.")] + public string StatusDescription { get; set; } - [Required(ErrorMessage = "Region Name is required")] - [StringLength(40, ErrorMessage = "Region Name cannot exceed 40 characters")] - public string RegionName { get; set; } = string.Empty; + [Required(ErrorMessage = "Payment terms is required.")] + [StringLength(4, ErrorMessage = "Payment terms cannot exceed 4 characters.")] + public string PaymentTerms { get; set; } - [Required(ErrorMessage = "Area is required")] - [StringLength(10, MinimumLength = 1, ErrorMessage = "Area must be between 1 and 10 characters")] - public string Area { get; set; } = string.Empty; + [Required(ErrorMessage = "Payment terms description is required.")] + public string PaymentTermsDescription { get; set; } - [Required(ErrorMessage = "Area Name is required")] - [StringLength(40, ErrorMessage = "Area Name cannot exceed 40 characters")] - public string AreaName { get; set; } = string.Empty; + [Required(ErrorMessage = "Search term is required.")] + [StringLength(20, ErrorMessage = "Search term cannot exceed 20 characters.")] + public string SearchTerm { get; set; } - [Required(ErrorMessage = "Sales Unit is required")] - [StringLength(3, MinimumLength = 1, ErrorMessage = "Sales Unit must be between 1 and 3 characters")] - public string SalesUnit { get; set; } = string.Empty; + [Required(ErrorMessage = "Area/Region is required.")] + [StringLength(3, ErrorMessage = "Area/Region cannot exceed 3 characters.")] + public string AreaRegion { get; set; } - [Required(ErrorMessage = "Sales Unit Name is required")] - [StringLength(30, ErrorMessage = "Sales Unit Name cannot exceed 30 characters")] - public string SalesUnitName { get; set; } = string.Empty; + [Required(ErrorMessage = "Area/Region description is required.")] + [StringLength(40, ErrorMessage = "Area/Region description cannot exceed 40 characters.")] + public string AreaRegionDescription { get; set; } - [Required(ErrorMessage = "Territory is required")] - [StringLength(3, MinimumLength = 1, ErrorMessage = "Territory must be between 1 and 3 characters")] - public string Territory { get; set; } = string.Empty; + [Required(ErrorMessage = "Sales Unit/Area-AV is required.")] + [StringLength(10, ErrorMessage = "Sales Unit/Area-AV cannot exceed 10 characters.")] + public string SalesUnitAreaAV { get; set; } - [Required(ErrorMessage = "Territory Name is required")] - [StringLength(20, ErrorMessage = "Territory Name cannot exceed 20 characters")] - public string TerritoryName { get; set; } = string.Empty; + [Required(ErrorMessage = "Sales Unit/Area-AV description is required.")] + [StringLength(40, ErrorMessage = "Sales Unit/Area-AV description cannot exceed 40 characters.")] + public string SalesUnitAreaAVDescription { get; set; } - [Required(ErrorMessage = "Plant is required")] - [StringLength(4, MinimumLength = 1, ErrorMessage = "Plant must be between 1 and 4 characters")] - public string Plant { get; set; } = string.Empty; + [Required(ErrorMessage = "Territory is required.")] + [StringLength(3, ErrorMessage = "Territory cannot exceed 3 characters.")] + public string Territory { get; set; } - [Required(ErrorMessage = "Plant Name is required")] - [StringLength(30, ErrorMessage = "Plant Name cannot exceed 30 characters")] - public string PlantName { get; set; } = string.Empty; + [Required(ErrorMessage = "Territory name is required.")] + [StringLength(20, ErrorMessage = "Territory name cannot exceed 20 characters.")] + public string TerritoryName { get; set; } + + [Required(ErrorMessage = "Plant is required.")] + [StringLength(4, ErrorMessage = "Plant cannot exceed 4 characters.")] + public string Plant { get; set; } + + [Required(ErrorMessage = "Plant name is required.")] + [StringLength(30, ErrorMessage = "Plant name cannot exceed 30 characters.")] + public string PlantName { get; set; } } + public class CustomerByCompanyCodeRequest { [Required(ErrorMessage = "Customer Number is required")] diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/EmployeeIntegrationRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/EmployeeIntegrationRequest.cs new file mode 100644 index 0000000..91f0c0f --- /dev/null +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/EmployeeIntegrationRequest.cs @@ -0,0 +1,116 @@ +using System.ComponentModel.DataAnnotations; + +namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; + +public class EmployeeIntegrationRequest +{ + [Required(ErrorMessage = "Employee vendor code is required.")] + [StringLength(10, ErrorMessage = "Employee vendor code cannot exceed 10 characters.")] + public string EmployeeVendorCode { get; set; } + + [Required(ErrorMessage = "Employee vendor name is required.")] + [StringLength(35, ErrorMessage = "Employee vendor name cannot exceed 35 characters.")] + public string EmployeeVendorName { get; set; } + + [Required(ErrorMessage = "Designation is required.")] + [StringLength(4, ErrorMessage = "Designation cannot exceed 4 characters.")] + public string Designation { get; set; } + + [Required(ErrorMessage = "Designation description is required.")] + [StringLength(30, ErrorMessage = "Designation description cannot exceed 30 characters.")] + public string DesignationDescription { get; set; } + + [Required(ErrorMessage = "Mobile number is required.")] + [StringLength(31, ErrorMessage = "Mobile number cannot exceed 31 characters.")] + [Phone(ErrorMessage = "Mobile number is not a valid phone number.")] + public string MobileNo { get; set; } + + [Required(ErrorMessage = "Email address is required.")] + [StringLength(241, ErrorMessage = "Email address cannot exceed 241 characters.")] + [EmailAddress(ErrorMessage = "Email address is not valid.")] + public string Mail { get; set; } + + [Required(ErrorMessage = "Company code is required.")] + [StringLength(4, ErrorMessage = "Company code cannot exceed 4 characters.")] + public string CompanyCode { get; set; } + + [Required(ErrorMessage = "Company name is required.")] + [StringLength(25, ErrorMessage = "Company name cannot exceed 25 characters.")] + public string CompanyName { get; set; } + + [Required(ErrorMessage = "Sales org is required.")] + [StringLength(4, ErrorMessage = "Sales org cannot exceed 4 characters.")] + public string SalesOrg { get; set; } + + [Required(ErrorMessage = "Sales org description is required.")] + [StringLength(40, ErrorMessage = "Sales org description cannot exceed 40 characters.")] + public string SalesOrgDescription { get; set; } + + [Required(ErrorMessage = "Distribution channel is required.")] + [StringLength(2, ErrorMessage = "Distribution channel cannot exceed 2 characters.")] + public string DistChannel { get; set; } + + [Required(ErrorMessage = "Distribution channel description is required.")] + [StringLength(20, ErrorMessage = "Distribution channel description cannot exceed 20 characters.")] + public string DistChannelDescription { get; set; } + + [Required(ErrorMessage = "Division is required.")] + [StringLength(2, ErrorMessage = "Division cannot exceed 2 characters.")] + public string Division { get; set; } + + [Required(ErrorMessage = "Division description is required.")] + [StringLength(20, ErrorMessage = "Division description cannot exceed 20 characters.")] + public string DivisionDescription { get; set; } + + [Required(ErrorMessage = "Region/Area code is required.")] + [StringLength(3, ErrorMessage = "Region/Area code cannot exceed 3 characters.")] + public string RegionAreaCode { get; set; } + + [Required(ErrorMessage = "Region/Area description is required.")] + [StringLength(40, ErrorMessage = "Region/Area description cannot exceed 40 characters.")] + public string RegionAreaDescription { get; set; } + + [Required(ErrorMessage = "Area-AV/Sales unit code is required.")] + [StringLength(10, ErrorMessage = "Area-AV/Sales unit code cannot exceed 10 characters.")] + public string AreaAVSalesUnitCode { get; set; } + + [Required(ErrorMessage = "Area-AV/Sales unit description is required.")] + [StringLength(40, ErrorMessage = "Area-AV/Sales unit description cannot exceed 40 characters.")] + public string AreaAVSalesUnitDescription { get; set; } + + [Required(ErrorMessage = "Territory is required.")] + [StringLength(3, ErrorMessage = "Territory cannot exceed 3 characters.")] + public string Territory { get; set; } + + [Required(ErrorMessage = "Territory description is required.")] + [StringLength(20, ErrorMessage = "Territory description cannot exceed 20 characters.")] + public string TerritoryDescription { get; set; } + + [Required(ErrorMessage = "Plant is required.")] + [StringLength(4, ErrorMessage = "Plant cannot exceed 4 characters.")] + public string Plant { get; set; } + + [Required(ErrorMessage = "Plant description is required.")] + [StringLength(30, ErrorMessage = "Plant description cannot exceed 30 characters.")] + public string PlantDescription { get; set; } + + [Required(ErrorMessage = "Status is required.")] + [StringLength(1, ErrorMessage = "Status cannot exceed 1 character.")] + public string Status { get; set; } + + [Required(ErrorMessage = "Status description is required.")] + [StringLength(30, ErrorMessage = "Status description cannot exceed 30 characters.")] + public string StatusDescription { get; set; } +} + +public class EmployeeIntegrationByComapanyRequest +{ + [Required(ErrorMessage = "Employee vendor code is required.")] + [StringLength(10, ErrorMessage = "Employee vendor code cannot exceed 10 characters.")] + public string EmployeeVendorCode { get; set; } + + [Required(ErrorMessage = "Company code is required.")] + [StringLength(4, ErrorMessage = "Company code cannot exceed 4 characters.")] + public string CompanyCode { get; set; } + +} diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationAuthRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationAuthRequest.cs index b1891c7..49eeda3 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationAuthRequest.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationAuthRequest.cs @@ -13,10 +13,10 @@ public class IntegrationLoginRequest public string LoginId { get; set; } [Required, NotNull, StringLength(maximumLength: 150, MinimumLength = 5, ErrorMessage = "Password must be between 1 and 30 characters.")] - public string Password { get; set; } - public string RefreshToken { get; set; } + public string Password { get; set; } } + public class IntegrationRefreshTokenRequest { public string RefreshToken { get; set; } @@ -35,7 +35,7 @@ public class RevokedRefreshTokenRequest public class GenerateRefreshTokenRequest { - public User User { get; set; } + public int UserId { get; set; } public string IpAddress { get; set; } public string RawRefreshToken { get; set; } } \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/MaterialIntegrationRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/MaterialIntegrationRequest.cs new file mode 100644 index 0000000..2050732 --- /dev/null +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/MaterialIntegrationRequest.cs @@ -0,0 +1,73 @@ +using System.ComponentModel.DataAnnotations; + +namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; + +public class MaterialIntegrationRequest +{ + [Required(ErrorMessage = "Material type is required.")] + [StringLength(4, ErrorMessage = "Material type cannot exceed 4 characters.")] + public string MaterialType { get; set; } + + [Required(ErrorMessage = "Material type description is required.")] + [StringLength(25, ErrorMessage = "Material type description cannot exceed 25 characters.")] + public string MaterialTypeDescription { get; set; } + + [Required(ErrorMessage = "Material code is required.")] + [StringLength(10, ErrorMessage = "Material code cannot exceed 10 characters.")] + public string MaterialCode { get; set; } + + [Required(ErrorMessage = "Material description is required.")] + [StringLength(40, ErrorMessage = "Material description cannot exceed 40 characters.")] + public string MaterialDescription { get; set; } + + [Required(ErrorMessage = "Material group code is required.")] + [StringLength(9, ErrorMessage = "Material group code cannot exceed 9 characters.")] + public string MaterialGroupCode { get; set; } + + [Required(ErrorMessage = "Material group description is required.")] + [StringLength(20, ErrorMessage = "Material group description cannot exceed 20 characters.")] + public string MaterialGroupDescription { get; set; } + + [Required(ErrorMessage = "Base unit of measure is required.")] + [StringLength(3, ErrorMessage = "Base unit of measure cannot exceed 3 characters.")] + public string BaseUnitOfMeasure { get; set; } + + [Required(ErrorMessage = "Sales unit of measure is required.")] + [StringLength(3, ErrorMessage = "Sales unit of measure cannot exceed 3 characters.")] + public string SalesUnitOfMeasure { get; set; } + + [Required(ErrorMessage = "Unit conversion with base UoM is required.")] + [Range(0.001, 999.999, ErrorMessage = "Unit conversion must be between 0.001 and 999.999.")] + public decimal UnitConversionWithBaseUoM { get; set; } + + [Required(ErrorMessage = "Plant code is required.")] + [StringLength(4, ErrorMessage = "Plant code cannot exceed 4 characters.")] + public string PlantCode { get; set; } + + [Required(ErrorMessage = "Plant description is required.")] + [StringLength(30, ErrorMessage = "Plant description cannot exceed 30 characters.")] + public string PlantDescription { get; set; } + + [Required(ErrorMessage = "Storage location code is required.")] + [StringLength(4, ErrorMessage = "Storage location code cannot exceed 4 characters.")] + public string StorageLocationCode { get; set; } + + [Required(ErrorMessage = "Storage location description is required.")] + [StringLength(16, ErrorMessage = "Storage location description cannot exceed 16 characters.")] + public string StorageLocationDescription { get; set; } + + [Required(ErrorMessage = "Sales Organization code is required.")] + [StringLength(4, ErrorMessage = "Sales Organization code cannot exceed 4 characters.")] + public string SalesOrganization { get; set; } + + [Required(ErrorMessage = "Sales Organization Description is required.")] + [StringLength(16, ErrorMessage = "Sales Organization Description cannot exceed 16 characters.")] + public string SalesOrganizationDescription { get; set; } +} + +public class GetMaterialByCodeRequest +{ + [Required(ErrorMessage = "Material code is required.")] + [StringLength(10, ErrorMessage = "Material code cannot exceed 10 characters.")] + public string MaterialCode { get; set; } +} \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/CustomerIntegrationResponse.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/CustomerIntegrationResponse.cs index a1ba8ec..d29a1c2 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/CustomerIntegrationResponse.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/CustomerIntegrationResponse.cs @@ -2,61 +2,47 @@ public class CustomerIntegrationResponse : ResponseBase { - + public string CustomerNumber { get; set; } + public string CompanyCode { get; set; } + public bool IsUpdated { get; set; } } public class CustomerByCompanyCodeResponse : ResponseBase { - public int CustomerId { get; set; } + public int CustomerId { get; set; } public string CustomerNumber { get; set; } public string CustomerName { get; set; } - public string AccountGroup { get; set; } public string AccountGroupDescription { get; set; } - public string CompanyCode { get; set; } public string CompanyCodeDescription { get; set; } - public string SalesOrganization { get; set; } public string SalesOrganizationDescription { get; set; } - public string DistributionChannel { get; set; } public string DistributionChannelDescription { get; set; } - public string Division { get; set; } public string DivisionDescription { get; set; } - public string MobileNumber { get; set; } public string EmailAddress { get; set; } - public string BusinessTaxNumber { get; set; } - - public decimal? CreditLimit { get; set; } - - public string SalesOffice { get; set; } - public string SalesOfficeDescription { get; set; } - + public decimal CreditLimit { get; set; } public string SalesGroup { get; set; } + public string SalesGroupDescription { get; set; } public string CustomerGroup { get; set; } - - public string Status { get; set; } - + public string CustomerGroupDescription { get; set; } + public string CustomerPriceGroup { get; set; } + public string CustomerPriceGroupDescription { get; set; } + public string StatusCode { get; set; } + public string StatusDescription { get; set; } public string PaymentTerms { get; set; } - + public string PaymentTermsDescription { get; set; } public string SearchTerm { get; set; } - - public string Region { get; set; } - public string RegionName { get; set; } - - public string Area { get; set; } - public string AreaName { get; set; } - - public string SalesUnit { get; set; } - public string SalesUnitName { get; set; } - + public string AreaRegion { get; set; } + public string AreaRegionDescription { get; set; } + public string SalesUnitAreaAV { get; set; } + public string SalesUnitAreaAVDescription { get; set; } public string Territory { get; set; } public string TerritoryName { get; set; } - public string Plant { get; set; } public string PlantName { get; set; } } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/EmployeeIntegrationResponse.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/EmployeeIntegrationResponse.cs new file mode 100644 index 0000000..620d352 --- /dev/null +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/EmployeeIntegrationResponse.cs @@ -0,0 +1,39 @@ +namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; + +public class EmployeeIntegrationResponse : ResponseBase +{ + public int EmployeeId { get; set; } + public string EmployeeVendorCode { get; set; } + public string EmployeeVendorName { get; set; } + public string Designation { get; set; } + public string DesignationDescription { get; set; } + public string MobileNo { get; set; } + public string Mail { get; set; } + public string CompanyCode { get; set; } + public string CompanyName { get; set; } + public string SalesOrg { get; set; } + public string SalesOrgDescription { get; set; } + public string DistChannel { get; set; } + public string DistChannelDescription { get; set; } + public string Division { get; set; } + public string DivisionDescription { get; set; } + public string RegionAreaCode { get; set; } + public string RegionAreaDescription { get; set; } + public string AreaAVSalesUnitCode { get; set; } + public string AreaAVSalesUnitDescription { get; set; } + public string Territory { get; set; } + public string TerritoryDescription { get; set; } + public string Plant { get; set; } + public string PlantDescription { get; set; } + public string Status { get; set; } + public string StatusDescription { get; set; } +} + + +public class EmployeeIntegrationReqResponse : ResponseBase +{ + public string EmployeeVendorCode { get; set; } + public string CompanyCode { get; set; } + public bool IsUpdated { get; set; } + +} \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationAuthResponse.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationAuthResponse.cs index 864f662..090c76e 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationAuthResponse.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationAuthResponse.cs @@ -14,10 +14,16 @@ public class IntegrationLoginResponse : ResponseBase public DateTime AccessTokenExpiry { get; set; } } +public class IntegrationRrefreshTokenResponse : ResponseBase +{ + public string AccessToken { get; set; } = string.Empty; + public string RefreshToken { get; set; } = string.Empty; +} + public class RefreshTokenResponse : ResponseBase { - public string UserId { get; set; } + public int UserId { get; set; } public string TokenHash { get; set; } public string IpAddress { get; set; } public DateTime ExpiredAt { get; set; } @@ -30,4 +36,13 @@ public class GenerateRefreshTokenResponse : ResponseBase { public string RefreshToken { get; set; } public DateTime ExpireTime { get; set; } +} + +public class UserByRefreshTokenResponse : ResponseBase +{ + public int UserId { get; set; } + public string LoginId { get; set; } + public string EmailAddress { get; set; } + public string AuthKey { get; set; } + public bool IsActive { set; get; } } \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/MeterialIntegrationResponse.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/MeterialIntegrationResponse.cs new file mode 100644 index 0000000..eabdb93 --- /dev/null +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/MeterialIntegrationResponse.cs @@ -0,0 +1,29 @@ +using System.ComponentModel.DataAnnotations; + +namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; + +public class MaterialIntegrationResponse : ResponseBase +{ + public int MeterialId { get; set; } + public string MaterialType { get; set; } + public string MaterialTypeDescription { get; set; } + public string MaterialCode { get; set; } + public string MaterialDescription { get; set; } + public string MaterialGroupCode { get; set; } + public string MaterialGroupDescription { get; set; } + public string BaseUnitOfMeasure { get; set; } + public string SalesUnitOfMeasure { get; set; } + public decimal UnitConversionWithBaseUoM { get; set; } + public string PlantCode { get; set; } + public string PlantDescription { get; set; } + public string StorageLocationCode { get; set; } + public string StorageLocationDescription { get; set; } + public string SalesOrganization { get; set; } + public string SalesOrganizationDescription { get; set; } +} + +public class MaterialIntegrationReqResponse : ResponseBase +{ + public string MaterialCode { get; set; } + public bool IsUpdated { get; set; } +} \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Auth/IRefreshTokenService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Auth/IRefreshTokenService.cs index c83520f..9f7730c 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Auth/IRefreshTokenService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Auth/IRefreshTokenService.cs @@ -6,9 +6,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth; public interface IRefreshTokenService { - Task GetByTokenHashAsync(string tokenHash); - Task AddAsync(InsertRefreshTokenRequest refreshToken); - Task RevokeAsync(RevokedRefreshTokenRequest token); - Task RevokeAllForUserAsync(int userId); - Task GenerateRefreshToken(GenerateRefreshTokenRequest request); + Task GenerateRefreshTokenByUserAsync(GenerateRefreshTokenRequest request); + Task GenerateRefreshTokenAsync(string refreshToken, string ipAddress); + Task GetUserByRefreshTokenAsync(string refreshToken); } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationService.cs index eca423e..28857fa 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationService.cs @@ -7,6 +7,15 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations; public interface IIntegrationService { - Task UpsertCustomerAsync(CustomerIntegrationRequest request); + //Customer + Task UpsertCustomerAsync(CustomerIntegrationRequest request); Task GetCustomerByCompanyCodeAsync(CustomerByCompanyCodeRequest request); + + //Employee + Task UpsertEmployeeAsync(EmployeeIntegrationRequest request); + Task GetEmployeeBySalesOrgAsync(EmployeeIntegrationByComapanyRequest request); + + //Meterial + Task UpsertMaterialAsync(MaterialIntegrationRequest request); + Task GetMaterialByCodeAsync(GetMaterialByCodeRequest request); } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Auth/RefreshTokenService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Auth/RefreshTokenService.cs index 9b5ba19..4453fb3 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Auth/RefreshTokenService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Auth/RefreshTokenService.cs @@ -3,7 +3,6 @@ using Ease.NetCore.DataAccess.SQL; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Options; using OnlineSalesAutoCrop.CoreAPI.Models.Global; -using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems; using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth; @@ -23,26 +22,118 @@ public class RefreshTokenService : IRefreshTokenService _settings = settings.Value; } - - public async Task AddAsync(InsertRefreshTokenRequest refreshToken) + public async Task GetUserByRefreshTokenAsync(string refreshToken) { - bool returnValue = false; + UserByRefreshTokenResponse response = new(); try { - using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true); - AddAsync(tc, refreshToken); + using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode); + try + { + response = await GetUserByRefreshTokenAsync(tc, refreshToken); + tc.End(); + } + catch (Exception ie) + { + tc?.HandleError(); - tc.End(); + throw DBCustomError.GenerateCustomError(ie); + } } catch (Exception e) { throw new InvalidOperationException(e.Message, e); } - return returnValue; + return response; } - private bool AddAsync( TransactionContext tc, InsertRefreshTokenRequest refreshToken) + public async Task GenerateRefreshTokenByUserAsync(GenerateRefreshTokenRequest request) + { + GenerateRefreshTokenResponse refreshTokenResponse = new(); + try + { + using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true); + try + { + // Rotate: revoke old token, issue new one + RevokeRefreshTokenByUserIdAsync(tc, request.UserId); + + refreshTokenResponse= await IssueTokensAsync(tc,request.UserId, request.IpAddress); + + tc.End(); + } + catch (Exception ie) + { + tc?.HandleError(); + + throw DBCustomError.GenerateCustomError(ie); + } + } + catch (Exception e) + { + throw new InvalidOperationException(e.Message, e); + } + + return refreshTokenResponse; + } + + public async Task GenerateRefreshTokenAsync(string refreshToken, string ipAddress) + { + string refreshTokenResponse = string.Empty; + try + { + using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true); + try + { + bool isValid = IsValidRefreshTokenAsync(tc, refreshToken); + if(string.IsNullOrEmpty(refreshToken) && !isValid) + { + throw new Exception($"Refresh token has expired or been revoked- {refreshToken}"); + } + + var storedToken = await GetByTokenHashAsync(tc, refreshToken); + + RevokeRefreshTokenByUserIdAsync(tc, storedToken.UserId); + + var result = await IssueTokensAsync(tc, storedToken.UserId, ipAddress); + refreshTokenResponse = result.RefreshToken; + + tc.End(); + } + catch (Exception ie) + { + tc?.HandleError(); + + throw DBCustomError.GenerateCustomError(ie); + } + } + catch (Exception e) + { + throw new InvalidOperationException(e.Message, e); + } + + return refreshTokenResponse; + } + + #region Private Methods + // ----- private helpers ----- + + private bool IsValidRefreshTokenAsync(TransactionContext tc, string refreshToken ) + { + try + { + string sql = SQLParser.MakeSQL("Select Count(1) FROM RefreshTokens where TokenHash = %s AND RevokedAt is null", refreshToken); + var returnValue = tc.ExecuteScalar(sql); + return Convert.ToInt32(returnValue) > 0 ? true : false; + } + catch(Exception) + { + throw; + } + } + + private bool AddAsync(TransactionContext tc, InsertRefreshTokenRequest refreshToken) { bool returnValue = false; @@ -68,33 +159,6 @@ public class RefreshTokenService : IRefreshTokenService return returnValue; } - - public async Task GetByTokenHashAsync(string tokenHash) - { - RefreshTokenResponse response = new(); - try - { - using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode); - try - { - await GetByTokenHashAsync(tc, tokenHash); - tc.End(); - } - catch (Exception ie) - { - tc?.HandleError(); - - throw DBCustomError.GenerateCustomError(ie); - } - } - catch (Exception e) - { - throw new InvalidOperationException(e.Message, e); - } - - return response; - } - private async Task GetByTokenHashAsync(TransactionContext tc, string tokenHash) { RefreshTokenResponse response = new(); @@ -108,7 +172,7 @@ public class RefreshTokenService : IRefreshTokenService { if (dr.Read()) { - response.UserId = dr.GetString(0); + response.UserId = dr.GetInt32(0); response.TokenHash = dr.GetString(1); response.IpAddress = dr.GetString(2); response.ExpiredAt = dr.GetDateTime(3); @@ -125,76 +189,16 @@ public class RefreshTokenService : IRefreshTokenService return response; } - public async Task RevokeAllForUserAsync(int userId) - { - bool returnValue = false; - try - { - using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true); - try - { - SqlParameter[] p = - [ - SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: userId) - ]; - _ = await tc.ExecuteNonQuerySpAsync(spName: "dbo.RevokedAllRefreshToken", parameterValues: p); - - returnValue = true; - - tc.End(); - } - catch (Exception ie) - { - tc?.HandleError(); - - throw DBCustomError.GenerateCustomError(ie); - } - } - catch (Exception e) - { - throw new InvalidOperationException(e.Message, e); - } - - return returnValue; - } - - public async Task RevokeAsync(RevokedRefreshTokenRequest token) - { - bool returnValue = false; - try - { - using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true); - try - { - returnValue = RevokeAsync(tc, token); - - tc.End(); - } - catch (Exception ie) - { - tc?.HandleError(); - - throw DBCustomError.GenerateCustomError(ie); - } - } - catch (Exception e) - { - throw new InvalidOperationException(e.Message, e); - } - - return returnValue; - } - - private bool RevokeAsync(TransactionContext tc, RevokedRefreshTokenRequest token) + private bool RevokeRefreshTokenByUserIdAsync(TransactionContext tc, int userId) { bool returnValue = false; try { SqlParameter[] p = [ - SqlHelperExtension.CreateInParam(pName: "@RefreshToken", pType: SqlDbType.NVarChar, pValue: token.RefreshToken) + SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: userId) ]; - _ = tc.ExecuteNonQuerySp(spName: "dbo.RevokedAllRefreshToken", parameterValues: p); + _ = tc.ExecuteNonQuerySp(spName: "dbo.RevokedAllRefreshTokenByUserId", parameterValues: p); returnValue = true; @@ -206,33 +210,27 @@ public class RefreshTokenService : IRefreshTokenService return returnValue; } - public async Task GenerateRefreshToken(GenerateRefreshTokenRequest request) + + private async Task GetUserByRefreshTokenAsync(TransactionContext tc, string refreshToken) { - GenerateRefreshTokenResponse refreshTokenResponse = new(); + UserByRefreshTokenResponse response = new(); try { - using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true); - try + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam(pName: "@RefreshToken", pType: SqlDbType.VarChar, pValue: refreshToken), + ]; + using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetUserByRefreshToken", parameterValues: p)) { - var tokenHash = HashToken(request.RawRefreshToken); - - var storedToken = await GetByTokenHashAsync(tc, tokenHash); - - if (storedToken.UserId is not null && !storedToken.IsActive) - throw new UnauthorizedAccessException("Refresh token has expired or been revoked."); - - // Rotate: revoke old token, issue new one - RevokeAsync(tc,new RevokedRefreshTokenRequest() { RefreshToken = storedToken.TokenHash }); - - refreshTokenResponse= await IssueTokensAsync(tc,request.User, request.IpAddress); - - tc.End(); - } - catch (Exception ie) - { - tc?.HandleError(); - - throw DBCustomError.GenerateCustomError(ie); + if (dr.Read()) + { + response.UserId = dr.GetInt32(0); + response.LoginId = dr.GetString(1); + response.EmailAddress = dr.IsDBNull(2) ? string.Empty : dr.GetString(2); + response.AuthKey = dr.IsDBNull(3) ? string.Empty : dr.GetString(3); + response.IsActive = dr.IsDBNull(4) ? true : false; + } + dr.Close(); } } catch (Exception e) @@ -240,19 +238,17 @@ public class RefreshTokenService : IRefreshTokenService throw new InvalidOperationException(e.Message, e); } - return refreshTokenResponse; + return response; } - - // ----- private helpers ----- - - private async Task IssueTokensAsync(TransactionContext tc, User user, string ipAddress) + private async Task IssueTokensAsync(TransactionContext tc, int userId, string ipAddress) { string rawRefreshToken = GenerateRowToken(); + string tokenHash = HashToken(rawRefreshToken); var refreshToken = new InsertRefreshTokenRequest { - UserId = user.UserId, - TokenHash = HashToken(rawRefreshToken), + UserId = userId, + TokenHash = tokenHash, IpAddress = ipAddress, CreatedAt = DateTime.UtcNow, ExpiresAt = DateTime.UtcNow.AddDays(_settings.RefreshTokenDuration) @@ -262,7 +258,7 @@ public class RefreshTokenService : IRefreshTokenService return new GenerateRefreshTokenResponse { - RefreshToken = rawRefreshToken, + RefreshToken = tokenHash, ExpireTime = DateTime.UtcNow.AddMinutes(_settings.RefreshTokenDuration) }; } @@ -280,4 +276,6 @@ public class RefreshTokenService : IRefreshTokenService rng.GetBytes(bytes); return Convert.ToBase64String(bytes); } + + #endregion } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs index 73c84d2..842b59b 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs @@ -8,8 +8,6 @@ using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations; using System; using System.Data; -using System.Security.Cryptography; -using System.Text; using System.Threading.Tasks; namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations; @@ -23,6 +21,7 @@ public class IntegrationService : IIntegrationService _settings = options.Value; } + public async Task GetCustomerByCompanyCodeAsync(CustomerByCompanyCodeRequest request) { CustomerByCompanyCodeResponse response = new(); @@ -49,13 +48,12 @@ public class IntegrationService : IIntegrationService return response; } - - public async Task UpsertCustomerAsync(CustomerIntegrationRequest request) + public async Task UpsertCustomerAsync(CustomerIntegrationRequest request) { - bool response = false; + CustomerIntegrationResponse response = new(); try { - using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode); + using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode,true); try { var customer = await GetCustomerByCompanyCodeAsync(tc, new CustomerByCompanyCodeRequest() { CompanyCode = request.CompanyCode, CustomerNumber = request.CustomerNumber }); @@ -63,12 +61,19 @@ public class IntegrationService : IIntegrationService if( customer != null && customer.CustomerId>0) { //Update Here + UpdateCustomer(tc, request); + response.IsUpdated = true; } else { //Insert Here + + CreateCustomer(tc, request); + response.IsUpdated = false; } + response.CustomerNumber = request.CustomerNumber; + response.CompanyCode = request.CompanyCode; tc.End(); } catch (Exception ie) @@ -86,16 +91,155 @@ public class IntegrationService : IIntegrationService return response; } + + public async Task GetEmployeeBySalesOrgAsync(EmployeeIntegrationByComapanyRequest request) + { + EmployeeIntegrationResponse response = new(); + try + { + using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode); + try + { + await GetEmployeeBySalesOrgAsync(tc, request); + tc.End(); + } + catch (Exception ie) + { + tc?.HandleError(); + + throw DBCustomError.GenerateCustomError(ie); + } + } + catch (Exception ex) + { + throw; + } + + return response; + } + + public async Task UpsertEmployeeAsync(EmployeeIntegrationRequest request) + { + EmployeeIntegrationReqResponse response = new EmployeeIntegrationReqResponse(); + try + { + using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true); + try + { + EmployeeIntegrationResponse employee = await GetEmployeeBySalesOrgAsync(tc, + new EmployeeIntegrationByComapanyRequest() { EmployeeVendorCode = request.EmployeeVendorCode, CompanyCode = request.CompanyCode }); + + + if (employee != null && employee.EmployeeId > 0) + { + UpdateEmployee(tc, request); + response.IsUpdated = true; + } + else + { + InsertEmployee(tc, request); + response.IsUpdated = false; + } + + response.EmployeeVendorCode = request.EmployeeVendorCode; + response.CompanyCode = request.CompanyCode; + tc.End(); + } + catch (Exception ie) + { + tc?.HandleError(); + + throw DBCustomError.GenerateCustomError(ie); + } + } + catch (Exception ex) + { + throw; + } + + return response; + } + + + public async Task UpsertMaterialAsync(MaterialIntegrationRequest request) + { + MaterialIntegrationReqResponse response = new MaterialIntegrationReqResponse(); + try + { + using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true); + try + { + MaterialIntegrationResponse meterial = await GetMaterialByCodeAsync(tc, + new GetMaterialByCodeRequest() { MaterialCode = request.MaterialCode }); + + if (meterial != null && meterial.MeterialId > 0) + { + UpdateMaterial(tc, request); + response.IsUpdated = true; + } + else + { + CreateMaterial(tc, request); + response.IsUpdated = false; + } + + response.MaterialCode = request.MaterialCode; + tc.End(); + } + catch (Exception ie) + { + tc?.HandleError(); + + throw DBCustomError.GenerateCustomError(ie); + } + } + catch (Exception ex) + { + throw; + } + + return response; + } + + public async Task GetMaterialByCodeAsync(GetMaterialByCodeRequest request) + { + MaterialIntegrationResponse response = new(); + try + { + using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode); + try + { + response= await GetMaterialByCodeAsync(tc, request); + tc.End(); + } + catch (Exception ie) + { + tc?.HandleError(); + + throw DBCustomError.GenerateCustomError(ie); + } + } + catch (Exception ex) + { + throw; + } + + return response; + } + + + #region Customer Private Functions + private async Task GetCustomerByCompanyCodeAsync(TransactionContext tc, CustomerByCompanyCodeRequest request) { CustomerByCompanyCodeResponse response = new CustomerByCompanyCodeResponse(); + try { SqlParameter[] p = [ - SqlHelperExtension.CreateInParam(pName: "@CustomerNumber", pType: SqlDbType.NVarChar,pValue: request.CustomerNumber ), - SqlHelperExtension.CreateInParam(pName: "@CompanyCode", pType: SqlDbType.NVarChar,pValue: request.CompanyCode ), - + SqlHelperExtension.CreateInParam(pName: "@CompanyCode", pType: SqlDbType.NVarChar, pValue: request.CompanyCode), + SqlHelperExtension.CreateInParam(pName: "@CustomerNumber", pType: SqlDbType.NVarChar, pValue: request.CustomerNumber) ]; using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetCustomerByCompanyCode", parameterValues: p)) @@ -104,49 +248,515 @@ public class IntegrationService : IIntegrationService { response = new CustomerByCompanyCodeResponse() { - CustomerNumber = dr["CustomerNumber"].ToString(), - CustomerName = dr["CustomerName"].ToString(), - AccountGroup = dr["AccountGroup"].ToString(), - AccountGroupDescription = dr["AccountGroupDescription"].ToString(), - CompanyCode = dr["CompanyCode"].ToString(), - CompanyCodeDescription = dr["CompanyCodeDescription"].ToString(), - SalesOrganization = dr["SalesOrganization"].ToString(), - SalesOrganizationDescription = dr["SalesOrganizationDescription"].ToString(), - DistributionChannel = dr["DistributionChannel"].ToString(), - DistributionChannelDescription = dr["DistributionChannelDescription"].ToString(), - Division = dr["Division"].ToString(), - DivisionDescription = dr["DivisionDescription"].ToString(), - MobileNumber = dr["MobileNumber"].ToString(), - EmailAddress = dr["EmailAddress"].ToString(), - BusinessTaxNumber = dr["BusinessTaxNumber"].ToString(), - CreditLimit = dr["CreditLimit"] == DBNull.Value ? 0 : Convert.ToDecimal(dr["CreditLimit"]), - SalesOffice = dr["SalesOffice"].ToString(), - SalesOfficeDescription = dr["SalesOfficeDescription"].ToString(), - SalesGroup = dr["SalesGroup"].ToString(), - CustomerGroup = dr["CustomerGroup"].ToString(), - Status = dr["Status"].ToString(), - PaymentTerms = dr["PaymentTerms"].ToString(), - SearchTerm = dr["SearchTerm"].ToString(), - Region = dr["Region"].ToString(), - RegionName = dr["RegionName"].ToString(), - Area = dr["Area"].ToString(), - AreaName = dr["AreaName"].ToString(), - SalesUnit = dr["SalesUnit"].ToString(), - SalesUnitName = dr["SalesUnitName"].ToString(), - Territory = dr["Territory"].ToString(), - TerritoryName = dr["TerritoryName"].ToString(), - Plant = dr["Plant"].ToString(), - PlantName = dr["PlantName"].ToString() - + CustomerId = dr.GetInt32(0), + CustomerNumber = dr.GetString(1), + CustomerName = dr.GetString(2), + AccountGroup = dr.GetString(3), + AccountGroupDescription = dr.GetString(4), + CompanyCode = dr.GetString(5), + CompanyCodeDescription = dr.GetString(6), + SalesOrganization = dr.GetString(7), + SalesOrganizationDescription = dr.GetString(8), + DistributionChannel = dr.GetString(9), + DistributionChannelDescription = dr.GetString(10), + Division = dr.GetString(11), + DivisionDescription = dr.GetString(12), + MobileNumber = dr.GetString(13), + EmailAddress = dr.GetString(14), + BusinessTaxNumber = dr.GetString(15), + CreditLimit = dr.GetDecimal(16), + SalesGroup = dr.GetString(17), + SalesGroupDescription = dr.GetString(18), + CustomerGroup = dr.GetString(19), + CustomerGroupDescription = dr.GetString(20), + CustomerPriceGroup = dr.GetString(21), + CustomerPriceGroupDescription = dr.GetString(22), + StatusCode = dr.GetString(23), + StatusDescription = dr.GetString(24), + PaymentTerms = dr.GetString(25), + PaymentTermsDescription = dr.GetString(26), + SearchTerm = dr.GetString(27), + AreaRegion = dr.GetString(28), + AreaRegionDescription = dr.GetString(29), + SalesUnitAreaAV = dr.GetString(30), + SalesUnitAreaAVDescription = dr.GetString(31), + Territory = dr.GetString(32), + TerritoryName = dr.GetString(33), + Plant = dr.GetString(34), + PlantName = dr.GetString(35) }; } dr.Close(); } } - catch(Exception ex) + catch (Exception ex) + { + throw DBCustomError.GenerateCustomError(ex); + } + + return response; + } + + private bool CreateCustomer(TransactionContext tc, CustomerIntegrationRequest request) + { + bool returnValue = false; + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam("@CustomerNumber", SqlDbType.NVarChar, request.CustomerNumber), + SqlHelperExtension.CreateInParam("@CustomerName", SqlDbType.NVarChar, request.CustomerName), + + SqlHelperExtension.CreateInParam("@AccountGroup", SqlDbType.NVarChar, request.AccountGroup), + SqlHelperExtension.CreateInParam("@AccountGroupDescription", SqlDbType.NVarChar, request.AccountGroupDescription), + + SqlHelperExtension.CreateInParam("@CompanyCode", SqlDbType.NVarChar, request.CompanyCode), + SqlHelperExtension.CreateInParam("@CompanyCodeDescription", SqlDbType.NVarChar, request.CompanyCodeDescription), + + SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization), + SqlHelperExtension.CreateInParam("@SalesOrganizationDescription", SqlDbType.NVarChar, request.SalesOrganizationDescription), + + SqlHelperExtension.CreateInParam("@DistributionChannel", SqlDbType.NVarChar, request.DistributionChannel), + SqlHelperExtension.CreateInParam("@DistributionChannelDescription", SqlDbType.NVarChar, request.DistributionChannelDescription), + + SqlHelperExtension.CreateInParam("@Division", SqlDbType.NVarChar, request.Division), + SqlHelperExtension.CreateInParam("@DivisionDescription", SqlDbType.NVarChar, request.DivisionDescription), + + SqlHelperExtension.CreateInParam("@MobileNumber", SqlDbType.NVarChar, request.MobileNumber), + SqlHelperExtension.CreateInParam("@EmailAddress", SqlDbType.NVarChar, request.EmailAddress), + + SqlHelperExtension.CreateInParam("@BusinessTaxNumber", SqlDbType.NVarChar, request.BusinessTaxNumber), + SqlHelperExtension.CreateInParam("@CreditLimit", SqlDbType.Decimal, request.CreditLimit), + + SqlHelperExtension.CreateInParam("@SalesGroup", SqlDbType.NVarChar, request.SalesGroup), + SqlHelperExtension.CreateInParam("@SalesGroupDescription", SqlDbType.NVarChar, request.SalesGroupDescription), + + SqlHelperExtension.CreateInParam("@CustomerGroup", SqlDbType.NVarChar, request.CustomerGroup), + SqlHelperExtension.CreateInParam("@CustomerGroupDescription", SqlDbType.NVarChar, request.CustomerGroupDescription), + + SqlHelperExtension.CreateInParam("@CustomerPriceGroup", SqlDbType.NVarChar, request.CustomerPriceGroup), + SqlHelperExtension.CreateInParam("@CustomerPriceGroupDescription", SqlDbType.NVarChar, request.CustomerPriceGroupDescription), + + SqlHelperExtension.CreateInParam("@StatusCode", SqlDbType.NChar, request.StatusCode), + SqlHelperExtension.CreateInParam("@StatusDescription", SqlDbType.NVarChar, request.StatusDescription), + + SqlHelperExtension.CreateInParam("@PaymentTerms", SqlDbType.NVarChar, request.PaymentTerms), + SqlHelperExtension.CreateInParam("@PaymentTermsDescription", SqlDbType.NVarChar, request.PaymentTermsDescription), + + SqlHelperExtension.CreateInParam("@SearchTerm", SqlDbType.NVarChar, request.SearchTerm), + + SqlHelperExtension.CreateInParam("@AreaRegion", SqlDbType.NVarChar, request.AreaRegion), + SqlHelperExtension.CreateInParam("@AreaRegionDescription", SqlDbType.NVarChar, request.AreaRegionDescription), + + SqlHelperExtension.CreateInParam("@SalesUnitAreaAV", SqlDbType.NVarChar, request.SalesUnitAreaAV), + SqlHelperExtension.CreateInParam("@SalesUnitAreaAVDescription", SqlDbType.NVarChar, request.SalesUnitAreaAVDescription), + + SqlHelperExtension.CreateInParam("@Territory", SqlDbType.NVarChar, request.Territory), + SqlHelperExtension.CreateInParam("@TerritoryName", SqlDbType.NVarChar, request.TerritoryName), + + SqlHelperExtension.CreateInParam("@Plant", SqlDbType.NVarChar, request.Plant), + SqlHelperExtension.CreateInParam("@PlantName", SqlDbType.NVarChar, request.PlantName) + ]; + + _ = tc.ExecuteNonQuerySp(spName: "dbo.CreateCustomer", parameterValues: p); + + returnValue = true; + } + catch (Exception) { throw; } + + return returnValue; + } + + private bool UpdateCustomer(TransactionContext tc, CustomerIntegrationRequest request) + { + bool returnValue = false; + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam("@CustomerNumber", SqlDbType.NVarChar, request.CustomerNumber), + SqlHelperExtension.CreateInParam("@CustomerName", SqlDbType.NVarChar, request.CustomerName), + + SqlHelperExtension.CreateInParam("@AccountGroup", SqlDbType.NVarChar, request.AccountGroup), + SqlHelperExtension.CreateInParam("@AccountGroupDescription", SqlDbType.NVarChar, request.AccountGroupDescription), + + SqlHelperExtension.CreateInParam("@CompanyCode", SqlDbType.NVarChar, request.CompanyCode), + SqlHelperExtension.CreateInParam("@CompanyCodeDescription", SqlDbType.NVarChar, request.CompanyCodeDescription), + + SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization), + SqlHelperExtension.CreateInParam("@SalesOrganizationDescription", SqlDbType.NVarChar, request.SalesOrganizationDescription), + + SqlHelperExtension.CreateInParam("@DistributionChannel", SqlDbType.NVarChar, request.DistributionChannel), + SqlHelperExtension.CreateInParam("@DistributionChannelDescription", SqlDbType.NVarChar, request.DistributionChannelDescription), + + SqlHelperExtension.CreateInParam("@Division", SqlDbType.NVarChar, request.Division), + SqlHelperExtension.CreateInParam("@DivisionDescription", SqlDbType.NVarChar, request.DivisionDescription), + + SqlHelperExtension.CreateInParam("@MobileNumber", SqlDbType.NVarChar, request.MobileNumber), + SqlHelperExtension.CreateInParam("@EmailAddress", SqlDbType.NVarChar, request.EmailAddress), + + SqlHelperExtension.CreateInParam("@BusinessTaxNumber", SqlDbType.NVarChar, request.BusinessTaxNumber), + SqlHelperExtension.CreateInParam("@CreditLimit", SqlDbType.Decimal, request.CreditLimit), + + SqlHelperExtension.CreateInParam("@SalesGroup", SqlDbType.NVarChar, request.SalesGroup), + SqlHelperExtension.CreateInParam("@SalesGroupDescription", SqlDbType.NVarChar, request.SalesGroupDescription), + + SqlHelperExtension.CreateInParam("@CustomerGroup", SqlDbType.NVarChar, request.CustomerGroup), + SqlHelperExtension.CreateInParam("@CustomerGroupDescription", SqlDbType.NVarChar, request.CustomerGroupDescription), + + SqlHelperExtension.CreateInParam("@CustomerPriceGroup", SqlDbType.NVarChar, request.CustomerPriceGroup), + SqlHelperExtension.CreateInParam("@CustomerPriceGroupDescription", SqlDbType.NVarChar, request.CustomerPriceGroupDescription), + + SqlHelperExtension.CreateInParam("@StatusCode", SqlDbType.NChar, request.StatusCode), + SqlHelperExtension.CreateInParam("@StatusDescription", SqlDbType.NVarChar, request.StatusDescription), + + SqlHelperExtension.CreateInParam("@PaymentTerms", SqlDbType.NVarChar, request.PaymentTerms), + SqlHelperExtension.CreateInParam("@PaymentTermsDescription", SqlDbType.NVarChar, request.PaymentTermsDescription), + + SqlHelperExtension.CreateInParam("@SearchTerm", SqlDbType.NVarChar, request.SearchTerm), + + SqlHelperExtension.CreateInParam("@AreaRegion", SqlDbType.NVarChar, request.AreaRegion), + SqlHelperExtension.CreateInParam("@AreaRegionDescription", SqlDbType.NVarChar, request.AreaRegionDescription), + + SqlHelperExtension.CreateInParam("@SalesUnitAreaAV", SqlDbType.NVarChar, request.SalesUnitAreaAV), + SqlHelperExtension.CreateInParam("@SalesUnitAreaAVDescription", SqlDbType.NVarChar, request.SalesUnitAreaAVDescription), + + SqlHelperExtension.CreateInParam("@Territory", SqlDbType.NVarChar, request.Territory), + SqlHelperExtension.CreateInParam("@TerritoryName", SqlDbType.NVarChar, request.TerritoryName), + + SqlHelperExtension.CreateInParam("@Plant", SqlDbType.NVarChar, request.Plant), + SqlHelperExtension.CreateInParam("@PlantName", SqlDbType.NVarChar, request.PlantName) + ]; + + _ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateCustomer", parameterValues: p); + + returnValue = true; + } + catch (Exception) + { + throw; + } + + return returnValue; + } + + #endregion + + #region Employee Private Functions + + private async Task GetEmployeeBySalesOrgAsync(TransactionContext tc, EmployeeIntegrationByComapanyRequest request) + { + EmployeeIntegrationResponse response = new EmployeeIntegrationResponse(); + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam(pName: "@EmployeeVendorCode", pType: SqlDbType.NVarChar, pValue: request.EmployeeVendorCode), + SqlHelperExtension.CreateInParam(pName: "@CompanyCode", pType: SqlDbType.NVarChar, pValue: request.CompanyCode) + ]; + + using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetEmployeeByVendorCode", parameterValues: p)) + { + if (dr.Read()) + { + response = new EmployeeIntegrationResponse() + { + EmployeeId = dr.GetInt32(0), + EmployeeVendorCode = dr.GetString(1), + EmployeeVendorName = dr.GetString(2), + Designation = dr.GetString(3), + DesignationDescription = dr.GetString(4), + MobileNo = dr.GetString(5), + Mail = dr.GetString(6), + CompanyCode = dr.GetString(7), + CompanyName = dr.GetString(8), + SalesOrg = dr.GetString(9), + SalesOrgDescription = dr.GetString(10), + DistChannel = dr.GetString(11), + DistChannelDescription = dr.GetString(12), + Division = dr.GetString(13), + DivisionDescription = dr.GetString(14), + RegionAreaCode = dr.GetString(15), + RegionAreaDescription = dr.GetString(16), + AreaAVSalesUnitCode = dr.GetString(17), + AreaAVSalesUnitDescription = dr.GetString(18), + Territory = dr.GetString(19), + TerritoryDescription = dr.GetString(20), + Plant = dr.GetString(21), + PlantDescription = dr.GetString(22), + Status = dr.GetString(23), + StatusDescription = dr.GetString(24) + }; + } + dr.Close(); + } + } + catch (Exception ex) + { + throw DBCustomError.GenerateCustomError(ex); + } + return response; } + + private bool InsertEmployee(TransactionContext tc, EmployeeIntegrationRequest request) + { + bool returnValue = false; + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam(pName: "@EmployeeVendorCode", pType: SqlDbType.NVarChar, pValue: request.EmployeeVendorCode), + SqlHelperExtension.CreateInParam(pName: "@EmployeeVendorName", pType: SqlDbType.NVarChar, pValue: request.EmployeeVendorName), + + SqlHelperExtension.CreateInParam(pName: "@Designation", pType: SqlDbType.NVarChar, pValue: request.Designation), + SqlHelperExtension.CreateInParam(pName: "@DesignationDescription", pType: SqlDbType.NVarChar, pValue: request.DesignationDescription), + + SqlHelperExtension.CreateInParam(pName: "@MobileNo", pType: SqlDbType.NVarChar, pValue: request.MobileNo), + SqlHelperExtension.CreateInParam(pName: "@Mail", pType: SqlDbType.NVarChar, pValue: request.Mail), + + SqlHelperExtension.CreateInParam(pName: "@CompanyCode", pType: SqlDbType.NVarChar, pValue: request.CompanyCode), + SqlHelperExtension.CreateInParam(pName: "@CompanyName", pType: SqlDbType.NVarChar, pValue: request.CompanyName), + + SqlHelperExtension.CreateInParam(pName: "@SalesOrg", pType: SqlDbType.NVarChar, pValue: request.SalesOrg), + SqlHelperExtension.CreateInParam(pName: "@SalesOrgDescription", pType: SqlDbType.NVarChar, pValue: request.SalesOrgDescription), + + SqlHelperExtension.CreateInParam(pName: "@DistChannel", pType: SqlDbType.NVarChar, pValue: request.DistChannel), + SqlHelperExtension.CreateInParam(pName: "@DistChannelDescription", pType: SqlDbType.NVarChar, pValue: request.DistChannelDescription), + + SqlHelperExtension.CreateInParam(pName: "@Division", pType: SqlDbType.NVarChar, pValue: request.Division), + SqlHelperExtension.CreateInParam(pName: "@DivisionDescription", pType: SqlDbType.NVarChar, pValue: request.DivisionDescription), + + SqlHelperExtension.CreateInParam(pName: "@RegionAreaCode", pType: SqlDbType.NVarChar, pValue: request.RegionAreaCode), + SqlHelperExtension.CreateInParam(pName: "@RegionAreaDescription", pType: SqlDbType.NVarChar, pValue: request.RegionAreaDescription), + + SqlHelperExtension.CreateInParam(pName: "@AreaAVSalesUnitCode", pType: SqlDbType.NVarChar, pValue: request.AreaAVSalesUnitCode), + SqlHelperExtension.CreateInParam(pName: "@AreaAVSalesUnitDescription", pType: SqlDbType.NVarChar, pValue: request.AreaAVSalesUnitDescription), + + SqlHelperExtension.CreateInParam(pName: "@Territory", pType: SqlDbType.NVarChar, pValue: request.Territory), + SqlHelperExtension.CreateInParam(pName: "@TerritoryDescription", pType: SqlDbType.NVarChar, pValue: request.TerritoryDescription), + + SqlHelperExtension.CreateInParam(pName: "@Plant", pType: SqlDbType.NVarChar, pValue: request.Plant), + SqlHelperExtension.CreateInParam(pName: "@PlantDescription", pType: SqlDbType.NVarChar, pValue: request.PlantDescription), + + SqlHelperExtension.CreateInParam(pName: "@Status", pType: SqlDbType.NChar, pValue: request.Status), + SqlHelperExtension.CreateInParam(pName: "@StatusDescription", pType: SqlDbType.NVarChar, pValue: request.StatusDescription) + ]; + + _ = tc.ExecuteNonQuerySp(spName: "dbo.InsertEmployee", parameterValues: p); + + returnValue = true; + } + catch (Exception) + { + throw; + } + + return returnValue; + } + + private bool UpdateEmployee(TransactionContext tc, EmployeeIntegrationRequest request) + { + bool returnValue = false; + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam(pName: "@EmployeeVendorCode", pType: SqlDbType.NVarChar, pValue: request.EmployeeVendorCode), + SqlHelperExtension.CreateInParam(pName: "@CompanyCode", pType: SqlDbType.NVarChar, pValue: request.CompanyCode), + + SqlHelperExtension.CreateInParam(pName: "@EmployeeVendorName", pType: SqlDbType.NVarChar, pValue: request.EmployeeVendorName), + + SqlHelperExtension.CreateInParam(pName: "@Designation", pType: SqlDbType.NVarChar, pValue: request.Designation), + SqlHelperExtension.CreateInParam(pName: "@DesignationDescription", pType: SqlDbType.NVarChar, pValue: request.DesignationDescription), + + SqlHelperExtension.CreateInParam(pName: "@MobileNo", pType: SqlDbType.NVarChar, pValue: request.MobileNo), + SqlHelperExtension.CreateInParam(pName: "@Mail", pType: SqlDbType.NVarChar, pValue: request.Mail), + + SqlHelperExtension.CreateInParam(pName: "@CompanyName", pType: SqlDbType.NVarChar, pValue: request.CompanyName), + + SqlHelperExtension.CreateInParam(pName: "@SalesOrg", pType: SqlDbType.NVarChar, pValue: request.SalesOrg), + SqlHelperExtension.CreateInParam(pName: "@SalesOrgDescription", pType: SqlDbType.NVarChar, pValue: request.SalesOrgDescription), + + SqlHelperExtension.CreateInParam(pName: "@DistChannel", pType: SqlDbType.NVarChar, pValue: request.DistChannel), + SqlHelperExtension.CreateInParam(pName: "@DistChannelDescription", pType: SqlDbType.NVarChar, pValue: request.DistChannelDescription), + + SqlHelperExtension.CreateInParam(pName: "@Division", pType: SqlDbType.NVarChar, pValue: request.Division), + SqlHelperExtension.CreateInParam(pName: "@DivisionDescription", pType: SqlDbType.NVarChar, pValue: request.DivisionDescription), + + SqlHelperExtension.CreateInParam(pName: "@RegionAreaCode", pType: SqlDbType.NVarChar, pValue: request.RegionAreaCode), + SqlHelperExtension.CreateInParam(pName: "@RegionAreaDescription", pType: SqlDbType.NVarChar, pValue: request.RegionAreaDescription), + + SqlHelperExtension.CreateInParam(pName: "@AreaAVSalesUnitCode", pType: SqlDbType.NVarChar, pValue: request.AreaAVSalesUnitCode), + SqlHelperExtension.CreateInParam(pName: "@AreaAVSalesUnitDescription", pType: SqlDbType.NVarChar, pValue: request.AreaAVSalesUnitDescription), + + SqlHelperExtension.CreateInParam(pName: "@Territory", pType: SqlDbType.NVarChar, pValue: request.Territory), + SqlHelperExtension.CreateInParam(pName: "@TerritoryDescription", pType: SqlDbType.NVarChar, pValue: request.TerritoryDescription), + + SqlHelperExtension.CreateInParam(pName: "@Plant", pType: SqlDbType.NVarChar, pValue: request.Plant), + SqlHelperExtension.CreateInParam(pName: "@PlantDescription", pType: SqlDbType.NVarChar, pValue: request.PlantDescription), + + SqlHelperExtension.CreateInParam(pName: "@Status", pType: SqlDbType.NChar, pValue: request.Status), + SqlHelperExtension.CreateInParam(pName: "@StatusDescription", pType: SqlDbType.NVarChar, pValue: request.StatusDescription) + ]; + + _ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateEmployee", parameterValues: p); + + returnValue = true; + } + catch (Exception) + { + throw; + } + + return returnValue; + } + + #endregion + + #region Meterial Private Functions + + private async Task GetMaterialByCodeAsync(TransactionContext tc, GetMaterialByCodeRequest request) + { + MaterialIntegrationResponse response = new MaterialIntegrationResponse(); + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam(pName: "@MaterialCode", pType: SqlDbType.NVarChar, pValue: request.MaterialCode) + ]; + + using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetMaterialByMaterialCode", parameterValues: p)) + { + if (dr.Read()) + { + response = new MaterialIntegrationResponse() + { + MeterialId = dr.GetInt32(0), + MaterialType = dr.GetString(1), + MaterialTypeDescription = dr.GetString(2), + MaterialCode = dr.GetString(3), + MaterialDescription = dr.GetString(4), + MaterialGroupCode = dr.GetString(5), + MaterialGroupDescription = dr.GetString(6), + BaseUnitOfMeasure = dr.GetString(7), + SalesUnitOfMeasure = dr.GetString(8), + UnitConversionWithBaseUoM = dr.GetDecimal(9), + PlantCode = dr.GetString(10), + PlantDescription = dr.GetString(11), + StorageLocationCode = dr.GetString(12), + StorageLocationDescription = dr.GetString(13), + SalesOrganization = dr.GetString(14), + SalesOrganizationDescription = dr.GetString(15), + }; + } + dr.Close(); + } + } + catch (Exception ex) + { + throw DBCustomError.GenerateCustomError(ex); + } + + return response; + } + + private bool CreateMaterial(TransactionContext tc, MaterialIntegrationRequest request) + { + bool returnValue = false; + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam("@MaterialType", SqlDbType.NVarChar, request.MaterialType), + SqlHelperExtension.CreateInParam("@MaterialTypeDescription", SqlDbType.NVarChar, request.MaterialTypeDescription), + + SqlHelperExtension.CreateInParam("@MaterialCode", SqlDbType.NVarChar, request.MaterialCode), + SqlHelperExtension.CreateInParam("@MaterialDescription", SqlDbType.NVarChar, request.MaterialDescription), + + SqlHelperExtension.CreateInParam("@MaterialGroupCode", SqlDbType.NVarChar, request.MaterialGroupCode), + SqlHelperExtension.CreateInParam("@MaterialGroupDescription", SqlDbType.NVarChar, request.MaterialGroupDescription), + + SqlHelperExtension.CreateInParam("@BaseUnitOfMeasure", SqlDbType.NVarChar, request.BaseUnitOfMeasure), + SqlHelperExtension.CreateInParam("@SalesUnitOfMeasure", SqlDbType.NVarChar, request.SalesUnitOfMeasure), + + SqlHelperExtension.CreateInParam("@UnitConversionWithBaseUoM", SqlDbType.Decimal, request.UnitConversionWithBaseUoM), + + SqlHelperExtension.CreateInParam("@PlantCode", SqlDbType.NVarChar, request.PlantCode), + SqlHelperExtension.CreateInParam("@PlantDescription", SqlDbType.NVarChar, request.PlantDescription), + + SqlHelperExtension.CreateInParam("@StorageLocationCode", SqlDbType.NVarChar, request.StorageLocationCode), + SqlHelperExtension.CreateInParam("@StorageLocationDescription", SqlDbType.NVarChar, request.StorageLocationDescription), + + SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization), + SqlHelperExtension.CreateInParam("@SalesOrganizationDescription", SqlDbType.NVarChar, request.SalesOrganizationDescription) + ]; + + _ = tc.ExecuteNonQuerySp(spName: "dbo.CreateMaterial", parameterValues: p); + + returnValue = true; + } + catch (Exception) + { + throw; + } + + return returnValue; + } + + private bool UpdateMaterial(TransactionContext tc, MaterialIntegrationRequest request) + { + bool returnValue = false; + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam("@MaterialType", SqlDbType.NVarChar, request.MaterialType), + SqlHelperExtension.CreateInParam("@MaterialTypeDescription", SqlDbType.NVarChar, request.MaterialTypeDescription), + + SqlHelperExtension.CreateInParam("@MaterialCode", SqlDbType.NVarChar, request.MaterialCode), + SqlHelperExtension.CreateInParam("@MaterialDescription", SqlDbType.NVarChar, request.MaterialDescription), + + SqlHelperExtension.CreateInParam("@MaterialGroupCode", SqlDbType.NVarChar, request.MaterialGroupCode), + SqlHelperExtension.CreateInParam("@MaterialGroupDescription", SqlDbType.NVarChar, request.MaterialGroupDescription), + + SqlHelperExtension.CreateInParam("@BaseUnitOfMeasure", SqlDbType.NVarChar, request.BaseUnitOfMeasure), + SqlHelperExtension.CreateInParam("@SalesUnitOfMeasure", SqlDbType.NVarChar, request.SalesUnitOfMeasure), + + SqlHelperExtension.CreateInParam("@UnitConversionWithBaseUoM", SqlDbType.Decimal, request.UnitConversionWithBaseUoM), + + SqlHelperExtension.CreateInParam("@PlantCode", SqlDbType.NVarChar, request.PlantCode), + SqlHelperExtension.CreateInParam("@PlantDescription", SqlDbType.NVarChar, request.PlantDescription), + + SqlHelperExtension.CreateInParam("@StorageLocationCode", SqlDbType.NVarChar, request.StorageLocationCode), + SqlHelperExtension.CreateInParam("@StorageLocationDescription", SqlDbType.NVarChar, request.StorageLocationDescription), + + SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization), + SqlHelperExtension.CreateInParam("@SalesOrganizationDescription", SqlDbType.NVarChar, request.SalesOrganizationDescription) + ]; + + _ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateMaterial", parameterValues: p); + + returnValue = true; + } + catch (Exception) + { + throw; + } + + return returnValue; + } + + #endregion } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Systems/UserService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Systems/UserService.cs index f447bad..13cb407 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Systems/UserService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Systems/UserService.cs @@ -3,8 +3,6 @@ using Ease.NetCore.DataAccess.SQL; using Ease.NetCore.Utility; using OnlineSalesAutoCrop.CoreAPI.Models; using OnlineSalesAutoCrop.CoreAPI.Models.Global; -using OnlineSalesAutoCrop.CoreAPI.Models.Objects; -using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Setups; using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems; using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems; using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems; diff --git a/Api/OnlineSalesAutoCrop.CoreAPI/.config/dotnet-tools.json b/Api/OnlineSalesAutoCrop.CoreAPI/.config/dotnet-tools.json deleted file mode 100644 index b0e38ab..0000000 --- a/Api/OnlineSalesAutoCrop.CoreAPI/.config/dotnet-tools.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": {} -} \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationAuthController.cs b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationAuthController.cs index cba08ce..b3c59be 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationAuthController.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationAuthController.cs @@ -1,36 +1,26 @@ -using Asp.Versioning; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.SignalR; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Microsoft.IdentityModel.Tokens; -using OnlineSalesAutoCrop.CoreAPI.Configurations; -using OnlineSalesAutoCrop.CoreAPI.Models; -using OnlineSalesAutoCrop.CoreAPI.Models.Global; -using OnlineSalesAutoCrop.CoreAPI.Models.Objects; -using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems; -using OnlineSalesAutoCrop.CoreAPI.Models.Requests; -using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; -using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Setups; -using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems; -using OnlineSalesAutoCrop.CoreAPI.Models.Responses; -using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; -using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems; -using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth; -using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems; -using OnlineSalesAutoCrop.CoreAPI.SignalRHub; -using System; -using System.Collections.Generic; +using System; using System.DirectoryServices; using System.IdentityModel.Tokens.Jwt; -using System.IO; -using System.Linq; using System.Runtime.Versioning; using System.Security.Claims; using System.Text; using System.Threading.Tasks; +using Asp.Versioning; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using OnlineSalesAutoCrop.CoreAPI.Models; +using OnlineSalesAutoCrop.CoreAPI.Models.Global; +using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems; +using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; +using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; +using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems; +using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth; +using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems; + namespace OnlineSalesAutoCrop.CoreAPI.Controllers { @@ -215,12 +205,12 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers string userToken = tokenHandler.WriteToken(token); GenerateRefreshTokenRequest refreshTokenRequest = new GenerateRefreshTokenRequest() { - User = user, + UserId = user.UserId, IpAddress = ipAddress, - RawRefreshToken = request.RefreshToken + RawRefreshToken = string.Empty }; - var refreshToken =await _refreshTokenService.GenerateRefreshToken(refreshTokenRequest); + var refreshToken =await _refreshTokenService.GenerateRefreshTokenByUserAsync(refreshTokenRequest); //If token length is greater than or equal to 4096 (4KB) then return error @@ -253,1749 +243,117 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers } } - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("loadMenu")] - public async Task LoadMenu([FromBody] ByUserIdRequest request) + + /// + /// Login using your credential data retrieve from SqlServer + /// + /// + /// + /// + /// If login successful ValidUser: true + /// If login successful Return ValidUser: true and UserName: not empty + [HttpPost("RefreshToken")] + [AllowAnonymous] + [IgnoreAntiforgeryToken] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationLoginResponse))] + public async Task GetRefreshToken([FromBody] IntegrationRefreshTokenRequest request) { - ArgumentNullException.ThrowIfNull(request); - - try - { - MenuResponse response = await _service.GetUserPermissionsAsync(userId: request.UserId); - return Ok(response.Item); - } - catch (Exception ex) - { - _logger.LogError(ex); - return StatusCode(StatusCodes.Status500InternalServerError, (ex.InnerException != null ? ex.InnerException.Message : ex.Message)); - } - } - - /// - /// - /// - /// - /// - [IgnoreAntiforgeryToken] - [HttpPost("validateOtp")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task ValidateOtp([FromBody] OtpValidationRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { Value = false, ReturnStatus = StatusCodes.Status200OK }; - if (string.IsNullOrEmpty(request.OtpCode) || request.OtpCode.Length != 6) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Otp must be 6 digit."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - if (request.AuthMethod == EnumAuthenticationMethod.ThirdPartyAuthenticator) + IntegrationRrefreshTokenResponse response = new(); + try + { + var userRefreshToken = await _refreshTokenService.GetUserByRefreshTokenAsync(request.RefreshToken); + if(!userRefreshToken.IsActive) { - string secretKey = HttpContext.User.GetClaimValue("AuthKey"); - if (string.IsNullOrEmpty(secretKey)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Authentication key is required."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } + string msg = $"Refresh Token is not active: {request?.RefreshToken}"; + _logger.LogError(message: msg); + response.ReturnStatus = StatusCodes.Status401Unauthorized; + response.ReturnMessage.Add(msg); + return StatusCode(StatusCodes.Status401Unauthorized, response); + } - TOtpService otp = new(); - DateTime now = DateTime.UtcNow; - response.Value = otp.ValidateTwoFactorPIN(secretKey, request.OtpCode, now); - } - else + byte[] key = Encoding.ASCII.GetBytes(_appSettings.JwtCryptoKey); + JwtSecurityTokenHandler tokenHandler = new(); + var tokenDescriptor = new SecurityTokenDescriptor { - response.Value = await _service.ValidateAuthValueAsync(request.OtpCode, request.UserId); - } - - if (!response.Value) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("This is not a valid Otp."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - else - { - return Ok(response); - } - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status406NotAcceptable; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("addUser")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task AddUser([FromBody] NewUserRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - bool permitted = await HttpContext.IsPermitted("ELIT.1.2.2_1"); - if (!permitted) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add("You are not authorize to Add User."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string ipAddress = Request.HttpContext.GetIpAddress(); - int createdBy = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.AddUserAsync(user: request, ipAddress: ipAddress, createdBy: createdBy); - response.ReturnMessage.Add("User added successfully..."); - - //Cache - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("editUser")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task EditUser([FromBody] UserRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - bool permitted = await HttpContext.IsPermitted("ELIT.1.2.2_2"); - if (!permitted) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add("You are not authorize to Update User."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (request.AuthMethod == EnumAuthenticationMethod.ThirdPartyAuthenticator && (string.IsNullOrEmpty(request.AuthKey) || string.IsNullOrWhiteSpace(request.AuthKey) || request.AuthKey.Length <= 0)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("For third party Authenticator, Authentication key is required."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string ipAddress = Request.HttpContext.GetIpAddress(); - int modifiedBy = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.EditUserAsync(user: request, ipAddress: ipAddress, modifiedBy: modifiedBy); - response.ReturnMessage.Add("User edited successfully..."); - - //Cache - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("deleteUser")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task DeleteUser([FromBody] ByUserIdRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - bool permitted = await HttpContext.IsPermitted("ELIT.1.2.2_3"); - if (!permitted) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add("You are not authorize to Delete User."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - int deletedBy = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.DeleteUserAsync(userId: request.UserId, deletedBy: deletedBy); - response.ReturnMessage.Add("User deleted successfully..."); - - //Cache - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("unlockUser")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task UnlockUser([FromBody] UserUnlockRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - bool permitted = await HttpContext.IsPermitted("ELIT.1.2.2_2"); - if (!permitted) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add("You are not authorize to Unlock User."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - int unlockedBy = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.UnlockUserAsync(userId: request.UserId, loginId: request.LoginId, unlockedBy: unlockedBy); - response.ReturnMessage.Add("User Unlocked successfully..."); - - //Cache - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("resetPassword")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task ResetPassword([FromBody] ResetPasswordRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - if (request.UserId == 0) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("User is not valid."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.Password) || string.IsNullOrWhiteSpace(request.Password)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Invalid parameter value Password."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.ConfirmPassword) || string.IsNullOrWhiteSpace(request.ConfirmPassword)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Invalid parameter value Confirm Password."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - #region Decrypt Password - - string cipherSecretKey = GlobalFunctions.ConvertFromBase64String(_appSettings.CipherSecretKey); - request.Password = Helper.DecryptData(secret: cipherSecretKey, data: request.Password); - request.ConfirmPassword = Helper.DecryptData(secret: cipherSecretKey, data: request.ConfirmPassword); - - #endregion - - if (!request.Password.Equals(request.ConfirmPassword)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("New password and confirm password are not same."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - bool permitted = await HttpContext.IsPermitted("ELIT.1.2.3_2"); - if (!permitted) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add("You are not authorize to Reset Password."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string ipAddress = Request.HttpContext.GetIpAddress(); - int changedBy = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.ResetPasswordAsync(userId: request.UserId, newPassword: request.ConfirmPassword, ipAddress: ipAddress, changedBy: changedBy); - response.ReturnMessage.Add("Password Reset successfully, User must change password at next Login."); - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [IgnoreAntiforgeryToken] - [HttpPost("changePassword")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task ChangePassword([FromBody] PasswordChangeRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - if (request.UserId == 0) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add("Your not a valid user."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.OldPassword) || string.IsNullOrWhiteSpace(request.OldPassword)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Invalid parameter value Old Password."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.Password) || string.IsNullOrWhiteSpace(request.Password)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Invalid parameter value Password."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.ConfirmPassword) || string.IsNullOrWhiteSpace(request.ConfirmPassword)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Invalid parameter value Confirm Password."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - #region Decrypt Password - - string cipherSecretKey = GlobalFunctions.ConvertFromBase64String(_appSettings.CipherSecretKey); - request.OldPassword = Helper.DecryptData(secret: cipherSecretKey, data: request.OldPassword); - request.Password = Helper.DecryptData(secret: cipherSecretKey, data: request.Password); - request.ConfirmPassword = Helper.DecryptData(secret: cipherSecretKey, data: request.ConfirmPassword); - - #endregion - - if (!request.Password.Equals(request.ConfirmPassword)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("New password and confirm password are not same."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string ipAddress = Request.HttpContext.GetIpAddress(); - int changedBy = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.ChangePasswordAsync(userId: request.UserId, oldPassword: request.OldPassword, newPassword: request.ConfirmPassword, ipAddress: ipAddress, changedBy: changedBy); - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("updateMyPassword")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task UpdateMyPassword([FromBody] PasswordChangeRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - if (string.IsNullOrEmpty(request.OldPassword) || string.IsNullOrWhiteSpace(request.OldPassword)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Invalid parameter value Old Password."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.Password) || string.IsNullOrWhiteSpace(request.Password)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Invalid parameter value Password."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.ConfirmPassword) || string.IsNullOrWhiteSpace(request.ConfirmPassword)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Invalid parameter value Confirm Password."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - #region Decrypt Password - - string cipherSecretKey = GlobalFunctions.ConvertFromBase64String(_appSettings.CipherSecretKey); - request.OldPassword = Helper.DecryptData(secret: cipherSecretKey, data: request.OldPassword); - request.Password = Helper.DecryptData(secret: cipherSecretKey, data: request.Password); - request.ConfirmPassword = Helper.DecryptData(secret: cipherSecretKey, data: request.ConfirmPassword); - - #endregion - - if (!request.Password.Equals(request.ConfirmPassword)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("New password and confirm password are not same."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string ipAddress = Request.HttpContext.GetIpAddress(); - int userId = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.ChangePasswordAsync(userId: userId, oldPassword: request.OldPassword, newPassword: request.ConfirmPassword, ipAddress: ipAddress, changedBy: userId); - response.ReturnMessage.Add("Password changed successfully."); - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("updateMyTheme")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task UpdateMyTheme([FromBody] UserThemeRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - int userId = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.UpdateMyThemeAsync(userId: userId, menuLayout: request.MenuLayout, themeName: request.ThemeName, schemeName: request.SchemeName); - response.ReturnMessage.Add("Your theme set successfully. Need re-login to see the effect."); - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("updateMyInfo")] - [AllowAnonymous, IgnoreAntiforgeryToken] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task UpdateMyInfo([FromBody] UpdateMyInfoRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - if (request.EmployeeId < 0) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("System allow to update only Your Information."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - int modifiedBy = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.UpdateMyInfoAsync(address: request.Address, contactNo: request.ContactNo, modifiedBy: modifiedBy, emplyeeId: request.EmployeeId); - response.ReturnMessage.Add("Your Information updated successfully."); - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getAttributes")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserAttributesResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(UserAttributesResponse))] - public async Task GetAttributes([FromBody] ByUserAttributesRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - UserAttributesResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - string key = "UserAttributes"; - string key2 = $"{request.UserId}~{request.ClientType}"; - if (!_cache.TryGetValue(key: key, key2: key2, value: out response)) - { - response = await _service.GetAttributesAsync(userId: request.UserId, clientType: request.ClientType); - - //Cache - _ = _cache.Set(key: key, key2: key2, value: response, options: _options); - } - response.ReturnStatus = StatusCodes.Status200OK; - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("saveAttributes")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task SaveAttributes([FromBody] UserAttributesRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - if (request.UkIds == null || request.UkIds.Count <= 0) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("There is no data to save."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - string msg, key; - if (request.ClientType == 2) - { - key = "ELIT.1.5.12_2"; - msg = "Supplier(s) to user"; - } - else - { - key = "ELIT.1.5.11_2"; - msg = "Project(s) to user"; - } - - bool permitted = await HttpContext.IsPermitted(key); - if (!permitted) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add($"You are not authorize to Assign {msg}."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string ipAddress = Request.HttpContext.GetIpAddress(); - int attributeSetBy = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.SaveAttributesAsync(userId: request.UserId, clientType: request.ClientType, ipAddress: ipAddress, attributeSetBy: attributeSetBy, ukIds: request.UkIds); - response.ReturnMessage.Add($"{msg} Assigned successfully..."); - - //Cache - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("deleteAttributes")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task DeleteAttributes([FromBody] ByUserAttributesRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - string msg, key; - if (request.ClientType == 2) - { - key = "ELIT.1.5.12_3"; - msg = "Supplier(s) from user"; - } - else - { - key = "ELIT.1.5.11_3"; - msg = "Project(s) from user"; - } - - bool permitted = await HttpContext.IsPermitted(key); - if (!permitted) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add($"You are not authorize to Unassign {msg}."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - int deletedBy = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.DeleteAttributesAsync(userId: request.UserId, clientType: request.ClientType, deletedBy: deletedBy); - response.ReturnMessage.Add($"{msg} Unassigned successfully..."); - - //Cache - _cache.Clear("User"); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// Returns users according to search criteria. - /// - /// - /// top 50 users - /// - /// Top 50 users - /// If the item is null. - //[ValidateSession] - //[HttpPost("getUsers")] - //[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserSearchResponse))] - //[ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(UserSearchResponse))] - //public async Task GetUsers([FromBody] UserSearchRequest request) - //{ - // ArgumentNullException.ThrowIfNull(request); - - // UserSearchResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - // try - // { - // int userId = HttpContext.User.GetClaimValue(Constants.UserId); - // request.CheckOwner = userId != Models.Objects.Systems.User.SuperUser_Id; - - // string key = "Users"; - // string key2 = $"{request.Criteria}~{request.Status}~{request.SortField}~{request.SortOrder}~{request.Skip}~{request.PageSize}~{request.CheckOwner}~{userId}"; - // if (!_cache.TryGetValue(key: key, key2: key2, value: out response)) - // { - // response = await _service.GetUsersAsync(request: request, userId: userId); - // _ = _cache.Set(key: key, key2: key2, value: response, options: _options); - // } - - // response.ReturnStatus = StatusCodes.Status200OK; - // return Ok(response); - // } - // catch (Exception ex) - // { - // _logger.LogError(ex); - // response.ReturnStatus = StatusCodes.Status500InternalServerError; - // response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - // return StatusCode(StatusCodes.Status500InternalServerError, response); - // } - //} - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getUsersBasic")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserBasicInfoResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(UserBasicInfoResponse))] - public async Task GetUsersBasic([FromBody] BasicUserSearchRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - UserBasicInfoResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - string teamSpaceIds = request.TeamSpaceId > 0 ? $"{request.TeamSpaceId}" : HttpContext.User.GetClaimValue("TeamSpaceIds"); - response = await _service.GetUsersBasicAsync(applyFilter: request.ApplyFilter, teamSpaceIds: teamSpaceIds, projectId: request.ProjectId); - response.ReturnStatus = StatusCodes.Status200OK; - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getUsersByTeamSpace")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserBasicInfoResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(UserBasicInfoResponse))] - public async Task GetUsersByTeamSpace([FromBody] BasicUserByTeamSpaceRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - UserBasicInfoResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - string teamSpaceIds = request.TeamSpaceId > 0 ? $"{request.TeamSpaceId}" : HttpContext.User.GetClaimValue("TeamSpaceIds"); - response = await _service.GetUsersByTeamSpaceAsync(teamSpaceIds: teamSpaceIds, projectId: request.ProjectId, userId: request.UserId); - response.ReturnStatus = StatusCodes.Status200OK; - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getAttendanceUsers")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserBasicInfoResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(UserBasicInfoResponse))] - public async Task GetAttendanceUsers([FromBody] ByUserIdRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - UserBasicInfoResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - response = await _service.GetAttendanceUsersAsync(userId: request.UserId); - response.ReturnStatus = StatusCodes.Status200OK; - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getUsersForForceLogout")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserForceLogoutResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(UserForceLogoutResponse))] - public async Task GetForceLogoutUsers([FromBody] NoContentRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - UserForceLogoutResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - int userId = HttpContext.User.GetClaimValue(Constants.UserId); - response = await _service.GetForceLogoutUsersAsync(createdBy: userId); - - response.ReturnStatus = StatusCodes.Status200OK; - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - [ValidateSession] - [HttpPost("forceLogoutNow")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(BooleanResponse))] - public async Task ForceLogoutNow([FromBody] ForceUserLogoutRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - if (request.UserIds == null || request.UserIds.Count <= 0) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Parameter value is null/no User was selected."); - return BadRequest(response); - } - - bool permitted = await HttpContext.IsPermitted("ELIT.1.2.4_2"); - if (!permitted) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add("You are not authorize to Do Force Logout."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string ipAddress = Request.HttpContext.GetIpAddress(); - response.Value = await _service.ForceLogoutNowAsync(userIds: request.UserIds, ipAddress: ipAddress); - response.ReturnMessage.Add("Process completed successfully..."); - response.ReturnStatus = StatusCodes.Status200OK; - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getUser")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserGetResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(UserGetResponse))] - public async Task GetUser([FromBody] ByUserIdRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - UserGetResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - string key = "User"; - string key2 = $"{request.UserId}"; - if (!_cache.TryGetValue(key: key, key2: key2, value: out response)) - { - response = await _service.GetUserAsync(userId: request.UserId); - _ = _cache.Set(key: key, key2: key2, value: response, options: _options); - } - response.ReturnStatus = StatusCodes.Status200OK; - return Ok(response); - - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getCurrentUser")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserGetResponse))] - public async Task GetCurrentUser([FromBody] NoContentRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - UserGetResponse response; - try - { - int userId = HttpContext.User.GetClaimValue(Constants.UserId); - - string key = "UserCurrent"; - string key2 = $"{userId}"; - if (!_cache.TryGetValue(key: key, key2: key2, value: out response)) - { - response = await _service.GetUserAsync(userId: userId); - response.ReturnStatus = StatusCodes.Status200OK; - _ = _cache.Set(key: key, key2: key2, value: response, options: _options); - } - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response = new UserGetResponse() { ReturnStatus = StatusCodes.Status500InternalServerError }; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getMyProfile")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserProfileResponse))] - public async Task GetMyProfile([FromBody] NoContentRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - UserProfileResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - int userId = HttpContext.User.GetClaimValue(Constants.UserId); - response = await _service.GetUserProfileAsync(userId: userId); - response.HasPayslipPath = !string.IsNullOrEmpty(_appSettings.PayslipPath); - response.HasAIApiKey = !string.IsNullOrEmpty(_appSettings.ApiKeyOpenAI) || !string.IsNullOrEmpty(_appSettings.ApiKeyGoogle); - response.ReturnStatus = StatusCodes.Status200OK; - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getMyPayslip")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(StringResponse))] - public IActionResult GetMyPayslip([FromBody] PayslipRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - StringResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - if (string.IsNullOrEmpty(_appSettings.PayslipPath)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Payslip path is not in the system."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - string employeeId = HttpContext.User.GetClaimValue("EmployeeId"); - if (string.IsNullOrEmpty(employeeId)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("You are not a valid Employee to view payslip."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string path = $"{employeeId}_{request.YearMonth:yyyy}_{request.YearMonth:MM}.pdf"; - path = Path.Combine(_appSettings.PayslipPath, path); - if (System.IO.File.Exists(path)) - { - response.Value = Convert.ToBase64String(System.IO.File.ReadAllBytes(path: path)); - return Ok(response); - } - else - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add($"Payslip does not exists for the Month: {request.YearMonth:MMMM, yyyy}"); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("sendQrCodeViaEmail")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public IActionResult SendQrCodeViaEmail([FromForm] QRCodeUploadRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - if (string.IsNullOrEmpty(request.EmailAddress)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("There is no email address to send mail."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.FileName)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("There is no image to send to send mail."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (request.FileData.Length <= 0) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("There is no image to send to send mail."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - Result result = ImageFileValidator.Validate(request.FileData); - if (!result.Acceptable) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("This is not a valid image file."); - return BadRequest(response); - } - - var fileSpec = Path.Combine(_appSettings.UploadFolder, request.FileName); - if (System.IO.File.Exists(fileSpec)) - System.IO.File.Delete(fileSpec); - - using (var stream = new FileStream(fileSpec, FileMode.Create)) - { - request.FileData.CopyTo(stream); - } - - bool sent = MailHelper.SendMailMessage(settings: _appSettings, to: [request.EmailAddress], - cc: null, bcc: null, attachments: [fileSpec], embeddedImages: null, isHtmlBody: false, - priority: System.Net.Mail.MailPriority.High, subject: "QR Code", messageBody: "Scan image"); - - if (sent) - { - if (System.IO.File.Exists(fileSpec)) - System.IO.File.Delete(fileSpec); - - response.Value = sent; - response.ReturnMessage.Add($"Successfully mail sent to {request.EmailAddress}"); - return Ok(response); - } - else - { - response.Value = sent; - response.ReturnMessage.Add($"Cannot send mail to {request.EmailAddress}"); - return StatusCode(StatusCodes.Status422UnprocessableEntity, response); - } - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("uploadProfileImage")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public IActionResult UploadProfileImage([FromForm] FileUploadRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - if (string.IsNullOrEmpty(request.FileName)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("There is no Image to set Profile image."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (request.FileData.Length <= 0) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("There is no image to set Profile image."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - Result result = ImageFileValidator.Validate(request.FileData); - if (!result.Acceptable) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("This is not a valid image file."); - return BadRequest(response); - } - - long maxSz = 20 * 1024; - if (request.FileData.Length > maxSz) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Maximum size allowed is 20 Kb"); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - var fileSpec = Path.Combine(_appSettings.ProfileImageFolder, request.FileName); - if (System.IO.File.Exists(fileSpec)) - System.IO.File.Delete(fileSpec); - - using (var stream = new FileStream(fileSpec, FileMode.Create)) - { - request.FileData.CopyTo(stream); - } - response.Value = true; - response.ReturnMessage.Add("Refresh page to view your profile image."); - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("uploadDocument")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task UploadDocument([FromForm] UploadDocumentRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - if (string.IsNullOrEmpty(request.FileName)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("There is no valid file to process."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (request.FileData.Length <= 0) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("There is no valid data to process."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - string fileName, fileSpec; - if (request.DocumentOf == 6) - { - string[] allowedExtensions = [".xlsx", ".xls"]; - string fileExtension = Path.GetExtension(request.FileName).ToLowerInvariant(); - if (!allowedExtensions.Contains(fileExtension)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Only excel file is allowed to process."); - return BadRequest(response); - } - - if (fileExtension.EndsWith(".xls")) - { - Result result = ExcelFileValidator.Validate(request.FileData); - if (!result.Acceptable) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("This is not a valid Excel file."); - return BadRequest(response); - } - } - else - { - Result result = ExcelxFileValidator.Validate(request.FileData); - if (!result.Acceptable) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("This is not a valid Excel file."); - return BadRequest(response); - } - } - - fileName = request.FileName; - fileSpec = Path.Combine(_appSettings.UploadFolder, fileName); - if (System.IO.File.Exists(fileSpec)) - System.IO.File.Delete(fileSpec); - } - else if (request.DocumentOf == 2) - { - if (!request.FileName.ToLower().EndsWith(".csv")) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Only csv file is allowed to process."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - fileName = request.FileName; - fileSpec = Path.Combine(_appSettings.UploadFolder, fileName); - if (System.IO.File.Exists(fileSpec)) - System.IO.File.Delete(fileSpec); - } - else - { - if (!request.FileName.ToLower().EndsWith(".pdf")) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Only pdf file is allowed to Process."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - long maxSz = 10 * 1024 * 1024; - if (request.FileData.Length > maxSz) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Maximum allowable size is 10 MB"); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - fileName = $"{request.Id}_{request.DocumentOf}.pdf"; - fileSpec = Path.Combine(_appSettings.UploadFolder, fileName); - if (System.IO.File.Exists(fileSpec)) - System.IO.File.Delete(fileSpec); - } - - using (var stream = new FileStream(fileSpec, FileMode.Create)) - { - request.FileData.CopyTo(stream); - } - - int userId = HttpContext.User.GetClaimValue(Constants.UserId); - response.Value = await _service.UploadDocumentAsync(userId: userId, id: request.Id, documentOf: request.DocumentOf, orgFileName: request.FileName, fileName: fileName); - response.ReturnMessage.Add("File Uploaded successfully."); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getDocument")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(StringResponse))] - public IActionResult GetDocument([FromBody] FileViewRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - StringResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - if (string.IsNullOrEmpty(request.FileName)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("There is no Image to set Profile image."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - string path = Path.Combine(_appSettings.UploadFolder, request.FileName); - if (System.IO.File.Exists(path)) - { - response.Value = Convert.ToBase64String(System.IO.File.ReadAllBytes(path: path)); - } - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [HttpPost("findAccount")] - [AllowAnonymous, IgnoreAntiforgeryToken] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(FindAccountResponse))] - public async Task FindAccount([FromBody] FindAccountRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - FindAccountResponse response = new(); - if (string.IsNullOrEmpty(request.AccountId)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Login Id or Email address or Mobile number is required."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string key = GlobalFunctions.ConvertFromBase64String(_appSettings.CipherSecretKey); - request.AccountId = Helper.DecryptData(secret: key, data: request.AccountId); - response = await _service.FindAccountAsync(accountId: request.AccountId); - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [HttpPost("sendPassword")] - [AllowAnonymous, IgnoreAntiforgeryToken] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task SendPassword([FromBody] SendPasswordRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - if (string.IsNullOrEmpty(request.UserId)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("User Id is required."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.MobileNo)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Mobile number is required."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - if (string.IsNullOrEmpty(request.EmailAddress)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Email address is required."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string key = GlobalFunctions.ConvertFromBase64String(_appSettings.CipherSecretKey); - string decipherValue = Helper.DecryptData(secret: key, data: request.UserId); - if (string.IsNullOrEmpty(decipherValue)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("User Id is required."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - if (!int.TryParse(decipherValue, out int userId)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("User Id is required."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - if (userId == 0) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("User Id is required."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - request.MobileNo = Helper.DecryptData(secret: key, data: request.MobileNo); - request.EmailAddress = Helper.DecryptData(secret: key, data: request.EmailAddress); - if (string.IsNullOrEmpty(request.MobileNo) && string.IsNullOrEmpty(request.EmailAddress)) - { - response.ReturnStatus = StatusCodes.Status417ExpectationFailed; - response.ReturnMessage.Add("Mobile number and Email address both cannot be empty."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - //Do reset password - string newPassword = $"{new Random().Next(100000, 999999)}"; - string ipAddress = Request.HttpContext.GetIpAddress(); - response.Value = await _service.SendPasswordAsync(userId: userId, newPassword: newPassword, ipAddress: ipAddress); - if (response.Value) - { - if (!string.IsNullOrEmpty(request.EmailAddress) && !string.IsNullOrWhiteSpace(request.EmailAddress)) - { - List to = [.. request.EmailAddress.Split(separator: ';', options: StringSplitOptions.RemoveEmptyEntries)]; - await MailHelper.SendMailMessageAsync(settings: _appSettings, to: to, cc: null, bcc: null, attachments: null, embeddedImages: null, isHtmlBody: false, priority: System.Net.Mail.MailPriority.Normal, - subject: "One Time Password", messageBody: $"Your one time password (use as Old password): {newPassword} and must change password at next Login."); - } - if (!string.IsNullOrEmpty(request.MobileNo) && !string.IsNullOrWhiteSpace(request.MobileNo)) - { - MailHelper.SendSMSOrWhatsAppMessage(settings: _appSettings, whatsAppMsg: false, msg: $"Your one time password (use as Old password): {newPassword} and must change password at next Login.", mobileNumber: request.MobileNo); - } - - response.ReturnMessage.Add("Password sent to your Email address and/or Mobile number, User must change password at next Login."); - } - else - { - response.ReturnMessage.Add("Cannot do action on your request."); - } - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("saveAuthorizeLimit")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(BooleanResponse))] - public async Task SaveAuthorizeLimit([FromBody] UserLimitAuthorizeRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - bool permitted = await HttpContext.IsPermitted("ELIT.9.1.14_1") || await HttpContext.IsPermitted("ELIT.9.1.14_2"); - if (!permitted) - { - response.ReturnStatus = StatusCodes.Status403Forbidden; - response.ReturnMessage.Add("You are not authorize to Update Authorization Limit."); - return StatusCode(StatusCodes.Status417ExpectationFailed, response); - } - - try - { - string ipAddress = Request.HttpContext.GetIpAddress(); - string loginId = HttpContext.User.GetClaimValue(Constants.LoginId); - response.Value = await _service.SaveAuthorizeLimitAsync(maxAuthLimit: request.MaxAuthorizeAmount, userId: request.UserId, ipAddress: ipAddress, savedBy: loginId); - response.ReturnMessage.Add("Process completed successfully..."); - response.ReturnStatus = StatusCodes.Status200OK; - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getAuthorizeLimit")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserAuthorizeLimitResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(UserAuthorizeLimitResponse))] - public async Task GetAuthorizeLimit([FromBody] ByUserIdRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - UserAuthorizeLimitResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - response = await _service.GetAuthorizeLimitAsync(userId: request.UserId); - response.ReturnStatus = StatusCodes.Status200OK; - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - [HttpPost("logOut")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BooleanResponse))] - public async Task LogOut([FromBody] LogoutRequest request) - { - BooleanResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - string key = HttpContext.GetAuthenticationToken(); - string ipAddress = Request.HttpContext.GetIpAddress(); - int userId = HttpContext.User.GetClaimValue(Constants.UserId); - string loginId = HttpContext.User.GetClaimValue(Constants.LoginId); - - if (request.AttendanceLogout) - { - string cipherSecretKey = GlobalFunctions.ConvertFromBase64String(_appSettings.CipherSecretKey); - request.IpAddress = Helper.DecryptData(secret: cipherSecretKey, data: request.IpAddress); - request.MacAddress = Helper.DecryptData(secret: cipherSecretKey, data: request.MacAddress); - request.HostName = Helper.DecryptData(secret: cipherSecretKey, data: request.HostName); - } - _ = await _service.LogoutAsync(ipAddress: ipAddress, userId: userId, logId: request.LogId, attendanceLogout: request.AttendanceLogout, loginId: loginId, localIp: request.IpAddress, macAddress: request.MacAddress, hostName: request.HostName, logoutRemarks: request.LogoutRemarks); - _cache.Clear(pattern: key); - _ = await HttpContext.ClearSessionAsync(); - - response.Value = true; - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// 0 - [AllowAnonymous] - [IgnoreAntiforgeryToken] - [HttpPost("sessionExpired")] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task SessionExpired([FromBody] LogoutRequest request) - { - try - { - int userId = HttpContext.User.GetClaimValue(Constants.UserId); - string ipAddress = Request.HttpContext.GetIpAddress(); - _ = await _service.LogoutAsync(ipAddress: ipAddress, userId: userId, logId: request.LogId, attendanceLogout: false, loginId: string.Empty, localIp: string.Empty, macAddress: string.Empty, hostName: string.Empty, logoutRemarks: string.Empty); - _ = await HttpContext.ClearSessionAsync(); - } - catch (Exception ex) - { - _logger.LogError(ex); - } - } - - /// - /// - /// - /// - /// - /// - [SupportedOSPlatform("windows")] - private int GetADLoginStatus(string loginId, string password) - { - try - { - const string displayNameAttribute = "DisplayName"; - const string samAccountNameAttribute = "SAMAccountName"; - const string userAccountControlAttribute = "useraccountcontrol"; - - string username = (string.IsNullOrEmpty(_appSettings.ADConfig.Domain) || string.IsNullOrWhiteSpace(_appSettings.ADConfig.Domain)) ? loginId : $"{loginId}@{_appSettings.ADConfig.Domain}"; - using DirectoryEntry entry = new(path: _appSettings.ADConfig.Path, username: username, password: password); - using DirectorySearcher searcher = new(searchRoot: entry); - searcher.Filter = $"({samAccountNameAttribute}={loginId})"; - searcher.PropertiesToLoad.Add(value: displayNameAttribute); - searcher.PropertiesToLoad.Add(value: samAccountNameAttribute); - searcher.PropertiesToLoad.Add(value: userAccountControlAttribute); - var result = searcher.FindOne(); - if (result == null) - return 0; - - ResultPropertyValueCollection displayName = result.Properties[name: displayNameAttribute]; - ResultPropertyValueCollection samAccountName = result.Properties[name: samAccountNameAttribute]; - ResultPropertyValueCollection userAccountControl = result.Properties[name: userAccountControlAttribute]; - int uacFlag = (userAccountControl != null && userAccountControl.Count > 0) ? Convert.ToInt32(userAccountControl[0]) : 0; - if ((uacFlag & 0x000002) == 0x000002) //Disabled - return 2; - else if ((uacFlag & 0x800000) == 0x800000) //Password expired - return 3; - - if (displayName != null && displayName.Count > 0 && samAccountName != null && samAccountName.Count > 0) - return 1; - else - return 0; - } - catch (Exception ex) - { - _logger.LogError(ex); - return 0; - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("getAccessLog")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AccessLogResponse))] - [ProducesResponseType(StatusCodes.Status204NoContent, Type = typeof(AccessLogResponse))] - public async Task GetAccessLog([FromBody] AccessLogSearchRequest request) - { - ArgumentNullException.ThrowIfNull(request); - - AccessLogResponse response = new() { ReturnStatus = StatusCodes.Status200OK }; - try - { - string loginId = HttpContext.User.GetClaimValue(Constants.LoginId); - bool permitted = await HttpContext.IsPermitted("ELIT.1.2.5_2"); - if (!(permitted || loginId.Equals(value: Models.Objects.Systems.User.SuperUser_LoginId, comparisonType: StringComparison.OrdinalIgnoreCase))) - { - request.LoginId = loginId; - } - response = await _service.GetAccessLogAsync(accessType: request.AccessType, loginId: request.LoginId, startDate: request.StartDate, endDate: request.EndDate); - response.ReturnStatus = StatusCodes.Status200OK; - - return Ok(response); - } - catch (Exception ex) - { - _logger.LogError(ex); - response.ReturnStatus = StatusCodes.Status500InternalServerError; - response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError, response); - } - } - - /// - /// - /// - /// - /// - [ValidateSession] - [HttpPost("loadNotificationCount")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(int))] - public async Task LoadNotificationCount([FromBody] NoContentRequest request) - { - ArgumentNullException.ThrowIfNull(request); - try - { - int value = HttpContext.User.GetClaimValue(Constants.UserId); - value = await _service.LoadNotificationCountAsync(userId: value); - - return Ok(value); - } - catch (Exception ex) - { - _logger.LogError(ex); - return StatusCode(StatusCodes.Status500InternalServerError); - } - } - } + Subject = new ClaimsIdentity( + [ + Helper.CreateClaim("LoginId", userRefreshToken.LoginId), + Helper.CreateClaim("Email", userRefreshToken.EmailAddress), + Helper.CreateClaim("AuthKey", $"{userRefreshToken.AuthKey}"), + Helper.CreateClaim("HashKey", Guid.NewGuid().ToString()) + ]), + Expires = DateTime.UtcNow.AddHours(12), + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature) + }; + + SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); + string userToken = tokenHandler.WriteToken(token); + + string ipAddress = Request.HttpContext.GetIpAddress(); + var refreshToken = await _refreshTokenService.GenerateRefreshTokenAsync(request.RefreshToken, ipAddress); + + response.AccessToken = userToken; + response.RefreshToken = refreshToken; + + return StatusCode(StatusCodes.Status431RequestHeaderFieldsTooLarge, response); + + } + catch (Exception ex) + { + string msg = $"{request?.RefreshToken}"; + _logger.LogError(exception: ex, message: msg); + response.ReturnStatus = StatusCodes.Status500InternalServerError; + response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError, response); + } + return Ok(); + } + + /// + /// + /// + /// + /// + /// + [SupportedOSPlatform("windows")] + private int GetADLoginStatus(string loginId, string password) + { + try + { + const string displayNameAttribute = "DisplayName"; + const string samAccountNameAttribute = "SAMAccountName"; + const string userAccountControlAttribute = "useraccountcontrol"; + + string username = (string.IsNullOrEmpty(_appSettings.ADConfig.Domain) || string.IsNullOrWhiteSpace(_appSettings.ADConfig.Domain)) ? loginId : $"{loginId}@{_appSettings.ADConfig.Domain}"; + using DirectoryEntry entry = new(path: _appSettings.ADConfig.Path, username: username, password: password); + using DirectorySearcher searcher = new(searchRoot: entry); + searcher.Filter = $"({samAccountNameAttribute}={loginId})"; + searcher.PropertiesToLoad.Add(value: displayNameAttribute); + searcher.PropertiesToLoad.Add(value: samAccountNameAttribute); + searcher.PropertiesToLoad.Add(value: userAccountControlAttribute); + var result = searcher.FindOne(); + if (result == null) + return 0; + + ResultPropertyValueCollection displayName = result.Properties[name: displayNameAttribute]; + ResultPropertyValueCollection samAccountName = result.Properties[name: samAccountNameAttribute]; + ResultPropertyValueCollection userAccountControl = result.Properties[name: userAccountControlAttribute]; + int uacFlag = (userAccountControl != null && userAccountControl.Count > 0) ? Convert.ToInt32(userAccountControl[0]) : 0; + if ((uacFlag & 0x000002) == 0x000002) //Disabled + return 2; + else if ((uacFlag & 0x800000) == 0x800000) //Password expired + return 3; + + if (displayName != null && displayName.Count > 0 && samAccountName != null && samAccountName.Count > 0) + return 1; + else + return 0; + } + catch (Exception ex) + { + _logger.LogError(ex); + return 0; + } + } + } } \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationController.cs b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationController.cs index c1a7b9c..f41a7b0 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationController.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationController.cs @@ -6,7 +6,6 @@ using Microsoft.Extensions.Logging; using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations; -using OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations; using System; using System.Threading.Tasks; @@ -38,8 +37,8 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi /// /// /// - /// if created return 201 or if updated return 204 true - [HttpGet("Customers")] + /// if created return 201 or if updated return 200 true + [HttpPost("Customers")] [IgnoreAntiforgeryToken] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationLoginResponse))] public async Task UpsertCustomers(CustomerIntegrationRequest request) @@ -47,8 +46,8 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi CustomerIntegrationResponse response = new CustomerIntegrationResponse(); try { - bool result = await _integrationService.UpsertCustomerAsync(request); - if (result) + response = await _integrationService.UpsertCustomerAsync(request); + if (!response.IsUpdated) { response.ReturnMessage.Add($"Customer Created Successfully for CustomerNumber :{request.CustomerNumber} & CompanyCode:{request.CompanyCode}"); response.ReturnStatus = StatusCodes.Status201Created; @@ -57,8 +56,8 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi else { response.ReturnMessage.Add($"Customer Updated Successfully for CustomerNumber :{request.CustomerNumber} & CompanyCode:{request.CompanyCode}"); - response.ReturnStatus = StatusCodes.Status204NoContent; - return StatusCode(StatusCodes.Status204NoContent, response); + response.ReturnStatus = StatusCodes.Status200OK; + return StatusCode(StatusCodes.Status200OK, response); } } catch (Exception ex) @@ -70,5 +69,85 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi return StatusCode(StatusCodes.Status500InternalServerError, response); } } + + /// + /// Insert or Update Employees for SAP + /// + /// + /// + /// + /// if created return 201 or if updated return 200 true + [HttpPost("Employees")] + [IgnoreAntiforgeryToken] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(EmployeeIntegrationReqResponse))] + public async Task UpsertEmployee(EmployeeIntegrationRequest request) + { + EmployeeIntegrationReqResponse response = new EmployeeIntegrationReqResponse(); + try + { + response = await _integrationService.UpsertEmployeeAsync(request); + if (!response.IsUpdated) + { + response.ReturnMessage.Add($"Employee Created Successfully for EmployeeVendorName :{request.EmployeeVendorName} & SalesOrgCode:{request.CompanyCode}"); + response.ReturnStatus = StatusCodes.Status201Created; + return StatusCode(StatusCodes.Status201Created, response); + } + else + { + response.ReturnMessage.Add($"Employee Updated Successfully for EmployeeVendorName :{request.EmployeeVendorName} & SalesOrgCode:{request.CompanyCode}"); + response.ReturnStatus = StatusCodes.Status200OK; + return StatusCode(StatusCodes.Status200OK, response); + } + } + catch (Exception ex) + { + string msg = $"Exception Occur in Employee Operation {request?.EmployeeVendorName}~{request?.CompanyCode}"; + _logger.LogError(exception: ex, msg); + response.ReturnStatus = StatusCodes.Status500InternalServerError; + response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError, response); + } + } + + + /// + /// Insert or Update Material for SAP + /// + /// + /// + /// + /// if created return 201 or if updated return 200 true + [HttpPost("Materials")] + [IgnoreAntiforgeryToken] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MaterialIntegrationReqResponse))] + [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(MaterialIntegrationReqResponse))] + public async Task UpsertMeterial(MaterialIntegrationRequest request) + { + MaterialIntegrationReqResponse response = new MaterialIntegrationReqResponse(); + try + { + response = await _integrationService.UpsertMaterialAsync(request); + if (!response.IsUpdated) + { + response.ReturnMessage.Add($"Material Created Successfully for MaterialCode :{request.MaterialCode} "); + response.ReturnStatus = StatusCodes.Status201Created; + return StatusCode(StatusCodes.Status201Created, response); + } + else + { + response.ReturnMessage.Add($"Material Updated Successfully for MaterialCode :{request.MaterialCode} "); + response.ReturnStatus = StatusCodes.Status200OK; + return StatusCode(StatusCodes.Status200OK, response); + } + } + catch (Exception ex) + { + string msg = $"Exception Occur in Material Operation {request?.MaterialCode}"; + _logger.LogError(exception: ex, msg); + response.ReturnStatus = StatusCodes.Status500InternalServerError; + response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError, response); + } + } } } \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI/OnlineSalesAutoCrop.CoreAPI.csproj.user b/Api/OnlineSalesAutoCrop.CoreAPI/OnlineSalesAutoCrop.CoreAPI.csproj.user index adaeb0c..f756d77 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI/OnlineSalesAutoCrop.CoreAPI.csproj.user +++ b/Api/OnlineSalesAutoCrop.CoreAPI/OnlineSalesAutoCrop.CoreAPI.csproj.user @@ -1,7 +1,7 @@  - D:\Local\EaseBilling\Api\EaseO2C.CoreAPI\Properties\PublishProfiles\Windows.Publish.pubxml + D:\Local\OnlineSalesAutoCrop\Api\OnlineSalesAutoCrop.CoreAPI\Properties\PublishProfiles\FolderProfile.pubxml IIS Express ApiControllerEmptyScaffolder root/Common/Api