Skip to content

Commit

Permalink
order cancellation implemented (#592)
Browse files Browse the repository at this point in the history
* order cancellation implemented

* fixed code smells

* fixed bug

* added unregistered service

* Update src/Altinn.Notifications.Persistence/Repository/OrderRepository.cs

Co-authored-by: Terje Holene <[email protected]>

* -> canCancel

* removed task from analysis

---------

Co-authored-by: Terje Holene <[email protected]>
  • Loading branch information
acn-sbuad and SandGrainOne authored Aug 19, 2024
1 parent 70775b8 commit 26f6c89
Show file tree
Hide file tree
Showing 18 changed files with 1,111 additions and 47 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/build-and-analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ jobs:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
- name: Process .NET test result
if: always()
uses: NasAmin/[email protected]
with:
TRX_PATH: ${{ github.workspace }}/TestResults
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: Process .NET test result
# if: always()
# uses: NasAmin/[email protected]
# with:
# TRX_PATH: ${{ github.workspace }}/TestResults
# REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 changes: 18 additions & 0 deletions src/Altinn.Notifications.Core/Enums/CancellationError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Altinn.Notifications.Core.Enums
{
/// <summary>
/// Enum for the different types of errors that can occur when cancelling an order
/// </summary>
public enum CancellationError
{
/// <summary>
/// Order was not found
/// </summary>
OrderNotFound,

/// <summary>
/// Order was found but processing had already started
/// </summary>
CancellationProhibited
}
}
3 changes: 2 additions & 1 deletion src/Altinn.Notifications.Core/Enums/OrderProcessingStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public enum OrderProcessingStatus
Registered,
Processing,
Completed,
SendConditionNotMet
SendConditionNotMet,
Cancelled
}
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public static void AddCoreServices(this IServiceCollection services, IConfigurat
.AddSingleton<IPreferredChannelProcessingService, PreferredChannelProcessingService>()
.AddSingleton<IGetOrderService, GetOrderService>()
.AddSingleton<IOrderRequestService, OrderRequestService>()
.AddSingleton<ICancelOrderService, CancelOrderService>()
.AddSingleton<IEmailNotificationSummaryService, EmailNotificationSummaryService>()
.AddSingleton<IEmailNotificationService, EmailNotificationService>()
.AddSingleton<ISmsNotificationService, SmsNotificationService>()
Expand Down
9 changes: 9 additions & 0 deletions src/Altinn.Notifications.Core/Persistence/IOrderRepository.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Altinn.Notifications.Core.Enums;
using Altinn.Notifications.Core.Models.Orders;
using Altinn.Notifications.Core.Shared;

namespace Altinn.Notifications.Core.Persistence;

Expand Down Expand Up @@ -49,4 +50,12 @@ public interface IOrderRepository
/// <param name="creator">The short name of the order creator</param>
/// <returns>A list of notification orders</returns>
public Task<List<NotificationOrder>> GetOrdersBySendersReference(string sendersReference, string creator);

/// <summary>
/// Cancels the order corresponding to the provided id within the provided creator scope if processing has not started yet
/// </summary>
/// <param name="id">The order id</param>
/// <param name="creator">The short name of the order creator</param>
/// <returns>If successful the cancelled notification order with status info. If error a cancellation error type.</returns>
public Task<Result<NotificationOrderWithStatus, CancellationError>> CancelOrder(Guid id, string creator);
}
42 changes: 42 additions & 0 deletions src/Altinn.Notifications.Core/Services/CancelOrderService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Altinn.Notifications.Core.Enums;
using Altinn.Notifications.Core.Models.Orders;
using Altinn.Notifications.Core.Persistence;
using Altinn.Notifications.Core.Services.Interfaces;
using Altinn.Notifications.Core.Shared;

namespace Altinn.Notifications.Core.Services
{
/// <summary>
/// Implementation of the <see cref="ICancelOrderService"/> interface.
/// </summary>
public class CancelOrderService : ICancelOrderService
{
private readonly IOrderRepository _repository;

/// <summary>
/// Initializes a new instance of the <see cref="CancelOrderService"/> class.
/// </summary>
/// <param name="repository">The repository</param>
public CancelOrderService(IOrderRepository repository)
{
_repository = repository;
}

/// <inheritdoc/>
public async Task<Result<NotificationOrderWithStatus, CancellationError>> CancelOrder(Guid id, string creator)
{
var result = await _repository.CancelOrder(id, creator);

return result.Match<Result<NotificationOrderWithStatus, CancellationError>>(
order =>
{
order.ProcessingStatus.StatusDescription = GetOrderService.GetStatusDescription(order.ProcessingStatus.Status);
return order;
},
error =>
{
return error;
});
}
}
}
3 changes: 2 additions & 1 deletion src/Altinn.Notifications.Core/Services/GetOrderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ public class GetOrderService : IGetOrderService
{ OrderProcessingStatus.Registered, "Order has been registered and is awaiting requested send time before processing." },
{ OrderProcessingStatus.Processing, "Order processing is ongoing. Notifications are being generated." },
{ OrderProcessingStatus.Completed, "Order processing is completed. All notifications have been generated." },
{ OrderProcessingStatus.SendConditionNotMet, "Order processing was stopped due to send condition not being met." }
{ OrderProcessingStatus.SendConditionNotMet, "Order processing was stopped due to send condition not being met." },
{ OrderProcessingStatus.Cancelled, "Order processing was stopped due to order being cancelled." }
};

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Altinn.Notifications.Core.Enums;
using Altinn.Notifications.Core.Models.Orders;
using Altinn.Notifications.Core.Shared;

namespace Altinn.Notifications.Core.Services.Interfaces
{
/// <summary>
/// Interface for operations related to cancelling notification orders
/// </summary>
public interface ICancelOrderService
{
/// <summary>
/// Cancels an order if it has not been processed yet
/// </summary>
/// <param name="id">The order id</param>
/// <param name="creator">The creator of the orders</param>
/// <returns>The cancelled order or a </returns>
public Task<Result<NotificationOrderWithStatus, CancellationError>> CancelOrder(Guid id, string creator);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
<DbToolsExecuted>true</DbToolsExecuted>
</PropertyGroup>

<Exec Command="$(TargetDir)../../../../DbTools/bin/Debug/$(TargetFramework)/DbTools $(TargetDir)../../../Migration"
Condition="'$(DbToolsExecuted)' != 'true' and (Exists('$(TargetDir)../../../../DbTools/bin/Debug/$(TargetFramework)/DbTools') or Exists('$(TargetDir)../../../../DbTools/bin/Debug/$(TargetFramework)/DbTools.exe'))" />
<Exec Command="$(TargetDir)../../../../DbTools/bin/Debug/$(TargetFramework)/DbTools $(TargetDir)../../../Migration" Condition="'$(DbToolsExecuted)' != 'true' and (Exists('$(TargetDir)../../../../DbTools/bin/Debug/$(TargetFramework)/DbTools') or Exists('$(TargetDir)../../../../DbTools/bin/Debug/$(TargetFramework)/DbTools.exe'))" />
</Target>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
CREATE OR REPLACE FUNCTION notifications.cancelorder(
_alternateid uuid,
_creatorname text
)
RETURNS TABLE(
cancelallowed boolean,
alternateid uuid,
creatorname text,
sendersreference text,
created timestamp with time zone,
requestedsendtime timestamp with time zone,
processed timestamp with time zone,
processedstatus orderprocessingstate,
notificationchannel text,
ignorereservation boolean,
resourceid text,
conditionendpoint text,
generatedemailcount bigint,
succeededemailcount bigint,
generatedsmscount bigint,
succeededsmscount bigint
)
LANGUAGE plpgsql
AS $$
DECLARE
order_record RECORD;
BEGIN
-- Retrieve the order and its status
SELECT o.requestedsendtime, o.processedstatus
INTO order_record
FROM notifications.orders o
WHERE o.alternateid = _alternateid AND o.creatorname = _creatorname;

-- If no order is found, return an empty result set
IF NOT FOUND THEN
RETURN;
END IF;

-- Check if order is already cancelled
IF order_record.processedstatus = 'Cancelled' THEN
RETURN QUERY
SELECT TRUE AS cancelallowed,
order_details.*
FROM notifications.getorder_includestatus_v4(_alternateid, _creatorname) AS order_details;
ELSEIF (order_record.requestedsendtime <= NOW() + INTERVAL '5 minutes' or order_record.processedstatus != 'Registered') THEN
RETURN QUERY
SELECT FALSE AS cancelallowed, NULL::uuid, NULL::text, NULL::text, NULL::timestamp with time zone, NULL::timestamp with time zone, NULL::timestamp with time zone, NULL::orderprocessingstate, NULL::text, NULL::boolean, NULL::text, NULL::text, NULL::bigint, NULL::bigint, NULL::bigint, NULL::bigint;
ELSE
-- Cancel the order by updating its status
UPDATE notifications.orders
SET processedstatus = 'Cancelled', processed = NOW()
WHERE notifications.orders.alternateid = _alternateid;

-- Retrieve the updated order details
RETURN QUERY
SELECT TRUE AS cancelallowed,
order_details.*
FROM notifications.getorder_includestatus_v4(_alternateid, _creatorname) AS order_details;
END IF;
END;
$$;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TYPE public.orderprocessingstate ADD VALUE IF NOT EXISTS 'Cancelled';
Loading

0 comments on commit 26f6c89

Please sign in to comment.