-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVoucherController.cs
More file actions
220 lines (211 loc) · 10.7 KB
/
VoucherController.cs
File metadata and controls
220 lines (211 loc) · 10.7 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
219
220
using System.Security.Claims;
using ErrorOr;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using ShoeStore.Application.DTOs;
using ShoeStore.Application.DTOs.VoucherDtos;
using ShoeStore.Application.Interface.VoucherInterface;
namespace ShoeStore.Api.Controllers;
/// <summary>
/// Controller for managing vouchers in the system.
/// Provides endpoints for voucher creation, retrieval, update, and deletion (Admin only).
/// </summary>
/// <param name="voucherService">Service for handling voucher logic operations.</param>
[ApiController]
[Route("api/admin/vouchers")]
[Authorize(Roles = "Admin")]
public class VoucherController(IVoucherService voucherService) : ControllerBase
{
/// <summary>
/// Creates a new voucher for the store.
/// </summary>
/// <remarks>
/// Requires Admin role authorization.
/// The request body should include:
/// - <c>VoucherName</c>: Name of the voucher
/// - <c>Discount</c>: Value of the discount
/// - <c>DiscountType</c>: Type of discount (Percentage/FixedAmount)
/// - <c>TotalQuantity</c>: Number of vouchers available
/// - <c>ValidFrom/ValidTo</c>: Expiration dates
/// </remarks>
/// <param name="createVoucherDto">Data transfer object containing voucher creation details.</param>
/// <param name="token">Cancellation token for the request.</param>
/// <response code="201">Voucher created successfully.</response>
/// <response code="400">Bad request; invalid voucher data provided.</response>
/// <response code="401">Unauthorized; user must be authenticated with Admin role.</response>
/// <response code="500">Internal server error; an unexpected error occurred.</response>
/// <returns>An action result with status 201 (Created) on success, or an error response.</returns>
[ProducesResponseType(typeof(object), StatusCodes.Status201Created)]
[ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(object), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
[HttpPost]
public async Task<IActionResult> CreateVoucher([FromBody] CreateVoucherDto createVoucherDto, CancellationToken token)
{
var result = await voucherService.CreateVoucherAsync(createVoucherDto, token);
return await result.MatchAsync<IActionResult>(
async _ =>
{
var adminEmail = User.FindFirstValue(ClaimTypes.Email) ?? "[email protected]";
await voucherService.NotifyUserAboutNewVoucherAsync(
adminEmail: adminEmail,
voucherName: createVoucherDto.VoucherName ?? "New Discount",
validTo: createVoucherDto.ValidTo ?? DateTime.UtcNow,
token: token
);
return Created("", new { message = "Voucher created and users notified" });
},
errors => Task.FromResult<IActionResult>(BadRequest(new
{
message = "Failed to create voucher",
detail = errors[0].Description
}))
);
}
/// <summary>
/// Updates an existing voucher's details.
/// </summary>
/// <remarks>
/// Requires Admin role authorization.
/// Updates the specified voucher with the provided information.
/// </remarks>
/// <param name="voucherGuid">The unique identifier (GUID) of the voucher to update.</param>
/// <param name="updateVoucherDto">Data transfer object containing updated voucher details.</param>
/// <param name="token">Cancellation token for the request.</param>
/// <response code="200">Voucher updated successfully.</response>
/// <response code="400">Bad request; invalid update data provided.</response>
/// <response code="401">Unauthorized; user must be authenticated with Admin role.</response>
/// <response code="404">Not found; the voucher with the specified ID does not exist.</response>
/// <response code="500">Internal server error; an unexpected error occurred.</response>
/// <returns>An action result with status 200 (OK) on success, or an error response.</returns>
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(object), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
[HttpPut("{voucherGuid}")]
public async Task<IActionResult> UpdateVoucher(Guid voucherGuid, [FromForm] UpdateVoucherDto updateVoucherDto,
CancellationToken token)
{
var result = await voucherService.UpdateVoucherAsync(voucherGuid, updateVoucherDto, token);
return result.Match<IActionResult>(
_ => Ok(new { message = "Voucher updated successfully" }),
errors => errors[0].Code switch
{
"VOUCHER_NOT_FOUND" => NotFound(new
{
message = "Voucher not found",
detail = errors[0].Description
}),
_ => BadRequest(new
{
message = "Failed to update voucher",
detail = errors[0].Description
})
});
}
/// <summary>
/// Deletes a specific voucher from the system (soft delete).
/// </summary>
/// <remarks>
/// Requires Admin role authorization.
/// Performs a soft delete by marking the voucher as deleted.
/// </remarks>
/// <param name="voucherGuid">The unique identifier (GUID) of the voucher to delete.</param>
/// <param name="token">Cancellation token for the request.</param>
/// <response code="200">Voucher deleted successfully.</response>
/// <response code="401">Unauthorized; user must be authenticated with Admin role.</response>
/// <response code="404">Not found; the voucher with the specified ID does not exist.</response>
/// <response code="500">Internal server error; an unexpected error occurred.</response>
/// <returns>An action result with status 200 (OK) on success, or an error response.</returns>
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(object), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
[HttpDelete("{voucherGuid}")]
public async Task<IActionResult> DeleteVoucher(Guid voucherGuid, CancellationToken token)
{
var result = await voucherService.DeleteVoucherByGuidAsync(voucherGuid, token);
return result.Match<IActionResult>(
_ => Ok(new { message = "Voucher deleted successfully" }),
errors => errors[0].Code switch
{
"VOUCHER_NOT_FOUND" => NotFound(new
{
message = "Voucher not found",
detail = errors[0].Description
}),
_ => BadRequest(new
{
message = "Failed to delete voucher",
detail = errors[0].Description
})
});
}
/// <summary>
/// Deletes all expired vouchers from the system (soft delete).
/// </summary>
/// <remarks>
/// Requires Admin role authorization.
/// Identifies and soft deletes all vouchers whose expiration date has passed.
/// </remarks>
/// <param name="token">Cancellation token for the request.</param>
/// <response code="200">Expired vouchers deleted successfully.</response>
/// <response code="400">Bad request; failed to delete expired vouchers or no expired vouchers found.</response>
/// <response code="401">Unauthorized; user must be authenticated with Admin role.</response>
/// <response code="500">Internal server error; an unexpected error occurred.</response>
/// <returns>An action result with status 200 (OK) on success, or an error response.</returns>
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(object), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
[HttpDelete("expire")]
public async Task<IActionResult> DeleteExpiredVouchers(CancellationToken token)
{
var result = await voucherService.DeleteVoucherExpireAsync(token);
return result.Match<IActionResult>(
_ => Ok(new { message = "Expired vouchers deleted successfully" }),
errors => BadRequest(new
{
message = "Failed to delete expired vouchers",
detail = errors[0].Description
}));
}
/// <summary>
/// Retrieves a paginated list of vouchers for administrative purposes.
/// </summary>
/// <remarks>
/// Requires Admin role authorization.
/// Provides a list of vouchers with detailed information relevant for administrators.
/// </remarks>
/// <param name="token">Cancellation token for the request.</param>
/// <response code="200">Vouchers retrieved successfully.</response>
/// <response code="401">Unauthorized; user must be authenticated with Admin role.</response>
/// <response code="404">Not found; no vouchers found in the system.</response>
/// <response code="500">Internal server error; an unexpected error occurred.</response>
/// <returns>An action result containing a paginated list of vouchers on success, or an error response.</returns>
[ProducesResponseType(typeof(PageResult<ResponseVoucherAdminDto>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(object), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
[HttpGet]
public async Task<IActionResult> GetVouchersForAdmin(CancellationToken token)
{
var result = await voucherService.GetVoucherForAdminAsync(token);
return result.Match<IActionResult>(
vouchers => Ok(vouchers),
errors => errors[0].Code switch
{
"NO_VOUCHERS_FOUND" => NotFound(new
{
message = "No vouchers found",
detail = errors[0].Description
}),
_ => BadRequest(new
{
message = "Failed to retrieve vouchers",
detail = errors[0].Description
})
});
}
}