add customer api for integration

This commit is contained in:
dibakor 2026-06-16 17:22:46 +06:00
parent 70fe243e37
commit 08c285678b
8 changed files with 478 additions and 12 deletions

View File

@ -0,0 +1,57 @@
namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Integrations;
public class CustomerIntegration
{
public int CustomerId { get; set; }
public string CustomerNumber { get; set; }
public string CustomerName { get; set; }
public string AccountGroup { get; set; }
public string AccountGroupDescription { get; set; }
public string CompanyCode { get; set; }
public string CompanyCodeDescription { get; set; }
public string SalesOrganization { get; set; }
public string SalesOrganizationDescription { get; set; }
public string DistributionChannel { get; set; }
public string DistributionChannelDescription { get; set; }
public string Division { get; set; }
public string DivisionDescription { get; set; }
public string MobileNumber { get; set; }
public string EmailAddress { get; set; }
public string BusinessTaxNumber { get; set; }
public decimal? CreditLimit { get; set; }
public string SalesOffice { get; set; }
public string SalesOfficeDescription { get; set; }
public string SalesGroup { get; set; }
public string CustomerGroup { get; set; }
public string Status { get; set; }
public string PaymentTerms { get; set; }
public string SearchTerm { get; set; }
public string Region { get; set; }
public string RegionName { get; set; }
public string Area { get; set; }
public string AreaName { get; set; }
public string SalesUnit { get; set; }
public string SalesUnitName { get; set; }
public string Territory { get; set; }
public string TerritoryName { get; set; }
public string Plant { get; set; }
public string PlantName { get; set; }
}

View File

@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
public class CustomerIntegrationRequest
{
[Required(ErrorMessage = "Customer Number is required")]
[StringLength(10, MinimumLength = 1, ErrorMessage = "Customer Number must be between 1 and 10 characters")]
public string CustomerNumber { get; set; } = string.Empty;
[Required(ErrorMessage = "Customer Name is required")]
[StringLength(35, MinimumLength = 1, ErrorMessage = "Customer Name must be between 1 and 35 characters")]
public string CustomerName { get; set; } = string.Empty;
[Required(ErrorMessage = "Account Group is required")]
[StringLength(3, MinimumLength = 1, ErrorMessage = "Account Group must be between 1 and 3 characters")]
public string AccountGroup { get; set; } = string.Empty;
[Required(ErrorMessage = "Account Group Description is required")]
[StringLength(30, ErrorMessage = "Account Group Description cannot exceed 30 characters")]
public string AccountGroupDescription { get; set; } = string.Empty;
[Required(ErrorMessage = "Company Code is required")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "Company Code must be between 1 and 4 characters")]
public string CompanyCode { get; set; } = string.Empty;
[Required(ErrorMessage = "Company Code Description is required")]
[StringLength(25, ErrorMessage = "Company Code Description cannot exceed 25 characters")]
public string CompanyCodeDescription { get; set; } = string.Empty;
[Required(ErrorMessage = "Sales Organization is required")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "Sales Organization must be between 1 and 4 characters")]
public string SalesOrganization { get; set; } = string.Empty;
[Required(ErrorMessage = "Sales Organization Description is required")]
[StringLength(40, ErrorMessage = "Sales Organization Description cannot exceed 40 characters")]
public string SalesOrganizationDescription { get; set; } = string.Empty;
[Required(ErrorMessage = "Distribution Channel is required")]
[StringLength(2, MinimumLength = 1, ErrorMessage = "Distribution Channel must be between 1 and 2 characters")]
public string DistributionChannel { get; set; } = string.Empty;
[Required(ErrorMessage = "Distribution Channel Description is required")]
[StringLength(20, ErrorMessage = "Distribution Channel Description cannot exceed 20 characters")]
public string DistributionChannelDescription { get; set; } = string.Empty;
[Required(ErrorMessage = "Division is required")]
[StringLength(2, MinimumLength = 1, ErrorMessage = "Division must be between 1 and 2 characters")]
public string Division { get; set; } = string.Empty;
[Required(ErrorMessage = "Division Description is required")]
[StringLength(20, ErrorMessage = "Division Description cannot exceed 20 characters")]
public string DivisionDescription { get; set; } = string.Empty;
[Required(ErrorMessage = "Mobile Number is required")]
[StringLength(31, ErrorMessage = "Mobile Number cannot exceed 31 characters")]
[Phone(ErrorMessage = "Invalid mobile number format")]
public string MobileNumber { get; set; } = string.Empty;
[Required(ErrorMessage = "Email Address is required")]
[StringLength(241, ErrorMessage = "Email Address cannot exceed 241 characters")]
[EmailAddress(ErrorMessage = "Invalid email address format")]
public string EmailAddress { get; set; } = string.Empty;
[Required(ErrorMessage = "Business/Tax Number is required")]
[StringLength(16, ErrorMessage = "Business/Tax Number cannot exceed 16 characters")]
public string BusinessTaxNumber { get; set; } = string.Empty;
[Required(ErrorMessage = "Credit Limit is required")]
[Range(0, 9999999999999, ErrorMessage = "Credit Limit must be a valid number")]
public decimal CreditLimit { get; set; }
[Required(ErrorMessage = "Sales Office is required")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "Sales Office must be between 1 and 4 characters")]
public string SalesOffice { get; set; } = string.Empty;
[StringLength(255, ErrorMessage = "Sales Office Description cannot exceed 255 characters")]
public string? SalesOfficeDescription { get; set; }
[Required(ErrorMessage = "Sales Group is required")]
[StringLength(3, MinimumLength = 1, ErrorMessage = "Sales Group must be between 1 and 3 characters")]
public string SalesGroup { get; set; } = string.Empty;
[Required(ErrorMessage = "Customer Group is required")]
[StringLength(2, MinimumLength = 1, ErrorMessage = "Customer Group must be between 1 and 2 characters")]
public string CustomerGroup { get; set; } = string.Empty;
[Required(ErrorMessage = "Status is required")]
[StringLength(1, MinimumLength = 1, ErrorMessage = "Status must be exactly 1 character")]
public string Status { get; set; } = string.Empty;
[Required(ErrorMessage = "Payment Terms are required")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "Payment Terms must be between 1 and 4 characters")]
public string PaymentTerms { get; set; } = string.Empty;
[Required(ErrorMessage = "Search Term is required")]
[StringLength(20, ErrorMessage = "Search Term cannot exceed 20 characters")]
public string SearchTerm { get; set; } = string.Empty;
[Required(ErrorMessage = "Region is required")]
[StringLength(3, MinimumLength = 1, ErrorMessage = "Region must be between 1 and 3 characters")]
public string Region { get; set; } = string.Empty;
[Required(ErrorMessage = "Region Name is required")]
[StringLength(40, ErrorMessage = "Region Name cannot exceed 40 characters")]
public string RegionName { get; set; } = string.Empty;
[Required(ErrorMessage = "Area is required")]
[StringLength(10, MinimumLength = 1, ErrorMessage = "Area must be between 1 and 10 characters")]
public string Area { get; set; } = string.Empty;
[Required(ErrorMessage = "Area Name is required")]
[StringLength(40, ErrorMessage = "Area Name cannot exceed 40 characters")]
public string AreaName { get; set; } = string.Empty;
[Required(ErrorMessage = "Sales Unit is required")]
[StringLength(3, MinimumLength = 1, ErrorMessage = "Sales Unit must be between 1 and 3 characters")]
public string SalesUnit { get; set; } = string.Empty;
[Required(ErrorMessage = "Sales Unit Name is required")]
[StringLength(30, ErrorMessage = "Sales Unit Name cannot exceed 30 characters")]
public string SalesUnitName { get; set; } = string.Empty;
[Required(ErrorMessage = "Territory is required")]
[StringLength(3, MinimumLength = 1, ErrorMessage = "Territory must be between 1 and 3 characters")]
public string Territory { get; set; } = string.Empty;
[Required(ErrorMessage = "Territory Name is required")]
[StringLength(20, ErrorMessage = "Territory Name cannot exceed 20 characters")]
public string TerritoryName { get; set; } = string.Empty;
[Required(ErrorMessage = "Plant is required")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "Plant must be between 1 and 4 characters")]
public string Plant { get; set; } = string.Empty;
[Required(ErrorMessage = "Plant Name is required")]
[StringLength(30, ErrorMessage = "Plant Name cannot exceed 30 characters")]
public string PlantName { get; set; } = string.Empty;
}
public class CustomerByCompanyCodeRequest
{
[Required(ErrorMessage = "Customer Number is required")]
[StringLength(10, MinimumLength = 1, ErrorMessage = "Customer Number must be between 1 and 10 characters")]
public string CustomerNumber { get; set; } = string.Empty;
[Required(ErrorMessage = "Company Code is required")]
[StringLength(4, MinimumLength = 1, ErrorMessage = "Company Code must be between 1 and 4 characters")]
public string CompanyCode { get; set; } = string.Empty;
}

View File

@ -0,0 +1,62 @@
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
public class CustomerIntegrationResponse : ResponseBase
{
}
public class CustomerByCompanyCodeResponse : ResponseBase
{
public int CustomerId { get; set; }
public string CustomerNumber { get; set; }
public string CustomerName { get; set; }
public string AccountGroup { get; set; }
public string AccountGroupDescription { get; set; }
public string CompanyCode { get; set; }
public string CompanyCodeDescription { get; set; }
public string SalesOrganization { get; set; }
public string SalesOrganizationDescription { get; set; }
public string DistributionChannel { get; set; }
public string DistributionChannelDescription { get; set; }
public string Division { get; set; }
public string DivisionDescription { get; set; }
public string MobileNumber { get; set; }
public string EmailAddress { get; set; }
public string BusinessTaxNumber { get; set; }
public decimal? CreditLimit { get; set; }
public string SalesOffice { get; set; }
public string SalesOfficeDescription { get; set; }
public string SalesGroup { get; set; }
public string CustomerGroup { get; set; }
public string Status { get; set; }
public string PaymentTerms { get; set; }
public string SearchTerm { get; set; }
public string Region { get; set; }
public string RegionName { get; set; }
public string Area { get; set; }
public string AreaName { get; set; }
public string SalesUnit { get; set; }
public string SalesUnitName { get; set; }
public string Territory { get; set; }
public string TerritoryName { get; set; }
public string Plant { get; set; }
public string PlantName { get; set; }
}

View File

@ -0,0 +1,12 @@

using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
public interface IIntegrationService
{
Task<bool> UpsertCustomerAsync(CustomerIntegrationRequest request);
Task<CustomerByCompanyCodeResponse> GetCustomerByCompanyCodeAsync(CustomerByCompanyCodeRequest request);
}

View File

@ -1,15 +1,11 @@
using DocumentFormat.OpenXml.Spreadsheet; using Ease.NetCore.DataAccess;
using DocumentFormat.OpenXml.VariantTypes;
using Ease.NetCore.DataAccess;
using Ease.NetCore.DataAccess.SQL; using Ease.NetCore.DataAccess.SQL;
using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using MySqlX.XDevAPI.Common;
using OnlineSalesAutoCrop.CoreAPI.Models.Global; using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems; using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
using System; using System;
using System.Data; using System.Data;

View File

@ -0,0 +1,152 @@
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.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
using System;
using System.Data;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations;
public class IntegrationService : IIntegrationService
{
private readonly AppSettings _settings;
public IntegrationService(IOptions<AppSettings> options)
{
_settings = options.Value;
}
public async Task<CustomerByCompanyCodeResponse> GetCustomerByCompanyCodeAsync(CustomerByCompanyCodeRequest request)
{
CustomerByCompanyCodeResponse response = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
await GetCustomerByCompanyCodeAsync(tc, request);
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
public async Task<bool> UpsertCustomerAsync(CustomerIntegrationRequest request)
{
bool response = false;
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
var customer = await GetCustomerByCompanyCodeAsync(tc, new CustomerByCompanyCodeRequest() { CompanyCode = request.CompanyCode, CustomerNumber = request.CustomerNumber });
if( customer != null && customer.CustomerId>0)
{
//Update Here
}
else
{
//Insert Here
}
tc.End();
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
private async Task<CustomerByCompanyCodeResponse> GetCustomerByCompanyCodeAsync(TransactionContext tc, CustomerByCompanyCodeRequest request)
{
CustomerByCompanyCodeResponse response = new CustomerByCompanyCodeResponse();
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@CustomerNumber", pType: SqlDbType.NVarChar,pValue: request.CustomerNumber ),
SqlHelperExtension.CreateInParam(pName: "@CompanyCode", pType: SqlDbType.NVarChar,pValue: request.CompanyCode ),
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetCustomerByCompanyCode", parameterValues: p))
{
if (dr.Read())
{
response = new CustomerByCompanyCodeResponse()
{
CustomerNumber = dr["CustomerNumber"].ToString(),
CustomerName = dr["CustomerName"].ToString(),
AccountGroup = dr["AccountGroup"].ToString(),
AccountGroupDescription = dr["AccountGroupDescription"].ToString(),
CompanyCode = dr["CompanyCode"].ToString(),
CompanyCodeDescription = dr["CompanyCodeDescription"].ToString(),
SalesOrganization = dr["SalesOrganization"].ToString(),
SalesOrganizationDescription = dr["SalesOrganizationDescription"].ToString(),
DistributionChannel = dr["DistributionChannel"].ToString(),
DistributionChannelDescription = dr["DistributionChannelDescription"].ToString(),
Division = dr["Division"].ToString(),
DivisionDescription = dr["DivisionDescription"].ToString(),
MobileNumber = dr["MobileNumber"].ToString(),
EmailAddress = dr["EmailAddress"].ToString(),
BusinessTaxNumber = dr["BusinessTaxNumber"].ToString(),
CreditLimit = dr["CreditLimit"] == DBNull.Value ? 0 : Convert.ToDecimal(dr["CreditLimit"]),
SalesOffice = dr["SalesOffice"].ToString(),
SalesOfficeDescription = dr["SalesOfficeDescription"].ToString(),
SalesGroup = dr["SalesGroup"].ToString(),
CustomerGroup = dr["CustomerGroup"].ToString(),
Status = dr["Status"].ToString(),
PaymentTerms = dr["PaymentTerms"].ToString(),
SearchTerm = dr["SearchTerm"].ToString(),
Region = dr["Region"].ToString(),
RegionName = dr["RegionName"].ToString(),
Area = dr["Area"].ToString(),
AreaName = dr["AreaName"].ToString(),
SalesUnit = dr["SalesUnit"].ToString(),
SalesUnitName = dr["SalesUnitName"].ToString(),
Territory = dr["Territory"].ToString(),
TerritoryName = dr["TerritoryName"].ToString(),
Plant = dr["Plant"].ToString(),
PlantName = dr["PlantName"].ToString()
};
}
dr.Close();
}
}
catch(Exception ex)
{
throw;
}
return response;
}
}

View File

@ -1,8 +1,10 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Setups; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Setups;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.Auth; using OnlineSalesAutoCrop.CoreAPI.Services.Services.Auth;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.Setups; using OnlineSalesAutoCrop.CoreAPI.Services.Services.Setups;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems; using OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems;
@ -28,7 +30,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Configuration.DI
services.AddTransient<IThisSystemService, ThisSystemService>(); services.AddTransient<IThisSystemService, ThisSystemService>();
services.AddTransient<IAuthModulesService, AuthModulesService>(); services.AddTransient<IAuthModulesService, AuthModulesService>();
services.AddTransient<IRefreshTokenService, RefreshTokenService>(); services.AddTransient<IRefreshTokenService, RefreshTokenService>();
services.AddScoped<IIntegrationService, IntegrationService>();
} }
} }
} }

View File

@ -2,8 +2,12 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations; using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
using OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi
@ -14,23 +18,49 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi
/// <remarks> /// <remarks>
/// ///
/// </remarks> /// </remarks>
/// <param name="service"></param>
/// <param name="appSettings"></param>
/// <param name="cache"></param>
/// <param name="logger"></param> /// <param name="logger"></param>
/// <param name="integrationService"></param>
[Authorize] [Authorize]
[ApiController] [ApiController]
[ApiVersion("1.0")] [ApiVersion("1.0")]
[ValidateAntiForgeryToken] [ValidateAntiForgeryToken]
[Route("api/v{version:apiVersion}/Integration")] [Route("api/v{version:apiVersion}/Integration")]
public class IntegrationController : ControllerBase public class IntegrationController(ILogger<IntegrationAuthController> logger, IIntegrationService integrationService) : ControllerBase
{ {
private readonly ILogger _logger = logger;
private readonly IIntegrationService _integrationService = integrationService;
[HttpGet("Customers")] [HttpGet("Customers")]
[IgnoreAntiforgeryToken] [IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationLoginResponse))] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationLoginResponse))]
public async Task<IActionResult> Customers() public async Task<IActionResult> UpsertCustomers(CustomerIntegrationRequest request)
{ {
return Ok("Data Insert Successfully"); CustomerIntegrationResponse response = new CustomerIntegrationResponse();
try
{
bool result = await _integrationService.UpsertCustomerAsync(request);
if (result)
{
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.Status204NoContent;
return StatusCode(StatusCodes.Status204NoContent, 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);
}
} }
} }
} }