Skip to content

Commit 709dcc8

Browse files
authored
Improve Omnichannel Activity Managements (#472)
1 parent 46b52aa commit 709dcc8

67 files changed

Lines changed: 1932 additions & 616 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Abstractions/CrestApps.OrchardCore.ContentTransfer.Abstractions/IContentImportRowFilter.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
#nullable enable
22

3-
using System.Data;
4-
using OrchardCore.ContentManagement.Metadata.Models;
5-
63
namespace CrestApps.OrchardCore.ContentTransfer;
74

85
/// <summary>

src/Core/CrestApps.OrchardCore.ContentTransfer.Core/Models/ImportContentOptionsPart.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ public sealed class ImportContentOptionsPart
88
/// <summary>
99
/// Gets or sets a value indicating whether imported content should be published after it is saved.
1010
/// </summary>
11-
public bool PublishImportedContent { get; set; }
11+
public bool PublishImportedContent { get; set; } = true;
1212
}

src/Core/CrestApps.OrchardCore.Omnichannel.Core/Models/BulkManageActivityFilter.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,40 @@ public sealed class BulkManageActivityFilter : Entity
6363
/// </summary>
6464
public ActivityUrgencyLevel? UrgencyLevel { get; set; }
6565

66+
/// <summary>
67+
/// Gets or sets the maximum number of records to retrieve.
68+
/// When <see langword="null"/>, no limit is applied beyond normal pagination.
69+
/// </summary>
70+
public int? Limit { get; set; }
71+
72+
/// <summary>
73+
/// Gets or sets the phone number to search for in contact records.
74+
/// The value should be in E.164 format (e.g., +17025551234).
75+
/// </summary>
76+
public string PhoneNumber { get; set; }
77+
78+
/// <summary>
79+
/// Gets or sets the match type for the phone number filter.
80+
/// </summary>
81+
public PhoneNumberMatchType PhoneNumberMatchType { get; set; }
82+
83+
/// <summary>
84+
/// Gets or sets the time zone identifiers to filter contacts by.
85+
/// </summary>
86+
public string[] TimeZoneIds { get; set; }
87+
88+
/// <summary>
89+
/// Gets or sets the earliest Do Not Call date to filter by.
90+
/// Matches contacts whose Do Not Call date is on or after this value.
91+
/// </summary>
92+
public DateTime? DoNotCallFrom { get; set; }
93+
94+
/// <summary>
95+
/// Gets or sets the latest Do Not Call date to filter by.
96+
/// Matches contacts whose Do Not Call date is on or before this value.
97+
/// </summary>
98+
public DateTime? DoNotCallTo { get; set; }
99+
66100
/// <summary>
67101
/// Gets or sets the route values for preserving filter state during pagination.
68102
/// </summary>

src/Core/CrestApps.OrchardCore.Omnichannel.Core/Models/OmnichannelActivityBatch.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,38 @@ public sealed class OmnichannelActivityBatch : CatalogItem, IDisplayTextAwareMod
114114
/// </summary>
115115
public bool OnlyPublishedLeads { get; set; } = true;
116116

117+
/// <summary>
118+
/// Gets or sets the maximum number of leads to load into the batch.
119+
/// When <see langword="null"/>, all matching leads are loaded.
120+
/// </summary>
121+
public int? Limit { get; set; }
122+
123+
/// <summary>
124+
/// Gets or sets the phone number to filter leads by.
125+
/// The value should be in E.164 format (e.g., +17025551234).
126+
/// </summary>
127+
public string PhoneNumber { get; set; }
128+
129+
/// <summary>
130+
/// Gets or sets the match type for the phone number filter.
131+
/// </summary>
132+
public PhoneNumberMatchType PhoneNumberMatchType { get; set; }
133+
134+
/// <summary>
135+
/// Gets or sets the time zone identifiers to filter leads by.
136+
/// </summary>
137+
public string[] TimeZoneIds { get; set; }
138+
139+
/// <summary>
140+
/// Gets or sets the subject content type of the last completed activity to filter leads by.
141+
/// </summary>
142+
public string LastActivitySubjectContentType { get; set; }
143+
144+
/// <summary>
145+
/// Gets or sets the disposition identifier of the last completed activity to filter leads by.
146+
/// </summary>
147+
public string LastActivityDispositionId { get; set; }
148+
117149
/// <summary>
118150
/// Creates a copy of the current activity batch.
119151
/// </summary>
@@ -143,6 +175,12 @@ public OmnichannelActivityBatch Clone()
143175
LeadCreatedFrom = LeadCreatedFrom,
144176
LeadCreatedTo = LeadCreatedTo,
145177
OnlyPublishedLeads = OnlyPublishedLeads,
178+
Limit = Limit,
179+
PhoneNumber = PhoneNumber,
180+
PhoneNumberMatchType = PhoneNumberMatchType,
181+
TimeZoneIds = TimeZoneIds?.ToArray(),
182+
LastActivitySubjectContentType = LastActivitySubjectContentType,
183+
LastActivityDispositionId = LastActivityDispositionId,
146184
};
147185
}
148186
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace CrestApps.OrchardCore.Omnichannel.Core.Models;
2+
3+
/// <summary>
4+
/// Defines how a phone number filter value should be matched against stored phone numbers.
5+
/// </summary>
6+
public enum PhoneNumberMatchType
7+
{
8+
/// <summary>
9+
/// Match phone numbers that exactly equal the given value.
10+
/// </summary>
11+
Exact,
12+
13+
/// <summary>
14+
/// Match phone numbers that start with the given value.
15+
/// </summary>
16+
BeginsWith,
17+
18+
/// <summary>
19+
/// Match phone numbers that end with the given value.
20+
/// </summary>
21+
EndsWith,
22+
}
Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
using CrestApps.OrchardCore.Omnichannel.Core.Indexes;
21
using CrestApps.OrchardCore.Omnichannel.Core.Models;
32
using YesSql;
43

54
namespace CrestApps.OrchardCore.Omnichannel.Core.Services;
65

76
/// <summary>
8-
/// Represents the context for bulk manage activity filtering, containing both the filter criteria and the query to modify.
7+
/// Represents the context for bulk manage activity filtering.
8+
/// Handlers use the <see cref="SqlBuilder"/> to add INNER JOIN / LEFT JOIN
9+
/// and WHERE clauses that will be executed as a single server-side SQL query.
910
/// </summary>
1011
public sealed class BulkManageActivityFilterContext
1112
{
@@ -15,20 +16,67 @@ public sealed class BulkManageActivityFilterContext
1516
public BulkManageActivityFilter Filter { get; }
1617

1718
/// <summary>
18-
/// Gets or sets the query to apply filtering to.
19+
/// Gets the SQL query builder. Handlers add JOINs and WHERE clauses to this builder.
20+
/// The base query already selects from the activity index table with alias "a"
21+
/// and includes the base conditions (Status=NotStated, InteractionType=Manual).
1922
/// </summary>
20-
public IQuery<OmnichannelActivity, OmnichannelActivityIndex> Query { get; set; }
23+
public ISqlBuilder SqlBuilder { get; }
24+
25+
/// <summary>
26+
/// Gets the SQL dialect for quoting table/column names.
27+
/// </summary>
28+
public ISqlDialect Dialect { get; }
29+
30+
/// <summary>
31+
/// Gets the table prefix for constructing full table names.
32+
/// </summary>
33+
public string TablePrefix { get; }
34+
35+
/// <summary>
36+
/// Gets the table naming convention used to resolve collection-aware index table names.
37+
/// </summary>
38+
public ITableNameConvention TableNameConvention { get; }
39+
40+
/// <summary>
41+
/// Gets the database schema, if any.
42+
/// </summary>
43+
public string Schema { get; }
44+
45+
/// <summary>
46+
/// Gets the query parameters dictionary. Handlers add parameterized values here.
47+
/// </summary>
48+
public Dictionary<string, object> Parameters => SqlBuilder.Parameters;
49+
50+
/// <summary>
51+
/// Gets the alias used for the activity index table in the query.
52+
/// </summary>
53+
public string ActivityTableAlias { get; }
2154

2255
/// <summary>
2356
/// Initializes a new instance of the <see cref="BulkManageActivityFilterContext"/> class.
2457
/// </summary>
2558
/// <param name="filter">The filter criteria.</param>
26-
/// <param name="query">The query to filter.</param>
59+
/// <param name="sqlBuilder">The SQL builder to compose the query.</param>
60+
/// <param name="dialect">The SQL dialect.</param>
61+
/// <param name="tablePrefix">The table prefix.</param>
62+
/// <param name="tableNameConvention">The table naming convention.</param>
63+
/// <param name="schema">The database schema.</param>
64+
/// <param name="activityTableAlias">The alias for the activity index table.</param>
2765
public BulkManageActivityFilterContext(
2866
BulkManageActivityFilter filter,
29-
IQuery<OmnichannelActivity, OmnichannelActivityIndex> query)
67+
ISqlBuilder sqlBuilder,
68+
ISqlDialect dialect,
69+
string tablePrefix,
70+
ITableNameConvention tableNameConvention,
71+
string schema,
72+
string activityTableAlias)
3073
{
3174
Filter = filter;
32-
Query = query;
75+
SqlBuilder = sqlBuilder;
76+
Dialect = dialect;
77+
TablePrefix = tablePrefix;
78+
TableNameConvention = tableNameConvention;
79+
Schema = schema;
80+
ActivityTableAlias = activityTableAlias;
3381
}
3482
}

0 commit comments

Comments
 (0)