arreglo certificados de registro
This commit is contained in:
@@ -104,16 +104,25 @@ public sealed class InboxTrackingService : IInboxTrackingService
|
||||
LastDownloadedAt = meta?.LastDownloadedAtUtc?.ToString("O", CultureInfo.InvariantCulture),
|
||||
AlreadyImported = meta?.AlreadyImported ?? false,
|
||||
AlreadyInGestiona = meta?.AlreadyInGestiona ?? false,
|
||||
OwnerUsername = meta?.OwnerUsername,
|
||||
OwnedByCurrentUser = meta?.OwnedByCurrentUser ?? false,
|
||||
AccessibleByWorkGroup = meta?.AccessibleByWorkGroup ?? false,
|
||||
RequiresOwnerConfirmation = meta?.RequiresOwnerConfirmation ?? false,
|
||||
OwnerWorkGroups = meta?.OwnerWorkGroups ?? [],
|
||||
TrackingNote = BuildTrackingNote(meta)
|
||||
};
|
||||
})
|
||||
.Where(report => !IsLockedByAnotherUser(report))
|
||||
.Where(report =>
|
||||
string.IsNullOrWhiteSpace(report.OwnerUsername) ||
|
||||
report.OwnedByCurrentUser ||
|
||||
report.AccessibleByWorkGroup)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public async Task EnsureReportCanBeImportedByUserAsync(
|
||||
string username,
|
||||
ReportDto report,
|
||||
bool confirmDifferentOwner = false,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _denunciaStore.EnsureSchemaAsync(cancellationToken);
|
||||
@@ -140,14 +149,23 @@ public sealed class InboxTrackingService : IInboxTrackingService
|
||||
|
||||
await EnsureConnectionOpenAsync(connection, cancellationToken);
|
||||
var metadata = await LoadMetadataAsync(connection, userId, [report.Id], cancellationToken);
|
||||
if (metadata.TryGetValue(report.Id, out var meta) && meta.LockedByAnotherUser)
|
||||
if (!metadata.TryGetValue(report.Id, out var meta) ||
|
||||
string.IsNullOrWhiteSpace(meta.OwnerUsername) ||
|
||||
meta.OwnedByCurrentUser)
|
||||
{
|
||||
var owner = string.IsNullOrWhiteSpace(meta.LastDownloadedByUsername)
|
||||
? "otro usuario"
|
||||
: meta.LastDownloadedByUsername;
|
||||
return;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(
|
||||
$"La denuncia ya fue importada por {owner}. Solo ese usuario puede ver e importar sus actualizaciones.");
|
||||
if (!meta.AccessibleByWorkGroup)
|
||||
{
|
||||
throw new ReportOwnershipException(
|
||||
$"La denuncia pertenece a {meta.OwnerUsername} y no compartis ningun grupo de trabajo.");
|
||||
}
|
||||
|
||||
if (!confirmDifferentOwner)
|
||||
{
|
||||
throw new ReportOwnershipException(
|
||||
$"La denuncia pertenece a {meta.OwnerUsername}. Confirma expresamente que deseas importarla como miembro de su grupo.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +198,7 @@ public sealed class InboxTrackingService : IInboxTrackingService
|
||||
SET
|
||||
last_downloaded_at_utc = @nowUtc,
|
||||
last_downloaded_by_user_id = @userId,
|
||||
owner_user_id = COALESCE(owner_user_id, @userId),
|
||||
imported_complaint_report_id = COALESCE(@complaintId, imported_complaint_report_id),
|
||||
imported_to_store_at_utc = COALESCE(imported_to_store_at_utc, @nowUtc),
|
||||
updated_at_utc = CURRENT_TIMESTAMP(6)
|
||||
@@ -298,6 +317,7 @@ public sealed class InboxTrackingService : IInboxTrackingService
|
||||
ELSE last_downloaded_at_utc
|
||||
END,
|
||||
last_downloaded_by_user_id = @userId,
|
||||
owner_user_id = COALESCE(owner_user_id, @userId),
|
||||
imported_complaint_report_id = COALESCE(imported_complaint_report_id, @denunciaId),
|
||||
imported_to_store_at_utc = COALESCE(imported_to_store_at_utc, @handledAtUtc),
|
||||
updated_at_utc = CURRENT_TIMESTAMP(6)
|
||||
@@ -512,11 +532,37 @@ public sealed class InboxTrackingService : IInboxTrackingService
|
||||
ir.global_report_uuid,
|
||||
ir.last_downloaded_at_utc,
|
||||
downloader.username AS last_downloaded_by_username,
|
||||
owner.username AS owner_username,
|
||||
ir.imported_to_store_at_utc,
|
||||
COALESCE(c.is_in_gestiona, 0) AS already_in_gestiona,
|
||||
CASE WHEN uir.last_downloaded_at_utc IS NULL THEN 0 ELSE 1 END AS downloaded_by_current_user
|
||||
CASE WHEN uir.last_downloaded_at_utc IS NULL THEN 0 ELSE 1 END AS downloaded_by_current_user,
|
||||
CASE WHEN ir.owner_user_id = @userId THEN 1 ELSE 0 END AS owned_by_current_user,
|
||||
CASE
|
||||
WHEN ir.owner_user_id IS NULL THEN 0
|
||||
WHEN EXISTS (
|
||||
SELECT 1
|
||||
FROM app_user_groups current_group
|
||||
INNER JOIN app_user_groups owner_group
|
||||
ON owner_group.work_group_id = current_group.work_group_id
|
||||
INNER JOIN work_groups active_group
|
||||
ON active_group.id = current_group.work_group_id
|
||||
AND active_group.is_active = 1
|
||||
WHERE current_group.app_user_id = @userId
|
||||
AND owner_group.app_user_id = ir.owner_user_id
|
||||
) THEN 1
|
||||
ELSE 0
|
||||
END AS accessible_by_group,
|
||||
(
|
||||
SELECT GROUP_CONCAT(DISTINCT wg.code ORDER BY wg.code SEPARATOR ',')
|
||||
FROM app_user_groups owner_membership
|
||||
INNER JOIN work_groups wg
|
||||
ON wg.id = owner_membership.work_group_id
|
||||
AND wg.is_active = 1
|
||||
WHERE owner_membership.app_user_id = ir.owner_user_id
|
||||
) AS owner_group_codes
|
||||
FROM inbox_reports ir
|
||||
LEFT JOIN app_users downloader ON downloader.id = ir.last_downloaded_by_user_id
|
||||
LEFT JOIN app_users owner ON owner.id = ir.owner_user_id
|
||||
LEFT JOIN user_inbox_reports uir
|
||||
ON uir.inbox_report_id = ir.id
|
||||
AND uir.app_user_id = @userId
|
||||
@@ -533,14 +579,20 @@ public sealed class InboxTrackingService : IInboxTrackingService
|
||||
? null
|
||||
: reader.GetString(reader.GetOrdinal("last_downloaded_by_username"));
|
||||
var downloadedByCurrentUser = reader.GetInt32(reader.GetOrdinal("downloaded_by_current_user")) == 1;
|
||||
var lockedByAnotherUser =
|
||||
!downloadedByCurrentUser &&
|
||||
!reader.IsDBNull(reader.GetOrdinal("imported_to_store_at_utc")) &&
|
||||
!string.IsNullOrWhiteSpace(lastDownloadedByUsername);
|
||||
|
||||
var downloadedByAnotherUser =
|
||||
!downloadedByCurrentUser &&
|
||||
!string.IsNullOrWhiteSpace(lastDownloadedByUsername);
|
||||
var downloadedByAnotherUser =
|
||||
!downloadedByCurrentUser &&
|
||||
!string.IsNullOrWhiteSpace(lastDownloadedByUsername);
|
||||
var ownerUsername = reader.IsDBNull(reader.GetOrdinal("owner_username"))
|
||||
? null
|
||||
: reader.GetString(reader.GetOrdinal("owner_username"));
|
||||
var ownedByCurrentUser =
|
||||
reader.GetInt32(reader.GetOrdinal("owned_by_current_user")) == 1;
|
||||
var accessibleByGroup =
|
||||
reader.GetInt32(reader.GetOrdinal("accessible_by_group")) == 1;
|
||||
var ownerWorkGroups = reader.IsDBNull(reader.GetOrdinal("owner_group_codes"))
|
||||
? []
|
||||
: reader.GetString(reader.GetOrdinal("owner_group_codes"))
|
||||
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
|
||||
metadata[reportId] = new ReportMetadata
|
||||
{
|
||||
@@ -550,7 +602,10 @@ public sealed class InboxTrackingService : IInboxTrackingService
|
||||
LastDownloadedAtUtc = GetDateTimeOffset(reader, "last_downloaded_at_utc"),
|
||||
AlreadyImported = !reader.IsDBNull(reader.GetOrdinal("imported_to_store_at_utc")),
|
||||
AlreadyInGestiona = reader.GetInt32(reader.GetOrdinal("already_in_gestiona")) == 1,
|
||||
LockedByAnotherUser = lockedByAnotherUser,
|
||||
OwnerUsername = ownerUsername,
|
||||
OwnedByCurrentUser = ownedByCurrentUser,
|
||||
AccessibleByWorkGroup = accessibleByGroup,
|
||||
OwnerWorkGroups = ownerWorkGroups,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -654,11 +709,10 @@ public sealed class InboxTrackingService : IInboxTrackingService
|
||||
return null;
|
||||
}
|
||||
|
||||
if (metadata.LockedByAnotherUser)
|
||||
if (!string.IsNullOrWhiteSpace(metadata.OwnerUsername) &&
|
||||
!metadata.OwnedByCurrentUser)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(metadata.LastDownloadedByUsername)
|
||||
? "Importada por otro usuario"
|
||||
: $"Importada por {metadata.LastDownloadedByUsername}";
|
||||
return $"Propiedad de {metadata.OwnerUsername}";
|
||||
}
|
||||
|
||||
if (metadata.AlreadyInGestiona)
|
||||
@@ -693,15 +747,25 @@ public sealed class InboxTrackingService : IInboxTrackingService
|
||||
{
|
||||
public bool DownloadedByCurrentUser { get; init; }
|
||||
public bool DownloadedByAnotherUser { get; init; }
|
||||
public bool LockedByAnotherUser { get; init; }
|
||||
public string? LastDownloadedByUsername { get; init; }
|
||||
public DateTimeOffset? LastDownloadedAtUtc { get; init; }
|
||||
public bool AlreadyImported { get; init; }
|
||||
public bool AlreadyInGestiona { get; init; }
|
||||
public string? OwnerUsername { get; init; }
|
||||
public bool OwnedByCurrentUser { get; init; }
|
||||
public bool AccessibleByWorkGroup { get; init; }
|
||||
public IReadOnlyList<string> OwnerWorkGroups { get; init; } = [];
|
||||
public bool RequiresOwnerConfirmation =>
|
||||
!OwnedByCurrentUser &&
|
||||
AccessibleByWorkGroup &&
|
||||
!string.IsNullOrWhiteSpace(OwnerUsername);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ReportOwnershipException : InvalidOperationException
|
||||
{
|
||||
public ReportOwnershipException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
private static bool IsLockedByAnotherUser(ReportDto report)
|
||||
=> report.AlreadyImported &&
|
||||
report.DownloadedByAnotherUser &&
|
||||
!report.DownloadedByCurrentUser;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user