Compare commits

...

23 Commits

Author SHA1 Message Date
7acf518892 start working for save order endpoints 2026-07-15 18:51:09 +06:00
1aed28659e completed master data endpoints 2026-07-14 18:50:43 +06:00
376af6828e applied logic in employee integretion for app role type 2026-07-14 12:46:54 +06:00
b094c7ca75 implement payment terms endpoint 2026-07-14 12:18:46 +06:00
8bf59da423 complete foc and foc material endpoints 2026-07-13 18:32:45 +06:00
a7467fbb39 Completed Discount and Discount Materials route 2026-07-13 17:37:58 +06:00
66e52442df add discount endpoints without service implementation 2026-07-12 18:27:00 +06:00
0250908261 update customer endpoint response (add credit pros) and add access token validaity time in app settings 2026-07-12 12:44:45 +06:00
5778ee9203 update in attendance endpoint 2026-07-09 18:53:22 +06:00
cbd94a76ac set current date when create or update 2026-07-08 18:37:40 +06:00
a64aa85d33 add attendance endpoint 2026-07-08 18:15:24 +06:00
bdcda8c1fb update customer,brand, material endpoint request 2026-07-08 14:51:20 +06:00
8c6df3cd19 send only one validation message 2026-07-07 18:39:04 +06:00
18891cd584 implement brand, material and customer and change the response format when got bad request 2026-07-07 18:14:18 +06:00
ad9694f85d update mobile response base format 2026-07-07 12:15:19 +06:00
89ef87fb18 update length of login id 2026-07-06 18:43:46 +06:00
5d6228aba2 change password length in change password method 2026-07-06 18:20:41 +06:00
1b738897d2 complete auth for mobile api 2026-07-06 17:23:05 +06:00
43efe23587 add salesinvoice api 2026-06-30 18:57:11 +06:00
70a4a757f2 add payment terms api 2026-06-28 19:02:40 +06:00
a8f7cd51ce update Material price and FOC 2026-06-25 19:08:21 +06:00
e55821737f Add FOC Api 2026-06-25 12:41:18 +06:00
7ae8591ce6 Add Integration Material Price Api 2026-06-23 17:34:45 +06:00
55 changed files with 4702 additions and 279 deletions

View File

@ -700,4 +700,58 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models
[Description("From Others")]
FromOthers = 3,
}
public enum IntegrationMaterialCalCulationType : short
{
[Description("Percentage")]
A = 1,
[Description("Fixed value ")]
B = 2,
}
public enum IntegrationMaterialPriceType: short
{
[Description("Base Price")]
PR00 = 1 ,
[Description("Amount Based Discount")]
ZDS1 = 2 ,
[Description("Percentage Based Discount")]
ZDS2 = 3
}
public enum UserPlatFormType : short
{
SAP=1,
AppUser =2,
}
public enum UserRoleTypeEnum : short
{
[Description("Order Collector")]
OrderCollector = 1,
[Description("OrderValidator")]
OrderValidator = 2,
[Description("OrderApprover")]
OrderApprover = 3 ,
[Description("SAP User")]
SapUser = 4 ,
}
public enum OrderStatusEnum : short
{
[Description("Draft")]
Draft = 1,
[Description("Order Sent to Validator")]
InOrderValidation = 2,
[Description("Cancelled by Validator")]
CancelledByValidator = 3,
[Description("Order Sent to Approver")]
InOrderApproval = 4,
[Description("Cancelled by Approver")]
CancelledByApprover = 5,
[Description("Approved")]
Approved = 6,
[Description("Sent To SAP")]
SentToSAP = 7
}
}

View File

@ -54,6 +54,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models.Global
public bool JwtValidateIssuer { get; set; }
public bool JwtValidateAudience { get; set; }
public int RefreshTokenDuration { get; set; }
public int AccessTokenDuration { get; set; }
/// <summary>
/// Folder management

View File

@ -2,7 +2,7 @@
namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations;
public class CustomerIntegration
public class IntegrationCustomer
{
public string CustomerNumber { get; set; }
public string CustomerName { get; set; }

View File

@ -1,6 +1,6 @@
namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations;
public class EmployeeIntegration
public class IntegrationEmployee
{
public string EmployeeVendorCode { get; set; }
public string EmployeeVendorName { get; set; }

View File

@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations;
public class MaterialIntegration
public class IntegrationMaterial
{
public int MeterialId { get; set; }
public string MaterialType { get; set; }

View File

@ -0,0 +1,23 @@
using System;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations;
public class IntegrationMaterialFreeGood
{
public int FreeGoodsId { get; set; } // required for Update
public string SalesOrg { get; set; }
public string DistributionChannel { get; set; }
public int? CustomerId { get; set; } // nullable
public string CustomerPriceGroup { get; set; }
public int MaterialId{ get; set; }
public decimal MinOrderQuantity { get; set; }
public decimal ForQuantity { get; set; }
public string UnitOfMeasure { get; set; }
public decimal FreeQuantity { get; set; }
public string FocUnitOfMeasure { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime ValidTo { get; set; }
public string? Status { get; set; } // NULL = Active, X = Inactive
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}

View File

@ -0,0 +1,24 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations;
public class IntegrationMaterialPrice
{
public int MaterialPriceId { get; set; }
public string SalesOrg { get; set; }
public string DistributionChannel { get; set; }
public string CustomerNumber { get; set; }
public string CustomerGroupCode { get; set; }
public string MaterialCode { get; set; }
public string ConditionType { get; set; }
public string CalculationType { get; set; }
public string PricingUnit { get; set; }
public string UnitOfMeasure { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime ValidTo { get; set; }
public string Status { get; set; }
public decimal ConditionValue { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}

View File

@ -0,0 +1,15 @@
using System;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations;
internal class IntegrationPaymentTerm
{
public int CreditCodeId { get; set; }
public string CreditCode { get; set; }
public string Description { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime ValidTo { get; set; }
public string SalesOrg { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? ModifiedDate { get; set; }
}

View File

@ -26,9 +26,14 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems
public string SchemeName { get; set; }
public string MenuLayout { get; set; }
public bool IsLocked { get; set; }
public EnumLoginStatus LoginStatus { get; set; }
public DateTime? NextLoginTime { get; set; }
public UserPlatFormType? UserPlatFormType { get; set; }
public UserRoleTypeEnum? UserRoleType { get; set; }
public string? EmployeeNumber { get; set; }
public string? DesignationCode { get; set; }
public string? DesignationName { get; set; }
public EnumLoginStatus LoginStatus { get; set; }
public DateTime? NextLoginTime { get; set; }
}
public class LoginHistory

View File

@ -27,4 +27,13 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests
{
public string AuthenticationId { get; set; }
}
public abstract class PagedRequest
{
[Range(1, int.MaxValue, ErrorMessage = "PageNumber must be at least 1.")]
public int PageNumber { get; set; } = 1;
[Range(1, 1000, ErrorMessage = "PageSize must be between 1 and 1000.")]
public int PageSize { get; set; } = 1000;
}
}

View File

@ -0,0 +1,14 @@

using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
public class AuthLoginRequest
{
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "Login Id must be between 3 and 10 characters.")]
public string LoginId { get; set; }
[Required, NotNull, StringLength(maximumLength: 20, MinimumLength = 5, ErrorMessage = "Password must be between 5 and 20 characters.")]
public string Password { get; set; }
}

View File

@ -1,41 +1,41 @@
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
using System;
using System.Collections.Generic;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Text;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
public class IntegrationLoginRequest
public class IntegrationLoginRequest : AuthLoginRequest
{
[Required, NotNull, StringLength(maximumLength: 150, MinimumLength = 3, ErrorMessage = "Login Id must be between 4 and 30 characters.")]
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 class IntegrationRefreshTokenRequest
{
public string RefreshToken { get; set; }
[Required]
public string RefreshToken { get; set; }
}
public class InsertRefreshTokenRequest : RefreshToken
{
[Required]
public string RefreshToken { get; set; }
}
public class RevokedRefreshTokenRequest
public class RevokedRefreshTokenRequest
{
[Required]
public string RefreshToken { get; set; }
[Required]
public int UserId { get; set; }
}
public class GenerateRefreshTokenRequest
{
[Required]
public int UserId { get; set; }
[Required]
public string IpAddress { get; set; }
[Required]
public string RawRefreshToken { get; set; }
}

View File

@ -5,7 +5,7 @@ using System.Text;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
public class CustomerIntegrationRequest
public class IntegrationCustomerRequest
{
[Required(ErrorMessage = "Customer number is required.")]
[StringLength(10, ErrorMessage = "Customer number cannot exceed 10 characters.")]
@ -16,7 +16,7 @@ public class CustomerIntegrationRequest
public string CustomerName { get; set; }
[Required(ErrorMessage = "Account group is required.")]
[StringLength(4, ErrorMessage = "Account group cannot exceed 3 characters.")]
[StringLength(4, ErrorMessage = "Account group cannot exceed 4 characters.")]
public string AccountGroup { get; set; }
[Required(ErrorMessage = "Account group description is required.")]

View File

@ -2,7 +2,7 @@
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
public class EmployeeIntegrationRequest
public class IntegrationEmployeeRequest
{
[Required(ErrorMessage = "Employee vendor code is required.")]
[StringLength(10, ErrorMessage = "Employee vendor code cannot exceed 10 characters.")]

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
public class IntegrationInvoiceRequest
{
[Required(ErrorMessage = "Invoice document number is required.")]
[StringLength(10, ErrorMessage = "Invoice document number cannot exceed 10 characters.")]
public string InvoiceDocumentNo { get; set; }
[Required(ErrorMessage = "Invoice date is required.")]
public DateTime InvoiceDate { get; set; }
[Required(ErrorMessage = "Sales order reference number is required.")]
[StringLength(13, ErrorMessage = "Sales order reference number cannot exceed 13 characters.")]
public string SalesOrderRefNo { get; set; }
[Required(ErrorMessage = "Delivery reference number is required.")]
[StringLength(10, ErrorMessage = "Delivery reference number cannot exceed 10 characters.")]
public string DeliveryRefNo { get; set; }
[Required(ErrorMessage = "Invoice amount is required.")]
[Range(typeof(decimal), "0.01", "999999999999.99",
ErrorMessage = "Invoice amount must be greater than 0.")]
public decimal InvoiceAmount { get; set; }
[Required(ErrorMessage = "Invoice items are required.")]
[MinLength(1, ErrorMessage = "At least one invoice item is required.")]
public List<IntegrationInvoiceItemRequest> Items { get; set; } = new();
}
public class IntegrationInvoiceItemRequest
{
[Required(ErrorMessage = "Material code is required.")]
[RegularExpression(@".*\S.*", ErrorMessage = "Material code cannot be empty or whitespace.")]
[StringLength(10, ErrorMessage = "Material code cannot exceed 10 characters.")]
public string MaterialCode { get; set; }
[Required(ErrorMessage = "Quantity is required.")]
[Range(typeof(decimal), "0.01", "999999999999.99",
ErrorMessage = "Quantity must be greater than 0.")]
public decimal Quantity { get; set; }
[Required(ErrorMessage = "Unit of measurement is required.")]
[StringLength(10, ErrorMessage = "Unit of measurement cannot exceed 10 characters.")]
public string UnitOfMeasurement { get; set; }
}

View File

@ -0,0 +1,77 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
public class IntegrationMaterialFreeGoodsRequest
{
[Required(ErrorMessage = "SalesOrg is required.")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "SalesOrg must be between 1 and 4 characters.")]
public string SalesOrg { get; set; }
[Required(ErrorMessage = "DistributionChannel is required.")]
[StringLength(2, MinimumLength = 1, ErrorMessage = "DistributionChannel must be between 1 and 2 characters.")]
public string DistributionChannel { get; set; }
[StringLength(13, MinimumLength = 1, ErrorMessage = "CustomerNumber must be between 1 and 13 characters.")]
public string? CustomerNumber { get; set; } // nullable
[StringLength(2, MinimumLength = 1, ErrorMessage = "CustomerPriceGroup must be between 1 and 2 characters.")]
public string? CustomerPriceGroup { get; set; }
[Required(ErrorMessage = "MaterialCode is required.")]
[StringLength(10, MinimumLength = 1, ErrorMessage = "MaterialCode must be between 1 and 10 characters.")]
public string MaterialCode { get; set; }
[Required(ErrorMessage = "MinOrderQuantity is required.")]
[Range(0.001, 9999999999999.999, ErrorMessage = "MinOrderQuantity must be greater than 0.")]
public decimal MinOrderQuantity { get; set; }
[Required(ErrorMessage = "ForQuantity is required.")]
[Range(0.001, 9999999999999.999, ErrorMessage = "ForQuantity must be greater than 0.")]
public decimal ForQuantity { get; set; }
[Required(ErrorMessage = "UnitOfMeasure is required.")]
[StringLength(3, MinimumLength = 1, ErrorMessage = "UnitOfMeasure must be between 1 and 3 characters.")]
public string UnitOfMeasure { get; set; }
[Required(ErrorMessage = "FreeQuantity is required.")]
[Range(0.001, 9999999999999.999, ErrorMessage = "FreeQuantity must be greater than 0.")]
public decimal FreeQuantity { get; set; }
[Required(ErrorMessage = "FocUnitOfMeasure is required.")]
[StringLength(3, MinimumLength = 1, ErrorMessage = "FocUnitOfMeasure must be between 1 and 3 characters.")]
public string FocUnitOfMeasure { get; set; }
[Required(ErrorMessage = "ValidFrom is required.")]
public DateOnly ValidFrom { get; set; }
[Required(ErrorMessage = "ValidTo is required.")]
public DateOnly ValidTo { get; set; }
[StringLength(1, MinimumLength = 1, ErrorMessage = "Status must be 1 character.")]
public string? Status { get; set; } // NULL = Active, X = Inactive
}
public class GetMaterialFreeGoodsByFilterRequest
{
[Required(ErrorMessage = "SalesOrg is required.")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "SalesOrg must be between 1 and 4 characters.")]
public string SalesOrg { get; set; }
[Required(ErrorMessage = "DistributionChannel is required.")]
[StringLength(2, MinimumLength = 1, ErrorMessage = "DistributionChannel must be between 1 and 2 characters.")]
public string DistributionChannel { get; set; }
[StringLength(13, MinimumLength = 1, ErrorMessage = "CustomerNumber must be between 1 and 13 characters.")]
public string? CustomerNumber { get; set; } // nullable
[StringLength(2, MinimumLength = 1, ErrorMessage = "CustomerPriceGroup must be between 1 and 2 characters.")]
public string? CustomerPriceGroup { get; set; }
[Required(ErrorMessage = "MaterialCode is required.")]
[StringLength(10, MinimumLength = 1, ErrorMessage = "MaterialCode must be between 1 and 10 characters.")]
public string MaterialCode { get; set; }
}

View File

@ -0,0 +1,77 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
public class IntegrationMaterialPriceRequest
{
[Required(ErrorMessage = "Sales Org is required.")]
[StringLength(4, ErrorMessage = "Sales Org cannot exceed 4 characters.")]
public string SalesOrg { get; set; }
[Required(ErrorMessage = "Distribution Channel is required.")]
[StringLength(2, ErrorMessage = "Distribution Channel cannot exceed 2 characters.")]
public string DistributionChannel { get; set; }
[StringLength(13, ErrorMessage = "Customer Number cannot exceed 13 characters.")]
public string? CustomerNumber { get; set; }
[StringLength(10, ErrorMessage = "Customer Group Code cannot exceed 10 characters.")]
public string? CustomerGroupCode { get; set; }
[Required(ErrorMessage = "Material Code is required.")]
[StringLength(10, ErrorMessage = "Material Code cannot exceed 10 characters.")]
public string MaterialCode { get; set; }
[Required(ErrorMessage = "Condition Type is required.")]
[StringLength(4, ErrorMessage = "Condition Type cannot exceed 4 characters.")]
public string ConditionType { get; set; }
[Required(ErrorMessage = "Calculation Type is required.")]
[StringLength(1, ErrorMessage = "Calculation Type cannot exceed 1 character.")]
public string CalculationType { get; set; }
[Required(ErrorMessage = "Pricing Unit is required.")]
[StringLength(1, ErrorMessage = "Pricing Unit cannot exceed 1 character.")]
public string PricingUnit { get; set; }
[Required(ErrorMessage = "Unit Of Measure is required.")]
[StringLength(3, ErrorMessage = "Unit Of Measure cannot exceed 3 characters.")]
public string UnitOfMeasure { get; set; }
[Required(ErrorMessage = "Valid From date is required.")]
public DateTime ValidFrom { get; set; }
[Required(ErrorMessage = "Valid To date is required.")]
public DateTime ValidTo { get; set; }
[StringLength(1, ErrorMessage = "Status cannot exceed 1 character.")]
[RegularExpression(@"^$|^X$", ErrorMessage = "Status must be blank (Active) or 'X' (Inactive).")]
public string Status { get; set; }
[Required(ErrorMessage = "Condition Value is required.")]
[Range(typeof(decimal), "0", "999999999999999999.99",
ErrorMessage = "Condition Value must be greater than or equal to 0.")]
public decimal ConditionValue { get; set; }
}
public class GetMaterialPriceByCodeRequest
{
[Required(ErrorMessage = "Sales Org is required.")]
[StringLength(4, ErrorMessage = "Sales Org cannot exceed 4 characters.")]
public string SalesOrg { get; set; }
[Required(ErrorMessage = "Material Code is required.")]
[StringLength(10, ErrorMessage = "Material Code cannot exceed 10 characters.")]
public string MaterialCode { get; set; }
[Required(ErrorMessage = "Condition Type is required.")]
[StringLength(4, ErrorMessage = "Condition Type cannot exceed 4 characters.")]
public string ConditionType { get; set; }
[StringLength(13, ErrorMessage = "Customer Number cannot exceed 13 characters.")]
public string? CustomerNumber { get; set; }
[StringLength(10, ErrorMessage = "Customer Group Code cannot exceed 10 characters.")]
public string? CustomerGroupCode { get; set; }
}

View File

@ -2,7 +2,7 @@
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
public class MaterialIntegrationRequest
public class IntegrationMaterialRequest
{
[Required(ErrorMessage = "Material type is required.")]
[StringLength(4, ErrorMessage = "Material type cannot exceed 4 characters.")]
@ -18,7 +18,15 @@ public class MaterialIntegrationRequest
[Required(ErrorMessage = "Material description is required.")]
[StringLength(40, ErrorMessage = "Material description cannot exceed 40 characters.")]
public string MaterialDescription { get; set; }
public string MaterialDescription { get; set; }
[Required(ErrorMessage = "BrandCode is required.")]
[StringLength(3, ErrorMessage = "BrandCode cannot exceed 3 characters.")]
public string BrandCode { get; set; }
[Required(ErrorMessage = "BrandName is required.")]
[StringLength(20, ErrorMessage = "BrandName cannot exceed 20 characters.")]
public string BrandName { get; set; }
[Required(ErrorMessage = "Material group code is required.")]
[StringLength(9, ErrorMessage = "Material group code cannot exceed 9 characters.")]

View File

@ -0,0 +1,39 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
public class IntegrationPaymentTermRequest
{
[Required(ErrorMessage = "CreditCode is required.")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "CreditCode must be between 1 and 4 characters.")]
public string CreditCode { get; set; }
[Required(ErrorMessage = "Description is required.")]
[StringLength(30, MinimumLength = 1, ErrorMessage = "Description must be between 1 and 30 characters.")]
public string Description { get; set; }
[Required(ErrorMessage = "ValidFrom is required.")]
public DateTime ValidFrom { get; set; }
[Required(ErrorMessage = "ValidTo is required.")]
public DateTime ValidTo { get; set; }
[Required(ErrorMessage = "SalesOrg is required.")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "SalesOrg must be between 1 and 4 characters.")]
public string SalesOrg { get; set; }
}
public class GetIntegrationPaymentTermRequest
{
[Required(ErrorMessage = "CreditCode is required.")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "CreditCode must be between 1 and 4 characters.")]
public string CreditCode { get; set; }
[Required(ErrorMessage = "SalesOrg is required.")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "SalesOrg must be between 1 and 4 characters.")]
public string SalesOrg { get; set; }
}

View File

@ -0,0 +1,61 @@

using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
public class MobileAppAuthRequest : AuthLoginRequest
{
}
public class AuthLogoutRequest
{
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "Login Id must be between 3 and 10 characters.")]
public string LoginId { get; set; }
}
public class AppUserChangePasswordRequest
{
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "Login Id must be between 3 and 10 characters.")]
public string LoginId { get; set; }
[Required, NotNull, StringLength(maximumLength: 20, MinimumLength = 5, ErrorMessage = "Password must be between 5 and 20 characters.")]
public string Password { get; set; }
[Required, NotNull, StringLength(maximumLength: 20, MinimumLength = 5, ErrorMessage = "Password must be between 5 and 20 characters.")]
public string NewPassword { get; set; }
[Required, NotNull, StringLength(maximumLength: 20, MinimumLength = 5, ErrorMessage = "Password must be between 5 and 20 characters.")]
[Compare("NewPassword", ErrorMessage = "Password and Confirm Password do not match.")]
public string ConfirmPassword { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (!string.IsNullOrWhiteSpace(NewPassword) &&
!string.IsNullOrWhiteSpace(ConfirmPassword) &&
Password != ConfirmPassword)
{
yield return new ValidationResult(
"Password and Confirm Password do not match.",
[nameof(NewPassword), nameof(ConfirmPassword)]
);
}
if (!string.IsNullOrWhiteSpace(LoginId) &&
!string.IsNullOrWhiteSpace(NewPassword) &&
Password.Equals(LoginId, StringComparison.OrdinalIgnoreCase))
{
yield return new ValidationResult(
"Password must not be the same as your Login ID.",
[nameof(NewPassword)]
);
}
}
}

View File

@ -0,0 +1,179 @@

using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
public class GetMarketHeirarchyByEmpRequest
{
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "EmployeeNumber must be between 3 and 10 characters.")]
public string EmployeeNumber { get; set; }
}
public class GetBrandsRequest : PagedRequest
{
[StringLength(6, MinimumLength = 1, ErrorMessage = "Brand code must be between 1 and 6 characters.")]
public string? BrandCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
public string? SalesOrgCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
public string? EmployeeNumber { get; set; }
}
public class GetMaterialsRequest : PagedRequest
{
[StringLength(10, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
public string SalesOrgCode { get; set; }
[StringLength(6, MinimumLength = 1, ErrorMessage = "Brand code must be between 1 and 6 characters.")]
public string? BrandCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
public string? MaterialCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
public string? EmployeeNumber { get; set; }
}
public class GetMaterialPriceRequest : PagedRequest
{
[StringLength(10, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
public string SalesOrgCode { get; set; }
[StringLength(6, MinimumLength = 1, ErrorMessage = "Brand code must be between 1 and 6 characters.")]
public string? BrandCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
public string? MaterialCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
public string? EmployeeNumber { get; set; }
}
public class GetCustomersRequest : PagedRequest
{
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
public string SalesOrgCode { get; set; }
[StringLength(5, MinimumLength = 3, ErrorMessage = "Teritory Code must be between 1 and 5 characters.")]
public string? TeritoryCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
public string? CustomerCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
public string? EmployeeNumber { get; set; }
}
public class GetAttendanceByEmpRequest
{
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "EmployeeNumber must be between 3 and 10 characters.")]
public string EmployeeNumber { get; set; }
public DateTime? AttendanceDate { get; set; }
}
public class UpsertAttendanceByEmpRequest
{
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "EmployeeNumber must be between 3 and 10 characters.")]
public string EmployeeNumber { get; set; }
public TimeSpan? CheckInTime { get; set; }
public string? CheckInLatitude { get; set; }
public string? CheckInLongitude { get; set; }
public string? CheckInLocationName { get; set; }
public TimeSpan? CheckOutTime { get; set; }
public string? CheckOutLatitude { get; set; }
public string? CheckOutLongitude { get; set; }
public string? CheckOutLocationName { get; set; }
public bool IsCheckIn => CheckInTime.HasValue ? true : false;
public bool IsCheckOut => CheckOutTime.HasValue ? true : false;
}
public class GetDiscountRequest : PagedRequest
{
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
public string SalesOrgCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
public string? CustomerCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
public string? EmployeeNumber { get; set; }
[StringLength(10, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
public string? MaterialCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 10 characters.")]
public string? DiscountCode { get; set; }
}
public class GetDiscountMaterialRequest : PagedRequest
{
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
public string SalesOrgCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
public string? CustomerCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
public string? EmployeeNumber { get; set; }
[StringLength(10, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
public string? MaterialCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 10 characters.")]
public string? DiscountCode { get; set; }
}
public class GetFOCRequest : PagedRequest
{
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
public string SalesOrgCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
public string? CustomerCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
public string? EmployeeNumber { get; set; }
[StringLength(10, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
public string? MaterialCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 10 characters.")]
public string? FOCCode { get; set; }
}
public class GetFOCMaterialRequest : PagedRequest
{
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
public string SalesOrgCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
public string? CustomerCode { get; set; }
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
public string? EmployeeNumber { get; set; }
[StringLength(10, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
public string? MaterialCode { get; set; }
[StringLength(10, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 10 characters.")]
public string? FOCCode { get; set; }
}
public class GetPaymentTermRequest : PagedRequest
{
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
public string SalesOrgCode { get; set; }
[StringLength(10, MinimumLength = 3, ErrorMessage = "PayementTerm Code must be between 3 and 10 characters.")]
public string? PaymentTermCode { get; set; }
}

View File

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
public class SaveOrderRequest
{
public SaveOrderRequest()
{
Items = new List<SaveOrderItemRequest>();
}
public int? OrderId { get; set; }
public string? OrderNo { get; set; }
public DateTime? OrderDate { get; set; }
public DateTime? ExpectedDeliveryDate { get; set; }
public string UUID { get; set; }
public string SalesOrgCode { get; set; }
public string CustomerCode { get; set; }
public string CustomerName { get; set; }
public int? EmployeeId { get; set; }
public string EmployeeCode { get; set; }
public string? ReferenceTxtNo { get; set; }
public string PaymentTermCode { get; set; }
public string DiscountCode { get; set; }
public string FocCode { get; set; }
public decimal DiscountValue { get; set; }
public decimal GrossValue { get; set; }
public decimal NetValue { get; set; }
public OrderStatusEnum OrderStatus { get; set; }
public IList<SaveOrderItemRequest> Items { get; set; }
}
public class SaveOrderItemRequest
{
public string MaterialCode { get; set; }
public string MaterialName { get; set; }
public decimal UnitPrice { get; set; }
public string SalesUnit { get; set; }
public decimal OrderQuantity { get; set; }
public decimal ValidatedQuantity { get; set; }
public decimal ApprovedQuantity { get; set; }
public decimal DiscountPercentage { get; set; }
public decimal DiscountAmount { get; set; }
public bool IsFocItem { get; set; }
public decimal LineTotalValue { get; set; }
}
public class SaveOrderPromotionRequest
{
public int OrderId { get; set; }
public int MaterialId { get; set; }
public string PromotionCode { get; set; }
public decimal DiscountPercentage { get; set; }
public decimal DiscountValue { get; set; }
public decimal ForQuantity { get; set; }
public decimal OrderFocQty { get; set; }
public decimal ValidatedFocQty { get; set; }
public decimal ApprovedFocQty { get; set; }
public int PromotionType { get; set; }
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.CodeAnalysis;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
@ -219,3 +220,43 @@ public class PayslipRequest
[Required, NotNull]
public DateTime YearMonth { get; set; }
}
public class AppUserCreateRequest
{
[Required(ErrorMessage = "Login ID is required.")]
[MaxLength(100, ErrorMessage = "Login ID cannot exceed 100 characters.")]
public string LoginId { get; set; } = string.Empty;
[Required(ErrorMessage = "Username is required.")]
[MaxLength(150, ErrorMessage = "Username cannot exceed 150 characters.")]
public string UserName { get; set; } = string.Empty;
[Required]
public int Status { get; set; }
[Required]
public int AccessStatus { get; set; }
[Phone(ErrorMessage = "Invalid mobile number format.")]
[MaxLength(20, ErrorMessage = "Mobile number cannot exceed 20 characters.")]
public string? MobileNo { get; set; }
[Required(ErrorMessage = "Email address is required.")]
[EmailAddress(ErrorMessage = "Invalid email address format.")]
[MaxLength(200, ErrorMessage = "Email address cannot exceed 200 characters.")]
public string EmailAddress { get; set; } = string.Empty;
public int IsLocked { get; set; }
[Required(ErrorMessage = "Password is required.")]
[MaxLength(500, ErrorMessage = "Password hash length cannot exceed 500 characters.")]
public string Password { get; set; } = string.Empty;
public int? UserPlatformId { get; set; }
public int? UserRoleType { get; set; }
[MaxLength(10,ErrorMessage = "EmployeeNumber hash length cannot exceed 10 characters")]
public string? EmployeeNumber { get; set; }
}

View File

@ -1,7 +1,4 @@
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
using System;
using System.Collections.Generic;
using System.Text;
using System;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
@ -14,16 +11,22 @@ 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 class MobileRrefreshTokenResponse
{
public int UserId { get; set; }
public string AccessToken { get; set; } = string.Empty;
public string RefreshToken { get; set; } = string.Empty;
}
public class RefreshTokenResponse : ResponseBase
{
public int UserId { get; set; }
public string TokenHash { get; set; }
public string IpAddress { get; set; }
public DateTime ExpiredAt { get; set; }
@ -35,14 +38,14 @@ public class RefreshTokenResponse : ResponseBase
public class GenerateRefreshTokenResponse : ResponseBase
{
public string RefreshToken { get; set; }
public DateTime ExpireTime { get; set; }
public DateTime ExpireTime { get; set; }
}
public class UserByRefreshTokenResponse : ResponseBase
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; }
public string EmailAddress { get; set; }
public string AuthKey { get; set; }
public bool IsActive { set; get; }
}

View File

@ -1,6 +1,6 @@
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
public class CustomerIntegrationResponse : ResponseBase
public class IntegrationCustomerResponse : ResponseBase
{
public string CustomerNumber { get; set; }
public string CompanyCode { get; set; }

View File

@ -1,6 +1,6 @@
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
public class EmployeeIntegrationResponse : ResponseBase
public class IntegrationEmployeeResponse : ResponseBase
{
public int EmployeeId { get; set; }
public string EmployeeVendorCode { get; set; }

View File

@ -0,0 +1,13 @@
using System;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
public class IntegrationInvoiceReqResponse : ResponseBase
{
public string SalesOrderRefNo { get; set; }
public string InvoiceDocumnentNo { get; set; }
public DateTime InvoiceDate { get; set; }
public string DeliveryRefNo { get; set; }
public int NumberOfMaterial { get; set; }
}

View File

@ -0,0 +1,31 @@
using System;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
public class IntegrationMaterialFreeGoodsResponse : ResponseBase
{
public int FreeGoodsId { get; set; } // required for Update
public string SalesOrg { get; set; }
public string DistributionChannel { get; set; }
public string? CustomerNumber { get; set; } // nullable
public string? CustomerPriceGroup { get; set; }
public string MaterialCode { get; set; }
public decimal MinOrderQuantity { get; set; }
public decimal ForQuantity { get; set; }
public string UnitOfMeasure { get; set; }
public decimal FreeQuantity { get; set; }
public string FocUnitOfMeasure { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime ValidTo { get; set; }
public string? Status { get; set; }
}
public class MaterialFreeGoodsByReqResponse : ResponseBase
{
public string SalesOrg { get; set; }
public string DistributionChannel { get; set; }
public string CustomerNumber { get; set; }
public string CustomerPriceGroup { get; set; }
public string MaterialCode { get; set; }
public bool IsUpdated { get; set; }
}

View File

@ -0,0 +1,30 @@
using System;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
public class IntegrationMaterialPriceResponse : ResponseBase
{
public int MaterialPriceId { get; set; }
public string SalesOrg { get; set; }
public string DistributionChannel { get; set; }
public string? CustomerNumber { get; set; }
public string? CustomerGroupCode { get; set; }
public string MaterialCode { get; set; }
public string ConditionType { get; set; }
public string CalculationType { get; set; }
public string PricingUnit { get; set; }
public string UnitOfMeasure { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime ValidTo { get; set; }
public string Status { get; set; }
public decimal ConditionValue { get; set; }
}
public class MaterialIntegrationPriceReqResponse : ResponseBase
{
public string MaterialCode { get; set; }
public string ConditionType { get; set; }
public string? CustomerNumber { get; set; }
public string? CustomerGroupCode { get; set; }
public bool IsUpdated { get; set; }
}

View File

@ -2,7 +2,7 @@
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
public class MaterialIntegrationResponse : ResponseBase
public class IntegrationMaterialResponse : ResponseBase
{
public int MeterialId { get; set; }
public string MaterialType { get; set; }
@ -20,6 +20,8 @@ public class MaterialIntegrationResponse : ResponseBase
public string StorageLocationDescription { get; set; }
public string SalesOrganization { get; set; }
public string SalesOrganizationDescription { get; set; }
public string BrandCode { get; set; }
public string BrandName { get; set; }
}
public class MaterialIntegrationReqResponse : ResponseBase

View File

@ -0,0 +1,20 @@
using System;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
public class IntegrationPaymentTermResponse : ResponseBase
{
public int CreditCodeId { get; set; }
public string CreditCode { get; set; }
public string Description { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime ValidTo { get; set; }
public string SalesOrg { get; set; }
}
public class IntegrationPaymentTermReqResponse : ResponseBase
{
public string CreditCode { get; set; }
public string SalesOrg { get; set; }
public bool IsUpdated { get; set; }
}

View File

@ -0,0 +1,41 @@

using System;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
public class AppAuthUserResponse
{
public int UserId { get; set; }
public string LoginId { get; set; }
public string Name { get; set; }
public string? Email { get; set; }
public string? MobileNumber { get; set; }
public string EmployeeNumber { get; set; }
public string DesignationCode { get; set; }
public string DesignationName { get; set; }
public bool IsLocked { get; set; }
public UserRoleTypeEnum UserRole { get; set; }
public string AccessToken { get; set; }
public DateTime AccessTokenExpiryTime { get; set; }
public string RefreshToken { get; set; }
public DateTime RefreshTokenExpiryTime { get; set; }
public EnumLoginStatus LoginStatus { get; set; }
public bool IsAuthorized { get; set; }
public bool IsInitialPassword { get; set; }
}
public class AuthLogoutResponse
{
public int UserId { get; set; }
public string LoginId { get; set; }
public bool IsSuccess { get; set; }
}
public class AppChangePasswordResponse
{
public int UserId { get; set; }
public string LoginId { get; set; }
public bool IsSuccess { get; set; }
}

View File

@ -0,0 +1,222 @@
using Microsoft.AspNetCore.Mvc.Formatters;
using System;
using System.Collections.Generic;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
public class MarketHeirarchyByEmpResponse
{
public MarketHeirarchyByEmpResponse()
{
Companies = new List<EmpCompanyResponse>();
SalesOrgs = new List<SalesOrgResponse>();
DistributionChannels = new List<DistibutionChannleResponse>();
Regions = new List<RegionResponse>();
Areas = new List<AreaResponse>();
Teritories = new List<TeritoryResponse>();
Plants = new List<PlantResponse>();
}
public IList<EmpCompanyResponse> Companies { get; set; }
public IList<SalesOrgResponse> SalesOrgs { get; set; }
public IList<DistibutionChannleResponse> DistributionChannels { get; set; }
public IList<RegionResponse> Regions { get; set; }
public IList<AreaResponse> Areas { get; set; }
public IList<TeritoryResponse> Teritories { get; set; }
public IList<PlantResponse> Plants { get; set; }
}
public class EmpCompanyResponse
{
public string CompanyCode { get; set; }
public string CompanyName { get; set; }
}
public class SalesOrgResponse
{
public string CompanyCode { get; set; }
public string SalesOrgCode { get; set; }
public string SalesOrgName { get; set; }
}
public class DistibutionChannleResponse
{
public string CompanyCode { get; set; }
public string SalesOrgCode { get; set; }
public string DistributorChannelCode { get; set; }
public string DistributorChannelName { get; set; }
}
public class RegionResponse
{
public string CompanyCode { get; set; }
public string SalesOrgCode { get; set; }
public string RegionCode { get; set; }
public string RegionName { get; set; }
}
public class AreaResponse
{
public string CompanyCode { get; set; }
public string SalesOrgCode { get; set; }
public string RegionCode { get; set; }
public string AreaCode { get; set; }
public string AreaName { get; set; }
}
public class TeritoryResponse
{
public string CompanyCode { get; set; }
public string SalesOrgCode { get; set; }
public string RegionCode { get; set; }
public string AreaCode { get; set; }
public string TeritoryCode { get; set; }
public string TeritoryName { get; set; }
}
public class PlantResponse
{
public string CompanyCode { get; set; }
public string SalesOrgCode { get; set; }
public string PlantCode { get; set; }
public string PlantName { get; set; }
}
public class GetBrandResponse
{
public string BrandCode { get; set; } = string.Empty;
public string BrandName { get; set; } = string.Empty;
}
public class GetMaterialResponse
{
public string MaterialName { get; set; }
public string MaterialCode { get; set; }
public string TypeCode { get; set; }
public string TypeName { get; set; }
public string GroupCode { get; set; }
public string GroupName { get; set; }
public string BaseUnitMeasurement { get; set; }
public string SalesUnitMeasurement { get; set; }
public decimal UnitConversionValue { get; set; }
public string BrandCode { get; set; }
public string BrandName { get; set; }
public string SalesOrg { get; set; }
}
public class GetMaterialPriceResponse
{
public string SalesOrgCode { get; set; }
public string CustomerCode { get; set; }
public string MaterialCode { get; set; }
public decimal BasePrice { get; set; }
}
public class GetCustomerResponse
{
public string CustomerCode { get; set; }
public string CustomerName { get; set; }
public string AccountGroupCode { get; set; }
public string AccountGroupDescription { get; set; }
public string DistributionChannelCode { get; set; }
public string DistributionChannelName { get; set; }
public string DivisionCode { get; set; }
public string DivisionName { get; set; }
public string MobileNumber { get; set; }
public string EmailAddress { get; set; }
public string TaxNumber { get; set; }
public string SalesGroupCode { get; set; }
public string SalesGroupName { get; set; }
public string CustomerGroupCode { get; set; }
public string CustomerGroupName { get; set; }
public string CustomerPriceGroupCode { get; set; }
public string CustomerPriceGroupName { get; set; }
public string PaymentTermCode { get; set; }
public string SalesOrgCode { get; set; }
public string TeritoryCode { get; set; }
public string PlantCode { get; set; }
public bool IsCreditCustomer { get; set; }
public decimal CreditLimit { get; set; }
public decimal CreditBalance { get; set; }
public decimal CreditAvailable => CreditLimit - CreditBalance;
public decimal CreditOverdue { get; set; }
}
public class GetAttendanceByEmpResponse
{
public DateTime? AttendanceDate { get; set; }
public string EmployeeNumber { get; set; }
public TimeSpan? CheckInTime { get; set; }
public string? CheckInLatitude { get; set; }
public string? CheckInLongitude { get; set; }
public string? CheckInLocationName { get; set; }
public TimeSpan? CheckOutTime { get; set; }
public string? CheckOutLatitude { get; set; }
public string? CheckOutLongitude { get; set; }
public string? CheckOutLocationName { get; set; }
public bool? IsCheckIn => CheckInTime.HasValue ? true : false;
public bool? IsCheckOut => CheckOutTime.HasValue ? true : false;
}
public class GetDiscountResponse
{
public string SalesOrgcCode { get; set; }
public string DiscountCode { get; set; }
public string DiscountName { get; set; }
public string DistributorChannelCode { get; set; }
public string DistributorChannelName { get; set; }
public string CalculationType { get; set; }
}
public class GetDiscountMaterialResponse
{
public string DiscountCode { get; set; }
public string CustomerCode { get; set; }
public string MaterialCode { get; set; }
public string UnitOfMeasurement { get; set; }
public string CalculationType { get; set; }
public decimal DiscountValue { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
public class GetFOCResponse
{
public string SalesOrgcCode { get; set; }
public string FOCCode { get; set; }
public string FOCName { get; set; }
public string DistributorChannelCode { get; set; }
public string DistributorChannelName { get; set; }
}
public class GetFOCMaterialResponse
{
public string FOCCode { get; set; }
public string CustomerCode { get; set; }
public string MaterialCode { get; set; }
public string UnitOfMeasurement { get; set; }
public decimal MinimumOrderQty { get; set; }
public decimal ForQuantity { get; set; }
public decimal FreeQty { get; set; }
public string FOCUnitOfMeasurement { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
public class GetPaymentTermResponse
{
public int PaymentTermId { get; set; }
public string PaymentTermCode { get; set; }
public string PaymentTermDescription { get; set; }
public string SalesOrgCode { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string PaymentTermType { get; set; }
}

View File

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
public class SaveOrderResponse
{
public int OrderId { get; set; }
public string OrderNo { get; set; }
public string UUID { get; set; }
public DateTime OrderDate { get; set; }
public bool IsNewOrder { get; set; }
}
public class GetOrderByUUIDResponse
{
public int OrderId { get; set; }
public string OrderNo { get; set; }
public DateTime OrderDate { get; set; }
public DateTime? ExpectedSalesDate { get; set; }
public Guid UUID { get; set; }
public string SalesOrgCode { get; set; }
public int CustomerId { get; set; }
public string CustomerCode { get; set; }
public string CustomerName { get; set; }
public int EmployeeId { get; set; }
public string EmployeeCode { get; set; }
public string EmployeeName { get; set; }
public string PaymentTermCode { get; set; }
public string? ReferenceTxtNo { get; set; }
public decimal GrossValue { get; set; }
public decimal DiscountValue { get; set; }
public decimal FOCValue { get; set; }
public decimal NetValue { get; set; }
public string OrderStatus { get; set; }
public string SAPReferenceOrderNo { get; set; }
public List<GetOrderItemResponse> Items { get; set; } = new();
public List<GetOrderPromotionResponse> Promotions { get; set; } = new();
}
public class GetOrderItemResponse
{
public int ItemId { get; set; }
public int OrderID { get; set; }
public int MaterialId { get; set; }
public string MaterialCode { get; set; }
public string MaterialName { get; set; }
public decimal UnitPrice { get; set; }
public string SalesUnit { get; set; }
public decimal OrderQuantity { get; set; }
public decimal ValidatedQuantity { get; set; }
public decimal ApprovedQuantity { get; set; }
public decimal DiscountPercentage { get; set; }
public decimal DiscountValue { get; set; }
public bool IsFOCItem { get; set; }
public decimal OrderFocQuantity { get; set; }
public decimal ValidatedFocQuantity { get; set; }
public decimal ApprovedFocQuantity { get; set; }
public decimal LineTotalValue { get; set; }
}
public class GetOrderPromotionResponse
{
public int ItemId { get; set; }
public int OrderID { get; set; }
public int MaterialId { get; set; }
public string PromotionCode { get; set; }
public decimal DiscountPercentage { get; set; }
public decimal DiscountValue { get; set; }
public decimal ForQuantity { get; set; }
public decimal OrderFocQuantity { get; set; }
public decimal ValidatedFocQuantity { get; set; }
public decimal ApprovedFocQuantity { get; set; }
public int PromotionType { get; set; }
}

View File

@ -1,7 +1,9 @@
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Objects;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses
{
@ -12,7 +14,21 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses
public List<string> ReturnMessage { get; set; } = [];
}
public abstract class TotalRowsResponseBase : ResponseBase
public class MobileResponseBase<T>
{
public int ReturnStatus { get; set; }
public List<string> ReturnMessage { get; set; } = [];
public T? Data { get; set; }
public static MobileResponseBase<T> Success(T data, string message = "Success") =>
new() { ReturnStatus = 200, ReturnMessage = [message], Data = data };
public static MobileResponseBase<T> Failure(string message, int status = 400 ) =>
new() { ReturnStatus = status, ReturnMessage = [message], Data = default };
}
public abstract class TotalRowsResponseBase : ResponseBase
{
public int TotalRows { get; set; }
}
@ -50,4 +66,15 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses
{
public List<FoundKeywordItem> FoundKeywords { get; set; }
}
public class PagedResult<T>
{
public IList<T> Items { get; set; } = [];
public int TotalCount { get; set; }
public int PageNumber { get; set; } = 1;
public int PageSize { get; set; } = 10000;
public int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize);
public bool HasNextPage => PageNumber < TotalPages;
public bool HasPreviousPage => PageNumber > 1;
}
}

View File

@ -1,4 +1,5 @@
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
using Ease.NetCore.DataAccess;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using System.Threading.Tasks;
@ -9,4 +10,5 @@ public interface IRefreshTokenService
Task<GenerateRefreshTokenResponse> GenerateRefreshTokenByUserAsync(GenerateRefreshTokenRequest request);
Task<string> GenerateRefreshTokenAsync(string refreshToken, string ipAddress);
Task<UserByRefreshTokenResponse> GetUserByRefreshTokenAsync(string refreshToken);
Task<bool> InvalidRefreshTokenAsync(TransactionContext tc, int userId);
}

View File

@ -8,14 +8,30 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
public interface IIntegrationService
{
//Customer
Task<CustomerIntegrationResponse> UpsertCustomerAsync(CustomerIntegrationRequest request);
Task<IntegrationCustomerResponse> UpsertCustomerAsync(IntegrationCustomerRequest request);
Task<CustomerByCompanyCodeResponse> GetCustomerByCompanyCodeAsync(CustomerByCompanyCodeRequest request);
//Employee
Task<EmployeeIntegrationReqResponse> UpsertEmployeeAsync(EmployeeIntegrationRequest request);
Task<EmployeeIntegrationResponse> GetEmployeeBySalesOrgAsync(EmployeeIntegrationByComapanyRequest request);
Task<EmployeeIntegrationReqResponse> UpsertEmployeeAsync(IntegrationEmployeeRequest request);
Task<IntegrationEmployeeResponse> GetEmployeeBySalesOrgAsync(EmployeeIntegrationByComapanyRequest request);
//Meterial
Task<MaterialIntegrationReqResponse > UpsertMaterialAsync(MaterialIntegrationRequest request);
Task<MaterialIntegrationResponse> GetMaterialByCodeAsync(GetMaterialByCodeRequest request);
//Material
Task<MaterialIntegrationReqResponse > UpsertMaterialAsync(IntegrationMaterialRequest request);
Task<IntegrationMaterialResponse> GetMaterialByCodeAsync(GetMaterialByCodeRequest request);
//Material Price
Task<MaterialIntegrationPriceReqResponse> UpsertMaterialPriceAsync(IntegrationMaterialPriceRequest request);
Task<IntegrationMaterialPriceResponse> GetMaterialPriceByCodeAsync( GetMaterialPriceByCodeRequest request);
//Material Free Goods
Task<MaterialFreeGoodsByReqResponse> UpsertMaterialFreeGoodsAsync(IntegrationMaterialFreeGoodsRequest request);
Task<IntegrationMaterialFreeGoodsResponse> GetMaterialFreeGoodseByFilterAsync(GetMaterialFreeGoodsByFilterRequest request);
//Payment Terms
Task<IntegrationPaymentTermReqResponse> UpsertPaymentTermsAsync(IntegrationPaymentTermRequest request);
Task<IntegrationPaymentTermResponse> GetPaymentTermsByFilterAsync(GetIntegrationPaymentTermRequest request);
//Invoices
Task<IntegrationInvoiceReqResponse> SaveInvoiceAsync(IntegrationInvoiceRequest request);
}

View File

@ -0,0 +1,23 @@
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
public interface IMobileMasterDataService
{
Task<MarketHeirarchyByEmpResponse> GetMarketHeirarchiesByEmpAsync(GetMarketHeirarchyByEmpRequest request);
Task<PagedResult<GetBrandResponse>> GetBrandsAsync(GetBrandsRequest request);
Task<PagedResult<GetMaterialResponse>> GetMaterialsAsync(GetMaterialsRequest request);
Task<PagedResult<GetMaterialPriceResponse>> GetMaterialPricesAsync(GetMaterialPriceRequest request);
Task<PagedResult<GetCustomerResponse>> GetCustomersAsync(GetCustomersRequest request);
Task<GetAttendanceByEmpResponse> GetAttendanceByEmpAsync(GetAttendanceByEmpRequest request);
Task<GetAttendanceByEmpResponse> UpsertAttendanceByEmpAsync(UpsertAttendanceByEmpRequest request);
Task<PagedResult<GetDiscountResponse>> GetDiscountAsync(GetDiscountRequest request);
Task<PagedResult<GetDiscountMaterialResponse>> GetDiscountMaterialsAsync(GetDiscountMaterialRequest request);
Task<PagedResult<GetFOCResponse>> GetFOCsAsync(GetFOCRequest request);
Task<PagedResult<GetFOCMaterialResponse>> GetFOCMaterialsAsync(GetFOCMaterialRequest request);
Task<PagedResult<GetPaymentTermResponse>> GetPaymentTermsAsync(GetPaymentTermRequest request);
}

View File

@ -0,0 +1,11 @@

using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
public interface IOrderService
{
Task<SaveOrderResponse> SaveOrderAsync(SaveOrderRequest request);
}

View File

@ -1,7 +1,10 @@
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Setups;
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems;
using System;
using System.Collections.Generic;
@ -13,10 +16,14 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems
{
Task<bool> ValidateAuthValueAsync(string authValue, int userId);
Task<User> LoginAsync(LoginRequest request, string ipAddress, bool checkPwd);
Task<AppAuthUserResponse> LoginAsync(MobileAppAuthRequest request, string ipAddress);
Task<User> IntegrationLoginAsync(IntegrationLoginRequest request, string ipAddress, bool checkPwd);
Task<bool> LogoutAsync(string ipAddress, int userId, int logId, bool attendanceLogout, string loginId, string localIp, string macAddress, string hostName, string logoutRemarks);
Task<AuthLogoutResponse> LogoutAsync(AuthLogoutRequest request, string ipAddress);
Task<AppChangePasswordResponse> ChangePasswordAsync(AppUserChangePasswordRequest request, string ipAddress);
Task<bool> DeleteUserAsync(int userId, int deletedBy);
Task<bool> ForceLogoutNowAsync(List<int> userIds, string ipAddress);
Task<bool> UnlockUserAsync(int userId, string loginId, int unlockedBy);

View File

@ -3,6 +3,7 @@ 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;
@ -116,6 +117,22 @@ public class RefreshTokenService : IRefreshTokenService
return refreshTokenResponse;
}
public async Task<bool> InvalidRefreshTokenAsync( TransactionContext tc, int userId)
{
bool response = false;
try
{
RevokeRefreshTokenByUserIdAsync(tc, userId);
response = true;
}
catch (Exception e)
{
throw new InvalidOperationException(e.Message, e);
}
return response;
}
#region Private Methods
// ----- private helpers -----
@ -145,7 +162,7 @@ public class RefreshTokenService : IRefreshTokenService
SqlHelperExtension.CreateInParam(pName: "@TokenHash", pType: SqlDbType.VarChar, pValue: refreshToken.TokenHash),
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: refreshToken.IpAddress),
SqlHelperExtension.CreateInParam(pName: "@CreatedAt", pType: SqlDbType.DateTime, pValue: DateTime.Now),
SqlHelperExtension.CreateInParam(pName: "@ExpiredAt", pType: SqlDbType.DateTime, pValue: DateTime.Now.AddMinutes(_settings.RefreshTokenDuration)),
SqlHelperExtension.CreateInParam(pName: "@ExpiredAt", pType: SqlDbType.DateTime, pValue: refreshToken.ExpiresAt),
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.InsertRefreshToken", parameterValues: p);
@ -259,7 +276,7 @@ public class RefreshTokenService : IRefreshTokenService
return new GenerateRefreshTokenResponse
{
RefreshToken = tokenHash,
ExpireTime = DateTime.UtcNow.AddMinutes(_settings.RefreshTokenDuration)
ExpireTime = DateTime.UtcNow.AddDays(_settings.RefreshTokenDuration)
};
}
@ -277,5 +294,7 @@ public class RefreshTokenService : IRefreshTokenService
return Convert.ToBase64String(bytes);
}
#endregion
}

View File

@ -1,13 +1,20 @@
using Ease.NetCore.DataAccess;
using Ease.NetCore.DataAccess.SQL;
using Ease.NetCore.Utility;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
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.Requests.Systems;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations;
@ -15,10 +22,12 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations;
public class IntegrationService : IIntegrationService
{
private readonly AppSettings _settings;
private readonly IUserService _userService;
public IntegrationService(IOptions<AppSettings> options)
public IntegrationService(IOptions<AppSettings> options, IUserService userService)
{
_settings = options.Value;
_userService = userService;
}
@ -48,9 +57,9 @@ public class IntegrationService : IIntegrationService
return response;
}
public async Task<CustomerIntegrationResponse> UpsertCustomerAsync(CustomerIntegrationRequest request)
public async Task<IntegrationCustomerResponse> UpsertCustomerAsync(IntegrationCustomerRequest request)
{
CustomerIntegrationResponse response = new();
IntegrationCustomerResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode,true);
@ -92,9 +101,9 @@ public class IntegrationService : IIntegrationService
}
public async Task<EmployeeIntegrationResponse> GetEmployeeBySalesOrgAsync(EmployeeIntegrationByComapanyRequest request)
public async Task<IntegrationEmployeeResponse> GetEmployeeBySalesOrgAsync(EmployeeIntegrationByComapanyRequest request)
{
EmployeeIntegrationResponse response = new();
IntegrationEmployeeResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
@ -118,7 +127,7 @@ public class IntegrationService : IIntegrationService
return response;
}
public async Task<EmployeeIntegrationReqResponse> UpsertEmployeeAsync(EmployeeIntegrationRequest request)
public async Task<EmployeeIntegrationReqResponse> UpsertEmployeeAsync(IntegrationEmployeeRequest request)
{
EmployeeIntegrationReqResponse response = new EmployeeIntegrationReqResponse();
try
@ -126,7 +135,7 @@ public class IntegrationService : IIntegrationService
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
try
{
EmployeeIntegrationResponse employee = await GetEmployeeBySalesOrgAsync(tc,
IntegrationEmployeeResponse employee = await GetEmployeeBySalesOrgAsync(tc,
new EmployeeIntegrationByComapanyRequest() { EmployeeVendorCode = request.EmployeeVendorCode, CompanyCode = request.CompanyCode });
@ -141,6 +150,29 @@ public class IntegrationService : IIntegrationService
response.IsUpdated = false;
}
int roleTypeId = GetRegionAreaTerritoryLevel(request);
bool isUserExist = await IsUserExistByEmployeeNumberAsync(tc, request.EmployeeVendorCode);
if (!isUserExist)
{
AppUserCreateRequest appUser = new()
{
LoginId = request.EmployeeVendorCode,
UserName = request.EmployeeVendorCode,
Status = (int)EnumStatus.Authorized,
AccessStatus = (int)EnumAccessStatus.FirstTime,
MobileNo = request.MobileNo,
EmailAddress = request.Mail,
IsLocked = 0,
Password ="12345",
UserRoleType = roleTypeId,
UserPlatformId = (int)UserPlatFormType.AppUser,
EmployeeNumber = request.EmployeeVendorCode
};
await AddUserAsync(tc, appUser);
}
response.EmployeeVendorCode = request.EmployeeVendorCode;
response.CompanyCode = request.CompanyCode;
tc.End();
@ -160,8 +192,31 @@ public class IntegrationService : IIntegrationService
return response;
}
private int GetRegionAreaTerritoryLevel(IntegrationEmployeeRequest request)
{
bool hasRegion = !string.IsNullOrWhiteSpace(request.RegionAreaCode);
bool hasArea = !string.IsNullOrWhiteSpace(request.AreaAVSalesUnitCode);
bool hasTerritory = !string.IsNullOrWhiteSpace(request.Territory);
public async Task<MaterialIntegrationReqResponse> UpsertMaterialAsync(MaterialIntegrationRequest request)
if (hasRegion && hasArea && hasTerritory)
{
return (int)UserRoleTypeEnum.OrderCollector;
}
if (hasRegion && hasArea && !hasTerritory)
{
return (int)UserRoleTypeEnum.OrderValidator;
}
if (hasRegion && !hasArea && !hasTerritory)
{
return (int)UserRoleTypeEnum.OrderApprover;
}
return 0;
}
public async Task<MaterialIntegrationReqResponse> UpsertMaterialAsync(IntegrationMaterialRequest request)
{
MaterialIntegrationReqResponse response = new MaterialIntegrationReqResponse();
try
@ -169,7 +224,7 @@ public class IntegrationService : IIntegrationService
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
try
{
MaterialIntegrationResponse meterial = await GetMaterialByCodeAsync(tc,
IntegrationMaterialResponse meterial = await GetMaterialByCodeAsync(tc,
new GetMaterialByCodeRequest() { MaterialCode = request.MaterialCode });
if (meterial != null && meterial.MeterialId > 0)
@ -201,9 +256,9 @@ public class IntegrationService : IIntegrationService
return response;
}
public async Task<MaterialIntegrationResponse> GetMaterialByCodeAsync(GetMaterialByCodeRequest request)
public async Task<IntegrationMaterialResponse> GetMaterialByCodeAsync(GetMaterialByCodeRequest request)
{
MaterialIntegrationResponse response = new();
IntegrationMaterialResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
@ -228,6 +283,217 @@ public class IntegrationService : IIntegrationService
}
public async Task<MaterialIntegrationPriceReqResponse> UpsertMaterialPriceAsync(IntegrationMaterialPriceRequest request)
{
MaterialIntegrationPriceReqResponse response = new MaterialIntegrationPriceReqResponse();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
try
{
IntegrationMaterialPriceResponse meterialPrice = await GetMaterialPriceByCodeAndConditionTypeAsync(tc,
new GetMaterialPriceByCodeRequest() { MaterialCode = request.MaterialCode, ConditionType = request.ConditionType,
SalesOrg=request.SalesOrg, CustomerNumber = request.CustomerNumber,CustomerGroupCode = request.CustomerGroupCode });
if (meterialPrice != null && !string.IsNullOrWhiteSpace(meterialPrice.MaterialCode))
{
UpdateMaterialPrice(tc, request);
response.IsUpdated = true;
}
else
{
CreateMaterialPrice(tc, request);
response.IsUpdated = false;
}
response.MaterialCode = request.MaterialCode;
response.ConditionType = request.ConditionType;
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<IntegrationMaterialPriceResponse> GetMaterialPriceByCodeAsync(GetMaterialPriceByCodeRequest request)
{
IntegrationMaterialPriceResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
response = await GetMaterialPriceByCodeAndConditionTypeAsync(tc, request);
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<MaterialFreeGoodsByReqResponse> UpsertMaterialFreeGoodsAsync(IntegrationMaterialFreeGoodsRequest request)
{
MaterialFreeGoodsByReqResponse response = new MaterialFreeGoodsByReqResponse();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
try
{
IntegrationMaterialFreeGoodsResponse meterialFreeGoods = await GetMaterialFreeGoodsByFilterAsync(tc,
new GetMaterialFreeGoodsByFilterRequest() { SalesOrg = request.SalesOrg, DistributionChannel = request.DistributionChannel,
CustomerPriceGroup = request.CustomerPriceGroup,MaterialCode = request.MaterialCode, CustomerNumber = request.CustomerNumber });
if (meterialFreeGoods != null && !string.IsNullOrWhiteSpace(meterialFreeGoods.MaterialCode))
{
UpdateMaterialFreeGoods(tc, request);
response.IsUpdated = true;
}
else
{
CreateMaterialFreeGoods(tc, request);
response.IsUpdated = false;
}
response.SalesOrg = request.SalesOrg;
response.DistributionChannel = request.DistributionChannel;
response.CustomerPriceGroup = request.CustomerPriceGroup;
response.MaterialCode = request.MaterialCode;
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<IntegrationMaterialFreeGoodsResponse> GetMaterialFreeGoodseByFilterAsync(GetMaterialFreeGoodsByFilterRequest request)
{
IntegrationMaterialFreeGoodsResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
response = await GetMaterialFreeGoodsByFilterAsync(tc, request);
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<IntegrationPaymentTermReqResponse> UpsertPaymentTermsAsync(IntegrationPaymentTermRequest request)
{
IntegrationPaymentTermReqResponse response = new IntegrationPaymentTermReqResponse();
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
try
{
IntegrationPaymentTermResponse paymentTerms = await GetPaymentTermByFilterAsync(tc,
new GetIntegrationPaymentTermRequest()
{
CreditCode = request.CreditCode,
SalesOrg = request.SalesOrg
});
if (paymentTerms != null && !string.IsNullOrWhiteSpace(paymentTerms.CreditCode))
{
UpdatePaymentTerm(tc, request);
response.IsUpdated = true;
}
else
{
CreatePaymentTerm(tc, request);
response.IsUpdated = false;
}
response.SalesOrg = request.SalesOrg;
response.CreditCode = request.CreditCode;
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
return response;
}
public async Task<IntegrationPaymentTermResponse> GetPaymentTermsByFilterAsync(GetIntegrationPaymentTermRequest request)
{
IntegrationPaymentTermResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
response = await GetPaymentTermByFilterAsync(tc, request);
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<IntegrationInvoiceReqResponse> SaveInvoiceAsync(IntegrationInvoiceRequest request)
{
throw new NotImplementedException();
}
#region Customer Private Functions
private async Task<CustomerByCompanyCodeResponse> GetCustomerByCompanyCodeAsync(TransactionContext tc, CustomerByCompanyCodeRequest request)
@ -297,7 +563,7 @@ public class IntegrationService : IIntegrationService
return response;
}
private bool CreateCustomer(TransactionContext tc, CustomerIntegrationRequest request)
private bool CreateCustomer(TransactionContext tc, IntegrationCustomerRequest request)
{
bool returnValue = false;
@ -371,7 +637,7 @@ public class IntegrationService : IIntegrationService
return returnValue;
}
private bool UpdateCustomer(TransactionContext tc, CustomerIntegrationRequest request)
private bool UpdateCustomer(TransactionContext tc, IntegrationCustomerRequest request)
{
bool returnValue = false;
@ -449,9 +715,9 @@ public class IntegrationService : IIntegrationService
#region Employee Private Functions
private async Task<EmployeeIntegrationResponse> GetEmployeeBySalesOrgAsync(TransactionContext tc, EmployeeIntegrationByComapanyRequest request)
private async Task<IntegrationEmployeeResponse> GetEmployeeBySalesOrgAsync(TransactionContext tc, EmployeeIntegrationByComapanyRequest request)
{
EmployeeIntegrationResponse response = new EmployeeIntegrationResponse();
IntegrationEmployeeResponse response = new IntegrationEmployeeResponse();
try
{
@ -465,7 +731,7 @@ public class IntegrationService : IIntegrationService
{
if (dr.Read())
{
response = new EmployeeIntegrationResponse()
response = new IntegrationEmployeeResponse()
{
EmployeeId = dr.GetInt32(0),
EmployeeVendorCode = dr.GetString(1),
@ -505,7 +771,94 @@ public class IntegrationService : IIntegrationService
return response;
}
private bool InsertEmployee(TransactionContext tc, EmployeeIntegrationRequest request)
public async Task<bool> AddUserAsync(TransactionContext tc, AppUserCreateRequest user)
{
bool returnValue;
try
{
int userId = 0;
user.Password = EncryptPassword(password: user.Password);
if (!string.IsNullOrEmpty(user.EmailAddress))
user.EmailAddress = user.EmailAddress.Replace(" ", "");
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: user.LoginId, size: 100),
SqlHelperExtension.CreateInParam(pName: "@UserName", pType: SqlDbType.VarChar, pValue: user.UserName, size: 150),
SqlHelperExtension.CreateInParam(pName: "@Status", pType: SqlDbType.Int, pValue: user.Status),
SqlHelperExtension.CreateInParam(pName: "@AccessStatus", pType: SqlDbType.Int, pValue: user.AccessStatus),
SqlHelperExtension.CreateInParam(pName: "@MobileNo", pType: SqlDbType.VarChar, pValue: DataReader.GetNullValue(user.MobileNo), size: 20),
SqlHelperExtension.CreateInParam(pName: "@EmailAddress", pType: SqlDbType.VarChar, pValue: user.EmailAddress, size: 200),
SqlHelperExtension.CreateInParam(pName: "@IsLocked", pType: SqlDbType.Int, pValue: user.IsLocked),
SqlHelperExtension.CreateInParam(pName: "@Password", pType: SqlDbType.NVarChar, pValue: user.Password, size: 500),
SqlHelperExtension.CreateInParam(pName: "@UserPlatformId", pType: SqlDbType.Int, pValue: DataReader.GetNullValue(user.UserPlatformId)),
SqlHelperExtension.CreateInParam(pName: "@UserRoleType", pType: SqlDbType.Int, pValue: DataReader.GetNullValue(user.UserRoleType)),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: DataReader.GetNullValue(user.EmployeeNumber), size: 10),
SqlHelperExtension.CreateOutParam(pName: "@NewUserId", pType: SqlDbType.Int) // index 11 — output
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.InsertUser", parameterValues: p);
userId = (p[11]?.Value != null && p[11]?.Value != DBNull.Value)
? Convert.ToInt32(p[11].Value)
: 0;
returnValue = userId > 0;
}
catch (Exception e)
{
throw new InvalidOperationException(e.Message, e);
}
return returnValue;
}
private string EncryptPassword(string password)
{
try
{
string pwdSecretKey = GlobalFunctions.ConvertFromBase64String(_settings.PwdSecretKey);
return Global.CipherFunctions.EncryptByAES(privateKey: pwdSecretKey, publicKey: pwdSecretKey, data: password);
}
catch (Exception e)
{
throw new InvalidOperationException(e.Message, e);
}
}
private async Task<bool> IsUserExistByEmployeeNumberAsync(TransactionContext tc, string employeeNumber)
{
bool response = false;
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.NVarChar, pValue: employeeNumber)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.IsUserExistByEmployeeNumber", parameterValues: p))
{
if (dr.Read())
{
response = dr.GetInt32(0) > 0 ? true: false;
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private bool InsertEmployee(TransactionContext tc, IntegrationEmployeeRequest request)
{
bool returnValue = false;
@ -514,40 +867,40 @@ public class IntegrationService : IIntegrationService
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: "@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: "@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: "@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: "@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: "@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: "@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: "@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: "@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: "@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: "@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: "@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)
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);
@ -562,7 +915,7 @@ public class IntegrationService : IIntegrationService
return returnValue;
}
private bool UpdateEmployee(TransactionContext tc, EmployeeIntegrationRequest request)
private bool UpdateEmployee(TransactionContext tc, IntegrationEmployeeRequest request)
{
bool returnValue = false;
@ -624,9 +977,9 @@ public class IntegrationService : IIntegrationService
#region Meterial Private Functions
private async Task<MaterialIntegrationResponse> GetMaterialByCodeAsync(TransactionContext tc, GetMaterialByCodeRequest request)
private async Task<IntegrationMaterialResponse> GetMaterialByCodeAsync(TransactionContext tc, GetMaterialByCodeRequest request)
{
MaterialIntegrationResponse response = new MaterialIntegrationResponse();
IntegrationMaterialResponse response = new IntegrationMaterialResponse();
try
{
@ -639,7 +992,7 @@ public class IntegrationService : IIntegrationService
{
if (dr.Read())
{
response = new MaterialIntegrationResponse()
response = new IntegrationMaterialResponse()
{
MeterialId = dr.GetInt32(0),
MaterialType = dr.GetString(1),
@ -657,6 +1010,8 @@ public class IntegrationService : IIntegrationService
StorageLocationDescription = dr.GetString(13),
SalesOrganization = dr.GetString(14),
SalesOrganizationDescription = dr.GetString(15),
BrandCode = dr.GetString(16),
BrandName = dr.GetString(17)
};
}
dr.Close();
@ -670,7 +1025,7 @@ public class IntegrationService : IIntegrationService
return response;
}
private bool CreateMaterial(TransactionContext tc, MaterialIntegrationRequest request)
private bool CreateMaterial(TransactionContext tc, IntegrationMaterialRequest request)
{
bool returnValue = false;
@ -698,8 +1053,11 @@ public class IntegrationService : IIntegrationService
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)
SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization),
SqlHelperExtension.CreateInParam("@SalesOrganizationDescription", SqlDbType.NVarChar, request.SalesOrganizationDescription),
SqlHelperExtension.CreateInParam("@BrandCode", SqlDbType.NVarChar, request.BrandCode),
SqlHelperExtension.CreateInParam("@BrandName", SqlDbType.NVarChar, request.BrandName)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.CreateMaterial", parameterValues: p);
@ -714,7 +1072,7 @@ public class IntegrationService : IIntegrationService
return returnValue;
}
private bool UpdateMaterial(TransactionContext tc, MaterialIntegrationRequest request)
private bool UpdateMaterial(TransactionContext tc, IntegrationMaterialRequest request)
{
bool returnValue = false;
@ -742,8 +1100,11 @@ public class IntegrationService : IIntegrationService
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)
SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization),
SqlHelperExtension.CreateInParam("@SalesOrganizationDescription", SqlDbType.NVarChar, request.SalesOrganizationDescription),
SqlHelperExtension.CreateInParam("@BrandCode", SqlDbType.NVarChar, request.BrandCode),
SqlHelperExtension.CreateInParam("@BrandName", SqlDbType.NVarChar, request.BrandName)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateMaterial", parameterValues: p);
@ -759,4 +1120,347 @@ public class IntegrationService : IIntegrationService
}
#endregion
#region Material Price Private Functions
private async Task<IntegrationMaterialPriceResponse> GetMaterialPriceByCodeAndConditionTypeAsync(
TransactionContext tc, GetMaterialPriceByCodeRequest request)
{
IntegrationMaterialPriceResponse response = new IntegrationMaterialPriceResponse();
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam("@SalesOrg", SqlDbType.NVarChar, request.SalesOrg),
SqlHelperExtension.CreateInParam("@MaterialCode", SqlDbType.NVarChar, request.MaterialCode),
SqlHelperExtension.CreateInParam("@ConditionType", SqlDbType.NVarChar, request.ConditionType),
SqlHelperExtension.CreateInParam("@CustomerNumber", SqlDbType.NVarChar, string.IsNullOrWhiteSpace(request.CustomerNumber)? null : request.CustomerNumber ),
SqlHelperExtension.CreateInParam("@CustomerGroup", SqlDbType.NVarChar, string.IsNullOrWhiteSpace(request.CustomerGroupCode)? null : request.CustomerGroupCode )
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetMaterialPriceByMaterialCodeAndConditionType", parameterValues: p))
{
if (dr.Read())
{
response=new IntegrationMaterialPriceResponse()
{
MaterialPriceId = dr.GetInt32(0),
SalesOrg = dr.GetString(1),
DistributionChannel = dr.GetString(2),
CustomerNumber = dr.IsDBNull(3) ? null : dr.GetString(3),
CustomerGroupCode = dr.IsDBNull(4) ? null : dr.GetString(4),
MaterialCode = dr.GetString(5),
ConditionType = dr.GetString(6),
CalculationType = dr.GetString(7),
PricingUnit = dr.GetString(8),
UnitOfMeasure = dr.GetString(9),
ValidFrom = dr.GetDateTime(10),
ValidTo = dr.GetDateTime(11),
Status = dr.IsDBNull(12) ? null : dr.GetString(12),
ConditionValue = dr.GetDecimal(13)
};
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private bool CreateMaterialPrice(TransactionContext tc, IntegrationMaterialPriceRequest request)
{
bool response = false;
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam("@SalesOrg", SqlDbType.NVarChar, request.SalesOrg),
SqlHelperExtension.CreateInParam("@DistributionChannel", SqlDbType.NVarChar, request.DistributionChannel),
SqlHelperExtension.CreateInParam("@CustomerNumber", SqlDbType.NVarChar, request.CustomerNumber),
SqlHelperExtension.CreateInParam("@CustomerGroupCode", SqlDbType.NVarChar, request.CustomerGroupCode),
SqlHelperExtension.CreateInParam("@MaterialCode", SqlDbType.NVarChar, request.MaterialCode),
SqlHelperExtension.CreateInParam("@ConditionType", SqlDbType.NVarChar, request.ConditionType),
SqlHelperExtension.CreateInParam("@CalculationType", SqlDbType.NVarChar, request.CalculationType),
SqlHelperExtension.CreateInParam("@PricingUnit", SqlDbType.NVarChar, request.PricingUnit),
SqlHelperExtension.CreateInParam("@UnitOfMeasure", SqlDbType.NVarChar, request.UnitOfMeasure),
SqlHelperExtension.CreateInParam("@ValidFrom", SqlDbType.DateTime, request.ValidFrom),
SqlHelperExtension.CreateInParam("@ValidTo", SqlDbType.DateTime, request.ValidTo),
SqlHelperExtension.CreateInParam("@Status", SqlDbType.NVarChar, request.Status),
SqlHelperExtension.CreateInParam("@ConditionValue", SqlDbType.Decimal, request.ConditionValue)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.InsertIntegrationMaterialPrice", parameterValues: p);
response = true;
}
catch (Exception)
{
throw;
}
return response;
}
private bool UpdateMaterialPrice(TransactionContext tc, IntegrationMaterialPriceRequest request)
{
bool returnValue = false;
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam("@SalesOrg", SqlDbType.NVarChar, request.SalesOrg),
SqlHelperExtension.CreateInParam("@DistributionChannel", SqlDbType.NVarChar, request.DistributionChannel),
SqlHelperExtension.CreateInParam("@CustomerNumber", SqlDbType.NVarChar, string.IsNullOrWhiteSpace(request.CustomerNumber) ? null : request.CustomerNumber),
SqlHelperExtension.CreateInParam("@CustomerGroupCode", SqlDbType.NVarChar, request.CustomerGroupCode),
SqlHelperExtension.CreateInParam("@MaterialCode", SqlDbType.NVarChar, request.MaterialCode),
SqlHelperExtension.CreateInParam("@ConditionType", SqlDbType.NVarChar, request.ConditionType),
SqlHelperExtension.CreateInParam("@CalculationType", SqlDbType.NVarChar, request.CalculationType),
SqlHelperExtension.CreateInParam("@PricingUnit", SqlDbType.NVarChar, request.PricingUnit),
SqlHelperExtension.CreateInParam("@UnitOfMeasure", SqlDbType.NVarChar, request.UnitOfMeasure),
SqlHelperExtension.CreateInParam("@ValidFrom", SqlDbType.DateTime, request.ValidFrom),
SqlHelperExtension.CreateInParam("@ValidTo", SqlDbType.DateTime, request.ValidTo),
SqlHelperExtension.CreateInParam("@Status", SqlDbType.NVarChar, request.Status),
SqlHelperExtension.CreateInParam("@ConditionValue", SqlDbType.Decimal, request.ConditionValue)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateIntegrationMaterialPrice", parameterValues: p);
returnValue = true;
}
catch (Exception)
{
throw;
}
return returnValue;
}
#endregion
#region Material Free Goods Private Functions
private async Task<IntegrationMaterialFreeGoodsResponse> GetMaterialFreeGoodsByFilterAsync(
TransactionContext tc, GetMaterialFreeGoodsByFilterRequest request)
{
IntegrationMaterialFreeGoodsResponse response = new IntegrationMaterialFreeGoodsResponse();
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam("@SalesOrg", SqlDbType.NVarChar, request.SalesOrg),
SqlHelperExtension.CreateInParam("@DistributionChannel", SqlDbType.NVarChar, request.DistributionChannel),
SqlHelperExtension.CreateInParam("@CustomerNumber", SqlDbType.NVarChar, request.CustomerNumber),
SqlHelperExtension.CreateInParam("@CustomerPriceGroup", SqlDbType.NVarChar, request.CustomerPriceGroup),
SqlHelperExtension.CreateInParam("@MaterialCode", SqlDbType.NVarChar, request.MaterialCode)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetAllMaterialFreeGoodsForUpdate", parameterValues: p))
{
while (dr.Read())
{
response= new IntegrationMaterialFreeGoodsResponse()
{
FreeGoodsId = dr.GetInt32(0),
SalesOrg = dr.GetString(1),
DistributionChannel = dr.GetString(2),
CustomerNumber = dr.IsDBNull(3) ? null : dr.GetString(3),
CustomerPriceGroup = dr.GetString(4),
MaterialCode = dr.GetString(5),
MinOrderQuantity = dr.GetDecimal(6),
ForQuantity = dr.GetDecimal(7),
UnitOfMeasure = dr.GetString(8),
FreeQuantity = dr.GetDecimal(9),
FocUnitOfMeasure = dr.GetString(10),
ValidFrom = dr.GetDateTime(11),
ValidTo = dr.GetDateTime(12),
Status = dr.IsDBNull(13) ? null : dr.GetString(13)
};
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private bool CreateMaterialFreeGoods(TransactionContext tc, IntegrationMaterialFreeGoodsRequest request)
{
bool response = false;
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam("@SalesOrg", SqlDbType.NVarChar, request.SalesOrg),
SqlHelperExtension.CreateInParam("@DistributionChannel", SqlDbType.NVarChar, request.DistributionChannel),
SqlHelperExtension.CreateInParam("@CustomerNumber", SqlDbType.NVarChar, (object?)request.CustomerNumber ?? DBNull.Value),
SqlHelperExtension.CreateInParam("@CustomerPriceGroup", SqlDbType.NVarChar, request.CustomerPriceGroup),
SqlHelperExtension.CreateInParam("@MaterialCode", SqlDbType.NVarChar, request.MaterialCode),
SqlHelperExtension.CreateInParam("@MinOrderQuantity", SqlDbType.Decimal, request.MinOrderQuantity),
SqlHelperExtension.CreateInParam("@ForQuantity", SqlDbType.Decimal, request.ForQuantity),
SqlHelperExtension.CreateInParam("@UnitOfMeasure", SqlDbType.NVarChar, request.UnitOfMeasure),
SqlHelperExtension.CreateInParam("@FreeQuantity", SqlDbType.Decimal, request.FreeQuantity),
SqlHelperExtension.CreateInParam("@FocUnitOfMeasure", SqlDbType.NVarChar, request.FocUnitOfMeasure),
SqlHelperExtension.CreateInParam("@ValidFrom", SqlDbType.Date, request.ValidFrom),
SqlHelperExtension.CreateInParam("@ValidTo", SqlDbType.Date, request.ValidTo),
SqlHelperExtension.CreateInParam("@Status", SqlDbType.NVarChar, (object?)request.Status ?? DBNull.Value),
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.InsertIntegrationMaterialFreeGoods", parameterValues: p);
response = true;
}
catch (Exception)
{
throw;
}
return response;
}
private bool UpdateMaterialFreeGoods(TransactionContext tc, IntegrationMaterialFreeGoodsRequest request)
{
bool returnValue = false;
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam("@SalesOrg", SqlDbType.NVarChar, request.SalesOrg),
SqlHelperExtension.CreateInParam("@DistributionChannel", SqlDbType.NVarChar, request.DistributionChannel),
SqlHelperExtension.CreateInParam("@CustomerNumber", SqlDbType.NVarChar, string.IsNullOrWhiteSpace(request.CustomerNumber)? null : request.CustomerNumber ),
SqlHelperExtension.CreateInParam("@CustomerPriceGroup", SqlDbType.NVarChar, request.CustomerPriceGroup),
SqlHelperExtension.CreateInParam("@MaterialCode", SqlDbType.NVarChar, request.MaterialCode),
SqlHelperExtension.CreateInParam("@MinOrderQuantity", SqlDbType.Decimal, request.MinOrderQuantity),
SqlHelperExtension.CreateInParam("@ForQuantity", SqlDbType.Decimal, request.ForQuantity),
SqlHelperExtension.CreateInParam("@UnitOfMeasure", SqlDbType.NVarChar, request.UnitOfMeasure),
SqlHelperExtension.CreateInParam("@FreeQuantity", SqlDbType.Decimal, request.FreeQuantity),
SqlHelperExtension.CreateInParam("@FocUnitOfMeasure", SqlDbType.NVarChar, request.FocUnitOfMeasure),
SqlHelperExtension.CreateInParam("@ValidFrom", SqlDbType.Date, request.ValidFrom),
SqlHelperExtension.CreateInParam("@ValidTo", SqlDbType.Date, request.ValidTo),
SqlHelperExtension.CreateInParam("@Status", SqlDbType.NVarChar, (object?)request.Status ?? DBNull.Value)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateIntegrationMaterialFreeGoods", parameterValues: p);
returnValue = true;
}
catch (Exception)
{
throw;
}
return returnValue;
}
#endregion
#region Payment Terms Private Functions
private async Task<IntegrationPaymentTermResponse> GetPaymentTermByFilterAsync(TransactionContext tc,
GetIntegrationPaymentTermRequest request)
{
IntegrationPaymentTermResponse response = new IntegrationPaymentTermResponse();
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam("@CreditCode", SqlDbType.NVarChar, request.CreditCode),
SqlHelperExtension.CreateInParam("@SalesOrg", SqlDbType.NVarChar, request.SalesOrg)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetPaymentTermByFilter", parameterValues: p))
{
if (dr.Read())
{
response=new IntegrationPaymentTermResponse()
{
CreditCodeId = dr.GetInt32(0),
CreditCode = dr.GetString(1),
Description = dr.GetString(2),
ValidFrom = dr.GetDateTime(3),
ValidTo = dr.GetDateTime(4),
SalesOrg = dr.GetString(5)
};
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private bool CreatePaymentTerm(TransactionContext tc, IntegrationPaymentTermRequest request)
{
bool response = false;
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam("@CreditCode", SqlDbType.NVarChar, request.CreditCode),
SqlHelperExtension.CreateInParam("@Description", SqlDbType.NVarChar, request.Description),
SqlHelperExtension.CreateInParam("@ValidFrom", SqlDbType.DateTime, request.ValidFrom),
SqlHelperExtension.CreateInParam("@ValidTo", SqlDbType.DateTime, request.ValidTo),
SqlHelperExtension.CreateInParam("@SalesOrg", SqlDbType.NVarChar, request.SalesOrg)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.InsertIntegrationPaymentTerm", parameterValues: p);
response = true;
}
catch (Exception)
{
throw;
}
return response;
}
private bool UpdatePaymentTerm(TransactionContext tc, IntegrationPaymentTermRequest request)
{
bool returnValue = false;
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam("@CreditCode", SqlDbType.NVarChar, request.CreditCode),
SqlHelperExtension.CreateInParam("@Description", SqlDbType.NVarChar, request.Description),
SqlHelperExtension.CreateInParam("@ValidFrom", SqlDbType.DateTime, request.ValidFrom),
SqlHelperExtension.CreateInParam("@ValidTo", SqlDbType.DateTime, request.ValidTo),
SqlHelperExtension.CreateInParam("@SalesOrg", SqlDbType.NVarChar, request.SalesOrg)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateIntegrationPaymentTerms", parameterValues: p);
returnValue = true;
}
catch (Exception)
{
throw;
}
return returnValue;
}
#endregion
}

View File

@ -0,0 +1,935 @@
using Ease.NetCore.DataAccess;
using Ease.NetCore.DataAccess.SQL;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
using MySqlX.XDevAPI.Common;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.MobileApp;
public class MobileMasterDataService : IMobileMasterDataService
{
private readonly AppSettings _settings;
private readonly IUserService _userService;
public MobileMasterDataService(IOptions<AppSettings> options, IUserService userService)
{
_settings = options.Value;
_userService = userService;
}
public async Task<MarketHeirarchyByEmpResponse> GetMarketHeirarchiesByEmpAsync(GetMarketHeirarchyByEmpRequest request)
{
MarketHeirarchyByEmpResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
string employeeNumber = request.EmployeeNumber;
response.Companies = await GetCompaniesByEmployeeNumberAsync(tc, employeeNumber);
response.SalesOrgs = await GetSalesOrgsByEmployeeNumberAsync(tc, employeeNumber);
response.DistributionChannels = await GetDistributionChannelsByEmployeeNumberAsync(tc, employeeNumber);
response.Regions = await GetRegionsByEmployeeNumberAsync(tc, employeeNumber);
response.Areas = await GetAreasByEmployeeNumberAsync(tc, employeeNumber);
response.Teritories = await GetTerritoriesByEmployeeNumberAsync(tc, employeeNumber);
response.Plants = await GetPlantsByEmployeeNumberAsync(tc, employeeNumber);
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<PagedResult<GetBrandResponse>> GetBrandsAsync(GetBrandsRequest request)
{
PagedResult<GetBrandResponse> response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@BrandCode", pType: SqlDbType.VarChar, pValue: request.BrandCode),
SqlHelperExtension.CreateInParam(pName: "@SalesOrganization", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetBrandsPaginated", parameterValues: p))
{
while (dr.Read())
{
response.Items.Add(new GetBrandResponse
{
BrandCode = dr.GetString(0),
BrandName = dr.GetString(1)
});
}
dr.Close();
response.TotalCount = response.Items.Count;
response.PageNumber = request.PageNumber;
response.PageSize = request.PageSize;
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<PagedResult<GetMaterialResponse>> GetMaterialsAsync(GetMaterialsRequest request)
{
PagedResult<GetMaterialResponse> response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@BrandCode", pType: SqlDbType.VarChar, pValue: request.BrandCode),
SqlHelperExtension.CreateInParam(pName: "@MaterialCode", pType: SqlDbType.VarChar, pValue: request.MaterialCode),
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetMaterialsPaginated", parameterValues: p))
{
while (dr.Read())
{
response.Items.Add(new GetMaterialResponse
{
MaterialCode = dr.GetString(0),
MaterialName = dr.GetString(1),
TypeCode = dr.GetString(2),
TypeName = dr.GetString(3),
GroupCode = dr.GetString(4),
GroupName = dr.GetString(5),
BaseUnitMeasurement = dr.GetString(6),
SalesUnitMeasurement = dr.GetString(7),
UnitConversionValue = dr.GetDecimal(8),
BrandCode = dr.GetString(9),
BrandName = dr.GetString(10),
SalesOrg = dr.GetString(11)
});
}
dr.Close();
response.TotalCount = response.Items.Count;
response.PageNumber = request.PageNumber;
response.PageSize = request.PageSize;
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<PagedResult<GetMaterialPriceResponse>> GetMaterialPricesAsync(GetMaterialPriceRequest request)
{
PagedResult<GetMaterialPriceResponse> response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@BrandCode", pType: SqlDbType.VarChar, pValue: request.BrandCode),
SqlHelperExtension.CreateInParam(pName: "@MaterialCode", pType: SqlDbType.VarChar, pValue: request.MaterialCode),
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetMaterialPricePaginated", parameterValues: p))
{
while (dr.Read())
{
response.Items.Add(new GetMaterialPriceResponse
{
SalesOrgCode = dr.GetString(0),
CustomerCode = dr.GetString(1),
MaterialCode = dr.GetString(2),
BasePrice = dr.GetDecimal(3)
});
}
dr.Close();
response.TotalCount = response.Items.Count;
response.PageNumber = request.PageNumber;
response.PageSize = request.PageSize;
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<PagedResult<GetCustomerResponse>> GetCustomersAsync(GetCustomersRequest request)
{
PagedResult<GetCustomerResponse> response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@TeritoryCode", pType: SqlDbType.VarChar, pValue: request.TeritoryCode),
SqlHelperExtension.CreateInParam(pName: "@CustomerCode", pType: SqlDbType.VarChar, pValue: request.CustomerCode),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetCustomersPaginated", parameterValues: p))
{
while (dr.Read())
{
response.Items.Add(new GetCustomerResponse
{
CustomerCode = dr.GetString(0),
CustomerName = dr.GetString(1),
AccountGroupCode = dr.GetString(2),
AccountGroupDescription = dr.GetString(3),
DistributionChannelCode = dr.GetString(4),
DistributionChannelName = dr.GetString(5),
DivisionCode = dr.GetString(6),
DivisionName = dr.GetString(7),
MobileNumber = dr.GetString(8),
EmailAddress = dr.GetString(9),
TaxNumber = dr.GetString(10),
SalesGroupCode = dr.GetString(11),
SalesGroupName = dr.GetString(12),
CustomerGroupCode = dr.GetString(13),
CustomerGroupName = dr.GetString(14),
CustomerPriceGroupCode = dr.GetString(15),
CustomerPriceGroupName = dr.GetString(16),
PaymentTermCode = dr.GetString(17),
TeritoryCode = dr.GetString(18),
SalesOrgCode = dr.GetString(19),
PlantCode = dr.GetString(20),
IsCreditCustomer = dr.GetInt32(21) > 0 ,
CreditLimit = dr.GetDecimal(22),
CreditBalance = dr.GetDecimal(23),
CreditOverdue = dr.GetDecimal(24),
});
}
dr.Close();
response.TotalCount = response.Items.Count;
response.PageNumber = request.PageNumber;
response.PageSize = request.PageSize;
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
private async Task<List<EmpCompanyResponse>> GetCompaniesByEmployeeNumberAsync(TransactionContext tc, string employeeNumber)
{
List<EmpCompanyResponse> response = [];
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.NVarChar, pValue: employeeNumber)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetCompaniesByEmployeeNumber", parameterValues: p))
{
while (dr.Read())
{
response.Add(new EmpCompanyResponse
{
CompanyCode = dr.GetString(0),
CompanyName = dr.GetString(1)
});
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private async Task<List<SalesOrgResponse>> GetSalesOrgsByEmployeeNumberAsync(TransactionContext tc, string employeeNumber)
{
List<SalesOrgResponse> response = [];
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.NVarChar, pValue: employeeNumber)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetSalesOrgsByEmployeeNumber", parameterValues: p))
{
while (dr.Read())
{
response.Add(new SalesOrgResponse
{
CompanyCode = dr.GetString(0),
SalesOrgCode = dr.GetString(1),
SalesOrgName = dr.GetString(2)
});
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private async Task<List<DistibutionChannleResponse>> GetDistributionChannelsByEmployeeNumberAsync(TransactionContext tc, string employeeNumber)
{
List<DistibutionChannleResponse> response = [];
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.NVarChar, pValue: employeeNumber)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetDistributionChannelsByEmployeeNumber", parameterValues: p))
{
while (dr.Read())
{
response.Add(new DistibutionChannleResponse
{
CompanyCode = dr.GetString(0),
SalesOrgCode = dr.GetString(1),
DistributorChannelCode = dr.GetString(2),
DistributorChannelName = dr.GetString(3)
});
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private async Task<List<RegionResponse>> GetRegionsByEmployeeNumberAsync(TransactionContext tc, string employeeNumber)
{
List<RegionResponse> response = [];
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.NVarChar, pValue: employeeNumber)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetRegionsByEmployeeNumber", parameterValues: p))
{
while (dr.Read())
{
response.Add(new RegionResponse
{
CompanyCode = dr.GetString(0),
SalesOrgCode = dr.GetString(1),
RegionCode = dr.GetString(2),
RegionName = dr.GetString(3)
});
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private async Task<List<AreaResponse>> GetAreasByEmployeeNumberAsync(TransactionContext tc, string employeeNumber)
{
List<AreaResponse> response = [];
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.NVarChar, pValue: employeeNumber)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetAreasByEmployeeNumber", parameterValues: p))
{
while (dr.Read())
{
response.Add(new AreaResponse
{
CompanyCode = dr.GetString(0),
SalesOrgCode = dr.GetString(1),
RegionCode = dr.GetString(2),
AreaCode = dr.GetString(3),
AreaName = dr.GetString(4)
});
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private async Task<List<TeritoryResponse>> GetTerritoriesByEmployeeNumberAsync(TransactionContext tc, string employeeNumber)
{
List<TeritoryResponse> response = [];
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.NVarChar, pValue: employeeNumber)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetTerritoriesByEmployeeNumber", parameterValues: p))
{
while (dr.Read())
{
response.Add(new TeritoryResponse
{
CompanyCode = dr.GetString(0),
SalesOrgCode = dr.GetString(1),
RegionCode = dr.GetString(2),
AreaCode = dr.GetString(3),
TeritoryCode = dr.GetString(4),
TeritoryName = dr.GetString(5)
});
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
private async Task<List<PlantResponse>> GetPlantsByEmployeeNumberAsync(TransactionContext tc, string employeeNumber)
{
List<PlantResponse> response = [];
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.NVarChar, pValue: employeeNumber)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetPlantsByEmployeeNumber", parameterValues: p))
{
while (dr.Read())
{
response.Add(new PlantResponse
{
CompanyCode = dr.GetString(0),
SalesOrgCode = dr.GetString(1),
PlantCode = dr.GetString(2),
PlantName = dr.GetString(3)
});
}
dr.Close();
}
}
catch (Exception ex)
{
throw DBCustomError.GenerateCustomError(ex);
}
return response;
}
public async Task<GetAttendanceByEmpResponse> GetAttendanceByEmpAsync(GetAttendanceByEmpRequest request)
{
GetAttendanceByEmpResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@AttendanceDate", pType: SqlDbType.Date, pValue: request.AttendanceDate)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetAttendanceByEmployee", parameterValues: p))
{
if (dr.Read())
{
response = MapToResponse(dr);
}
dr.Close();
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<GetAttendanceByEmpResponse> UpsertAttendanceByEmpAsync(UpsertAttendanceByEmpRequest request)
{
GetAttendanceByEmpResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode,true);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@AttendanceDate", pType: SqlDbType.Date, pValue: DateTime.Now),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@CheckInTime", pType: SqlDbType.DateTime, pValue: request.CheckInTime != null ? DateTime.Today.Add(request.CheckInTime.Value) : null),
SqlHelperExtension.CreateInParam(pName: "@CheckInLatitude", pType: SqlDbType.VarChar, pValue: request.CheckInLatitude),
SqlHelperExtension.CreateInParam(pName: "@CheckInLongitude", pType: SqlDbType.VarChar, pValue: request.CheckInLongitude),
SqlHelperExtension.CreateInParam(pName: "@CheckInLocationName", pType: SqlDbType.VarChar, pValue: request.CheckInLocationName),
SqlHelperExtension.CreateInParam(pName: "@CheckOutTime", pType: SqlDbType.DateTime, pValue: request.CheckOutTime != null ? DateTime.Today.Add(request.CheckOutTime.Value) : null),
SqlHelperExtension.CreateInParam(pName: "@CheckOutLatitude", pType: SqlDbType.VarChar, pValue: request.CheckOutLatitude),
SqlHelperExtension.CreateInParam(pName: "@CheckOutLongitude", pType: SqlDbType.VarChar, pValue: request.CheckOutLongitude),
SqlHelperExtension.CreateInParam(pName: "@CheckOutLocationName", pType: SqlDbType.VarChar, pValue: request.CheckOutLocationName)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.UpsertAttendanceByEmployee", parameterValues: p))
{
if (dr.Read())
{
response = MapToResponse(dr);
}
dr.Close();
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
private static GetAttendanceByEmpResponse MapToResponse(IDataReader dr)
{
return new GetAttendanceByEmpResponse
{
AttendanceDate = dr.GetDateTime(0),
EmployeeNumber = dr.GetString(1),
CheckInTime = dr.IsDBNull(2) ? null : dr.GetDateTime(2).TimeOfDay,
CheckInLatitude = dr.IsDBNull(3) ? null : dr.GetString(3),
CheckInLongitude = dr.IsDBNull(4) ? null : dr.GetString(4),
CheckInLocationName = dr.IsDBNull(5) ? null : dr.GetString(5),
CheckOutTime = dr.IsDBNull(6) ? null : dr.GetDateTime(6).TimeOfDay,
CheckOutLatitude = dr.IsDBNull(7) ? null : dr.GetString(7),
CheckOutLongitude = dr.IsDBNull(8) ? null : dr.GetString(8),
CheckOutLocationName = dr.IsDBNull(9) ? null : dr.GetString(9)
};
}
public async Task<PagedResult<GetDiscountResponse>> GetDiscountAsync(GetDiscountRequest request)
{
PagedResult<GetDiscountResponse> response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
SqlHelperExtension.CreateInParam(pName: "@CustomerCode", pType: SqlDbType.VarChar, pValue: request.CustomerCode),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@MaterialCode", pType: SqlDbType.VarChar, pValue: request.MaterialCode),
SqlHelperExtension.CreateInParam(pName: "@DiscountCode", pType: SqlDbType.VarChar, pValue: request.DiscountCode),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetDiscountPaginated", parameterValues: p))
{
while (dr.Read())
{
response.Items.Add(new GetDiscountResponse
{
SalesOrgcCode = dr.GetString(0),
DiscountCode = dr.GetString(1),
DiscountName = dr.GetString(2),
DistributorChannelCode = dr.GetString(3),
DistributorChannelName = dr.GetString(4),
CalculationType = dr.GetString(5)
});
}
dr.Close();
response.TotalCount = response.Items.Count;
response.PageNumber = request.PageNumber;
response.PageSize = request.PageSize;
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<PagedResult<GetDiscountMaterialResponse>> GetDiscountMaterialsAsync(GetDiscountMaterialRequest request)
{
PagedResult<GetDiscountMaterialResponse> response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
SqlHelperExtension.CreateInParam(pName: "@CustomerCode", pType: SqlDbType.VarChar, pValue: request.CustomerCode),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@MaterialCode", pType: SqlDbType.VarChar, pValue: request.MaterialCode),
SqlHelperExtension.CreateInParam(pName: "@DiscountCode", pType: SqlDbType.VarChar, pValue: request.DiscountCode),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetDiscountMaterialsPaginated", parameterValues: p))
{
while (dr.Read())
{
response.Items.Add(new GetDiscountMaterialResponse
{
DiscountCode = dr.GetString(0),
CustomerCode = dr.GetString(1),
MaterialCode = dr.GetString(2),
UnitOfMeasurement = dr.GetString(3),
CalculationType = dr.GetString(4),
DiscountValue = dr.GetDecimal(5),
StartDate = dr.GetDateTime(6),
EndDate = dr.GetDateTime(7),
});
}
dr.Close();
response.TotalCount = response.Items.Count;
response.PageNumber = request.PageNumber;
response.PageSize = request.PageSize;
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<PagedResult<GetFOCResponse>> GetFOCsAsync(GetFOCRequest request)
{
PagedResult<GetFOCResponse> response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
SqlHelperExtension.CreateInParam(pName: "@CustomerCode", pType: SqlDbType.VarChar, pValue: request.CustomerCode),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@MaterialCode", pType: SqlDbType.VarChar, pValue: request.MaterialCode),
SqlHelperExtension.CreateInParam(pName: "@DiscountCode", pType: SqlDbType.VarChar, pValue: request.FOCCode),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetFOCPaginated", parameterValues: p))
{
while (dr.Read())
{
response.Items.Add(new GetFOCResponse
{
SalesOrgcCode = dr.GetString(0),
FOCCode = dr.GetString(1),
FOCName = dr.GetString(2),
DistributorChannelCode = dr.GetString(3),
DistributorChannelName = dr.GetString(4)
});
}
dr.Close();
response.TotalCount = response.Items.Count;
response.PageNumber = request.PageNumber;
response.PageSize = request.PageSize;
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<PagedResult<GetFOCMaterialResponse>> GetFOCMaterialsAsync(GetFOCMaterialRequest request)
{
PagedResult<GetFOCMaterialResponse> response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
SqlHelperExtension.CreateInParam(pName: "@CustomerCode", pType: SqlDbType.VarChar, pValue: request.CustomerCode),
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: request.EmployeeNumber),
SqlHelperExtension.CreateInParam(pName: "@MaterialCode", pType: SqlDbType.VarChar, pValue: request.MaterialCode),
SqlHelperExtension.CreateInParam(pName: "@DiscountCode", pType: SqlDbType.VarChar, pValue: request.FOCCode),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetFOCMaterialsPaginated", parameterValues: p))
{
while (dr.Read())
{
response.Items.Add(new GetFOCMaterialResponse
{
FOCCode = dr.GetString(0),
CustomerCode = dr.GetString(1),
MaterialCode = dr.GetString(2),
UnitOfMeasurement = dr.GetString(3),
MinimumOrderQty = dr.GetDecimal(4),
ForQuantity = dr.GetDecimal(5),
FreeQty = dr.GetDecimal(6),
FOCUnitOfMeasurement = dr.GetString(7),
StartDate = dr.GetDateTime(8),
EndDate = dr.GetDateTime(9),
});
}
dr.Close();
response.TotalCount = response.Items.Count;
response.PageNumber = request.PageNumber;
response.PageSize = request.PageSize;
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<PagedResult<GetPaymentTermResponse>> GetPaymentTermsAsync(GetPaymentTermRequest request)
{
PagedResult<GetPaymentTermResponse> response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
SqlHelperExtension.CreateInParam(pName: "@PaymentTermCode", pType: SqlDbType.VarChar, pValue: request.PaymentTermCode),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetPaymentTermsPaginated", parameterValues: p))
{
while (dr.Read())
{
response.Items.Add(new GetPaymentTermResponse
{
PaymentTermId = dr.GetInt32(0),
PaymentTermCode = dr.GetString(1),
PaymentTermDescription = dr.GetString(2),
SalesOrgCode = dr.GetString(3),
StartDate = dr.GetDateTime(4),
EndDate = dr.GetDateTime(5),
PaymentTermType = dr.GetString(6),
});
}
dr.Close();
response.TotalCount = response.Items.Count;
response.PageNumber = request.PageNumber;
response.PageSize = request.PageSize;
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception)
{
throw;
}
return response;
}
}

View File

@ -0,0 +1,167 @@
using Ease.NetCore.DataAccess;
using Ease.NetCore.DataAccess.SQL;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.MobileApp;
public class OrderService : IOrderService
{
private readonly AppSettings _settings;
private readonly IUserService _userService;
private readonly IMobileMasterDataService _masterService;
public OrderService(IOptions<AppSettings> options, IUserService userService, IMobileMasterDataService masterService)
{
_settings = options.Value;
_userService = userService;
_masterService = masterService;
}
public async Task<SaveOrderResponse> SaveOrderAsync(SaveOrderRequest request)
{
SaveOrderResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode,true);
GetOrderByUUIDResponse order= await GetOrderByUUIDAsync(tc, request.UUID);
tc.End();
}
catch(Exception)
{
throw;
}
return new SaveOrderResponse()
{
OrderId = 12345,
OrderDate = DateTime.Now,
OrderNo = "Ord-000001-" + DateTime.Now.ToString("HH-mm-ss"),
UUID = request.UUID,
IsNewOrder =true
};
}
private async Task<GetOrderByUUIDResponse> GetOrderByUUIDAsync(TransactionContext tc, string uuid)
{
GetOrderByUUIDResponse response = null;
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@UUID", pType: SqlDbType.UniqueIdentifier, pValue: uuid)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetOrderDetailsByUUID", parameterValues: p))
{
// Result Set 1: Order Header
if (dr.Read())
{
response = new GetOrderByUUIDResponse
{
OrderId = dr.GetInt32(0),
OrderNo = dr.GetString(1),
OrderDate = dr.GetDateTime(2),
ExpectedSalesDate = dr.IsDBNull(3) ? null : dr.GetDateTime(3),
UUID = dr.GetGuid(4),
SalesOrgCode = dr.GetString(5),
CustomerId = dr.GetInt32(6),
CustomerCode = dr.GetString(7),
CustomerName = dr.GetString(8),
EmployeeId = dr.GetInt32(9),
EmployeeCode = dr.GetString(10),
EmployeeName = dr.GetString(11),
PaymentTermCode = dr.GetString(12),
ReferenceTxtNo = dr.IsDBNull(13) ? null : dr.GetString(13),
GrossValue = dr.GetDecimal(14),
DiscountValue = dr.GetDecimal(15),
FOCValue = dr.GetDecimal(16),
NetValue = dr.GetDecimal(17),
OrderStatus = dr.GetString(18),
SAPReferenceOrderNo = dr.IsDBNull(19) ? null : dr.GetString(19)
};
}
if (response != null && dr.NextResult())
{
while (dr.Read())
{
GetOrderItemResponse item = new()
{
ItemId = dr.GetInt32(0),
OrderID = dr.GetInt32(1),
MaterialId = dr.GetInt32(2),
MaterialCode = dr.GetString(3),
MaterialName = dr.GetString(4),
UnitPrice = dr.GetDecimal(5),
SalesUnit = dr.GetString(6),
OrderQuantity = dr.GetDecimal(7),
ValidatedQuantity = dr.GetDecimal(8),
ApprovedQuantity = dr.GetDecimal(9),
DiscountPercentage = dr.GetDecimal(10),
DiscountValue = dr.GetDecimal(11),
IsFOCItem = dr.GetBoolean(12),
OrderFocQuantity = dr.GetDecimal(13),
ValidatedFocQuantity = dr.GetDecimal(14),
ApprovedFocQuantity = dr.GetDecimal(15),
LineTotalValue = dr.GetDecimal(16),
};
response.Items.Add(item);
}
}
// Result Set 3: Promotions (attach to matching item)
if (response != null && dr.NextResult())
{
while (dr.Read())
{
GetOrderPromotionResponse promotion = new()
{
ItemId = dr.GetInt32(0),
OrderID = dr.GetInt32(1),
MaterialId = dr.GetInt32(2),
PromotionCode = dr.GetString(3),
DiscountPercentage = dr.GetDecimal(4),
DiscountValue = dr.GetDecimal(5),
ForQuantity = dr.GetDecimal(6),
OrderFocQuantity = dr.GetDecimal(7),
ValidatedFocQuantity = dr.GetDecimal(8),
ApprovedFocQuantity = dr.GetDecimal(9),
PromotionType = dr.GetInt32(10),
};
response.Promotions.Add(promotion);
}
}
dr.Close();
}
tc.End();
}
catch (Exception)
{
throw;
}
return response;
}
}

View File

@ -1,28 +1,32 @@
using Ease.NetCore.DataAccess;
using Ease.NetCore.DataAccess.SQL;
using Ease.NetCore.Utility;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
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.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
{
public class UserService(IOptions<AppSettings> settings, IOptions<MenuSettings> menuSettings) : IUserService
public class UserService(IOptions<AppSettings> settings, IOptions<MenuSettings> menuSettings, IRefreshTokenService refreshTokenService) : IUserService
{
private readonly AppSettings _settings = settings?.Value;
private readonly MenuSettings _menuSettings = menuSettings?.Value;
private readonly IRefreshTokenService _refreshTokenService = refreshTokenService;
/// <summary>
///
@ -348,6 +352,196 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
}
public async Task<AppAuthUserResponse> LoginAsync(MobileAppAuthRequest request, string ipAddress)
{
AppAuthUserResponse response = null;
try
{
string password = EncryptPassword(password: request.Password);
User user = null;
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
try
{
DateTime sysDate = DateTime.Today.Date;
string appVer = string.Empty, alParams = string.Empty;
int maxTryCount = 5, lockTime = 1;
bool initialPassword = false;
#region Read User data using authentication data
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.NVarChar, pValue: request.LoginId)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetUserByLogin", parameterValues: p))
{
if (dr.Read())
{
user = new User();
{
user.UserId = dr.GetInt32(0);
user.Password = dr.GetString(1);
user.LoginId = dr.GetString(2);
user.UserName = dr.GetString(3);
user.Status = (EnumStatus)dr.GetInt32(4);
user.MobileNo = dr.GetString(5);
user.EmailAddress = dr.GetString(6);
user.AuthKey = dr.GetString(7);
user.AuthValue = dr.GetString(8);
user.IsLocked = dr.GetBoolean(9);
user.LoginStatus = EnumLoginStatus.Success;
user.UserRoleType = (UserRoleTypeEnum)dr.GetInt32(10);
user.EmployeeNumber = dr.GetString(11);
user.DesignationCode = dr.GetString(12);
user.DesignationName = dr.GetString(13);
};
initialPassword = dr.GetInt32(14) > 0;
}
dr.Close();
}
if (user is null)
{
tc.End();
response = new();
response.IsAuthorized = true;
return response;
}
if (!password.Equals(user.Password))
{
tc.End();
response = new();
response.IsAuthorized = false;
response.LoginStatus = EnumLoginStatus.Unsuccessful;
return response;
}
#endregion
#region If the user was locked, try set set unlock if Time expired
if (!request.LoginId.ToLower().Equals(User.SuperUser_LoginId) && user.IsLocked)
{
int isSuccessful = 0;
p =
[
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: request.LoginId, size: 30),
SqlHelperExtension.CreateInParam(pName: "@LockTime", pType: SqlDbType.Int, pValue: lockTime),
SqlHelperExtension.CreateOutParam(pName: "@IsSuccessful", pType: SqlDbType.Int, pValue: isSuccessful),
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.DoUnlockUser", parameterValues: p);
if (p[2] != null && p[2].Value != null && p[2].Value != DBNull.Value)
isSuccessful = Convert.ToInt32(p[2].Value);
if (isSuccessful == 1)
user.IsLocked = false;
}
#endregion
#region Keep log for unauthrise access and Set user lock if exceeds max try
if (!request.LoginId.ToLower().Equals(User.SuperUser_LoginId) && maxTryCount > 0 && user.LoginStatus == EnumLoginStatus.Unsuccessful)
{
int remainsTry = 0;
DateTime? nextLoginTime = null;
string tryLoginInfo = $"{request.LoginId}~{password}~13";
p =
[
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: request.LoginId, size: 30),
SqlHelperExtension.CreateInParam(pName: "@TryLoginInfo", pType: SqlDbType.VarChar, pValue: tryLoginInfo, size: 100),
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: ipAddress, size: 20),
SqlHelperExtension.CreateInParam(pName: "@MaxTryCount", pType: SqlDbType.SmallInt, pValue: maxTryCount),
SqlHelperExtension.CreateInParam(pName: "@LockTime", pType: SqlDbType.Int, pValue: lockTime),
SqlHelperExtension.CreateOutParam(pName: "@RemainingTry", pType: SqlDbType.SmallInt, pValue: remainsTry),
SqlHelperExtension.CreateOutParam(pName: "@NextLoginTime", pType: SqlDbType.DateTime, pValue: nextLoginTime),
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.LogUnauthorizeAccess", parameterValues: p);
if (p[5] != null && p[5].Value != null && p[5].Value != DBNull.Value)
remainsTry = Convert.ToInt32(p[5].Value);
if (p[6] != null && p[6].Value != null && p[6].Value != DBNull.Value)
nextLoginTime = Convert.ToDateTime(p[6].Value);
if (remainsTry <= 0)
{
user.IsLocked = true;
if (lockTime <= 0)
{
user.NextLoginTime = nextLoginTime;
user.UnsuccessfulMsg = "Please contact with Head office to Unlock";
}
else
{
user.NextLoginTime = nextLoginTime;
user.UnsuccessfulMsg = $"You can Login after {user.NextLoginTime:dd-MMM-yyyy H:mm:ss}";
}
}
else
{
user.UnsuccessfulMsg = $"{remainsTry} More attempt{(remainsTry > 1 ? "s" : "")} remaining";
}
}
#endregion
#region If login successful and user is active read module id for this user
if (user.LoginStatus == EnumLoginStatus.Success && user.Status == EnumStatus.Authorized && !user.IsLocked)
{
p =
[
SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: user.UserId),
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: user.LoginId, size: 30),
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: ipAddress, size: 20),
SqlHelperExtension.CreateInParam(pName: "@LoginTime", pType: SqlDbType.DateTime, pValue: DateTime.Now),
SqlHelperExtension.CreateInParam(pName: "@LogoutTime", pType: SqlDbType.DateTime, pValue: null)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.SaveAccessLog", parameterValues: p);
}
#endregion
response = new()
{
UserId = user.UserId,
Name = user.UserName,
LoginId = user.LoginId,
Email = user.EmailAddress,
MobileNumber = user.MobileNo,
IsLocked = user.IsLocked,
UserRole = user.UserRoleType.Value,
LoginStatus = user.LoginStatus,
IsAuthorized = EnumStatus.Authorized == user.Status,
EmployeeNumber = user.EmployeeNumber,
DesignationCode = user.DesignationCode,
DesignationName = user.DesignationName,
IsInitialPassword = initialPassword
};
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception e)
{
throw new InvalidOperationException(e.Message, e);
}
return response;
}
public async Task<User> IntegrationLoginAsync(IntegrationLoginRequest request, string ipAddress, bool checkPwd)
{
User user = null;
@ -365,7 +559,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
#region Read User data using authentication data
string commandText = SQLParser.MakeSQL("SELECT UserId,Password,LoginId, UserName, Status, ISNULL(MobileNo,'')MobileNo ,ISNULL( EmailAddress,'')EmailAddress,"
+ " ISNULL(AuthKey,'') AuthKey, ISNULL(AuthValue,'')AuthValue, IsLocked FROM Users WHERE LoginID=%s", request.LoginId);
+ " ISNULL(AuthKey,'') AuthKey, ISNULL(AuthValue,'')AuthValue, IsLocked FROM Users WHERE LoginID=%s and UserPlatformId=1 ", request.LoginId);
using (IDataReader dr = tc.ExecuteReader(commandText: commandText))
{
@ -481,7 +675,8 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: user.UserId),
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: user.LoginId, size: 30),
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: ipAddress, size: 20),
SqlHelperExtension.CreateInParam(pName: "@LoginTime", pType: SqlDbType.DateTime, pValue: DateTime.Now)
SqlHelperExtension.CreateInParam(pName: "@LoginTime", pType: SqlDbType.DateTime, pValue: DateTime.Now),
SqlHelperExtension.CreateInParam(pName: "@LogoutTime", pType: SqlDbType.DateTime, pValue: null)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.SaveAccessLog", parameterValues: p);
@ -505,6 +700,8 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
return user;
}
/// <summary>
///
/// </summary>
@ -2231,6 +2428,206 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
return returnValue;
}
public async Task<AuthLogoutResponse> LogoutAsync(AuthLogoutRequest request, string ipAddress)
{
AuthLogoutResponse response = null;
try
{
User user = null;
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
try
{
DateTime sysDate = DateTime.Today.Date;
string appVer = string.Empty, alParams = string.Empty;
#region Read User data using authentication data
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.NVarChar, pValue: request.LoginId)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetUserByLogin", parameterValues: p))
{
if (dr.Read())
{
user = new User();
{
user.UserId = dr.GetInt32(0);
user.Password = dr.GetString(1);
user.LoginId = dr.GetString(2);
user.UserName = dr.GetString(3);
user.Status = (EnumStatus)dr.GetInt32(4);
user.MobileNo = dr.GetString(5);
user.EmailAddress = dr.GetString(6);
user.AuthKey = dr.GetString(7);
user.AuthValue = dr.GetString(8);
user.IsLocked = dr.GetBoolean(9);
user.LoginStatus = EnumLoginStatus.Success;
user.UserRoleType = (UserRoleTypeEnum)dr.GetInt32(10);
user.EmployeeNumber = dr.GetString(11);
user.DesignationCode = dr.GetString(12);
user.DesignationName = dr.GetString(13);
}
;
}
dr.Close();
}
if (user is null)
{
tc.End();
throw new InvalidOperationException($"User not found with login: {request.LoginId}");
}
#endregion
#region If login successful and user is active read module id for this user
if (user.LoginStatus == EnumLoginStatus.Success && user.Status == EnumStatus.Authorized && !user.IsLocked)
{
p =
[
SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: user.UserId),
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: user.LoginId, size: 30),
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: ipAddress, size: 20),
SqlHelperExtension.CreateInParam(pName: "@LoginTime", pType: SqlDbType.DateTime, pValue: null),
SqlHelperExtension.CreateInParam(pName: "@LogoutTime", pType: SqlDbType.DateTime, pValue: DateTime.Now)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.SaveAccessLog", parameterValues: p);
}
#endregion
await _refreshTokenService.InvalidRefreshTokenAsync(tc, user.UserId);
response = new()
{
UserId = user.UserId,
LoginId = user.LoginId,
IsSuccess = true
};
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception e)
{
throw new InvalidOperationException(e.Message, e);
}
return response;
}
public async Task<AppChangePasswordResponse> ChangePasswordAsync(AppUserChangePasswordRequest request, string ipAddress)
{
AppChangePasswordResponse response = null;
try
{
string password = EncryptPassword(password: request.Password);
User user = null;
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
try
{
DateTime sysDate = DateTime.Today.Date;
string appVer = string.Empty, alParams = string.Empty;
#region Read User data using authentication data
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.NVarChar, pValue: request.LoginId)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetUserByLogin", parameterValues: p))
{
if (dr.Read())
{
user = new User();
{
user.UserId = dr.GetInt32(0);
user.Password = dr.GetString(1);
user.LoginId = dr.GetString(2);
user.UserName = dr.GetString(3);
user.Status = (EnumStatus)dr.GetInt32(4);
user.MobileNo = dr.GetString(5);
user.EmailAddress = dr.GetString(6);
user.AuthKey = dr.GetString(7);
user.AuthValue = dr.GetString(8);
user.IsLocked = dr.GetBoolean(9);
user.LoginStatus = EnumLoginStatus.Success;
user.UserRoleType = (UserRoleTypeEnum)dr.GetInt32(10);
user.EmployeeNumber = dr.GetString(11);
user.DesignationCode = dr.GetString(12);
user.DesignationName = dr.GetString(13);
}
;
}
dr.Close();
}
if (user is null)
{
tc.End();
throw new InvalidOperationException($"User not found with login: {request.LoginId}");
}
if (!password.Equals(user.Password))
{
tc.End();
throw new InvalidOperationException($"Password mismatch for login: {request.LoginId}");
}
#endregion
string newPassword = EncryptPassword(request.ConfirmPassword);
p =
[
SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: user.UserId),
SqlHelperExtension.CreateInParam(pName: "@Password", pType: SqlDbType.NVarChar, pValue: newPassword, size: 50),
SqlHelperExtension.CreateInParam(pName: "@LastPassword", pType: SqlDbType.NVarChar, pValue: password, size: 50),
SqlHelperExtension.CreateInParam(pName: "@LastPasswordChnageDate", pType: SqlDbType.DateTime, pValue: DateTime.Now)
];
_ = tc.ExecuteNonQuerySp(spName: "dbo.ChangePassword", parameterValues: p);
response = new()
{
UserId = user.UserId,
LoginId = user.LoginId,
IsSuccess = true
};
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception e)
{
throw new InvalidOperationException(e.Message, e);
}
return response;
}
/// <summary>
///
/// </summary>
@ -2635,12 +3032,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
throw new NotImplementedException();
}
#endregion
}
internal class UserSearchResponse
{
}
}

View File

@ -1,10 +1,12 @@
using Microsoft.Extensions.DependencyInjection;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Setups;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.Auth;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.Setups;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems;
@ -31,6 +33,8 @@ namespace OnlineSalesAutoCrop.CoreAPI.Configuration.DI
services.AddTransient<IAuthModulesService, AuthModulesService>();
services.AddTransient<IRefreshTokenService, RefreshTokenService>();
services.AddScoped<IIntegrationService, IntegrationService>();
services.AddScoped<IMobileMasterDataService, MobileMasterDataService>();
services.AddScoped<IOrderService, OrderService>();
}
}
}

View File

@ -230,7 +230,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers
loginReponse.AccessToken = userToken;
loginReponse.RefreshToken = refreshToken.RefreshToken;
loginReponse.AccessTokenExpiry = refreshToken.ExpireTime;
return StatusCode(StatusCodes.Status431RequestHeaderFieldsTooLarge, loginReponse);
return StatusCode(StatusCodes.Status200OK, loginReponse);
}
catch (Exception ex)
@ -295,7 +295,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers
response.AccessToken = userToken;
response.RefreshToken = refreshToken;
return StatusCode(StatusCodes.Status431RequestHeaderFieldsTooLarge, response);
return StatusCode(StatusCodes.Status200OK, response);
}
catch (Exception ex)

View File

@ -0,0 +1,319 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using OnlineSalesAutoCrop.CoreAPI;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
using System;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Controllers
{
/// <summary>
///
/// </summary>
/// <remarks>
///
/// </remarks>
/// <param name="logger"></param>
/// <param name="integrationService"></param>
[Authorize]
[ApiController]
[ApiVersion("1.0")]
[ValidateAntiForgeryToken]
[Route("api/v{version:apiVersion}/Integration")]
public class IntegrationController(ILogger<IntegrationAuthController> logger, IIntegrationService integrationService) : ControllerBase
{
private readonly ILogger _logger = logger;
private readonly IIntegrationService _integrationService = integrationService;
/// <summary>
/// Insert or Update Customers for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("Customers")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationLoginResponse))]
public async Task<IActionResult> UpsertCustomers(IntegrationCustomerRequest request)
{
IntegrationCustomerResponse response = new IntegrationCustomerResponse();
try
{
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;
return StatusCode(StatusCodes.Status201Created, response);
}
else
{
response.ReturnMessage.Add($"Customer Updated Successfully for CustomerNumber :{request.CustomerNumber} & CompanyCode:{request.CompanyCode}");
response.ReturnStatus = StatusCodes.Status200OK;
return StatusCode(StatusCodes.Status200OK, response);
}
}
catch (Exception ex)
{
string msg = $"Exception Occur in Customer Operation {request?.CustomerName}~{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);
}
}
/// <summary>
/// Insert or Update Employees for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("Employees")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(EmployeeIntegrationReqResponse))]
public async Task<IActionResult> UpsertEmployee(IntegrationEmployeeRequest 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);
}
}
/// <summary>
/// Insert or Update Material for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("Materials")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MaterialIntegrationReqResponse))]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(MaterialIntegrationReqResponse))]
public async Task<IActionResult> UpsertMeterial(IntegrationMaterialRequest 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);
}
}
/// <summary>
/// Insert or Update Material Prices for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("MaterialPrices")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MaterialIntegrationPriceReqResponse))]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(MaterialIntegrationPriceReqResponse))]
public async Task<IActionResult> UpsertMeterialPrices(IntegrationMaterialPriceRequest request)
{
MaterialIntegrationPriceReqResponse response = new MaterialIntegrationPriceReqResponse();
try
{
response = await _integrationService.UpsertMaterialPriceAsync(request);
if (!response.IsUpdated)
{
response.ReturnMessage.Add($"Material Price Created Successfully for MaterialCode :{request.MaterialCode} And ConditionType : {request.ConditionType}" +
$"And Customer Number : {request.CustomerNumber} And Customer Group Code : {request.CustomerGroupCode} ");
response.ReturnStatus = StatusCodes.Status201Created;
return StatusCode(StatusCodes.Status201Created, response);
}
else
{
response.ReturnMessage.Add($"Material Price Updated Successfully for MaterialCode :{request.MaterialCode} And ConditionType : {request.ConditionType}" +
$"And Customer Number : {request.CustomerNumber} And Customer Group Code : {request.CustomerGroupCode} ");
response.ReturnStatus = StatusCodes.Status200OK;
return StatusCode(StatusCodes.Status200OK, response);
}
}
catch (Exception ex)
{
string msg = $"Exception Occur in Material Price Operation MaterialCode :{request.MaterialCode} And ConditionType : {request.ConditionType}" +
$"And Customer Number : {request.CustomerNumber} And Customer Group Code : {request.CustomerGroupCode} ";
_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);
}
}
/// <summary>
/// Insert or Update Material Prices for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("MaterialFreeGoods")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MaterialFreeGoodsByReqResponse))]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(MaterialFreeGoodsByReqResponse))]
public async Task<IActionResult> UpsertMaterialFreeGoods(IntegrationMaterialFreeGoodsRequest request)
{
MaterialFreeGoodsByReqResponse response = new MaterialFreeGoodsByReqResponse();
try
{
response = await _integrationService.UpsertMaterialFreeGoodsAsync(request);
if (!response.IsUpdated)
{
response.ReturnMessage.Add($"Material Free Goods Created Successfully for SalesOrg :{request.SalesOrg} " +
$"And CustomerPriceGroup : {request.CustomerPriceGroup} And MaterialCode : {request.MaterialCode} And DistributorChannel : {request.DistributionChannel}" +
$" And Customer Number :{request.CustomerNumber} And Customer Price Group : {request.CustomerPriceGroup}");
response.ReturnStatus = StatusCodes.Status201Created;
return StatusCode(StatusCodes.Status201Created, response);
}
else
{
response.ReturnMessage.Add($"Material Free Goods Updated Successfully for SalesOrg :{request.SalesOrg} " +
$"And CustomerPriceGroup : {request.CustomerPriceGroup} And MaterialCode : {request.MaterialCode} And DistributorChannel : {request.DistributionChannel}" +
$" And Customer Number :{request.CustomerNumber} And Customer Price Group : {request.CustomerPriceGroup}");
response.ReturnStatus = StatusCodes.Status200OK;
return StatusCode(StatusCodes.Status200OK, response);
}
}
catch (Exception ex)
{
string msg = $"Exception Occur in Material Free Goods Operation SalesOrg :{request.SalesOrg} " +
$" And CustomerPriceGroup : {request.CustomerPriceGroup} And MaterialCode : {request.MaterialCode} And DistributorChannel : {request.DistributionChannel}" +
$" And Customer Number :{request.CustomerNumber} And Customer Price Group : {request.CustomerPriceGroup}";
_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);
}
}
/// <summary>
/// Insert or Update Payment Terms for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("PaymentTerms")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationPaymentTermReqResponse))]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(IntegrationPaymentTermReqResponse))]
public async Task<IActionResult> UpsertPaymentTerms(IntegrationPaymentTermRequest request)
{
IntegrationPaymentTermReqResponse response = new IntegrationPaymentTermReqResponse();
try
{
response = await _integrationService.UpsertPaymentTermsAsync(request);
if (!response.IsUpdated)
{
response.ReturnMessage.Add($"Payment Terms Created Successfully for SalesOrg :{request.SalesOrg} " +
$"And CreditCode : {request.CreditCode} ");
response.ReturnStatus = StatusCodes.Status201Created;
return StatusCode(StatusCodes.Status201Created, response);
}
else
{
response.ReturnMessage.Add($"Payment Terms Updated Successfully for SalesOrg :{request.SalesOrg} " +
$"And CreditCode : {request.CreditCode} ");
response.ReturnStatus = StatusCodes.Status200OK;
return StatusCode(StatusCodes.Status200OK, response);
}
}
catch (Exception ex)
{
string msg = $"Exception Occur in Payment Terms for SalesOrg :{request.SalesOrg} " +
$"And CreditCode : {request.CreditCode} ";
_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);
}
}
/// <summary>
/// Insert Invoices for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("Invoices")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationInvoiceReqResponse))]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(IntegrationInvoiceReqResponse))]
public async Task<IActionResult> SaveInvoices(IntegrationInvoiceRequest request)
{
IntegrationInvoiceReqResponse response = new IntegrationInvoiceReqResponse();
try
{
response = await _integrationService.SaveInvoiceAsync(request);
response.ReturnMessage.Add($"Successfully Save the Invoices for InvoiceNo :{request.InvoiceDocumentNo} " +
$"And InvoiceDate : {request.InvoiceDate} ");
response.ReturnStatus = StatusCodes.Status201Created;
return StatusCode(StatusCodes.Status201Created, response);
}
catch (Exception ex)
{
string msg = $"Exception Occur in Invoices for InvoiceNo :{request.InvoiceDocumentNo} " +
$"And InvoiceDate : {request.InvoiceDate} " ;
_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);
}
}
}
}

View File

@ -1,153 +0,0 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
using System;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi
{
/// <summary>
///
/// </summary>
/// <remarks>
///
/// </remarks>
/// <param name="logger"></param>
/// <param name="integrationService"></param>
[Authorize]
[ApiController]
[ApiVersion("1.0")]
[ValidateAntiForgeryToken]
[Route("api/v{version:apiVersion}/Integration")]
public class IntegrationController(ILogger<IntegrationAuthController> logger, IIntegrationService integrationService) : ControllerBase
{
private readonly ILogger _logger = logger;
private readonly IIntegrationService _integrationService = integrationService;
/// <summary>
/// Insert or Update Customers for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("Customers")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationLoginResponse))]
public async Task<IActionResult> UpsertCustomers(CustomerIntegrationRequest request)
{
CustomerIntegrationResponse response = new CustomerIntegrationResponse();
try
{
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;
return StatusCode(StatusCodes.Status201Created, response);
}
else
{
response.ReturnMessage.Add($"Customer Updated Successfully for CustomerNumber :{request.CustomerNumber} & CompanyCode:{request.CompanyCode}");
response.ReturnStatus = StatusCodes.Status200OK;
return StatusCode(StatusCodes.Status200OK, response);
}
}
catch (Exception ex)
{
string msg = $"Exception Occur in Customer Operation {request?.CustomerName}~{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);
}
}
/// <summary>
/// Insert or Update Employees for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("Employees")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(EmployeeIntegrationReqResponse))]
public async Task<IActionResult> 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);
}
}
/// <summary>
/// Insert or Update Material for SAP
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>if created return 201 or if updated return 200 true</returns>
[HttpPost("Materials")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MaterialIntegrationReqResponse))]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(MaterialIntegrationReqResponse))]
public async Task<IActionResult> 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);
}
}
}
}

View File

@ -0,0 +1,306 @@
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;
using OnlineSalesAutoCrop.CoreAPI.Models;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Controllers
{
/// <summary>
///
/// </summary>
/// <remarks>
///
/// </remarks>
/// <param name="service"></param>
/// <param name="appSettings"></param>
/// <param name="cache"></param>
/// <param name="logger"></param>
/// <param name="refreshTokenService"></param>
[Authorize]
[ApiController]
[ApiVersion("1.0")]
[ValidateAntiForgeryToken]
[Route("api/mobile/v{version:apiVersion}/auth")]
public class MobileAuthController(IUserService service, IOptions<AppSettings> appSettings, IEaseCache cache, ILogger<MobileAuthController> logger,
IRefreshTokenService refreshTokenService) : ControllerBase
{
private readonly ILogger _logger = logger;
private readonly IEaseCache _cache = cache;
private readonly IUserService _service = service;
private readonly IRefreshTokenService _refreshTokenService = refreshTokenService;
private readonly AppSettings _appSettings = appSettings?.Value;
private readonly DateTimeOffset _options = Helper.CreateEaseCacheOptions();
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>If login successful ValidUser: true</returns>
/// <response code="200">If login successful Return ValidUser: true and UserName: not empty</response>
[HttpPost("Login")]
[AllowAnonymous]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MobileAppAuthRequest))]
public async Task<IActionResult> Login([FromBody] MobileAppAuthRequest request)
{
ArgumentNullException.ThrowIfNull(request);
AppAuthUserResponse loginReponse = new();
if (string.IsNullOrEmpty(request.LoginId))
{
string message = "Login ID is required.";
return BadRequest(MobileResponseBase<AppAuthUserResponse>.Failure(message, StatusCodes.Status400BadRequest));
}
if (string.IsNullOrEmpty(request.Password))
{
string message = "Password is required.";
return BadRequest(MobileResponseBase<AppAuthUserResponse>.Failure(message, StatusCodes.Status400BadRequest));
}
string ipAddress = string.Empty;
try
{
#region Decrypt LoginID
string cipherSecretKey = GlobalFunctions.ConvertFromBase64String(_appSettings.CipherSecretKey);
#endregion
bool checkPwd = true;
ipAddress = Request.HttpContext.GetIpAddress();
loginReponse = await _service.LoginAsync(request: request, ipAddress: ipAddress);
if (loginReponse == null || loginReponse.UserId == 0)
{
string message = "Login ID/Password is invalid.\" : \"You are not Authorized to login into the System.";
return Unauthorized(MobileResponseBase<AppAuthUserResponse>.Failure(message, StatusCodes.Status401Unauthorized));
}
if (loginReponse.LoginStatus == EnumLoginStatus.Unsuccessful)
{
string message = checkPwd ? $"Login ID/Password is invalid for {request.LoginId}." : "You are not Authorized to login into the System";
return Unauthorized(MobileResponseBase<AppAuthUserResponse>.Failure(message, StatusCodes.Status401Unauthorized));
}
if (loginReponse.IsLocked)
{
string message =$"Your Account is locked . Please try again after few minutes";
return Unauthorized(MobileResponseBase<AppAuthUserResponse>.Failure(message, StatusCodes.Status401Unauthorized));
}
if (!loginReponse.IsAuthorized )
{
string message = $"You are not Authorized to Login into the System, Please contact with System Administrator.";
return Unauthorized(MobileResponseBase<AppAuthUserResponse>.Failure(message, StatusCodes.Status401Unauthorized));
}
string pwdSecretKey = GlobalFunctions.ConvertFromBase64String(_appSettings.PwdSecretKey);
string userPwd = Ease.NetCore.Utility.Global.CipherFunctions.EncryptByAES(privateKey: pwdSecretKey, publicKey: pwdSecretKey, data: request.Password);
byte[] key = Encoding.ASCII.GetBytes(_appSettings.JwtCryptoKey);
JwtSecurityTokenHandler tokenHandler = new();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(
[
Helper.CreateClaim("LoginId", loginReponse.LoginId),
Helper.CreateClaim("Email", loginReponse.Email),
Helper.CreateClaim("Mobile", $"{loginReponse.MobileNumber}"),
Helper.CreateClaim("HashKey", Guid.NewGuid().ToString())
]),
Expires = DateTime.UtcNow.AddMinutes(_appSettings.AccessTokenDuration),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
};
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);
string userToken = tokenHandler.WriteToken(token);
GenerateRefreshTokenRequest refreshTokenRequest = new GenerateRefreshTokenRequest()
{
UserId = loginReponse.UserId,
IpAddress = ipAddress,
RawRefreshToken = string.Empty
};
var refreshToken = await _refreshTokenService.GenerateRefreshTokenByUserAsync(refreshTokenRequest);
//If token length is greater than or equal to 4096 (4KB) then return error
//because cookie can not store more than 4KB data and we are storing this token in cookie for authentication
if (userToken.Length >= 4096) //4Kb
{
string message = $"Authentication Token is too large for cookie.";
return StatusCode(StatusCodes.Status431RequestHeaderFieldsTooLarge, MobileResponseBase<AppAuthUserResponse>.Failure(message, StatusCodes.Status431RequestHeaderFieldsTooLarge));
}
loginReponse.LoginId = loginReponse.LoginId;
loginReponse.AccessToken = userToken;
loginReponse.RefreshToken = refreshToken.RefreshToken;
loginReponse.AccessTokenExpiryTime = DateTime.UtcNow.AddHours(12);
loginReponse.RefreshTokenExpiryTime = refreshToken.ExpireTime;
return Ok(MobileResponseBase<AppAuthUserResponse>.Success(loginReponse));
}
catch (Exception ex)
{
string msg = $"{request?.LoginId}~{ipAddress}";
_logger.LogError(exception: ex, message: msg);
string mesgae= ex.InnerException != null ? ex.InnerException.Message : ex.Message;
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(mesgae, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>If login successful ValidUser: true</returns>
/// <response code="200">If login successful Return ValidUser: true and UserName: not empty</response>
[HttpPost("RefreshToken")]
[AllowAnonymous]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MobileRrefreshTokenResponse))]
public async Task<IActionResult> GetRefreshToken([FromBody] IntegrationRefreshTokenRequest request)
{
MobileRrefreshTokenResponse response = new();
try
{
var userRefreshToken = await _refreshTokenService.GetUserByRefreshTokenAsync(request.RefreshToken);
if (!userRefreshToken.IsActive)
{
string msg = $"Refresh Token is not active: {request?.RefreshToken}";
_logger.LogError(message: msg);
return Unauthorized( MobileResponseBase<AppAuthUserResponse>.Failure(msg, StatusCodes.Status401Unauthorized));
}
byte[] key = Encoding.ASCII.GetBytes(_appSettings.JwtCryptoKey);
JwtSecurityTokenHandler tokenHandler = new();
var tokenDescriptor = new SecurityTokenDescriptor
{
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 Ok(MobileResponseBase<MobileRrefreshTokenResponse>.Success(response));
}
catch (Exception ex)
{
string msg = $"{request?.RefreshToken}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>If login successful ValidUser: true</returns>
/// <response code="200">If login successful Return ValidUser: true and UserName: not empty</response>
[HttpPost("Logout")]
[Authorize]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AuthLogoutResponse))]
public async Task<IActionResult> Logout([FromBody] AuthLogoutRequest request)
{
AuthLogoutResponse response = new();
try
{
string ipAddress = Request.HttpContext.GetIpAddress();
response = await _service.LogoutAsync(request, ipAddress);
return Ok(MobileResponseBase<AuthLogoutResponse>.Success(response, "Successfully Logout"));
}
catch (Exception ex)
{
string msg = $"Exception occur on logout {request?.LoginId}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <returns>If login successful ValidUser: true</returns>
/// <response code="200">If login successful Return ValidUser: true and UserName: not empty</response>
[HttpPost("ChangePassword")]
[Authorize]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AppChangePasswordResponse))]
public async Task<IActionResult> ChangePassword([FromBody] AppUserChangePasswordRequest request)
{
AppChangePasswordResponse response = new();
try
{
if(request.Password.Equals(request.ConfirmPassword))
{
string msg = $"You can't use your old password as your new password.";
_logger.LogError(message: msg);
return BadRequest(MobileResponseBase<AppAuthUserResponse>.Failure(msg, StatusCodes.Status400BadRequest));
}
string ipAddress = Request.HttpContext.GetIpAddress();
response = await _service.ChangePasswordAsync(request, ipAddress);
return Ok(MobileResponseBase<AppChangePasswordResponse>.Success(response, "Successfully Changed the Password"));
}
catch (Exception ex)
{
string msg = $"Exception occur on logout {request?.LoginId}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
}
}

View File

@ -0,0 +1,363 @@
using Asp.Versioning;
using DocumentFormat.OpenXml.Office2010.ExcelAc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OnlineSalesAutoCrop.CoreAPI;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Controllers
{
/// <summary>
///
/// </summary>
/// <remarks>
///
/// </remarks>
/// <param name="service"></param>
/// <param name="appSettings"></param>
/// <param name="cache"></param>
/// <param name="logger"></param>
[Authorize]
[ApiController]
[ApiVersion("1.0")]
[ValidateAntiForgeryToken]
[Route("api/mobile/v{version:apiVersion}/masterdata")]
public class MobileMasterDataController(IMobileMasterDataService service, IOptions<AppSettings> appSettings, IEaseCache cache, ILogger<MobileMasterDataController> logger) : ControllerBase
{
private readonly ILogger _logger = logger;
private readonly IEaseCache _cache = cache;
private readonly IMobileMasterDataService _service = service;
private readonly AppSettings _appSettings = appSettings?.Value;
private readonly DateTimeOffset _options = Helper.CreateEaseCacheOptions();
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return MarketHierarchies List</response>
[HttpGet("MarketHierarchies")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MarketHeirarchyByEmpResponse))]
public async Task<IActionResult> EmployeeMarketHierarchies([FromQuery] GetMarketHeirarchyByEmpRequest request)
{
MarketHeirarchyByEmpResponse response = new();
try
{
response = await _service.GetMarketHeirarchiesByEmpAsync(request);
return Ok(MobileResponseBase<MarketHeirarchyByEmpResponse>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on MarketHeirarchys endpoint with employee request - {request?.EmployeeNumber}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Brands List</response>
[HttpGet("Brands")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MarketHeirarchyByEmpResponse))]
public async Task<IActionResult> Brands([FromQuery] GetBrandsRequest request)
{
PagedResult<GetBrandResponse> response = new();
try
{
response = await _service.GetBrandsAsync(request);
return Ok(MobileResponseBase<PagedResult<GetBrandResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on brands endpoint with employee request - {request?.BrandCode}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Material List</response>
[HttpGet("Materials")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetMaterialResponse))]
public async Task<IActionResult> Materials([FromQuery] GetMaterialsRequest request)
{
PagedResult<GetMaterialResponse> response = new();
try
{
response = await _service.GetMaterialsAsync(request);
return Ok(MobileResponseBase<PagedResult<GetMaterialResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Materials endpoint with employee request - {request?.BrandCode} -{request?.MaterialCode}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Material List</response>
[HttpGet("CustomerWiseMaterialPrices")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetMaterialPriceResponse))]
public async Task<IActionResult> GetCustomerWiseMaterialPrices([FromQuery] GetMaterialPriceRequest request)
{
PagedResult<GetMaterialPriceResponse> response = new();
try
{
response = await _service.GetMaterialPricesAsync(request);
return Ok(MobileResponseBase<PagedResult<GetMaterialPriceResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Materials prices endpoint with employee request - {request?.MaterialCode} -{request?.EmployeeNumber}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Material List</response>
[HttpGet("Customers")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetCustomerResponse))]
public async Task<IActionResult> Customers([FromQuery] GetCustomersRequest request)
{
PagedResult<GetCustomerResponse> response = new();
try
{
response = await _service.GetCustomersAsync(request);
return Ok(MobileResponseBase<PagedResult<GetCustomerResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Materials endpoint with employee request - {request?.TeritoryCode} -{request?.CustomerCode}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
[HttpGet("Attendance")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetAttendanceByEmpResponse))]
public async Task<IActionResult> GetAttendance([FromQuery] GetAttendanceByEmpRequest request)
{
GetAttendanceByEmpResponse response = new();
try
{
response = await _service.GetAttendanceByEmpAsync(request);
return Ok(MobileResponseBase<GetAttendanceByEmpResponse>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Get Attendance endpoint with employee request - {request?.EmployeeNumber} -{request?.AttendanceDate}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
[HttpPost("SaveAttendance")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetAttendanceByEmpResponse))]
public async Task<IActionResult> UpsertAttendance([FromBody] UpsertAttendanceByEmpRequest request)
{
GetAttendanceByEmpResponse response = new();
try
{
response = await _service.UpsertAttendanceByEmpAsync(request);
return Ok(MobileResponseBase<GetAttendanceByEmpResponse>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Save Attendance endpoint with employee request - {request?.EmployeeNumber}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
[HttpGet("Discounts")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetDiscountResponse))]
public async Task<IActionResult> GetDiscounts([FromQuery] GetDiscountRequest request)
{
PagedResult<GetDiscountResponse> response = new();
try
{
response = await _service.GetDiscountAsync(request);
return Ok(MobileResponseBase<PagedResult<GetDiscountResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Get Discounts endpoint with request - {request?.EmployeeNumber} -{request?.DiscountCode}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
[HttpGet("DiscountMaterials")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetDiscountMaterialResponse))]
public async Task<IActionResult> GetDiscountMaterials([FromQuery] GetDiscountMaterialRequest request)
{
PagedResult<GetDiscountMaterialResponse> response = new();
try
{
response = await _service.GetDiscountMaterialsAsync(request);
return Ok(MobileResponseBase<PagedResult<GetDiscountMaterialResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Get DiscountMaterials endpoint with request - {request?.MaterialCode} -{request?.DiscountCode}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
[HttpGet("FOCs")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetFOCResponse))]
public async Task<IActionResult> GetMaterialFOCs([FromQuery] GetFOCRequest request)
{
PagedResult<GetFOCResponse> response = new();
try
{
response = await _service.GetFOCsAsync(request);
return Ok(MobileResponseBase<PagedResult<GetFOCResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Get MaterialFOCs endpoint with request - {request?.EmployeeNumber} -{request?.FOCCode}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
[HttpGet("FOCsMaterials")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetFOCMaterialResponse))]
public async Task<IActionResult> GetFOCsMaterials([FromQuery] GetFOCMaterialRequest request)
{
PagedResult<GetFOCMaterialResponse> response = new();
try
{
response = await _service.GetFOCMaterialsAsync(request);
return Ok(MobileResponseBase<PagedResult<GetFOCMaterialResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Get FOCsMaterials endpoint with request - {request?.MaterialCode} -{request?.FOCCode}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
[HttpGet("PaymentTerms")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetPaymentTermResponse))]
public async Task<IActionResult> GetPaymentTerms([FromQuery] GetPaymentTermRequest request)
{
PagedResult<GetPaymentTermResponse> response = new();
try
{
response = await _service.GetPaymentTermsAsync(request);
return Ok(MobileResponseBase<PagedResult<GetPaymentTermResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Get PaymentTerms endpoint with request - {request?.SalesOrgCode} -{request?.PaymentTermCode}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
}
}

View File

@ -0,0 +1,68 @@
using Asp.Versioning;
using Google.Api;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
using System;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Controllers.Mobile;
/// <summary>
///
/// </summary>
/// <remarks>
///
/// </remarks>
/// <param name="service"></param>
/// <param name="appSettings"></param>
/// <param name="cache"></param>
/// <param name="logger"></param>
[Authorize]
[ApiController]
[ApiVersion("1.0")]
[ValidateAntiForgeryToken]
[Route("api/mobile/v{version:apiVersion}/orders")]
public class OrdersController(IOrderService service, IOptions<AppSettings> appSettings, IEaseCache cache, ILogger<OrdersController> logger) : ControllerBase
{
private readonly ILogger _logger = logger;
private readonly IEaseCache _cache = cache;
private readonly IOrderService _service = service;
private readonly AppSettings _appSettings = appSettings?.Value;
private readonly DateTimeOffset _options = Helper.CreateEaseCacheOptions();
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
[HttpPost("SaveOrder")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(SaveOrderResponse))]
public async Task<IActionResult> UpsertAttendance([FromBody] SaveOrderRequest request)
{
SaveOrderResponse response = new();
try
{
response = await _service.SaveOrderAsync(request);
return Ok(MobileResponseBase<SaveOrderResponse>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Save Orders endpoint with Order UUID request - {request?.UUID}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
}

View File

@ -1,12 +1,5 @@
using Asp.Versioning;
using Asp.Versioning.ApiExplorer;
using OnlineSalesAutoCrop.CoreAPI.API.Swagger;
using OnlineSalesAutoCrop.CoreAPI.Configuration.DI;
using OnlineSalesAutoCrop.CoreAPI.Configurations;
using OnlineSalesAutoCrop.CoreAPI.Models;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
using OnlineSalesAutoCrop.CoreAPI.SignalRHub;
using Hangfire;
using Hangfire.SqlServer;
using Microsoft.AspNetCore.Authentication.JwtBearer;
@ -24,9 +17,19 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using OnlineSalesAutoCrop.CoreAPI.API.Swagger;
using OnlineSalesAutoCrop.CoreAPI.Configuration.DI;
using OnlineSalesAutoCrop.CoreAPI.Configurations;
using OnlineSalesAutoCrop.CoreAPI.Models;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
using OnlineSalesAutoCrop.CoreAPI.SignalRHub;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
@ -73,20 +76,40 @@ namespace OnlineSalesAutoCrop.CoreAPI
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.Configure<MenuSettings>(Configuration.GetSection("MenuSettings"));
#endregion
#endregion
#region Controllers
#region Controllers
services.AddControllers(options =>
services.AddControllers(options =>
{
options.Filters.Add(new ProducesAttribute("application/json"));
});
#endregion
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
var errors = context.ModelState
.Where(kvp => kvp.Value?.Errors.Count > 0)
.SelectMany(kvp => kvp.Value!.Errors.Select(e => e.ErrorMessage))
.ToList();
#region API versioning
var response = new MobileResponseBase<object>
{
ReturnStatus = StatusCodes.Status400BadRequest,
ReturnMessage =new List<string>() { errors.Count > 0 ? errors[0] : string.Empty },
Data = null
};
services.AddApiVersioning(options =>
return new BadRequestObjectResult(response);
};
});
#endregion
#region API versioning
services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.DefaultApiVersion = new ApiVersion(1, 0);

View File

@ -84,7 +84,8 @@
"WaAuthToken": "024a6897584671d9f9fa588d7c94aa96",
"WaMsgSvcSid": "MG8401d33a9a3b2aea95619bda3e5757b5",
"WaSenderId": "+8801326755660",
"RefreshTokenDuration": "15"
"RefreshTokenDuration": "15",
"AccessTokenDuration": "60"
},
"MenuSettings": {

View File

@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "10.0.9",
"commands": [
"dotnet-ef"
],
"rollForward": false
}
}
}