diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/IntegrationPaymentTerm.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/IntegrationPaymentTerm.cs new file mode 100644 index 0000000..35265ff --- /dev/null +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Objects/Integrations/IntegrationPaymentTerm.cs @@ -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; } +} diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationAuthRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationAuthRequest.cs index 49eeda3..bd373a0 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationAuthRequest.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationAuthRequest.cs @@ -1,9 +1,7 @@ -using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems; -using System; -using System.Collections.Generic; + +using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems; using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; -using System.Text; namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; @@ -13,13 +11,13 @@ public class IntegrationLoginRequest public string LoginId { get; set; } [Required, NotNull, StringLength(maximumLength: 150, MinimumLength = 5, ErrorMessage = "Password must be between 1 and 30 characters.")] - public string Password { get; set; } + public string Password { get; set; } } public class IntegrationRefreshTokenRequest { - public string RefreshToken { get; set; } + public string RefreshToken { get; set; } } public class InsertRefreshTokenRequest : RefreshToken @@ -27,7 +25,7 @@ public class InsertRefreshTokenRequest : RefreshToken public string RefreshToken { get; set; } } -public class RevokedRefreshTokenRequest +public class RevokedRefreshTokenRequest { public string RefreshToken { get; set; } public int UserId { get; set; } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationPaymentTermRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationPaymentTermRequest.cs new file mode 100644 index 0000000..96a3b26 --- /dev/null +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationPaymentTermRequest.cs @@ -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; } +} + diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationAuthResponse.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationAuthResponse.cs index 090c76e..656291b 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationAuthResponse.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationAuthResponse.cs @@ -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; @@ -21,9 +18,9 @@ public class IntegrationRrefreshTokenResponse : ResponseBase } -public class RefreshTokenResponse : ResponseBase +public class RefreshTokenResponse : ResponseBase { - public int UserId { get; set; } + public int UserId { get; set; } public string TokenHash { get; set; } public string IpAddress { get; set; } public DateTime ExpiredAt { get; set; } @@ -35,14 +32,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; } } \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationPaymentTermResponse.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationPaymentTermResponse.cs new file mode 100644 index 0000000..1762aea --- /dev/null +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationPaymentTermResponse.cs @@ -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; } +} \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationService.cs index 6e397bf..e865bff 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationService.cs @@ -27,4 +27,8 @@ public interface IIntegrationService //Material Free Goods Task UpsertMaterialFreeGoodsAsync(IntegrationMaterialFreeGoodsRequest request); Task GetMaterialFreeGoodseByFilterAsync(GetMaterialFreeGoodsByFilterRequest request); + + //Payment Terms + Task UpsertPaymentTermsAsync(IntegrationPaymentTermRequest request); + Task GetPaymentTermsByFilterAsync(GetIntegrationPaymentTermRequest request); } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs index cbb460f..4f9607e 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs @@ -369,6 +369,71 @@ public class IntegrationService : IIntegrationService } + public async Task 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 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; + } + #region Customer Private Functions private async Task GetCustomerByCompanyCodeAsync(TransactionContext tc, CustomerByCompanyCodeRequest request) @@ -1146,5 +1211,102 @@ public class IntegrationService : IIntegrationService return returnValue; } + #endregion + + #region Credit Code Private Functions + + private async Task 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 } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationController.cs b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationController.cs index b529e72..1d3cd68 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationController.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/IntegretionApi/IntegrationController.cs @@ -238,5 +238,48 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi return StatusCode(StatusCodes.Status500InternalServerError, response); } } + + /// + /// Insert or Update Payment Terms for SAP + /// + /// + /// + /// + /// if created return 201 or if updated return 200 true + [HttpPost("PaymentTerms")] + [IgnoreAntiforgeryToken] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationPaymentTermReqResponse))] + [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(IntegrationPaymentTermReqResponse))] + public async Task 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); + } + } } } \ No newline at end of file