Filters
This commit is contained in:
@@ -148,6 +148,7 @@ function convertQSODatabaseFormat(adifQSO, userId) {
|
||||
mode: normalizeMode(adifQSO.mode),
|
||||
freq: adifQSO.freq ? parseInt(adifQSO.freq) : null,
|
||||
freqRx: adifQSO.freq_rx ? parseInt(adifQSO.freq_rx) : null,
|
||||
// DCL may or may not include DXCC fields - use them if available
|
||||
entity: adifQSO.country || adifQSO.dxcc_country || '',
|
||||
entityId: adifQSO.dxcc ? parseInt(adifQSO.dxcc) : null,
|
||||
grid: adifQSO.gridsquare || '',
|
||||
@@ -252,7 +253,6 @@ export async function syncQSOs(userId, dclApiKey, sinceDate = null, jobId = null
|
||||
|
||||
if (dataChanged) {
|
||||
// Update existing QSO with changed DCL confirmation and DOK data
|
||||
// Only update DOK/grid fields if DCL actually sent values (non-empty)
|
||||
const updateData = {
|
||||
dclQslRdate: dbQSO.dclQslRdate,
|
||||
dclQslRstatus: dbQSO.dclQslRstatus,
|
||||
@@ -268,6 +268,24 @@ export async function syncQSOs(userId, dclApiKey, sinceDate = null, jobId = null
|
||||
updateData.gridSource = dbQSO.gridSource;
|
||||
}
|
||||
|
||||
// DXCC priority: LoTW > DCL
|
||||
// Only update entity fields from DCL if:
|
||||
// 1. QSO is NOT LoTW confirmed, AND
|
||||
// 2. DCL actually sent entity data, AND
|
||||
// 3. Current entity is missing
|
||||
const hasLoTWConfirmation = existingQSO.lotwQslRstatus === 'Y';
|
||||
const hasDCLData = dbQSO.entity || dbQSO.entityId;
|
||||
const missingEntity = !existingQSO.entity || existingQSO.entity === '';
|
||||
|
||||
if (!hasLoTWConfirmation && hasDCLData && missingEntity) {
|
||||
// Fill in entity data from DCL (only if DCL provides it)
|
||||
if (dbQSO.entity) updateData.entity = dbQSO.entity;
|
||||
if (dbQSO.entityId) updateData.entityId = dbQSO.entityId;
|
||||
if (dbQSO.continent) updateData.continent = dbQSO.continent;
|
||||
if (dbQSO.cqZone) updateData.cqZone = dbQSO.cqZone;
|
||||
if (dbQSO.ituZone) updateData.ituZone = dbQSO.ituZone;
|
||||
}
|
||||
|
||||
await db
|
||||
.update(qsos)
|
||||
.set(updateData)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { db, logger } from '../config.js';
|
||||
import { qsos } from '../db/schema/index.js';
|
||||
import { max, sql, eq, and, desc } from 'drizzle-orm';
|
||||
import { max, sql, eq, and, or, desc, like } from 'drizzle-orm';
|
||||
import { updateJobProgress } from './job-queue.service.js';
|
||||
import { parseADIF, normalizeBand, normalizeMode } from '../utils/adif-parser.js';
|
||||
|
||||
@@ -328,6 +328,35 @@ export async function getUserQSOs(userId, filters = {}, options = {}) {
|
||||
if (filters.mode) conditions.push(eq(qsos.mode, filters.mode));
|
||||
if (filters.confirmed) conditions.push(eq(qsos.lotwQslRstatus, 'Y'));
|
||||
|
||||
// Confirmation type filter: lotw, dcl, both, none
|
||||
if (filters.confirmationType) {
|
||||
if (filters.confirmationType === 'lotw') {
|
||||
conditions.push(eq(qsos.lotwQslRstatus, 'Y'));
|
||||
} else if (filters.confirmationType === 'dcl') {
|
||||
conditions.push(eq(qsos.dclQslRstatus, 'Y'));
|
||||
} else if (filters.confirmationType === 'both') {
|
||||
conditions.push(and(
|
||||
eq(qsos.lotwQslRstatus, 'Y'),
|
||||
eq(qsos.dclQslRstatus, 'Y')
|
||||
));
|
||||
} else if (filters.confirmationType === 'none') {
|
||||
conditions.push(and(
|
||||
sql`${qsos.lotwQslRstatus} IS NULL OR ${qsos.lotwQslRstatus} != 'Y'`,
|
||||
sql`${qsos.dclQslRstatus} IS NULL OR ${qsos.dclQslRstatus} != 'Y'`
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Search filter: callsign, entity, or grid
|
||||
if (filters.search) {
|
||||
const searchTerm = `%${filters.search}%`;
|
||||
conditions.push(or(
|
||||
like(qsos.callsign, searchTerm),
|
||||
like(qsos.entity, searchTerm),
|
||||
like(qsos.grid, searchTerm)
|
||||
));
|
||||
}
|
||||
|
||||
const allResults = await db.select().from(qsos).where(and(...conditions));
|
||||
const totalCount = allResults.length;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user