add salesinvoice api

This commit is contained in:
dibakor 2026-06-30 18:57:11 +06:00
parent 70a4a757f2
commit 43efe23587
7 changed files with 130 additions and 7 deletions

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

@ -20,6 +20,14 @@ public class IntegrationMaterialRequest
[StringLength(40, ErrorMessage = "Material description cannot exceed 40 characters.")] [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.")] [Required(ErrorMessage = "Material group code is required.")]
[StringLength(9, ErrorMessage = "Material group code cannot exceed 9 characters.")] [StringLength(9, ErrorMessage = "Material group code cannot exceed 9 characters.")]
public string MaterialGroupCode { get; set; } public string MaterialGroupCode { 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

@ -20,6 +20,8 @@ public class IntegrationMaterialResponse : ResponseBase
public string StorageLocationDescription { get; set; } public string StorageLocationDescription { get; set; }
public string SalesOrganization { get; set; } public string SalesOrganization { get; set; }
public string SalesOrganizationDescription { get; set; } public string SalesOrganizationDescription { get; set; }
public string BrandCode { get; set; }
public string BrandName { get; set; }
} }
public class MaterialIntegrationReqResponse : ResponseBase public class MaterialIntegrationReqResponse : ResponseBase

View File

@ -31,4 +31,7 @@ public interface IIntegrationService
//Payment Terms //Payment Terms
Task<IntegrationPaymentTermReqResponse> UpsertPaymentTermsAsync(IntegrationPaymentTermRequest request); Task<IntegrationPaymentTermReqResponse> UpsertPaymentTermsAsync(IntegrationPaymentTermRequest request);
Task<IntegrationPaymentTermResponse> GetPaymentTermsByFilterAsync(GetIntegrationPaymentTermRequest request); Task<IntegrationPaymentTermResponse> GetPaymentTermsByFilterAsync(GetIntegrationPaymentTermRequest request);
//Invoices
Task<IntegrationInvoiceReqResponse> SaveInvoiceAsync(IntegrationInvoiceRequest request);
} }

View File

@ -434,6 +434,12 @@ public class IntegrationService : IIntegrationService
return response; return response;
} }
public async Task<IntegrationInvoiceReqResponse> SaveInvoiceAsync(IntegrationInvoiceRequest request)
{
throw new NotImplementedException();
}
#region Customer Private Functions #region Customer Private Functions
private async Task<CustomerByCompanyCodeResponse> GetCustomerByCompanyCodeAsync(TransactionContext tc, CustomerByCompanyCodeRequest request) private async Task<CustomerByCompanyCodeResponse> GetCustomerByCompanyCodeAsync(TransactionContext tc, CustomerByCompanyCodeRequest request)
@ -863,6 +869,8 @@ public class IntegrationService : IIntegrationService
StorageLocationDescription = dr.GetString(13), StorageLocationDescription = dr.GetString(13),
SalesOrganization = dr.GetString(14), SalesOrganization = dr.GetString(14),
SalesOrganizationDescription = dr.GetString(15), SalesOrganizationDescription = dr.GetString(15),
BrandCode = dr.GetString(16),
BrandName = dr.GetString(17)
}; };
} }
dr.Close(); dr.Close();
@ -904,8 +912,11 @@ public class IntegrationService : IIntegrationService
SqlHelperExtension.CreateInParam("@StorageLocationCode", SqlDbType.NVarChar, request.StorageLocationCode), SqlHelperExtension.CreateInParam("@StorageLocationCode", SqlDbType.NVarChar, request.StorageLocationCode),
SqlHelperExtension.CreateInParam("@StorageLocationDescription", SqlDbType.NVarChar, request.StorageLocationDescription), SqlHelperExtension.CreateInParam("@StorageLocationDescription", SqlDbType.NVarChar, request.StorageLocationDescription),
SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization), SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization),
SqlHelperExtension.CreateInParam("@SalesOrganizationDescription", SqlDbType.NVarChar, request.SalesOrganizationDescription) 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); _ = tc.ExecuteNonQuerySp(spName: "dbo.CreateMaterial", parameterValues: p);
@ -948,8 +959,11 @@ public class IntegrationService : IIntegrationService
SqlHelperExtension.CreateInParam("@StorageLocationCode", SqlDbType.NVarChar, request.StorageLocationCode), SqlHelperExtension.CreateInParam("@StorageLocationCode", SqlDbType.NVarChar, request.StorageLocationCode),
SqlHelperExtension.CreateInParam("@StorageLocationDescription", SqlDbType.NVarChar, request.StorageLocationDescription), SqlHelperExtension.CreateInParam("@StorageLocationDescription", SqlDbType.NVarChar, request.StorageLocationDescription),
SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization), SqlHelperExtension.CreateInParam("@SalesOrganization", SqlDbType.NVarChar, request.SalesOrganization),
SqlHelperExtension.CreateInParam("@SalesOrganizationDescription", SqlDbType.NVarChar, request.SalesOrganizationDescription) 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); _ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateMaterial", parameterValues: p);
@ -1213,7 +1227,7 @@ public class IntegrationService : IIntegrationService
#endregion #endregion
#region Credit Code Private Functions #region Payment Terms Private Functions
private async Task<IntegrationPaymentTermResponse> GetPaymentTermByFilterAsync(TransactionContext tc, private async Task<IntegrationPaymentTermResponse> GetPaymentTermByFilterAsync(TransactionContext tc,
GetIntegrationPaymentTermRequest request) GetIntegrationPaymentTermRequest request)
@ -1307,6 +1321,5 @@ public class IntegrationService : IIntegrationService
return returnValue; return returnValue;
} }
#endregion #endregion
} }

View File

@ -3,6 +3,7 @@ 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 Microsoft.Extensions.Logging;
using OnlineSalesAutoCrop.CoreAPI;
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.Contracts.Integrations;
@ -281,5 +282,38 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi
return StatusCode(StatusCodes.Status500InternalServerError, response); 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);
}
}
} }
} }