Files
OnboardXAdmin/SimpleAdmin.Application/Services/Onboarding/TaskContractVariable/OnboardingTaskContractVariableService.cs
T
2026-08-25 10:20:53 +08:00

156 lines
5.9 KiB
C#

namespace SimpleAdmin.Application;
/// <summary>
/// 管理端在链接发送前填写合同薪资、补贴等人事变量。
/// </summary>
public class OnboardingTaskContractVariableService : IOnboardingTaskContractVariableService
{
private readonly SqlSugarScope _db;
public OnboardingTaskContractVariableService()
=> _db = DbContext.DB;
/// <summary>
/// 查询任务下全部合同及其变量当前值。
/// </summary>
public async Task<List<OnboardingTaskContractVariableOutput>> List(
OnboardingTaskContractVariableQueryInput input)
{
var task = await _db.Queryable<ObOnboardingTask>()
.InSingleAsync(input.TaskId)
?? throw Oops.Bah("入职任务不存在");
var contracts = await _db.Queryable<ObTaskContract>()
.Where(x => x.TaskId == task.Id)
.ToListAsync();
var contractIds = contracts.Select(x => x.Id).ToList();
var templateVersionIds = contracts.Select(x => x.TemplateVersionId).ToList();
var variables = await _db.Queryable<ObTaskContractVariable>()
.Where(x => contractIds.Contains(x.TaskContractId))
.ToListAsync();
var definitions = await _db.Queryable<ObTemplateVariable>()
.Where(x => templateVersionIds.Contains(x.TemplateVersionId))
.ToListAsync();
return contracts.Select(contract => new OnboardingTaskContractVariableOutput
{
TaskContractId = contract.Id,
ContractName = contract.ContractName,
ContractType = contract.ContractType,
Variables = variables
.Where(variable => variable.TaskContractId == contract.Id)
.OrderBy(variable => variable.VariableCode)
.Select(variable =>
{
var definition = definitions.FirstOrDefault(x =>
x.TemplateVersionId == contract.TemplateVersionId &&
x.VariableCode == variable.VariableCode);
var hrEditable = definition?.HrEditable == true;
return new OnboardingTaskContractVariableItemOutput
{
Id = variable.Id,
VariableCode = variable.VariableCode,
VariableName = variable.VariableName,
VariableType = variable.VariableType,
DataType = variable.DataType,
VariableValue = variable.VariableValue,
Required = definition?.Required == true,
HrEditable = hrEditable,
Editable =
variable.VariableType == ContractVariableType.Contract ||
(variable.VariableType == ContractVariableType.Company && hrEditable)
};
})
.ToList()
}).ToList();
}
/// <summary>
/// 保存允许人事编辑的任务合同变量值。
/// </summary>
public async Task Save(OnboardingTaskContractVariableSaveInput input)
{
var contract = await _db.Queryable<ObTaskContract>()
.InSingleAsync(input.TaskContractId)
?? throw Oops.Bah("任务合同不存在");
var task = await _db.Queryable<ObOnboardingTask>()
.InSingleAsync(contract.TaskId)
?? throw Oops.Bah("入职任务不存在");
if (task.TaskStatus != OnboardingTaskStatus.PendingFill &&
task.TaskStatus != OnboardingTaskStatus.Rejected)
{
throw Oops.Bah("任务已提交审核,不能再修改合同参数");
}
var valueIds = input.Values
.Select(x => x.Id)
.Distinct()
.ToList();
var rows = await _db.Queryable<ObTaskContractVariable>()
.Where(x =>
x.TaskContractId == contract.Id &&
valueIds.Contains(x.Id))
.ToListAsync();
if (rows.Count != valueIds.Count)
{
throw Oops.Bah("包含不属于该合同的变量");
}
var variableCodes = rows
.Select(x => x.VariableCode)
.ToList();
var definitions = await _db.Queryable<ObTemplateVariable>()
.Where(x =>
x.TemplateVersionId == contract.TemplateVersionId &&
variableCodes.Contains(x.VariableCode))
.ToListAsync();
foreach (var row in rows)
{
var definition = definitions.FirstOrDefault(x =>
x.VariableCode == row.VariableCode)
?? throw Oops.Bah("合同变量定义不存在");
if (row.VariableType != ContractVariableType.Contract &&
!(row.VariableType == ContractVariableType.Company &&
definition.HrEditable))
{
throw Oops.Bah($"变量“{row.VariableName}”不允许人事手工修改");
}
var inputValue = input.Values.First(x => x.Id == row.Id);
row.VariableValue = inputValue.VariableValue;
row.SourceType = ContractVariableSourceType.HrInput;
// 标记为手工覆盖后,后续刷新员工或公司自动变量时保留该值。
row.IsManualOverride = true;
}
if (rows.Count > 0)
{
await _db.Updateable(rows)
.ExecuteCommandAsync();
// 人事参数变化后,原合同文件和员工确认必须失效,避免员工确认旧内容。
contract.GeneratedDocxFileId = null;
contract.GeneratedPdfFileId = null;
contract.GeneratedAt = null;
contract.ReadAt = null;
contract.ConfirmedAt = null;
contract.ContractStatus = TaskContractStatus.PendingGenerate;
await _db.Updateable(contract).ExecuteCommandAsync();
}
}
}