using DS.Module.Core;
using DS.WMS.Core.Application.Entity;
using DS.WMS.Core.Application.Method;
using DS.WMS.Core.Code.Entity;
using DS.WMS.Core.Invoice.Dtos;
using DS.WMS.Core.Invoice.Interface;
using DS.WMS.Core.Sys.Entity;
using Masuit.Tools;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
using SqlSugar;
namespace DS.WMS.Core.Invoice.Method
{
///
/// 发票开具服务
///
public sealed class InvoiceIssuanceService : ApplicationServiceBase, IInvoiceIssuanceService
{
readonly InvoiceApiFox api;
///
/// 初始化并加载配置
///
///
public InvoiceIssuanceService(IServiceProvider provider) : base(provider)
{
var config = provider.GetRequiredService();
api = new InvoiceApiFox(config);
}
///
/// 发起开票请求
///
/// 发票ID
///
public async Task> InitiateAsync(params long[] ids)
{
ArgumentNullException.ThrowIfNull(ids, nameof(ids));
long userId = long.Parse(User.UserId);
var userInfo = await Db.Queryable().Where(x => x.Id == userId).Select(x => new
{
x.UserName,
x.IdCardNo
}).FirstAsync();
if (string.IsNullOrEmpty(userInfo.IdCardNo))
return DataResult.FailedWithDesc(MultiLanguageConst.DrawerIDNumberIsNull);
//请求参数设置
InvoiceIssuanceRequest request = new()
{
order = await TenantDb.Queryable().Where(x => ids.Contains(x.Id)).Select(x => new InvoiceInfo
{
invoiceType = ((int)x.Type).ToString(),
orderNo = x.BillNO,
email = x.Email,
buyerTaxNum = x.TaxID,
buyerName = x.InvoiceHeader,
buyerAddress = x.CustomerAddress,
buyerTel = x.CustomerPhone,
gmfkhh = x.CustomerBankName,
gmfzh = x.CustomerAccount,
skyhmc = x.BankName,
skyhzh = x.Account,
checker = x.Checker,
payee = x.Payee,
//---------金额项---------
hjse = x.InvoiceAmount * x.TaxRate,
hjje = x.InvoiceAmount - x.InvoiceAmount * x.TaxRate,
jshj = x.InvoiceAmount,
clerk = userInfo.UserName, //开票人
kprzjhm = userInfo.IdCardNo, //证件号
kprzjlx = "201", //身份证,
//---------发票明细---------
invoiceDetail = SqlFunc.Subqueryable().Where(y => y.ApplicationId == x.Id)
.LeftJoin((y, z) => y.CodeId == z.Id).ToList((y, z) => new InvoiceDetailInfo
{
mxxh = SqlFunc.RowNumber(y.Id), //x.InvoiceDetails.IndexOf(y) + 1,
xmmc = y.Name,
spfwjc = string.Empty,
specType = y.Specification,
unit = y.Unit,
num = y.Quantity.ToString(),
taxExcludedAmount = y.UnitPrice,
taxRate = y.TaxRate.ToString(),
tax = y.TaxAmount,
taxIncludedAmount = y.TaxUnitPrice,
goodsCode = z.Code, //商品和服务税收分类合并编码
invoiceLineProperty = "00",
favouredPolicyFlag = z.PreferentialPolicyDescription
})
}).ToListAsync()
};
if (request.order.Count == 0 || request.order.Any(x => x.invoiceDetail.Count == 0))
return DataResult.FailedWithDesc(MultiLanguageConst.InvoiceIncomplete);
var result = await api.PostAsync>("/api/Invoice/services", request);
if (!result.Succeeded)
return DataResult.Failed(result.Message, result.MultiCode);
var invResult = result.Data;
JObject? jObj = JObject.Parse(invResult.Data);
if (invResult.Success)
{
return DataResult.Success(jObj);
}
else
{
if (invResult.Code == 1)
return await InitiateAsync(ids);
return DataResult.FailedData(jObj, invResult.Message);
}
}
///
/// 发票冲红
///
///
///
public async Task> ReverseAsync(InvoiceReversalRequest request)
{
var invoice = await TenantDb.Queryable()
.WhereIF(request.InvoiceId.HasValue, x => x.Id == request.InvoiceId)
.WhereIF(!request.orderNo.IsNullOrEmpty(), x => x.BillNO == request.orderNo)
.FirstAsync();
if (invoice == null)
return DataResult.FailedWithDesc(MultiLanguageConst.EmptyData);
var req = new InvoiceReversalRequest { orderNo = invoice.BillNO };
var result = await api.PostAsync>("/api/Invoice/RedInvoicing", req);
if (!result.Succeeded)
return DataResult.Failed(result.Message, result.MultiCode);
var invResult = result.Data;
JObject? jObj = JObject.Parse(invResult.Data);
if (invResult.Success)
return DataResult.FailedData(jObj, invResult.Message);
invoice.IsSetRed = true;
invoice.RedReason = request.Reason;
await TenantDb.Updateable(invoice).UpdateColumns(x => new { x.IsSetRed, x.RedReason }).ExecuteCommandAsync();
return DataResult.Success(jObj);
}
///
/// 添加租户信息
///
/// 租户信息
///
/// 当为null时引发。
public async Task AddTenantAsync(Tenant tenant)
{
ArgumentNullException.ThrowIfNull(tenant, nameof(tenant));
var result = await api.PostAsync("/api/Login/AddTenant", tenant);
return result.Data;
}
}
}