fixed transfer process
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { db } from '../db/client.js';
|
||||
import type { BirdGender, BirdRow, VetVisitRow, WeightRow } from '../types.js';
|
||||
import type { BirdGender, BirdRow, PendingBirdTransferRow, VetVisitRow, WeightRow } from '../types.js';
|
||||
|
||||
const birdSelectFields = `
|
||||
birds.id,
|
||||
@@ -195,6 +195,97 @@ export const transferBirdToWorkspace = async (birdId: string, sourceWorkspaceId:
|
||||
return result.rows[0] ?? null;
|
||||
};
|
||||
|
||||
export const createPendingBirdTransfer = async ({
|
||||
birdId,
|
||||
sourceWorkspaceId,
|
||||
destinationOwnerEmail,
|
||||
requestedByUserId,
|
||||
}: {
|
||||
birdId: string;
|
||||
sourceWorkspaceId: number;
|
||||
destinationOwnerEmail: string;
|
||||
requestedByUserId: string;
|
||||
}) => {
|
||||
const result = await db.query<PendingBirdTransferRow>(
|
||||
`INSERT INTO pending_bird_transfers (bird_id, source_workspace_id, destination_owner_email, requested_by_user_id)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (bird_id) WHERE completed_at IS NULL DO UPDATE
|
||||
SET destination_owner_email = EXCLUDED.destination_owner_email,
|
||||
requested_by_user_id = EXCLUDED.requested_by_user_id,
|
||||
last_error = NULL,
|
||||
created_at = CURRENT_TIMESTAMP
|
||||
RETURNING id, bird_id, source_workspace_id, destination_owner_email, requested_by_user_id, completed_at::text, completed_workspace_id, last_error, created_at`,
|
||||
[birdId, sourceWorkspaceId, destinationOwnerEmail, requestedByUserId],
|
||||
);
|
||||
|
||||
return result.rows[0] ?? null;
|
||||
};
|
||||
|
||||
export const listPendingBirdTransfersForOwnerEmail = async (ownerEmail: string) => {
|
||||
const result = await db.query<PendingBirdTransferRow>(
|
||||
`SELECT id, bird_id, source_workspace_id, destination_owner_email, requested_by_user_id, completed_at::text, completed_workspace_id, last_error, created_at
|
||||
FROM pending_bird_transfers
|
||||
WHERE LOWER(destination_owner_email) = LOWER($1)
|
||||
AND completed_at IS NULL
|
||||
ORDER BY created_at ASC`,
|
||||
[ownerEmail],
|
||||
);
|
||||
|
||||
return result.rows;
|
||||
};
|
||||
|
||||
export const markPendingBirdTransferCompleted = async (transferId: string, completedWorkspaceId: number) => {
|
||||
await db.query(
|
||||
`UPDATE pending_bird_transfers
|
||||
SET completed_at = CURRENT_TIMESTAMP,
|
||||
completed_workspace_id = $2,
|
||||
last_error = NULL
|
||||
WHERE id = $1`,
|
||||
[transferId, completedWorkspaceId],
|
||||
);
|
||||
};
|
||||
|
||||
export const markPendingBirdTransferFailed = async (transferId: string, lastError: string) => {
|
||||
await db.query(
|
||||
`UPDATE pending_bird_transfers
|
||||
SET last_error = $2
|
||||
WHERE id = $1`,
|
||||
[transferId, lastError],
|
||||
);
|
||||
};
|
||||
|
||||
export const completePendingBirdTransfersForOwner = async (ownerEmail: string, targetWorkspaceId: number) => {
|
||||
const transfers = await listPendingBirdTransfersForOwnerEmail(ownerEmail);
|
||||
let completed = 0;
|
||||
let failed = 0;
|
||||
|
||||
for (const transfer of transfers) {
|
||||
try {
|
||||
const bird = await transferBirdToWorkspace(transfer.bird_id, transfer.source_workspace_id, targetWorkspaceId);
|
||||
|
||||
if (!bird) {
|
||||
failed += 1;
|
||||
await markPendingBirdTransferFailed(transfer.id, 'Bird is no longer available in the source flock.');
|
||||
continue;
|
||||
}
|
||||
|
||||
await markPendingBirdTransferCompleted(transfer.id, targetWorkspaceId);
|
||||
completed += 1;
|
||||
} catch (error) {
|
||||
failed += 1;
|
||||
const message =
|
||||
typeof error === 'object' && error && 'code' in error && error.code === '23505'
|
||||
? 'The receiving flock already has a bird using the same band/tag ID.'
|
||||
: error instanceof Error
|
||||
? error.message
|
||||
: 'Unable to complete pending bird transfer.';
|
||||
await markPendingBirdTransferFailed(transfer.id, message);
|
||||
}
|
||||
}
|
||||
|
||||
return { completed, failed };
|
||||
};
|
||||
|
||||
export const listWeightsForBird = async (birdId: string, workspaceId: number, days: number) => {
|
||||
const result = await db.query<WeightRow>(
|
||||
`SELECT id, bird_id, weight_grams, recorded_on::text, notes
|
||||
|
||||
Reference in New Issue
Block a user