mirror of
https://github.com/System-End/scraps.git
synced 2026-04-19 16:28:20 +00:00
aaa
This commit is contained in:
parent
ad844dbcb3
commit
8bfdcc7d52
3 changed files with 42 additions and 14 deletions
24
backend/dist/index.js
vendored
24
backend/dist/index.js
vendored
|
|
@ -32628,17 +32628,17 @@ function calculateScrapsFromHours(hours, tier = 1) {
|
|||
}
|
||||
async function getUserScrapsBalance(userId, txOrDb = db) {
|
||||
const earnedResult = await txOrDb.select({
|
||||
total: sql`COALESCE(SUM(${projectsTable.scrapsPaidAmount}), 0)`
|
||||
}).from(projectsTable).where(sql`${projectsTable.userId} = ${userId} AND ${projectsTable.scrapsPaidAmount} > 0`);
|
||||
total: sql`COALESCE(SUM(CASE WHEN ${projectsTable.scrapsPaidAmount} > 0 THEN ${projectsTable.scrapsPaidAmount} ELSE ${projectsTable.scrapsAwarded} END), 0)`
|
||||
}).from(projectsTable).where(sql`${projectsTable.userId} = ${userId} AND ${projectsTable.scrapsPaidAt} IS NOT NULL AND ${projectsTable.scrapsAwarded} > 0`);
|
||||
const pendingResult = await txOrDb.select({
|
||||
total: sql`COALESCE(SUM(${projectsTable.scrapsAwarded} - ${projectsTable.scrapsPaidAmount}), 0)`
|
||||
}).from(projectsTable).where(sql`${projectsTable.userId} = ${userId} AND ${projectsTable.status} = 'shipped' AND (${projectsTable.deleted} = 0 OR ${projectsTable.deleted} IS NULL) AND ${projectsTable.scrapsPaidAt} IS NULL AND ${projectsTable.scrapsAwarded} > ${projectsTable.scrapsPaidAmount}`);
|
||||
total: sql`COALESCE(SUM(${projectsTable.scrapsAwarded} - CASE WHEN ${projectsTable.scrapsPaidAmount} > 0 THEN ${projectsTable.scrapsPaidAmount} ELSE 0 END), 0)`
|
||||
}).from(projectsTable).where(sql`${projectsTable.userId} = ${userId} AND ${projectsTable.status} = 'shipped' AND (${projectsTable.deleted} = 0 OR ${projectsTable.deleted} IS NULL) AND ${projectsTable.scrapsPaidAt} IS NULL AND ${projectsTable.scrapsAwarded} > 0`);
|
||||
const bonusResult = await txOrDb.select({
|
||||
total: sql`COALESCE(SUM(${userBonusesTable.amount}), 0)`
|
||||
}).from(userBonusesTable).where(eq(userBonusesTable.userId, userId));
|
||||
const spentResult = await txOrDb.select({
|
||||
total: sql`COALESCE(SUM(${shopOrdersTable.totalPrice}), 0)`
|
||||
}).from(shopOrdersTable).where(eq(shopOrdersTable.userId, userId));
|
||||
}).from(shopOrdersTable).where(sql`${shopOrdersTable.userId} = ${userId} AND ${shopOrdersTable.status} NOT IN ('cancelled', 'deleted')`);
|
||||
const upgradeSpentResult = await txOrDb.select({
|
||||
total: sql`COALESCE(SUM(${refinerySpendingHistoryTable.cost}), 0)`
|
||||
}).from(refinerySpendingHistoryTable).where(eq(refinerySpendingHistoryTable.userId, userId));
|
||||
|
|
@ -34339,7 +34339,19 @@ function formatHoursMinutes(hours) {
|
|||
}
|
||||
function buildJustification(project, reviews, effectiveHours) {
|
||||
const lines = [];
|
||||
lines.push(`The user logged ${formatHoursMinutes(effectiveHours)} on hackatime.`);
|
||||
const rawHours = project.hours ?? 0;
|
||||
if (project.hoursOverride !== null && project.hoursOverride !== rawHours) {
|
||||
lines.push(`The user logged ${formatHoursMinutes(rawHours)} on hackatime.`);
|
||||
lines.push(`Hours were overridden to ${formatHoursMinutes(project.hoursOverride)} by a reviewer.`);
|
||||
if (effectiveHours !== project.hoursOverride) {
|
||||
lines.push(`After deducting overlapping projects, effective hours: ${formatHoursMinutes(effectiveHours)}.`);
|
||||
}
|
||||
} else if (effectiveHours !== rawHours) {
|
||||
lines.push(`The user logged ${formatHoursMinutes(rawHours)} on hackatime.`);
|
||||
lines.push(`After deducting overlapping projects, effective hours: ${formatHoursMinutes(effectiveHours)}.`);
|
||||
} else {
|
||||
lines.push(`The user logged ${formatHoursMinutes(effectiveHours)} on hackatime.`);
|
||||
}
|
||||
lines.push("");
|
||||
lines.push(`The scraps project can be found at ${config.frontendUrl}/projects/${project.id}`);
|
||||
if (reviews.length > 0) {
|
||||
|
|
|
|||
|
|
@ -44,8 +44,20 @@ function buildJustification(project: {
|
|||
createdAt: Date
|
||||
}[], effectiveHours: number): string {
|
||||
const lines: string[] = []
|
||||
const rawHours = project.hours ?? 0
|
||||
|
||||
lines.push(`The user logged ${formatHoursMinutes(effectiveHours)} on hackatime.`)
|
||||
if (project.hoursOverride !== null && project.hoursOverride !== rawHours) {
|
||||
lines.push(`The user logged ${formatHoursMinutes(rawHours)} on hackatime.`)
|
||||
lines.push(`Hours were overridden to ${formatHoursMinutes(project.hoursOverride)} by a reviewer.`)
|
||||
if (effectiveHours !== project.hoursOverride) {
|
||||
lines.push(`After deducting overlapping projects, effective hours: ${formatHoursMinutes(effectiveHours)}.`)
|
||||
}
|
||||
} else if (effectiveHours !== rawHours) {
|
||||
lines.push(`The user logged ${formatHoursMinutes(rawHours)} on hackatime.`)
|
||||
lines.push(`After deducting overlapping projects, effective hours: ${formatHoursMinutes(effectiveHours)}.`)
|
||||
} else {
|
||||
lines.push(`The user logged ${formatHoursMinutes(effectiveHours)} on hackatime.`)
|
||||
}
|
||||
lines.push('')
|
||||
lines.push(`The scraps project can be found at ${config.frontendUrl}/projects/${project.id}`)
|
||||
|
||||
|
|
|
|||
|
|
@ -154,24 +154,26 @@ export async function getUserScrapsBalance(
|
|||
spent: number;
|
||||
balance: number;
|
||||
}> {
|
||||
// Earned scraps: sum of scrapsPaidAmount (what has actually been paid out per project)
|
||||
// Earned scraps: sum of paid amounts for projects that have been paid out
|
||||
// Use scrapsPaidAmount if set, otherwise fall back to scrapsAwarded for legacy projects
|
||||
// that were paid before scrapsPaidAmount was introduced
|
||||
const earnedResult = await txOrDb
|
||||
.select({
|
||||
total: sql<number>`COALESCE(SUM(${projectsTable.scrapsPaidAmount}), 0)`,
|
||||
total: sql<number>`COALESCE(SUM(CASE WHEN ${projectsTable.scrapsPaidAmount} > 0 THEN ${projectsTable.scrapsPaidAmount} ELSE ${projectsTable.scrapsAwarded} END), 0)`,
|
||||
})
|
||||
.from(projectsTable)
|
||||
.where(
|
||||
sql`${projectsTable.userId} = ${userId} AND ${projectsTable.scrapsPaidAmount} > 0`,
|
||||
sql`${projectsTable.userId} = ${userId} AND ${projectsTable.scrapsPaidAt} IS NOT NULL AND ${projectsTable.scrapsAwarded} > 0`,
|
||||
);
|
||||
|
||||
// Pending scraps: the delta between scrapsAwarded and scrapsPaidAmount for shipped unpaid projects
|
||||
// Pending scraps: scrapsAwarded for shipped unpaid projects
|
||||
const pendingResult = await txOrDb
|
||||
.select({
|
||||
total: sql<number>`COALESCE(SUM(${projectsTable.scrapsAwarded} - ${projectsTable.scrapsPaidAmount}), 0)`,
|
||||
total: sql<number>`COALESCE(SUM(${projectsTable.scrapsAwarded} - CASE WHEN ${projectsTable.scrapsPaidAmount} > 0 THEN ${projectsTable.scrapsPaidAmount} ELSE 0 END), 0)`,
|
||||
})
|
||||
.from(projectsTable)
|
||||
.where(
|
||||
sql`${projectsTable.userId} = ${userId} AND ${projectsTable.status} = 'shipped' AND (${projectsTable.deleted} = 0 OR ${projectsTable.deleted} IS NULL) AND ${projectsTable.scrapsPaidAt} IS NULL AND ${projectsTable.scrapsAwarded} > ${projectsTable.scrapsPaidAmount}`,
|
||||
sql`${projectsTable.userId} = ${userId} AND ${projectsTable.status} = 'shipped' AND (${projectsTable.deleted} = 0 OR ${projectsTable.deleted} IS NULL) AND ${projectsTable.scrapsPaidAt} IS NULL AND ${projectsTable.scrapsAwarded} > 0`,
|
||||
);
|
||||
|
||||
const bonusResult = await txOrDb
|
||||
|
|
@ -186,7 +188,9 @@ export async function getUserScrapsBalance(
|
|||
total: sql<number>`COALESCE(SUM(${shopOrdersTable.totalPrice}), 0)`,
|
||||
})
|
||||
.from(shopOrdersTable)
|
||||
.where(eq(shopOrdersTable.userId, userId));
|
||||
.where(
|
||||
sql`${shopOrdersTable.userId} = ${userId} AND ${shopOrdersTable.status} NOT IN ('cancelled', 'deleted')`,
|
||||
);
|
||||
|
||||
// Calculate scraps spent on refinery upgrades (permanent history, only deleted on undo)
|
||||
const upgradeSpentResult = await txOrDb
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue