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; } } }