往来单位数据导入

dev
嵇文龙 1 month ago
parent 8f5757854f
commit 5d11966440

@ -0,0 +1,83 @@
namespace DS.WMS.Core.Info.Dtos
{
/// <summary>
/// 往来单位银行与发票导入模型
/// </summary>
public class InfoClientBankModel
{
/// <summary>
/// 公司名称
/// </summary>
public string? CompanyName { get; set; }
/// <summary>
/// 币种
/// </summary>
public string? Currency { get; set; }
/// <summary>
/// 银行名称
/// </summary>
public string? BankName { get; set; }
/// <summary>
/// 银行账号
/// </summary>
public string? BankAccount { get; set; }
/// <summary>
/// 银行地址
/// </summary>
public string? BankAddress { get; set; }
/// <summary>
/// 发票地址
/// </summary>
public string? InvoiceAddress { get; set; }
/// <summary>
/// 发票收件人
/// </summary>
public string? InvoiceRecevier { get; set; }
/// <summary>
/// 联系电话
/// </summary>
public string? Tel { get; set; }
/// <summary>
/// 纳税人识别号
/// </summary>
public string? TaxId { get; set; }
/// <summary>
/// 开票电话
/// </summary>
public string? InvoiceTel { get; set; }
/// <summary>
/// 备注
/// </summary>
public string? Remark { get; set; }
/// <summary>
/// 发票抬头
/// </summary>
public string? InvoiceHeader { get; set; }
/// <summary>
/// 默认应付
/// </summary>
public bool IsDefaultP { get; set; }
/// <summary>
/// 默认应收
/// </summary>
public bool IsDefaultR { get; set; }
/// <summary>
/// 默认银行
/// </summary>
public bool IsDefault { get; set; }
}
}

@ -0,0 +1,53 @@
namespace DS.WMS.Core.Info.Dtos
{
/// <summary>
/// 往来单位联系人导入模型
/// </summary>
public class InfoClientContactModel
{
/// <summary>
/// 所属公司
/// </summary>
public string? CompanyName { get; set; }
/// <summary>
/// 联系人名称
/// </summary>
public string? ContactName { get; set; }
/// <summary>
/// 联系人英文名
/// </summary>
public string? ContactEnName { get; set; }
/// <summary>
/// 电话
/// </summary>
public string? Tel { get; set; }
/// <summary>
/// 手机
/// </summary>
public string? Mobile { get; set; }
/// <summary>
/// 邮箱
/// </summary>
public string? Email { get; set; }
/// <summary>
/// QQ
/// </summary>
public string? QQ { get; set; }
/// <summary>
/// 职务
/// </summary>
public string? Job { get; set; }
/// <summary>
/// 是否默认联系人
/// </summary>
public bool IsDefault { get; set; }
}
}

@ -75,6 +75,11 @@
/// </summary>
public string? Attribute { get; set; }
/// <summary>
/// 客户属性
/// </summary>
public string[] AttributeNames => Attribute == null ? [] : Attribute.Split(',', StringSplitOptions.RemoveEmptyEntries);
/// <summary>
/// 商务
/// </summary>

@ -33,4 +33,11 @@ public interface IClientBankService
/// <param name="req"></param>
/// <returns></returns>
Task<DataResult> DeleteAsync(IdModel req);
/// <summary>
/// 导入客户银行
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
Task<DataResult> ImportAsync(List<InfoClientBankModel> list);
}

@ -35,4 +35,11 @@ public interface IClientContactService
/// <param name="model"></param>
/// <returns></returns>
Task<DataResult> DeleteAsync(IdModel model);
/// <summary>
/// 导入客户联系人
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
Task<DataResult> ImportAsync(List<InfoClientContactModel> list);
}

@ -1,6 +1,8 @@
using System.Text;
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Info.Dtos;
using DS.WMS.Core.Info.Entity;
using DS.WMS.Core.Info.Interface;
@ -111,4 +113,94 @@ public class ClientBankService : ServiceBase, IClientBankService
int rows = await TenantDb.Deleteable<InfoClientBank>().Where(x => req.Ids.Contains(x.Id)).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
/// <summary>
/// 导入客户银行
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public async Task<DataResult> ImportAsync(List<InfoClientBankModel> list)
{
long userId = long.Parse(User.UserId);
DateTime dtNow = DateTime.Now;
var clientNames = list.Select(x => x.CompanyName).Distinct();
var clients = await TenantDb.Queryable<InfoClient>().Where(x => clientNames.Contains(x.ShortName))
.Select(x => new
{
x.Id,
x.ShortName,
x.OrgId
}).ToListAsync();
StringBuilder sb = new();
List<InfoClientBank> banks = new List<InfoClientBank>(list.Count);
foreach (var model in list)
{
var client = clients.Find(x => x.ShortName == model.CompanyName);
if (client == null)
{
sb.Append("," + model.CompanyName);
continue;
}
InfoClientBank bank = new()
{
ClientId = client.Id,
OrgId = client.OrgId,
BankName = model.BankName,
Account = model.BankAccount,
BankAddress = model.BankAddress,
BankAccountNo = model.BankAccount,
IsInvoiceDefault = model.IsDefault,
CreateBy = userId,
CreateUserName = User.UserName,
CreateTime = dtNow,
InvoiceHeaders = []
};
if (model.Currency == "人民币")
bank.Currency = FeeCurrency.RMB_CODE;
else if (model.Currency == "美元")
bank.Currency = FeeCurrency.USD_CODE;
bank.InvoiceHeaders.Add(new InvoiceHeader
{
Header = model.InvoiceHeader,
AddressTel = model.InvoiceAddress + " " + model.InvoiceTel
});
banks.Add(bank);
}
if (sb.Length > 0)
{
sb.Remove(0, 1);
return DataResult.Failed("下列【公司名称】匹配不到客户/供应商:" + sb.ToString());
}
await TenantDb.Ado.BeginTranAsync();
try
{
await TenantDb.Fastest<InfoClientBank>().BulkMergeAsync(banks);
foreach (var bank in banks)
{
foreach (var item in bank.InvoiceHeaders)
item.RelativeId = bank.Id;
}
var invoiceHeaders = banks.SelectMany(x => x.InvoiceHeaders).ToList();
await TenantDb.Fastest<InvoiceHeader>().BulkMergeAsync(invoiceHeaders);
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.Failed("导入失败:" + ex.Message);
}
}
}

@ -1,10 +1,13 @@
using System.Text;
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Info.Dtos;
using DS.WMS.Core.Info.Entity;
using DS.WMS.Core.Info.Interface;
using Mapster;
using Masuit.Tools.Models;
namespace DS.WMS.Core.Info.Method;
@ -87,4 +90,75 @@ public class ClientContactService : ServiceBase, IClientContactService
int rows = await TenantDb.Deleteable<InfoClientContact>().Where(x => model.Ids.Contains(x.Id)).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
/// <summary>
/// 导入客户联系人
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public async Task<DataResult> ImportAsync(List<InfoClientContactModel> list)
{
long userId = long.Parse(User.UserId);
DateTime dtNow = DateTime.Now;
var clientNames = list.Select(x => x.CompanyName).Distinct();
var clients = await TenantDb.Queryable<InfoClient>().Where(x => clientNames.Contains(x.ShortName))
.Select(x => new
{
x.Id,
x.ShortName,
x.OrgId
}).ToListAsync();
StringBuilder sb = new();
List<InfoClientContact> contacts = new List<InfoClientContact>(list.Count);
foreach (var model in list)
{
var client = clients.Find(x => x.ShortName == model.CompanyName);
if (client == null)
{
sb.Append("," + model.CompanyName);
continue;
}
InfoClientContact contact = new()
{
ClientId = client.Id,
OrgId = client.OrgId,
CreateBy = userId,
CreateUserName = User.UserName,
CreateTime = dtNow,
Name = model.ContactName,
EnName = model.ContactEnName,
Job = model.Job,
Email = model.Email,
Mobile = model.Mobile,
Tel = model.Tel,
QQ = model.QQ,
IsDefault = model.IsDefault
};
contacts.Add(contact);
}
if (sb.Length > 0)
{
sb.Remove(0, 1);
return DataResult.Failed("下列【所属公司】匹配不到客户/供应商:" + sb.ToString());
}
await TenantDb.Ado.BeginTranAsync();
try
{
await TenantDb.Fastest<InfoClientContact>().BulkMergeAsync(contacts);
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.Failed("导入失败:" + ex.Message);
}
}
}

@ -261,7 +261,7 @@ public class ClientInfoService : ServiceBase, IClientInfoService
long userId = long.Parse(User.UserId);
DateTime dtNow = DateTime.Now;
var attrbutes = list.Select(x => x.Attribute).Where(x => !string.IsNullOrEmpty(x)).Distinct();
var attrbutes = list.SelectMany(x => x.AttributeNames).Where(x => !string.IsNullOrEmpty(x)).Distinct();
var dicList = await Db.Queryable<SysDictData>().InnerJoin<SysDictType>((d, t) => d.TypeId == t.Id)
.Where((d, t) => t.Code == "infoclient-ArrclientTag" && attrbutes.Contains(d.Name))
.Select((d, t) => new
@ -306,12 +306,12 @@ public class ClientInfoService : ServiceBase, IClientInfoService
IsSupplier = model.IsSupplier,
OperatorId = users.Find(x => x.UserName == model.OP)?.Id,
OperatorName = model.OP,
Name = model.CNName,
OrgId = (users.Find(x => x.UserName == model.Sale)?.DefaultOrgId).GetValueOrDefault(),
Sale = model.Sale,
SaleId = users.Find(x => x.UserName == model.Sale)?.Id,
QQ = model.QQ,
ShortName = model.CNName,
Description = model.CNName,
Tel = model.Tel,
Note = "系统导入",
ClientTag = new InfoClientTag(),
@ -337,17 +337,17 @@ public class ClientInfoService : ServiceBase, IClientInfoService
CreateTime = dtNow,
});
client.Contacts.Add(new InfoClientContact
{
Name = model.ContactName,
Address = model.Address,
Email = model.Email,
Mobile = model.Phone,
Tel = model.Tel,
QQ = model.QQ,
IsDefault = true,
OrgId = client.OrgId
});
//client.Contacts.Add(new InfoClientContact
//{
// Name = model.ContactName,
// Address = model.Address,
// Email = model.Email,
// Mobile = model.Phone,
// Tel = model.Tel,
// QQ = model.QQ,
// IsDefault = true,
// OrgId = client.OrgId
//});
clients.Add(client);
}
@ -355,13 +355,23 @@ public class ClientInfoService : ServiceBase, IClientInfoService
await TenantDb.Ado.BeginTranAsync();
try
{
await TenantDb.Storageable(clients).WhereColumns(x => new { x.ShortName, x.Description }).ExecuteCommandAsync();
await TenantDb.Fastest<InfoClient>().BulkMergeAsync(clients);
foreach (var client in clients)
{
client.ClientTag.ClientId = client.Id;
foreach (var item in client.AccountDates)
item.ClientId = client.Id;
//foreach (var item in client.Contacts)
// item.ClientId = client.Id;
}
var accountDates = clients.SelectMany(x => x.AccountDates).ToList();
await TenantDb.Fastest<InfoClientAccountDate>().BulkMergeAsync(accountDates);
//await TenantDb.InsertNav(clients)
//.Include(x => x.ClientTag)
//.Include(x => x.AccountDates)
//.Include(x => x.Contacts)
//.ExecuteCommandAsync();
//var contacts = clients.SelectMany(x => x.Contacts).ToList();
//await TenantDb.Fastest<InfoClientContact>().BulkMergeAsync(contacts);
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;

@ -10,7 +10,7 @@ using MiniExcelLibs;
namespace DS.WMS.FeeApi.Controllers
{
/// <summary>
/// 往来单位费用模板API
/// 自动费用模板API
/// </summary>
public class FeeCustTemplateController : ApiController
{
@ -53,24 +53,13 @@ namespace DS.WMS.FeeApi.Controllers
/// </summary>
/// <returns></returns>
[HttpPost, Route("Import")]
public async Task<IActionResult> ImportAsync()
public async Task<IActionResult> ImportAsync(IFormFile file)
{
Stream? stream;
try
{
if (Request.Form.Files.Count == 0)
return BadRequest("请求不包含文件流");
stream = Request.Form.Files[0].OpenReadStream();
}
catch (InvalidOperationException)
{
stream = Request.Body;
}
if (file == null)
return BadRequest("请求未包含文件流");
MemoryStream ms = new();
await stream.CopyToAsync(ms);
var query = await MiniExcel.QueryAsync(ms, excelType: ExcelType.XLSX, startCell: "A4");
var stream = file.OpenReadStream();
var query = await MiniExcel.QueryAsync(stream, excelType: ExcelType.XLSX, startCell: "A4");
List<FeeCustTemplateModel> list = [];
try
{
@ -116,7 +105,6 @@ namespace DS.WMS.FeeApi.Controllers
}
var result = await _invokeService.ImportAsync(list);
ms.Dispose();
return Ok(result);
}

@ -191,7 +191,7 @@ namespace DS.WMS.FeeApi.Controllers
/// <param name="model">业务ID和类型</param>
/// <returns></returns>
[HttpPost, Route("ApplyBusinessAudit")]
public async Task<DataResult> ApplyBusinessAuditAsync(IdModel model)
public async Task<DataResult> ApplyBusinessAuditAsync([FromBody] IdModel model)
{
if (!long.TryParse(model.Id, out long bid) || model.BusinessType == null)
return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest);
@ -204,7 +204,8 @@ namespace DS.WMS.FeeApi.Controllers
/// </summary>
/// <param name="model">业务ID和类型</param>
/// <returns></returns>
public async Task<DataResult> WithdrawBusinessAsync(IdModel model)
[HttpPost, Route("WithdrawBusiness")]
public async Task<DataResult> WithdrawBusinessAsync([FromBody] IdModel model)
{
if (!long.TryParse(model.Id, out long bid) || model.BusinessType == null)
return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest);
@ -218,7 +219,7 @@ namespace DS.WMS.FeeApi.Controllers
/// <param name="model">费用记录ID</param>
/// <returns></returns>
[HttpPost, Route("GetPrintInfo")]
public async Task<DataResult<dynamic>> GetPrintInfoAsync(IdModel model)
public async Task<DataResult<dynamic>> GetPrintInfoAsync([FromBody] IdModel model)
{
if (model == null || model.Ids?.Length == 0)
return DataResult<dynamic>.Failed("参数无效", MultiLanguageConst.IllegalRequest);
@ -236,7 +237,7 @@ namespace DS.WMS.FeeApi.Controllers
/// <param name="model">费用记录ID</param>
/// <returns></returns>
[HttpPost, Route("SetInvoiceEnabled")]
public async Task<DataResult> SetInvoiceEnabledAsync(IdModel model)
public async Task<DataResult> SetInvoiceEnabledAsync([FromBody] IdModel model)
{
if (model == null || model.Ids?.Length == 0)
return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest);

@ -196,13 +196,12 @@ public class ClientInfoController : ApiController
#region 导入
/// <summary>
/// 导入客户/供应商
/// 导入客户
/// </summary>
/// <param name="type">类型1=客户2=供应商3=客户+供应商</param>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost, Route("Import")]
public async Task<DataResult> ImportAsync([FromForm] int type, IFormFile file)
[HttpPost, Route("ImportClient")]
public async Task<DataResult> ImportClientAsync(IFormFile file)
{
if (file == null)
return DataResult.Failed("请求未包含文件流");
@ -248,20 +247,76 @@ public class ClientInfoController : ApiController
Email = item["AF"]?.ToString(),
ContactName = item["AG"]?.ToString(),
NFDS = item["AP"] == null ? null : int.Parse(item["AP"].ToString()),
IsCustomer = true
};
//if (string.IsNullOrEmpty(model.DeptName))
// sb.Append($"行号:{rows.IndexOf(item) + 2} 未填写【所属部门】");
if (type == 3)
{
model.IsCustomer = model.IsSupplier = true;
}
else
list.Add(model);
}
if (sb.Length > 0)
return DataResult.Failed("导入失败:" + sb.ToString());
}
catch (Exception ex)
{
return DataResult.Failed("读取文件失败:" + ex.Message);
}
return await _invokeService.ImportAsync(list);
}
/// <summary>
/// 导入供应商
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost, Route("ImportSupplier")]
public async Task<DataResult> ImportSupplierAsync(IFormFile file)
{
if (file == null)
return DataResult.Failed("请求未包含文件流");
var stream = file.OpenReadStream();
var rows = (await MiniExcel.QueryAsync(stream, excelType: ExcelType.XLSX, startCell: "A2")).ToList();
StringBuilder sb = new StringBuilder();
List<InfoClientModel> list = [];
try
{
foreach (IDictionary<string, object> item in rows)
{
var model = new InfoClientModel
{
model.IsCustomer = type == 1;
model.IsSupplier = type == 2;
}
ContactTel = item["A"]?.ToString(),
Contact = item["B"]?.ToString(),
AgreementTerm = item["C"] == null ? null : DateTime.Parse(item["C"].ToString()),
StatusText = item["D"]?.ToString(),
Address = item["E"]?.ToString(),
CNName = item["F"]?.ToString(),
ENName = item["G"]?.ToString(),
ShortName = item["H"]?.ToString(),
TaxID = item["I"]?.ToString(),
Code = item["J"]?.ToString(),
StlType = item["K"]?.ToString(),
Attribute = item["V"]?.ToString(),
Business = item["L"]?.ToString(),
OP = item["M"]?.ToString(),
Sale = item["N"]?.ToString(),
CustomerService = item["P"]?.ToString(),
Authenticator = item["Q"]?.ToString(),
PrepaidRMB = item["R"] == null ? 0 : decimal.Parse(item["R"].ToString()),
PrepaidUSD = item["S"] == null ? 0 : decimal.Parse(item["S"].ToString()),
Quota = item["T"] == null ? 0 : decimal.Parse(item["T"].ToString()),
RestQuota = item["U"] == null ? 0 : decimal.Parse(item["U"].ToString()),
ContactName = item["B"]?.ToString(),
IsSupplier = true
};
//if (string.IsNullOrEmpty(model.DeptName))
// sb.Append($"行号:{rows.IndexOf(item) + 2} 未填写【所属部门】");
list.Add(model);
}
@ -278,6 +333,115 @@ public class ClientInfoController : ApiController
return await _invokeService.ImportAsync(list);
}
/// <summary>
/// 导入银行与发票
/// </summary>
/// <param name="service"></param>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost, Route("ImportBank")]
public async Task<DataResult> ImportBankAsync([FromServices] IClientBankService service, IFormFile file)
{
if (file == null)
return DataResult.Failed("请求未包含文件流");
var stream = file.OpenReadStream();
var rows = (await MiniExcel.QueryAsync(stream, excelType: ExcelType.XLSX, startCell: "A2")).ToList();
StringBuilder sb = new StringBuilder();
List<InfoClientBankModel> list = [];
try
{
foreach (IDictionary<string, object> item in rows)
{
var model = new InfoClientBankModel
{
CompanyName = item["A"]?.ToString(),
Currency = item["B"]?.ToString(),
BankName = item["C"]?.ToString(),
BankAccount = item["E"]?.ToString(),
BankAddress = item["F"]?.ToString(),
InvoiceAddress = item["G"]?.ToString(),
InvoiceRecevier = item["H"]?.ToString(),
Tel = item["I"]?.ToString(),
TaxId = item["J"]?.ToString(),
InvoiceTel = item["K"]?.ToString(),
Remark = item["L"]?.ToString(),
InvoiceHeader = item["M"]?.ToString(),
IsDefaultP = int.TryParse(item["N"]?.ToString(), out int value1) && value1 == 1,
IsDefaultR = int.TryParse(item["O"]?.ToString(), out int value2) && value2 == 1,
IsDefault = int.TryParse(item["P"]?.ToString(), out int value3) && value3 == 1,
};
if (string.IsNullOrEmpty(model.CompanyName))
sb.Append($"行号:{rows.IndexOf(item) + 2} 未填写【公司名称】");
list.Add(model);
}
if (sb.Length > 0)
return DataResult.Failed("导入失败:" + sb.ToString());
}
catch (Exception ex)
{
return DataResult.Failed("读取文件失败:" + ex.Message);
}
return await service.ImportAsync(list);
}
/// <summary>
/// 导入联系人
/// </summary>
/// <param name="service"></param>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost, Route("ImportContact")]
public async Task<DataResult> ImportContactAsync([FromServices] IClientContactService service, IFormFile file)
{
if (file == null)
return DataResult.Failed("请求未包含文件流");
var stream = file.OpenReadStream();
var rows = (await MiniExcel.QueryAsync(stream, excelType: ExcelType.XLSX, startCell: "A2")).ToList();
StringBuilder sb = new StringBuilder();
List<InfoClientContactModel> list = [];
try
{
foreach (IDictionary<string, object> item in rows)
{
var model = new InfoClientContactModel
{
CompanyName = item["A"]?.ToString(),
ContactName = item["B"]?.ToString(),
ContactEnName = item["C"]?.ToString(),
Tel = item["D"]?.ToString(),
Mobile = item["E"]?.ToString(),
Email = item["F"]?.ToString(),
QQ = item["G"]?.ToString(),
IsDefault = item["H"]?.ToString() == "是",
Job = item["I"]?.ToString()
};
if (string.IsNullOrEmpty(model.CompanyName))
sb.Append($"行号:{rows.IndexOf(item) + 2} 未填写【公司名称】");
list.Add(model);
}
if (sb.Length > 0)
return DataResult.Failed("导入失败:" + sb.ToString());
}
catch (Exception ex)
{
return DataResult.Failed("读取文件失败:" + ex.Message);
}
return await service.ImportAsync(list);
}
#endregion
}
Loading…
Cancel
Save