@burgan-tech/morph-touch-runtime 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/burgan-tech-morph-touch-runtime-0.0.2.tgz +0 -0
- package/package.json +21 -0
- package/touch/Extensions/.gitkeep +0 -0
- package/touch/Functions/.gitkeep +0 -0
- package/touch/Functions/check-livekit-room-access.1.0.0.json +28 -0
- package/touch/Functions/check-livekit-room-access.http +44 -0
- package/touch/Functions/get-absence-entry.1.0.0.json +28 -0
- package/touch/Functions/get-advisor-stats.1.0.0.json +27 -0
- package/touch/Functions/get-available-slots.1.0.0.json +30 -0
- package/touch/Functions/get-available-slots.http +29 -0
- package/touch/Functions/get-chat-rooms.1.0.0.json +28 -0
- package/touch/Functions/get-chat-rooms.http +62 -0
- package/touch/Functions/get-customer-info.1.0.0.json +27 -0
- package/touch/Functions/get-matrix-sync.1.0.0.json +28 -0
- package/touch/Functions/get-rezervations.1.0.0.json +26 -0
- package/touch/Functions/get-rezervations.http +59 -0
- package/touch/Functions/get-room-messages.1.0.0.json +29 -0
- package/touch/Functions/get-room-messages.http +45 -0
- package/touch/Functions/rezervation-transfer.http +118 -0
- package/touch/Functions/send-room-message.1.0.0.json +29 -0
- package/touch/Functions/src/CheckLivekitRoomAccessMapping.csx +238 -0
- package/touch/Functions/src/GetAbsenceEntryMapping.csx +225 -0
- package/touch/Functions/src/GetAdvisorStatsMapping.csx +190 -0
- package/touch/Functions/src/GetAvailableSlotsMapping.csx +468 -0
- package/touch/Functions/src/GetChatRoomsMapping.csx +202 -0
- package/touch/Functions/src/GetCustomerInfoMapping.csx +140 -0
- package/touch/Functions/src/GetMatrixSyncMapping.csx +197 -0
- package/touch/Functions/src/GetRezervationsMapping.csx +162 -0
- package/touch/Functions/src/GetRoomMessagesMapping.csx +165 -0
- package/touch/Functions/src/SendCancelNotificationMapping.csx +63 -0
- package/touch/Functions/src/SendRoomMessageMapping.csx +131 -0
- package/touch/Schemas/.gitkeep +0 -0
- package/touch/Schemas/absence-entry.1.0.0.json +232 -0
- package/touch/Schemas/advisor-chat-rooms.1.0.0.json +62 -0
- package/touch/Schemas/chat-room.1.0.0.json +110 -0
- package/touch/Schemas/notification-sender.1.0.0.json +159 -0
- package/touch/Schemas/portfolio-manager.1.0.0.json +63 -0
- package/touch/Schemas/rezervation.1.0.0.json +102 -0
- package/touch/Tasks/.gitkeep +0 -0
- package/touch/Tasks/cancel-absence-entry-for-rezervation.1.0.0.json +21 -0
- package/touch/Tasks/check-already-completed-chat-room.1.0.0.json +24 -0
- package/touch/Tasks/check-duplicate-portfolio-manager.1.0.0.json +23 -0
- package/touch/Tasks/check-duplicate-rezervation.1.0.0.json +23 -0
- package/touch/Tasks/check-existing-permanent-chat-room.1.0.0.json +21 -0
- package/touch/Tasks/check-randevu-time.1.0.0.json +17 -0
- package/touch/Tasks/create-permanent-chat-room.1.0.0.json +28 -0
- package/touch/Tasks/determine-transfer-type.1.0.0.json +16 -0
- package/touch/Tasks/enrich-rezervations-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/execute-permanent-chatroom-update.1.0.0.json +21 -0
- package/touch/Tasks/execute-rez-chatroom-transfer.1.0.0.json +21 -0
- package/touch/Tasks/execute-rezervation-transfer.1.0.0.json +19 -0
- package/touch/Tasks/fetch-absence-entries-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/fetch-advisors-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/fetch-permanent-chatrooms-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/fetch-rez-chatrooms-for-transfer.1.0.0.json +23 -0
- package/touch/Tasks/fetch-rezervations-for-transfer.1.0.0.json +22 -0
- package/touch/Tasks/get-absence-entry-task.1.0.0.json +23 -0
- package/touch/Tasks/get-available-slots-http.1.0.0.json +27 -0
- package/touch/Tasks/get-available-slots.1.0.0.json +24 -0
- package/touch/Tasks/get-chat-room-data-for-rezervation.1.0.0.json +23 -0
- package/touch/Tasks/get-chat-token.1.0.0.json +27 -0
- package/touch/Tasks/get-matrix-room-messages.1.0.0.json +25 -0
- package/touch/Tasks/get-matrix-sync.1.0.0.json +25 -0
- package/touch/Tasks/get-rezervation-data-task.1.0.0.json +22 -0
- package/touch/Tasks/get-rezervation-state-task.1.0.0.json +22 -0
- package/touch/Tasks/get-rezervations-task.1.0.0.json +21 -0
- package/touch/Tasks/get-user-info-for-rezervation.1.0.0.json +24 -0
- package/touch/Tasks/get-video-call-url.1.0.0.json +17 -0
- package/touch/Tasks/invite-user-to-rezervation-room.1.0.0.json +27 -0
- package/touch/Tasks/join-chat-room-for-rezervation.1.0.0.json +28 -0
- package/touch/Tasks/join-matrix-room.1.0.0.json +27 -0
- package/touch/Tasks/join-user-to-room.1.0.0.json +27 -0
- package/touch/Tasks/merge-invited-user.1.0.0.json +17 -0
- package/touch/Tasks/merge-rezervation-update.1.0.0.json +16 -0
- package/touch/Tasks/merge-target-advisor-for-transfer.1.0.0.json +17 -0
- package/touch/Tasks/merge-update-body-for-randevu-update.1.0.0.json +16 -0
- package/touch/Tasks/merge-video-call-urls.1.0.0.json +17 -0
- package/touch/Tasks/query-chat-room-instances.1.0.0.json +23 -0
- package/touch/Tasks/remove-member-from-room.1.0.0.json +28 -0
- package/touch/Tasks/send-matrix-room-message.1.0.0.json +26 -0
- package/touch/Tasks/send-push-notification.1.0.0.json +26 -0
- package/touch/Tasks/send-sms-notification.1.0.0.json +26 -0
- package/touch/Tasks/set-chat-room-status-active.1.0.0.json +16 -0
- package/touch/Tasks/set-chat-room-status-deactive.1.0.0.json +16 -0
- package/touch/Tasks/set-previous-advisor.1.0.0.json +16 -0
- package/touch/Tasks/set-user-from-headers-for-rezervation.1.0.0.json +17 -0
- package/touch/Tasks/start-absence-entry-for-rezervation.1.0.0.json +21 -0
- package/touch/Tasks/start-chat-room-for-rezervation.1.0.0.json +20 -0
- package/touch/Tasks/start-notification-sender.1.0.0.json +20 -0
- package/touch/Tasks/start-permanent-chat-room.1.0.0.json +21 -0
- package/touch/Tasks/start-transfer-from-absence-entry.1.0.0.json +19 -0
- package/touch/Tasks/start-video-call.1.0.0.json +22 -0
- package/touch/Tasks/trigger-chat-room-deactivate.1.0.0.json +21 -0
- package/touch/Tasks/trigger-chat-room-transfer.1.0.0.json +21 -0
- package/touch/Tasks/trigger-chat-room-update.1.0.0.json +20 -0
- package/touch/Tasks/trigger-rezervation-add-invited-participant.1.0.0.json +20 -0
- package/touch/Tasks/trigger-rezervation-apply-update.1.0.0.json +20 -0
- package/touch/Tasks/trigger-rezervation-to-in-meet.1.0.0.json +20 -0
- package/touch/Tasks/trigger-rezervation-video-call-update.1.0.0.json +21 -0
- package/touch/Tasks/validate-date-for-rezervation.1.0.0.json +18 -0
- package/touch/Tasks/validate-slot-for-rezervation.1.0.0.json +24 -0
- package/touch/Tasks/validate-transfer-availability.1.0.0.json +23 -0
- package/touch/Views/.gitkeep +0 -0
- package/touch/Workflows/.gitkeep +0 -0
- package/touch/Workflows/absence-entry.http +458 -0
- package/touch/Workflows/absence-entry.json +179 -0
- package/touch/Workflows/add-participant-to-rezervation.http +47 -0
- package/touch/Workflows/add-participant-to-rezervation.json +340 -0
- package/touch/Workflows/chat-room.http +207 -0
- package/touch/Workflows/chat-room.json +452 -0
- package/touch/Workflows/investment-advisor.json +367 -0
- package/touch/Workflows/notification-sender.http +299 -0
- package/touch/Workflows/notification-sender.json +262 -0
- package/touch/Workflows/portfolio-manager.json +367 -0
- package/touch/Workflows/randevu-update.http +87 -0
- package/touch/Workflows/rezervation-start.json +467 -0
- package/touch/Workflows/rezervation-transfer.json +512 -0
- package/touch/Workflows/rezervation-update.http +87 -0
- package/touch/Workflows/rezervation-update.json +485 -0
- package/touch/Workflows/rezervation.http +214 -0
- package/touch/Workflows/rezervation.json +726 -0
- package/touch/Workflows/src/AllChatRoomsSuccessRule.csx +65 -0
- package/touch/Workflows/src/AlwaysTrueRule.csx +13 -0
- package/touch/Workflows/src/AnyChatRoomFailedRule.csx +64 -0
- package/touch/Workflows/src/AutoProcessRule.csx +38 -0
- package/touch/Workflows/src/BuildRezChatRoomPlanMapping.csx +160 -0
- package/touch/Workflows/src/CanStartRezervationTimerMapping.csx +48 -0
- package/touch/Workflows/src/CanStartTransferMapping.csx +14 -0
- package/touch/Workflows/src/CancelAbsenceEntryForRezervationMapping.csx +48 -0
- package/touch/Workflows/src/CancelAbsenceForRandevuUpdateMapping.csx +62 -0
- package/touch/Workflows/src/ChatRoomCreatedFailedRule.csx +54 -0
- package/touch/Workflows/src/ChatRoomCreatedSuccessRule.csx +54 -0
- package/touch/Workflows/src/ChatRoomRemoveMapping.csx +104 -0
- package/touch/Workflows/src/ChatRoomTransferInviteMapping.csx +109 -0
- package/touch/Workflows/src/ChatRoomTransferRemoveMapping.csx +71 -0
- package/touch/Workflows/src/ChatRoomUpdateMapping.csx +107 -0
- package/touch/Workflows/src/CheckAlreadyCompletedChatRoomMapping.csx +100 -0
- package/touch/Workflows/src/CheckDuplicatePortfolioManagerMapping.csx +119 -0
- package/touch/Workflows/src/CheckDuplicateRezervationMapping.csx +150 -0
- package/touch/Workflows/src/CheckExistingPermanentChatRoomMapping.csx +169 -0
- package/touch/Workflows/src/CheckRandevuTimeMapping.csx +67 -0
- package/touch/Workflows/src/CheckRezervationStateActiveOrInMeetRule.csx +14 -0
- package/touch/Workflows/src/CreateAbsenceEntryForRezervationMapping.csx +111 -0
- package/touch/Workflows/src/CreateAbsenceForRandevuUpdateMapping.csx +108 -0
- package/touch/Workflows/src/CreateChatRoomForRezervationMapping.csx +122 -0
- package/touch/Workflows/src/CreatePermanentChatRoomMapping.csx +140 -0
- package/touch/Workflows/src/CustomerControlToEndRule.csx +14 -0
- package/touch/Workflows/src/DetermineTransferTypeMapping.csx +92 -0
- package/touch/Workflows/src/EnrichRezervationsForTransferMapping.csx +495 -0
- package/touch/Workflows/src/ExecutePermanentChatRoomUpdateMapping.csx +124 -0
- package/touch/Workflows/src/ExecuteRezChatRoomTransferMapping.csx +95 -0
- package/touch/Workflows/src/ExecuteTransferMapping.csx +152 -0
- package/touch/Workflows/src/FetchAbsenceEntriesForTransferMapping.csx +116 -0
- package/touch/Workflows/src/FetchAdvisorsForTransferMapping.csx +145 -0
- package/touch/Workflows/src/FetchPermanentChatRoomsMapping.csx +128 -0
- package/touch/Workflows/src/FetchRezervationsForTransferMapping.csx +124 -0
- package/touch/Workflows/src/GetChatRoomDataForRezervationMapping.csx +100 -0
- package/touch/Workflows/src/GetChatTokenMapping.csx +85 -0
- package/touch/Workflows/src/GetRezervationDataForAddParticipantMapping.csx +105 -0
- package/touch/Workflows/src/GetRezervationDataForRandevuUpdateMapping.csx +110 -0
- package/touch/Workflows/src/GetRezervationDataMapping.csx +111 -0
- package/touch/Workflows/src/GetRezervationStateForRandevuUpdateMapping.csx +80 -0
- package/touch/Workflows/src/GetRezervationStateMapping.csx +92 -0
- package/touch/Workflows/src/GetUserInfoForRezervationMapping.csx +63 -0
- package/touch/Workflows/src/GetVideoCallUrlMapping.csx +62 -0
- package/touch/Workflows/src/HasChangedAdvisorRule.csx +28 -0
- package/touch/Workflows/src/HasChatIntegrationRule.csx +41 -0
- package/touch/Workflows/src/HasExistingPermanentRoomRule.csx +28 -0
- package/touch/Workflows/src/InviteAdvisorForRandevuUpdateMapping.csx +86 -0
- package/touch/Workflows/src/InviteNewAdvisorToRezervationRoomMapping.csx +78 -0
- package/touch/Workflows/src/InviteNewParticipantToRandevuRoomMapping.csx +88 -0
- package/touch/Workflows/src/InvitedUserMergeMapping.csx +77 -0
- package/touch/Workflows/src/InvitedUserNotAllowedRule.csx +71 -0
- package/touch/Workflows/src/InvitedUserNotInMeetRule.csx +19 -0
- package/touch/Workflows/src/IsNotfSentRule.csx +36 -0
- package/touch/Workflows/src/JoinChatRoomForAddParticipantMapping.csx +118 -0
- package/touch/Workflows/src/JoinChatRoomForRandevuStartMapping.csx +119 -0
- package/touch/Workflows/src/JoinChatRoomForRezervationMapping.csx +118 -0
- package/touch/Workflows/src/JoinMatrixRoomMapping.csx +100 -0
- package/touch/Workflows/src/JoinUserToRoomMapping.csx +118 -0
- package/touch/Workflows/src/LoginForAddParticipantChatMapping.csx +102 -0
- package/touch/Workflows/src/LoginForRandevuStartChatMapping.csx +96 -0
- package/touch/Workflows/src/MergeRezervationUpdateMapping.csx +82 -0
- package/touch/Workflows/src/MergeTargetAdvisorForTransferMapping.csx +79 -0
- package/touch/Workflows/src/MergeUpdateBodyForRandevuUpdateMapping.csx +91 -0
- package/touch/Workflows/src/NoExistingPermanentRoomRule.csx +23 -0
- package/touch/Workflows/src/NotificationCompleteAlwaysRule.csx +14 -0
- package/touch/Workflows/src/NotificationCompleteFromPendingRule.csx +41 -0
- package/touch/Workflows/src/NotificationCompleteFromSmsRule.csx +36 -0
- package/touch/Workflows/src/NotificationPushFromPendingRule.csx +42 -0
- package/touch/Workflows/src/NotificationPushFromSmsRule.csx +36 -0
- package/touch/Workflows/src/NotificationSmsPendingRule.csx +32 -0
- package/touch/Workflows/src/PermanentDoneRule.csx +44 -0
- package/touch/Workflows/src/PermanentProcessNextRule.csx +44 -0
- package/touch/Workflows/src/RezChatRoomProcessNextRule.csx +44 -0
- package/touch/Workflows/src/RezChatRoomsDoneRule.csx +44 -0
- package/touch/Workflows/src/SendPushNotificationMapping.csx +146 -0
- package/touch/Workflows/src/SendSmsNotificationMapping.csx +138 -0
- package/touch/Workflows/src/SetChatRoomStatusActiveMapping.csx +22 -0
- package/touch/Workflows/src/SetChatRoomStatusDeactiveMapping.csx +22 -0
- package/touch/Workflows/src/SetPreviousAdvisorMapping.csx +28 -0
- package/touch/Workflows/src/SetUserFromHeadersForRezervationMapping.csx +24 -0
- package/touch/Workflows/src/SlotAvailableRule.csx +33 -0
- package/touch/Workflows/src/SlotUnavailableRule.csx +33 -0
- package/touch/Workflows/src/StartChatRoomForRezervationMapping.csx +100 -0
- package/touch/Workflows/src/StartGetChatTokenForRezervationMapping.csx +71 -0
- package/touch/Workflows/src/StartNotificationForAdvisorMapping.csx +117 -0
- package/touch/Workflows/src/StartNotificationForRezervationFromUserInfoMapping.csx +128 -0
- package/touch/Workflows/src/StartNotificationForUserMapping.csx +117 -0
- package/touch/Workflows/src/StartPermanentChatRoomMapping.csx +92 -0
- package/touch/Workflows/src/StartTransferFromAbsenceEntryMapping.csx +94 -0
- package/touch/Workflows/src/StartVideoCallCustomerSubFlowMapping.csx +37 -0
- package/touch/Workflows/src/StartVideoCallForInvitedParticipantMapping.csx +54 -0
- package/touch/Workflows/src/StartVideoCallForRandevuStartMapping.csx +70 -0
- package/touch/Workflows/src/StartVideoCallStaffSubFlowMapping.csx +37 -0
- package/touch/Workflows/src/StateActiveForUpdateRule.csx +14 -0
- package/touch/Workflows/src/StateActiveRule.csx +14 -0
- package/touch/Workflows/src/StateInMeetRule.csx +14 -0
- package/touch/Workflows/src/StateNotActiveForUpdateRule.csx +14 -0
- package/touch/Workflows/src/StateNotActiveOrInMeetRule.csx +14 -0
- package/touch/Workflows/src/StatusCustomerEnterRule.csx +25 -0
- package/touch/Workflows/src/StatusStaffEnterRule.csx +25 -0
- package/touch/Workflows/src/SyncWorkingHoursRule.csx +46 -0
- package/touch/Workflows/src/TokenSuccessRule.csx +24 -0
- package/touch/Workflows/src/TransferAllDoneRule.csx +50 -0
- package/touch/Workflows/src/TransferHasInvalidRule.csx +34 -0
- package/touch/Workflows/src/TransferProcessNextRule.csx +50 -0
- package/touch/Workflows/src/TriggerChatRoomDeactivateMapping.csx +77 -0
- package/touch/Workflows/src/TriggerChatRoomTransferMapping.csx +93 -0
- package/touch/Workflows/src/TriggerChatRoomUpdateMapping.csx +99 -0
- package/touch/Workflows/src/TriggerRezervationAddInvitedParticipantMapping.csx +77 -0
- package/touch/Workflows/src/TriggerRezervationApplyUpdateMapping.csx +66 -0
- package/touch/Workflows/src/TriggerRezervationToInMeetMapping.csx +69 -0
- package/touch/Workflows/src/TriggerRezervationVideoCallUpdateMapping.csx +67 -0
- package/touch/Workflows/src/ValidateDateForRezervationMapping.csx +60 -0
- package/touch/Workflows/src/ValidateSlotForRandevuUpdateMapping.csx +211 -0
- package/touch/Workflows/src/ValidateSlotForRezervationMapping.csx +246 -0
- package/touch/Workflows/src/ValidateTransferMapping.csx +243 -0
- package/touch/Workflows/src/VideoCallUrlUpdateMergeMapping.csx +141 -0
- package/touch/Workflows/start-chat.json +217 -0
- package/touch/Workflows/start-video-call.http +93 -0
- package/touch/Workflows/start-video-call.json +206 -0
- package/vnext.config.json +58 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using System.Threading.Tasks;
|
|
5
|
+
using BBT.Workflow.Scripting;
|
|
6
|
+
using BBT.Workflow.Definitions;
|
|
7
|
+
|
|
8
|
+
/// <summary>
|
|
9
|
+
/// Mapping for validate-slot-for-rezervation task in randevu-update flow.
|
|
10
|
+
/// Same logic as ValidateSlotForRezervationMapping - uses advisor, startDateTime, endDateTime from instance.
|
|
11
|
+
/// </summary>
|
|
12
|
+
internal sealed class GetAvailableSlotsExceptionRandevuUpdate : Exception
|
|
13
|
+
{
|
|
14
|
+
public GetAvailableSlotsExceptionRandevuUpdate(string message) : base(message) { }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public class ValidateSlotForRandevuUpdateMapping : ScriptBase, IMapping
|
|
18
|
+
{
|
|
19
|
+
public Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
20
|
+
{
|
|
21
|
+
try
|
|
22
|
+
{
|
|
23
|
+
var serviceTask = task as DaprServiceTask;
|
|
24
|
+
if (serviceTask == null)
|
|
25
|
+
throw new InvalidOperationException("Task must be a DaprServiceTask");
|
|
26
|
+
|
|
27
|
+
var appId = GetConfigValue("DAPR_APP_ID");
|
|
28
|
+
if (!string.IsNullOrEmpty(appId))
|
|
29
|
+
serviceTask.SetAppId(appId);
|
|
30
|
+
|
|
31
|
+
var data = context.Instance?.Data;
|
|
32
|
+
if (data == null)
|
|
33
|
+
throw new InvalidOperationException("Instance data is required");
|
|
34
|
+
|
|
35
|
+
var advisor = GetString(data, "advisor");
|
|
36
|
+
var startDateTimeStr = GetString(data, "startDateTime");
|
|
37
|
+
if (string.IsNullOrEmpty(advisor) || string.IsNullOrEmpty(startDateTimeStr))
|
|
38
|
+
{
|
|
39
|
+
return Task.FromResult(new ScriptResponse
|
|
40
|
+
{
|
|
41
|
+
Key = "validation-error",
|
|
42
|
+
Data = new { slotCheckResult = new { available = false, key = "validation-error" } }
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
DateTime startDateTime;
|
|
47
|
+
if (!DateTime.TryParse(startDateTimeStr, out startDateTime))
|
|
48
|
+
{
|
|
49
|
+
return Task.FromResult(new ScriptResponse
|
|
50
|
+
{
|
|
51
|
+
Key = "validation-error",
|
|
52
|
+
Data = new { slotCheckResult = new { available = false, key = "validation-error" } }
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
var dateStr = startDateTime.ToString("yyyy-MM-dd");
|
|
57
|
+
var queryParams = new List<string>
|
|
58
|
+
{
|
|
59
|
+
"advisorId=" + Uri.EscapeDataString(advisor),
|
|
60
|
+
"date=" + Uri.EscapeDataString(dateStr)
|
|
61
|
+
};
|
|
62
|
+
serviceTask.SetQueryString(string.Join("&", queryParams));
|
|
63
|
+
|
|
64
|
+
return Task.FromResult(new ScriptResponse());
|
|
65
|
+
}
|
|
66
|
+
catch (Exception ex)
|
|
67
|
+
{
|
|
68
|
+
return Task.FromResult(new ScriptResponse
|
|
69
|
+
{
|
|
70
|
+
Key = "input-error",
|
|
71
|
+
Data = new { slotCheckResult = new { available = false, key = "input-error", error = ex.Message } }
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
77
|
+
{
|
|
78
|
+
var body = context.Body;
|
|
79
|
+
if (body != null && body.isSuccess == false)
|
|
80
|
+
{
|
|
81
|
+
var dataNode = body.data ?? body.Data;
|
|
82
|
+
var detail = GetString(dataNode, "detail") ?? GetString(body, "errorMessage") ?? GetString(body, "detail");
|
|
83
|
+
throw new ArgumentException(detail ?? "", "");
|
|
84
|
+
}
|
|
85
|
+
try
|
|
86
|
+
{
|
|
87
|
+
var data = context.Instance?.Data;
|
|
88
|
+
if (data == null)
|
|
89
|
+
{
|
|
90
|
+
return Task.FromResult(new ScriptResponse
|
|
91
|
+
{
|
|
92
|
+
Data = new { slotCheckResult = new { available = false, key = "no-instance-data" } }
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
var startDateTimeStr = GetString(data, "startDateTime");
|
|
97
|
+
var endDateTimeStr = GetString(data, "endDateTime");
|
|
98
|
+
if (string.IsNullOrEmpty(startDateTimeStr) || string.IsNullOrEmpty(endDateTimeStr))
|
|
99
|
+
{
|
|
100
|
+
return Task.FromResult(new ScriptResponse
|
|
101
|
+
{
|
|
102
|
+
Data = new { slotCheckResult = new { available = false, key = "validation-error" } }
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
DateTime startDt = DateTime.MinValue;
|
|
107
|
+
DateTime endDt = DateTime.MinValue;
|
|
108
|
+
try
|
|
109
|
+
{
|
|
110
|
+
startDt = DateTime.Parse(startDateTimeStr);
|
|
111
|
+
endDt = DateTime.Parse(endDateTimeStr);
|
|
112
|
+
}
|
|
113
|
+
catch (Exception)
|
|
114
|
+
{
|
|
115
|
+
return Task.FromResult(new ScriptResponse
|
|
116
|
+
{
|
|
117
|
+
Data = new { slotCheckResult = new { available = false, key = "validation-error" } }
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
var requestedSlot = startDt.ToString("HH:mm") + "-" + endDt.ToString("HH:mm");
|
|
122
|
+
bool available = false;
|
|
123
|
+
string responseKey = null;
|
|
124
|
+
|
|
125
|
+
if (body != null)
|
|
126
|
+
{
|
|
127
|
+
responseKey = GetString(body, "key") ?? GetString(body, "Key");
|
|
128
|
+
var dataNode = body.data ?? body.Data ?? body;
|
|
129
|
+
if (dataNode != null && HasProperty(dataNode, "getAvailableSlots"))
|
|
130
|
+
{
|
|
131
|
+
var getAvailableSlots = dataNode.getAvailableSlots;
|
|
132
|
+
if (HasProperty(getAvailableSlots, "availableSlots"))
|
|
133
|
+
{
|
|
134
|
+
var availableSlots = getAvailableSlots.availableSlots;
|
|
135
|
+
if (availableSlots != null)
|
|
136
|
+
{
|
|
137
|
+
var list = availableSlots as IEnumerable<object>;
|
|
138
|
+
if (list != null)
|
|
139
|
+
{
|
|
140
|
+
foreach (var s in list)
|
|
141
|
+
{
|
|
142
|
+
if (s?.ToString() == requestedSlot) { available = true; break; }
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else
|
|
148
|
+
{
|
|
149
|
+
var detailMsg = GetString(dataNode, "detail") ?? GetString(body, "detail");
|
|
150
|
+
if (!string.IsNullOrEmpty(detailMsg))
|
|
151
|
+
throw new GetAvailableSlotsExceptionRandevuUpdate(detailMsg);
|
|
152
|
+
return Task.FromResult(new ScriptResponse
|
|
153
|
+
{
|
|
154
|
+
Data = new { slotCheckResult = new { available = false, key = "validation-error" } }
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (responseKey == null && body.isSuccess == false)
|
|
159
|
+
available = false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return Task.FromResult(new ScriptResponse
|
|
163
|
+
{
|
|
164
|
+
Data = new
|
|
165
|
+
{
|
|
166
|
+
slotCheckResult = new
|
|
167
|
+
{
|
|
168
|
+
available,
|
|
169
|
+
key = responseKey ?? (available ? "available-slots-success" : "slot-unavailable"),
|
|
170
|
+
slots = body?.data?.getAvailableSlots?.availableSlots ?? body?.getAvailableSlots?.availableSlots
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
catch (GetAvailableSlotsExceptionRandevuUpdate)
|
|
176
|
+
{
|
|
177
|
+
throw;
|
|
178
|
+
}
|
|
179
|
+
catch (Exception ex)
|
|
180
|
+
{
|
|
181
|
+
return Task.FromResult(new ScriptResponse
|
|
182
|
+
{
|
|
183
|
+
Data = new
|
|
184
|
+
{
|
|
185
|
+
slotCheckResult = new
|
|
186
|
+
{
|
|
187
|
+
available = false,
|
|
188
|
+
key = "output-error",
|
|
189
|
+
error = ex.Message,
|
|
190
|
+
unavailable = context.Body
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private string GetString(dynamic obj, string name)
|
|
198
|
+
{
|
|
199
|
+
if (obj == null) return null;
|
|
200
|
+
try
|
|
201
|
+
{
|
|
202
|
+
if (HasProperty(obj, name))
|
|
203
|
+
{
|
|
204
|
+
var v = GetPropertyValue(obj, name);
|
|
205
|
+
return v?.ToString();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch { }
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using System.Threading.Tasks;
|
|
5
|
+
using BBT.Workflow.Scripting;
|
|
6
|
+
using BBT.Workflow.Definitions;
|
|
7
|
+
|
|
8
|
+
/// <summary>
|
|
9
|
+
/// Mapping for validate-slot-for-rezervation task.
|
|
10
|
+
/// Invokes get-available-slots function with advisor and date from rezervation instance,
|
|
11
|
+
/// then checks if the requested startDateTime-endDateTime slot is in the available slots list.
|
|
12
|
+
/// Output: slotCheckResult { available: bool, key?: string } for use by validating state auto transitions.
|
|
13
|
+
/// </summary>
|
|
14
|
+
internal sealed class GetAvailableSlotsException : Exception
|
|
15
|
+
{
|
|
16
|
+
public GetAvailableSlotsException(string message) : base(message) { }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public class ValidateSlotForRezervationMapping : ScriptBase, IMapping
|
|
20
|
+
{
|
|
21
|
+
public Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
22
|
+
{
|
|
23
|
+
try
|
|
24
|
+
{
|
|
25
|
+
var serviceTask = task as DaprServiceTask;
|
|
26
|
+
if (serviceTask == null)
|
|
27
|
+
throw new InvalidOperationException("Task must be a DaprServiceTask");
|
|
28
|
+
|
|
29
|
+
var appId = GetConfigValue("DAPR_APP_ID");
|
|
30
|
+
if (!string.IsNullOrEmpty(appId))
|
|
31
|
+
serviceTask.SetAppId(appId);
|
|
32
|
+
|
|
33
|
+
var data = context.Instance?.Data;
|
|
34
|
+
if (data == null)
|
|
35
|
+
throw new InvalidOperationException("Instance data is required");
|
|
36
|
+
|
|
37
|
+
var advisor = GetString(data, "advisor");
|
|
38
|
+
var startDateTimeStr = GetString(data, "startDateTime");
|
|
39
|
+
if (string.IsNullOrEmpty(advisor) || string.IsNullOrEmpty(startDateTimeStr))
|
|
40
|
+
{
|
|
41
|
+
return Task.FromResult(new ScriptResponse
|
|
42
|
+
{
|
|
43
|
+
Key = "validation-error",
|
|
44
|
+
Data = new
|
|
45
|
+
{
|
|
46
|
+
slotCheckResult = new { available = false, key = "validation-error" }
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
DateTime startDateTime;
|
|
52
|
+
if (!DateTime.TryParse(startDateTimeStr, out startDateTime))
|
|
53
|
+
{
|
|
54
|
+
return Task.FromResult(new ScriptResponse
|
|
55
|
+
{
|
|
56
|
+
Key = "validation-error",
|
|
57
|
+
Data = new
|
|
58
|
+
{
|
|
59
|
+
slotCheckResult = new { available = false, key = "validation-error" }
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
var dateStr = startDateTime.ToString("yyyy-MM-dd");
|
|
65
|
+
var queryParams = new List<string>
|
|
66
|
+
{
|
|
67
|
+
"advisorId=" + Uri.EscapeDataString(advisor),
|
|
68
|
+
"date=" + Uri.EscapeDataString(dateStr)
|
|
69
|
+
};
|
|
70
|
+
serviceTask.SetQueryString(string.Join("&", queryParams));
|
|
71
|
+
|
|
72
|
+
return Task.FromResult(new ScriptResponse());
|
|
73
|
+
}
|
|
74
|
+
catch (Exception ex)
|
|
75
|
+
{
|
|
76
|
+
return Task.FromResult(new ScriptResponse
|
|
77
|
+
{
|
|
78
|
+
Key = "input-error",
|
|
79
|
+
Data = new
|
|
80
|
+
{
|
|
81
|
+
slotCheckResult = new
|
|
82
|
+
{
|
|
83
|
+
available = false,
|
|
84
|
+
key = "input-error",
|
|
85
|
+
error = ex.Message
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
93
|
+
{
|
|
94
|
+
var body = context.Body;
|
|
95
|
+
if (body != null && HasProperty(body, "isSuccess") && body.isSuccess == false)
|
|
96
|
+
{
|
|
97
|
+
var errNode = HasProperty(body, "data") ? body.data : null;
|
|
98
|
+
var detail = GetString(errNode, "detail") ?? GetString(body, "errorMessage") ?? GetString(body, "detail");
|
|
99
|
+
throw new ArgumentException(detail ?? "Function call failed","");
|
|
100
|
+
}
|
|
101
|
+
try
|
|
102
|
+
{
|
|
103
|
+
var data = context.Instance?.Data;
|
|
104
|
+
if (data == null)
|
|
105
|
+
{
|
|
106
|
+
return Task.FromResult(new ScriptResponse
|
|
107
|
+
{
|
|
108
|
+
Data = new { slotCheckResult = new { available = false, key = "no-instance-data" } }
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
var startDateTimeStr = GetString(data, "startDateTime");
|
|
113
|
+
var endDateTimeStr = GetString(data, "endDateTime");
|
|
114
|
+
if (string.IsNullOrEmpty(startDateTimeStr) || string.IsNullOrEmpty(endDateTimeStr))
|
|
115
|
+
{
|
|
116
|
+
return Task.FromResult(new ScriptResponse
|
|
117
|
+
{
|
|
118
|
+
Data = new { slotCheckResult = new { available = false, key = "validation-error" } }
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
DateTime startDt = DateTime.MinValue;
|
|
123
|
+
DateTime endDt = DateTime.MinValue;
|
|
124
|
+
try
|
|
125
|
+
{
|
|
126
|
+
startDt = DateTime.Parse(startDateTimeStr);
|
|
127
|
+
endDt = DateTime.Parse(endDateTimeStr);
|
|
128
|
+
}
|
|
129
|
+
catch (Exception ex)
|
|
130
|
+
{
|
|
131
|
+
return Task.FromResult(new ScriptResponse
|
|
132
|
+
{
|
|
133
|
+
Data = new { slotCheckResult = new { available = false, key = "validation-error" } }
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
var requestedSlot = startDt.ToString("HH:mm") + "-" + endDt.ToString("HH:mm");
|
|
138
|
+
|
|
139
|
+
bool available = false;
|
|
140
|
+
string responseKey = null;
|
|
141
|
+
dynamic resolvedSlots = null;
|
|
142
|
+
|
|
143
|
+
if (body != null)
|
|
144
|
+
{
|
|
145
|
+
responseKey = GetString(body, "key") ?? GetString(body, "Key");
|
|
146
|
+
|
|
147
|
+
dynamic slotsContainer = null;
|
|
148
|
+
|
|
149
|
+
if (HasProperty(body, "getAvailableSlots"))
|
|
150
|
+
{
|
|
151
|
+
slotsContainer = body.getAvailableSlots;
|
|
152
|
+
}
|
|
153
|
+
else
|
|
154
|
+
{
|
|
155
|
+
var dataNode = HasProperty(body, "data") ? body.data : (HasProperty(body, "Data") ? body.Data : null);
|
|
156
|
+
if (dataNode != null && HasProperty(dataNode, "getAvailableSlots"))
|
|
157
|
+
{
|
|
158
|
+
slotsContainer = dataNode.getAvailableSlots;
|
|
159
|
+
}
|
|
160
|
+
else if (dataNode != null && HasProperty(dataNode, "availableSlots"))
|
|
161
|
+
{
|
|
162
|
+
slotsContainer = dataNode;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (slotsContainer != null && HasProperty(slotsContainer, "availableSlots"))
|
|
167
|
+
{
|
|
168
|
+
var availableSlots = slotsContainer.availableSlots;
|
|
169
|
+
resolvedSlots = availableSlots;
|
|
170
|
+
if (availableSlots != null)
|
|
171
|
+
{
|
|
172
|
+
var list = availableSlots as IEnumerable<object>;
|
|
173
|
+
if (list != null)
|
|
174
|
+
{
|
|
175
|
+
foreach (var s in list)
|
|
176
|
+
{
|
|
177
|
+
var slotStr = s?.ToString();
|
|
178
|
+
if (slotStr == requestedSlot)
|
|
179
|
+
{
|
|
180
|
+
available = true;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else
|
|
188
|
+
{
|
|
189
|
+
var detailMsg = GetString(body, "detail");
|
|
190
|
+
if (!string.IsNullOrEmpty(detailMsg))
|
|
191
|
+
throw new GetAvailableSlotsException(detailMsg);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (responseKey == null && HasProperty(body, "isSuccess") && body.isSuccess == false)
|
|
195
|
+
available = false;
|
|
196
|
+
}
|
|
197
|
+
return Task.FromResult(new ScriptResponse
|
|
198
|
+
{
|
|
199
|
+
Data = new
|
|
200
|
+
{
|
|
201
|
+
slotCheckResult = new
|
|
202
|
+
{
|
|
203
|
+
available,
|
|
204
|
+
key = responseKey ?? (available ? "available-slots-success" : "slot-unavailable"),
|
|
205
|
+
slots = resolvedSlots
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
}
|
|
211
|
+
catch (GetAvailableSlotsException)
|
|
212
|
+
{
|
|
213
|
+
throw;
|
|
214
|
+
}
|
|
215
|
+
catch (Exception ex)
|
|
216
|
+
{
|
|
217
|
+
return Task.FromResult(new ScriptResponse
|
|
218
|
+
{
|
|
219
|
+
Data = new
|
|
220
|
+
{
|
|
221
|
+
slotCheckResult = new
|
|
222
|
+
{
|
|
223
|
+
available = false,
|
|
224
|
+
key = "output-error",
|
|
225
|
+
error = ex.Message
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private string GetString(dynamic obj, string name)
|
|
233
|
+
{
|
|
234
|
+
if (obj == null) return null;
|
|
235
|
+
try
|
|
236
|
+
{
|
|
237
|
+
if (HasProperty(obj, name))
|
|
238
|
+
{
|
|
239
|
+
var v = GetPropertyValue(obj, name);
|
|
240
|
+
return v?.ToString();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
catch { }
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using System.Threading.Tasks;
|
|
5
|
+
using BBT.Workflow.Scripting;
|
|
6
|
+
using BBT.Workflow.Definitions;
|
|
7
|
+
|
|
8
|
+
/// <summary>
|
|
9
|
+
/// Mapping for validate-transfer-availability task (DaprServiceTask - Type 3).
|
|
10
|
+
/// Queries all active reservations in the date range for target advisors.
|
|
11
|
+
/// OutputHandler checks each transferPlan item to see if the target advisor
|
|
12
|
+
/// still has a free slot at the reservation's timeslot.
|
|
13
|
+
/// Sets validationResult.allValid = true/false accordingly.
|
|
14
|
+
/// </summary>
|
|
15
|
+
public class ValidateTransferMapping : ScriptBase, IMapping
|
|
16
|
+
{
|
|
17
|
+
public Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
18
|
+
{
|
|
19
|
+
var serviceTask = task as DaprServiceTask;
|
|
20
|
+
if (serviceTask == null)
|
|
21
|
+
throw new InvalidOperationException("Task must be a DaprServiceTask");
|
|
22
|
+
|
|
23
|
+
var appId = GetConfigValue("DAPR_APP_ID");
|
|
24
|
+
if (!string.IsNullOrEmpty(appId))
|
|
25
|
+
serviceTask.SetAppId(appId);
|
|
26
|
+
|
|
27
|
+
var data = context.Instance?.Data;
|
|
28
|
+
if (data == null)
|
|
29
|
+
throw new InvalidOperationException("Instance data is required");
|
|
30
|
+
|
|
31
|
+
var transferPlan = data.transferPlan;
|
|
32
|
+
if (transferPlan == null)
|
|
33
|
+
throw new ArgumentException("transferPlan is required.", "transferPlan");
|
|
34
|
+
|
|
35
|
+
var startDate = GetString(data, "startDate");
|
|
36
|
+
var endDate = GetString(data, "endDate");
|
|
37
|
+
|
|
38
|
+
if (string.IsNullOrEmpty(startDate))
|
|
39
|
+
throw new ArgumentException("startDate is required.", "startDate");
|
|
40
|
+
if (string.IsNullOrEmpty(endDate))
|
|
41
|
+
endDate = "2099-12-31";
|
|
42
|
+
|
|
43
|
+
var conditions = new List<string>
|
|
44
|
+
{
|
|
45
|
+
"{\"or\":[" +
|
|
46
|
+
"{\"currentState\":{\"eq\":\"active\"}}," +
|
|
47
|
+
"{\"currentState\":{\"eq\":\"in-meet\"}}" +
|
|
48
|
+
"]}",
|
|
49
|
+
"{\"status\":{\"eq\":\"A\"}}",
|
|
50
|
+
"{\"attributes\":{\"startDateTime\":{\"gte\":\"" + startDate + "\"}}}",
|
|
51
|
+
"{\"attributes\":{\"endDateTime\":{\"lte\":\"" + endDate + "\"}}}"
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
var filterJson = "{\"and\":[" + string.Join(",", conditions) + "]}";
|
|
55
|
+
var queryParams = new List<string>
|
|
56
|
+
{
|
|
57
|
+
"pageSize=100",
|
|
58
|
+
"filter=" + filterJson
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
serviceTask.SetQueryString(string.Join("&", queryParams));
|
|
62
|
+
return Task.FromResult(new ScriptResponse());
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
66
|
+
{
|
|
67
|
+
try
|
|
68
|
+
{
|
|
69
|
+
var body = context.Body;
|
|
70
|
+
var data = context.Instance?.Data;
|
|
71
|
+
|
|
72
|
+
if (body != null && body.isSuccess == false)
|
|
73
|
+
{
|
|
74
|
+
var errorMessage = body.errorMessage?.ToString() ?? "Validation service error";
|
|
75
|
+
throw new Exception(errorMessage);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var responseData = body?.data;
|
|
79
|
+
var allItems = responseData?.items;
|
|
80
|
+
|
|
81
|
+
var transferPlan = data?.transferPlan;
|
|
82
|
+
var enrichedRezervations = data?.enrichedRezervations;
|
|
83
|
+
|
|
84
|
+
bool allValid = true;
|
|
85
|
+
var details = new List<object>();
|
|
86
|
+
|
|
87
|
+
if (transferPlan != null)
|
|
88
|
+
{
|
|
89
|
+
foreach (var planItem in transferPlan)
|
|
90
|
+
{
|
|
91
|
+
if (planItem == null) continue;
|
|
92
|
+
|
|
93
|
+
dynamic pi = planItem;
|
|
94
|
+
var rezervationKey = pi.rezervationKey?.ToString();
|
|
95
|
+
var targetAdvisor = pi.targetAdvisor?.ToString();
|
|
96
|
+
|
|
97
|
+
if (string.IsNullOrEmpty(rezervationKey) || string.IsNullOrEmpty(targetAdvisor))
|
|
98
|
+
{
|
|
99
|
+
details.Add(new { rezervationKey, targetAdvisor, valid = false, reason = "missing-data" });
|
|
100
|
+
allValid = false;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
string rezStartStr = null, rezEndStr = null;
|
|
105
|
+
if (enrichedRezervations != null)
|
|
106
|
+
{
|
|
107
|
+
foreach (var er in enrichedRezervations)
|
|
108
|
+
{
|
|
109
|
+
if (er == null) continue;
|
|
110
|
+
var erKey = HasProperty(er, "key") ? er.key?.ToString() : "";
|
|
111
|
+
if (erKey == rezervationKey)
|
|
112
|
+
{
|
|
113
|
+
rezStartStr = HasProperty(er, "startDateTime") ? er.startDateTime?.ToString() : null;
|
|
114
|
+
rezEndStr = HasProperty(er, "endDateTime") ? er.endDateTime?.ToString() : null;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (string.IsNullOrEmpty(rezStartStr) || string.IsNullOrEmpty(rezEndStr))
|
|
121
|
+
{
|
|
122
|
+
details.Add(new { rezervationKey, targetAdvisor, valid = true, reason = "no-time-data-to-validate" });
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
DateTime rezStart = DateTime.MinValue;
|
|
127
|
+
DateTime rezEnd = DateTime.MinValue;
|
|
128
|
+
if (!DateTime.TryParse(rezStartStr, out rezStart) || !DateTime.TryParse(rezEndStr, out rezEnd))
|
|
129
|
+
{
|
|
130
|
+
details.Add(new { rezervationKey, targetAdvisor, valid = true, reason = "unparseable-time" });
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
bool hasConflict = false;
|
|
135
|
+
if (allItems != null)
|
|
136
|
+
{
|
|
137
|
+
foreach (var item in allItems)
|
|
138
|
+
{
|
|
139
|
+
if (item == null) continue;
|
|
140
|
+
var itemAdvisor = GetNestedString(item, "attributes", "advisor")
|
|
141
|
+
?? GetString(item, "advisor");
|
|
142
|
+
if (itemAdvisor != targetAdvisor) continue;
|
|
143
|
+
|
|
144
|
+
var itemStartStr = GetNestedString(item, "attributes", "startDateTime")
|
|
145
|
+
?? GetString(item, "startDateTime");
|
|
146
|
+
var itemEndStr = GetNestedString(item, "attributes", "endDateTime")
|
|
147
|
+
?? GetString(item, "endDateTime");
|
|
148
|
+
|
|
149
|
+
if (string.IsNullOrEmpty(itemStartStr) || string.IsNullOrEmpty(itemEndStr))
|
|
150
|
+
continue;
|
|
151
|
+
|
|
152
|
+
DateTime itemStart = DateTime.MinValue;
|
|
153
|
+
DateTime itemEnd = DateTime.MinValue;
|
|
154
|
+
if (DateTime.TryParse(itemStartStr, out itemStart) && DateTime.TryParse(itemEndStr, out itemEnd))
|
|
155
|
+
{
|
|
156
|
+
var itemKey = HasProperty(item, "key") ? item.key?.ToString() : "";
|
|
157
|
+
if (itemKey == rezervationKey) continue;
|
|
158
|
+
|
|
159
|
+
if (itemStart < rezEnd && itemEnd > rezStart)
|
|
160
|
+
{
|
|
161
|
+
hasConflict = true;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (hasConflict)
|
|
169
|
+
{
|
|
170
|
+
allValid = false;
|
|
171
|
+
details.Add(new { rezervationKey, targetAdvisor, valid = false, reason = "slot-conflict" });
|
|
172
|
+
}
|
|
173
|
+
else
|
|
174
|
+
{
|
|
175
|
+
details.Add(new { rezervationKey, targetAdvisor, valid = true });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return Task.FromResult(new ScriptResponse
|
|
181
|
+
{
|
|
182
|
+
Data = new
|
|
183
|
+
{
|
|
184
|
+
validationResult = new
|
|
185
|
+
{
|
|
186
|
+
allValid,
|
|
187
|
+
details
|
|
188
|
+
},
|
|
189
|
+
processedIndex = 0
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
catch (Exception ex)
|
|
194
|
+
{
|
|
195
|
+
return Task.FromResult(new ScriptResponse
|
|
196
|
+
{
|
|
197
|
+
Data = new
|
|
198
|
+
{
|
|
199
|
+
validationResult = new
|
|
200
|
+
{
|
|
201
|
+
allValid = false,
|
|
202
|
+
error = ex.Message
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private string GetString(dynamic obj, string name)
|
|
210
|
+
{
|
|
211
|
+
if (obj == null) return null;
|
|
212
|
+
try
|
|
213
|
+
{
|
|
214
|
+
if (HasProperty(obj, name))
|
|
215
|
+
{
|
|
216
|
+
var v = GetPropertyValue(obj, name);
|
|
217
|
+
return v?.ToString();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch { }
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
private string GetNestedString(dynamic obj, string parent, string child)
|
|
225
|
+
{
|
|
226
|
+
if (obj == null) return null;
|
|
227
|
+
try
|
|
228
|
+
{
|
|
229
|
+
if (HasProperty(obj, parent))
|
|
230
|
+
{
|
|
231
|
+
var nested = GetPropertyValue(obj, parent);
|
|
232
|
+
if (nested != null && HasProperty(nested, child))
|
|
233
|
+
{
|
|
234
|
+
var v = GetPropertyValue(nested, child);
|
|
235
|
+
return v?.ToString();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch { }
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|