-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSalesService.cs
More file actions
218 lines (175 loc) · 9.91 KB
/
Copy pathSalesService.cs
File metadata and controls
218 lines (175 loc) · 9.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
using System.Text;
using Serilog;
using SmartTalk.Core.Ioc;
using SmartTalk.Core.Services.Http.Clients;
using SmartTalk.Messages.Dto.Crm;
using SmartTalk.Messages.Dto.Sales;
namespace SmartTalk.Core.Services.Sale;
public interface ISalesService : IScopedDependency
{
Task<string> BuildCustomerItemsStringAsync(List<string> soldToIds, CancellationToken cancellationToken);
Task<string> HandleOrderArrivalTimeList(List<string> customerIds, CancellationToken cancellationToken);
Task<string> BuildCrmCustomerInfoByPhoneAsync(string phoneNumber, string crmToken, CancellationToken cancellationToken);
}
public class SalesService : ISalesService
{
private readonly ICrmClient _crmClient;
private readonly ISalesClient _salesClient;
public SalesService(ICrmClient crmClient,ISalesClient salesClient)
{
_crmClient = crmClient;
_salesClient = salesClient;
}
public async Task<string> BuildCustomerItemsStringAsync(List<string> soldToIds, CancellationToken cancellationToken)
{
var allItems = new List<string>();
if (soldToIds == null || soldToIds.Count == 0)
{
Log.Warning("BuildCustomerItemsStringAsync called with empty soldToIds");
return string.Empty;
}
foreach (var soldToId in soldToIds)
{
var askInfoResponse = await _salesClient
.GetAskInfoDetailListByCustomerAsync(
new GetAskInfoDetailListByCustomerRequestDto { CustomerNumbers = new List<string> { soldToId } },
cancellationToken).ConfigureAwait(false);
var askItems = askInfoResponse?.Data ?? new List<VwAskDetail>();
var orderResponse = await _salesClient
.GetOrderHistoryByCustomerAsync(new GetOrderHistoryByCustomerRequestDto { CustomerNumber = soldToId },
cancellationToken).ConfigureAwait(false);
var orderItems = orderResponse?.Data ?? new List<SalesOrderHistoryDto>();
var levelCodes = askItems.Where(x => !string.IsNullOrWhiteSpace(x.LevelCode))
.Select(x =>
{
var levelCode = x.LevelCode.Trim();
return levelCode[..Math.Min(levelCode.Length, 15)];
})
.Concat(orderItems.Where(x => !string.IsNullOrWhiteSpace(x.LevelCode))
.Select(x =>
{
var levelCode = x.LevelCode.Trim();
return levelCode[..Math.Min(levelCode.Length, 15)];
}))
.Where(x => !string.IsNullOrWhiteSpace(x))
.Distinct()
.ToList();
var materials = askItems.Where(x => !string.IsNullOrEmpty(x.Material)).Select(x => x.Material)
.Concat(orderItems.Where(x => !string.IsNullOrEmpty(x.MaterialNumber)).Select(x => x.MaterialNumber))
.Distinct().ToList();
var requestDto = new GetCustomerLevel5HabitRequstDto
{
CustomerId = soldToId,
LevelCode5List = levelCodes,
Material = materials
};
Log.Information("Sending GetCustomerLevel5HabitAsync with: {@RequestDto}", requestDto);
var habitResponse = levelCodes.Any()
? await _salesClient.GetCustomerLevel5HabitAsync(requestDto, cancellationToken).ConfigureAwait(false)
: null;
Log.Information("GetCustomerLevel5HabitAsync Response: {@HabitResponse}", habitResponse);
var habitLookup = habitResponse?.HistoryCustomerLevel5HabitDtos?
.Where(h => !string.IsNullOrWhiteSpace(h.LevelCode5))
.GroupBy(h =>
{
var levelCode = h.LevelCode5.Trim();
return levelCode[..Math.Min(levelCode.Length, 15)];
})
.ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase)
?? new Dictionary<string, HistoryCustomerLevel5HabitDto>(StringComparer.OrdinalIgnoreCase);
string FormatItem(string materialDesc, string levelCode = null, string materialNumber = null)
{
var parts = materialDesc?.Split('·') ?? Array.Empty<string>();
var name = parts.Length > 4 ? $"{parts[0]}{parts[4]}" : parts.FirstOrDefault() ?? "";
var brand = parts.Length > 1 ? parts[1] : "";
var size = parts.Length > 3 ? parts[3] : "";
string aliasText = "";
MaterialPartInfoDto partInfo = null;
var normalizedLevelCode = string.IsNullOrWhiteSpace(levelCode)
? string.Empty
: levelCode.Trim()[..Math.Min(levelCode.Trim().Length, 15)];
if (!string.IsNullOrEmpty(normalizedLevelCode) && habitLookup.TryGetValue(normalizedLevelCode, out var habit))
{
aliasText = habit.CustomerLikeNames != null && habit.CustomerLikeNames.Any()
? string.Join(", ", habit.CustomerLikeNames.Select(n => n.CustomerLikeName))
: "";
partInfo = habit.MaterialPartInfoDtos?.FirstOrDefault(p =>
string.Equals(p.MaterialNumber, materialNumber, StringComparison.OrdinalIgnoreCase));
}
return $"Item: {name}, Brand: {brand}, Size: {size}, Aliases: {aliasText}, " +
$"baseUnit: {partInfo?.BaseUnit ?? ""}, salesUnit: {partInfo?.SalesUnit ?? ""}, weights: {partInfo?.Weights ?? 0}, " +
$"placeOfOrigin: {partInfo?.PlaceOfOrigin ?? ""}, packing: {partInfo?.Packing ?? ""}, specifications: {partInfo?.Specifications ?? ""}, " +
$"ranks: {partInfo?.Ranks ?? ""}, atr: {partInfo?.Atr}";
}
allItems.AddRange(askItems.Select(x => FormatItem(x.MaterialDesc, x.LevelCode, x.Material)));
allItems.AddRange(orderItems.Select(x => FormatItem(x.MaterialDescription, x.LevelCode, x.MaterialNumber)));
}
return string.Join(Environment.NewLine, allItems.Distinct().Take(150));
}
public async Task<string> HandleOrderArrivalTimeList(List<string> customerIds, CancellationToken cancellationToken)
{
var processedCustomerIds = customerIds.Select(id => "0000" + id).ToList();
var getOrderArrivalTimeList = await _salesClient.GetOrderArrivalTimeAsync(new GetOrderArrivalTimeRequestDto { CustomerIds = processedCustomerIds }, cancellationToken).ConfigureAwait(false);
if (getOrderArrivalTimeList.Data.Count == 0) return "这位客户暂时没有订单。";
var resultBuilder = new StringBuilder();
var notDeliveredOrders = getOrderArrivalTimeList.Data.Where(order => new[] { 0, 1, 2, 3, 5, 6, 8 }.Contains(order.OrderStatus)).ToList();
var deliveringOrders = getOrderArrivalTimeList.Data.Where(order => order.OrderStatus == 4).ToList();
var completedOrders = getOrderArrivalTimeList.Data.Where(order => order.OrderStatus == 7).ToList();
AppendOrderSection(resultBuilder, "未配送", notDeliveredOrders);
AppendOrderSection(resultBuilder, "配送中", deliveringOrders);
AppendOrderSection(resultBuilder, "已完成", completedOrders);
return resultBuilder.ToString();
}
public async Task<string> BuildCrmCustomerInfoByPhoneAsync(string phoneNumber, string crmToken, CancellationToken cancellationToken)
{
var customerInfo = new StringBuilder();
try
{
var crmCustomers = await _crmClient.GetCustomersByPhoneNumberAsync(new GetCustmoersByPhoneNumberRequestDto { PhoneNumber = phoneNumber }, crmToken, cancellationToken).ConfigureAwait(false);
if (crmCustomers != null && crmCustomers.Any())
{
foreach (var customer in crmCustomers)
{
customerInfo.AppendLine($"手机号 {phoneNumber}:");
customerInfo.AppendLine($"- SAP编号: {customer.SapId}");
customerInfo.AppendLine($"- 客户名称: {customer.CustomerName}");
customerInfo.AppendLine($"- 地址: {customer.Street}");
customerInfo.AppendLine($"- 仓库: {customer.Warehouse}");
customerInfo.AppendLine($"- 备注: {customer.HeaderNote1}");
if (customer.Contacts != null && customer.Contacts.Count > 0)
{
customerInfo.AppendLine(" 联系人信息:");
foreach (var c in customer.Contacts)
{
customerInfo.AppendLine($" - 姓名:{c.Name},电话:{c.Phone},身份:{c.Identity},语言:{c.Language}");
}
}
customerInfo.AppendLine();
}
}
else
{
customerInfo.AppendLine($"没有找到手机号 {phoneNumber} 的 CRM 客户信息");
}
}
catch (Exception ex)
{
Log.Error(ex, "Build CRM info failed for phone {PhoneNumber}", phoneNumber);
}
return customerInfo.ToString();
}
private void AppendOrderSection(StringBuilder builder, string sectionName, List<GetOrderArrivalTimeDataDto> orders)
{
if (orders.Count > 0)
{
builder.AppendLine($"{sectionName}:");
for (int i = 0; i < orders.Count; i++)
{
var order = orders[i];
builder.AppendLine(
$"{i + 1}. 订单号码:{order.SalesOrderNumber} ,客户ID:{order.CustomerId} ,预计送到时间:{order.EstimatedDeliveryTime}");
}
builder.AppendLine();
}
}
}