标准开票类签入

usertest
嵇文龙 4 months ago
parent 9083604cb0
commit 5b292efc82

@ -80,7 +80,7 @@ namespace DS.Module.Core.Enums
Invoiced = 4, Invoiced = 4,
/// <summary> /// <summary>
/// 开出 /// 部分开出
/// </summary> /// </summary>
[Description("部分开出")] [Description("部分开出")]
PartialInvoiced = 5 PartialInvoiced = 5

@ -7,17 +7,23 @@ namespace DS.Module.Core.Enums
/// </summary> /// </summary>
public enum InvoiceCategory public enum InvoiceCategory
{ {
/// <summary>
/// 普通发票
/// </summary>
[Description("普通发票")]
General = 0,
/// <summary> /// <summary>
/// 电子发票 /// 电子发票
/// </summary> /// </summary>
[Description("电子发票")] [Description("电子发票")]
Electronic = 0, Electronic = 1,
/// <summary> /// <summary>
/// 纸质发票 /// 纸质发票
/// </summary> /// </summary>
[Description("纸质发票")] [Description("纸质发票")]
Paper = 1 Paper = 2
} }
/// <summary> /// <summary>

@ -45,10 +45,17 @@ namespace DS.WMS.Core.Application.Dtos
public string? AmountUppercase { get; set; } public string? AmountUppercase { get; set; }
/// <summary> /// <summary>
/// 所属机构(公司) /// 所属机构(公司)ID
/// </summary> /// </summary>
[IgnoreDataMember]
public long? OrgId { get; set; } public long? OrgId { get; set; }
/// <summary>
/// 所属机构(公司)
/// </summary>
[IgnoreDataMember]
public string? OrgName { get; set; }
/// <summary> /// <summary>
/// 客户地址电话 /// 客户地址电话
/// </summary> /// </summary>

@ -253,5 +253,10 @@ namespace DS.WMS.Core.Invoice.Dto
/// 发票明细 /// 发票明细
/// </summary> /// </summary>
public List<InvoiceDetail>? InvoiceDetails { get; set; } public List<InvoiceDetail>? InvoiceDetails { get; set; }
/// <summary>
/// 费用明细汇总
/// </summary>
public List<SummaryItem>? Summary { get; set; }
} }
} }

@ -317,7 +317,7 @@ namespace DS.WMS.Core.Invoice.Entity
/// 作废时间 /// 作废时间
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "作废时间")] [SugarColumn(ColumnDescription = "作废时间")]
public DateTime CancelTime { get; set; } public DateTime? CancelTime { get; set; }
/// <summary> /// <summary>
/// 费用明细 /// 费用明细

@ -1,7 +1,6 @@
using DS.Module.Core; using DS.Module.Core;
using DS.WMS.Core.Application.Dtos; using DS.WMS.Core.Application.Dtos;
using DS.WMS.Core.Fee.Dtos; using DS.WMS.Core.Fee.Dtos;
using DS.WMS.Core.Invoice.Dto;
namespace DS.WMS.Core.Invoice.Interface namespace DS.WMS.Core.Invoice.Interface
{ {
@ -24,11 +23,6 @@ namespace DS.WMS.Core.Invoice.Interface
/// <returns></returns> /// <returns></returns>
Task<DataResult<InvoiceApplicaitonBiz>> GetFeesAsync(params BizItem[] items); Task<DataResult<InvoiceApplicaitonBiz>> GetFeesAsync(params BizItem[] items);
/// <summary>
/// 获取发票详情
/// </summary>
/// <param name="id">发票ID</param>
/// <returns></returns>
Task<DataResult<InvoiceDto>> GetAsync(long id);
} }
} }

@ -0,0 +1,10 @@
namespace DS.WMS.Core.Invoice.Interface
{
/// <summary>
/// 标准开票
/// </summary>
public interface IGeneralInvoiceService : IInvoiceService<Entity.Invoice>
{
}
}

@ -17,6 +17,13 @@ namespace DS.WMS.Core.Invoice.Interface
/// <returns></returns> /// <returns></returns>
Task<DataResult<List<InvoiceDto>>> GetListAsync(PageRequest<string> request); Task<DataResult<List<InvoiceDto>>> GetListAsync(PageRequest<string> request);
/// <summary>
/// 获取发票详情
/// </summary>
/// <param name="id">发票ID</param>
/// <returns></returns>
Task<DataResult<InvoiceDto>> GetAsync(long id);
/// <summary> /// <summary>
/// 提交发票开票 /// 提交发票开票
/// </summary> /// </summary>
@ -45,5 +52,13 @@ namespace DS.WMS.Core.Invoice.Interface
/// <param name="ids">发票ID</param> /// <param name="ids">发票ID</param>
/// <returns></returns> /// <returns></returns>
Task<DataResult> SetLockAsync(bool isLocked, params long[] ids); Task<DataResult> SetLockAsync(bool isLocked, params long[] ids);
/// <summary>
/// 设置发票的作废状态
/// </summary>
/// <param name="isCancelled">是否锁定</param>
/// <param name="ids">发票ID</param>
/// <returns></returns>
Task<DataResult> SetCancelAsync(bool isCancelled, params long[] ids);
} }
} }

@ -52,6 +52,7 @@ namespace DS.WMS.Core.Invoice.Method
FeeType = x.FeeType, FeeType = x.FeeType,
ApplyAmount = x.ApplyAmount, ApplyAmount = x.ApplyAmount,
ExchangeRate = x.ExchangeRate, ExchangeRate = x.ExchangeRate,
Currency = x.Currency,
OriginalAmount = x.OriginalAmount, OriginalAmount = x.OriginalAmount,
OriginalCurrency = x.OriginalCurrency, OriginalCurrency = x.OriginalCurrency,
OriginalRate = x.OriginalRate, OriginalRate = x.OriginalRate,
@ -66,6 +67,13 @@ namespace DS.WMS.Core.Invoice.Method
Voyage = x.Voyage, Voyage = x.Voyage,
}).ToListAsync(); }).ToListAsync();
invoice.Summary = invoice.Details.GroupBy(x => new { x.FeeType, x.Currency }).Select(x => new SummaryItem
{
FeeType = x.Key.FeeType,
Currency = x.Key.Currency,
Amount = x.Sum(y => y.ApplyAmount)
}).ToList();
invoice.InvoiceDetails = await TenantDb.Queryable<InvoiceDetail>().Where( invoice.InvoiceDetails = await TenantDb.Queryable<InvoiceDetail>().Where(
x => x.ApplicationId == id && x.Category == DetailCategory.InvoiceIssuance).ToListAsync(); x => x.ApplicationId == id && x.Category == DetailCategory.InvoiceIssuance).ToListAsync();
} }

@ -0,0 +1,82 @@
using DS.Module.Core;
using DS.Module.Core.Enums;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Application.Dtos;
using DS.WMS.Core.Application.Entity;
using DS.WMS.Core.Invoice.Interface;
using DS.WMS.Core.Sys.Entity;
using SqlSugar;
namespace DS.WMS.Core.Invoice.Method
{
/// <summary>
/// 标准(按申请)开票实现
/// </summary>
public class GeneralInvoiceService : InvoiceService<Entity.Invoice>, IGeneralInvoiceService
{
/// <summary>
/// 初始化
/// </summary>
/// <param name="provider"></param>
public GeneralInvoiceService(IServiceProvider provider) : base(provider)
{
}
/// <summary>
/// 获取付费申请分页列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult<List<InvoiceApplicationDto>>> GetApplicationListAsync(PageRequest request)
{
var query = TenantDb.Queryable<InvoiceApplication>().Where(x => x.Status == InvoiceApplicationStatus.AuditPassed || x.Status == InvoiceApplicationStatus.PartialInvoiced)
.InnerJoin<ApplicationDetail>((a, d) => a.Id == d.ApplicationId && (d.OriginalAmount - d.OriginalProcessedAmount) != 0)
.Select(a => new InvoiceApplicationDto
{
Id = a.Id,
ApplicationNO = a.ApplicationNO,
Status = a.Status,
CustomerId = a.CustomerId,
CustomerName = a.CustomerName, //结算单位
InvoiceHeader = a.InvoiceHeader,
ApplyAmount = a.ApplyAmount,
InvoiceAmount = a.InvoiceAmount,
Currency = a.Currency,
Category = a.Category,
OrgId = a.OrgId, //所属部门
SaleDeptId = a.SaleDeptId, //所属分部
CreateBy = a.CreateBy, //申请人
CreateTime = a.CreateTime, //申请日期
InvoiceRemark = a.InvoiceRemark, //开票要求
Note = a.Note,
//原币金额
OriginalAmountList = SqlFunc.Subqueryable<ApplicationDetail>().Where(y => a.Id == y.ApplicationId)
.GroupBy(y => y.OriginalCurrency).ToList(y => new CurrencyAmount { Currency = y.OriginalCurrency, Amount = y.OriginalAmount })
});
var whereList = request.GetConditionalModels(Db);
var result = await query.Where(whereList).ToQueryPageAsync(request.PageCondition);
if (result.Data.Count > 0)
{
var userIds = result.Data.Select(x => x.CreateBy).Distinct();
var users = await Db.Queryable<SysUser>().Where(x => userIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToListAsync();
var orgIds = result.Data.Where(x => x.SaleDeptId.HasValue).Select(x => x.SaleDeptId)
.Union(result.Data.Where(x => x.OrgId.HasValue).Select(x => x.OrgId))
.Distinct();
var orgs = await Db.Queryable<SysOrg>().Where(x => orgIds.Contains(x.Id)).Select(x => new { x.Id, x.OrgName }).ToListAsync();
foreach (var item in result.Data)
{
item.CreateByName = users.Find(x => x.Id == item.CreateBy)?.UserName;
item.SaleDeptName = orgs.Find(x => x.Id == item.SaleDeptId)?.OrgName;
item.OrgName = orgs.Find(x => x.Id == item.OrgId)?.OrgName;
}
}
return result;
}
}
}

@ -518,5 +518,28 @@ namespace DS.WMS.Core.Invoice.Method
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
} }
/// <summary>
/// 设置发票的作废状态
/// </summary>
/// <param name="isCancelled">是否锁定</param>
/// <param name="ids">发票ID</param>
/// <returns></returns>
public async Task<DataResult> SetCancelAsync(bool isCancelled, params long[] ids)
{
var dt = DateTime.Now;
var userId = long.Parse(User.UserId);
var list = ids.Select(x => new TEntity
{
Id = x,
IsCancelled = isCancelled,
CancelTime = isCancelled ? dt : null,
CancelUserId = isCancelled ? userId : null
}).ToList();
int rows = await TenantDb.Updateable(list)
.UpdateColumns(x => new { x.IsCancelled, x.CancelTime, x.CancelUserId }).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
} }
} }

@ -1,5 +1,4 @@
using DS.Module.Core; using DS.Module.Core;
using DS.Module.Core.Data;
using DS.WMS.Core.Application.Dtos; using DS.WMS.Core.Application.Dtos;
using DS.WMS.Core.Fee.Dtos; using DS.WMS.Core.Fee.Dtos;
using DS.WMS.Core.Invoice.Dto; using DS.WMS.Core.Invoice.Dto;
@ -72,48 +71,5 @@ namespace DS.WMS.FeeApi.Controllers
return await _service.SaveAsync(request); return await _service.SaveAsync(request);
} }
/// <summary>
/// 删除发票明细
/// </summary>
/// <param name="model">发票明细ID</param>
/// <returns></returns>
[HttpPost, Route("DeleteDetail")]
public async Task<DataResult> DeleteDetailAsync([FromBody] IdModel model)
{
if (!ModelState.IsValid)
return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
return await _service.DeleteDetailAsync(model.Ids);
}
/// <summary>
/// 删除发票
/// </summary>
/// <param name="model">发票ID</param>
/// <returns></returns>
[HttpPost, Route("Delete")]
public async Task<DataResult> DeleteAsync([FromBody] IdModel model)
{
if (!ModelState.IsValid)
return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
return await _service.DeleteAsync(model.Ids);
}
/// <summary>
/// 设置发票的锁定状态
/// </summary>
/// <param name="model">发票ID</param>
/// <returns></returns>
[HttpPost, Route("SetLock")]
public async Task<DataResult> SetLockAsync([FromBody] IdModel model)
{
if (!ModelState.IsValid)
return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
bool isLocked = Convert.ToBoolean(model.Value);
return await _service.SetLockAsync(isLocked, model.Ids);
}
} }
} }

@ -0,0 +1,95 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.WMS.Core.Invoice.Dto;
using DS.WMS.Core.Invoice.Dtos;
using DS.WMS.Core.Invoice.Entity;
using DS.WMS.Core.Invoice.Interface;
using Microsoft.AspNetCore.Mvc;
namespace DS.WMS.FeeApi.Controllers
{
/// <summary>
/// 标准按申请开票API
/// </summary>
public class GeneralInvoiceController : ApiController
{
readonly IGeneralInvoiceService _service;
/// <summary>
/// 初始化
/// </summary>
/// <param name="service"></param>
public GeneralInvoiceController(IGeneralInvoiceService service)
{
_service = service;
}
/// <summary>
/// 获取发票详情
/// </summary>
/// <param name="id">发票ID</param>
/// <returns></returns>
[HttpGet, Route("Get")]
public async Task<DataResult<InvoiceDto>> GetAsync(long id)
{
return await _service.GetAsync(id);
}
/// <summary>
/// 提交发票开票
/// </summary>
/// <param name="request">请求参数</param>
/// <returns></returns>
[HttpPost, Route("Save")]
public async Task<DataResult<Invoice>> SaveAsync(InvoiceRequest<Invoice> request)
{
if (!ModelState.IsValid)
return DataResult<Invoice>.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
return await _service.SaveAsync(request);
}
/// <summary>
/// 删除发票明细
/// </summary>
/// <param name="model">发票明细ID</param>
/// <returns></returns>
[HttpPost, Route("DeleteDetail")]
public async Task<DataResult> DeleteDetailAsync([FromBody] IdModel model)
{
if (!ModelState.IsValid)
return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
return await _service.DeleteDetailAsync(model.Ids);
}
/// <summary>
/// 删除发票
/// </summary>
/// <param name="model">发票ID</param>
/// <returns></returns>
[HttpPost, Route("Delete")]
public async Task<DataResult> DeleteAsync([FromBody] IdModel model)
{
if (!ModelState.IsValid)
return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
return await _service.DeleteAsync(model.Ids);
}
/// <summary>
/// 设置发票的锁定状态
/// </summary>
/// <param name="model">发票ID</param>
/// <returns></returns>
[HttpPost, Route("SetLock")]
public async Task<DataResult> SetLockAsync([FromBody] IdModel model)
{
if (!ModelState.IsValid)
return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
bool isLocked = Convert.ToBoolean(model.Value);
return await _service.SetLockAsync(isLocked, model.Ids);
}
}
}

@ -2798,3 +2798,10 @@
2024-07-16 11:28:24.8156 Info Validating config: TargetNames=console, ownFile-web, ConfigItems=54, FilePath=D:\Source\Repos\DS8\ds-wms-service\DS.WMS.FeeApi\bin\Debug\net8.0\nlog.config 2024-07-16 11:28:24.8156 Info Validating config: TargetNames=console, ownFile-web, ConfigItems=54, FilePath=D:\Source\Repos\DS8\ds-wms-service\DS.WMS.FeeApi\bin\Debug\net8.0\nlog.config
2024-07-16 11:28:24.8156 Warn Unused target detected. Add a rule for this target to the configuration. TargetName: allfile 2024-07-16 11:28:24.8156 Warn Unused target detected. Add a rule for this target to the configuration. TargetName: allfile
2024-07-16 11:28:24.8313 Info Configuration initialized. 2024-07-16 11:28:24.8313 Info Configuration initialized.
2024-07-16 14:04:36.2569 Info Registered target NLog.Targets.FileTarget(Name=allfile)
2024-07-16 14:04:36.2882 Info Registered target NLog.Targets.FileTarget(Name=ownFile-web)
2024-07-16 14:04:36.2985 Info Registered target NLog.Targets.ColoredConsoleTarget(Name=console)
2024-07-16 14:04:36.3120 Info NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c. File version: 5.2.8.2366. Product version: 5.2.8+f586f1341c46fa38aaaff4c641e7f0fa7e813943. GlobalAssemblyCache: False
2024-07-16 14:04:36.3120 Info Validating config: TargetNames=console, ownFile-web, ConfigItems=54, FilePath=D:\Source\Repos\DS8\ds-wms-service\DS.WMS.FeeApi\bin\Debug\net8.0\nlog.config
2024-07-16 14:04:36.3120 Warn Unused target detected. Add a rule for this target to the configuration. TargetName: allfile
2024-07-16 14:04:36.3280 Info Configuration initialized.

Loading…
Cancel
Save