diff --git a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/plugins/filterRow.js b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/plugins/filterRow.js
index cfad9c7c22..08449b0c09 100644
--- a/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/plugins/filterRow.js
+++ b/applications/Unity.GrantManager/modules/Unity.Theme.UX2/src/Unity.Theme.UX2/wwwroot/themes/ux2/plugins/filterRow.js
@@ -89,8 +89,7 @@
* @private
*/
_constructor: function () {
- let that = this;
- let dt = this.s.dt;
+ const dt = this.s.dt;
// Create the filter row
this._buildFilterRow();
@@ -104,20 +103,19 @@
this._restoreFilterState();
// Listen for column visibility and reorder events
- dt.on('column-reorder' + this.s.namespace, function () {
- that._rebuildFilterRow();
+ dt.on('column-reorder' + this.s.namespace, () => {
+ this._rebuildFilterRow();
});
- dt.on('column-visibility' + this.s.namespace, function () {
- that._rebuildFilterRow();
+ dt.on('column-visibility' + this.s.namespace, () => {
+ this._rebuildFilterRow();
});
// Listen for destroy event to cleanup
- dt.on('destroy' + this.s.namespace, function () {
- that._destroy();
+ dt.on('destroy' + this.s.namespace, () => {
+ this._destroy();
});
- // Show filter row if autoShow is enabled
if (this.s.opts.autoShow) {
this.dom.filterRow.show();
}
@@ -131,26 +129,29 @@
* @private
*/
_buildFilterRow: function () {
- let dt = this.s.dt;
- let that = this;
- let filterRow = $('
').hide();
dt.columns().every(function () {
- let column = this;
+ const column = this;
// Only create filter cells for visible columns
if (column.visible()) {
- let title = $(column.header()).text();
- let colName = dt.settings()[0].aoColumns[column.index()].name || title;
+ const title = $(column.header()).text();
+ const colName = dt.settings()[0].aoColumns[column.index()].name || title;
if (title && title !== 'Actions' && title !== 'Action' && title !== 'Default') {
- let placeholder = that.s.opts.placeholderPrefix ?
- that.s.opts.placeholderPrefix + ' ' + title :
- title;
- // Get filter value by column name (not title) for persistence across reorders
- let filterValue = that.s.filterData[colName] || column.search() || '';
+ const placeholder = opts.placeholderPrefix
+ ? opts.placeholderPrefix + ' ' + title
+ : title;
- let input = $('', {
+ const filterValue = filterData[colName] || column.search() || '';
+
+ const input = $('', {
type: 'text',
class: 'form-control input-sm custom-filter-input',
placeholder: placeholder,
@@ -158,7 +159,7 @@
'data-column-name': colName
});
- let cell = $('| ').append(input);
+ const cell = $(' | ').append(input);
// Apply search value if it differs from current column search
if (column.search() !== filterValue) {
@@ -166,29 +167,26 @@
}
// Bind keyup event for filtering
- input.on('keyup' + that.s.namespace, function () {
- let val = this.value;
+ input.on('keyup' + namespace, function () {
+ const val = this.value;
+
if (column.search() !== val) {
column.search(val).draw();
// Store by column name for persistence
- that.s.filterData[colName] = val;
- that._updateButtonState();
+ filterData[colName] = val;
+ updateButtonState();
}
});
filterRow.append(cell);
} else {
- // Empty cell for action columns
filterRow.append($(' | '));
}
}
- // Skip hidden columns - don't add any td element
});
- // Remove existing filter row if present
dt.table().header().parentNode.querySelector('.tr-toggle-filter')?.remove();
- // Append to table header
$(dt.table().header()).after(filterRow);
this.dom.filterRow = filterRow;
},
@@ -198,23 +196,23 @@
* @private
*/
_rebuildFilterRow: function () {
- let dt = this.s.dt;
- let that = this;
-
// Preserve current filter values before rebuilding
- this.dom.filterRow?.find('.custom-filter-input').each(function() {
- let colName = $(this).data('column-name');
- let val = $(this).val();
+ this.dom.filterRow?.find('.custom-filter-input').each((_, el) => {
+ const colName = $(el).data('column-name');
+ const val = $(el).val();
if (colName && val) {
- that.s.filterData[colName] = val;
+ this.s.filterData[colName] = val;
}
});
-
- let wasVisible = this.dom.filterRow?.is(':visible');
+
+ const wasVisible = this.dom.filterRow?.is(':visible');
+
this._buildFilterRow();
+
if (wasVisible) {
this.dom.filterRow.show();
}
+
this._updateButtonState();
},
@@ -223,17 +221,14 @@
* @private
*/
_initializePopover: function () {
- let that = this;
- let btnSelector = '#' + this.s.opts.buttonId;
- let $btn = $(btnSelector);
+ const btnSelector = '#' + this.s.opts.buttonId;
+ const $btn = $(btnSelector);
- if (!$btn.length) {
- return; // Button not found, skip popover
- }
+ if (!$btn.length) return;
this.dom.button = $btn;
- $btn.on('click' + this.s.namespace, function () {
+ $btn.on('click' + this.s.namespace, () => {
$btn.popover('toggle');
});
@@ -247,58 +242,64 @@
`,
- content: function () {
- let isChecked = that.dom.filterRow.is(':visible');
+ content: () => {
+ const isChecked = this.dom.filterRow.is(':visible');
+
return `
-
+
- CLEAR FILTER
+
`;
},
placement: this.s.opts.popoverPlacement
});
- // Handle popover shown event
- $btn.on('shown.bs.popover' + this.s.namespace, function () {
- let $popover = $('.popover.custom-popover');
-
- // Toggle filter row visibility
- $popover.find('#showFilter').on('click', function () {
- that.dom.filterRow.toggle();
- that.s.dt.trigger('filterRow-visibility', [that.dom.filterRow.is(':visible')]);
- });
-
- // Clear all filters
- $popover.find('#btnClearFilter').on('click', function () {
- that.clearFilters();
- $btn.popover('hide');
- });
-
- // Close popover on outside click/hover
- $(document).on('click.popover' + that.s.namespace, function (e) {
- if (!$(e.target).closest(btnSelector).length &&
- !$(e.target).closest('.popover').length) {
- $btn.popover('hide');
- }
- });
+ $btn.on('shown.bs.popover' + this.s.namespace, () => {
+
+ const $popover = $('.popover.custom-popover');
+
+ $popover.find('#showFilter')
+ .off('click' + this.s.namespace)
+ .on('click' + this.s.namespace, () => {
+ this.dom.filterRow.toggle();
+ this.s.dt.trigger('filterRow-visibility', [
+ this.dom.filterRow.is(':visible')
+ ]);
+ });
- $(document).on('mouseenter.popover' + that.s.namespace, function (e) {
- if (!$(e.target).closest(btnSelector).length &&
- !$(e.target).closest('.popover').length) {
+ $popover.find('#btnClearFilter')
+ .off('click' + this.s.namespace)
+ .on('click' + this.s.namespace, () => {
+ this.clearFilters();
$btn.popover('hide');
- }
- });
+ });
+
+ // ✅ FIXED OUTSIDE CLICK
+ $(document)
+ .off('mousedown' + this.s.namespace)
+ .on('mousedown' + this.s.namespace, (e) => {
+
+ const $popoverEl = $('.popover.custom-popover');
+ if (!$popoverEl.is(':visible')) return;
+
+ const $target = $(e.target);
+
+ const insidePopover = $target.closest('.popover.custom-popover').length > 0;
+ const insideButton = $target.closest(btnSelector).length > 0;
+
+ if (!insidePopover && !insideButton) {
+ $btn.popover('hide');
+ }
+ });
});
// Cleanup popover events on hide
- $btn.on('hide.bs.popover' + this.s.namespace, function () {
- let $popover = $('.popover.custom-popover');
- $popover.find('#showFilter').off('click');
- $popover.find('#btnClearFilter').off('click');
- $(document).off('click.popover' + that.s.namespace);
- $(document).off('mouseenter.popover' + that.s.namespace);
+ $btn.on('hide.bs.popover' + this.s.namespace, () => {
+ $(document).off('mousedown' + this.s.namespace);
});
},
@@ -310,7 +311,6 @@
let dt = this.s.dt;
let hasFilters = false;
- // Check column filters
dt.columns().every(function () {
if (this.search()) {
hasFilters = true;
@@ -318,20 +318,9 @@
}
});
- // Check global search
- let externalSearchId = dt.init().externalSearchInputId;
- if (externalSearchId) {
- let searchVal = $(externalSearchId).val();
- if (searchVal && searchVal !== '') {
- hasFilters = true;
- }
- }
-
- // Update button text
if (this.dom.button) {
- this.dom.button.text(hasFilters ?
- this.s.opts.buttonTextActive :
- this.s.opts.buttonText
+ this.dom.button.text(
+ hasFilters ? this.s.opts.buttonTextActive : this.s.opts.buttonText
);
}
},
@@ -341,30 +330,25 @@
* @private
*/
_restoreFilterState: function () {
- let dt = this.s.dt;
- let that = this;
+ const dt = this.s.dt;
+ const filterData = this.s.filterData;
let needsRedraw = false;
dt.columns().every(function (i) {
- let column = this;
- let colName = dt.settings()[0].aoColumns[i].name;
- let title = $(column.header()).text();
- let searchVal = column.search();
+ const column = this;
+ const colName = dt.settings()[0].aoColumns[i].name;
+ const title = $(column.header()).text();
+ const searchVal = column.search();
+
+ const key = colName || title;
- // Store by column name (preferred) or fallback to title
- let key = colName || title;
if (searchVal) {
- that.s.filterData[key] = searchVal;
+ filterData[key] = searchVal;
needsRedraw = true;
}
});
- // Show filter row if filters are active
- let externalSearchId = dt.init().externalSearchInputId;
- let externalSearchVal = externalSearchId ? $(externalSearchId).val() : '';
- let hasFilters = Object.keys(this.s.filterData).length > 0 || externalSearchVal !== '';
-
- if (hasFilters) {
+ if (Object.keys(this.s.filterData).length > 0) {
this.dom.filterRow.show();
}
@@ -385,68 +369,45 @@
let externalSearchId = dtInit.externalSearchInputId;
let initialSortOrder = (dtInit && dtInit.order) ? dtInit.order : [];
- // Clear external search
if (externalSearchId) {
$(externalSearchId).val('');
}
- // Clear the search input field
- $('#search').val('');
-
- // Clear custom filter inputs
- $('.custom-filter-input').val('');
+ this.dom.filterRow.find('.custom-filter-input').val('');
- // Clear DataTable searches
dt.search('').columns().search('');
+ dt.order(initialSortOrder).draw();
- // Clear order
- dt.order(initialSortOrder);
-
- // If we want to reset quick date range dropdown to default (last 6 months) and trigger change
- // The change event handler will reload the table, so would need to remove ajax.reload() here
- $('#quickDateRange').val($('#quickDateRange option[selected]').val()).trigger('change');
-
- // Update button state
- this._updateButtonState();
+ let $quickDateRange = $('#quickDateRange');
+ if ($quickDateRange.length) {
+ let defaultVal = $quickDateRange.find('option[selected]').val();
+ if (defaultVal) {
+ $quickDateRange.val(defaultVal).trigger('change');
+ }
+ }
- // Clear internal filter data
this.s.filterData = {};
+ this._updateButtonState();
},
- /**
- * Show the filter row
- * @public
- */
show: function () {
this.dom.filterRow.show();
this.s.dt.trigger('filterRow-visibility', [true]);
return this;
},
- /**
- * Hide the filter row
- * @public
- */
hide: function () {
this.dom.filterRow.hide();
this.s.dt.trigger('filterRow-visibility', [false]);
return this;
},
- /**
- * Toggle the filter row visibility
- * @public
- */
toggle: function () {
this.dom.filterRow.toggle();
this.s.dt.trigger('filterRow-visibility', [this.dom.filterRow.is(':visible')]);
return this;
},
- /**
- * Destroy the filter row feature
- * @private
- */
_destroy: function () {
let dt = this.s.dt;
@@ -462,12 +423,7 @@
}
}
- // Remove filter row from DOM
- if (this.dom.filterRow) {
- this.dom.filterRow.remove();
- }
-
- // Remove reference from settings
+ this.dom.filterRow?.remove();
dt.settings()[0]._filterRow = null;
}
};
@@ -491,4 +447,22 @@
});
return DataTable.FilterRow;
+
})(jQuery);
+
+
+$(document).on('mousedown', function (e) {
+ const $popover = $('.popover.custom-popover');
+ if (!$popover.is(':visible')) return;
+
+ const $target = $(e.target);
+ const popoverId = $popover.attr('id');
+ const $trigger = $('[aria-describedby="' + popoverId + '"]');
+
+ const insidePopover = $target.closest('.popover.custom-popover').length > 0;
+ const insideButton = $trigger.length > 0 && $target.closest($trigger).length > 0;
+
+ if (!insidePopover && !insideButton) {
+ $trigger.popover('hide');
+ }
+});
\ No newline at end of file
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application.Contracts/Attachments/IAttachmentAppService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application.Contracts/Attachments/IAttachmentAppService.cs
index 1b638f3bc3..f41512c411 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application.Contracts/Attachments/IAttachmentAppService.cs
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application.Contracts/Attachments/IAttachmentAppService.cs
@@ -9,6 +9,7 @@ public interface IAttachmentAppService : IApplicationService
{
Task> GetApplicationAsync(Guid applicationId);
Task> GetAssessmentAsync(Guid assessmentId);
+ Task> GetApplicantAsync(Guid applicantId);
Task ResyncSubmissionAttachmentsAsync(Guid applicationId);
Task> GetAttachmentsAsync(AttachmentParametersDto attachmentParametersDto);
Task GetAttachmentMetadataAsync(AttachmentType attachmentType, Guid attachmentId);
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/AttachmentAppService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/AttachmentAppService.cs
index 3073e17437..a535776df1 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/AttachmentAppService.cs
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/AttachmentAppService.cs
@@ -21,6 +21,7 @@ public class AttachmentAppService(
IApplicationAttachmentRepository applicationAttachmentRepository,
IApplicationChefsFileAttachmentRepository applicationChefsFileAttachmentRepository,
IAssessmentAttachmentRepository assessmentAttachmentRepository,
+ IApplicantAttachmentRepository applicantAttachmentRepository,
IIntakeFormSubmissionManager intakeFormSubmissionManager,
IPersonRepository personUserRepository) : ApplicationService, IAttachmentAppService
{
@@ -54,6 +55,11 @@ public async Task> GetAssessmentAsync(Guid assess
}).ToList();
}
+ public async Task> GetApplicantAsync(Guid applicantId)
+ {
+ return await GetAttachmentsAsync(new AttachmentParametersDto(AttachmentType.APPLICANT, applicantId));
+ }
+
public async Task> GetApplicationChefsFileAttachmentsAsync(Guid applicationId)
{
return await applicationChefsFileAttachmentRepository.GetListAsync(applicationId);
@@ -79,6 +85,9 @@ public async Task> GetAttachmentsAsync(AttachmentParam
AttachmentType.ASSESSMENT => await GetAttachmentsInternalAsync(
assessmentAttachmentRepository,
attachment => attachment.AssessmentId == attachmentParametersDto.AttachedResourceId),
+ AttachmentType.APPLICANT => await GetAttachmentsInternalAsync(
+ applicantAttachmentRepository,
+ attachment => attachment.ApplicantId == attachmentParametersDto.AttachedResourceId),
_ => throw new ArgumentException("Attachment type is not supported", nameof(attachmentParametersDto)),
};
}
@@ -117,6 +126,8 @@ public async Task GetAttachmentMetadataAsync(AttachmentTy
attachmentId, assessmentAttachmentRepository),
AttachmentType.CHEFS => await GetMetadataInternalAsync(
attachmentId, applicationChefsFileAttachmentRepository),
+ AttachmentType.APPLICANT => await GetMetadataInternalAsync(
+ attachmentId, applicantAttachmentRepository),
_ => throw new ArgumentException("Invalid attachment type", nameof(attachmentType)),
};
}
@@ -152,6 +163,10 @@ public async Task UpdateAttachmentMetadataAsync(UpdateAtt
updateAttachment,
applicationChefsFileAttachmentRepository,
AttachmentType.CHEFS),
+ AttachmentType.APPLICANT => await UpdateMetadataInternalAsync(
+ updateAttachment,
+ applicantAttachmentRepository,
+ AttachmentType.APPLICANT),
_ => throw new ArgumentException("Invalid attachment type", nameof(updateAttachment)),
};
}
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/S3BlobProvider.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/S3BlobProvider.cs
index 065e17d24a..2bcff48acd 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/S3BlobProvider.cs
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/S3BlobProvider.cs
@@ -21,14 +21,16 @@ public partial class S3BlobProvider : BlobProviderBase, ITransientDependency
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IApplicationAttachmentRepository _applicationAttachmentRepository;
- private readonly IAssessmentAttachmentRepository _assessmentAttachmentRepository;
+ private readonly IAssessmentAttachmentRepository _assessmentAttachmentRepository;
+ private readonly IApplicantAttachmentRepository _applicantAttachmentRepository;
private readonly AmazonS3Client _amazonS3Client;
- public S3BlobProvider(IHttpContextAccessor httpContextAccessor, IApplicationAttachmentRepository attachmentRepository, IAssessmentAttachmentRepository assessmentAttachmentRepository, IConfiguration configuration)
+ public S3BlobProvider(IHttpContextAccessor httpContextAccessor, IApplicationAttachmentRepository attachmentRepository, IAssessmentAttachmentRepository assessmentAttachmentRepository, IApplicantAttachmentRepository applicantAttachmentRepository, IConfiguration configuration)
{
_httpContextAccessor = httpContextAccessor;
_applicationAttachmentRepository = attachmentRepository;
_assessmentAttachmentRepository = assessmentAttachmentRepository;
+ _applicantAttachmentRepository = applicantAttachmentRepository;
AmazonS3Config s3config = new()
{
@@ -89,6 +91,19 @@ public override async Task DeleteAsync(BlobProviderDeleteArgs args)
await _assessmentAttachmentRepository.DeleteAsync(attachment);
}
}
+ else if (attachmentType == "Applicant")
+ {
+ if (attachmentTypeId.IsNullOrEmpty())
+ {
+ throw new AbpValidationException("Missing ApplicantId");
+ }
+ IQueryable queryableAttachment = _applicantAttachmentRepository.GetQueryableAsync().Result;
+ ApplicantAttachment? attachment = queryableAttachment.FirstOrDefault(a => a.S3ObjectKey.Equals(s3ObjectKey) && a.ApplicantId.Equals(new Guid(attachmentTypeId.ToString())));
+ if (attachment != null)
+ {
+ await _applicantAttachmentRepository.DeleteAsync(attachment);
+ }
+ }
else
{
throw new AbpValidationException("Wrong AttachmentType:"+attachmentType);
@@ -146,30 +161,34 @@ public override async Task SaveAsync(BlobProviderSaveArgs args)
var httpContext = _httpContextAccessor.HttpContext ?? throw new InvalidOperationException("No active HttpContext.");
var queryParams = httpContext.Request?.Query ?? throw new InvalidOperationException("No query parameters in the current request.");
var routeData = _httpContextAccessor.HttpContext.GetRouteData();
- var assessmentId = routeData.Values["assessmentId"];
+ var assessmentId = routeData.Values["assessmentId"];
+ var applicationId = routeData.Values["applicationId"];
+ var applicantId = routeData.Values["applicantId"];
+ queryParams.TryGetValue("userId", out StringValues currentUserId);
if (assessmentId != null)
{
- queryParams.TryGetValue("userId", out StringValues currentUserId);
-#pragma warning disable CS8604 // Possible null reference argument.
+
+ #pragma warning disable CS8604 // Possible null reference argument.
await UploadAssessmentAttachment(args, assessmentId.ToString(), currentUserId.ToString());
-#pragma warning restore CS8604 // Possible null reference argument.
+ #pragma warning restore CS8604 // Possible null reference argument.
+ }
+ else if(applicationId != null)
+ {
+ #pragma warning disable CS8604 // Possible null reference argument.
+ await UploadApplicationAttachment(args, applicationId.ToString(), currentUserId.ToString());
+ #pragma warning restore CS8604 // Possible null reference argument.
+ }
+ else if (applicantId != null)
+ {
+ #pragma warning disable CS8604 // Possible null reference argument.
+ await UploadApplicantAttachment(args, applicantId.ToString(), currentUserId.ToString());
+ #pragma warning restore CS8604 // Possible null reference argument.
}
else
{
- var applicationId = routeData.Values["applicationId"];
- if(applicationId != null)
- {
- queryParams.TryGetValue("userId", out StringValues currentUserId);
-#pragma warning disable CS8604 // Possible null reference argument.
- await UploadApplicationAttachment(args, applicationId.ToString(), currentUserId.ToString());
-#pragma warning restore CS8604 // Possible null reference argument.
- }
- else
- {
- throw new AbpValidationException("Missing parameter: applicationId/assessmentId");
- }
- }
+ throw new AbpValidationException("Missing parameter: applicationId/assessmentId/applicantId");
+ }
}
private async Task UploadAssessmentAttachment(BlobProviderSaveArgs args, string assessmentId, string currentUserId)
@@ -246,6 +265,43 @@ await _applicationAttachmentRepository.InsertAsync(
}
}
+ private async Task UploadApplicantAttachment(BlobProviderSaveArgs args, string applicantId, string currentUserId)
+ {
+ var config = args.Configuration.GetS3BlobProviderConfiguration();
+ var bucket = config.Bucket;
+ var folder = args.Configuration.GetS3BlobProviderConfiguration().ApplicantS3Folder;
+ if (!folder.EndsWith('/'))
+ {
+ folder += "/";
+ }
+ folder += applicantId;
+ var key = folder + "/" + args.BlobName;
+ var escapedKey = folder + "/" + Uri.EscapeDataString(args.BlobName);
+ var mimeType = GetMimeType(args.BlobName);
+ await UploadToS3(args, bucket, escapedKey, mimeType);
+ IQueryable queryableAttachment = _applicantAttachmentRepository.GetQueryableAsync().Result;
+ ApplicantAttachment? attachment = queryableAttachment.FirstOrDefault(a => a.S3ObjectKey.Equals(key) && a.ApplicantId.Equals(new Guid(applicantId)));
+ if (attachment == null)
+ {
+ await _applicantAttachmentRepository.InsertAsync(
+ new ApplicantAttachment
+ {
+ ApplicantId = new Guid(applicantId),
+ S3ObjectKey = key,
+ UserId = new Guid(currentUserId),
+ FileName = args.BlobName,
+ Time = DateTime.UtcNow,
+ });
+ }
+ else
+ {
+ attachment.UserId = new Guid(currentUserId);
+ attachment.FileName = args.BlobName;
+ attachment.Time = DateTime.UtcNow;
+ await _applicantAttachmentRepository.UpdateAsync(attachment);
+ }
+ }
+
public async Task UploadToS3(BlobProviderSaveArgs args, string bucket, string key, string mimeType)
{
byte[] fileBytes;
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/S3BlobProviderConfiguration.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/S3BlobProviderConfiguration.cs
index 9c611dcc6f..9430802abd 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/S3BlobProviderConfiguration.cs
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/Attachments/S3BlobProviderConfiguration.cs
@@ -51,5 +51,12 @@ public string AssessmentS3Folder
.GetConfiguration("S3BlobProvider.AssessmentS3Folder");
set => _containerConfiguration
.SetConfiguration("S3BlobProvider.AssessmentS3Folder", value);
+ }
+ public string ApplicantS3Folder
+ {
+ get => _containerConfiguration
+ .GetConfiguration("S3BlobProvider.ApplicantS3Folder");
+ set => _containerConfiguration
+ .SetConfiguration("S3BlobProvider.ApplicantS3Folder", value);
}
}
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/GrantManagerApplicationModule.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/GrantManagerApplicationModule.cs
index 033d04d512..0b46ff244d 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/GrantManagerApplicationModule.cs
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/GrantManagerApplicationModule.cs
@@ -120,6 +120,7 @@ public override void ConfigureServices(ServiceConfigurationContext context)
provider.SecretAccessKey = configuration["S3:SecretAccessKey"] ?? "";
provider.ApplicationS3Folder = configuration["S3:ApplicationS3Folder"] ?? "";
provider.AssessmentS3Folder = configuration["S3:AssessmentS3Folder"] ?? "";
+ provider.ApplicantS3Folder = configuration["S3:ApplicantS3Folder"] ?? "";
});
});
});
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Domain.Shared/Attachments/AttachmentType.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Domain.Shared/Attachments/AttachmentType.cs
index 944cd73765..956f7be21d 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Domain.Shared/Attachments/AttachmentType.cs
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Domain.Shared/Attachments/AttachmentType.cs
@@ -8,5 +8,6 @@ public enum AttachmentType
APPLICATION = 0,
ASSESSMENT = 1,
CHEFS = 2,
- EMAIL = 3
+ EMAIL = 3,
+ APPLICANT = 4
}
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/Applications/ApplicantAttachment.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/Applications/ApplicantAttachment.cs
new file mode 100644
index 0000000000..7cd3c10d2d
--- /dev/null
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/Applications/ApplicantAttachment.cs
@@ -0,0 +1,12 @@
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using Unity.GrantManager.Attachments;
+
+namespace Unity.GrantManager.Applications;
+
+public class ApplicantAttachment : AbstractS3Attachment
+{
+ [NotMapped]
+ public override AttachmentType AttachmentType => AttachmentType.APPLICANT;
+ public Guid ApplicantId { get; set; }
+}
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/Applications/IApplicantAttachmentRepository.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/Applications/IApplicantAttachmentRepository.cs
new file mode 100644
index 0000000000..da65ccc89c
--- /dev/null
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/Applications/IApplicantAttachmentRepository.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.Domain.Repositories;
+
+namespace Unity.GrantManager.Applications
+{
+ public interface IApplicantAttachmentRepository : IRepository
+ {
+ Task> GetListAsync(
+ int skipCount,
+ int maxResultCount,
+ string sorting,
+ string filter
+ );
+ }
+}
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/GrantManagerDataSeederContributor.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/GrantManagerDataSeederContributor.cs
index 3958d29de3..e469c96074 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/GrantManagerDataSeederContributor.cs
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Domain/GrantManagerDataSeederContributor.cs
@@ -30,7 +30,7 @@ public static class GrantApplicationStates
public const string INITITAL_REVIEW_COMPLETED = "Initial Review Completed";
public const string UNDER_ASSESSMENT = "Under Assessment";
public const string ASSESSMENT_COMPLETED = "Assessment Completed";
- public const string GRANT_APPROVED = "Grant Approved";
+ public const string GRANT_APPROVED = "Approved";
public const string DECLINED = "Declined";
public const string DEFER = "Deferred";
public const string ON_HOLD = "On Hold";
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/EntityFrameworkCore/GrantTenantDbContext.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/EntityFrameworkCore/GrantTenantDbContext.cs
index f20765fecc..eca253ff34 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/EntityFrameworkCore/GrantTenantDbContext.cs
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/EntityFrameworkCore/GrantTenantDbContext.cs
@@ -39,6 +39,7 @@ public class GrantTenantDbContext : AbpDbContext
public DbSet ApplicationTags { get; set; }
public DbSet ApplicantAgents { get; set; }
public DbSet ApplicantComments { get; set; }
+ public DbSet ApplicantAttachments { get; set; }
public DbSet ApplicationAttachments { get; set; }
public DbSet ApplicationFormSubmissions { get; set; }
public DbSet AssessmentAttachments { get; set; }
@@ -217,6 +218,14 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
.HasForeignKey(x => x.CommenterId);
});
+ modelBuilder.Entity(b =>
+ {
+ b.ToTable(GrantManagerConsts.TenantTablePrefix + "ApplicantAttachments", GrantManagerConsts.DbSchema);
+
+ b.ConfigureByConvention();
+ b.HasOne().WithMany().HasForeignKey(x => x.ApplicantId).IsRequired();
+ });
+
modelBuilder.Entity(b =>
{
b.ToTable(GrantManagerConsts.TenantTablePrefix + "ApplicationAttachments", GrantManagerConsts.DbSchema);
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260401222707_AddApplicantAttachments.Designer.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260401222707_AddApplicantAttachments.Designer.cs
new file mode 100644
index 0000000000..678061b573
--- /dev/null
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore/Migrations/TenantMigrations/20260401222707_AddApplicantAttachments.Designer.cs
@@ -0,0 +1,4938 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Unity.GrantManager.EntityFrameworkCore;
+using Volo.Abp.EntityFrameworkCore;
+
+#nullable disable
+
+namespace Unity.GrantManager.Migrations.TenantMigrations
+{
+ [DbContext(typeof(GrantTenantDbContext))]
+ [Migration("20260401222707_AddApplicantAttachments")]
+ partial class AddApplicantAttachments
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.PostgreSql)
+ .HasAnnotation("ProductVersion", "9.0.5")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Unity.Flex.Domain.ScoresheetInstances.ScoresheetInstance", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasColumnType("uuid");
+
+ b.Property("CorrelationProvider")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("DeletionTime");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("ReportData")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("ScoresheetId")
+ .HasColumnType("uuid");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ScoresheetId");
+
+ b.ToTable("ScoresheetInstances", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.Scoresheets.Answer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("CurrentValue")
+ .HasColumnType("jsonb");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("DeletionTime");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("QuestionId")
+ .HasColumnType("uuid");
+
+ b.Property("ScoresheetInstanceId")
+ .HasColumnType("uuid");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("Version")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("QuestionId");
+
+ b.HasIndex("ScoresheetInstanceId");
+
+ b.ToTable("Answers", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.Scoresheets.Question", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("Definition")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Description")
+ .HasColumnType("text");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("Label")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Order")
+ .HasColumnType("bigint");
+
+ b.Property("SectionId")
+ .HasColumnType("uuid");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SectionId");
+
+ b.ToTable("Questions", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.Scoresheets.Scoresheet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("DeletionTime");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Order")
+ .HasColumnType("bigint");
+
+ b.Property("Published")
+ .HasColumnType("boolean");
+
+ b.Property("ReportColumns")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ReportKeys")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ReportViewName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Version")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.ToTable("Scoresheets", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.Scoresheets.ScoresheetSection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("DeletionTime");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Order")
+ .HasColumnType("bigint");
+
+ b.Property("ScoresheetId")
+ .HasColumnType("uuid");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ScoresheetId");
+
+ b.ToTable("ScoresheetSections", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.WorksheetInstances.CustomFieldValue", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("CurrentValue")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("CustomFieldId")
+ .HasColumnType("uuid");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("WorksheetInstanceId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("WorksheetInstanceId");
+
+ b.ToTable("CustomFieldValues", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.WorksheetInstances.WorksheetInstance", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasColumnType("uuid");
+
+ b.Property("CorrelationProvider")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("CurrentValue")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("DeletionTime");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("ReportData")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("UiAnchor")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("WorksheetCorrelationId")
+ .HasColumnType("uuid");
+
+ b.Property("WorksheetCorrelationProvider")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("WorksheetId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.ToTable("WorksheetInstances", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.WorksheetLinks.WorksheetLink", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasColumnType("uuid");
+
+ b.Property("CorrelationProvider")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Order")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("UiAnchor")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("WorksheetId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("WorksheetId");
+
+ b.ToTable("WorksheetLinks", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.Worksheets.CustomField", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("Definition")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Label")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Order")
+ .HasColumnType("bigint");
+
+ b.Property("SectionId")
+ .HasColumnType("uuid");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SectionId");
+
+ b.ToTable("CustomFields", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.Worksheets.Worksheet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("DeletionTime");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Published")
+ .HasColumnType("boolean");
+
+ b.Property("ReportColumns")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ReportKeys")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ReportViewName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Version")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.ToTable("Worksheets", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.Flex.Domain.Worksheets.WorksheetSection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("DeletionTime");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Order")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("WorksheetId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("WorksheetId");
+
+ b.ToTable("WorksheetSections", "Flex");
+ });
+
+ modelBuilder.Entity("Unity.GrantManager.Applications.Applicant", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("ApplicantName")
+ .IsRequired()
+ .HasMaxLength(600)
+ .HasColumnType("character varying(600)");
+
+ b.Property("ApproxNumberOfEmployees")
+ .HasColumnType("text");
+
+ b.Property("AuditComments")
+ .HasColumnType("text");
+
+ b.Property("BusinessNumber")
+ .HasColumnType("text");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("FiscalDay")
+ .HasColumnType("integer");
+
+ b.Property("FiscalMonth")
+ .HasColumnType("text");
+
+ b.Property("FundingHistoryComments")
+ .HasColumnType("text");
+
+ b.Property("IndigenousOrgInd")
+ .HasColumnType("text");
+
+ b.Property("IsDuplicated")
+ .HasColumnType("boolean");
+
+ b.Property("IssueTrackingComments")
+ .HasColumnType("text");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("MatchPercentage")
+ .HasColumnType("numeric");
+
+ b.Property("NonRegOrgName")
+ .HasColumnType("text");
+
+ b.Property("NonRegisteredBusinessName")
+ .HasColumnType("text");
+
+ b.Property("OrgName")
+ .HasColumnType("text");
+
+ b.Property("OrgNumber")
+ .HasColumnType("text");
+
+ b.Property("OrgStatus")
+ .HasColumnType("text");
+
+ b.Property("OrganizationSize")
+ .HasColumnType("text");
+
+ b.Property("OrganizationType")
+ .HasColumnType("text");
+
+ b.Property("RedStop")
+ .HasColumnType("boolean");
+
+ b.Property("Sector")
+ .HasColumnType("text");
+
+ b.Property("SectorSubSectorIndustryDesc")
+ .HasColumnType("text");
+
+ b.Property("SiteId")
+ .HasColumnType("uuid");
+
+ b.Property("StartedOperatingDate")
+ .HasColumnType("date");
+
+ b.Property("Status")
+ .HasColumnType("text");
+
+ b.Property("SubSector")
+ .HasColumnType("text");
+
+ b.Property("SupplierId")
+ .HasColumnType("uuid");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("UnityApplicantId")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ApplicantName");
+
+ b.ToTable("Applicants", (string)null);
+ });
+
+ modelBuilder.Entity("Unity.GrantManager.Applications.ApplicantAddress", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("AddressType")
+ .HasColumnType("integer");
+
+ b.Property("ApplicantId")
+ .HasColumnType("uuid");
+
+ b.Property("ApplicationId")
+ .HasColumnType("uuid");
+
+ b.Property("City")
+ .HasColumnType("text");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("Country")
+ .HasColumnType("text");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("CreatorId");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Postal")
+ .HasColumnType("text");
+
+ b.Property("Province")
+ .HasColumnType("text");
+
+ b.Property("Street")
+ .HasColumnType("text");
+
+ b.Property("Street2")
+ .HasColumnType("text");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("TenantId");
+
+ b.Property("Unit")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ApplicantId");
+
+ b.HasIndex("ApplicationId");
+
+ b.ToTable("ApplicantAddresses", (string)null);
+ });
+
+ modelBuilder.Entity("Unity.GrantManager.Applications.ApplicantAgent", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("ApplicantId")
+ .HasColumnType("uuid");
+
+ b.Property("ApplicationId")
+ .HasColumnType("uuid");
+
+ b.Property("BceidBusinessGuid")
+ .HasColumnType("uuid");
+
+ b.Property("BceidBusinessName")
+ .HasColumnType("text");
+
+ b.Property |